Localedatenbank zum Speichern von Rezepten und Speisen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Ooldman24
User
Beiträge: 16
Registriert: Samstag 11. August 2018, 14:09

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
__deets__
User
Beiträge: 14523
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

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.
Ooldman24
User
Beiträge: 16
Registriert: Samstag 11. August 2018, 14:09

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
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

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.
Ooldman24
User
Beiträge: 16
Registriert: Samstag 11. August 2018, 14:09

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. :)
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

@Ooldman24: klar ist das möglich, es ist sogar sinnvoll, klein anzufangen.
Ooldman24
User
Beiträge: 16
Registriert: Samstag 11. August 2018, 14:09

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.

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))

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 :)
Ooldman24
User
Beiträge: 16
Registriert: Samstag 11. August 2018, 14:09

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")
Habe gerade das hier gefunden und werde es gleich mal testen
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

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.
Ooldman24
User
Beiträge: 16
Registriert: Samstag 11. August 2018, 14:09

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.
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

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.
Mir ist nicht klar, was Du möchtest? Ich habe mal folgendes in der Konsole gemacht, möglicherweise kannst du davon etwas gebrauchen:

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
Falls es um den Aufbau des Wochenplans in der Datei geht, dann würde ich den Wochenplan einmal per Hand erzeugen und dann ein zweites Mal dynamisch mit Python, wobei ich die statischen Inhalte fest in die Datei schreibe und den Rest mittels Schleifen (1 x spaltenweise, 1 x zeilenweise) dynamisch. Es bietet sich an, dass erst einmal in der Konsole zu machen, um zu prüfen, dass die richtigen Menüs ausgewählt werden und dann erst - bei geeigneter Datenstruktur - ins Excel-File zu schreiben, also sich um diesen Teil zu kümmern.
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Schaust du mal, ob dir das hilft?

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)
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...
Ooldman24
User
Beiträge: 16
Registriert: Samstag 11. August 2018, 14:09

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 :lol:
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

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.
[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?

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.
Benutzeravatar
__blackjack__
User
Beiträge: 13071
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:

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()
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.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Ooldman24
User
Beiträge: 16
Registriert: Samstag 11. August 2018, 14:09

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!
Antworten