Hallo liebe Pythongemeinde,
ich bin ganz frisch in der Materie und möchte bevor ich mein erstes Programm schreibe ein paar Informationen zusammen tragen. Ich hoffe ihr könnt mir dabei helfen.
Kurz zu mir, ich bin absoluer Neuling, habe allerdings vor zwanzig Jahren in Qbasic programmiert, da mir die Syntax von Python dadurch zumindest etwas bekannt vorkam habe ich mich dazu entschlossen diese Sprache neu zu erlernen.
Zu meinem Vorhaben:
Ich möchte gerne ein Programm schreiben das mir automatisch einen Speisenplan aus 15 Speisen erstellt (pro Wochentag 3 Speisen)
Dies soll am besten zufällig geschehen um immer wieder unterschiedliche Pläne zu erhalten.
Ich habe sämtliche Speisen als Kalkulationen Excel Format und müsste diese dann erst einmal in eine Datenbank einpflegen. Da ich lediglich weiß wie man eine MySQL Datenbank anlegt und einen Nutzer hinzufügt, war mein nächster Gedanke, wieso das ganze nicht in eine XML datenbank packen.
Meine Frage an euch wäre nun welche Methode mehr Sinn macht und was für einen blutigen Anfänger das simpelste wäre.
Später soll die Software auch noch die dazugehörigen Kalkulationen mit ausgeben und eine Einkaufsliste erstellen.
Ja, ich weiß, sehr ambitioniert für einen Anfänger aber ich dachte mir, wenn du das schon lernst dann bestenit einem Praxisnahen und nützlichen Ziel. Da ich Hauptberuflich Küchenchef bin, könnte ich solch eine Software schon sehr gut gebrauchen
Liebe Grüße und danke im Vorraus
Localedatenbank zum Speichern von Rezepten und Speisen
XML kann man nehmen, aber schöner ist JSON. Das schreibt sich leichter, und das einlesen und verarbeiten ist sehr trivial. auch CSV ginge.
Eine SQL datenbank lohnt sich erst dann, wenn du nicht nur lesen und auswählen, sondern auch schreiben willst, zb um dir zu merken, was wann gewählt wurde & dann sicherzustellen, das in der Woche drauf nicht das gleiche kommt, oder sowas. Da ist das mitgelieferte SQLite aber schon ausreichend.
Eine SQL datenbank lohnt sich erst dann, wenn du nicht nur lesen und auswählen, sondern auch schreiben willst, zb um dir zu merken, was wann gewählt wurde & dann sicherzustellen, das in der Woche drauf nicht das gleiche kommt, oder sowas. Da ist das mitgelieferte SQLite aber schon ausreichend.
Bevor Du Dir Gedanken um eine Datenbank machst, überlege zuerst, was das Programm alles können soll. Um aus einer Liste von 350 Gerichten 15 zufällig auszuwählen braucht man nämlich keine Datenbank, da reicht die Excel-Tabelle.
Erster Schritt ist also, ein Programm zu schreiben, das die Excel-Tabelle in eine passenden Datenstruktur einliest (brauchst Du sowieso, denn man will ja nicht die Speisen von Hand in eine Datenbank übertragen). Damit kannst Du schonmal den Speiseplan erstellen.
Sollte später mehr Funktionen hinzukommen, und es nötig machen, irgendwelche Information zu speichern, kannst Du Dir immer noch überlegnen, wie man das am Besten in einer Datenbank organisiert.
Erster Schritt ist also, ein Programm zu schreiben, das die Excel-Tabelle in eine passenden Datenstruktur einliest (brauchst Du sowieso, denn man will ja nicht die Speisen von Hand in eine Datenbank übertragen). Damit kannst Du schonmal den Speiseplan erstellen.
Sollte später mehr Funktionen hinzukommen, und es nötig machen, irgendwelche Information zu speichern, kannst Du Dir immer noch überlegnen, wie man das am Besten in einer Datenbank organisiert.
Danke für die schnellen Antworten, beide haben mir sehr weitergeholfen.
@sirius3
Da hast du natürlich vollkommen recht.Ich habe das ganze wohl möglich schon zu weit gesponnen.
In der ersten Version soll die Software aus bestehenden Excel Kalkulationen die alle nach dem Gericht benannt sind, neue Speisenpläne zusammen stellen.
Meine Idee war, dass der User in die prompt das Datum eingibt, anschließend durchsucht die Software den Ordner der Kalkulationen und schreibt die Gerichte in eine vorher angelegte Excelvorlage.
Dabei muss sie beachten dass es pro Tag:
Ein Vegtarischen Essen
Ein beliebiges Essen mit Fleisch
Und
Ein Fit Food gibt.
Später soll die Software wie gesagt noch die Mengen aus den Kalkulationen lesen und daraus eine Einkaufsliste erstellen. Eventuell wird es mal eine GUI geben in der dann auch die Kalkulationen erstellt werden können, diese soll dann auch verschiedene Lieferanten beinhalten und deren Preise.
Ich hoffe ich drücke mich verständlich aus
@sirius3
Da hast du natürlich vollkommen recht.Ich habe das ganze wohl möglich schon zu weit gesponnen.
In der ersten Version soll die Software aus bestehenden Excel Kalkulationen die alle nach dem Gericht benannt sind, neue Speisenpläne zusammen stellen.
Meine Idee war, dass der User in die prompt das Datum eingibt, anschließend durchsucht die Software den Ordner der Kalkulationen und schreibt die Gerichte in eine vorher angelegte Excelvorlage.
Dabei muss sie beachten dass es pro Tag:
Ein Vegtarischen Essen
Ein beliebiges Essen mit Fleisch
Und
Ein Fit Food gibt.
Später soll die Software wie gesagt noch die Mengen aus den Kalkulationen lesen und daraus eine Einkaufsliste erstellen. Eventuell wird es mal eine GUI geben in der dann auch die Kalkulationen erstellt werden können, diese soll dann auch verschiedene Lieferanten beinhalten und deren Preise.
Ich hoffe ich drücke mich verständlich aus
Statt einer GUI würde ich heute überlegen, ob man es nicht mit einem Web-Interface (bottle.py oder Flask) machen kann.
Ich weiß nicht, wie viele Gerichte du tatsächlich hast, aber im Prinzip könnte man das auch auf Basis bestehender Excel files (dann z. B. mit openpyxl) lösen, das hätte den Vorteil, dass die Inhalte weiterhin leicht via Excel zugänglich sind.
Falls in den files markiert ist, zu welcher Kategorie das Menü gehört, dann könnte man m. E. die Zuordnung leicht vornehmen. Du suchst dann das random-Modul für den Zufall.
BTW: Spannendes Projekt, liest sich toll.
Ich weiß nicht, wie viele Gerichte du tatsächlich hast, aber im Prinzip könnte man das auch auf Basis bestehender Excel files (dann z. B. mit openpyxl) lösen, das hätte den Vorteil, dass die Inhalte weiterhin leicht via Excel zugänglich sind.
Falls in den files markiert ist, zu welcher Kategorie das Menü gehört, dann könnte man m. E. die Zuordnung leicht vornehmen. Du suchst dann das random-Modul für den Zufall.
BTW: Spannendes Projekt, liest sich toll.
Das ist natürlich auch eine klasse idee, ist es denn möglich das ich das Programm erst rein für die Konsole schreibe und es später mit dem Webinterface ansprechbar mache?
Ich glaube auch wenn es sich um ein kleines Programm handelt wird es mich schon sehr vordern.
Ich glaube auch wenn es sich um ein kleines Programm handelt wird es mich schon sehr vordern.
Hey, da bin ich wieder!
Also ich habe nun die ersten Zeilen Code geschrieben, sozusagen ein Dummy der erst einmal den Plan einliest und in einer Variable speichert, diese dann via Print auf in der Konsole ausgibt.
Hier könnt ihr mal drüber schauen, ich denke es hätte bestimmt eine Möglichkeit gegeben das einfacher zu gestalten, mit weniger Code. Allerdings kann ich mit Openpyxl nur Zeile für Zeile einlesen, da jedes Gericht 3-5 Zeilen hat, habe ich jeder Zeile eine eigene Variable zugeordnet.
Der nächste Schritt ist mir noch etwas unklar, die Daten müssen ja in eine Datei geschrieben werden aber vorher muss diese Datei ja gefüllt werden und möchte nicht jedes mal den Dateinamen im Code ändern. Also müsste ich eine Input Schnittstelle schaffen, damit der Benutzer einen Ordner einlesen kann in dem die schon geschriebenen Speisepläne hinterlegt sind.
Dafür habe ich schon einmal die Bibliothek os eingefügt.
So wie ich es verstanden habe bekomme ich dadurch die Möglichkeit im Betriebsystem zu navigieren/ordner zu erstellen etc...
Kann ich denn mit Openpyxl auch Vorlagen befüllen? In der Dokumentation habe ich leider nur lesen können wie man neue Dateien erstellt und schreibt.
Liebe grüße und ein schönes Wochenende
Also ich habe nun die ersten Zeilen Code geschrieben, sozusagen ein Dummy der erst einmal den Plan einliest und in einer Variable speichert, diese dann via Print auf in der Konsole ausgibt.
Hier könnt ihr mal drüber schauen, ich denke es hätte bestimmt eine Möglichkeit gegeben das einfacher zu gestalten, mit weniger Code. Allerdings kann ich mit Openpyxl nur Zeile für Zeile einlesen, da jedes Gericht 3-5 Zeilen hat, habe ich jeder Zeile eine eigene Variable zugeordnet.
Code: Alles auswählen
#!/Documente/Python
import openpyxl
from openpyxl import Workbook
import os
speisenPlan = openpyxl.load_workbook('beispiel.xlsx')
sheetNamen = speisenPlan['Mittag']
#Speisenplan Einlesen
var2 = sheetNamen['B09'].value #Mo GerichtI
var3 = sheetNamen['B10'].value
var4 = sheetNamen['B11'].value
#var5 = sheetNamen['B12'].value
var6 = sheetNamen['C09'].value #Mo GerichtII
var7 = sheetNamen['C10'].value
var8 = sheetNamen['C11'].value
var9 = sheetNamen['C12'].value
#var10 = sheetNamen['C13'].value
var11 = sheetNamen['D09'].value #Mo GerichtFF
var12 = sheetNamen['D10'].value
var13 = sheetNamen['D11'].value
var14 = sheetNamen['D12'].value
#var15 = sheetNamen['D13'].value
var16 = sheetNamen['B15'].value #Di GerichtI
var17 = sheetNamen['B16'].value
var18 = sheetNamen['B17'].value
#var19 = sheetNamen['B18'].value
var20 = sheetNamen['C15'].value #Di GerichtII
var21 = sheetNamen['C16'].value
var22 = sheetNamen['C17'].value
var23 = sheetNamen['C18'].value
#var24 = sheetNamen['C19'].value
var25 = sheetNamen['D15'].value #Di GerichtFF
var26 = sheetNamen['D16'].value
var27 = sheetNamen['D17'].value
var28 = sheetNamen['D18'].value
#var29 = sheetNamen['D19'].value
var30 = sheetNamen['B21'].value #Mi GerichtI
var31 = sheetNamen['B22'].value
var32 = sheetNamen['B23'].value
#var33 = sheetNamen['B24'].value
var34 = sheetNamen['C21'].value #Mi GerichtII
var35 = sheetNamen['C22'].value
var36 = sheetNamen['C23'].value
var37 = sheetNamen['C24'].value
#var38 = sheetNamen['C25'].value
var39 = sheetNamen['D21'].value #Mi GerichtFF
var40 = sheetNamen['D22'].value
var41 = sheetNamen['D23'].value
var42 = sheetNamen['D24'].value
#var43 = sheetNamen['D25'].value
var44 = sheetNamen['B27'].value #Do GerichtI
var45 = sheetNamen['B28'].value
var46 = sheetNamen['B29'].value
#var47 = sheetNamen['B30'].value
var48 = sheetNamen['C27'].value #Do GerichtII
var49 = sheetNamen['C28'].value
var50 = sheetNamen['C29'].value
var51 = sheetNamen['C30'].value
#var52 = sheetNamen['C31'].value
var53 = sheetNamen['D27'].value #Do GerichtFF
var54 = sheetNamen['D28'].value
var55 = sheetNamen['D29'].value
var56 = sheetNamen['D30'].value
#var57 = sheetNamen['D31'].value
var58 = sheetNamen['B33'].value #Fr GerichtI
var59 = sheetNamen['B34'].value
var60 = sheetNamen['B35'].value
var61 = sheetNamen['B36'].value
#var62 = sheetNamen['B37'].value
var63 = sheetNamen['C33'].value #Fr GerichtII
var64 = sheetNamen['C34'].value
var65 = sheetNamen['C35'].value
var66 = sheetNamen['C36'].value
#var67 = sheetNamen['C37'].value
var68 = sheetNamen['D33'].value #Fr GerichtFF
var69 = sheetNamen['D34'].value
var70 = sheetNamen['D35'].value
var71 = sheetNamen['D36'].value
#var72 = sheetNamen['D37'].value
print("Montag Gericht I")
print(str(var2))
print(str(var3))
print(str(var4))
#print(str(var5))
print("Montag Gericht II")
print(str(var6))
print(str(var7))
print(str(var8))
print(str(var9))
#print(str(var10))
print("Montag Gericht FF")
print(str(var11))
print(str(var12))
print(str(var13))
print(str(var14))
#print(str(var15))
print("Dienstag Gericht I")
print(str(var16))
print(str(var17))
print(str(var18))
#print(str(var19))
print("Dienstag Gericht II")
print(str(var20))
print(str(var21))
print(str(var22))
print(str(var23))
#print(str(var24))
print("Dienstag Gericht FF")
print(str(var25))
print(str(var26))
print(str(var27))
print(str(var28))
#print(str(var29))
print("Mittwoch Gericht I")
print(str(var30))
print(str(var31))
print(str(var32))
#print(str(var33))
print("Mittwoch Gericht II")
print(str(var34))
print(str(var35))
print(str(var36))
print(str(var37))
#print(str(var38))
print("Mittwoch Gericht FF")
print(str(var39))
print(str(var40))
print(str(var41))
print(str(var42))
#print(str(var43))
print("Donnerstag Gericht I")
print(str(var44))
print(str(var45))
print(str(var46))
#print(str(var47))
print("Donnerstag Gericht II")
print(str(var48))
print(str(var49))
print(str(var50))
print(str(var51))
#print(str(var52))
print("Donnerstag Gericht FF")
print(str(var53))
print(str(var54))
print(str(var55))
print(str(var56))
#print(str(var57))
print("Freitag Gericht I")
print(str(var58))
print(str(var59))
print(str(var60))
print(str(var61))
#print(str(var62))
print("Freitag Gericht II")
print(str(var63))
print(str(var64))
print(str(var65))
print(str(var66))
#print(str(var67))
print("Freitag Gericht FF")
print(str(var68))
print(str(var69))
print(str(var70))
print(str(var71))
#print(str(var72))
Dafür habe ich schon einmal die Bibliothek os eingefügt.
So wie ich es verstanden habe bekomme ich dadurch die Möglichkeit im Betriebsystem zu navigieren/ordner zu erstellen etc...
Kann ich denn mit Openpyxl auch Vorlagen befüllen? In der Dokumentation habe ich leider nur lesen können wie man neue Dateien erstellt und schreibt.
Liebe grüße und ein schönes Wochenende
Code: Alles auswählen
from openpyxl import load_workbook
wb = load_workbook('template.xlsx')
# grab the active worksheet
ws = wb.active
# Data can be assigned directly to cells
ws['A2'] = 'Tom'
ws['B2'] = 30
ws['A3'] = 'Marry'
ws['B3'] = 29
# Save the file
wb.save("sample.xlsx")
Schaust du mal hier:
[1] https://openpyxl.readthedocs.io/en/2.5/tutorial.html
[2] http://zetcode.com/articles/openpyxl/
Ich würde mir die Daten komplett ziehen und dann schauen, was ich von den Daten brauche. Das erleichtert m. E. die Arbeit sehr, zwingt Dich aber dazu, dass nach Möglichkeit die files eine ähnliche Struktur haben sollten - zumindest, wenn du einfach parsen möchtest.
[1] https://openpyxl.readthedocs.io/en/2.5/tutorial.html
[2] http://zetcode.com/articles/openpyxl/
Ich würde mir die Daten komplett ziehen und dann schauen, was ich von den Daten brauche. Das erleichtert m. E. die Arbeit sehr, zwingt Dich aber dazu, dass nach Möglichkeit die files eine ähnliche Struktur haben sollten - zumindest, wenn du einfach parsen möchtest.
Danke dir pixewakb, Habe mir die Artikel nochmal durchgelesen und konnte einiges umsetzen. Die Speisepläne die eingelesen werden sind identisch mit denen die geschrieben werden.
Das habe ich bisher alles umgesetzt. Stand jetzt:
-Benutzer wählt Datei aus
-Datei wird eingelesen
-Datei wird in Template geschrieben
Soweit so gut, nun müsste ich eine Möglichkeit haben dynamisch in ein neues Excelfile zuschreiben. Sprich aufeinander folgend oder noch besser sortiert. Wie ich in ein neues Sheet schreibe weiss ich. Nur müssen die Spalten und Reihen immer fortlaufend sein damit die bestehenden Daten nicht überschrieben werden.
Das habe ich bisher alles umgesetzt. Stand jetzt:
-Benutzer wählt Datei aus
-Datei wird eingelesen
-Datei wird in Template geschrieben
Soweit so gut, nun müsste ich eine Möglichkeit haben dynamisch in ein neues Excelfile zuschreiben. Sprich aufeinander folgend oder noch besser sortiert. Wie ich in ein neues Sheet schreibe weiss ich. Nur müssen die Spalten und Reihen immer fortlaufend sein damit die bestehenden Daten nicht überschrieben werden.
Mir ist nicht klar, was Du möchtest? Ich habe mal folgendes in der Konsole gemacht, möglicherweise kannst du davon etwas gebrauchen:Ooldman24 hat geschrieben: ↑Sonntag 12. August 2018, 22:46Soweit so gut, nun müsste ich eine Möglichkeit haben dynamisch in ein neues Excelfile zuschreiben. Sprich aufeinander folgend oder noch besser sortiert. Wie ich in ein neues Sheet schreibe weiss ich. Nur müssen die Spalten und Reihen immer fortlaufend sein damit die bestehenden Daten nicht überschrieben werden.
Code: Alles auswählen
>>> import datetime
>>> filename = "Wochenplan {}.xlsx".format(datetime.date.today())
>>> filename
'Wochenplan 2018-08-13.xlsx'
>>> datetime.date(2018,8,13).weekday()
0
>>> d = datetime.date(2018,8,13)
>>> d2 = d + datetime.timedelta(7)
>>> d2.weekday()
0
Schaust du mal, ob dir das hilft?
Falls ja, wirst du an einigen Stellen m. E. noch nacharbeiten müssen. Du kannst über den Zwischenschritt 1 die Platzierung der Inhalte im file ändern, du musst dann an einer Stelle noch die statischen Inhalte in die Datei schreiben lassen. Wahrscheinlich kann man die beiden Zwischenschritte eleganter machen, das kommt aber darauf an, wie deine Ursprungsdaten beschaffen sind. Für mich wäre das eine erst einmal funktionsfähige Lösung...
Code: Alles auswählen
import datetime
from openpyxl import Workbook
from openpyxl.compat import range
from openpyxl.utils import get_column_letter
wb = Workbook()
dest_filename = 'Wochenplan {}.xlsx'.format(datetime.date.today())
ws1 = wb.active
ws1.title = "Wochenplan"
speisen = [["Vegetarisch 1", "Fleisch 1", "Fit Food 1"], # monday
["Vegetarisch 2", "Fleisch 2", "Fit Food 2"], # tuesday
["Vegetarisch 3", "Fleisch 3", "Fit Food 3"], # wednesday
["Vegetarisch 4", "Fleisch 4", "Fit Food 4"], # thursday
["Vegetarisch 5", "Fleisch 5", "Fit Food 5"]] # friday
# Wir ermitteln die Zellziele colums_rows
# Zwischenschritt 1 von 2
column_rows = []
for column in ["B", "C", "D", "E", "F"]:
for row in [2, 3, 4]:
column_rows.append("{}{}".format(column, row))
# Wir machen aus der verschachtelten Liste eine flache Liste
# Zwischenschritt 2 von 2
flat_list_speisen = [item for sublist in speisen for item in sublist]
# Wir schreiben die Inhalte in den Wochenplan
for column_row, meal in zip(column_rows, flat_list_speisen):
ws1[column_row] = meal
wb.save(filename = dest_filename)
Guten Morgen!
Ich bin wirklich sprachlos, vielen Dank für deine Mühe. Das wird mir in den nächsten Schritten extrem weiter helfen. Unglaublich das du das in 15 min runter geschrieben hast, Respekt !
Ja, das war etwas schwammig formuliert, da stimme ich Dir zu. Also der nächste Schritt wäre der, dass vorhandene Speisepläne die schon ausgefüllt sind in eine Datenbank (Ein leeres Excelfile) aufgenommen werden. Die muss ja zwingend fortlaufend und Dynamisch passieren.
Wenn diese "Datenbank" dann gefüllt ist mit Speisen komme ich zu dem nächsten Schritt den du mir hier schon auf das Silbertablett gelegt hast.
Habe gestern nochmal ein bißchen gegoogelt und bin auf die Funktion append gestoßen, damit soll es wohl möglich sein fortlaufend in ein Excel Dokument zu schreiben. Da muss ich mir dann nochmal die Syntax anschauen, IDLE gab mir aus die Fehler Meldung "Invalid Charakter identifier" aus.
Um es nochmal zu veranschaulichen ist hier die Vorlage meines Wochenplans:
https://imgur.com/RmvC3E7
Und so soll das Programm in der ersten Version funktionieren:
-Speisen aus allen Plänen einlesen.
-Vorlage mit Datum (von bis) und Speisen aus "Datenbank" random befüllen.
Für die drei unterschiedlichen Speisen werde ich dann Pro Art ein Blatt im Exceldokument anfertigen.
Ich hoffe ich habe mich verständlicher ausgedrückt nach einer Mütze voll Schlaf
Ich bin wirklich sprachlos, vielen Dank für deine Mühe. Das wird mir in den nächsten Schritten extrem weiter helfen. Unglaublich das du das in 15 min runter geschrieben hast, Respekt !
Ja, das war etwas schwammig formuliert, da stimme ich Dir zu. Also der nächste Schritt wäre der, dass vorhandene Speisepläne die schon ausgefüllt sind in eine Datenbank (Ein leeres Excelfile) aufgenommen werden. Die muss ja zwingend fortlaufend und Dynamisch passieren.
Wenn diese "Datenbank" dann gefüllt ist mit Speisen komme ich zu dem nächsten Schritt den du mir hier schon auf das Silbertablett gelegt hast.
Habe gestern nochmal ein bißchen gegoogelt und bin auf die Funktion append gestoßen, damit soll es wohl möglich sein fortlaufend in ein Excel Dokument zu schreiben. Da muss ich mir dann nochmal die Syntax anschauen, IDLE gab mir aus die Fehler Meldung "Invalid Charakter identifier" aus.
Um es nochmal zu veranschaulichen ist hier die Vorlage meines Wochenplans:
https://imgur.com/RmvC3E7
Und so soll das Programm in der ersten Version funktionieren:
-Speisen aus allen Plänen einlesen.
-Vorlage mit Datum (von bis) und Speisen aus "Datenbank" random befüllen.
Für die drei unterschiedlichen Speisen werde ich dann Pro Art ein Blatt im Exceldokument anfertigen.
Ich hoffe ich habe mich verständlicher ausgedrückt nach einer Mütze voll Schlaf
[1] Also den Punkt verstehe ich nicht und mein Bauchgefühl sagt mir, dass das nicht sinnvoll ist. Wenn Du alle Rezepte (?) in Excel-files hast, warum lässt du es dann damit nicht bewenden und lädst nur die files, die du laut Auswahl tatsächlich für deinen Wochenplan benötigst?Ooldman24 hat geschrieben: ↑Montag 13. August 2018, 06:19Ja, das war etwas schwammig formuliert, da stimme ich Dir zu. Also der nächste Schritt wäre der, dass vorhandene Speisepläne die schon ausgefüllt sind in eine Datenbank (Ein leeres Excelfile) aufgenommen werden. Die muss ja zwingend fortlaufend und Dynamisch passieren.
Für mich - und hoffentlich auch andere *) - ist nicht klar, wie deine Rezepte aussehen und wie die Dateien heißen, aber, wenn du alles in eine Datei abkippst, dann schaffst du dir damit m. E. mehr Probleme, als dass du die löst.
[2] Wenn es Dir um die Speisepläne (?) geht, weil du die Metadaten auslesen willst, also etwa <Name der Speise>, <Zusatzbemerkung>, <Allergene>, <Speisentyp> (Speisentyp: vegetarisch, mit Fleisch, fit food), dann würde ich das in ein csv file abkippen und von dort laden. Das dürfte gegenüber einem Excelfile performanter sein. Eine interessante Spalte könnte noch der Name des files sein, aus dem du die Daten geladen hast...
PS: Wenn Du es noch nicht gemacht hast, ich würde von deinen Ursprungsdateien mal eine Sicherungskopie anlegen. Das klingt alles nicht danach, dass du bestehende Dateien bearbeitest, aber, falls du das mal machst, kannst du bei einem Fehler auf ein backup zurückgreifen.
*) Dass ich eine lauffähige Version geschrieben habe, heißt leider nicht, dass ich ein *guter* Programmierer bin. Einige aus dem Forum könnten das Problem wahrscheinlich noch besser lösen und kontrollieren hoffentlich gerade mein Feedback und melden sich, wenn meine Meinung in die falsche Richtugn läuft.
- __blackjack__
- User
- Beiträge: 13236
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Ooldman24: Zu dem Code der die Daten aus einer Exceldatei extrahiert: Ich denke das ist nicht nur eine Frage das einfacher zu gestalten, sondern es ist schlicht eine falsche herangehensweise so verdammt viel Code zu haben der durch kopieren und einfügen entstanden ist und die ganzen durchnummerierten, nichtssagenden Namen. Bei dem ganzen Code der da steht, hätte man auch gleich die Daten per Hand kopieren können. Man programmiert ja normalerweise um manuelle Wiederholungen zu vermeiden, nicht um manuell viel Code (und/oder Daten) zu wiederholen. Und das macht man mit Schleifen, Funktionen, und Datenstrukturen.
Aber fangen wir mit der ersten Zeile an. Die macht keinen Sinn, es sei denn Du hast wirklich im Ordner `/Documente/` einen Python-Interpreter mit dem Namen `Python`. Die „she bang“-Zeile sagt unter Unix mit welchem Programm eine Textdatei ausgeführt werden soll. Unter Windows wird die vom System selbst nicht ausgewertet, aber sie ist mindestens für den Leser interessant um zu sehen ob das für Python 2.x oder Python 3.x gedacht ist, und es gibt Programme wie Webserver und den Python-Launcher der mit *.py-Dateien verknüpft ist, die diese Zeile (teilweise) auswerten. Wenn das Python 3.x-Quelltext sein soll, dann ist die übliche Zeile ``#!/usr/bin/env python3``. Und das ist auch unter Windows sinnvoll, damit der Python-Launcher weiss das ein Python 3.x-Interpreter verwendet werden soll.
`Workbook` wird importiert, aber nirgends verwendet.
Namenskonvention in Python ist kleinbuchstaben_mit_unterstrichen für alles ausser Konstanten (KOMPLETT_GROSS) und Klassennamen (MixedCase). Also `speisenplan` oder `speisen_plan` statt `speisenPlan` und `sheetnamen` oder `sheet_namen` statt `sheetNamen`.
Wobei `sheet_namen` irreführend ist, denn hinter dem Namen würde man zum Beispiel eine Liste mit Zeichenketten erwarten, eben Namen von Arbeitsblättern. Es ist aber tatsächlich das Arbeitsblatt mit dem Namen 'Mittag'.
Und dann fangen die vielen Wiederholungen an. An der Stelle sollte man sich die Struktur der Daten anschauen, sich eine Struktur überlegen in der man die Daten hinterher haben möchte, und dann schauen wie man das eine in das andere Überführen kann.
Es geht ja anscheinend um fünf Wochentage, die jeweils immer gleich strukturiert sind, nämlich als drei Spalten für die drei Gerichte in denen fünf Zeilen pro Gericht stehen. Diese Blöcke haben einen Versatz von neun Zeilen vom Anfang und sind im Abstand von sechs Zeilen angeordnet. Das sind die Eckdaten die man im Programm als Zahlenwerte vorgeben kann.
Als Ziel könnte man eine Liste mit einem Eintrag pro Wochentag nehmen, wobei jeder Eintrag aus drei Listen mit den Zellwerten für das jeweilige Gericht bestehen.
`print()` wandelt die Argumente schon von selbst in Zeichenketten um vor der Ausgabe — ein extra `str()`-Aufruf ist da nicht nötig.
Das ganze ist dann auch mit Schleifen immer noch recht umfangreich; IMHO zu umfangreich für *eine* Funktion. Es werden ja auch zwei deutlich unterscheidbare Dinge getan: Die Daten werden eingelesen und sie werden (leicht) formatiert, ausgegeben. Eingabe, Verarbeitung, und Ausgabe sind traditionell Bereiche an denen man ein Programm gut und sinnvoll auftrennen kann. Eine Verarbeitung fällt hier ja erst einmal weg, also haben wir eine Funktion zum einlesen der Daten in eine sinnvoll Struktur, die Ausgabe der Daten, und das Hauptprogramm, das beides verbindet und üblicherweise in einer Funktion steht die `main()` heisst. Ungetestet:
Was hier noch etwas unschön ist, sind die ”parallelen” Listen mit Werten die Zusammengehören, also die Wochentagnamen und die Daten für den jeweiligen Wochentag, und das gleiche noch einmal mit den Gerichtnamen. Da könnte man überlegen die mit in die Datenstruktur zu stecken und sich beispielsweise `collections.namedtupel` zu erstellen.
Aber fangen wir mit der ersten Zeile an. Die macht keinen Sinn, es sei denn Du hast wirklich im Ordner `/Documente/` einen Python-Interpreter mit dem Namen `Python`. Die „she bang“-Zeile sagt unter Unix mit welchem Programm eine Textdatei ausgeführt werden soll. Unter Windows wird die vom System selbst nicht ausgewertet, aber sie ist mindestens für den Leser interessant um zu sehen ob das für Python 2.x oder Python 3.x gedacht ist, und es gibt Programme wie Webserver und den Python-Launcher der mit *.py-Dateien verknüpft ist, die diese Zeile (teilweise) auswerten. Wenn das Python 3.x-Quelltext sein soll, dann ist die übliche Zeile ``#!/usr/bin/env python3``. Und das ist auch unter Windows sinnvoll, damit der Python-Launcher weiss das ein Python 3.x-Interpreter verwendet werden soll.
`Workbook` wird importiert, aber nirgends verwendet.
Namenskonvention in Python ist kleinbuchstaben_mit_unterstrichen für alles ausser Konstanten (KOMPLETT_GROSS) und Klassennamen (MixedCase). Also `speisenplan` oder `speisen_plan` statt `speisenPlan` und `sheetnamen` oder `sheet_namen` statt `sheetNamen`.
Wobei `sheet_namen` irreführend ist, denn hinter dem Namen würde man zum Beispiel eine Liste mit Zeichenketten erwarten, eben Namen von Arbeitsblättern. Es ist aber tatsächlich das Arbeitsblatt mit dem Namen 'Mittag'.
Und dann fangen die vielen Wiederholungen an. An der Stelle sollte man sich die Struktur der Daten anschauen, sich eine Struktur überlegen in der man die Daten hinterher haben möchte, und dann schauen wie man das eine in das andere Überführen kann.
Es geht ja anscheinend um fünf Wochentage, die jeweils immer gleich strukturiert sind, nämlich als drei Spalten für die drei Gerichte in denen fünf Zeilen pro Gericht stehen. Diese Blöcke haben einen Versatz von neun Zeilen vom Anfang und sind im Abstand von sechs Zeilen angeordnet. Das sind die Eckdaten die man im Programm als Zahlenwerte vorgeben kann.
Als Ziel könnte man eine Liste mit einem Eintrag pro Wochentag nehmen, wobei jeder Eintrag aus drei Listen mit den Zellwerten für das jeweilige Gericht bestehen.
`print()` wandelt die Argumente schon von selbst in Zeichenketten um vor der Ausgabe — ein extra `str()`-Aufruf ist da nicht nötig.
Das ganze ist dann auch mit Schleifen immer noch recht umfangreich; IMHO zu umfangreich für *eine* Funktion. Es werden ja auch zwei deutlich unterscheidbare Dinge getan: Die Daten werden eingelesen und sie werden (leicht) formatiert, ausgegeben. Eingabe, Verarbeitung, und Ausgabe sind traditionell Bereiche an denen man ein Programm gut und sinnvoll auftrennen kann. Eine Verarbeitung fällt hier ja erst einmal weg, also haben wir eine Funktion zum einlesen der Daten in eine sinnvoll Struktur, die Ausgabe der Daten, und das Hauptprogramm, das beides verbindet und üblicherweise in einer Funktion steht die `main()` heisst. Ungetestet:
Code: Alles auswählen
#!/usr/bin/env python3
import os
import openpyxl
DAY_NAMES = ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag']
MEAL_NAMES = ['I', 'II', 'FF']
FIRST_COLUMN_NUMBER = 1
FIRST_ROW_NUMBER = 9
MEALS_PER_DAY = 3
ROWS_PER_MEAL = 5
ROWS_PER_DAY = 6
assert ROWS_PER_DAY >= ROWS_PER_MEAL
def load_menu(filename):
sheet = openpyxl.load_workbook(filename)['Mittag']
days = list()
for i in range(len(DAY_NAMES)):
meals = list()
day_row_number = FIRST_ROW_NUMBER + i * ROWS_PER_DAY
meal_columns = sheet.iter_cols(
FIRST_COLUMN_NUMBER,
FIRST_COLUMN_NUMBER + MEALS_PER_DAY,
day_row_number,
day_row_number + ROWS_PER_MEAL
)
for column in meal_columns:
meals.append([cell.value for cell in column])
days.append(meals)
return days
def print_menu(days):
for day_name, meals in zip(DAY_NAMES, days):
for meal_name, meal in zip(MEAL_NAMES, meals):
print('{} Gericht {}'.format(day_name, meal_name))
for value in meal:
print(value)
def main():
days = load_menu('beispiel.xlsx')
print_menu(days)
if __name__ == '__main__':
main()
Please call it what it is: copyright infringement, not piracy. Piracy takes place in international waters, and involves one or more of theft, murder, rape and kidnapping. Making an unauthorized copy of a piece of software is not piracy, it is an infringement of a government-granted monopoly.
Hey __Blackjack__
Vielen dank für deinen Postund sorry für meine späte Antwort. Ich möchte bevor ich weiter an dem Programm schreibe, deinen Code für mich analysieren und vor allem verstehen. Das was du geschrieben hast ist natürlich völlig richtig.
Ich melde mich die Tage wieder, bin z.Z relativ eingespannt.
Vielen lieben Dank für deine Mühe!
Vielen dank für deinen Postund sorry für meine späte Antwort. Ich möchte bevor ich weiter an dem Programm schreibe, deinen Code für mich analysieren und vor allem verstehen. Das was du geschrieben hast ist natürlich völlig richtig.
Ich melde mich die Tage wieder, bin z.Z relativ eingespannt.
Vielen lieben Dank für deine Mühe!