save and load

This commit is contained in:
2022-01-05 23:15:12 +01:00
parent b509527b7c
commit 5087df5bdd
3 changed files with 119 additions and 52 deletions

View File

@ -1,10 +1,12 @@
import inputHelper import inputHelper
import turtle import turtle
import time import drawer
turtle.tracer(0, 0) turtleObject = drawer.newTurtle()
turtleObject = turtle.Turtle() screen = turtleObject.screen
turtleObject.hideturtle() screen.colormode(255)
turtleObject.screen.colormode(255) try:
inputHelper.takeInput(turtleObject) inputHelper.takeInput(turtleObject)
turtleObject.screen.mainloop() except EOFError:
quit()
screen.mainloop()

View File

@ -16,21 +16,26 @@ class DrawingInfo:
scale: float scale: float
recursionDepth: int recursionDepth: int
@dataclass
class Drawing:
info: DrawingInfo
turtle: turtle.Turtle
drawings = [] drawings = []
class Drawer(): class Drawer():
def __init__(self, drawingInfo, turtleObject): def __init__(self, drawing):
self.startWord = drawingInfo.lSystem.startWord self.startWord = drawing.info.lSystem.startWord
self.recursionDepth = drawingInfo.recursionDepth self.recursionDepth = drawing.info.recursionDepth
self.productionRules = drawingInfo.lSystem.productionRules self.productionRules = drawing.info.lSystem.productionRules
self.angel = drawingInfo.lSystem.angel self.angel = drawing.info.lSystem.angel
self.forwardDistance = drawingInfo.scale self.forwardDistance = drawing.info.scale
self.turtle = turtleObject self.turtle = drawing.turtle
self.turtle.penup() self.turtle.penup()
self.turtle.setposition(drawingInfo.position) self.turtle.setposition(drawing.info.position)
self.turtle.setheading(drawingInfo.rotation) self.turtle.setheading(drawing.info.rotation)
self.turtle.pendown() self.pendown()
self.turtle.pencolor(drawingInfo.color) self.turtle.pencolor(drawing.info.color)
def storeEdges(self): def storeEdges(self):
pass pass
@ -79,9 +84,8 @@ class Edges:
return turtle.Vec2D(self.max[0], self.max[1]) return turtle.Vec2D(self.max[0], self.max[1])
class DrawerSimulation(Drawer): class DrawerSimulation(Drawer):
def __init__(self, drawingInfo, turtleObject): def __init__(self, drawing):
super(DrawerSimulation, self).__init__(drawingInfo, turtleObject) super(DrawerSimulation, self).__init__(drawing)
self.turtle.penup()
self.edges = Edges() self.edges = Edges()
def storeEdges(self): def storeEdges(self):
@ -94,9 +98,11 @@ class DrawerSimulation(Drawer):
def pendown(self): def pendown(self):
pass pass
def draw(turtleObject, lSystem, recursionDepth, middle, rotation, size, color): def draw(lSystem, recursionDepth, middle, rotation, size, color):
drawingInfo = DrawingInfo(lSystem, turtle.Vec2D(0, 0), rotation, color, 1, recursionDepth) drawingInfo = DrawingInfo(lSystem, turtle.Vec2D(0, 0), rotation, color, 1, recursionDepth)
simulatedDraw = DrawerSimulation(drawingInfo, turtleObject) turtleObject = newTurtle()
drawing = Drawing(drawingInfo, turtleObject)
simulatedDraw = DrawerSimulation(drawing)
simulatedDraw.draw() simulatedDraw.draw()
maxVec = simulatedDraw.edges.maxVec() maxVec = simulatedDraw.edges.maxVec()
minVec = simulatedDraw.edges.minVec() minVec = simulatedDraw.edges.minVec()
@ -105,14 +111,21 @@ def draw(turtleObject, lSystem, recursionDepth, middle, rotation, size, color):
yScale = size[1] / distance[1] yScale = size[1] / distance[1]
scale = yScale if xScale > yScale else xScale scale = yScale if xScale > yScale else xScale
pos = middle + (-minVec - distance * (1/2)) * scale pos = middle + (-minVec - distance * (1/2)) * scale
drawingInfo.position = pos drawing.info.position = pos
drawingInfo.scale = scale drawing.info.scale = scale
actualDrawer = Drawer(drawingInfo, turtleObject) drawScaled(drawing)
actualDrawer.draw()
drawings.append(drawingInfo)
def redraw(turtleObject): def newTurtle():
turtleObject.clear() turtleObject = turtle.Turtle()
for drawing in drawings: turtleObject.hideturtle()
drawer = Drawer(drawing, turtleObject) turtleObject._tracer(0, 0)
drawer.draw() return turtleObject
def delete(i):
drawings[i].turtle.clear()
del drawings[i]
def drawScaled(drawing):
actualDrawer = Drawer(drawing)
actualDrawer.draw()
drawings.append(drawing)

View File

@ -1,18 +1,35 @@
import drawer import drawer
import turtle import turtle
import lSystems import lSystems
import pickle
from dataclasses import dataclass
@dataclass
class Save:
backgroundColor: any
drawingInfos: [drawer.DrawingInfo]
loadedFilepath = None
backgroundColor = "white"
def defaultValueMsg(defaultValue):
if defaultValue == None:
return ""
return f" (Standartwert: {defaultValue})"
def inputWithDefault(description, defaultValue):
return input(f"{description}{defaultValueMsg(defaultValue)}: ")
def inputNum(inputType, description, rangeErrorMsg, minRange, maxRange, defaultValue = None): def inputNum(inputType, description, rangeErrorMsg, minRange, maxRange, defaultValue = None):
n: int
while True: while True:
inputValue = input(description) inputValue = inputWithDefault(description, defaultValue)
try: try:
n = inputType(inputValue) number = inputType(inputValue)
inputError = n < minRange or n > maxRange inputError = number < minRange or number > maxRange
if inputError: if inputError:
print(rangeErrorMsg) print(rangeErrorMsg)
else: else:
return n return number
except ValueError: except ValueError:
if inputValue == "" and defaultValue != None: if inputValue == "" and defaultValue != None:
return defaultValue return defaultValue
@ -23,28 +40,33 @@ def inputColorError():
def inputColor(turtleObject, question, defaultValue = None): def inputColor(turtleObject, question, defaultValue = None):
while True: while True:
defaultValueMsg = f" (Standartwert: {defaultValue})" if defaultValue != None else "" inputValue = input(f"{question} RGB-Wert eingeben, wobei die Farben mit Leerzeichen getrennt werden, oder einen Tk-Farbnamen eingeben [0 0 0 - 255 255 255 oder Farben auf https://www.tcl.tk/man/tcl8.4/TkCmd/colors.html]{defaultValueMsg(defaultValue)}: ")
inputValue = input(f"{question} RGB-Wert eingeben, wobei die Farben mit Leerzeichen getrennt werden, oder einen Tk-Farbnamen eingeben [0 0 0 - 255 255 255 oder Farben auf https://www.tcl.tk/man/tcl8.4/TkCmd/colors.html]{defaultValueMsg}: ")
if inputValue == "": if inputValue == "":
if defaultValue != None: if defaultValue != None:
return defaultValue return defaultValue
inputColorError() inputColorError()
else: else:
oldPenColor = turtleObject.pencolor()
try: try:
color = tuple([int(color) for color in inputValue.split()]) color = tuple([int(color) for color in inputValue.split()])
turtleObject.pencolor(color) turtleObject.pencolor(color)
turtleObject.pencolor(oldPenColor)
return color return color
except: except:
try: try:
turtleObject.pencolor(inputValue) turtleObject.pencolor(inputValue)
turtleObject.pencolor(oldPenColor)
return inputValue return inputValue
except: except:
inputColorError() inputColorError()
def inputString(question, defaultValue = None):
while True:
inputValue = inputWithDefault(question, defaultValue)
if inputValue != "":
return inputValue
if defaultValue != None:
return defaultValue
def takeInput(turtleObject): def takeInput(turtleObject):
global backgroundColor
inputValue = input("Bitte einen Befehl eingeben. h für Hilfe: ") inputValue = input("Bitte einen Befehl eingeben. h für Hilfe: ")
match inputValue: match inputValue:
case "h": case "h":
@ -52,21 +74,23 @@ def takeInput(turtleObject):
d: ein neues Lindenmayer-System zeichnen d: ein neues Lindenmayer-System zeichnen
l: ein Lindenmayer-System löschen l: ein Lindenmayer-System löschen
b: Hintergrundfarbe ändern b: Hintergrundfarbe ändern
q: Programm beenden""") q: Programm beenden
s: Lindenmayer-Systeme speichern
r: zuvor gespeicherte Lindenmayer-Systeme wiederherstellen""")
case "d": case "d":
for i, lSystem in enumerate(lSystems.LSystems): for i, lSystem in enumerate(lSystems.LSystems):
print(f"{i}: {lSystem.name}") print(f"{i}: {lSystem.name}")
lSystemIndex = inputNum(int, "Bitte ein Lindenmayer-System auswählen und die entsprechende Nummer eingeben: ", "Es gibt kein L-System mit dieser Nummer.", 0, len(lSystems.LSystems) - 1) lSystemIndex = inputNum(int, "Bitte ein Lindenmayer-System auswählen und die entsprechende Nummer eingeben: ", "Es gibt kein L-System mit dieser Nummer.", 0, len(lSystems.LSystems) - 1)
lSystem = lSystems.LSystems[lSystemIndex] lSystem = lSystems.LSystems[lSystemIndex]
recursionDepth = inputNum(int, "Rekursiontiefe des Lindenmayer-Systems eingeben [1-20] (Standartwert: 5): ", "Rekursionstiefe nicht im vorgegebenen Bereich.", 1, 20, 5) recursionDepth = inputNum(int, "Rekursiontiefe des Lindenmayer-Systems eingeben [1-20]", "Rekursionstiefe nicht im vorgegebenen Bereich.", 1, 20, 5)
rotation = inputNum(float, "Bitte die Rotation in Grad gegen den Uhrzeigersinn angeben, wobei 0° rechts ist (Standartwert: 90°): ", "nur Gradzahlen von 0 bis 360 werden akzeptiert.", 0, 360, 90) rotation = inputNum(float, "Bitte die Rotation in Grad gegen den Uhrzeigersinn angeben, wobei 0° rechts ist", "nur Gradzahlen von 0 bis 360 werden akzeptiert.", 0, 360, 90)
inputError = True inputError = True
color = inputColor(turtleObject, "Welche Farbe soll das Lindenmayer-System haben?", "black") color = inputColor(turtleObject, "Welche Farbe soll das Lindenmayer-System haben?", "black")
while inputError: while inputError:
match input("Möchtest du das das Lindenmayer-System das ganze Fenster ausfüllt? [J/n]: ").lower(): match input("Möchtest du das das Lindenmayer-System das ganze Fenster ausfüllt? [J/n]: ").lower():
case "j"|"": case "j"|"":
inputError = False inputError = False
drawer.draw(turtleObject, lSystem, recursionDepth, turtle.Vec2D(0, 0), rotation, turtleObject.screen._window_size(), color) drawer.draw(lSystem, recursionDepth, turtle.Vec2D(0, 0), rotation, turtleObject.screen._window_size(), color)
takeInput(turtleObject) takeInput(turtleObject)
case "n": case "n":
inputError = False inputError = False
@ -78,14 +102,15 @@ q: Programm beenden""")
size = pos[1] - pos[0] size = pos[1] - pos[0]
middle = pos[0] + (1/2) * size middle = pos[0] + (1/2) * size
size = turtle.Vec2D(abs(size[0]), abs(size[1])) size = turtle.Vec2D(abs(size[0]), abs(size[1]))
drawer.draw(turtleObject, lSystem, recursionDepth, middle, rotation, size, color) drawer.draw(lSystem, recursionDepth, middle, rotation, size, color)
takeInput(turtleObject) takeInput(turtleObject)
turtleObject.screen.onclick(lambda x, y: afterClick(turtle.Vec2D(x, y))) turtleObject.screen.onclick(lambda x, y: afterClick(turtle.Vec2D(x, y)))
case _: case _:
print("Bitte j oder n eingeben") print("Bitte j oder n eingeben")
case "b": case "b":
turtleObject.screen.bgcolor(inputColor(turtleObject, "Hintergrundfarbe eingeben")) backgroundColor = inputColor(turtleObject, "Hintergrundfarbe eingeben")
turtleObject.screen.bgcolor(backgroundColor)
case "q": case "q":
quit() quit()
case "l": case "l":
@ -93,10 +118,37 @@ q: Programm beenden""")
print("Es gibt nichts, was man löschen könnte.") print("Es gibt nichts, was man löschen könnte.")
else: else:
for i, drawing in enumerate(drawer.drawings): for i, drawing in enumerate(drawer.drawings):
print(f"{i}: {drawing.lSystem.name} Position: {drawing.position}") print(f"{i}: {drawing.info.lSystem.name} Position: {drawing.info.position}")
iDelete = inputNum(int, "Nummer des zu löschenden Zeichnung eingeben: ", "Es gibt keine Zeichnung mit dieser Nummer", 0, len(drawer.drawings) - 1) iDelete = inputNum(int, "Nummer des zu löschenden Zeichnung eingeben: ", "Es gibt keine Zeichnung mit dieser Nummer", 0, len(drawer.drawings) - 1)
del drawer.drawings[iDelete] drawer.delete(iDelete)
drawer.redraw(turtleObject) case "s":
filepath = inputString("Dateipfad zum Speichern eingeben", loadedFilepath)
drawingInfo = [drawing.info for drawing in drawer.drawings]
save = Save(backgroundColor, drawingInfo)
try:
file = open(filepath, "wb")
pickle.dump(save, file)
print("erfolgreich gespeichert")
except Exception as err:
print(err)
finally:
file.close()
case "r":
filepath = inputString("Datei, die geladen werden soll eingeben")
save: Save
try:
file = open(filepath, "rb")
save = pickle.load(file)
except Exception as err:
print(err)
finally:
file.close()
turtleObject.screen.clear()
backgroundColor = save.backgroundColor
turtleObject.screen.bgcolor(save.backgroundColor)
for drawingInfo in save.drawingInfos:
drawing = drawer.Drawing(drawingInfo, drawer.newTurtle())
drawer.drawScaled(drawing)
case _: case _:
print("unbekannter Befehl") print("unbekannter Befehl")
if inputValue != "d": if inputValue != "d":