Strings, Tupels und Listen

Werbung
Python 3.0 im Informatikunterricht der Jahrgangsstufe 8
Einführung
V. Berg
2015
Der Text wird zurzeit ständig aktualisiert. Die aktuelle Version stammt vom 10.05.15.
Einleitung
Die Programmiersprache Python
Installation
Der interaktive Modus und Idle
Einfache Datentypen
Ganze Zahlen
Gleitkommazahlen
Zeichenketten
Variablen
Arithmetische Operatoren für Zahlen
Mathematische Standardfunktionen
Aufgaben 1
Informative Programme
Grundlegendes zu Python-Programmen
Aufgaben 2
Turtle
Die Turtle und ihre Befehle
Aufgaben 3
Schreiben einer Funktion
Architektur am Bildschirm
Kontrollstrukturen
Verzweigungen
Aufgaben 4
Wiederholungen
For-Schleife
While-Schleife
Aufgaben 5
Wahr oder falsch
Funktionen mit Rückgabe
Aufgabe 6
Rekursion
Objekte und Methoden
Polyturtle
Strings, Tuples und Listen
Strings
Tuples
Listen
Aufgaben 7
Wörterbücher
Caesar-Code
Einleitung
Die Programmiersprache Python
Python ist eine objektorientierte Skriptsprache, die Anfang der 1990er-Jahre von
Guido van Rossum am CWI (Centrum voor Wiskunde en Informatica) in Amsterdam
entwickelt wurde und heute auf einer Vielzahl von Betriebssystem-Plattformen
(Unix/Linux, Windows, MacOS, etc.) verfügbar ist. Ihre leicht lesbare Syntax und
umfangreiche Standard-Bibliothek ("Batteries included") sowie eine Vielzahl von
Erweiterungen aus den verschiedensten Bereichen (GUI, Netzwerke, Datenbanken,
Graphik, 3D, Audio, Video, Web, GIS, Numerik, Spiele, etc.) haben sie zum Mittel der
Wahl bei vielen Open-Source-Projekten und in namhaften Unternehmen und
Organisationen gemacht. Die Sprache ist nach der britischen Komikertruppe Monty
Python benannt, nicht etwa nach der gleichnamigen Schlangengattung.
Installation
Die jeweils aktuelle Version (zur Zeit Version 2.7.9 vom 10.12.2014, Version 3.4.3
vom 25.02.2015) von Python findet man auf der offiziellen Python-Website unter
http://www.python.org. Es gibt Versionen für Windows, Linux und Mac OS X. Viele
Linux-Distributionen beinhalten Python bereits. Unter Windows muss Python in
jedem Fall installiert werden.
Im Unterricht wird die Version 3 benutzt.
Nach der Installation unter Windows befinden sich im Startmenü unter Python 3.4
zwei wichtige Einträge: IDLE(Python GUI) und Python(command line). Das erste
Programm startet die graphische Entwicklungsumgebung, das zweite den
interaktiven Modus.
Der interaktive Modus und IDLE
Im interaktiven Modus können einzelne Programmzeilen eingegeben und direkt
betrachtet werden. Zum Erlernen der Sprache Python wäre er somit fast ideal, da
sehr schnell kleine Programme oder Programmzeilen getestet werden können. Seine
Lesbarkeit ist jedoch sehr schlecht, da in einem schwarzen Fenster graue Schrift
benutzt wird.
Die IDLE (Integrated DeveLopment Enviroment) ist eine graphische
Entwicklungsumgebung (Python-Shell). Beim Starten wird ein Fenster geöffnet, das
wie der interaktive Modus Direkteingaben zulässt. Über den Menüpunkt File  New
Window kann eine Python-Programmdatei erstellt und editiert werden. Für das
Programmieren ist diese Oberfläche wesentlich brauchbarer als der interaktive
Modus.
Die Python Shell meldet sich in beiden Versionen mit dem Bereitschaftszeichen
(Prompt) >>>.
Nach dem Prompt kann man einen Ausdruck oder eine Anweisung eingeben. Wie
vorgeschlagen kann man einmal die Begriffe "copyright", "credits" und "license()"
eingeben. Nach Auswertung der Eingabe durch den Interpreter wird eine Ausgabe in
der nächsten Zeile gemacht. Dieses Verfahren lässt sich nicht auf mehrere
Programmzeilen anwenden. Dazu benutzt man wie schon erwähnt einen Editor. Die
Ausgabe kann dann auch in der Python-Shell erfolgen.
Einfache Datentypen
Die interaktive Python-Shell kann man auch als "Taschenrechner" nutzen. Man tippt
einfach den gewünschten Ausdruck nach dem Prompt ein, und betätigt die
Eingabetaste.
>>> 13+4*3
25
>>> (13+4)*3
51
>>> (3-5)*(13+4)
-34
Python kennt, wie die meisten anderen Programmiersprachen, die Regel
"Punktrechnung geht vor Strichrechnung". Genauso werden Klammern in
arithmetischen Ausdrücken erkannt. Eine Besonderheit ist das oder die
Divisionszeichen. In Python werden drei verschiedene Divisionszeichen verwendet.
>>> 6/4
1.5
>>> 6 // 4
1
>>> 6 % 4
2
Die erste Rechnung verwendet das „normale“ Divisionszeichen. Das Ergebnis ist wie
erwartet. Was passiert aber bei den anderen Divisionen? Dividiert man zwei
Ganzzahlen mittels des doppelten Divisionszeichens ist auch das Ergebnis eine
Ganzzahl. 4 ist in 6 einmal enthalten. Dividiert man zwei Ganzzahlen mittels des
Prozentzeichens, führt man eine modulo-Division durch Das Ergebnis ist der Rest
der Division. Dividiert man 8%4 erhält man 0, da es bei dieser Division keinen Rest
gibt.
Ganze Zahlen und Gleitkommazahlen
Das Literal für eine ganze Zahl (int) besteht aus den Ziffern 0 bis 9 und eventuell
einem positiven oder negativem Vorzeichen. Das Literal der Gleitkommazahl (float)
besteht aus einem Vorkommateil, einem Dezimalpunkt und einem Nachkommateil.
Wichtig ist, dass ein Dezimalpunkt und kein Dezimalkomma, wie im Deutschen
üblich, verwendet wird. Das Komma hat in Python eine andere Funktion, es ist in der
Regel ein Trennzeichen.
Zeichenketten
Zeichenketten (string) sind neben den Zahlen von entscheidender Bedeutung. Sie
ermöglichen es, Texte einzulesen, zu speichern und auszugeben. Um einen String
zu erzeugen, wird der Text in doppelte Hochkommata geschrieben:
>>> “Hallo Welt“
’Hallo Welt’
Der Interpreter gibt den Text in einfachen Hochkommata aus. Möchte man dies
verhindern, benötigt man die print-Anweisung:
>>> print (“Hallo Welt“)
Hallo Welt
>>> print (“3*12“)
3*12
>>> print (3*12)
36
“3*12“ ist ein String und wird von print Zeichen für Zeichen hingeschrieben, 3*12 ist
ein arithmetischer Ausdruck und wird zuerst berechnet und dann ausgegeben.
>>> print (“3*12“,3*12)
3*12 36
Die Klammern sind beim print-Befehl zwingend vorgeschrieben.
Variablen
Wie in anderen Programmiersprachen ist es auch in Python möglich, einer Zahl oder
einem String einen Namen zuzuweisen. In solch einer Zuweisung wird der Namen
auf der linken und das Literal auf der rechten Seite eines Gleichheitszeichens notiert.
Der Variabelenname (Bezeichner) darf aus allen Buchstaben des Alphabets und dem
Unterstrich zusammengesetzt werden. Nach mindestens einem Buchstaben oder
dem Unterstrich dürfen auch Ziffern verwendet werden. Bestimmte Schlüsselwörter
(reservierte Wörter) dürfen nicht als Namen verwendet werden. Die folgende Tabelle
enthält die Python Schlüsselworte:
and
assert
elif
else
global
if
or
pass
yield
Break
Class
Continue
Def
Del
except
exec
finally
for
from
import
in
is
lambda
not
print
raise
return
try
while
>>> name=0.5
>>> var123=12
>>> string=“Hallo Welt“
>>> name
0.5
>>> string
‘Hallo Welt’
>>> 2*name
1.0
>>> (var123+var123)/3
8.0
>>> var123+name
12.5
>>> a=1+2
>>> b=var123/4
>>> a+b
6
Mathematische Standardfunktionen
Neben den Operatoren für Addition, Subtraktion, Division und Multiplikation bietet
Python eine Reihe vordefinierter Funktion an. Diese befinden sich zum Teil im Modul
math. Deshalb muss dieses zu Programmanfang geladen werden:
from math import *
Folgende Funktionen werden häufig benötigt (eine vollständige Liste befindet sich in
den Dokumentationen):
Funktion
fabs(x)
exp(x)
log(x)
log(x,y)
log10(x)
pow(x,y)
sqrt(x)
sin(x)
cos(x)
tan(x)
Bedeutung
Argument ist
vom Typ
Absolutbetrag
int, float
Exponentialfunktion int, float
natürlicher
int, float
Logarithmus
Logarithmus zur
int, float
Basis y
Zehnerlogarithmus int, float
Potenz xy
int, float
Quadratwurzel
int, float
Sinus (Argument
int, float
im Bogenmaß)
Cosinus (Argument int, float
im Bogenmaß)
Tangens
int, float
Ergebnis ist
vom Typ
float
float
float
Beispiel
float
log(8,2)
float
float
float
float
log10(100)
pow(2,3)
sqrt(25)
sin(30)
float
cos(30)
float
tan(30)
fabs(-3.5)
exp(3)
log(3)
asin(x)
acos(x)
atan(x)
pi
degrees(x)
radians(x)
(Argument im
Bogenmaß)
Arcussinus
(Argument im
Bogenmaß)
Arcuscosinus
(Argument im
Bogenmaß)
Arcustangens
(Argument im
Bogenmaß)
die Zahl Pi
wandelt Winkel
vom Bogenmaß in
Gradzahl um
wandelt Winkel von
Gradzahl in
Bogenmaß um
int, float
float
asin(30)
int, float
float
acos(30)
int, float
float
atan(30)
int, float
float
float
pi
degrees(0.8)
int, float
float
radians(30)
Aufgaben 1
1. Gib den Bildschirmausdruck an! Kontrolliere anschließend durch Eingabe der Programme.
a)
print ("a = "),
b)
print ("a = ")
c)
print ("a = ")
d)
print (“a = “),
print (9)
print (9)
print ()
print ()
print (9)
print ()
print (9)
2. Verfahre wie in Aufgabe 1.
a)
print ("9 17 Ende")
c)
print ("9","17","Ende")
b)
d)
print ("9" "17" "Ende")
print (9,17,"Ende")
3. Schreibe ein Programm, das nach Eingabe der Zahlen 5 und – 20 den folgenden Ausdruck liefert
(nur print-Anweisungen:
5
-20
-205 -20
Das war’s
4. Gib die Werte der Variablen nach Ausführung der Anweisungsteile an.
a)
a=5
b)
a=5
c)
a=3
b=4
b=4
x=a
a=2*a
c = -10
x=x*x
b=a+b
c=a*b
x=a+x
a=a*a
a=b–1+c
a=x-a
b=3*(a–c)*(a–c)
5. Schreibe ein Programm zur Berechnung des jeweiligen Terms.
a)
a² - 7
b)
a–b
c)
a*b
-----------a+b
a–b
6. Berechne den Wert der folgenden Zuweisungen:
a)
a = 3 + 14 % ( 7 * 5 )
b)
b = 3 + 14 % 7 * 5
c)
c = ( 3 + 14 ) % 7 * 5
d)
d = 3 * 14 % 7 * 5
d)
a+b
------a*b
e)
e = ( 17 % 5 ) + ( 17 / 5 ) * 5
f)
f = ( 100 / 15 ) % ( 15 – 2 / 3)
7. Schreibe ein Programm zur Berechnung des jeweiligen Terms.
a)
(a+b)²
b)
a² + b²
c)
(a*b)²
e)
ab+2
f)
ab+2
g)
√a + 2
i)
│a³-4b² │
j)
│-b │
k)
232 - 216
d)
h)
l)
a*b²
√(a + 2)
a² * b³
Informative Programme
Die bisherigen Beispiele sind wenig benutzerfreundlich. Man muss sich jeweils
merken, was eingeben wurde und was der Computer ausrechnet. Folgende Aufgabe
soll etwas benutzerfreundlicher gestaltet werden: Ein Autofahrer möchte aus der
verbrauchten Benzinmenge und der Anzahl der gefahrenen Kilometer den
durchschnittlichen Benzinverbrauch pro 100 km Fahrstrecke berechnen. Das
Ergebnis soll auf zwei Nachkommastellen gerundet werden.
Wie kann man nun ein kleines Programm mit Python schreiben? In der Python Shell
klickt auf File und dann auf New Window. In dem nun geöffneten Editor schreibt
man das benötigte Programm. Man benötigt Eingabe-, Verarbeitungs- und
Ausgaberoutinen (EVA-Prinzip). Die Verarbeitungs- und Ausgaberoutinen
entsprechen den Eingaben im Direktmodus.
Die Eingabeaufforderung erfolgt durch den Befehl input. Eine Eingabe wie 2+2 wird
als String verarbeitet. Wenn eine Zahl eingeben werden soll, muss das Ergebnis von
input explizit in einen Wert des Datentyps int (ganze Zahl) oder float
(Gleitkommazahl) konvertiert werden. Das Programm sieht wie folgt aus:
benzinmenge=float(input("Benzinverbrauch in Litern: "))
strecke=float(input("zugehoerige Wegstrecke in Kilometern: "))
verbrauch=benzinmenge/strecke*100
print ("Verbrauch je 100 km Wegstrecke in Litern: ",round(verbrauch,2))
Der Befehl round(x,n) rundet die Gleitkommazahl auf n Nachkommastellen. Der
Parameter n ist optional und mit 0 vorbelegt. Bevor das Programm startet, fordert
Python den Benutzer auf, den Quelltext zu speichern. Es ist sinnvoll, einen Ordner
einzurichten, in dem man alle seine Programmierversuch speichern kann.
Pythonprogramme müssen die Endung .py haben. Der Name des Programms sollte
so gewählt werden, dass man auch später noch leicht erkennen kann, was das
Programm macht.
Benutzt man im Quelltext Sonderzeichen wie ä, ö, ü und ß meldet sich Python mit
einer Warnung, dass die Codierung nicht dem Standard-ASCII-Zeichensatz
entspricht. Beantwortet man die Warnung mit Ok wird die benötigte Erklärung
automatisch in das Programm eingefügt.
Ein weiteres Beispiel: Mischungstemperatur bei Wasser. Mischt man m 1 kg Wasser
der Temperatur t1 und m2 kg Wasser der Temperatur t2, so stellt sich als
Mischungstemperatur die Temperatur t=(m1t1 + m2t2) : (m1 + m2) ein.
print ("Temperatur und Masse der ersten Wassermenge:")
temp1=float(input("Temperatur: "))
masse1=float(input("Masse: "))
print
print ("Temperatur und Masse der zweiten Wassermenge:")
temp2=float(input("Temperatur: "))
masse2=float(input("Masse: "))
mischtemp=(masse1*temp1+masse2*temp2)/(masse1+masse2)
print
print ("Mischungstemperatur:",round(mischtemp,2))
Oft möchte man bei Berechnungen mit Gleitkommazahlen nur den ganzzahligen
Anteil für weitere Berechnungen nutzen. Wie kann man den Nachkommateil
entfernen? Dazu nutzt man den Befehl int(a.b). Das Ergebnis dieses Befehls ist a.
Beispiel: Eine einzugebende Anzahl von Sekunden soll in größere Zeiteinheiten,
nämlich in Jahre, Tage, Stunde, Minuten und Sekunden umgewandelt werden. Um
Sekunden in Minuten umzurechnen teilt man den Sekundenwert durch 60. Man bildet
den ganzzahligen Anteil und bestimmt anschließend den Rest. Den Minutenwert teilt
man wieder durch 60, um den Stundenwert zu erhalten; es wird wieder der
ganzzahlige Anteil bestimmt und der Rest bestimmt. Von den Stunden gelangt man
zu den Tagen und anschließend zu den Jahren (Schaltjahre werden nicht
berücksichtigt).
sekunden=int(input("Eingabe der Sekunden: "))
minuten=int(sekunden / 60);
sekunden=sekunden-minuten*60
stunden=int(minuten/60)
minuten=minuten-stunden*60
tag=int(stunden/24)
stunden=stunden-tag*24
jahr=int(tag/365)
tag=tag-jahr*365
print (jahr, tag, stunden, minuten, sekunden)
Aufgaben 2
1. Schreibe ein vollständiges Programm und teste es aus:
a) Aus den Seiten a und b eines Rechtecks sind Umfang und Flächeninhalt zu berechnen.
b) Der Zins ist aus Kapital, Zinssatz und der Anzahl der Tage zu bestimmen.
c) Berechne R aus R1, R2, R3 nach der Formel
R1 * R2
R = R3 + ----------R1 + R2
2. Das folgende Programm zur Berechnung eines Kegelstumpfes enthält syntaktische Fehler.
Welche?
# Programm Volumen
from math import
gk1=float(imput("Grundkreisradius 1: "))
gk2=float(input("Grundkreisradius 2: "))
h=(input("Hoehe: "))
V=pi*h(gk1*gk1+gk1*gk2+gk2*gk2)/3
print "Volumen:",)
3. Aus Länge, Breite und Höhe eines Quaders sollen dessen Volumen und der Inhalt der Oberfläche
berechnet werden.
4. Die Jahreszinsen können nach der Formel z=k*p:100 berechnet werden. Dabei bedeutet k das
Kapital, p den jährlichen Zinssatz in Prozenten und x die Zinsen. Schreibe ein Programm, mit dem der
Computer nach Eingabe von Kapital und Zinssatz die Jahreszinsen berechnen und ausdrucken kann.
5. Eine Schraubenfeder verlängert sich bei einem Gewicht von 28 g um 18 mm. Die Verlängerung der
Feder ist dem Gewicht des angehängten Körpers proportional. Schreibe ein Programm, mit dem der
Computer nach Eingabe des Gewichtes des angehängten Körpers die zugehörige Verlängerung der
Feder bestimmen kann.
6. Bei der Bank müssen häufig Münzen gezählt werden. Deshalb ist ein Programm nötig, mit dem
nach Eingabe der Anzahl der verschiedenen Münzen der Geldbetrag in Euro und Cent ausgedruckt
werden kann.
Turtle
Die Turtle und ihre Befehle
Die Programmiersprache LOGO ist vor allem wegen ihrer Turtle-Graphik bekannt
geworden. Eine oder mehrere virtuelle Schildkröten (engl.:turtle) lassen sich auf dem
Bildschirm bewegen und ziehen bei Bedarf eine farbige Linie hinter sich her. Diese
Turtle-Graphiken lassen sich auch mit Python realisieren. Ein entsprechendes Modul
ist in Python 2.5 eingebaut und lässt sich bei Bedarf aufrufen und verwenden.
Ein kleiner schwarzer Pfeil stellt die Turtle dar. Durch entsprechende Befehle lässt
sich der Pfeil steuern. Das folgende Programm zeichnet ein schwarzes Rechteck:
from turtle import *
forward(50)
left(90)
forward(50)
left(90)
forward(50)
left(90)
forward(50)
Was bedeuten die Befehle? Mit der Befehlsfolge from turtle import * wird das
Modul TURTLE geladen und die im Modul implementierten Befehle lassen sich direkt
durch Aufruf verwenden. Der Befehl forward(50) gibt der Turtle den Befehl, sich 50
Pixel nach vorne zu bewegen. Da die Turtle zu Beginn des Programms nach Osten
ausgerichtet ist, bewegt sie sich 50 Pixel nach rechts. left(90) dreht die Turtle um 90
Grad nach links. Sie ist jetzt nach Norden ausgerichtet. forward(50) bewegt sie
wieder 50 Pixel nach vorne (hier nach oben). Nach Abschluss der Befehlsfolge hat
die Turtle ihre Ausgangsposition wieder erreicht. Die Blickrichtung ist jetzt Süden. Um
die ursprüngliche Ausrichtung zu erhalten, muss noch einmal der Befehl left(90)
ausgeführt werden.
Das Programm wird um drei Befehle erweitert:
from turtle import *
reset()
color("red")
width(5)
forward(50)
left(90)
forward(50)
left(90)
forward(50)
left(90)
forward(50)
reset(): Der Befehl löscht den Bildschirm, setzt den Stift auf die Ausgangsposition
und alle Variablen auf ihre Vorgabewerte zurück.
color(“red“): Der Befehl bestimmt die Stiftfarbe, der Farbwert ist in
Anführungszeichen zu setzen. Zulässig sind die HTML-Farbwerte.
width(x): x definiert die Strichstärke des Stiftes in Pixel.
Das Programm wird nochmals erweitert bzw. verändert:
from turtle import *
color("red")
begin_fill()
forward(80)
left(90)
forward(80)
left(90)
forward(80)
left(90)
forward(80)
end_fill()
up()
forward(80)
left(90)
forward(80)
down()
color("blue")
begin_fill()
forward(80)
left(90)
forward(80)
left(90)
forward(80)
left(90)
forward(80)
end_fill()
up()
left(90)
backward(160)
down()
color("yellow")
begin_fill()
forward(80)
left(90)
forward(80)
left(90)
forward(80)
left(90)
forward(80)
end_fill()
color("red")
begin_fill() schaltet die Turtle in den Füllmodus, end_fill() beendet den Füllmodus.
up() und down() heben und senken den Stift. Solange der Stift angehoben ist,
zeichnet die Turtle eine unsichtbare Linie
backward(x): Die Turtle geht x Pixels rückwärts.
Das Turtle-Modul enthält noch eine Menge weiterer Befehle, die für Zeichnungen und
Konstruktionen genutzt werden können. In der folgenden Tabelle sind die wichtigsten
aufgelistet (auch die schon besprochenen Befehle):
degrees()
radians()
setup(***)
title(title_str)
reset()
clear()
speed(speed)
delay(delay)
forward(distance)
backward(distance)
left(angle)
right(angle)
up()
down()
width(width)
color(s)
write(text[,move])
begin_fill()
end_fill()
Winkel werden in Grad angegeben
Winkel werden im Bogenmaß angegeben
Größe und Position des Fensters werden bestimmt.
Schlüsselwörter sind width, height, startx und starty.
setup(): 50%*50% des Bildschirms, zentriert
setup (width=200, height=200, startx=0, starty=0):
Fenster hat eine Größe von 200*200 Pixel, links oben auf
dem Bildschirm
setup(width=.75, height=0.5, startx=None, starty=None):
Fenstergröße beträgt 75% * 50% des Bildschirms, zentriert
title(“Versuch”): Fenster erhält die Überschrift “Versuch”
Bildschirm wird gelöscht, Turtle wird zentriert, Variablen
werden auf Vorgabewerte gesetzt.
Bildschirm wird gelöscht
Die Geschwindigkeit der Turtle wird festgelegt:
speed(“fastest”):keine Verzögerung
speed(“fast”): 5 ms Verzögerung
speed(“normal”): 10 ms Verzögerung
speed(“slow“): 15 ms Verzögerung
speed(“slowest“): 20 ms Verzögerung
delay(25): Die Geschwindigkeit der Turtle wird auf 25 ms
gesetzt.
forward(80): Die Turtle bewegt sich 80 Pixel nach vorne
backward(80): Die Turtle bewegt sich 80 Pixel nach hinten
left(45): Die Turtle dreht sich um 45 Grad nach links
right(90): Die Turtle dreht sich um 90 Grad nach rechts
Der Zeichenstift wird angehoben
Der Zeichenstift wird abgesenkt
width(2): Die Breite des Stiftes beträgt 2 Pixel
color(“red“): Die Zeichenfarbe ist rot.
write(“Hallo“): An der aktuellen Stiftposition wird „Hallo“
geschrieben. Wenn move wahr ist, bewegt sich der Stift an
die rechte untere Ecke des Textes. Die Vorgabe für move
ist falsch.
Um eine Figur farblich auszufüllen, kann zu Beginn auch
dieser Befehl genutzt werden.
Zum Abschluss des Füllvorgangs muss dieser Befehl
gesetzt werden.
circle(radius[,extent]) circle(50): Dieser Befehl zeichnet einen Kreis mit dem
Radius 50 Pixel, dessen Mittelpunkt sich 50 Pixel links von
der aktuellen Turtleposition befindet.
circle(50,180): extent gibt an, welcher Teil des Kreises
gezeichnet werden soll. Der Wert 180 zeichnet einen
Halbkreis. Wenn kein voller Kreis gezeichnet wird, ist der
Endpunkt des Kreisbogens die aktuelle Stiftposition. Der
Bogen wird entgegen dem Uhrzeigersinn gezeichnet, wenn
radius positiv ist; ist radius negativ wird mit dem
Uhrzeigersinn gezeichnet. Die Richtung der Turtle wird
durch extent beeinflußt.
goto(x,y)
goto(-50,100): Die Turtle geht zur Position -50,100.
setx(x)
setx(40): Die x-Koordinate der Turtle wird auf 40 gesetzt.
sety(y)
sety(40): Die y-Koordinate der Turtle wird auf 40 gesetzt.
window_width()
Mit diesem Befehl kann die Breite des Fensters abgefragt
werden.
window_height()
Mit diesem Befehl kann die Höhe des Fensters abgefragt
werden.
position()
Mit diesem Befehl kann die aktuelle Position der Turtle
abgefragt werden.
heading()
Dieser Befehl gibt die Richtung der Turtle wieder.
setheading(angle)
Die Richtung der Turtle wird auf angle gesetzt.
Hier noch ein Beispiel, das viele der oben angeführten Befehle benutzt:
from turtle import *
forward(50)
left(90)
forward(50)
left(90)
forward(50)
left(90)
forward(50)
left(90)
up()
goto(-100,-100)
down()
color("red")
speed("fastest")
write("künstlerisch wertvoll")
forward(50)
left(90)
forward(50)
left(90)
forward(50)
left(90)
forward(50)
left(90)
up()
goto(100,100)
down()
color("blue")
speed("normal")
# 1. Quadrat
# Stift hoch
# neue Turtleposition
# neue Farbe
# Zeichengeschwindigkeit
# Text
# 2. Quadrat
begin_fill()
forward(50)
left(90)
forward(50)
left(90)
forward(50)
left(90)
forward(50)
left(90)
end_fill()
up()
setx(200)
down()
color("green")
forward(50)
left(90)
forward(50)
left(90)
forward(50)
left(90)
forward(50)
left(90)
up()
goto(-150,150)
down()
color("tomato")
speed("fast")
width(5)
circle(50)
left(90)
begin_fill()
color("gold")
circle(50)
end_fill()
left(90)
color("sienna")
circle(50)
left(90)
color("steelblue")
circle(50)
up()
forward(300)
down()
width(1)
circle(50,180)
circle(-50,180)
circle(50,-180)
circle(-50,-180)
circle(-100,90)
forward(200)
circle(-100,45)
circle(-90,45)
circle(-80,45)
circle(-70,45)
circle(-60,45)
circle(-50,45)
circle(-40,45)
circle(-30,45)
circle(-20,45)
circle(-90,45)
# 3. Quadrat, gefüllt
# neuer x-Wert der Turtle
# 4. Quadrat
# vier Kreise
# Linien
# Richtung der Turtle beachten
Auf den Befehl circle soll hier noch etwas genauer eingegangen werden. Das
folgende kleine Programm zeichnet zwei Kreise:
from turtle import *
circle(50)
circle(-50)
Der Befehl circle(50) zeichnet einen Kreis, dessen Mittelpunkt sich 50 Pixel links von
der aktuellen Turtleposition befindet; der zweite Befehl zeichnet einen Kreis, dessen
Mittelpunkt sich 50 Pixel rechts von der aktuellen Position befindet. Ist der Wert des
Radius positiv wird der Kreis nach links gezeichnet, ist der Wert negativ nach rechts.
Folgerichtig zeichnet das folgende Programm zweimal denselben Kreis.
from turtle import *
circle(50)
left(180)
circle(-50)
Der Befehl circle kann auch mit einer Erweiterung genutzt werden: circle(100,180).
Dieser Befehl zeichnet einen Halbkreis, dessen Mittelpunkt sich 100 Pixel links von
der aktuellen Position befindet. Der Halbkreis wird entgegen dem Uhrzeigersinn
gezeichnet. Ist die Erweiterung negativ (circle(100,-180)), wird ebenfalls ein Halbkreis
gezeichnet. Die Turtle bewegt sich jedoch rückwärts und zeichnet deshalb einen
Halbkreis im Uhrzeigersinn. Der Mittelpunkt befindet sich immer noch 100 Pixel
rechts von der aktuellen Position.
Aufgaben 3
Zeichne folgende Figuren:
Schreiben einer Funktion
In den Beispielen wurden mehrmals Quadrate gleicher Größe gezeichnet. Für jedes
Quadrat wurden jedes Mal die gleichen Befehle eingegeben. Dies ist nicht nur
umständlich, es macht die Programme auch schwer lesbar. Ein beliebiges Quadrat
kann wie folgt gezeichnet werden:
forward(seite)
left(90)
forward(seite)
left(90)
forward(seite)
left(90)
forward(seite)
left(90)
Um dem Programm verständlich zu machen, dass diese Befehlsfolge ein Quadrat
ergibt, definiert man eine Funktion namens Quadrat:
def quadrat():
forward(seite)
left(90)
forward(seite)
left(90)
forward(seite)
left(90)
forward(seite)
left(90)
Diese Funktion wird im Programm aufgerufen. Der Quellcode für ein Programm, dass
vier Quadrate unterschiedlicher Größe zeichnen soll, könnte wie folgt aussehen:
from turtle import *
def quadrat():
forward(seite)
left(90)
forward(seite)
left(90)
forward(seite)
left(90)
forward(seite)
left(90)
seite=60
quadrat()
seite=100
quadrat()
seite=140
quadrat()
seite=180
quadrat()
Noch einfacher wäre es, wenn man den Wert für die Seite beim Aufruf der Funktion
direkt übergeben könnte. Unter Python bereitet das kein Problem. Die Funktion wird
einfach abgewandelt:
def quadrat(seite):
…..
Das Programm sieht dann so aus:
from turtle import *
def quadrat(seite):
forward(seite)
left(90)
forward(seite)
left(90)
forward(seite)
left(90)
forward(seite)
left(90)
quadrat(60)
quadrat(100)
quadrat(140)
quadrat(180)
Das Programm wird nochmals verändert:
from turtle import *
def quadrat(seite):
forward(seite)
left(90)
forward(seite)
left(90)
forward(seite)
left(90)
forward(seite)
left(90)
seite=60
quadrat(seite)
quadrat(seite+40)
quadrat(seite+80)
quadrat(seite+120)
Der Wert der Variablen Seite soll beobachtet werden. Im Hauptprogramm beträgt der
Wert von Seite immer 60. In der Funktion ist er aber im ersten Quadrat 60, im
zweiten 100, im dritten 140 und im vierten 180. Überprüft man nach dem Zeichnen
den Wert von Seite (in der Python-Shell den Befehl print (seite) eingeben), so
beträgt er 60. Wie ist dies möglich? Anscheinend sind die Werte der Variablen Seite
im Hauptprogramm andere als die Werte der Variablen Seite in der Funktion. Ändert
man im Hauptprogramm oder in der Funktion den Namen der Variablen Seite, läuft
das Programm weiterhin fehlerfrei. Die Erklärung für dieses Verhalten: Python
unterscheidet zwischen lokalen und globalen Variablen. In der Definition der Funktion
wurde die Variablen Seite eingetragen. Die Variable Seite ist deshalb eine lokale
Variable, die nur in der Funktion gültig ist. Dass im Hauptprogramm ebenfalls eine
Variable Seite vorkommt, interessiert Python nicht. Auf die Bedeutung von lokaler
und globaler Variable wird später noch eingegangen.
In der Turtlegraphik liegt der Mittelpunkt des Kreises bei positiven Radiuswerten
immer links von der Turtle, bei negativen Werten immer rechts. In der Geometrie ist
es aber üblich, vom Mittelpunkt ausgehend einen Kreis mit einem bestimmten Radius
zu zeichnen. Mit Hilfe einer Funktion soll durch Angabe der Mittelpunktskoordinaten
und des Radius ein Kreis gezeichnet werden. Dabei ist die Richtung der Turtle zu
beachten. Diese Kreisfunktion richtet zum Zeichnen die Turtle nach Osten aus. Um
die ursprüngliche Richtung wieder herzustellen, wird der Richtungswert zwischengespeichert und am Ende der Funktion wieder übergeben.
def kreis(xm,ym,radius):
richtung=heading()
setheading(0)
up()
goto(xm, ym-radius)
down()
circle (radius)
setheading(richtung)
Diese Funktion kann man auch zum Zeichnen von Kreisbögen nutzen. Dazu muss
sie etwas abgewandelt werden. Zwei weitere Werte werden durch Aufruf übergeben:
die Winkelposition, ab dem der Kreisbogen gezeichnet werden soll und der
eigentliche Winkelbogen.
def kreisbogen(xm,ym,radius,start,laenge):
richtung=heading()
setheading(start)
up()
goto(xm, ym-radius)
down()
circle (radius,laenge)
setheading(richtung)
Architektur am Bildschirm
Die Fassade eines Bauwerks ist aus unterschiedlichen Bauteilen zusammengesetzt.
Wände, Türen , Dächer, Fenster sind auf ganz verschiedene Art miteinander von
Architekten kombiniert worden. Quadrate, Rechtecke, Kreise usw. sind bereits mit
der Turtle gezeichnet worden. Es sollen jetzt architektonische Elemente erstellt
werden, die alle auf dieselbe Art und Weise aufgerufen werden sollen: Name(xpos,
ypos, farbe). Damit diese Objekte vernünftig am Bildschirm angeordnet werden
können, sollen sie alle eine Rastergröße von 100*100, oder 50*100 oder 50*50 oder
25*100 Pixeln haben. Die Definition für ein großes Quadrat könnte dann wie folgt
aussehen:
def quadrat(xpos,ypos,farbe):
up()
goto(xpos+1,ypos+1)
down()
begin_fill()
color(farbe)
for i in range(4):
forward(98)
left(90)
end_fill()
forward(0)
Für ein kleines Quadrat sieht die Größenanordnung etwas anders aus:
def quadratk(xpos,ypos,farbe):
up()
goto(xpos+1,ypos+1)
down()
begin_fill()
color(farbe)
for i in range(4):
forward(48)
left(90)
end_fill()
forward(0)
Alle Elemente werden mit den Variablen xpos, ypos und farbe aufgerufen. Damit die
Elemente voneinander unterschieden werden könne, haben alle einen farblosen
Rand von einem Pixel Breite. Die Ausrichtung der Turtle ist zu Beginn und am Ende
der Funktion immer nach Osten.
Welche Elemente für eine Zeichnung benötigt werden, liegt im Ermessen jedes
Einzelnen, der solch eine Graphik herstellen möchte. In dem Beispiel sind 16
Bauelemente und 4 Fensterelemente verwandt worden. Die Fensterelemente
orientieren sich dabei an den entsprechenden Bauelementen.
Beispiel:
def rechtecks(xpos,ypos,farbe):
up()
goto(xpos+1,ypos+1)
down()
begin_fill()
color(farbe)
for i in range(2):
forward(48)
left(90)
forward(98)
left(90)
end_fill()
forward(0)
def fen4(xpos,ypos,farbe):
up()
goto(xpos+7,ypos+11)
down()
begin_fill()
color(farbe)
for i in range(2):
forward(36)
left(90)
forward(36)
left(90)
end_fill()
up()
goto(xpos+7,ypos+55)
down()
begin_fill()
for i in range(2):
forward(36)
left(90)
forward(36)
left(90)
end_fill()
forward(0)
rechtecks(175,-100,"black")
fen4(175,-100,"white")
Kontrollstrukturen
Für die Datentypen int, long, float und bool sind vergleichende Operatoren definiert.
Jeder dieser Operatoren liefert als Ergebnis einen Wahrheitswert True oder False.
Folgende Operatoren werden von Python bereit gestellt:
Operator
==
!=
<>
<
<=
>
>=
Beispiel
x == y
x != y
x <> y
x<y
x <= y
x>y
x >= y
Ergebnis
wahr, wenn x und y gleich sind
wahr, wenn x und y verschieden sind
analog zu !=, bitte nicht verwenden
wahr, wenn x kleiner ist als y
wahr, wenn x kleiner oder gleich y ist
wahr, wenn x größer y ist
wahr, wenn x größer oder gleich y ist
Verzweigungen
Den Aufgaben, die der Rechner bisher zu lösen hatte, war eines gemeinsam: er
musste nacheinander in der ihm vorgegebenen Reihenfolge verschiedene
Anweisungen ausführen. Oft ist es jedoch notwendig, dass der Rechner selber
Entscheidungen treffen muss. In Python gibt es für Fallunterscheidungen die
klassische if-Anweisung. Eine if-Anweisung besteht im einfachsten Fall aus einem
Anweisungskopf, der eine Bedingung enthält und aus einem Codeblock als
Anweisungskörper. Der Codeblock wird nur ausgeführt, wenn die Bedingung wahr
ist.
Bei einer Bank werden bei einem Girokonto für jede Buchung 0,20 € berechnet.
lediglich die ersten fünf Buchungen sind kostenfrei. Nach Eingabe der Anzahl der
Buchungen soll der Rechner die Gebühren berechnen und ausdrucken.
anzahl=int(input("Wie viele Buchungen? "))
gebuehr=0.0
buchung=0.2
gratis=5
if anzahl>=gratis:
gebuehr=buchung*(anzahl-gratis)
print ("Gebuehren:", gebuehr)
In vielen Fällen ist es aber mit einer einzelnen if-Anweisung nicht getan. Man benötigt
eine Kette von Fallunterscheidungen. Angenommen, die Variable x kann den Wert 1
bis 10 annehmen. Der jeweilige Wert soll ausgedruckt werden. Formuliert man das
Problem mit if-Anweisungen, sähe das Programm wie folgt aus:
if x==1:
print
if x==2:
print
if x==3:
print
if x==4:
print
usw.
“x hat den Wert 1“
“x hat den Wert 2“
“x hat den Wert 3“
“x hat den Wert 4“
Wenn x tatsächlich den Wert 10 hat, werden alle zehn Anweisungen abgearbeitet.
Sie werden aber auch alle abgearbeitet, wenn x den Wert 1 hat. Wenn x gleich 1 ist,
bräuchten die übrigen neun Anweisungen nicht mehr bearbeitet werden. Python
bietet die Anweisung elif an, die dieses Problem lösen kann. Das Programm sieht
dann wie folgt aus:
if x==1:
print “x
elif x==2:
print “x
elif x==3:
print “x
elif x==4:
print “x
usw.
hat den Wert 1“
hat den Wert 2“
hat den Wert 3“
hat den Wert 4“
Schreibarbeit erspart sich nicht, aber das Programm wird schneller abgearbeitet.
Eine weitere Ergänzung der if-Anweisung ist die zweiseitige Entscheidung. Wenn die
Bedingung im Anweisungskopf nicht erfüllt ist, soll ein zweiter Codeblock ausgeführt
werden. Dieser zweite Codeblock wird mit else eingeleitet.
Ein Beispiel: Der Computer soll feststellen, ob eine Zahl a durch b teilbar ist.
zahl_a=int(input("Zahl a: "))
zahl_b=int(input("Zahl b: "))
if zahl_a%zahl_b==0:
print zahl_a," ist durch ",zahl_b," teilbar"
else:
print zahl_a," ist durch ",zahl_b," nicht teilbar"
Sicherlich ist die Schaltjahrregelung bekannt. Jahre, die durch 4 teilbar sind, sind
Schaltjahre. Ausgenommen sind Jahre, die durch 100 teilbar sind. Sie sind keine
Schaltjahre, es sei, denn, sie sind durch 400 teilbar. Das Jahr 2008 ist also ein
Schaltjahr, 1900 war kein Schaltjahr, 2000 war ein Schaltjahr. Das folgende
Programm überprüft nach Eingabe der Jahreszahl, ob ein Schaltjahr vorliegt oder
nicht.
jahr=int(input("Eingabe des Jahres: "))
if jahr%4==0:
if jahr%100==0:
if jahr%400==0:
print "Schaltjahr"
else:
print "kein Schaltjahr"
else:
print "Schaltjahr"
else:
print "kein Schaltjahr"
Beispiel:
Bekanntlich kann man nicht immer aus drei beliebigen Streckenlängen ein Dreieck
konstruieren. Es ist dies jedoch immer möglich, wenn die größte Streckenlänge
kleiner als die Summe der verbleibenden Streckenlängen ist. Nach Eingabe der drei
Streckenlängen (Maximum zuerst) soll die Konstruierbarkeit beurteilt und
gegebenenfalls auf Rechtwinkligkeit überprüft werden.
c=float(input("Bitte längste Seite eingeben: "))
a=float(input("Bitte zweite Seite eingeben: "))
b=float(input("Bitte dritte Seite eingeben: "))
if (a + b)<= c:
print ("kein Dreieck konstruierbar")
else:
if a*a+b*b == c*c:
print ("Dreieck ist konstruierbar - rechtwinklig")
else:
print ("Dreieck ist konstruiebar - nicht rechtwinklig")
Beispiel:
Es ist die Lösung der Gleichung ax2 + bx + c = 0 mit a, b, c  auszugeben nach
Eingabe von a, b und c.
from math import sqrt
a=float(input("a = "))
b=float(input("b = "))
c=float(input("c = "))
if a==0:
if b==0:
if c==0:
print "L = R"
else:
print "L = [ ]"
else:
x0=-c/b
print "L = [ ",x0," ]"
else:
diskr=b*b-4*a*c
if diskr>0:
d=sqrt(diskr)
x1=(-b-d)/(2*a)
x2=(-b+d)/(2*a)
print ("L = [ ",x1,", ",x2," ]")
else:
if diskr==0:
x0=-b/(2*a)
print ("L = [",x0," ]")
else:
print ("L = [ ]")
Aufgaben 4
1. Zu einem gegebenen Datum soll die Nummer des Tages in diesem Jahr angegeben werden.
2. Für die Bestimmung des Osterdatums gilt die Osterformel von Gauss. Es bedeuten:
j = Jahreszahl
p = ganzzahliger Teil von j/100
n = Rest von j/100
q = ganzzahliger Teil von p/3
r = ganzzahliger Teil von p/4
x = Dreißigerrest von 15 + p – q – r
y = Siebenerrest von p – r + 4
a = Neunzehnerrest von j
b = Viererrest von j
c = Siebenerrest von j
d = Dreißigerrest von 19a + x
e = Siebenerrest von 2b + 4c +6d + y
Dann ist Ostern am (22+d+e). März oder am (d+e-9). April, je nachdem ob (22+d+e)<= 31 ist oder
nicht. Ausnahmen: Ist d=29 und e=6, so ist Ostern am 19. April. Ist d=28 und e=6, so ist Ostern am
18. April.
3. Umrechnung von Maßeinheiten der Temperatur
oC = Grad Celsius, oR = Grad Réaumur, oF = Grad Fahrenheit
Der Gefrierpunkt des Wassers ist bei 0 oC = 0 oR = 32 oF, der Siedepunkt bei 100 oC = 80 oR = 212 oF.
Es ist ein Programm zu schrieben, das die Werte der einen Skala in jede der beiden anderen
umrechnen kann.
4. Bekanntlich sind zwei geraden in einer Ebene mit den Gleichungen y=ax+b und und y=cx +d durch
die Zahlen a, b , c und d festgelegt. Schriebe ein Programm, mit dem der Computer den Schnittpunkt
berechnen und ausgeben kann. Dabei soll auch der Fall berücksichtigt werden, dass die geraden
parallel sind.
Wiederholungen
Sehr oft ist es notwendig, das Befehlsfolgen oder Befehle mehrfach ausgeführt
werden. Dabei unterscheidet man zwei Szenarien: man kennt die Anzahl der
benötigten Aufrufe („Würfele 3 mal“) oder man kennt sie nicht („Würfele, bis du eine
sechs geworfen hast“). Für beide Fälle hat Python entsprechende Befehle. Den
ersten Fall löst man mit einer for-Schleife, den zweiten mit einer while-Schleife.
FOR-Schleife
Die for-Schleife hat folgende Struktur:
for target_list in expression_list:
Anweisungblock
Hinter dem Schlüsselwort for kommt üblicherweise eine Laufvariable oder rein Tupel
von Variablennamen. Danach folgt das Schlüsselwort in und dahinter ein Ausdruck,
der eine Ansammlung von Objekten beschreibt. Im einfachsten Fall handelt es sich
um eine Sequenz. Die folgenden Beispiele sollen diese Aussagen deutlicher
machen:
>>> for farbe in (“rot“, “gelb“, “gruen“):
print (farbe)
rot
gelb
gruen
>>>
>>> for i in [1, 2, 3, 4, 5]:
print (i*i,end=“ “)
1 4 9 16 25
>>>
>>> for element in [2, 5, 11]:
print (element)
2
5
11
>>>
Gemeinsam ist allen Beispielen, dass die Anzahl der Elemente in der expression_list
beschränkt war. Wie sieht es aber aus, wenn eine Schleife 100 mal oder noch öfter
durchlaufen werden soll? Hilfreich für die Formulierung vieler Durchläufe ist die
range()-Funktion. Der Aufruf von range(n) erzeugt eine Liste ganzer Zahlen von 0
bis n-1.
>>> for nummer in range(5):
print (nummer, end=“ “)
0 1 2 3 4
>>>
Gerade dieses letzte Beispiel gibt die Standardanweisung für die for-Schleife wieder.
range kann dabei nicht nur ein Limit setzen, sondern allgemein in drei Varianten
verwendet werden: range(stop), range(start, stop), range(start, stop, step). Im
folgenden Beispiel wird 36 mal ein Quadrat gezeichnet. Der Winkel der Turtle wird
bei jedem Schleifenaufruf um 10 Grad verändert. Außerdem werden zwei Werte an
die Funktion übergeben: seite und farbe, und es gibt einen neuen Befehl tracer(n).
tracer(0) schaltet die Turtle aus (sie ist nicht mehr sichtbar) und tracer(1) schaltet sie
wieder ein. Die Zeichengeschwindigkeit wird damit in Programmen (bei denen es
nicht darauf ankommt, die Turtle zu beobachten) deutlich erhöht.
from turtle import *
def quadrat(seite,farbe):
color(farbe)
for i in range(4):
forward(seite)
left(90)
winkel=0
tracer(0)
for i in range(36):
quadrat(100,"red")
winkel=winkel+10
setheading(winkel)
Neben dem Quadrat gibt es noch eine große Anzahl von n-Ecken. In n_ecken sind
die Innenwinkel und die Seitenlängen immer gleich: Im Quadrat hat man vier Winkel
mit jeweils 90 Grad, die Kantenlänge ist beliebig, aber bei allen vier Seiten gleich
groß. Der Drehwinkel betrug 90 Grad. Im gleichseitigen Dreieck beträgt der
Drehwinkel 120 Grad, im Fünfeck 72 Grad. Allgemein gilt: der Drehwinkel der Turtle
beträgt bei einem n-Eck 360/n Grad. Das folgende Programm zeichnet beliebige nEcke. Die Anzahl der Ecken muss jeweils eingetragen werden.
from turtle import *
def n_eck(seite,anzahl):
drehwinkel=360/anzahl
for i in range(anzahl):
forward(seite)
left(drehwinkel)
n_eck(60,5)
Das folgende Programm ist zum Probieren:
from turtle import *
def n_eck(seite,anzahl,breite,stiftfarbe,fuellfarbe):
width(breite)
color(stiftfarbe)
begin_fill()
for i in range(anzahl):
forward(seite)
left(360/anzahl)
color(fuellfarbe)
end_fill()
winkel=0
eck=7
stiftbreite=3
wiederholung=6
speed("fast")
for i in range(wiederholung):
n_eck(100,eck,stiftbreite,"blue","yellow")
winkel=winkel+360/wiederholung
setheading(winkel)
Wie oben schon erwähnt wurde, kann die expression_list auch aus einer Liste
bestehen. Im folgenden Beispiel sollen Quadrate verschiedener Seitenlänge
mehrmals gezeichnet werden: siebenmal ein Quadrat mit der Seitenlänge 90,
siebenmal eines mit der Seitenlänge 70 und siebenmal eines mit der Seitenlänge 40.
Des weiteren soll nach jedem Durchgang Randfarbe und Blattfarbe gewechselt
werden. Wie funktioniert das? Unter Python ist die folgende Anweisung zulässig:
>>> x,y=y,x
Zwei Variablen können miteinander getauscht werden. Dieses Tauschen von Werten
soll etwas erläutert werden.
>>>
>>>
>>>
10
>>>
20
x=10
y=20
x
y
Dieses Verhalten von Python ist normal.
>>> x,y
(10, 20)
Python kann aber auch die Werte dieser Variablen in einer Anweisung in einem
Tupel ausgeben (Tupel sind an der runden Klammer erkennbar). Die Sprache erlaubt
auch die gleichzeitige Zuweisung an mehrere Variablen:
>>> x,y=10,20
>>> x
10
>>> y
20
>>> x,y
(10, 20)
>>> y,x
(20, 10)
>>> x,y=y,x
>>> x,y
(20,10)
>>> y,x
(10, 20)
Die Anweisung für das Zeichnen der Quadrate soll wie folgt aussehen: n_eck([90,
70,40], 4, 7, 3, “blue“, “pink“). 90, 70 und 40 sind die gewünschten Seitenlängen, 4
steht für Viereck, 7 für die gewünschte Anzahl, 3 für die Strichstärke, blue und pink
für Rand- bzw. Füllfarbe.
from turtle import *
def n_eck(seitenliste, eckenzahl, wiederholungen, breite, stiftfarbe,
fuellfarbe):
width(breite)
color(stiftfarbe)
winkel=0
for seite in seitenliste:
for i in range(wiederholungen):
begin_fill()
for i in range(eckenzahl):
forward(seite)
left(360/eckenzahl)
color(fuellfarbe)
end_fill()
winkel=winkel+360/wiederholungen
setheading(winkel)
color(stiftfarbe)
stiftfarbe,fuellfarbe=fuellfarbe, stiftfarbe
n_eck([90,70, 40],4,7,3,"green","yellow")
WHILE-Schleife
Es soll ein Würfelprogramm entwickelt werden. Im vorigen Abschnitt wurde die FORSchleife vorgestellt. Mit Hilfe dieser Schleife soll ein Programm formuliert werden,
dass dreimal eine beliebige Zahl würfeln soll. Anschließend soll die Summe der drei
Würfe ausgegeben werden. Zum Erzeugen von Zufallszahlen stellt Python ein
eigenes Modul random zu Verfügung. Aus diesem Modul wird die Funktion
randrange benötigt. randrange(n) erzeugt Zufallszahlen im Bereich von 0 bis n-1.
randrange(6) erzeugt die Würfelzahlen 0 bis 5. Die Befehlszeile
wurf=randrange(6)+1 sorgt dafür, dass die richtigen Zahlen von 1 bis 6 gespeichert
werden.
from random import randrange
summe=0
print ("Folgende Ergebnisse wurden erzielt:",end=“ “)
for i in range(3):
wurf=randrange(6)+1
print (wurf,)
summe=summe+wurf
print ()
print ("Summe aller Würfe:", summe)
Die Aufgabe wird nun abgewandelt. Es soll solange gewürfelt werden, bis eine 6
gewürfelt wird. Die Würfe sollen angezeigt werden und die Summe aller Würfe
ausgegeben werden. Das obige Programm wird etwas verändert:
from random import randrange
summe=0
wurf=0
print ("Folgende Ergebnisse wurden erzielt:",end=““)
while wurf<6:
wurf=randrange(6)+1
print (wurf,end=““)
summe=summe+wurf
print ()
print ("Summe aller Würfe:", summe)
Natürlich lassen sich while-Scheifen auch in der Turtle-Graphik verwenden. Das
folgende Beispiel berechnet die Werte für eine Polygonspirale und zeichnet sie.
Beispiel:Polygonspirale
from turtle import *
def spirale(winkel, zuwachs):
maxstrecke=250.0
strecke=1.0
while strecke < maxstrecke:
forward(strecke)
left(winkel)
strecke=strecke+zuwachs
spirale(154,1.5)
Bei einer while-Schleife wird vor Eintritt in den Schleifenkörper geprüft, ob die
Bedingung für die Schleife erfüllt ist. Wenn ja, wird anschließend die Schleife so oft
durchlaufen, bis die Bedingung erfüllt wird. Es ist beim Programmieren aber darauf
zu achten, dass sich das Programm nicht in einer Schleife aufhängt.
Python bietet zwei Möglichkeiten, Schleifendurchläufe abzubrechen. Die breakAnweisung beendet einen Schleifendurchlauf vorzeitig. Ein Beispiel:
from random import randrange
zu_ratende_zahl=randrange(1024)+1
ratezahl=0
while ratezahl != zu_ratende_zahl:
ratezahl=input("Raten Sie: ")
if ratezahl>zu_ratende_zahl:
print ("Zahl ist zu groß")
else:
print ("Zahl ist zu klein")
if ratezahl==0:
print ("Das Spiel wird abgebrochen")
break
else:
print ("Sie haben es geschafft")
Die continue-Anweisung bricht im Gegensatz zu break nicht die gesamte Schleife
ab, sondern nur den aktuelle Schleifendurchlauf.
Zur näherungsweisen Berechnung der Quadratwurzel aus einer Zahl a gibt es das
folgende Verfahren, das nach Heron von Alexandrien (ca. 60 n.Chr.) benannt ist.
- Wähle eine Zahl a.
- Halbiere die Zahl a und nenne das Ergebnis b.
- Dividiere die Zahl a durch die Zahl b und nenne das Ergebnis c.
- Solange (c – b) * (c - b) > 0.00000001 tue
- Addiere zu der Zahl b die Zahl c und nenne die Hälfte der Summe b.
- Dividiere die Zahl a durch die Zahl b und nenne das Ergebnis c.
- Drucke die Zahl c.
Programmtechnisch sieht das Verfahren wie folgt aus:
from math import sqrt
a=float(raw_input("Bitte eine Zahl eingeben: "))
b=a/2
c=a/b
while (c-b)*(c-b)>0.00000001:
b=(b+c)/2
c=a/b
print ("Heron-Wurzel: ",c)
print ("Wurzel mit Funktion SQRT: ",sqrt(a))
Aufgaben 5
1. Alle natürlichen Zahlentrippel (a, b, c) mit a²+b²=c² heißen pythagoreische
Zahlentrippel. Es ist ein Programm zu erstellen, das nach Eingabe einer Zahl n>=2
alle solchen Zahlentrippel (a, b, c) ausgibt mit a<b<c für alle c<=n.
2. Schreibe ein Programm, das alle Möglichkeiten ausgibt und die Anzahl der
Möglichkeiten zählt, wie man einen Geldbetrag in € mit 0,10 €, 0,20 €, 0,50 €, 1 €
und 2 € Stücken begleichen kann.
3. Umrechnung römischer Zahlen ins Dezimalsystem: Eine Zahl, die im römischen
System geschreiben ist (z.B. XXIV) ist ins Dezimalsystem zu übersetzen und
umgekehrt. Fehlerhaft geschriebene römische Zahlen sind zurückzuweisen. Es
dürfen höchstens 3 gleiche Zeichen hintereinander stehen (außer bei M = 1000). Zur
Subtraktion dürfen nur I, X, C benutzt werden, und zwar darf I nur vor V und X
stehen, X nur vor L und C, C nur vor D und M. Z.B.: 99 XCIX, 39 XXXIX, 40 XL.
4. Spieler A merkt sich eine beliebige Zahl, die kleiner ist als g (z.B. g=1000). Sein
Gegenspieler B hat diese durch möglichst wenige Fragen der Art: „Ist die Zahl im
Intervall [a,b]?“ herauszufinden. A ist der Computer. Ein Zufallszahlengenerator bildet
eine beliebige Zahl <= g. Der Spieler B gibt eine obere und untere Schranke an,
zwischen denen er die Zahl vermutet. Der Computer sagt ja oder nein und zählt die
Fragen. Schreibe ein Programm.
5. Es ist ein Programm zu schrieben, das eine ganze, höchstens 9-stellige Zahl in
Worten schreibt.
6. Die Dauer einer weniger als 24 Stunden dauernden Reise ist zu berechnen bei
gegebener Abfahrts- und Ankunftszeit. Die Zeitangaben sollen in drei- bzw.
vierstelligen Ziffern eingegeben werden (z.B. 1445). Nach der Eingabe der beiden
Zahlen soll die Korrektheit der Angaben geprüft werden (z.B. sollen 179 oder 2617
zurückgewiesen werden.
Wahr oder Falsch
In Python gibt es den Datentyp bool für logische Wahrheitswerte. Sie werden durch
die Literale True und False repräsentiert. Dabei ist unbedingt auf die Schreibweise
zu achten. Die logischen Verknüpfungen and, not und or sind bereits aus den ifAnweisungen bekannt. Mit Boolschen Variablen lassen sich auch for-Schleifen
bilden.
Beispiel: Es soll eine Wahrheitstafel für die Konjunktion ausgedruckt werden.
print "
A
B
A und B"
print "-------------------------"
for a in [False,True]:
for b in [False,True]:
c = a and b
if a:
print ("wahr ",end=”
else:
print ("falsch",end=“
if b:
print ("wahr ",end=“
else:
print ("falsch",end=“
if c:
print ("wahr ",end=“
else:
print ("falsch",end=“
print
“)
“)
“)
“)
“)
“)
Beispiel: Michaela schreibt Einladungen für ihre Geburtstagsfeier. Sie möchte
möglichst viele ihrer Freundinnen einladen. Dabei gibt es nur einige Probleme: Silvia
hatte Streit mit Monika und will auf keinen Fall kommen, wenn Monika eingeladen
wird. Karin und Annette sind unzertrennliche Freundinnen und nur im Doppelpack
erhältlich: entweder kommen beide oder beide nicht. Beate, Monika und Karin sollen
auch nicht zusammen eingeladen werden, sondern nur zwei von den dreien. Wenn
muss Michaela nun einladen, damit das Haus voll wird?
for silvia in [False,True]:
for monika in [False,True]:
for karin in [False,True]:
for annette in [False,True]:
for beate in [False,True]:
a=not monika or not silvia
b=(karin and annette) or (not karin and not annette)
c=(beate and monika and not karin) or \
(beate and not monika and karin) or \
(not beate and monika and karin)
d=a and b and c
if d:
if silvia:
print "Silvia ",
if monika:
print "Monika ",
if karin:
print "Karin ",
if annette:
print "Annette ",
if beate:
print "Beate ",
print
Aufgabe 6
1. Drucke eine Wahrheitstafel für die Disjunktion.
2. Drucke eine Wahrheitstafel für die Subjunktion.
Funktionen mit Rückgabe
Programme werden durch Funktionen sehr übersichtlich. Außerdem haben sie den
Vorteil, dass sie mehrfach aufgerufen werden können. Der Programmierumfang
eines Programms lässt sich damit deutlich reduzieren. In den bisherigen Beispielen
haben die Funktionen Werte aus dem Hauptprogramm übernommen und verarbeitet.
Oft ist es jedoch nötig, dass innerhalb einer Funktion ein Wert berechnet werden soll,
der anschließend vom Hauptprogramm wieder benutzt werden muss.
Beispiel: Es soll der ggT und das kgV zweier Zahlen berechnet werden. Zur
Berechnung des kgV wird der ggT benötigt. Der ggT lässt sich wie folgt berechnen:
Ein Teiler von a und b ist auch ein Teiler von a-b bzw. b-a. Mit diesem Satz gilt
ggT(a,b)=ggT(a-b),b) für a>b, ggT(a,b)=a für a=b und ggT(a,b)=ggT(a,b-a) für a<b.
Setzt man dies programmtechnisch um, erhält man die folgende Funktion:
def ggt(a,b):
while a!=b:
if a>b:
a=a-b
else:
b=b-a
return a
print ggt(92,69)
Das kgV berechnet sich nach der Formel kgV(a,b)=a*b/ggT(a,b). Das Programm wird
um die benötigten Programmzeilen erweitert.
def ggt(a,b):
while a!=b:
if a>b:
a=a-b
else:
b=b-a
return a
def kgv(a,b):
wert=a*b/ggt(a,b)
return wert
zahl1=int(input("1. Zahl: "))
zahl2=int(input("2. Zahl: "))
print ("ggt: ",ggt(zahl1,zahl2))
print ("kgV: ",kgv(zahl1,zahl2))
Ein weiteres Beispiel stammt aus der Bruchrechnung. Zwei Brüche sollen addiert
werden. Dazu muss zuerst der Hauptnenner gebildet werden. Anschließend werden
die Brüche erweitert und dann die Zähler addiert. Zuletzt werden Zähler und Nenner
gekürzt. Das Ergebnis wird ausgegeben.
def ggt(a,b):
while a != b:
if a>b:
a=a-b
else:
b=b-a
return a
def kgv(a,b):
c=(a*b)/ggt(a,b)
return c
def erw(a,b,c):
d=a*(c // b)
return d
def add(a,b):
c=a+b
return c
def kuerze(a,b):
c=a // b
return c
def ausgabe(a,b,c,d,e,f):
print ("%4i" % a, "
","%4i" % c,"
print "------ + ------ = ------"
print ("%4i" % b, "
","%4i" % d,"
","%4i" % e)
","%4i" % f)
zaehler1=int(input("1. Zaehler: "))
nenner1=int(input("1. Nenner: "))
zaehler2=int(input("2. Zaehler: "))
nenner2=int(input("2. Nenner: "))
gemn=kgv(nenner1,nenner2)
neuz1=erw(zaehler1,nenner1,gemn)
neuz2=erw(zaehler2,nenner2,gemn)
sumz=add(neuz1,neuz2)
kuerz=ggt(gemn,sumz)
endz=kuerze(sumz,kuerz)
endn=kuerze(gemn,kuerz)
ausgabe(zaehler1,nenner1,zaehler2,nenner2,endz,endn)
In Python lassen sich Ausgabewerte mit dem Formatierungsoperator % und einem
Formatierungsstring formatieren. Das allgemeine Format einer solchen printAnweisung lautet:
print formatierungsstring % wert
Der Formatierungsstring muss in Anführungsstrichen stehen. Er besteht (vereinfacht)
aus dem Zeichen %, einer (optionalen) Angabe der Stellenzahl, (optional) einem
Punkt gefolgt von der Anzahl der dargestellten Zeichen des Wertes bzw. bei
Gleitkommazahlen der Anzahl der Nachkommastellen und einem Buchstaben, der
das Datenformat kennzeichnet: i für ganze Zahlen, f für Dezimalzahlen, s für Strings.
Die Angabe “%4i“ % a druckt eine Ganzzahl a mit der Feldweite 4. Interessant ist der
formatierte Ausdruck vor allem in Tabellen.
Rekursion
In der Informatik taucht sehr häufig ein Begriffspaar auf: Iteration und Rekursion.
Programme lassen sich in der Regel sowohl iterativ als auch rekursiv formulieren. Ein
klassischer Fall ist die Berechnung der Fakultät. Unter der Fakultät einer natürlichen
Zahl n versteht man das Produkt n*(n-1)*(n-2)*(n-3)*...*3*2*1 (5!=120).
def fakultaet_iterativ(n):
fakultaet = 1
faktor = 2
while faktor <= n:
fakultaet = fakultaet * faktor
faktor = faktor + 1
return fakultaet
n=int(raw_input("Fakultaet von:"))
print fakultaet_iterativ(n)
def fakultaet_rekursiv(n):
if n <= 1:
return 1
else:
return ( n * fakultaet_rekursiv(n-1) )
n=int(input("Fakultaet von:"))
print (fakultaet_rekursiv(n))
Die Iteration arbeitet mit Schleifen, die Rekursion mit Verzweigungen. Eine Funktion
heißt rekursiv, wenn sie sich in ihrem Anweisungsteil selbst aufruft. Es gibt aber viele
Programmiersituationen, bei denen ein rekursive Programmierung wesentlich
einfacher ist als eine iterative bzw. bei denen eine äquivalente iterative Lösung nicht
so leicht zu finden ist. Ein Beispiel ist die Konstruktion von Binärbäumen. Unter
einem binären Baum versteht man eine Verzweigungsstruktur (Baum) mit der
Eigenschaft, dass an jeder Gabelung zwei neue Zweige hervorsprießen. Binäre
Bäume haben folgende rekursive Struktur: Entweder ist der Baum leer, oder er
besteht aus einem linken Teilbaum, einem Stamm und einem rechten Teilbaum.
Damit bietet sich folgendes Verfahren an:
zeichne ganzen Baum:
zeichne Stamm
zeichne links kleineren ganzen Baum
zeichne rechts kleineren ganzen Baum
kehre zum Fußpunkt des Stamms zurück
Wie sieht der Baum aber aus? Die Äste sind kleiner als der Stamm und sie stehen in
einem bestimmten Winkel zueinander. Außerdem muss der Baum ein Ende haben.
Dies führt zur folgender Funktion:
def baum(stufe,stamm,winkel,faktor):
if stufe < 1:
return
# Rücksprung in die aufrufende Funktion
forward(stamm)
# linker Teilbaum
left(winkel)
baum(stufe-1,faktor* stamm,winkel,faktor)
right(winkel)
# rechter Teilbaum
right(winkel)
baum(stufe-1,faktor * stamm,winkel,faktor)
left(winkel)
# zurück
backward(stamm)
Das komplette Programm sieht wie folgt aus:
from turtle import *
def baum(stufe,stamm,winkel,faktor):
if stufe < 1:
return
forward(stamm)
left(winkel)
baum(stufe-1,faktor* stamm,winkel,faktor)
right(winkel)
right(winkel)
baum(stufe-1,faktor * stamm,winkel,faktor)
left(winkel)
backward(stamm)
up()
goto(0,-200)
left(90)
down()
baum(8,200,45,0.5)
Eine rekursive Funktion hat in der Regel folgende Gestalt:
def arbeite_rekursiv:
if <Abbruchbedingung>:
<Anweisung1>
else:
<Anweisung2>
arbeite_rekursiv
<Anweisung3>
Anweisung 1 ist der direkte Fall der Rekursion und die else-Anweisungen sind der
Rekursionsfall. Wenn Anweisung 1 eine leere Anweisung ist, kann man auch mit
einer einseitigen Verzweigung arbeiten (siehe Beispiel). Entscheidend ist, dass
Anweisung 2 nach endlich vielen Schritten zu einer Abbruchsbedingung führt.
Anweisung 3 kann leer sein.
Objekte und Methoden
Bei der Turtle-Programmierung wurden Befehle wie forward, backward, left oder right
benutzt. Mit diesen Befehlen (Methoden) konnte eine Turtle (Objekt) gesteuert
werden. Objekte werden nach einem Bauplan erzeugt, der Klasse oder der
Klassendefiniton. Die Klasse, die Turtles erzeugen kann, heißt Pen. Um selber
Turtle-Objekte zu produzieren, muss man den Klassennamen aus dem Modul turtle
importieren. Dies geschieht durch die Anweisung
from turtle import Pen
Um jetzt eine Turtle zu produzieren, wird ein Name für das neue Turtle-Objekt
benötigt. Eine einfache Zuweisung ermöglicht dies:
axel = Pen()
Für ein Projekt Polyturtle werden vier Turtles benötigt. Also werden noch drei weitere
Objekt erzeugt:
bert = Pen()
cico = Pen()
dino = Pen()
Wie kann man die vier Turtles jetzt steuern? Im Gegensatz zu den bisherigen TurtleProgrammen wurde nur die Klasse Pen importiert. Mithilfe der Anweisung
name=Pen() wurden vier Objekte erzeugt. Jedes Objekt hat nun eigene Methoden
(Befehle), die objektgebunden aufgerufen werden müssen. Dies erfolgt durch den
Methodenaufruf objektname.methodenname(arg1, arg2...).
Beispiel: Die vier Turtles sollen unterschiedliche Farben erhalten und sollen am
Ausgangspunkt unterschiedliche Ausgangsrichtungen erhalten. Anschließend sollen
alle vier ein gleichseitiges Dreieck zeichnen.
from turtle import Pen
alex=Pen()
bert=Pen()
cico=Pen()
dino=Pen()
alex.setheading(0)
alex.color("blue")
bert.setheading(90)
bert.color("green")
cico.setheading(180)
cico.color("red")
dino.setheading(270)
dino.color("black")
kroeten=[alex,bert,cico,dino]
for i in kroeten:
i.left(30)
i.forward(60)
i.right(120)
i.forward(60)
i.right(120)
i.forward(60)
Vereinbarungsgemäß werden Klassenbezeichner mit einem Großbuchstaben
begonnen, Objekte mit einem Kleinbuchstaben.
Polyturtle
Eine Polyturtle ist ein Gebilde, das aus mehreren unanbahängig voneinander
operierenden Turtles besteht. In dem folgenden Beispiel sitzen die Turtles in den
Ecken eines Quadrates. Auf ein Kommando hin starten sie zur Verfolgungsjagd; T1
läuft hinter T2, T2 hinter T3, T3 hinter T4 und T4 hinter T1 her.
from turtle import Pen
alex=Pen()
bert=Pen()
cico=Pen()
dino=Pen()
kroeten=[alex,bert,cico,dino]
alex.up()
alex.color("blue")
alex.goto(-200,-200)
alex.down()
bert.up()
bert.color("green")
bert.goto(200,-200)
bert.down()
cico.up()
cico.color("red")
cico.goto(200,200)
cico.down()
dino.up()
dino.color("black")
dino.goto(-200,200)
dino.down()
def spirale(zahl,faktor):
for i in range(zahl):
x0=alex.position()[0]+(bert.position()[0]alex.position()[0])*faktor
y0=alex.position()[1]+(bert.position()[1]alex.position()[1])*faktor
x1=bert.position()[0]+(cico.position()[0]bert.position()[0])*faktor
y1=bert.position()[1]+(cico.position()[1]bert.position()[1])*faktor
x2=cico.position()[0]+(dino.position()[0]cico.position()[0])*faktor
y2=cico.position()[1]+(dino.position()[1]cico.position()[1])*faktor
x3=dino.position()[0]+(alex.position()[0]dino.position()[0])*faktor
y3=dino.position()[1]+(alex.position()[1]dino.position()[1])*faktor
alex.goto(x0,y0)
bert.goto(x1,y1)
cico.goto(x2,y2)
dino.goto(x3,y3)
spirale(200,0.1)
Das Programm wird dahingehend verändert, dass zwischen der Position der
Schildkröte und ihres Ziels die Verbindungsstrecke gezeichnet wird.
from turtle import Pen,tracer
alex=Pen()
bert=Pen()
cico=Pen()
dino=Pen()
kroeten=[alex,bert,cico,dino]
for i in kroeten:
i.tracer(0)
alex.up()
alex.color("blue")
alex.goto(-200,-200)
alex.down()
bert.up()
bert.color("green")
bert.goto(200,-200)
bert.down()
cico.up()
cico.color("red")
cico.goto(200,200)
cico.down()
dino.up()
dino.color("black")
dino.goto(-200,200)
dino.down()
for i in range(100):
x0=alex.position()[0]+(bert.position()[0]-alex.position()[0])*0.05
y0=alex.position()[1]+(bert.position()[1]-alex.position()[1])*0.05
x1=bert.position()[0]+(cico.position()[0]-bert.position()[0])*0.05
y1=bert.position()[1]+(cico.position()[1]-bert.position()[1])*0.05
x2=cico.position()[0]+(dino.position()[0]-cico.position()[0])*0.05
y2=cico.position()[1]+(dino.position()[1]-cico.position()[1])*0.05
x3=dino.position()[0]+(alex.position()[0]-dino.position()[0])*0.05
y3=dino.position()[1]+(alex.position()[1]-dino.position()[1])*0.05
alex.goto(x0,y0)
alex.goto(x1,y1)
alex.goto(x0,y0)
bert.goto(x1,y1)
bert.goto(x2,y2)
bert.goto(x1,y1)
cico.goto(x2,y2)
cico.goto(x3,y3)
cico.goto(x2,y2)
dino.goto(x3,y3)
dino.goto(x0,y0)
dino.goto(x3,y3)
for i in kroeten:
i.tracer(1)
Das Programm lässt sich weiter abändern. T1 verfolgt im ersten Lauf T2, T2 T3 usw.
In einem zweiten Lauf verfolgt T1 T4, T4 T3 usw.
from turtle import Pen
alex=Pen()
bert=Pen()
cico=Pen()
dino=Pen()
kroeten=[alex,bert,cico,dino]
for i in kroeten:
i.tracer(0)
i.up()
alex.color("blue")
alex.goto(-200,-200)
bert.color("green")
bert.goto(200,-200)
cico.color("red")
cico.goto(200,200)
dino.color("black")
dino.goto(-200,200)
for i in kroeten:
i.down()
for i in range(4):
dino.forward(400)
dino.right(90)
for i in range(100):
x0=alex.position()[0]+(bert.position()[0]-alex.position()[0])*0.05
y0=alex.position()[1]+(bert.position()[1]-alex.position()[1])*0.05
x1=bert.position()[0]+(cico.position()[0]-bert.position()[0])*0.05
y1=bert.position()[1]+(cico.position()[1]-bert.position()[1])*0.05
x2=cico.position()[0]+(dino.position()[0]-cico.position()[0])*0.05
y2=cico.position()[1]+(dino.position()[1]-cico.position()[1])*0.05
x3=dino.position()[0]+(alex.position()[0]-dino.position()[0])*0.05
y3=dino.position()[1]+(alex.position()[1]-dino.position()[1])*0.05
alex.goto(x0,y0)
alex.goto(x1,y1)
alex.goto(x0,y0)
bert.goto(x1,y1)
bert.goto(x2,y2)
bert.goto(x1,y1)
cico.goto(x2,y2)
cico.goto(x3,y3)
cico.goto(x2,y2)
dino.goto(x3,y3)
dino.goto(x0,y0)
dino.goto(x3,y3)
for i in kroeten:
i.up()
alex.goto(-200,-200)
bert.goto(200,-200)
cico.goto(200,200)
dino.goto(-200,200)
for i in kroeten:
i.down()
for i in range(4):
dino.forward(400)
dino.right(90)
for i in range(100):
x0=alex.position()[0]+(dino.position()[0]-alex.position()[0])*0.05
y0=alex.position()[1]+(dino.position()[1]-alex.position()[1])*0.05
x1=bert.position()[0]+(alex.position()[0]-bert.position()[0])*0.05
y1=bert.position()[1]+(alex.position()[1]-bert.position()[1])*0.05
x2=cico.position()[0]+(bert.position()[0]-cico.position()[0])*0.05
y2=cico.position()[1]+(bert.position()[1]-cico.position()[1])*0.05
x3=dino.position()[0]+(cico.position()[0]-dino.position()[0])*0.05
y3=dino.position()[1]+(cico.position()[1]-dino.position()[1])*0.05
alex.goto(x0,y0)
alex.goto(x1,y1)
alex.goto(x0,y0)
bert.goto(x1,y1)
bert.goto(x2,y2)
bert.goto(x1,y1)
cico.goto(x2,y2)
cico.goto(x3,y3)
cico.goto(x2,y2)
dino.goto(x3,y3)
dino.goto(x0,y0)
dino.goto(x3,y3)
Es muss aber nicht immer ein Quadrat
mit 4 Turtles sein; man kann auch
andere
geometrische
Figuren
benutzen und eine andere Anzahl von
Turtles.
from turtle import Pen,tracer
alex=Pen()
bert=Pen()
cico=Pen()
dino=Pen()
edda=Pen()
fine=Pen()
kroeten=[alex,bert,cico,dino,edda,fine]
alex.color("blue")
bert.color("green")
cico.color("red")
dino.color("black")
edda.color("yellow")
fine.color("gold")
for i in kroeten:
i.tracer(0)
def ausgangspunkt():
winkel=0
for i in kroeten:
i.up()
winkel=winkel+60
i.left(winkel)
i.forward(200)
i.down()
ausgangspunkt()
for i in range(100):
x0=alex.position()[0]+(bert.position()[0]-alex.position()[0])*0.05
y0=alex.position()[1]+(bert.position()[1]-alex.position()[1])*0.05
x1=bert.position()[0]+(cico.position()[0]-bert.position()[0])*0.05
y1=bert.position()[1]+(cico.position()[1]-bert.position()[1])*0.05
x2=cico.position()[0]+(dino.position()[0]-cico.position()[0])*0.05
y2=cico.position()[1]+(dino.position()[1]-cico.position()[1])*0.05
x3=dino.position()[0]+(edda.position()[0]-dino.position()[0])*0.05
y3=dino.position()[1]+(edda.position()[1]-dino.position()[1])*0.05
x4=edda.position()[0]+(fine.position()[0]-edda.position()[0])*0.05
y4=edda.position()[1]+(fine.position()[1]-edda.position()[1])*0.05
x5=fine.position()[0]+(alex.position()[0]-fine.position()[0])*0.05
y5=fine.position()[1]+(alex.position()[1]-fine.position()[1])*0.05
alex.goto(x0,y0)
alex.goto(x1,y1)
alex.goto(x0,y0)
bert.goto(x1,y1)
bert.goto(x2,y2)
bert.goto(x1,y1)
cico.goto(x2,y2)
cico.goto(x3,y3)
cico.goto(x2,y2)
dino.goto(x3,y3)
dino.goto(x4,y4)
dino.goto(x3,y3)
edda.goto(x4,y4)
edda.goto(x5,y5)
edda.goto(x4,y4)
fine.goto(x5,y5)
fine.goto(x0,y0)
fine.goto(x5,y5)
ausgangspunkt()
for i in range(100):
x0=alex.position()[0]+(fine.position()[0]-alex.position()[0])*0.05
y0=alex.position()[1]+(fine.position()[1]-alex.position()[1])*0.05
x1=bert.position()[0]+(alex.position()[0]-bert.position()[0])*0.05
y1=bert.position()[1]+(alex.position()[1]-bert.position()[1])*0.05
x2=cico.position()[0]+(bert.position()[0]-cico.position()[0])*0.05
y2=cico.position()[1]+(bert.position()[1]-cico.position()[1])*0.05
x3=dino.position()[0]+(cico.position()[0]-dino.position()[0])*0.05
y3=dino.position()[1]+(cico.position()[1]-dino.position()[1])*0.05
x4=edda.position()[0]+(dino.position()[0]-edda.position()[0])*0.05
y4=edda.position()[1]+(dino.position()[1]-edda.position()[1])*0.05
x5=fine.position()[0]+(edda.position()[0]-fine.position()[0])*0.05
y5=fine.position()[1]+(edda.position()[1]-fine.position()[1])*0.05
alex.goto(x0,y0)
alex.goto(x1,y1)
alex.goto(x0,y0)
bert.goto(x1,y1)
bert.goto(x2,y2)
bert.goto(x1,y1)
cico.goto(x2,y2)
cico.goto(x3,y3)
cico.goto(x2,y2)
dino.goto(x3,y3)
dino.goto(x4,y4)
dino.goto(x3,y3)
edda.goto(x4,y4)
edda.goto(x5,y5)
edda.goto(x4,y4)
fine.goto(x5,y5)
fine.goto(x0,y0)
fine.goto(x5,y5)
for i in kroeten:
i.tracer(1)
Man kann seiner Phantasie freien Lauf lassen.
from turtle import Pen,setup
setup(width=800,height=800,startx=None,starty=None)
alex=Pen()
bert=Pen()
cico=Pen()
dino=Pen()
alex.color("blue")
bert.color("green")
cico.color("red")
dino.color("black")
kroeten=[alex,bert,cico,dino]
def bild1():
for i in range(100):
x0=alex.position()[0]+(bert.position()[0]-alex.position()[0])*0.05
y0=alex.position()[1]+(bert.position()[1]-alex.position()[1])*0.05
x1=bert.position()[0]+(cico.position()[0]-bert.position()[0])*0.05
y1=bert.position()[1]+(cico.position()[1]-bert.position()[1])*0.05
x2=cico.position()[0]+(dino.position()[0]-cico.position()[0])*0.05
y2=cico.position()[1]+(dino.position()[1]-cico.position()[1])*0.05
x3=dino.position()[0]+(alex.position()[0]-dino.position()[0])*0.05
y3=dino.position()[1]+(alex.position()[1]-dino.position()[1])*0.05
alex.goto(x0,y0)
alex.goto(x1,y1)
alex.goto(x0,y0)
bert.goto(x1,y1)
bert.goto(x2,y2)
bert.goto(x1,y1)
cico.goto(x2,y2)
cico.goto(x3,y3)
cico.goto(x2,y2)
dino.goto(x3,y3)
dino.goto(x0,y0)
dino.goto(x3,y3)
def bild2():
for i in range(100):
x0=alex.position()[0]+(dino.position()[0]-alex.position()[0])*0.05
y0=alex.position()[1]+(dino.position()[1]-alex.position()[1])*0.05
x1=bert.position()[0]+(alex.position()[0]-bert.position()[0])*0.05
y1=bert.position()[1]+(alex.position()[1]-bert.position()[1])*0.05
x2=cico.position()[0]+(bert.position()[0]-cico.position()[0])*0.05
y2=cico.position()[1]+(bert.position()[1]-cico.position()[1])*0.05
x3=dino.position()[0]+(cico.position()[0]-dino.position()[0])*0.05
y3=dino.position()[1]+(cico.position()[1]-dino.position()[1])*0.05
alex.goto(x0,y0)
alex.goto(x1,y1)
alex.goto(x0,y0)
bert.goto(x1,y1)
bert.goto(x2,y2)
bert.goto(x1,y1)
cico.goto(x2,y2)
cico.goto(x3,y3)
cico.goto(x2,y2)
dino.goto(x3,y3)
dino.goto(x0,y0)
dino.goto(x3,y3)
def ausgang(a,b,c):
for i in kroeten:
i.tracer(0)
i.up()
alex.goto(-b,-b+c)
bert.goto(a,-b+c)
cico.goto(a,a+c)
dino.goto(-b,a+c)
for i in kroeten:
i.down()
ausgang(0,400,0)
bild1()
ausgang(0,400,0)
bild2()
ausgang(400,0,0)
bild1()
ausgang(400,0,0)
bild2()
ausgang(0,400,400)
bild1()
ausgang(0,400,400)
bild2()
ausgang(400,0,-400)
bild1()
ausgang(400,0,-400)
bild2()
Strings, Tupels und Listen
Python stellt eine Klasse von Datentypen zur Verfügung, mit der Folgen von
gleichartigen oder verschiedenen Elementen verwaltet werden können. Diese
sequentiellen Datentypen sind str (und unicode), list und tuple (Strings, Listen und
Tupels). Beispiele für Listen, Tupels und Strings sind:
>>>
>>>
>>>
>>>
>>>
>>>
listeA
listeB
listeC
listed
tupelA
tupelB
=
=
=
=
=
=
[3 ,4, 5, 5.5, 6]
[“red“, “yellow“, “green“]
[1, [2, 3], [4, [5, 6]]]
[ ]
(1, 3)
(1, (2,3), “hallo”, [ ])
>>> tupelC = (“Fritz”,)
>>> tupelD = ( )
>>> stringA = “X”
>>> stringB = “Hallo Welt”
>>> stringC = “”
Beim Erzeugen durch Anschreiben unterscheiden sich Tupel und Listen nur durch
die Art der Klammer. In einem einelementigen Tupel muss nach dem einzigen
Element ein Komma gesetzt werden, damit es von Klammerausdrücken
unterschieden werden kann. Der wesentliche Unterschied zwischen den beiden fast
identischen Datypen ist, dass eine Liste nach der Erzeugung verändert werden kann,
während ein Tupel keine Änderung des Anfangsinhalts zulässt: list ist mutable, tuple
ist immutable.
Für alle Sequenzen gibt es neben unterschiedlichen auch gemeinsame Operatoren.
Anhand des Datentyps str sollen die gemeinsamen Operatoren erläutert werden:
1. x in s: Es wird geprüft, ob x in s enthalten ist. Das Ergebnis ist vom Typ bool.
>>> s = “Python ist eine Skriptsprache“
>>> “y“ in s
True
>>> s=[1,2,3,4,5,6]
>>> 5 in s
True
2. x not in s: Es wird geprüft, ob x nicht in s enthalten ist.
>>> s = “Python ist eine Skriptsprache“
>>> “y“ not in s
False
>>> s=[1,2,3,4,5,6]
>>> 3.5 not in s
True
3. s + t: Das Ergebnis ist eine neue Sequenz.
>>> s = “Hallo“
>>> t = “Welt“
>>> s+t
’Hallo Welt’
4. s += t: Erzeugt eine Verkettung von s und t und weist sie s zu.
>>> s = “Volks“
>>> s += “wagen“
>>> s
’Volkswagen’
5. s *= n: Erzeugt das Produkt von s * n und weist es s zu.
>>> s = “SOS “
>>> s *= 3
>>> s
’SOS SOS SOS’
6. s[i]: Liefert das i-te Element von s
>>> s = “Sylt“
>>> s[1]
’y’
>>> s[-1]
‘t’
Man beachte die Zählweise der Indizes. Das erste Element von links hat den Index 0.
7. s[i:j]: Liefert den Ausschnitt aus s von i bis j.
>>> s = “Ameisen“
>>> s[1:6]
‘meise’
8. len(s): Gibt die Anzahl der Elemente von s an.
>>> s = “Wie lang ist dieser Satz“
>>> len(s)
24
9. min(s): Liefert das kleinste Element von s, sofern eine Ordnungsrelation für die
Elemente definiert ist, z.B. Alphabet.
>>>
>>>
‘G’
>>>
>>>
‘e’
s=“Geometrie“
min(s)
s=”geometrie”
min(s)
Beim Vergleich von Groß- und Kleinbuchstaben untereinander
Kleinbuchstaben immer größer: „a“ ist kleiner „z“ aber größer „Z“.
gelten
>>> s=[4,2,6,3,9,8]
>>> min(s)
2
10. max(s): Liefert das größte Element von s.
Strings
String-Instanzen verfügen über Methoden, die den Umgang mit Zeichenketten
vereinfachen. Aufgrund der großen Anzahl von String-Methoden wird im folgenden
Text nur auf einzelne beispielhaft eingegangen.
Drei Chinesen mit dem Kontrabass...
Sicherlich kennt jeder den folgenden Kinderreim:
Drei Chinesen mit dem Kontrabass
sitzen auf der Strasse und erzaehlen sich was.
Da kommt die Polizei und fragt:
Wass ist denn das?
Drei Chinesen mit dem Kontrabass!
Die anderen Strophen sind der ersten Strophe recht ähnlich: Nur wird an Stelle der
verschiedenen Vokale immer derselbe Vokal gesungen.
stringA="Drei Chinesen mit dem Kontrabass"
stringB="sitzen auf der Strasse und erzaehlen sich was."
stringC="Da kommt die Polizei und fragt:"
stringD="Was ist denn das?"
vokal=input("Gib einen Vokal an: ")
for i in (stringA, stringB, stringC, stringD, stringA):
for j in("a","A","e","E","i","I","o","O","u","U"):
i=i.replace(j,vokal)
print (i)
Wie oft kommt im Originaltext der Buchstabe „D“ vor? Dabei ist es egal, ob der
Buchstabe klein oder groß geschrieben wird.
stringA="Drei Chinesen mit dem Kontrabass"
stringB="sitzen auf der Strasse und erzaehlen sich was."
stringC="Da kommt die Polizei und fragt:"
stringD="Was ist denn das?"
zahl=0
buchstabe=input("Welcher Buchstabe soll ueberprueft werden? ")
buchstabe.upper()
for i in (stringA, stringB, stringC, stringD, stringA):
i.upper()
zahl=zahl+i.count(buchstabe)
print zahl
Folgende Methoden dienen zum Suchen von Teilstrings:
s.find(Teilstring[,start[,ende]])
>>>
>>>
8
>>>
-1
>>>
-1
>>>
-1
>>>
8
s="Es lebe Delphi bei der Stringmanipulation"
s.find("Delphi")
s.find("Delphi",10,18)
s.find("Delphi",2,10)
s.find("Delphi",0,10)
s.find("Delphi",0,15)
s.count(Teilstring[,start[,ende]])
>>> s="Es lebe Delphi bei der Stringmanipulation"
>>> s.count("Delphi")
1
Folgende Methoden dienen zum Ersetzen von Teilstrings:
s.replace(alt,neu[,Anzahl])
>>>
>>>
'Es
>>>
s="Es lebe Delphi bei der Stringmanipulation"
s.replace("e","x")
lxbx Dxlphi bxi dxr Stringmanipulation'
s="Es lebe Delphi bei der Stringmanipulation"
>>> s.replace("e","x",4)
'Es lxbx Dxlphi bxi der Stringmanipulation'
s.lower()
>>> s="Es lebe Delphi bei der Stringmanipulation"
>>> s.lower()
'es lebe delphi bei der stringmanipulation'
s.upper()
>>> s.upper()
>>> s="Es lebe Delphi bei der Stringmanipulation"
'ES LEBE DELPHI BEI DER STRINGMANIPULATION'
Folgende Methoden dienen zum Entfernen von Zeichen am Anfang oder am Ende
von Strings:
s.strip([char])
s.lstrip([char])
>>> s="Risotto"
>>> s.lstrip("Ris")
'otto'
s.rstrip([char])
Tupel
Tupel sind unveränderliche Sequenzen. Man kann ein Element eines Tupels nicht mit
einem neuen Wert überschreiben. Außerdem sind für Tupel-Elemente keine
Methoden definiert.
Listen
Listen sind für die Verwaltung beliebiger Instanzen auch unterschiedlicher
Datentypen geeignet. Eine Liste kann Zahlen, Strings und auch weitere Listen
enthalten. Inhalte einer Liste lassen sich auch nach ihrer Erzeugung verändern.
Deshalb sind weitere Operatoren für diesen sequentiellen Datentyp vorhanden.
1. s[i]=x: Das Element von s mit dem Index i wird durch x ersetzt.
>>> s = [1,2,3,4,5,6]
>>> s[3] = 8
>>> s
[1,2,3,8,5,6]
2. s[I:j]=t: Der Teil s[I:j] wird durch t ersetzt.
>>> s=["rot","rot","rot"]
>>> s[1:3]=["gelb","gruen"]
>>> s
['rot', 'gelb', 'gruen']
3. del s[i]: Das i-te Element von s wird entfernt.
4. del s[i:j]: Die Elemente mit den Indizes i bis j werden gelöscht.
Beispiel: Eine Klassenarbeit brachte folgende Ergebnisse: 3 mal sehr gut, 6 mal gut,
9 mal befriedigend, 8 mal ausreichend, 4 mal mangelhaft und 1 mal ungenügend. Die
Noten sollen graphisch mit Hilfe von Sternenreihen veranschaulicht werden.
notenliste=[0,0,0,0,0,0]
j=1
for i in range(6):
notenliste[i]=int(raw_input("Haufigkeit der Note "+chr(i+1+48)+": "))
for i in range(6):
print "Note ",i+1,": ",
for j in range(notenliste[i]):
print "*",
print
Ein weiteres Beispiel stammt aus der Chemie. Was leistet das folgende Programm?
lauge=["Natronlauge","Kalilauge","Kalkwasser"]
saeure=["Salzsaeure","Schwefelsaeure","Salpetersaeure","Kohlensaeure"]
def schreiben(i,j):
#global lauge,saeure
if i==lauge[0]:
print "Natrium",
elif i==lauge[1]:
print "Kalium",
elif i==lauge[2]:
print "Calcium",
if j==saeure[0]:
print "chlorid + Wasser"
elif j==saeure[1]:
print "sulfat + Wasser"
elif j==saeure[2]:
print "nitrat + Wasser"
elif j==saeure[3]:
print "carbonat + Wasser"
for i in lauge:
for j in saeure:
print i+" + "+j," = ",
schreiben(i,j)
Neben den Operatoren existieren für Listen Methoden.:
1. s.append(x): Hängt x ans Ende von s an.
2. s.extend(t): Hängt alle Elemente einer Liste t ans Ende von s an.
3. s.count(x): Gibt an, wie oft das Element x in s vorkommt.
4. s.index(x[,i[,j]]): Gibt den Index des ersten Vorkommens von x im Bereich von
i<=k<j zurück.
5. s.insert(i,x): Fügt x an der Stelle i in s ein.
6. s.pop([i]): Gibt das i-te Element von s zurück und entfernt es aus s. Ist i nicht
angegeben, wird das letzte Element genommen.
7. s.remove(x): Entfernt das erste Vorkommen von x aus s.
8. s.reverse(): Kehrt die Reihenfolge der Elemente in s um.
9. s.sort(): Sortiert s.
Es folgen Beispiele für Listenmethoden.
Beispiel 1: Nach seiner Eingabe soll ein Wort in umgekehrter Lesart ausgegeben
werden, z.B. wird PYTHON zu NOHTYP.
wort=[ ]
w=""
while w!="#":
w=raw_input("Buchstabe: ")
if w!="#":
wort.append(w)
wort.reverse()
for i in wort:
print i.upper(),
Beispiel 2: Es sollen alle Primzahlen bis zu einer einzugebenden Zahl n ausgegeben
werden. Dies soll nach dem Verfahren „Sieb des Eratosthenes“ erfolgen.
sieb=[ ]
zahl=int(raw_input("Primzahlen bis n= "))
for i in range(zahl):
sieb.append(False)
for i in range(2,zahl):
if sieb[i]==False:
print i,
for j in range(zahl // i):
sieb[i*j]=True
Aufgabe 7
1. Es soll die Zahl der Tage des Monats und der Wochentag; auf den der 1. Tag des Monats fällt,
eingegeben werden. Auszudrucken ist ein Monatkalender in einer der beiden nachstehenden Formen:
MONTAG
5
12
MO DI MI DO FR SA SO
DIENSTAG
6
13
1 2 3 4 5
MITTWOCH
7
....
6 7 8 9 10 11 12
DONNERSTAG
1
8
FREITAG
2
9
SAMSTAG
3
10
SONNTAG
4
11
2. Es gibt verschiedene Methoden bei Proportionalwahlverfahren. Zwei davon sollen hier behandelt
und ihre Wirkung verglichen werden. Gegeben sind die Stimmenzahlen der Parteien und die Zahl der
zu vergebenden Sitze.
a) Verfahren nach d’Hondt: Die Parteistimmenzahlen werden nacheinander durch 1, 2 , 3 usw. geteilt.
Die Sitze werden nach der Größe dieser Teilzahlen der Reihe nach zugeteilt. Bei gleichen Teilzahlen
entscheidet das Los.
b) Verfahren nach Hagenbach – Bischoff: Die Gesamtstimmzahl wird durch die um 1 erhöhte Zahl der
Sitze geteilt und auf die nächste ganze Zahl aufgerundet. Die Sitzzahlen der Parteien erhält man,
indem man die Parteistimmenzahlen durch diesen Wahlquotienten teilt und auf die nächste ganze
Zahl abrundet (1. Verteilung). Bleiben zu verteilende Sitze übrig, so wird die Stimmenzahl jeder Partei
durch die um 1 erhöhte Zahl der ihr bereits zugewiesenen Sitze geteilt und der erste der noch zu
verteilenden Sitze der Partei mit der größten Verteilungszahl zugewiesen. Dieses Verfahren wird
solange fortgesetzt, bis alle Sitze verteilt sind. Allenfalls entscheidet bei gleichen Verteilungszahlen
das Los.
Wörterbücher (Dictionaries)
Dictionary heißt auf Deutsch Wörterbuch. Ein einfaches Wörterbuch „Deutsch –
Englisch“ besteht aus Paaren von Worten. Einem deutschen Wort ist die englische
Übersetzung, also ein zweites Wort zugeordnet. Das folgende Beispiel zeigt ein
Miniwörterbuch als Python-Dictionary:
woerterbuch = {“mother“:“Mutter“, “father“:“Vater“, “child“:“Kind“, “son“:“Sohn“,
“daughter“:“Tochter“}
Dictionaries bestehen daher aus einer Menge von Paaren von Objekten, den
sogenanten Schlüssel-Wert-Paaren. Die Wertepaare sind durch Kommata getrennt,
zwischen den Wertepaaren steht ein Doppelpunkt. Eingefasst werden die
Wertepaare durch geschweifte Klammern. Der Schlüssel ist die Adresse des Wertes.
Mit seiner Hilfe hat man direkten Zugriff auf den Wert. Dazu schriebt man den
Schlüssel in eckige Klammern.
>>>woerterbuch [“child“]
’Kind’
Ein Dictionary kann Schritt für Schritt aufgebaut werden. Zuerst erzeugt man ein
leeres Wörterbuch.
>>> Kopfnoten { }
Dann trägt man die Schlüssel-Wert-Paare einzeln ein:
>>> Kopfnoten [’1’] = ’sehr gut’
>>> Kopfnoten [’2’] = ’gut’
>>> Kopfnoten [’3’] = ’befriedigend’
>>> Kopfnoten [’4’] = ’unbefriedigend’
>>> Kopfnoten ['2']
'gut'
>>> Kopfnoten
{'1': 'sehr gut', '3': 'befriedigend', '2': 'gut', '4': 'unbefriedigend'}
Bei der letzten Ausgabe ist zu beachten, dass die Einträge im Wörterbuch
ungeordnet sind. Man hat keinen Einfluss auf die Reihenfolge der Einträge.
Wie bei Listen und Strings gibt es auch bei den Dictionaries Methoden:
d.clear():
Diese Anweisung entfernt alle Schlüssel-Werte-Paare aus dem Dictionary. Zurück
bleibt ein leeres Wörterbuch, d.h., das Dictionary selbst wird nicht gelöscht.
d.get(k,x):
Der Aufruf liefert aus einem Dictionary d den mit dem Schlüssel k assoziierten Wert,
sofern k in der Liste vorhanden ist. Ansonsten wird der Wert x zurückgegeben.
d.keys():
Der Aufruf liefert eine Liste mit allen Schlüsseln.
d.values():
Der Aufruf liefert eine Liste mit alle Werten.
k in d und k not in d
Mit diesen Methoden kann man überprüfen, ob ein Schlüssel in der Schlüsselliste
vorhanden ist oder nicht. Im ersten Fall liefert der Ausdruck den Wert True, wenn der
Schlüssel vorhanden ist, im zweiten Fall den Wert False. Ist der Schlüssel nicht
vorhanden, sind die Rückgabewerte False und True.
Der Caesar-Code
Eine der ältesten kryptographischen Methoden ist die Caesar-Verschlüsselung. Jeder
Buchstabe des zu verschlüsselnden Textes wird durch einen anderen ersetzt.
Wichtig ist dabei die Ersetzungsvorschrift. Bei Caesar wurde das Alphabet einfach
um eine bestimmte Anzahl von Buchstaben verschoben:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
BCDEFGHIJKLMNOPQRSTUVWXYZA
CDEFGHIJKLMNOPQRSTUVWXYZAB
DEFGHIJKLMNOPQRSTUVWXYZABC
EFGHIJKLMNOPQRSTUVWXYZABCD
FGHIJKLMNOPQRSTUVWXYZABCDE
GHIJKLMNOPQRSTUVWXYZABCDEF
Aus „WIR GREIFEN IM MORGENGRAUEN AN“ wird COX MXKOLKT OS
SUXMKTMXGAKT GT. Diese Ersetzungsvorschrift lässt sich durch ein Dictionary
beschreiben: code = {"A":"G","B":"H","C":"I"} usw.
Damit für code die Schlüssel-Werte-Paare produziert werden können, wird zuerst
eine Liste klar mit allen Buchstaben des Alphabets hergestellt. Der Befehl chr(x)
erzeugt ein Zeichen mit dem ASCII-Code x. X muss einen Wert zwischen 0 und 255
haben. Die Großbuchstaben des Alphabets beginnen bei x=65.
klar=[]
for i in range(26):
klar.append(chr(i+65))
Anschließend wird die Liste geheim erstellt. Der Buchstabe A soll durch G ersetzt
werden. G ist der siebte Buchstabe des Alphabets. Da der Listenindex bei 0 beginnt,
wird die Liste klar ab der Stelle 6 in die Liste geheim übernommen und die fehlenden
Buchstaben werden angehängt.
geheim=klar[6:]+klar[:6]
Aus den Listen klar und geheim wird jetzt das Dictionary code erstellt.
code={}
for i in range(26):
code[klar[i]]=geheim[i]
In der Eingabeaufforderung der IDLE kann man das Ergebnis überprüfen.
>>> klar
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
>>> geheim
['G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F']
>>> code
{'A': 'G', 'C': 'I', 'B': 'H', 'E': 'K', 'D': 'J', 'G': 'M', 'F': 'L', 'I':
'O', 'H': 'N', 'K': 'Q', 'J': 'P', 'M': 'S', 'L': 'R', 'O': 'U', 'N': 'T',
'Q': 'W', 'P': 'V', 'S': 'Y', 'R': 'X', 'U': 'A', 'T': 'Z', 'W': 'C', 'V':
'B', 'Y': 'E', 'X': 'D', 'Z': 'F'}
Jetzt fehlt nur noch der Verschlüsselungsbefehl. Der zu verschlüsselnde Text wird
Zeichen für Zeichen dekodiert. Falls Leerzeichen im Text auftauchen, müssen diese
berücksichtigt werden.
for a in text:
geheimtext=geheimtext+code.get(a," ")
Der bisherige Quelltext sieht wie folgt aus:
text="Wir greifen im Morgengrauen an"
text=text.upper()
geheimtext=""
klar=[]
for i in range(26):
klar.append(chr(i+65))
geheim=klar[6:]+klar[:6]
code={}
for i in range(26):
code[klar[i]]=geheim[i]
for a in text:
geheimtext=geheimtext+code.get(a," ")
print geheimtext
Möchte man den Text wieder entschlüsseln, werden die folgenden Zeilen noch
angehängt:
dcode={}
ent=""
for i in range(26):
dcode[geheim[i]]=klar[i]
for a in geheimtext:
ent=ent+dcode.get(a," ")
print ent
Das ganze Programm lässt sich noch etwas eingabefreundlicher gestalten.
Außerdem kann das bisherige Programm nur den mit dem Programm selbst
verschlüsselten Text entschlüsseln. Was macht man aber, wenn man die CaesarVerschiebung nicht kennt? Brutale Gewalt! Unter der Voraussetzung, dass der
Geheimtext nach Caesar verschlüsselt wurde, wird der Text entschlüsselt.
text=raw_input("Geben Sie den Text ein: ")
ver=int(raw_input("Ist der Text unverschluesselt oder verschluesselt
(Eingabe 0 bzw. 1):"))
text=text.upper()
geheimtext=""
klar=[]
ent=""
code={}
dcode={}
for i in range(26):
klar.append(chr(i+65))
if ver==0:
schiebung=int(raw_input("Bitte den Verschiebungswert eingeben"))
geheim=klar[schiebung:]+klar[:schiebung]
for i in range(26):
code[klar[i]]=geheim[i]
for a in text:
geheimtext=geheimtext+code.get(a," ")
print geheimtext
else:
for j in range(26):
ent=""
geheim=klar[j:]+klar[:j]
for i in range(26):
dcode[geheim[i]]=klar[i]
for a in text:
ent=ent+dcode.get(a," ")
dcode.clear()
print ent
Dateien
Dateien sind Datenobjekte, die unter einem Dateinamen auf einem Speicher
abgelegt und vom Betriebssystem verwaltet werden. Um auf eine Datei lesend oder
schreibend zugreifen zu können, muss zuerst ein File-Objekt generiert werden. Als
Parameter wird der Pfad und der Modus übergeben. Die Datei wird geöffnet.
>>> datei = file(dateiname,“r“)
>>> datei = file(dateiname,“w“)
Der Dateiname kann eine vollständige Pfadangabe oder nur den Dateinamen
enthalten. Wird nur der Dateiname angegeben, wird die Datei im aktuellen
Verzeichnis gespeichert. Unter Windows kann die Pfadangabe wie folgt erfolgen:
>>> datei = file ( 'c:/Ordner/versuch.txt',"w") oder
>>> datei = file ( 'c:\\Klett\\versuch2.txt',"w")
Eingelesen wird die Datei durch Zuweisung:
>>> text = datei.read()
bzw. gespeichert durch die Zuweisung
>>> datei.write(text)
Sowohl nach dem Lesen als auch dem Schreiben wird die Datei geschlossen mit der
Anweisung
>>> datei.close()
TK-Inter
Herunterladen