==== L3 ====
from gturtle import *
makeTurtle()
# Turtle verstecken
ht()
s = 2
repeat 100:
forward(s)
left(90)
# turtle weiter als 20 vom ursprung und weniger weit als 30: bitte grün
if distance(0,0) > 20 and distance(0,0) < 30 :
setPenColor("green")
# sonst einfach blau
else:
setPenColor("blue")
s = s + 2
from gturtle import *
makeTurtle()
# Variable s für die Seitenlänge
s = 2
# Funktion segment mit zwei Parametern width und angle
def segment(width, angle):
forward(width)
left(angle)
repeat 20:
segment(s)
s = s + 2
==== L4 ====
# Rekursive Definition Fibonacci Zahlen
def fibonacci(n):
#f_0 = 1
if n == 0:
return(0)
#f_1 = 1
elif n == 1:
return(1)
# f_n = f_n-1 + f_n-2
else:
return(fibonacci(n-1)+fibonacci(n-2))
#1.618 goldener schnitt
goldensection = (sqrt(5)+1)/2
n = 2
#solange fibonacci ausrechnen, bis Quotient auf 0.0001 am goldenen Schnitt ist.
while abs(fibonacci(n)/fibonacci(n-1) - goldensection) > 0.00001:
print(fibonacci(n))
n += 1 #n wird um 1 erhöht äquivalent zu n = n+1
# Frage: ist das ''intelligent'' programmiert?
==== L5 ====
from gturtle import *
# notwending, weil getKeyCodeWait() aus gturtle ist.
makeTurtle()
print(getKeyCodeWait())
# oder
while True:
print(getKeyCodeWait())
a = 12 #globale Variable
def funprint():
print(a) # 'lesezugriff' globale Variablen
b=2*a # wird lokal verändert
print(b)
def funchange():
a=14 #lokale Variable, ändert globale Variable a nicht
print(a)
def funchangeglobal():
global a #welche globalen Variablen möchte ich in Funktion verwenden
a = 14 #verändert globale Variable a
print(a)
funprint()
print(a) #Ausgabe globale Variable
funchange()
print(a) #Ausgabe globale Variable
funchangeglobal()
print(a) #Ausgabe globale Variable
#Achtung: Globale Variablen zurückhaltend einsetzen.
==== L6 ====
Take-Aways Hausaufagben:
* Namen von Funktionen werden klein geschrieben.
* Konvention von Python: Falls notwendig mit Underscore zur Klärung. Bsp ''def move():'' oder ''def move_forward_fast():''
* Konvention von TigerJython: Falls notwending [[https://en.wikipedia.org/wiki/Camel_case|"Camel-Style"]] zur Klärung. Bsp ''def moveForwardFast():''
* Generelle Praxis: "Englisch programmieren". Ja oder Nein?
* If-Statements: Wenn inhaltlich sinnvoll mehrere Kriterien mit ''or'' und ''and'' verknüpfen
* Nicht per Mail abgeben.
* Divisionsrest: %, Ganzzahldivision / /
Besprechung Aufgabe 2.10:
from gturtle import *
# Keycodes der Tasten definieren
XLETTER = 88
LEFT = 37
RIGHT = 39
UP = 38
DOWN = 40
# Funktionsdefinition Key Listener
def onKeyPressed(key):
global stopit
if key == LEFT:
setHeading(-90)
elif key == RIGHT:
setHeading(90)
elif key == UP:
setHeading(0)
elif key == DOWN:
setHeading(180)
elif key == XLETTER:
stopit = True
# Turtle initalisieren
makeTurtle(keyPressed = onKeyPressed)
# globale Variable zum Schlaufen--Abbruch
stopit = False
# halbe Breite und halbe Höhe
h = getPlaygroundHeight()/2
w = getPlaygroundWidth()/2
# Turtle bewegen
while True:
forward(10)
print(getPos()) #Position der Turtle
# wenn eines der drei Abbruch-Kriterien erfüllt ist: break
if stopit or abs(getX()>w) or abs(getY())>h:
break
# wenn Programm regulär beendet wird, wird "habe fertig" als Reverenz an Trappatoni ausgegeben
print("Habe fertig")
==== L7 ====
==== L8 ====
=== Hausaufgaben ===
Take-Aways Hausaufagben:
* Unnötige Operationen / Iteration etc. vermeiden
* Standard-Variablen für Leserlichkeit verwenden (i,j,k anstelle von I, II, III)
* Aufgaben genau lesen resp. rückfragen.
== Strukturiertes Progammieren ==
import math
from gpanel import *
makeGPanel(-10, 10, -10, 10)
def stern(x, y, r):
fillTriangle(x - math.sqrt(3)/2 * r, y - r/2,
x + math.sqrt(3)/2 * r, y - r/2,
x, y + r);
fillTriangle(x - math.sqrt(3)/2 * r, y + r/2,
x + math.sqrt(3)/2 * r, y + r/2,
x, y - r);
stern(0, 0, 3)
== Farbwechsel ==
from gturtle import *
# Keycodes der Tasten definieren
XLETTER = 88
LEFT = 37
RIGHT = 39
UP = 38
DOWN = 40
# Funktion, welche die Farbe auf Grund x und y definiert
def changeColor(x,y):
distance = sqrt(x*x+y*y)
returncolor = "brown"
if(distance < 100):
returncolor = "blue"
elif(distance < 200):
returncolor = "green"
elif(distance < 300):
returncolor = "yellow"
## was würde passieren, wenn die Reihenfolge von 300, 200, 100 umgekehrt würde?
return returncolor
# Funktionsdefinition Key Listener
def onKeyPressed(key):
global stopit
if key == LEFT:
setHeading(-90)
elif key == RIGHT:
setHeading(90)
elif key == UP:
setHeading(0)
elif key == DOWN:
setHeading(180)
elif key == XLETTER:
stopit = True
# Turtle initalisieren
makeTurtle(keyPressed = onKeyPressed)
# globale Variable zum Schlaufen--Abbruch
stopit = False
# halbe Breite und halbe Höhe
h = getPlaygroundHeight()/2
w = getPlaygroundWidth()/2
# Turtle bewegen
while True:
forward(10)
print(getPos()) #Position der Turtle
#Aufruf der Funktion changeColor
setColor(changeColor(getX(),getY()))
# wenn eines der drei Abbruch-Kriterien erfüllt ist: break
if stopit or abs(getX()>w) or abs(getY())>h:
break
# wenn Programm regulär beendet wird, wird "habe fertig" als Reverenz an Trappatoni ausgegeben
print("Habe fertig")
== Primzahlen ==
# Um Ausführungszeit zu messen
import time
# Halbwegs effiziente Version
def checkPrime1(n,printout=True):
for i in range(2,n+1):
isPrime = True
for j in range(2,int(sqrt(i))+1):
if i%j == 0:
isPrime = False
break
if(isPrime):
if(printout):
print(i)
# Ineffiziente Version
def checkPrime2(n,printout=True):
for i in range(2,n+1):
isPrime = True
for j in range(2,i):
if i%j == 0:
isPrime = False
if(isPrime):
if(printout):
print(i)
## Zeit messen für checkPrimes1
t0 = time.clock()
repeat 100:
checkPrime1(1001,False)
print((time.clock()-t0))
## Nochmals messen für checkPrimes2
t0 = time.clock()
repeat 100:
checkPrime2(1001,False)
print((time.clock()-t0))
== Ganzzahl Operationen ==
Die Operationen / / und % sind nicht nur praktischer sonder auch einiges schneller:
# Um Ausführungszeit zu messen
import time
t0 = time.clock()
a = 0
repeat 1000000:
a = (14/2 == (int(14/2)))
print((time.clock()-t0))
t0 = time.clock()
a = 0
repeat 1000000:
a = (14%2 == 0)
print((time.clock()-t0))
==== L10 ====
=== Feebdack ===
Coding Style
* Funktionen werden klein geschrieben. Idealerweise auch als Verb und nicht als Subjekt, bsp. ''rotate'' statt ''rotation''
* Listennamen sind idealerweise im Plural. Dann ist bereits aus dem Variabelnamen klar, dass es sich um eine Liste handelt.
* Achtung mit mutable und imuutable data types.
=== Mutable und immutable data types ===
x = 'foo'
y = x
print x
# foo
y += 'bar'
print x
# foo
print y
# foobar
x = [1, 2, 3]
y = x
print x
# [1, 2, 3]
y += [3, 2, 1]
print x
# [1, 2, 3, 3, 2, 1]
print y
# [1, 2, 3, 3, 2, 1]
def fun(val):
val = 'bar'
x = 'foo'
print x
# foo
fun(x)
print x
# foo
def fun(val):
val[1]=-1
x = [1, 2, 3]
print x
# [1, 2, 3]
fun(x)
print x
# [1, -1, 3]
def fun(val):
val = [1,2,3]
val[1] = -2
x = [1, 2, 3]
print x
# [1, 2, 3]
fun(x)
print x
# [1,2, 3]
Bitte zusätzlich noch diese [[http://bjc.berkeley.edu/bjc-r/cur/programming/python/list_mutability.html|Ergänzung]] durchlesen. Lösungen dafür sind:
* Vom Modul ''copy'' ''copy.deepcopy'' verwenden, d.h. ''neueliste = copy.deepcopy(alteliste)''
* Jeweils eine neue Liste verwenden, d.h. ''neueliste = [1,2,3,4]''
* Das Verhalten <>. Achtung, bei Listen von Listen tritt dies doppelt auf.
=== Module ===
Wir haben bis jetzt schon mit Modulen gearbeitet. Diese haben wir entweder mit ''import modulename'' oder mit ''from modulname import *'' importiert. Man kann auch eigene Module schreiben, die Funktionen beinhaltet. Z.B. könnte man das Modul ''efinfo.py'' schreiben, welches alle Funktionen u.ä. enthält, welche wir für 2048 benutzen.
import sys
def printDoubleLists(lists):
for i in range(len(lists)):
for j in range(len(lists[i])):
sys.stdout.write(str(lists[i][j]))
sys.stdout.write("\t")
sys.stdout.write("\n")
Nachher könnte die Funktion wie folgt aufgerufen werden. Achtung ''efinfo.py'' muss im Pfad oder im gleichen Verzeichnis wie die ausgeführte Datei sein.
import efinfo
tiles = [[4, -1, 4, 8],
[16, 32, 64, 128],
[256, -1, -1, 2048],
[-1, -1, -1, -1]]
efinfo.printDoubleLists(tiles)
# oder
from efinfo import *
tiles = [[4, -1, 4, 8],
[16, 32, 64, 128],
[256, -1, -1, 2048],
[-1, -1, -1, -1]]
printDoubleLists(tiles)
=== Lernziele ===
* Alle Lernziele vom Lehrmittel der bearbeiten Kapitel (d.h., z.B. ohne Rekursion, ohne Objekte im Kapitel 2)
* Zusätzlich dazu:
* Programme mit gechachtelten Schlaufen lesen und schreiben können
* Programme mit geschachtelten Listen lesen und schreiben können
== Beispiel 1 ==
Was ist die Ausgabe des untenstehenden Programms? Was die Idee?
numbers = [[4, -1, 4, 8],
[16, 32, 64, 128],
[256, -1, -1, 2048],
[-1, -1, 1, -1]]
result = [0]*len(numbers)
for i in range(len(numbers)):
for j in range(len(numbers[i])):
result[i]+=numbers[i][j]
print(result)
== Beispiel 2 ==
Was ist die Ausgabe des untenstehenden Programms?
def dummyfunction(c,d):
e = 2+d
e += c
foofunction(c,e)
print(e)
if e>0:
print("Alles jut")
else:
print("So'n Mist hier")
def foofunction(c,d):
e=0
for i in range(c,d):
e+=i
print(e)
dummyfunction(2,1)
=== Lösungen ===
from efinfo import *
import copy
tiles = [[4, -1, 4, 8],
[16, 32, 64, 128],
[256, -1, -1, 2048],
[-1, -1, -1, -1]]
def shiftAndCollapseLine(inline):
##Idee: Kippen, ersetzen, kippen
#einmal kippen
#idee: alle nicht -1 sammeln, dann -1 wieder anhängen
#leere tiles
temp = []
#sammeln
for j in inline:
if j != -1:
temp.append(j)
#anhängen: Python'esquer Weg zum Anhängen
temp += [-1] * inline.count(-1)
#tiles umdrehen
temp.reverse()
#identicshe zellen verdoppeln und durch -1 ersetzen
for j in range(len(temp) - 1):
if temp[j] == temp[j + 1] and temp[j] != -1:
temp[j+1] = 2 * temp[j]
temp[j] = -1
inline=[]
#wieder sammeln und anhängen
for j in temp:
if j != -1:
inline.append(j)
inline+=[-1] * temp.count(-1)
#tiles umdrehen
inline.reverse()
return(inline)
def shiftAndCollapseGrid(tiles):
# 'leere' tiles mit länge von tiles
temp = [-1]*len(tiles)
for i in range(len(tiles)):
temp[i] = shiftAndCollapseLine(tiles[i])
return(temp)
def rotateGrid(tiles):
returnlist = copy.deepcopy(tiles)
#sehr Pythonish
return(list(map(list, zip(*returnlist[::-1]))))
printDoubleLists(tiles)
print
repeat 4:
tiles = rotateGrid(tiles)
printDoubleLists(tiles)
==== L11 ====
Auf Grund der Diskussionen in den Gruppen nochmals ein Brush-up:
=== Scoping (Lebensdauer von Variablen) ===
# Globale Variable a
a = 0
if a == 0:
# Immer noch eine globale Variable b
b = 1
def myFunction(c):
# d ist eine lokale Variable, c ist Argument der Funktion
d = 3
print(c)
print(d)
return(d+c)
# Funktionsaufruf mit Arugment 7, der Rückgabewert wird der _globalen_ Variable e zugewiesen
e = myFunction(7) # e = 10
# a,b,e exisiteren noch im Speicher und können ausgegeben werden
print('a')
print(a)
print('b')
print(b)
print('e')
print(e)
# c und d waren lokale Variablen und ergeben einen Fehler.
print(c)
print(d)
Möchte man eine globale Variable innerhalb einer Funktion verändern, braucht es den Aufruf ''global variablename'' als erste Zeile in der Funktion. Siehe auch [[efinf:blcks2017:jython:lektionen#l5|Lektion 5]]. *Achtung*: Das gilt genauso, wenn der Rückgabewert / die Variable ein anderer Typ (String, Boolean, Liste, etc.) ist.
=== Assignment Operatoren ===
# In Ordnung
a = 3
i = -3
# Nicht in Ordnung. Wenn Vergleich, dann ==
3 = 4
3 = a
a + b = 3
#In Ordnung
i = i + 1
i += 1 # äquivalent zu oben
# es gibt ebenfalls +=, -=, *=, /=, %=, //=, **=
a %= 3
a = a % 3
==== L12 ====
import random
def randomMatrix(zeilen, spalten):
matrix = []
for i in range(zeilen):
zeile = []
for j in range(spalten):
zeile.append(random.randint(0,1000))
matrix.append(zeile)
zeile = []
return matrix
from gpanel import *
from math import *
makeGPanel(-50,50, -50, 50)
def drawNumbers(n):
for i in range(1,n+1):
# x und y Koordinate des Punktes.
# x = cos(winkel)*radius,
# y = sin(winkel)*radius
# der Winkel ist dabei 2*Pi, entspricht 360°,
# dividiert durch n mal die Zahl i.
x = cos(2*pi/n*i)*40
y = sin(2*pi/n*i)*40
move(x,y)
# Kreisfarbe
setColor("green")
fillCircle(2)
# Textfarbe
setColor("black")
text(x,y,str(i))
drawNumbers(20)
def checkPrime(i):
return((all(map(lambda x: i%x!=0, range(2,i)))))
==== L13 ====
=== Aufgaben Teil 1 ===
Die Aufgaben Teil 1 sind korrigiert in One Note
=== Aufgaben Teil 2 ===
def dummyfunction(n):
for i in range(1,n+1):
print i
if i%15 == 0: #wichtig: zuerst modulo 15 teste!
print "TuTuTaTa"
elif i%3 == 0:
print "TaTa"
elif i%5 == 0:
print "TuTu"
dummyfunction(30)
import random
def randomMatrix(zeilen, spalten):
matrix = []
for i in range(zeilen):
zeile = []
for j in range(spalten):
zeile.append(random.randint(0,1000))
matrix.append(zeile)
zeile = []
return matrix
#i
meineMatrix = randomMatrix(3,5)
# ii
def summe(matrix):
sumvar = 0
# durch matrix loopen
for i in range(len(matrix)):
for j in range(len(matrix[i])):
# jedes element addieren
sumvar += matrix[i][j]
return sumvar
#iii
def durchschnitt(matrix):
sumvar = 0
count = 0
# durch matrix loopen
for i in range(len(matrix)):
for j in range(len(matrix[i])):
# jedes element addieren und counter erhöhen
sumvar += matrix[i][j]
count += 1
return sumvar/count
#iv
print(durchschnitt(randomMatrix(100,100)))
#oder
print(summe(randomMatrix(100,100))/(100**2))
# der durchschnitt nähert sich 500
from gpanel import *
from math import *
makeGPanel(-50,50, -50, 50)
#i
def checkPrime(n):
isPrime = True
for j in range(2,int(sqrt(n))+1):
if n%j == 0:
isPrime = False
break
return(isPrime)
def drawNumbers(n):
for i in range(1,n+1):
# x und y Koordinate des Punktes.
# x = cos(winkel)*radius,
# y = sin(winkel)*radius
# der Winkel ist dabei 2*Pi, entspricht 360°,
# dividiert durch n mal die Zahl i.
x = cos(2*pi/n*i)*40
y = sin(2*pi/n*i)*40
move(x,y)
# Kreisfarbe
# Aufgaben Teil ii)
if(checkPrime(i)):
setColor("green")
else:
setColor("orange")
fillCircle(2)
# Textfarbe
setColor("black")
text(x,y,str(i))
# Aufgabe Teil iv)
for j in range(1,n+1):
if j % i == 0 or i%j == 0:
xn = cos(2*pi/n*j)*40
yn = sin(2*pi/n*j)*40
line(x,y,xn,yn)
else:
continue
drawNumbers(30)