Seite 1 von 2
Ich präsentiere ... den Bierrechner :)
Verfasst: Dienstag 26. Mai 2009, 13:06
von snafu
Code: Alles auswählen
#!/usr/bin/env python
import sys
def buy_beer(money, price_bootle, deposit_bottle, bring_back=True):
bottles, rest = divmod(money, price_bottle)
if not bring_back:
return bottles, rest
deposit = bottles * deposit_bottle
money_after = rest + deposit
return bottles, rest, deposit, money_after
if __name__ == '__main__':
try:
money = float(raw_input('Wieviel Geld in Bier anlegen: '))
price_bottle = float(raw_input('Preis pro Flasche: '))
deposit_bottle = float(raw_input('Pfandpreis pro Flasche: '))
except ValueError:
print >> sys.stderr, (
'Bitte nur Zahlen im korrekten Format angeben!\n'
'(z.B.: 2.70 statt 2,70)')
exit(1)
print (
'Kaufe %d Flaschen, habe noch %0.2f Euro\n'
'Nach dem Austrinken gibt es %0.2f Euro an Pfand\n'
'Kontostand nun %0.2f Euro'
% buy_beer(money, price_bottle, deposit_bottle))
Verfasst: Dienstag 26. Mai 2009, 13:23
von Hyperion
Das Tool fehlte mir immer bisher
Wunschliste:
- GUI
- Vordefinierter Pfand (für Glasflaschen in D imho 0.08€)
- Vordefinierte Sorten mit Preisen (Kästenpreise?)
- Schnittstelle für eigene Online-Preis-Crawler für den Getränkemarkt seines Vertrauens
Dazu Plugin-System, damit man z.B. so etwas wie den Random-Bier-Chooser proggen kann, der einem bei Entscheidungsschwierigkeiten hilft, eine Sorte zu wählen
Wenn man dann noch Bewertungssysteme mit einbaut und das ganz womöglich fit macht für den Semantic- und Social-Desktop von KDE, kann man noch einiges rausholen für das komplette Biertrinker-Rundum-Sorglos-Suite

Verfasst: Dienstag 26. Mai 2009, 13:31
von snafu
Zum Pfand: Hatte ich erst vordefiniert, aber wenn man mal ein Flens oder andere Flaschen mit Plöppverschluss kauft, sind es 15 cent Pfand.
Ich werde mal sehen, ob ich ein paar Sachen einbaue. GUI sehe ich aber vorerst als nachrangig an. Mich freut aber die prompte positive Resonanz.
Und hey: Ich finde das Ding ernsthaft praktisch.
Vielleicht sollte ich es auch in Pfandtomator oder so umbennen. Es gibt ja durchaus Leute mit exzessivem Cola- oder ClubMate-Verbrauch.
Verfasst: Dienstag 26. Mai 2009, 13:53
von Hyperion
Naja, man könnte ja ein Mapping zwischen Sorte und Flasche einbauen. Daraus bestimmt sich der Pfand
Da man ja so seine bevorzugten Biersorten hat, könnte das schon helfen
Na, GUI wäre eben praktischer für die Eingaben / Einstellungen. Aber klar, hat sicher keine Priorität

Verfasst: Dienstag 26. Mai 2009, 14:02
von n4p
Es fehlt in meinen Augen eher die Schleife, wie weit man an einem Abend ca. kommt. (vielleicht auch noch mit der Möglichkeit im noch nüchternen Zustand einen Restwert für Bus / Taxi zu hinterlegen).
Ansonsten schließe ich mich natürlich dem Wunsch nach Preislisten (mit Onlineaktualisierung versteht sich) an.

Verfasst: Dienstag 26. Mai 2009, 14:32
von Damaskus
n4p hat geschrieben:Es fehlt in meinen Augen eher die Schleife, wie weit man an einem Abend ca. kommt. (vielleicht auch noch mit der Möglichkeit im noch nüchternen Zustand einen Restwert für Bus / Taxi zu hinterlegen).
Dito! Und bitte die Auswahlmöglichkeit für Fäßer hinzufügen!
Danke!
Gruß
Damaskus
Verfasst: Dienstag 26. Mai 2009, 14:50
von Dauerbaustelle
Und bitte eine Möglichkeit "Ethanolgehalt" mit "Koffeingehalt" auszutauschen - für die Nicht-Alkoholtrinker hier ;)
Verfasst: Dienstag 26. Mai 2009, 15:03
von Leonidas
Alkoholfreies Bier mit Koffein?! Das geht ja mal gar nicht!

Verfasst: Dienstag 26. Mai 2009, 15:56
von snafu
beercalc.py
beercalc_gui.py
beercalc.ui
Erstmal nur die grafische Umsetzung der bisherigen Funktionen.
Würde wohl ein Hintergrundbild aussehen? Ich dachte
daran.
Verfasst: Dienstag 26. Mai 2009, 16:00
von Hyperion
Postestes das UI-File bitte auch noch? Würds gerne mal antesten!

Verfasst: Dienstag 26. Mai 2009, 16:02
von snafu
Hyperion hat geschrieben:Postestes das UI-File bitte auch noch? Würds gerne mal antesten!

Ja, ganz vergessen. Hab's dazueditiert. Is aber nix besonderes... In Guis bin ich eh nicht so gut (Gestaltung).
Verfasst: Dienstag 26. Mai 2009, 17:15
von lunar
Verfasst: Dienstag 26. Mai 2009, 17:41
von Hyperion
nice

Verfasst: Dienstag 26. Mai 2009, 22:28
von snafu
Ich stehe jetzt vor einem Problem, das ich mir nicht erklären kann: Das Abspeichern neuer Biere ist auf CLI-Ebene einigermaßen implementiert und ich habe mir einen um Biereigenschaften erweiterten ConfigParser geschrieben. Jetzt möchte ich das Ganze in die grafische Oberfläche einbauen und nutze dafür ein QTableWidget. Der entsprechende
Abschnitt der Doku empfiehlt das Abschalten der Sortierung, wenn man Elemente per Loop einfügen will. Aber warum wirft mir das einen Fehler?
Code: Alles auswählen
~$ ./beerconf_gui.py
<class 'PyQt4.QtGui.QTableWidget'>
Traceback (most recent call last):
File "/home/sebastian/beerconf_gui.py", line 32, in <module>
window = MainWindow()
File "/home/sebastian/beerconf_gui.py", line 15, in __init__
self.init_beers()
File "/home/sebastian/beerconf_gui.py", line 23, in init_beers
self.beers.sortingEnabled(False)
AttributeError: sortingEnabled
Das Widget erbt doch von QTableView und folglich wundert mich der AttributeError. Oder bin ich blind und übersehe einen Tippfehler meinerseits?
beerconf_gui.py
beerconf.py
beerconf.ui
Verfasst: Dienstag 26. Mai 2009, 22:51
von Hyperion
snafu hat geschrieben:
Code: Alles auswählen
~$ ./beerconf_gui.py
<class 'PyQt4.QtGui.QTableWidget'>
Traceback (most recent call last):
File "/home/sebastian/beerconf_gui.py", line 32, in <module>
window = MainWindow()
File "/home/sebastian/beerconf_gui.py", line 15, in __init__
self.init_beers()
File "/home/sebastian/beerconf_gui.py", line 23, in init_beers
self.beers.sortingEnabled(False)
AttributeError: sortingEnabled
Oder bin ich blind und übersehe einen Tippfehler meinerseits?
Ich glaube schon. Du rufst eine Methode auf, das ist aber ein Attribut!
Verfasst: Dienstag 26. Mai 2009, 23:11
von lunar
Darf man fragen, was die Verrenkungen in "BeerConfig.__init__()" zum Zweck haben? Eine Bibliotheksklasse sollte
niemals globale Änderungen zur Folge haben (in diesem Fall die Manipulation des Arbeitsverzeichnisses), zumal du ein paar Zeilen weiter unten doch zeigst, dass du eigentlich weißt, wie man es richtig macht (in dem man absolute Pfade mit "os.path.join()" erzeugt). Außerdem existiert "ConfigParser.read()", so dass du dir den Test auf Existenz auch sparen kannst (der sowieso nicht atomar ist, im schlimmsten Fall leert diese Chose daher die Konfigurationsdatei). Die Ausgabe mit "print" gehört da übrigens ebenfalls nicht hin, Ausgaben aus Bibliotheksklassen sind allenfalls per "logging" ok.
Desweiteren sollte "BeerConfig.beers()" einen Generator zurückgeben, die Liste ist an dieser Stelle schließlich noch nicht nötig. Außerdem würde ich daraus vielleicht eine Eigenschaft und keine Methode machen.
Das Speichern der Konfigurationsdatei hat in "BeerConfig.add_beer()" imho nichts zu suchen, ich würde dafür eine separate Methode erzeugen. Außerdem ist eine Konfigurationsdatei keine Binärdatei, im Mindestens aber solltest du dich für eine der beiden Möglichkeiten entscheiden. Binär speichern und als Text lesen macht Probleme unter Windows. Die Ausnahmebehandlung ist an dieser Stelle imho unelegant, der Einsatz von "ConfigParser.has_section()" würde an dieser Stelle zwei Codezeilen sparen, die keinen Mehrwert bringen und die Lesbarkeit eher verringern.
Im Bezug auf den eigentlichen Fehler solltest du dir in der Beschreibung dieser Eigenschaft mal ganz genau durchlesen, wie die dazugehörigen Getter und Setter wirklich heißen. Für den Aufruf von ".setFixedSize()" in "MainWindow.__init__()" sollte man dich eigentlich hauen

, eine vernünftige GUI nutzt Layoutmanagement. Die explizite Konvertierung zu "QString()" in Zeile 25 von "beerconf_gui" ist iirc nicht nötig, allerdings bin ich mir da nicht sicher, dass müsstest du ausprobieren. Die UI-Datei per Konstruktor zu übergeben, ist imho keine gute Idee, die UI ist schließlich elementarer Bestandteil des Objekts und eigentlich keine Sache, die der Nutzer der Klasse konfigurieren sollte. Ich würde den Pfad zur UI-Datei in ein Klassenattribut stecken. Und außerdem einen absoluten Pfad dafür nutzen, nicht immer liegt die UI-Datei im aktuellen Arbeitsverzeichnis. So gesehen ist es reines Glück, dass du "BeerConfig" erst
nach dem Laden der UI erzeugst, andersrum knallst nämlich (siehe oben).
Btw, du darfst auch "Schleife" sagen

Verfasst: Dienstag 26. Mai 2009, 23:11
von snafu
Danke, ich werde mich wohl mal intensiver mit diesem QTableWidget beschäftigen müssen. Denn Items werden trotzdem nicht anzeigt.
Code: Alles auswählen
def init_beers(self):
self.beers.setSortingEnabled(False)
for beer in self.beerconfig.beers():
print beer
item = QtGui.QTableWidgetItem(QtCore.QString(beer[0]))
self.beers.setItem(1, 1, item)
self.beers.setSortingEnabled(True)
Aber für heute ist erstmal gut...
Verfasst: Dienstag 26. Mai 2009, 23:20
von lunar
Naja, du solltest vielleicht jedem Element seine eigene Zeile gönnen

Außerdem es ist vielleicht auch erforderlich, dem Widget mittels ".setRowCount()" und ".setColumnCount()" mitzuteilen, wie viele Spalten und Zeilen es denn tatsächlich anzeigen soll.
Verfasst: Mittwoch 27. Mai 2009, 15:07
von snafu
Vielen Dank für die ganzen Tipps, Lunar. Ich bin jetzt auf eine Liste umgestiegen, da eine Tabelle nicht wirklich das war, was ich wollte.
Mit dem Design hat es bei BeerConf ganz gut geklappt. Bei BeerCalc bin ich allerdings auf Probleme gestoßen, die ich beim besten Willen nicht alleine gelöst bekomme. Und zwar möchte ich, dass die Überschriften einen anderen Abstand zur jeweiligen SpinBox haben als die darunter liegenden Buttons.
Dazu habe ich Überschrift + SpinBox zu einem vertikalen Design zusammengefasst und dieses Design anschließend als weiteres vertikales Design mit dem Button verbunden. Das ganze eben dreimal.
Soweit sieht das auch aus wie gewünscht. Nur wenn ich daraus ein komplettes (tabellarisches) Design für's ganze Fenster machen will, haut er mir einen Riesenabstand zwischen Text und SpinBox rein, obwohl `spacing` auf 0 steht:
Wo liegt hier das Problem?
Archiv mit Dateien
Verfasst: Mittwoch 27. Mai 2009, 17:22
von Hyperion
Ich glaube das Problem liegt daran, dass halt irgend etwas expandiert werden muss.
Ich habe mal ein wenig mit Deiner Datei rumgespielt und folgende Muster bekommen:
Letzteres wäre ja evtl. das, was Dir vorschwebt. Allerdings ist es ja eigentlich ziemlich sinnlos, da der untere Teil ja eben expandiert. Da wäre es wohl besser die Vertikale Größe festzusetzen.
Habe grad festgestellt, dass es noch einfacher geht, indem man die Berechnungsgruppen jeweils in ein VerticalLayout steckt und dann den Spacer direkt darunter einfügt. Darauf dann das Tabellarische Layout anwenden und man hat optisch dasselbe Ergebnis wie Screenshot3.
Generell muss man darauf achten, auch bei den Layouts die layoutSize auf setFixedSize zu stellen.
Vielleicht hilft Dir das ja weiter
