Python-Programm - pyLottoCheck

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
pyMensch
User
Beiträge: 1
Registriert: Dienstag 10. Oktober 2006, 20:26

Hallo,

bin neu in Python und wollte kurz mal ein pyProgramm von mir vorstellen. Das Programm heißt pyLottoCheck und vergleicht Lottozahlen mit Lottozahlen aus einer Datei. Ich weiß die 37 Mio sind schon weg, aber gebrauchen kann man ja es noch immer. Vieleicht kennt ja einer das Problem, man spielt in eienr Tippgesellschaft 6 aus 49 und muss mehrere LottoTIPs mit den Lottozahlen vergleichen. Klar man koennte jetzt bis Monatsende warten, und man bekommt von der Tippgesellschaft ne Uebersicht aller Gewinne, aber wer möchte da denn warten, wenn gerade z.b. 37 Mio im Jackpot liegen. Mit pyLottoCheck geht das ganz schnell. Einfach die Lottozahlen in eine Datei eintippen, speichern und das Programm starten.

Das wäre schön wenn jemand sich das Programm anschauen würde und etwas darüber sagen könnte. Was ich falsch gemacht habe, Was ich vielleicht besser machen könnte, usw. halt solche Dinge. Wäre echt toll von euch.

Danke.


Code: Alles auswählen

"""
pyLottoCheck-V.0.1#10.10.2006
Vergleicht mehrere Lottozahlen aus einer Datei.
""" 

# ============================================================
# Beim erstellen einer Lottodatei bitte folgendes beachten:
# - Zahlen werden durch ein Leerzeichen getrennt
# - Jede Zeile enthaelt nur ein LottoTIP
# - Reihenfolge: Zahl1 Zahl2 Zahl3 Zahl4 Zahl5 Zahl6 Superzahl
# Beispiel-Datei:   5 10 15 20 25 30 5
#                   2 12 18 29 32 47 2
#                   8 22 28 31 39 45 9
# ============================================================

from sys import exit
from string import split

def fOpenFile(psFilePath):
    """ Liest den Inhalt aus einer Datei aus. """
    
    oFile = open(psFilePath,'r')
    sText = oFile.read()
    oFile.close()
    return sText
    
    
def fFileExist(psFilePath):
    """ Prueft die Existenz einer Datei. """
    
    try:
        oFile = open(psFilePath,'r')
    except IOError: #EA-Fehler
        return 0
    else:
        oFile.close()
        return 1

        
def fIsNumber(psCheckString):
    """ IsNumber """
    for f in [int, float,]:
        try:
            f(psCheckString)
        except ValueError:
            continue
        return 1
    return 0

    
def fCheckLottoString(psLottoString, iPartsCount):
    """ Prueft einen LottoTIP """

    lLottoNumbers = split(psLottoString)
    
    # Verschiedene Pruefvorgaenge ..

    # Enthaelt der LottoString exakt eine bestimmte Anzahl an Zahlen ?
    bLottoStringOK_1 = 1
    if (len(lLottoNumbers) <> iPartsCount):
        bLottoStringOK_1 = 0  # Nein

    # Hat der LottoString wirklich nur Zahlen ?
    bLottoStringOK_2 = 1
    for sLottoNumber in lLottoNumbers:
        if (fIsNumber(sLottoNumber) == 0):
            bLottoStringOK_2 = 0 # Nein

    # Waren alle Pruefungen okay ?
    if (bLottoStringOK_1 == 0) or (bLottoStringOK_2 == 0):
        return 0 # Nein
    else:
        return 1 # Ja

        
def fGetLottoList(psLottoFilePath):
    """ Laedt die LottoDatei und wandelt sie in eine Liste um. """
    
    sLottoFile = fOpenFile(psLottoFilePath)

    lLotto = split(sLottoFile,'\n')

    # Leere LottoListe erzeugen
    lLottoList = []
    
    # Umwandeln in eine Liste
    for sLottoString in lLotto:
        lLottoNumbers = split(sLottoString)

        # LottoString okay ?
        if (fCheckLottoString(sLottoString, 7) == 0):
            # LottoString ist falsch
            # LottoString wird uebersprungen
            print '---- ERROR: Folgender LottoTIP ist falsch: ' + sLottoString
        else:
            # LottoString zur LottoListe hinzufuegen
            lLottoStringList = []
            for sLottoNumber in lLottoNumbers:
                lLottoStringList.append(sLottoNumber)
            lLottoList.append(lLottoStringList)

    return lLottoList
    

def fStartLottoCheck(lLottoString, lUserLottoString):
    """ Vergleicht zwei LottoStrings. """

    iLottoHits = 0
    bZusatzzahl = 0
    bSuperzahl = 0

    # Lottozahlen (1-6) vergleichen
    for i1 in range(0,6):
        for i2 in range(0,6):
            if (lUserLottoString[i1] == lLottoString[i2]):
                iLottoHits  = iLottoHits + 1
                break

    # Zusatzzahl pruefen
    for i1 in range(0,6):
        if (lUserLottoString[6] == lLottoString[i1]):
            bZusatzzahl = 1
            break

    # Superzahl pruefen
    if (lUserLottoString[7] == lLottoString[6]):
        bSuperzahl = 1

    # Liste in einen String umwandeln
    sLottoNumbers = ''
    for sLottoNumber in lLottoString:
        sLottoNumbers  = sLottoNumbers  + sLottoNumber + ' '
        
    # Status ausgeben
    sLottoReport = ''
    if (iLottoHits >= 3): # Nur ab 3 Richtige ein Status ausgeben
        if (bZusatzzahl == 1):
            # Mehr als 2 Richtige mit Zussatzzahl
            sLottoReport = '%s | %s Richtige + Zussatzzahl' \
                            %(sLottoNumbers,str(iLottoHits))
        elif (bSuperzahl == 1 and iLottoHits == 6): 
            # Jackpot
            sLottoReport = '%s | JACKPOT' %sLottoNumbers
        else:
            # Mehr als 2 Richtige ohne Zussatzzahl
            sLottoReport = '%s | %s Richtige' \
                            %(sLottoNumbers,str(iLottoHits))
        # Status ausgeben
        print sLottoReport

# ============================
#             MAIN 
# ============================

# Dateipfad zur LottoDatei anfragen
bRunning = 1
while (bRunning == 1):
    print '>> Geben Sie den Dateipfad zur LottoDatei ein.'
    print ">> Geben Sie 'x' ein um zu beenden."
    inputFilePath = raw_input('Eingabe: ')
    # Hat der Benuetzer ein x eingegeben?
    if (inputFilePath == 'x'): 
        print '>> Auf Widersehen.'
        exit()
    # Pruefe Existenz
    print '>> Pruefe ob Datei existiert ...'
    if (fFileExist(inputFilePath) == 0):
        # Datei existiert nicht
        print '---- ERROR: Datei kann nicht gelesen werden ' \
              'oder existiert nicht.'
        print '---- Versuchen sie es erneut.'
    else:
        print '---- Datei existiert.'
        bRunning = 0

# Lottodaten aus der Datei importieren
print '>> Importiere alle Lottodaten aus der Datei ...'
lFileLottoList = fGetLottoList(inputFilePath)
print '---- Lottodaten importiert.'

# Nun die Lottozahlen anfragen
bRunning = 1
while (bRunning == 1):
    print '>> Geben Sie jetzt Ihre Lottozahlen ein.'
    print '>> Bitte trennen Sie jede Zahl durch eine Leerzeichen.'
    print '>> Reihenfolge (Z1 Z2 Z3 Z4 Z5 Z6 Superzahl Zusatzzahl).'
    print ">> Geben Sie 'x' ein um zu beenden"
    inputLottoNumbers = raw_input('Eingabe: ')
    if (inputLottoNumbers == 'x'): # Hat der Benuetzer ein x eingegeben?
        print '>> Auf Widersehen.'
        exit() # Programm beenden
    print '>> Pruefe eingegebene Lottozahlen ...'
    if (fCheckLottoString(inputLottoNumbers,8) == 0):
        print '---- Lottozahlen nicht korrekt! Versuchen Sie es erneut.'
    else:
        print '---- Lottozahlen okay.'
        bRunning = 0

print '>> Vergleiche Lottozahlen ...'

# Eingegebene Lottozahlen in eine Liste umwandeln
lLottoNumbers = split(inputLottoNumbers)
lUserLottoList = []
for lLottozNumber in lLottoNumbers:
    lUserLottoList.append(lLottozNumber)

#Lottozahlen auswerten
print '='*40
for lLottoString in lFileLottoList:
    fStartLottoCheck(lLottoString,lUserLottoList)
print '='*40

# Fertig!
print '>>>> Ueberpruefung abgeschlossen.'
Beipiel-LottoListe:
  • 3 9 25 42 45 46 4
    3 9 28 30 38 48 4
    4 6 27 28 38 49 4
    4 15 37 42 45 49 4
    4 25 30 46 48 49 4
    6 7 13 25 27 46 4
    6 27 30 42 45 48 4
    7 13 15 30 37 48 4
BlackJack

Erster Gedanke: Igitt da hat jemand versucht VisualBasic in Python zu programmieren. Das merkt man an der unsinnigen ungarischen Notation und den ``<>`` für "ungleich".

Wozu soll die ungarische Notation hier gut sein, ausser den Leser zu verwirren? Was bringt Dir die? Wenn irgendwo ``bla(42)`` steht, dann ist `blah` ganz offensichtlich eine Funktion, oder allgemeiner etwas aufrufbares, da muss kein 'f' am Anfang des Namens stehen. Der Typ von Parametern ist entweder offensichtlich, oder er wird im "docstring" beschrieben. Im Namen hat er nichts zu suchen. Was ist "ps*" für ein Typ? Oder was bedeutet das 'o' in `oFile`? Namenskonvention in Python ist kleine_worte_mit_unterstrichen, ausser bei Konstanten (GROSSE_BUCHSTABEN) und Klassennamen (MixedCase).

Die `string.split()` Funktion ist veraltet; bevorzugt wird die entsprechende Methode auf Zeichenketten.

Ob eine Datei existiert kann man mit `os.path.isfile()` testen.

Wenn man Wahrheitswerte haben möchte dann sollte man `True` und `False` anstelle von 1 und 0 verwenden.

Die Funktion zum Testen auf "Zahl" ist recht redundant wenn man das Ergebnis der Konvertierung nur für den Test benutzt und danach *nochmal* konvertiert weil man die Zahl wirklich braucht.

Klammern sind bei Bedingungen nicht notwendig.

`fCheckLottoString()` ist auch wieder eine Funktion die viel Konvertierung betreibt und die Ergebnisse davon einfach wieder "wegwirft".

Einlesen der Liste und umwandeln in Listen mit Zahlen inkusive Tests sind nur eine handvoll Zeilen:

Code: Alles auswählen

def read_lotto_list(path):
    lines = open(path, 'r')
    result = list()
    for line in lines:
        try:
            lotto_numbers = map(int, line.split())
            if len(lotto_numbers) != 7:
                raise ValueError('not seven numbers')
        except ValueError, error:
            print 'ERROR in Tip: %r (%s)' % (line, error)
        else:
            result.append(lotto_numbers)
    lines.close()
    return result
Listen an Funktionen übergeben, die verschiedene "Sachen" repräsentieren ist kein guter Stil. Zusatz- und Superzahl sind etwas anderes als die "normalen" Lottozahlen. Den Vergleich könnte man dann auch so schreiben:

Code: Alles auswählen

def compare_lotto_number(user_supplied_numbers,
                         extra_number,
                         super_number,
                         read_numbers,
                         read_super_number):

    hits = len(set(user_supplied_numbers) & set(read_numbers))
    
    if hits >= 3:
        if hits == 6 and super_number == read_super_number:
            report = 'JACKPOT'
        else:
            report = '%d Richtige' % hits
            if extra_number in read_numbers:
                report += ' + Zusatzzahl'
        print '%r | %s' % (read_numbers, report)
Wenn man das Hauptprogramm in eine `main()` Funktion verpackt und diese mit folgendem Code ausführt, dann kann man das Modul importieren und einzelne Funktionen testen, ohne dass das Programm ausgeführt wird.

Code: Alles auswählen

if __name__ == '__main__':
    main()
Antworten