Mein erstes kleines Programm...

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.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

EyDu hat geschrieben:Schau doch mal auf deine Zeilen 7 bis 10. Du machst zwei Abfragen und wandelst zweimal mit float_input um. Du machst also identische Dinge, das solltest du zusammenfassen.
Zum Thema "zusammenfassen" habe ich mir folgendes überlegt und mir ist dabei was aufgefallen:
Modul: Kalkulationsformeln.py

Code: Alles auswählen

[...]
def Replacer(prompt):
    f =  prompt.replace(",", ".") # Ausgabe: Das ist kein Text.
    try:
        return float(f)
    except ValueError:
        raise ValueError('Please give me a decimal!')
    
def Replacer1(Zahl, Zahl1):
    f1 =  Zahl.replace(",", ".")
    f2 =  Zahl1.replace(",", ".")
    try:
        return float(f1), float(f2)
    except ValueError:
        raise ValueError('Please give me a decimal!')
[...]
Es gibt in der Kalkulation Stellen, da muss man nur eine, und Stellen, da muss man mehrere Eingaben machen. Demzufolge muss ich zwei Funktionen schreiben, einmal eine Funktion mit einem Rückgabewert, und eine Funktion mit mehreren Rückgabewerten. Bläht sich dadurch das Modul nicht unnötig auf?

Hauptprogramm: Kalkulation.py

Code: Alles auswählen

import Kalkulationsformeln
[...]
def BKV():# Beschaffungskalkulation(Vorwaerts)
    print ""
    print " Die Beschaffungskalkulation(Vorwaerts) wurde gestartet."
    print ""
    LP = raw_input(" Listenpreis: ")
    LR = raw_input(" - Lieferantenrabatt (%): ")
    Wert = Kalkulationsformeln.Replacer1(LP, LR) # Übergabe mehrerer Werte
    ZKP = Kalkulationsformeln.Zieleinkaufspreis(Wert[0], Wert[1]) # Die beiden Rückgabewerte [0] und [1] verarbeiten
    print " = Zieleinkaufspreis: ", str(ZKP) + " Euro"
[...]
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Naja, falsch zusammengefasst ;-) In "Replacer1" wiederholst du dich wieder. Zu ersetzt an zwei Stellen das Komma durch einen Punkt und wandelst an zwei Stellen den Wert in einen float um. Was würdest du bei 100000 Zahlen machen? ;-) Zusätzlich hast du jetzt auch noch an zwei Stellen die Eingaben. mutetella hat dir auf Seite 1 ja bereits die Musterlösung gezeigt.
Das Leben ist wie ein Tennisball.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

EyDu hat geschrieben:Naja, falsch zusammengefasst ;-) In "Replacer1" wiederholst du dich wieder. Zu ersetzt an zwei Stellen das Komma durch einen Punkt und wandelst an zwei Stellen den Wert in einen float um. Was würdest du bei 100000 Zahlen machen? ;-) Zusätzlich hast du jetzt auch noch an zwei Stellen die Eingaben. mutetella hat dir auf Seite 1 ja bereits die Musterlösung gezeigt.
Also mit mutetellas Musterlösung möchte ich erst einmal nicht arbeiten, weil ich erst einmal meinen Code auf die Reihe kriegen will :-) Und das ich mich in "Replacer1" wiederhole, ist mir auch aufgefallen, jedoch muss ich das ja auch tun. Immerhin gibt es ja unterschiedliche Anzahlen von Rückgabewerten? Mhmh?
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

pillmuncher hat geschrieben:@sophus: schau dir mal das hier an: http://www.python-forum.de/pastebin.php?mode=view&s=414
Das Definieren der Hilfsfunktionen ist eine gute Idee. Die einzelnen Kalkulationen hätte ich aber wohl eher mit einer abstrakten Funktion verwirklicht, die als Parameter den gewünschten Prompt und eine Berechnungsfunktion erwartet. Für letzteres kann man prima Pythons `lambda`-Schlüsselwort einsetzen.

Die abstrakte Funktion würde sich dann um die Abfrage und Aufbereitung der Benutzereingabe sowie um die Anwendung der übergebenen Berechnungsfunktion auf diese Eingabe kümmern und das Ergebnis der Berechnung ausspucken. Um die Formatierung der Rückgabe hätte sich der Aufrufer zu kümmern.

Mit diesem Vorschlag möchte ich übrigens nicht behaupten, dass dein Ansatz völlig falsch sei. Dein Code fühlt sich im Hinblick auf den Anwendungsfall aber doch ziemlich "noisy" an. Ich würde eine etwas direktere Herangehensweise bevorzugen, anstatt die Zwischenschicht durch die `calculate_*`-Funktionen zu haben.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

pillmuncher hat geschrieben:@sophus: schau dir mal das hier an: http://www.python-forum.de/pastebin.php?mode=view&s=414
Hallo, pillmuncher,

ich werde mir deinen Vorschlag morgen genauer anschauen. Auf dem ersten Blick wirkt es auf einen Anfänger sehr erschlagend :-) Aber eine Frage mal zwischendurch: Wieso habt ihr immer den Drang auf englisch zu schreiben bzw. die Funktionen englische Namen zu geben? Dies ist für mich insofern befremdlich, weil wir hier nicht international "arbeiten". Ich finde es ja schön, dass man sein Englisch immer ein Bisschen auffrischen will, aber für meinen Geschmack wirkt es überzogen :-)
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Sophus hat geschrieben:Wieso habt ihr immer den Drang auf englisch zu schreiben bzw. die Funktionen englische Namen zu geben? Dies ist für mich insofern befremdlich, weil wir hier nicht international "arbeiten". Ich finde es ja schön, dass man sein Englisch immer ein Bisschen auffrischen will, aber für meinen Geschmack wirkt es überzogen :-)
  • Englisch ist die lingua franca der Informatik.
  • Englisch ist meist kürzer und prägnanter.
  • So gut wie alle Dokumentation ist in Englisch. Wenn ich Dokumentation lese und das gelesene auf meinen Code anwenden will, dann habe ich, wenn ich dabei die Sprache in der ich denke wechsle, auch einen Kontextwechsel. Das erzeugt unnützen mentalen Reibungswiderstand.
  • Die Namen der Schlüsselworte der allermeisten Programmiersprachen sind englische Worte. Ebenso die ihrer Standardfunktionen. Ebenso die der allermeisten Bibliotheken. Auch hier gilt, was ich zu Kontextwechsel geschrieben habe.
  • Außerdem, if ich read einen source, der two Sprachen mixed, finde I das very irritierend. Dann lieber gleich alles auf Deutsch:

Code: Alles auswählen

aus __zukunft__ importiere teilung, druck_funktion
 
aus dezimal importiere Dezimal, ABRUNDEN
 
 
def geld_betrag(dezimal):
    gib_zurück dezimal.quantisiere(Dezimal('.01'), runden=ABRUNDEN)
 
 
def addiere_prozent(betrag, prozent):
    gib_zurück geld_betrag(betrag + betrag * prozent)
 
 
def subtrahiere_prozent(betrag, prozent):
    gib_zurück geld_betrag(betrag - betrag * prozent)
 
 
def frage_nach_geld_betrag(eingabeaufforderung):
    gib_zurück geld_betrag(Dezimal(rohe_eingabe(eingabeaufforderung + ': ').ersetze(',', '.')))
Ist halt dann kein Python mehr.

Auch lustig:

Code: Alles auswählen

क = 1;
कुल = 0;
जब तक क छोटा है 10 से  {
    कुल += क;
}
छापो कुल

कार्य खाली मुख्य ( )      अंक समय       लिखें "Enter current time"    
     पढें समय        अगर [ समय < 12 ]    
        लिखें "Good Morning"    
  वरनाअगर [ समय >= 12 और समय < 16 ]    
           लिखें "Good Afternoon"    
  वरना              लिखें "Good Evening"    
  खत्म अगर    
खत्म कार्य
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

@Sophus: Das mit dem Menü sieht gut aus - ich hoffe Du hast das auch an sich verstanden :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

Es gab ja mal die deutsche Programmiersprache Teuton die eine Art Präprozessor für Python ist. :-)

Ein weiterer praktischer Grund für Englisch ist die Namensvergabe für Exemplare von Datencontainer-Typen wie Listen & Co: Wenn man für die Bezeichnung die Mehrzahl von dem nimmt wie man ein einzelnes Element nennen würde, dann funktioniert das im Englischen so gut wie immer problemlos, während es im Deutschen doch relativ viele Fälle gibt wo Einzahl und Mehrzahl die gleiche Bezeichnung haben.

Ebenfalls problematisch ist die Möglichkeit für zwei verschiedene Dinge die gleiche Bezeichnung in zwei verschiedenen Sprachen im gleichen Namensraum zu haben. Das finde ich sehr verwirrend.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Hyperion hat geschrieben:@Sophus: Das mit dem Menü sieht gut aus - ich hoffe Du hast das auch an sich verstanden :-)
Hallo Hyperion, das mit dem Menu habe ich relativ gut aufgenommen. Vielen Dank dafür.
Sophus hat geschrieben:
pillmuncher hat geschrieben:@sophus: schau dir mal das hier an: http://www.python-forum.de/pastebin.php?mode=view&s=414
pillmuncher hat geschrieben:
  • Englisch ist die lingua franca der Informatik.
  • Englisch ist meist kürzer und prägnanter.
  • So gut wie alle Dokumentation ist in Englisch. Wenn ich Dokumentation lese und das gelesene auf meinen Code anwenden will, dann habe ich, wenn ich dabei die Sprache in der ich denke wechsle, auch einen Kontextwechsel. Das erzeugt unnützen mentalen Reibungswiderstand.
  • Die Namen der Schlüsselworte der allermeisten Programmiersprachen sind englische Worte. Ebenso die ihrer Standardfunktionen. Ebenso die der allermeisten Bibliotheken. Auch hier gilt, was ich zu Kontextwechsel geschrieben habe.
  • Außerdem, if ich read einen source, der two Sprachen mixed, finde I das very irritierend. Dann lieber gleich alles auf Deutsch:
Hallo pillmuncher, das Englisch mittlerweile eine Weltsprache ist, ist mir durchaus einleuchtend :-) An sich habe ich auch nichts dagegen. Aber ich denke mir folgendes: Ich bin in einem deutschen Forum, unterhalte mich hier mit deutschen Bürgern, wieso also das "krampfhafte" Englisch? Wenn ich ein Programm schreiben würde, an welcher Menschen aus aller Welt arbeiten, sehe ich das vollkommen ein, dass man sich sowohl in der Programmiersprache (englische Variablen, englische Namensgebungen) als auch außerhalb der Programmierwelt (Kommentare, Besprechungen) auf Englisch verständigt. Aber lasst uns nicht darauf aufhalten. Ich musste nur etwas schmunzeln.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Modul: Kalkulationsformeln.py

Code: Alles auswählen

[...]
def Ersetzer(*Zahl): # beliebig viele Parameter
    f =  Zahl.replace(",", ".") 
    try:
        return float(f)
    except ValueError:
        raise ValueError('Dezimalzahlen bitte!')
[...]
Meine Idee war, beliebig viele Parameter entgegen zu nehmen. Es kann ja sein, dass ich a priori nicht weiß, wie viele Parameter es werden wird.

Hauptprogramm: Kalkulation.py

Code: Alles auswählen

import Kalkulationsformeln
[...]
def BKV():# Beschaffungskalkulation(Vorwaerts)
    print ""
    print " Die Beschaffungskalkulation(Vorwaerts) wurde gestartet."
    print ""
    LP = raw_input(" Listenpreis: ")
    LR = raw_input(" - Lieferantenrabatt (%): ")
    Wert = Kalkulationsformeln.Ersetzer(LP, LR) # Übergabe mehrerer Werte
    ZKP = Kalkulationsformeln.Zieleinkaufspreis(Wert[0], Wert[1]) # Die beiden Rückgabewerte [0] und [1] verarbeiten
    print " = Zieleinkaufspreis: ", str(ZKP) + " Euro"
[...]
Fehlermeldung
Traceback (most recent call last):
File "D:\Dan\Python\Übung\Calc\Kalkulation.py", line 165, in <module>
main()
File "D:\Dan\Python\Übung\Calc\Kalkulation.py", line 161, in main
handle_menu(menu)
File "D:\Dan\Python\Übung\Calc\Kalkulation.py", line 145, in handle_menu
menu[choice][1]()
File "D:\Dan\Python\Übung\Calc\Kalkulation.py", line 30, in BKV
Wert = Kalkulationsformeln.Replacer(LP, LR)
File "D:\Dan\Python\Übung\Calc\Kalkulationsformeln.py", line 7, in Replacer
f = Zahl.replace(",", ".") # Ausgabe: Das ist kein Text.
AttributeError: 'tuple' object has no attribute 'replace'
Wie ich also sehe, hat Tuple ein Problem mit dem Attribut "Replace". Wäre auch zu schön gewesen, wenn es mal auf Anhieb klappt :-) Gibt es in Python eine Art "Collection"? In VB6 kann man sehr gut mit "Collection" arbeiten. Dort sammelt man alle Daten und verarbeitet sie. So wollte ich das auch in der Funktion Ersetzer machen.
Üpsilon
User
Beiträge: 222
Registriert: Samstag 15. September 2012, 19:23

du suchst das sprachmittel der list-comprehension. damit kannst du auf alle elemente einer liste eine funktion anwenden. https://docs.python.org/2/tutorial/data ... rehensions

Ersetzer ist übrigens ein komischer name. nenn es string_to_float oder so.
PS: Die angebotene Summe ist beachtlich.
BlackJack

@Sophus: Ergänzend zum Namen: Funktionen und Methoden bekommen üblicherweise Tätigkeiten als Namen weil die etwas tun. Bezeichnungen von ”Dingen” im weitesten Sinne sind für Klassennamen. Und nur Klassennamen und Konstantennamen fangen mit einem Grossbuchstaben an, bei Konstanten geht's komplett in Grossbuchstaben weiter. Alles andere `keinbuchstaben_mit_unterstrichen_als_trenner`.

Wie schon gesagt werden Container in der Regel in der Mehrzahl benannt. Deshalb ist `zahl` für etwas das keine Zahl ist, sondern eine Sequenz von Zahlen, ein schlechter Name.

Mit ``*``-Magie bei Funktionargumenten sollte man sparsam umgehen. Das verbaut einem Möglichkeiten die API zu ändern/zu erweitern, und man kann die Funktion ohne ``*`` beim Aufruf nur manuell mit einzelnen Argumenten füttern. Wenn das dazu führt das man im Regelfall bei der Funktionsdefinition *und* beim Aufruf ein ``*`` braucht, dann kann man es auch gleich bei beiden Stellen weglassen und der Funktion an der Stelle einfach eine Liste oder etwas anderes in der Richtung übergeben.

In diesem speziellen Fall halte ich das auch für keine gute Schnittstelle. Denn wenn man diese Funktion für *einen* Wert schreibt, lässt der sich trivial mit der schon erwähnten „list comprehension”, oder mit der `map()`- oder `itertools.imap()`-Funktion auf Sequenzen von Werten anwenden.
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@snafu: Berachte meinen Code als Instanz von Uncle Bob's Clean Architecture.

Im Zentrum sind die Entities, das sind hier einfach Dezimalzahlen und Funktionen darauf (calculate_*()). Diese Funktionen werden mithilfe von Hilfsfunktionen implementiert, die bestimmte Regeln der Geschäftslogik aufrechterhalten, zB. dass Geldbeträge immer auf zwei Kommastellen gerundet werden, dass das Runden immer ein Abrunden ist, dass als Ergebnis einer Prozentrechnung ein Geldbetrag herauskommt, wenn diese auf einen Geldbetrag angewendet wird, und dass dabei entsprechend der o.g. Regeln gerundet wird. Sollte eine Regel geändert werden müssen, dann braucht man nicht den gesammten Code zu durchsuchen um alle Implementierungen der Regel zu ändern, sondern es gibt nur genau eine Stelle, die man ändern muss und der gesammte Code verwendet dann die geänderte Regel.

Dazu gibt es in der Präsentationsschicht Hilfsfunktionen, die Werte ausspucken, die direkt von den darunterliegenden Schichten verwendet werden können, ohne dass dort Konversionen oder Validierungen vorgenommen werden müssten. Auch die o.g. Regeln werden dort gleich auf die eingegebenen Werte angewendet.

Zwischen der allgemeinen Geschäftslogik (calculate_*()) und der Präsentationsschicht (ask_*(), show()) gibt es die Schicht der Use Cases. Das sind Funktionen wie beschaffungskalkulation(). Diese Schicht beschreibt anwendungsbezogene Geschäftsregeln, kommuniziert mit der darunterliegenden allgemeinen Geschäftslogik und sorgt dafür, dass Ein- und Ausgaben angestoßen werden (unter Zuhilfenahme der Funktionen der Präsentationsschicht).

Als Ergebnis bekommt man ein System, in dem Entities sich nicht um IO kümmern müssen, eine Präsentationsschicht, die nur ein paar sehr allgemeine Regeln beachten muss (zB. beim Runden) und eine Schicht von Use Cases, die nur über genau definierte Interfaces mit den anderen Schichten kommuniziert. An jeder Stelle können Implementierungen geändert werden, ohne dass dies die Klienten der Module interessieren müsste.

Interessant ist dabei auch, dass der IO soz. "umgestülpt" wird. IO findet nicht irgendwo in den Tiefen der allgemeinen Geschäftslogik statt, sondern auf der Ebene der Use Cases, wo es hingehört ("um ... zu berechnen, gibt der Benutzer die Werte ... und ... ein und erhält als Ergebnis ...").

Um die Implementierungen der Use Cases noch stärker von der Präsentationsschicht zu trennen, könnte man die IO-Funktionen als Callbacks übergeben:

Code: Alles auswählen

def beschaffungskalkulation(ask_for_money_amount, ask_for_percentage, show):
 
    zieleinkaufspreis = calculate_zieleinkaufspreis(
        listenpreis=ask_for_money_amount('Listenpreis'),
        lieferanten_rabatt=ask_for_percentage('Lieferantenrabatt'),
    )
    show('Zieleinkaufspreis', zieleinkaufspreis)
    ...
Oder als Objekt mit entsprechenden Methoden. Wenn man auf diese Weise die Trennung der Schichten vornimmt, dann kann man zB. auch eine GUI darüberlegen. Die ask_*() und show() Funktionen würden in diesem Fall einfach bestimmte Felder der GUI auslesen bzw. aktualisieren. Oder man könnte verschiedene Szenarien aus einem Spreadsheet generieren[*]:

Code: Alles auswählen

column_map = {
    'Listenpreis': 'A',
    'Lieferantenrabatt': 'B',
    'Zieleinkaufspreis': 'C',
    ...
}

def get_money_value(sheet, row, fieldname):
    return money_amount(sheet.get(row=row, column=column_map[fieldname]))

def get_percent_value(sheet, row, fieldname):
    return float(sheet.get(row=row, column=column_map[fieldname]))

def set_value(sheet, row, fieldname, value):
    sheet.set(row=row, column=column_map[fieldname], value=value)

from functools import partial

for row in spreadsheet.rows():
    beschaffungskalkulation(
        ask_for_money_amount=partial(get_money_value, spreadsheet, row),
        ask_for_percentage=partial(get_percent_value, spreadsheet, row),
        show=partial(set_value, spreadsheet, row),
    )
Praktisch, oder?

[*] Ja, ich weiß, dass Excel das auch ohne Python kann. Mir geht es darum, den Sinn dieser Architektur zu illustrieren.
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Üpsilon hat geschrieben:du suchst das sprachmittel der list-comprehension. damit kannst du auf alle elemente einer liste eine funktion anwenden. https://docs.python.org/2/tutorial/data ... rehensions

Ersetzer ist übrigens ein komischer name. nenn es string_to_float oder so.
Hallo Üpsilon, im Hinblick auf die sogenannte List-Comprehension habe ich mir folgendes überelgt:
Beispiel:

Code: Alles auswählen

def Umwandlung(*Parameter):
    Liste = []
    [Liste.append(Elemente)
     for Elemente in Parameter
     if not Liste.count(Elemente)]
    return Elemente 
    
def main():
    Zahl = [
    "5,2",
    "7,0",
    "8.0",
    "2,6"
    ]
    
    Ergebnis = Umwandlung(Zahl)
    print Ergebnis # Ausgabe [['5,2', '7,0', '8.0', '2,6']]

if __name__ == "__main__":
    main()
Nun dachte ich mir, da er mir prima all meine Parameter in Form einer Liste zurückgibt, könnte man nun den Inhalt der Liste einlesen und die entsprechenden Zeichen ersetzen. Die einzelnen Objekte in der Liste habe ich dann "Elemente" genannt. Also sieht mein Code wie folgt aus:

Code: Alles auswählen

# -*- coding: cp1252 -*-
def Umwandlung(*Parameter):
     Liste = []
     for Elemente in Parameter:
         f =  Elemente.replace(",", ".") 
         if not Liste.count(Elemente):
             Liste.append(Elemente)
     return float(f)
    
def main():

    Zahl = [
    "5,2",
    "7,0",
    "8.0",
    "2,6"
    ]
    
    Ergebnis = Umwandlung(Zahl)
    print Ergebnis

if __name__ == "__main__":
    main()
Ich habe das "Replace" also in eine For-Schleife gepackt. Aber irgendwie mag die Liste Replace auch nicht. Hier die Fehlermeldung:
Traceback (most recent call last):
File "D:\Dan\Python\Übung\Calc\Neues Textdokument.py", line 26, in <module>
main()
File "D:\Dan\Python\Übung\Calc\Neues Textdokument.py", line 22, in main
Ergebnis = colapse(Zahl)
File "D:\Dan\Python\Übung\Calc\Neues Textdokument.py", line 6, in colapse
f = Element.replace(",", ".") # Ausgabe: Das ist kein Text.
AttributeError: 'list' object has no attribute 'replace'
Üpsilon
User
Beiträge: 222
Registriert: Samstag 15. September 2012, 19:23

Code: Alles auswählen

    [Liste.append(Elemente)
     for Elemente in Zahlen
     if not Liste.count(Elemente)]
Da biste durcheinandergekommen. In der LC muss man eben *kein* append machen.

Ich meinte eher Folgendes: nimm wieder deine alte Umwandlungsfunktion ohne den *, und wenn du eine Liste von Strings zu Zahlen machen willst, tust du folgendes:

Code: Alles auswählen

[umwandlung(zahl) for zahl in zahlen]
So ähnlich solltest du die Variablennamen auch vergeben, wie Bj schon schrieb.

Edit: Kann es sein, dass du denkst, LCs wären ein eigener Datentyp? Das ist nicht der Fall, LCs sind ne Technik zum Erstellen normaler Listen.
PS: Die angebotene Summe ist beachtlich.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Üpsilon hat geschrieben:

Code: Alles auswählen

    [Liste.append(Elemente)
     for Elemente in Zahlen
     if not Liste.count(Elemente)]
Da biste durcheinandergekommen. In der LC muss man eben *kein* append machen.

Ich meinte eher Folgendes: nimm wieder deine alte Umwandlungsfunktion ohne den *, und wenn du eine Liste von Strings zu Zahlen machen willst, tust du folgendes:

Code: Alles auswählen

[umwandlung(zahl) for zahl in zahlen]
So ähnlich solltest du die Variablennamen auch vergeben, wie Bj schon schrieb.

Edit: Kann es sein, dass du denkst, LCs wären ein eigener Datentyp? Das ist nicht der Fall, LCs sind ne Technik zum Erstellen normaler Listen.
In VB6 gibt es eine Art Container, und die nennen wir Collection. Dort kann man alle Objekte hinlegen, und diese dann direkt ansprechen. Und da ich den LC wie einen Container betrachte, dachte ich, kann man auf die einzelnen Daten/Objekte innerhalb dieses Containers zugreifen. Demzufolge wollte ich die Objekte in diesem Container einlesen und die entsprechenden Zeichen ersetzen.

Nun zu dir, ich will meine Liste von Strings nicht zu Zahlen machen, sondern, die Zeichenketten einlesen und die entsprechenden Zeichen ersetzen. Ich habe gehofft, dass ich mir diesen Zwischenschritt sparen könnte. Ist ein direkter Weg nicht möglich? Müssen die Strings erst in Zahlen "umgewandelt" werden, ehe man bestimmte Zeichen in einem String durch andere Zeichen ersetzen kann?
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Sophus hat geschrieben:

Code: Alles auswählen

def Umwandlung(*Parameter):
    Liste = []
    [Liste.append(Elemente)
     for Elemente in Zahlen
     if not Liste.count(Elemente)]
    return Liste 
    
def main():
    Zahl = [
    "5,2",
    "7,0",
    "8.0",
    "2,6"
    ]
    
    Ergebnis = Umwandlung(Zahl)
    print Ergebnis # Ausgabe [['5,2', '7,0', '8.0', '2,6']]

if __name__ == "__main__":
    main()
Einen Paramter Parameter zu nennen ist nicht sinnvoll. Dass es ein Parameter ist, sehe ich daran, dass er syntaktisch an einer Stelle steht, die ihn zum Parameter macht. Wenn ich Code lese will ich aber wissen, was der Parameter im Programm für eine Bedeutung hat. Ein Parameter, der eine Zahl beinhaltet, repräsentiert dann zB. das Alter einer Person. Dann sollte man ihn alter nennen, aber nicht parameter. Übrigens sollte man ihn auch nicht zahl nennen. Denn wenn ich das lese, weiß ich nur den Typ des Parameters, aber nicht, was die Zahl bedeutet. Das Alter? Die Größer einer Person in cm? Den mittleren Abstand der Person von Betelgeuze?

Und der * vor Parameter ... warum steht der da? Das x in def f(*x): beinhaltet ein Tupel, dass die übergebenen Argumente als Elemente hat. In deinem Fall also ein Tupel, dass als erstes (und einziges) Element eine Liste von Strings besitzt. Also das hier:

Code: Alles auswählen

(["5,2", "7,0", "8.0", "2,6"],)
Wenn ich auf das dritte Element der Liste zugreifen möchte, muss ich das folglich so tun:

Code: Alles auswählen

x = Parameter[0][2]
Das Ergebnis ist dann "8.0". Auch das ist übrigens keine Zahl, sondern ein String, der Buchstaben enthält, aus denen zB. die Funktion float() eine Zahl erzeugen kann:

Code: Alles auswählen

>>> type("8.0")
<type 'str'>
>>> float("8.0")
8.0
>>> type(float("8.0"))
<type 'float'>
Als nächstes die List Comprehension (LC). Eine LC benötigt kein append(). Hier zum Vergleich ohne LC:

Code: Alles auswählen

>>> zahl_strings = ["5.2", "7.0", "8.0", "2.6"]
>>> zahlen = []
>>> for each in zahl_strings:
...     print each, ':', type(each)
...
5.2 : <type 'str'>
7.0 : <type 'str'>
8.0 : <type 'str'>
2.6 : <type 'str'>
>>> for each in zahl_strings:
...     zahlen.append(float(each))
...
>>> for each in zahlen:
...     print each, ':', type(each)
...
5.2 : <type 'float'>
7.0 : <type 'float'>
8.0 : <type 'float'>
2.6 : <type 'float'>
Und hier mit LC:

Code: Alles auswählen

>>> zahlen = [float(each) for each in zahl_strings]
>>> for each in zahlen:
...     print each, ':', type(each)
...
5.2 : <type 'float'>
7.0 : <type 'float'>
8.0 : <type 'float'>
2.6 : <type 'float'>
Wenn du die Kommata in den Strings zu Dezimalpunkten umwandeln und danach aus dem Ergebnis eine Zahl zu erzeugenmöchtest, dann kannst du das einfach so machen:

Code: Alles auswählen

>>> zahl_strings = ["5,2", "7,0", "8.0", "2,6"]
>>> zahlen = [float(each.replace(',', '.')) for each in zahl_strings]
>>> for each in zahlen:
...     print each, ':', type(each)
...
5.2 : <type 'float'>
7.0 : <type 'float'>
8.0 : <type 'float'>
2.6 : <type 'float'>
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Hallo pillmuncher, ich habe mich an deinem Beispiel gehalten und es wie folgt umgesetzt (ignorieren wir jetzt mal die sinnlosen Namensgebungen):

Code: Alles auswählen

# -*- coding: cp1252 -*-
def umandeln(Parameter):
    f = [float(Elemente.replace(',', '.')) for Elemente in Parameter]
    for Elemente in f:
          return Elemente

def main():
    Zahlen = [
    "5,2",
    "7,0",
    "8.0",
    "2,6"
    ]
    n = len(Zahlen) # Anzahl der Einträge aus der Liste Zahlen erfahren
    
    Ergebnis = umandeln(Zahlen) # An die Funktion die Zahlen aus der Liste Zahlen übergeben
    Rueckgabe = umandeln(Ergebnis[0-n])   # Da ich nicht nur einen bestimmten Eintrag zurückhaben will,
                                        # sondern so viele, wie in der Liste waren, also benutze ich hier n (hier: 0-4 Einträge - also alle Einträge)
    print Rueckgabe
    
if __name__ == "__main__":
    main()

Fehlermeldungen:
Traceback (most recent call last):
File "D:\Dan\Python\Übung\Calc\Neues Textdokument.py", line 22, in <module>
main()
File "D:\Dan\Python\Übung\Calc\Neues Textdokument.py", line 17, in main
Rueckgabe = umandeln(Ergebnis[n]) # Da ich nicht nur einen bestimmten Eintrag zurückhaben will,
TypeError: 'float' object has no attribute '__getitem__'
Üpsilon
User
Beiträge: 222
Registriert: Samstag 15. September 2012, 19:23

Du erinnerst mich an jemanden, der mal mit mir im Informatik-Wahlfach war. Der war auch so n Kandidat, ey.. :roll:

Wenn in einer Funktion return gemacht wird, dann ist die Funktion fertig gelaufen. Das, was du hier probierst, macht man afaik mit yield. Aber egal. In Wirklichkeit willst du doch die ganze Liste zurückgeben! :|

liste[0-n] macht übrigens etwas völlig anderes, als du denkst. Auch hier willst du die ganze Liste übergeben. :cry:

Lies meine Signatur! :D
PS: Die angebotene Summe ist beachtlich.
Antworten