Guten tag,
Ich habe gerade angefangen python zu lernen und habe bereits ein kleines Programm geschrieben.
Das geht so nach dem motto
Liste wird angezeigt -> etwas aus der liste wählen -> wenn es was aus der liste war x ausführen
-> wenn nicht print anzeigen und zurück zum anfang
Das zurück zum anfang klappt bei mir nicht so :K um ehrlich zu sein weiß ich nichtmal wirklich wie ich das anstellen soll.
Hoffe mir kann da jemand helfen
mfG. NeverGod
zurückspringen bzw auswahl wiederholen?
- Rebecca
- User
- Beiträge: 1662
- Registriert: Freitag 3. Februar 2006, 12:28
- Wohnort: DN, Heimat: HB
- Kontaktdaten:
Schau dir mal while-Schleifen an.
Offizielles Python-Tutorial (Deutsche Version)
Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Code: Alles auswählen
# -*- coding: utf-8 -*-
import msvcrt
import time
import math
print "Wilkommen zum Programm fuer die Flaechen/Volumenberechnung"
print "von Formen und Koerpern."
print " "
print "Bitte waehlen sie aus der folgenden Liste welche Berechnung sie"
print "durchfuehren moechten"
print " "
print "Benutzerhinweis : Anstatt die ueblichen Kommata (,) benutzen sie"
print "bitte Punkte (.) !"
print " 1 = Flaechenberechnung eines Vierecks "
print " 2 = Volumenberechnung eines Quaders "
print " 3 = Flaechenberechnung eines Kreises "
print " 4 = Flaechenberechnung eines Dreiecks "
Z = input("Bitte waehlen sie jetzt: ")
if Z == 1:
print " Sie haben sich fuer die Berechnung eines Vierecks entschieden."
a = input("Bitte geben sie hier die Laenge der ersten Seite ein: ")
b = input("Bitte geben sie hier die Laenge der zweiten Seite ein: ")
A = a * b
print "Der Flaecheninhalt betraegt: ",A
raw_input(" ")
elif Z == 2:
print " Sie haben sich fuer die Berechnung eines Quaders entschieden."
a = input("Bitte geben sie die Laenge des Quaders ein: ")
b = input("Bitte geben sie die Breite des Quaders ein: ")
c = input("Bitte geben sie die Hoehe des Quaders ein: ")
A = a * b * c
print "Das Volumen des Quaders betraegt: ",A
raw_input(" ")
elif Z == 3:
print " Sie haben sich fuer die Berechnung eines Kreises entschieden."
a = float(input("Bitte geben sie den Radius des Kreises an: "))
B = ( a * a ) * 3.141592653589793238462643383279
print("Der Flaecheninhalt des Kreises betraegt: "),B
raw_input(" ")
elif Z == 4:
print "Sie haben sich fuer die Berechnung eines Dreiecks entschieden."
a = input("Bitte geben sie die Laenge der Grundseite des Dreiecks an: ")
b = input("Bitte geben sie die Hoehe des Dreiecks an: ")
A = 0,5 * a * b
print("Der Flaecheninhalt des Dreiecks betraegt: "),A
raw_input(" ")
elif Z < 1:
print "Bitte waehlen sie nur aus der liste"
raw_input(" ")
elif Z > 4:
print "Bitte waehlen sie nur aus der liste"
raw_input(" ")
@nevergod: Wie Rebecca schon sagte: ``while``-Schleife. "Springen" in Form einer GOTO-Anweisung gibt's in strukturierten Programmiersprachen in der Regel nicht.
Noch ein paar Anmerkungen:
`input()` solltest Du nicht benutzen, da wird ein Python-Ausdruck vom Benutzer erwartet und ausgewertet. Da kann der Benutzer zum einen Sachen eingeben die "böse" Sachen machen, und zum anderen ist es für Dich als Programmierer schwierig auf Fehleingaben zu reagieren. Da kann nämlich so ziemlich alles passieren, inklusive `SyntaxError` wenn der Benutzer etwas eingibt was kein korrekter Python-Ausdruck ist. Das trifft zum Beispiel sogar schon auf die leere Eingabe zu, also wenn der Benutzer einfach nur die Eingabetaste drückt. Also besser `raw_input()` und die Zeichenkette in den gewünschten Typ umwandeln.
Code sollte möglichst nicht auf Modulebene stehen und man sollte längere Quelltexte auf verschiedene Funktionen aufteilen.
Wenn etwas am Ende von *jedem* Zweig bei ``if``/``elif``/``else`` gemacht wird, dann kann man das auch *einmal* und *danach* machen.
Die Konstante für Pi ist im `math`-Modul bereits definiert.
Die Berechnung vom Dreieck hast Du offensichtlich nicht ausprobiert, denn da kommt eine "komische" Ausgabe bei heraus.
Die Bedingungen der beiden letzten ``elif``\s lassen sich zusammenfassen bzw. willst Du das ja haben wenn keine der anderen Bedingungen zugetroffen hat -- also eigentlich ist das ein bedingungsloser ``else``-Zweig.
Weder `msvcrt` noch `time` werden verwendet.
Noch ein paar Anmerkungen:
`input()` solltest Du nicht benutzen, da wird ein Python-Ausdruck vom Benutzer erwartet und ausgewertet. Da kann der Benutzer zum einen Sachen eingeben die "böse" Sachen machen, und zum anderen ist es für Dich als Programmierer schwierig auf Fehleingaben zu reagieren. Da kann nämlich so ziemlich alles passieren, inklusive `SyntaxError` wenn der Benutzer etwas eingibt was kein korrekter Python-Ausdruck ist. Das trifft zum Beispiel sogar schon auf die leere Eingabe zu, also wenn der Benutzer einfach nur die Eingabetaste drückt. Also besser `raw_input()` und die Zeichenkette in den gewünschten Typ umwandeln.
Code sollte möglichst nicht auf Modulebene stehen und man sollte längere Quelltexte auf verschiedene Funktionen aufteilen.
Wenn etwas am Ende von *jedem* Zweig bei ``if``/``elif``/``else`` gemacht wird, dann kann man das auch *einmal* und *danach* machen.
Die Konstante für Pi ist im `math`-Modul bereits definiert.
Die Berechnung vom Dreieck hast Du offensichtlich nicht ausprobiert, denn da kommt eine "komische" Ausgabe bei heraus.
Die Bedingungen der beiden letzten ``elif``\s lassen sich zusammenfassen bzw. willst Du das ja haben wenn keine der anderen Bedingungen zugetroffen hat -- also eigentlich ist das ein bedingungsloser ``else``-Zweig.
Weder `msvcrt` noch `time` werden verwendet.
Hallo nevergod,
ich bin auch noch ziemlich am Anfang, deshalb wird es an meinem Code sicherlich auch noch einiges zum Bemängeln geben.
Aber was ich bisher gelernt habe, hab' ich mal versucht, umzusetzen:
ich bin auch noch ziemlich am Anfang, deshalb wird es an meinem Code sicherlich auch noch einiges zum Bemängeln geben.
Aber was ich bisher gelernt habe, hab' ich mal versucht, umzusetzen:
Code: Alles auswählen
# -*- coding: utf-8 -*-
import os
import math
AUSWAHL_TXT = (('Flächen', 'Vierecks'), \
('Volumen', 'Quaders'), \
('Flächen', 'Kreises'), \
('Flächen', 'Dreiecks'))
STATUS_TXT = ('Ihre Auswahl: ', \
'OOPS! Falsche Eingabe! Bitte wählen Sie zwischen 1 und 4: ')
STATUS = 0
def menue():
#Wenn Du Windows verwendest, muss hier statt 'clear' -> 'cls' stehen
os.system('clear')
print("Wilkommen zum Programm fuer die Flaechen/Volumenberechnung")
print("von Formen und Koerpern.\n")
print("Bitte waehlen sie aus der folgenden Liste welche Berechnung")
print("sie durchfuehren moechten\n")
print("Benutzerhinweis : Anstatt die ueblichen Kommata (,) benutzen")
print("sie bitte Punkte (.) !\n\n")
print("1 = Flaechenberechnung eines Vierecks ")
print("2 = Volumenberechnung eines Quaders ")
print("3 = Flaechenberechnung eines Kreises ")
print("4 = Flaechenberechnung eines Dreiecks\n")
print("0 = Ende\n")
def status(status):
return(STATUS_TXT[status])
def bestaetigung(auswahl):
print("\nSie haben sich für die %sberechnung eines %s entschieden." % \
(AUSWAHL_TXT[auswahl-1][0], AUSWAHL_TXT[auswahl-1][1]))
def viereck():
laenge_1 = float(raw_input('Erste Seite: '))
laenge_2 = float(raw_input('Zweite Seite: '))
print('Der Flächeninhalt beträgt: %f' % \
(laenge_1 * laenge_2))
raw_input()
def quader():
laenge = float(raw_input('Länge: '))
breite = float(raw_input('Breite: '))
hoehe = float(raw_input('Höhe: '))
print('Das Volumen des Quaders beträgt: %f' % \
(laenge * breite * hoehe))
raw_input()
def kreis():
radius = float(raw_input('Radius: '))
print('Der Flächeninhalt des Kreises beträgt: %f ' % \
((radius * radius) * math.pi))
raw_input()
def dreieck():
laenge = float(raw_input('Länge: '))
hoehe = float(raw_input('Höhe: '))
print('Der Flächeninhalt des Dreiecks beträgt: %f' % \
(0.5 * laenge * hoehe))
raw_input()
while True:
menue()
auswahl = int(raw_input(status(STATUS)))
STATUS = 0
if auswahl == 1:
bestaetigung(auswahl)
viereck()
elif auswahl == 2:
bestaetigung(auswahl)
quader()
elif auswahl == 3:
bestaetigung(auswahl)
kreis()
elif auswahl == 4:
bestaetigung(auswahl)
dreieck()
elif auswahl == 0:
print('\nOver and out.')
exit()
else:
STATUS = 1
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit )
@mutetella: Die \ an den Zeilenenden sind alle überflüssig. Solange nich geöffnete Klammern nicht geschlossen wurden, weiss der Compiler auch so, dass die "logische Zeile" noch nicht zuende ist.
Namen komplett in Grossbuchstaben stehen per Konvention für Konstanten, `STATUS` wird aber während des Programms verändert.
Die Klammern bei den ``print``-Anweisungen sind irreführend. Das ist in Python <3 keine Funktion. Und Python 3.x kann es nicht sein, weil es dort den Namen `raw_input()` nicht mehr gibt. ``return`` ist ebenfalls keine Funktion.
Statt des Kommentars in `menu()` könnte man an der Stelle prüfen ob das Programm auf Windows läuft und dort entsprechend ``cls`` aufrufen. Bei Konsolenanwendungen die nicht tatsächlich eine "full screen" Oberfläche haben, ist das Löschen des Inhalts aber unüblich und auch nicht nett. Was immer da stand, könnte für den Benutzer wichtig gewesen sein, und nun kommt er da nicht mehr heran. Normalerweise kann man in den üblichen Konsolen-/Terminal-Fenstern ja nach oben scrollen um alte Ausgaben zu lesen, aber wenn man den Inhalt löscht ist zumindest eine "Seite" verloren.
Die `status()`-Funktion erscheint mir überflüssig.
Am Ende jeder Berechnungsfunktion steht ein ``raw_input()``, diese Wiederholung könnte man sich sparen. ``bestaetigung(auswahl)`` steht IMHO auch unnötig oft im Quelltext und die ``if``/``elif``-Kaskade könnte man durch ein Dictionary oder in diesem Fall auch eine Liste ersetzen. Ungetestet:
Du hast mit `AUSWAHL_TXT` ja schon so ein bisschen angefangen Gemeinsamkeiten der Berechnungen als Datenstruktur heraus zu ziehen -- das kann man noch viel weiter treiben, so dass man für eine weitere Berechnungsart das Programm nur noch an *einer* Stelle um einen entsprechenden Datensatz erweitern muss und nicht Änderungen über den gesamten Quelltext verstreut durchführen muss.
Namen komplett in Grossbuchstaben stehen per Konvention für Konstanten, `STATUS` wird aber während des Programms verändert.
Die Klammern bei den ``print``-Anweisungen sind irreführend. Das ist in Python <3 keine Funktion. Und Python 3.x kann es nicht sein, weil es dort den Namen `raw_input()` nicht mehr gibt. ``return`` ist ebenfalls keine Funktion.
Statt des Kommentars in `menu()` könnte man an der Stelle prüfen ob das Programm auf Windows läuft und dort entsprechend ``cls`` aufrufen. Bei Konsolenanwendungen die nicht tatsächlich eine "full screen" Oberfläche haben, ist das Löschen des Inhalts aber unüblich und auch nicht nett. Was immer da stand, könnte für den Benutzer wichtig gewesen sein, und nun kommt er da nicht mehr heran. Normalerweise kann man in den üblichen Konsolen-/Terminal-Fenstern ja nach oben scrollen um alte Ausgaben zu lesen, aber wenn man den Inhalt löscht ist zumindest eine "Seite" verloren.
Die `status()`-Funktion erscheint mir überflüssig.
Am Ende jeder Berechnungsfunktion steht ein ``raw_input()``, diese Wiederholung könnte man sich sparen. ``bestaetigung(auswahl)`` steht IMHO auch unnötig oft im Quelltext und die ``if``/``elif``-Kaskade könnte man durch ein Dictionary oder in diesem Fall auch eine Liste ersetzen. Ungetestet:
Code: Alles auswählen
def main():
berechnungen = [viereck, quarder, kreis, dreieck]
status = 0
while True:
menue()
auswahl = int(raw_input(STATUS_TXT[status]))
if auswahl == 0:
print '\nOver and out.'
break
if 0 < auswahl < len(berechnungen):
bestaetigung(auswahl)
berechnungen[auswahl]()
raw_input()
status = 0
else:
status = 1
Peinlich...BlackJack hat geschrieben:Die \ an den Zeilenenden sind alle überflüssig. Solange nich geöffnete Klammern nicht geschlossen wurden, weiss der Compiler auch so, dass die "logische Zeile" noch nicht zuende ist.
Ok, wusste ich nicht.BlackJack hat geschrieben:Namen komplett in Grossbuchstaben stehen per Konvention für Konstanten, `STATUS` wird aber während des Programms verändert.
Ich verwende auch noch kein Python 3.x, habe mir aber schon mal angewohnt, 'print' als Funktion zu notieren. Auch wenn aus 'raw_input()' ab 3.x 'input()' wird, will ich das allerdings noch nicht ersetzen, da von 'raw_input()' zu 'input()' mehr passiert als von 'print' zu 'print()'. Aber vielleicht sollte ich mich wirklich auf entweder oder beschränken...?BlackJack hat geschrieben:Die Klammern bei den ``print``-Anweisungen sind irreführend. Das ist in Python <3 keine Funktion. Und Python 3.x kann es nicht sein, weil es dort den Namen `raw_input()` nicht mehr gibt. ``return`` ist ebenfalls keine Funktion.
Geb' ich Dir Recht, aber in dem Fall ist soviel Menütext, Bestätigungstext, Eingabetext etc. pp dabei, dass ich es übersichtlicher finde, wenn gelöscht wird. Aber das kann man sicherlich auch anderst sehen...BlackJack hat geschrieben:...ist das Löschen des Inhalts aber unüblich und auch nicht nett...
Mir auch...BlackJack hat geschrieben:Die `status()`-Funktion erscheint mir überflüssig.
Das ist cool, hab' ich gleich geändert....!!BlackJack hat geschrieben:...und die ``if``/``elif``-Kaskade könnte man durch ein Dictionary oder in diesem Fall auch eine Liste ersetzen.
Habe ich jetzt mal gemacht. Aber vom Gefühl her scheint mir 'lambda' hier irgendwie nicht das Richtige zu sein, oder? Es sollte eine Möglichkeit geben, lediglich eine Rechenformel ablegen zu können, die dann mit veränderten Parametern aufgerufen werden kann. Ich hing' schon am operator-Modul, wollte quasi sowas wieBlackJack hat geschrieben:...so dass man für eine weitere Berechnungsart das Programm nur noch an *einer* Stelle um einen entsprechenden Datensatz erweitern muss...
Code: Alles auswählen
formel = operator.mul(a, b, c)
Oder ist 'lambda' doch der Weg zum Glück?
Hier also mal die Änderung:
Code: Alles auswählen
# -*- coding: utf-8 -*-
import os
import math
AUSWAHL_TXT = (('Flächen', 'Vierecks'),
('Volumen', 'Quaders'),
('Flächen', 'Kreises'),
('Flächen', 'Dreiecks'))
STATUS_TXT = ('Ihre Auswahl: ',
'OOPS! Falsche Eingabe! Bitte wählen Sie zwischen 1 und 4: ')
BERECHNUNGEN = {0:(('Erste Seite: ', 'Zweite Seite: '),
lambda value: 'Der Flächeninhalt beträgt: %f' %
(value[0] * value[1])),
1:(('Länge: ', 'Breite: ', 'Höhe: '),
lambda value: 'Das Volumen des Quaders beträgt: %f' %
(value[0] * value[1] * value[2])),
2:(('Radius: ', ),
lambda value: 'Der Flächeninhalt des Kreises beträgt: %f' %
((value[0] * value[0]) * math.pi)),
3:(('Länge: ', 'Höhe: '),
lambda value: 'Der Flächeninhalt des Dreiecks beträgt: %f' %
(0.5 * value[0] * value[1]))}
def menue():
if os.name == 'nt':
command = 'cls'
else:
command = 'clear'
os.system(command)
print("Wilkommen zum Programm fuer die Flaechen/Volumenberechnung")
print("von Formen und Koerpern.\n")
print("Bitte waehlen sie aus der folgenden Liste welche Berechnung")
print("sie durchfuehren moechten\n")
print("Benutzerhinweis : Anstatt die ueblichen Kommata (,) benutzen")
print("sie bitte Punkte (.) !\n\n")
print("1 = Flaechenberechnung eines Vierecks ")
print("2 = Volumenberechnung eines Quaders ")
print("3 = Flaechenberechnung eines Kreises ")
print("4 = Flaechenberechnung eines Dreiecks\n")
print("0 = Ende\n")
def bestaetigung(auswahl):
print("\nSie haben sich für die %sberechnung eines %s entschieden." %
(AUSWAHL_TXT[auswahl][0], AUSWAHL_TXT[auswahl][1]))
def berechnung(auswahl):
value = []
for eingabe in BERECHNUNGEN[auswahl][0]:
value.append(float(raw_input(eingabe)))
print(BERECHNUNGEN[auswahl][1](value))
def main():
status = 0
while True:
menue()
auswahl = int(raw_input(STATUS_TXT[status]))
if auswahl == 0:
print('\nOver and out.')
break
if 0 < auswahl <= len(BERECHNUNGEN):
bestaetigung(auswahl-1)
berechnung(auswahl-1)
raw_input()
else:
status = 1
if __name__ == '__main__':
main()
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit )
@mutetella: Du kannst ``print`` in Python <3 nicht als Funktion benutzen. Die Klammern machen da keinen Funktionsaufruf draus. Insbesondere funktioniert das nicht mehr wenn Du mehrere Werte durch Kommas getrennt ausgeben willst, dann wird bei der ``print``-Anweisung daraus nämlich ein Tupel wenn Klammern drum herum sind.
``lambda`` ist da schon eine gute Idee wenn man kurze Formeln speichern will. Ich hätte die aber wirklich nur zum Berechnen des Ergebnisses verwendet, dann kann man das später vielleicht auch in einer GUI wiederverwenden, wenn das Ergebnis nicht als Satz sondern vielleicht nur in einer Textbox ausgegeben werden soll.
Das Menü ist noch unabhängig von der Datenstruktur und müsste zusätzlich erweitert werden, wenn man noch etwas hinzufügt.
``lambda`` ist da schon eine gute Idee wenn man kurze Formeln speichern will. Ich hätte die aber wirklich nur zum Berechnen des Ergebnisses verwendet, dann kann man das später vielleicht auch in einer GUI wiederverwenden, wenn das Ergebnis nicht als Satz sondern vielleicht nur in einer Textbox ausgegeben werden soll.
Das Menü ist noch unabhängig von der Datenstruktur und müsste zusätzlich erweitert werden, wenn man noch etwas hinzufügt.
Hmm... hab' ja schon ein bischen ein schlechtes Gewissen, weil ich nevergod hier einfach seinen Thread übernehme. Ich hoffe, er sieht mir das nach...
Könntest Du mir da ein Stichwort geben?
Gruß
mutetella
Hier noch die Änderung:
Ich dachte, 'print' ist seit 2.5/2.6 (weiß net genau) sowohl als Funktion wie auch als Anweisung implementiert. Aber wenn man nur 2 Meter weiterdenkt... Wäre ja so, wie ich mir das wieder mal vorstelle, auch nicht möglich... Aber geändert hab' ich's jetzt nicht mehr, bin ich zu faul...BlackJack hat geschrieben:Die Klammern machen da keinen Funktionsaufruf draus.
Stimmt, da bin ich ja schon wieder bei meinem aktuellen MVC-Thema...BlackJack hat geschrieben:Ich hätte die aber wirklich nur zum Berechnen des Ergebnisses verwendet, ...
Jepp...BlackJack hat geschrieben:Das Menü ist noch unabhängig von der Datenstruktur...
Und wenn man "tiefer" einsteigen möchte? Welche Möglichkeit gibt es, um umfangreichere Berechnungen zu speichern. Wenn sich z. B. der User seine eigenen Formeln zusammenfügen und diese dann für spätere Verwendungen abspeichern kann?BlackJack hat geschrieben:``lambda`` ist da schon eine gute Idee wenn man kurze Formeln speichern will.
Könntest Du mir da ein Stichwort geben?
Gruß
mutetella
Hier noch die Änderung:
Code: Alles auswählen
# -*- coding: utf-8 -*-
import os
import math
BERECHNUNGEN = {0:{'title':'Flächenberechnung eines Vierecks',
'values':('Erste Seite: ', 'Zweite Seite: '),
'operation':lambda value: (value[0] * value[1])},
1:{'title':'Volumenberechnung eines Quaders',
'values':('Länge: ', 'Breite: ', 'Höhe: '),
'operation':lambda value: (value[0] * value[1] * value[2])},
2:{'title':'Flächenberechnung eines Kreises',
'values':('Radius: ', ),
'operation':lambda value: ((value[0] * value[0]) * math.pi)},
3:{'title':'Flächenberechnung eines Dreiecks',
'values':('Länge: ', 'Höhe: '),
'operation':lambda value: (0.5 * value[0] * value[1])}}
STATUS_TXT = ('Ihre Auswahl: ',
'OOPS! Falsche Eingabe! Bitte wählen Sie zwischen 1 und %i: ' %
(len(BERECHNUNGEN)))
def menue():
if os.name == 'nt':
command = 'cls'
else:
command = 'clear'
os.system(command)
print("Wilkommen zum Programm fuer die Flaechen/Volumenberechnung")
print("von Formen und Koerpern.\n")
print("Bitte waehlen sie aus der folgenden Liste welche Berechnung")
print("sie durchfuehren moechten\n")
print("Benutzerhinweis : Anstatt die ueblichen Kommata (,) benutzen")
print("sie bitte Punkte (.) !\n\n")
for i in xrange(len(BERECHNUNGEN)):
print('%i = %s' % (i+1, BERECHNUNGEN[i]['title']))
print("0 = Ende\n")
def bestaetigung(auswahl):
print("\nSie haben sich für die %s entschieden." %
(BERECHNUNGEN[auswahl]['title']))
def berechnung(auswahl):
value = []
for eingabe in BERECHNUNGEN[auswahl]['values']:
value.append(float(raw_input(eingabe)))
print('Das Ergebnis der %s lautet %f' %
(BERECHNUNGEN[auswahl]['title'],
BERECHNUNGEN[auswahl]['operation'](value)))
def main():
status = 0
while True:
menue()
auswahl = int(raw_input(STATUS_TXT[status]))
if auswahl == 0:
print('\nOver and out.')
break
if 0 < auswahl <= len(BERECHNUNGEN):
bestaetigung(auswahl-1)
berechnung(auswahl-1)
raw_input()
else:
status = 1
if __name__ == '__main__':
main()
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit )
@mutetella: Wenn Der Benutzer eigene Formeln erstellen können soll, dann müsste man erst einmal klarstellen wie das genau vor sich gehen soll. Wenn es darauf hinausläuft, dass er was eingibt, was dann mit `eval()` ausgewertet wird, kann man ihm auch gleich sagen wie er das Programm in Python erweitert. Wenn es kontrollierter ausgeführt werden soll und auch so etwas passieren soll wie: Benutzer gibt Formel ein und Programm fragt nach den Bedeutungen/Beschreibungen der verwendeten Variablennamen, dann muss man sich einen Parser für mathematische Ausdrücke schreiben. Das ist dann schon etwas aufwändiger.
Für meinen Geschmack hast Du zu viele und zu lang verkettete Index- bzw. Schlüsselzugriffe im Quelltext. Und anstelle von Dictionaries könnte man hier IMHO schon eine Klasse sinnvoll einsetzen um die Berechnungen zu beschreiben.
Für meinen Geschmack hast Du zu viele und zu lang verkettete Index- bzw. Schlüsselzugriffe im Quelltext. Und anstelle von Dictionaries könnte man hier IMHO schon eine Klasse sinnvoll einsetzen um die Berechnungen zu beschreiben.
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
AlsoBlackJack hat geschrieben:@mutetella: Du kannst ``print`` in Python <3 nicht als Funktion benutzen.
Code: Alles auswählen
from __future__ import print_function
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Ok, hab' das dict durch eine Klasse ersetzt. Zudem hab' ich noch kleinere Formatierungen eingebaut, deswegen die decode()-Sachen, weil len('ä') etc. sonst falsche Werte zurückgibt. Wir Deutschen haben es schon schwer... Zuerst hatte ich bereits beim Ablegen der Texte in Formula() alles decodiert. Hatte dann aber das Problem, dass raw_input() keinen utf8-decodierten Prompt aus Formula() akzeptiert. Hätte also dann wieder zurückcodieren müssen. Auch blöd.
Bin mir einfach nicht sicher, ob es nicht einen sinnigeren Weg gäbe...
Gruß
mutetella
Bin mir einfach nicht sicher, ob es nicht einen sinnigeren Weg gäbe...
Bin mir nicht sicher, was Du meinst. Findest Du ein dict mit dict's als values schon zu viel? Ok, in diesem Fall ist eine Klasse in jedem Fall eleganter. Ich verwende aber dict's gerne zum Ablegen von config-Parametern oder auch zum Cachen. Und hab' ich schnell mal 2 - 3 Ebenen. Nicht so dolle, oder?BlackJack hat geschrieben:...zu lang verkettete Index- bzw. Schlüsselzugriffe...
Gruß
mutetella
Code: Alles auswählen
# -*- coding: utf-8 -*-
import os
formulas = []
class Formula(object):
counter = 0
def __init__(self, title, values, formula):
self.title = title
self.values = values
self.formula = formula
Formula.counter += 1
def calc(self, value):
return eval(self.formula)
def menue(status):
if os.name == 'nt':
command = 'cls'
else:
command = 'clear'
os.system(command)
status_txt = ('Ihre Auswahl: ',
'OOPS! Falsche Eingabe! Bitte wählen Sie zwischen 1 und %i: ' %
(Formula.counter))
print("Wilkommen zum Programm fuer die Flaechen/Volumenberechnung")
print("von Formen und Koerpern.\n")
print("Bitte waehlen sie aus der folgenden Liste welche Berechnung")
print("sie durchfuehren moechten\n")
print("Benutzerhinweis : Anstatt die ueblichen Kommata (,) benutzen")
print("sie bitte Punkte (.) !\n")
for i in xrange(Formula.counter):
print('%i = %s' % (i+1, formulas[i].title))
print('\n-1 = Formel hinzufügen')
print(' 0 = Ende\n')
return int(raw_input(status_txt[status]))
def bestaetigung(choice):
title_length = len(formulas[choice].title.decode('utf-8'))
print('\n%s\n%s\n' %
(formulas[choice].title,
title_length * '-'))
def berechnung(choice):
value = []
r_margin = len(sorted(
[v.decode('utf-8') for v in formulas[choice].values],
key=len)[-1]) + 1
for eingabe in formulas[choice].values:
eingabe = eingabe + (r_margin - len(eingabe.decode('utf-8'))) * ' '
value.append(float(raw_input(eingabe)))
print('\nErgebnis: %f' %
(formulas[choice].calc(value)))
def add_formula(title=None, values=None, formula=None):
if title == values == formula == None:
counter = 0
values = []
title = raw_input('Formeltitel: ')
while True:
value = raw_input('Name für value[%i]: '% (counter))
counter += 1
if value == '':
break
values.append(value)
formula = raw_input('Formel: ')
formulas.append(Formula(title, values, formula))
def choice(status=0):
while True:
choice = menue(status)
if choice == 0:
print('\nOver and out.')
break
elif choice == -1:
add_formula()
elif 0 < choice <= Formula.counter:
bestaetigung(choice - 1)
berechnung(choice - 1)
raw_input()
status = 0
else:
status = 1
def main():
DUMMY = (('Flächenberechnung eines Vierecks',
['Erste Seite:', 'Zweite Seite:'],
'value[0] * value[1]'),
('Volumenberechnung eines Quaders',
['Länge:', 'Breite:', 'Höhe:'],
'value[0] * value[1] * value[2]'),
('Flächenberechnung eines Kreises',
['Radius:'],
'(value[0] * value[0]) * 3.1415926535897931'),
('Flächenberechnung eines Dreiecks',
['Länge:', 'Höhe:'],
'0.5 * value[0] * value[1]'))
for title, values, formula in DUMMY:
add_formula(title, values, formula)
choice()
if __name__ == '__main__':
main()
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit )
@mutetella: `Formula.counter` ist keine gute Idee. Damit wird in der Klasse eine Information gespeichert, die eigentlich zu dem Container gehört in den man die Objekte steckt, und die dort ja auch via `len()` verfügbar ist. Auf der Klasse sorgt das dafür, dass die Klasse nicht so flexibel wiederverwendbar ist. Zum Beispiel könnte man die Objekte ja via `pickle` in eine Datei speichern und später wieder laden. Dann könnte der Benutzer Formelsammlungen zu verschiedenen Themengebieten anlegen. In dem Falle funktioniert so ein "globaler" Zähler aber nicht mehr.
Zu `eval()` sag ich jetzt mal nichts.
Was die Kodierungen angeht, wären Unicode-Literale schon der richtige Weg, allerdings muss man dann Zeichenketten sowohl bei der Aus- als auch bei der Eingabe entsprechend umkodieren.
Die Berechnung von `r_margin` erscheint mir ein wenig kompliziert. Schau Dir mal die `max()`-Funktion an. Und für die Formatierung der `eingabe` wozu man bei Zeichenkettenformatierung mittels ``%`` den '*' benutzen kann.
Zu `eval()` sag ich jetzt mal nichts.
Was die Kodierungen angeht, wären Unicode-Literale schon der richtige Weg, allerdings muss man dann Zeichenketten sowohl bei der Aus- als auch bei der Eingabe entsprechend umkodieren.
Die Berechnung von `r_margin` erscheint mir ein wenig kompliziert. Schau Dir mal die `max()`-Funktion an. Und für die Formatierung der `eingabe` wozu man bei Zeichenkettenformatierung mittels ``%`` den '*' benutzen kann.
Jetzt wollte ich gleich mal anwenden, worüber ich in meinem 'Methoden-Attribut'-Thread bereits so einiges, auch von Dir, gelernt habe. Nun ja, und dann gleich ein Griff ins Klo... Aber mir ist klar, warum das in diesem Fall nicht so geschickt ist.BlackJack hat geschrieben:`Formula.counter` ist keine gute Idee.
Doch, bitte! Ich hab' bereits eine Idee für ein Feature in meinem Kalenderprogramm, das in eine ähnliche Richtung gehen soll, wie die Formelgeschichte hier...BlackJack hat geschrieben:Zu `eval()` sag ich jetzt mal nichts.
Du meinst also, bevor Literale abgelegt werden (wo auch immer), erstmal mit decode in Unicode-Literale umwandeln und bei Verwendung dann wieder encoden?BlackJack hat geschrieben:Was die Kodierungen angeht, wären Unicode-Literale schon der richtige Weg, allerdings muss man dann Zeichenketten sowohl bei der Aus- als auch bei der Eingabe entsprechend umkodieren.
Das liegt daran, dass die Berechnung von 'r_margin' ein wenig kompliziert ist.BlackJack hat geschrieben:Die Berechnung von `r_margin` erscheint mir ein wenig kompliziert.
O Mann, genau sowas hab' ich gesucht...BlackJack hat geschrieben:Schau Dir mal die `max()`-Funktion an.
Is cool man... Ich muss mal dringend die built-in Funktionen anschauen. Man überfliegt sowas ja meist nur, aber da sind richtige Schätze drin....BlackJack hat geschrieben:...bei Zeichenkettenformatierung mittels ``%`` den '*' benutzen kann.
Noch 'ne ganz andere Frage:
Was hat es eigentlich mit ``xxx``, `xxx` oder 'xxx' auf sich?
Ich stell' jetzt das Programm nochmal komplett rein, auch wenn's den Thread langsam groß macht...
Code: Alles auswählen
# -*- coding: utf-8 -*-
import os
formulas = []
class Formula(object):
def __init__(self, title, values, formula):
self.title = title
self.values = values
self.formula = formula
def calc(self, value):
return eval(self.formula)
def menue(status):
if os.name == 'nt':
command = 'cls'
else:
command = 'clear'
os.system(command)
status_txt = ('Ihre Auswahl: ',
'OOPS! Falsche Eingabe! Bitte wählen Sie zwischen 1 und %i: ' %
(len(formulas)))
print("Wilkommen zum Programm fuer die Flaechen/Volumenberechnung")
print("von Formen und Koerpern.\n")
print("Bitte waehlen sie aus der folgenden Liste welche Berechnung")
print("sie durchfuehren moechten\n")
print("Benutzerhinweis : Anstatt die ueblichen Kommata (,) benutzen")
print("sie bitte Punkte (.) !\n")
for i in xrange(len(formulas)):
print('%i = %s' % (i+1, formulas[i].title))
print('\n-1 = Formel hinzufügen')
print(' 0 = Ende\n')
return int(raw_input(status_txt[status]))
def bestaetigung(choice):
title_length = len(formulas[choice].title.decode('utf-8'))
print('\n%s\n%s\n' %
(formulas[choice].title,
title_length * '-'))
def berechnung(choice):
value = []
r_margin = len(max(formulas[choice].values)) + 1
for eingabe in formulas[choice].values:
gap = r_margin - len(eingabe.decode('utf-8'))
eingabe = '%s%*s' % (eingabe, gap, ' ')
value.append(float(raw_input(eingabe)))
print('\nErgebnis: %f' %
(formulas[choice].calc(value)))
def add_formula(title=None, values=None, formula=None):
if title == values == formula == None:
counter = 0
values = []
title = raw_input('Formeltitel: ')
while True:
value = raw_input('Name für value[%i]: '% (counter))
counter += 1
if value == '':
break
values.append(value)
formula = raw_input('Formel: ')
formulas.append(Formula(title, values, formula))
def choice(status=0):
while True:
choice = menue(status)
if choice == 0:
print('\nOver and out.')
break
elif choice == -1:
add_formula()
elif 0 < choice <= len(formulas):
bestaetigung(choice - 1)
berechnung(choice - 1)
raw_input()
status = 0
else:
status = 1
def main():
DUMMY = (('Flächenberechnung eines Vierecks',
['Erste Seite:', 'Zweite Seite:'],
'value[0] * value[1]'),
('Volumenberechnung eines Quaders',
['Länge:', 'Breite:', 'Höhe:'],
'value[0] * value[1] * value[2]'),
('Flächenberechnung eines Kreises',
['Radius:'],
'(value[0] * value[0]) * 3.1415926535897931'),
('Flächenberechnung eines Dreiecks',
['Länge:', 'Höhe:'],
'0.5 * value[0] * value[1]'))
for title, values, formula in DUMMY:
add_formula(title, values, formula)
choice()
if __name__ == '__main__':
main()
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit )
@mutetella: `eval()` finde ich halt "evil".
Literale heissen die Zeichenfolgen *im Quelltext* für bestimmte Datentypen, für die es Syntax gibt um Konstanten von ihnen direkt zu schreiben. Also zum Beispiel Zahlen oder Zeichenketten. Zur Laufzeit kann man also nichts in ein Literal umwandeln. Ich meinte dass man wenn man mit Unicode arbeitet, das schon von Anfang an konsequent tun sollte. Also nicht ``'hällö'.decode('utf-8')`` sondern gleich ein Unicode-Literal in den Quelltext: ``u'hällö'``.
Jetzt musst Du `max()` nur noch richtig einsetzen:
Ich verwende bei Texten meistens reStructuredText als Auszeichnung, auch wenn das Medium das eigentlich gar nicht unterstützt. Darum die ``x`` und `x`.
Zum Quelltext: `berechung()` könnte man gleich das ausgewählte `Formula`-Exemplar übergeben, dann braucht man dort nicht auf das globale `formulas` zurückgreifen.
Literale heissen die Zeichenfolgen *im Quelltext* für bestimmte Datentypen, für die es Syntax gibt um Konstanten von ihnen direkt zu schreiben. Also zum Beispiel Zahlen oder Zeichenketten. Zur Laufzeit kann man also nichts in ein Literal umwandeln. Ich meinte dass man wenn man mit Unicode arbeitet, das schon von Anfang an konsequent tun sollte. Also nicht ``'hällö'.decode('utf-8')`` sondern gleich ein Unicode-Literal in den Quelltext: ``u'hällö'``.
Jetzt musst Du `max()` nur noch richtig einsetzen:
Code: Alles auswählen
In [835]: len(max(['aa', 'z']))
Out[835]: 1
In [836]: max(['aa', 'z'], key=len)
Out[836]: 'aa'
In [837]: len(max(['aa', 'z'], key=len))
Out[837]: 2
Zum Quelltext: `berechung()` könnte man gleich das ausgewählte `Formula`-Exemplar übergeben, dann braucht man dort nicht auf das globale `formulas` zurückgreifen.
Aus denselben Gründen wie bei 'input()'? Denn über die Funktion 'add_Formula()' geschieht ja letztlich nichts anderes als ein 'raw_input(eval())', das wiederum einem 'input()' entspricht. Oder gibt es noch andere Gründe?BlackJack hat geschrieben:`eval()` finde ich halt "evil".
Ok, das wusste ich nicht...BlackJack hat geschrieben:Literale heissen die Zeichenfolgen *im Quelltext*...
Ich denke mal, die Unicode-Geschichte wird mich immer wieder beschäftigen, aber bitte nicht heute...
Ich hasse es, wenn ich so schlampig bin...BlackJack hat geschrieben:Jetzt musst Du `max()` nur noch richtig einsetzen
Aber es steckt auch eine gewisse Fiesheit dahinter, dass 'a' < 'z' ist.
Ich werde mich jetzt NICHT mit reSructuredText beschäftigen... Nein, nein, nein... Aber den Link behalt' ich...BlackJack hat geschrieben:Ich verwende bei Texten meistens reStructuredText als Auszeichnung, ...
BlackJack hat geschrieben:`berechung()` könnte man gleich das ausgewählte `Formula`-Exemplar übergeben, ...
Code: Alles auswählen
def berechnung(formula):
value = []
r_margin = len(max(formula.values, key=len)) + 1
for eingabe in formula.values:
gap = r_margin - len(eingabe.decode('utf-8'))
eingabe = '%s%*s' % (eingabe, gap, ' ')
value.append(float(raw_input(eingabe)))
print('\nErgebnis: %f' %
(formula.calc(value)))
Gruß
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit )