Seite 1 von 1
Datenstruktur für Lottozahl
Verfasst: Donnerstag 21. August 2014, 13:28
von lackschuh
Hallo,
Ich bräuchte mal einen Tipp für eine geeignete Datenstruktur um Lottozahlen inkl. Zusatzzahl zu speichern, damit diese mit den Gewinnzahlen verglichen werden können. Momentan benutze ich verschachtelte Listen:
Code: Alles auswählen
gewinn_zahlen = [14, 20, 28, 29, 31, 41, [5]]
meine_zahlen = [
[22, 26, 29, 33, 35, 47, [2]],
[12, 32, 2, 26, 3, 36, [6]],
]
Mir geht es darum, wie ich das mit der Zusatzzahl am besten handhaben könnte. Was wäre eine bessere Alternative?
mfg
Re: Datenstruktur für Lottozahl
Verfasst: Donnerstag 21. August 2014, 13:39
von BlackJack
@lackschuh: Ich würde das je eher anders herum machen, die 6 normalen in einer Liste zusammenfassen und die Zusatzzahl einzeln lassen: ``[[14, 20, 28, 29, 31, 41], 5]``. Dann lässt sich das deutlich einfacher vergleichen ohne Teillisten per slicing kopieren zu müssen. Ohne Zusatzzahl ``a[0] == b[0]`` und mit Zusatzzahl ``a == b``. Insbesondere eine Liste die immer nur ein Element enthält mach nicht so viel Sinn. Ansonsten könnte man auch ein Wörterbuch oder gar eine Klasse schreiben, oder zumindest ein `collections.namedtupel` erzeugen.
Re: Datenstruktur für Lottozahl
Verfasst: Donnerstag 21. August 2014, 14:54
von fail
Ich würde ein Set nehmen, da dort Objekte nur einmal vorkommen dürfen und man einfach sehen kann, ob die gespielten Zahlen ein Subset der gezogenen Zahlen ist
Re: Datenstruktur für Lottozahl
Verfasst: Freitag 22. August 2014, 08:54
von lackschuh
Danke mal für die Tipps. Vergleichen tue ich momentan es so:
Code: Alles auswählen
for tip in meine_zahlen:
print set(tip[0]) & set(gewinn_zahlen[0]), tip[1] == gewinn_zahlen[1]
Ist aber nicht sehr elegant und zudem gibt es erst ab 3 richtige Zahlen Kohle. Was müsste ich beachten, so dass nur ab 3 übereinstimmenden Zahlen eine 'print' Anweisung gemacht wird und kann man die 'print' Ausgabe der sets formatieren(?), denn so sieht es nicht übersichtlich aus:
Code: Alles auswählen
>> set([14]) False
>> set([41]) False
>> set([41]) True
>> set([14, 31]) True
Re: Datenstruktur für Lottozahl
Verfasst: Freitag 22. August 2014, 10:07
von Sirius3
@lackschuh: hast Du schonmal was von len gehört?
Re: Datenstruktur für Lottozahl
Verfasst: Freitag 22. August 2014, 10:26
von lackschuh
Ja, ist der Börsenkürzel von Lennar Corporation
Aber wie lasse ich 'set([])' verschwinden und stattdessen einfach die Zahlen anzeigen lassen?
Danke
Re: Datenstruktur für Lottozahl
Verfasst: Freitag 22. August 2014, 12:01
von BlackJack
@lackschuh: Falls ich die Frage richtig verstanden habe: In dem Du Code schreibst der aus den Werten eine Zeichenkette erstellt die Deinen Vorstellungen entspricht, statt einfach Datenstrukturen auszugeben und deren Zeichenkettenrepräsentation zu verwenden. Das ist für Programmierer und die Fehlersuche gedacht, nicht um dem Endbenutzer etwas zu zeigen.
Re: Datenstruktur für Lottozahl
Verfasst: Freitag 22. August 2014, 12:48
von lackschuh
Danke, anbei sieht es nun so aus:
Code: Alles auswählen
# coding: utf-8
import requests
from bs4 import BeautifulSoup
URL = "https://www.swisslos.ch/swisslotto/home.do"
lotto_zahl = []
lotto_zahlen = []
count = 0
html = requests.get(URL)
soup = BeautifulSoup(html.text)
for label in soup.select('li.numberLarge'):
lotto_zahl.append(int(label.string))
zusatz_zahl = lotto_zahl[-1]
lotto_zahlen.append(lotto_zahl)
del lotto_zahl[-1]
lotto_zahlen.append(zusatz_zahl)
#gewinn_zahlen = [[14, 20, 28, 29, 31, 41], 5]
meine_zahlen = [
[[9, 17, 20, 25, 26, 29], 2],
[[1, 8, 16, 21, 32, 37], 6],
[[15, 20, 34, 35, 36, 39], 5],
[[14, 20, 29, 12, 14, 25], 5],
]
for tipp in meine_zahlen:
if len(set(tipp[0]) & set(lotto_zahlen[0])) >= 3:
count = count + 1
richtige = set(tipp[0]) & set(lotto_zahlen[0])
print '%d. Tipp:' % count, "%d richtige Zahlen %s," % (len(list(richtige)), list(richtige)), 'Zusatzzahl', tipp[1] == lotto_zahlen[1]
else:
count = count + 1
print '%d. Tipp:' % count, 'Leider kein Gewinn'
Re: Datenstruktur für Lottozahl
Verfasst: Freitag 22. August 2014, 13:06
von Hyperion
Also da sind einige Dinge noch unschön...
- Statt
würde man ``list.pop`` nutzen:
- Wenn man einen zusätzlichen Zähler/Index in einer Schleife braucht, dann sollte man ``enumerate`` nutzen!
- Wenn man Strings mit Platzhaltern nutzt, dann doch bitte "am Stück". Bisher sind die Platzhalter wenig sinnvoll und tragen nicht zur Lesbarkeit bei.
Code: Alles auswählen
'%d. Tipp: %d richtige Zahlen %s, Zusatzzahl %d' % ...
- Wieso die umständliche Umwandlung``(len(list(richtige))``? ``len`` kann man auch auf ``sets`` anwenden
- Der ``len`` Ausdruck in der ``if``-Bedingung wird darunter *exakt* noch einmal wiederholt. Zieh die Prüfung doch vor das ``if`` und schon hast Du ein wenig Redundanz weniger.
- Die Namensgebung ist imho inkonsistent: Wenn doch ``meine_zahlen`` eigentlich Tipps sind, wieso dann nicht ``meine_tipps``? Oder andersherum in der ``for``-Schleife eben ``for zahl in meine_zahlen``.
- Generell Code von Modulebene in Funktionen verlagern.
- Du vermischst hier noch zu viel Code miteinander. Ich würde mir für die Auswertung ggf. auch eine Struktur überlegen und die Ausgabe davon separieren. Dazu dann eine Funktion zum Holen und Parsen der richtigen Ergebnisse und schon bist Du viel flexibler bezüglich der Nutzung.
Re: Datenstruktur für Lottozahl
Verfasst: Sonntag 24. August 2014, 14:57
von BlackJack
@lackschuh: Zu den Namen wurde ja schon etwas gesagt. `lotto_zahl` (Einzahl) für eine Liste mit Zahlen (Mehrzahl) ist irreführend. Etwas präzisere Bezeichnungen wie Tipp und Ziehung statt allgemein Zahl(en) würden das Programm verständlicher machen.
Auch ungünstig ist das definieren von Namen lange bevor sie tatsächlich benötigt werden. Dann muss man dort nämlich erst wieder weiter oben suchen was die eigentlich für Startwerte haben. Es erschwert auch das spätere aufteilen in einzelne Funktionen wenn nicht der zusammengehörende Code beisammen steht und man sich erst alles über den Code verteilt zusammen suchen muss.
Die Tipps umgesetzt könnte das ungefähr so aussehen:
Code: Alles auswählen
#!/usr/bin/env python
# coding: utf-8
from __future__ import print_function
import requests
from bs4 import BeautifulSoup
URL = 'https://www.swisslos.ch/swisslotto/home.do'
def hole_ziehung():
soup = BeautifulSoup(requests.get(URL).text)
lottozahlen = [
int(n.string) for n in soup.select('div#actualNumbers li.numberLarge')
]
result = [lottozahlen]
result.append(lottozahlen.pop())
return result
def vergleiche(tipp, ziehung):
return (sorted(set(tipp[0]) & set(ziehung[0])), tipp[1] == ziehung[1])
def main():
ziehung = hole_ziehung()
tipps = [
[[9, 17, 20, 25, 26, 29], 2],
[[1, 8, 16, 21, 32, 37], 6],
[[15, 20, 34, 35, 36, 39], 5],
[[14, 20, 29, 12, 14, 25], 5],
]
for tipp_nr, tipp in enumerate(tipps, 1):
print('{0}. Tipp:'.format(tipp_nr), end=' ')
richtige, ist_zusatzzahl_richtig = vergleiche(tipp, ziehung)
if len(richtige) >= 3:
print(
'{0} richtige Zahlen {1}, Zusatzzahl: {2}.'.format(
len(richtige),
', '.join(richtige),
'ja' if ist_zusatzzahl_richtig else 'nein'
)
)
else:
print('Leider kein Gewinn')
if __name__ == '__main__':
main()
Re: Datenstruktur für Lottozahl
Verfasst: Montag 25. August 2014, 08:50
von lackschuh
Vielen Dank für die Tipps.
Ich benutze Python 2.7.
Was bedeutet ''from __future__ import print_function''?
Wenn ich dies auskommentiere, dann wird mir zB bei ''print('Leider kein Gewinn')'' ein Fehler angezeigt, wenn ich bei dieser print-Anweisung die Klammern entferne. Ist dies (__future__) vereinfacht gesagt das, was bei Python3 die print-Funktion neu ist?
Des Weiteren wurde noch gemeckert, dass bei ''''.join(richtige)'' ein String erwartet wird. ''''.join(str(richtige))''
Re: Datenstruktur für Lottozahl
Verfasst: Montag 25. August 2014, 08:57
von BlackJack
@lackschuh: Der `__future__`-Import macht aus ``print`` eine Funktion.
Ich hätte es mit Treffern testen sollen.

Nein, natürlich darf man nicht die Datenstruktur `richtige` in *eine* Zeichenkette umwandeln, sondern muss die einzelnen Elemente umwandeln die man dann mit `join()` zusammenfügen möchte:
Re: Datenstruktur für Lottozahl
Verfasst: Montag 25. August 2014, 11:38
von Malta
Ich habe mir auch schon mal Gedanken über ein Lottoprogramm gemacht, vielleicht kannst du daraus neue Erkenntnisse gewinnen:
https://github.com/MarkusHackspacher/pyLottoverwaltung
Re: Datenstruktur für Lottozahl
Verfasst: Montag 25. August 2014, 21:21
von darktrym
Ich würde das Projekt sicher nicht als Beispiel für guten Code sehen.
Besser er schaut nicht da rein, sonst schaut er sich wirklich noch was ab.
Re: Datenstruktur für Lottozahl
Verfasst: Freitag 24. Oktober 2014, 15:30
von lackschuh
Hallo
Ich hab das Programm für ein anderes
Lotto-System ein wenig umgeschrieben. Bei diesem System gibt es folgendes zu beachten für ein Gewinn:
Zahl (max 5) + Stern (max 2)
Gewinn ab 1 Zahl + 2 Sterne, zwei Zahlen + 0 Stern.
Nun habe ich zweimal die gleiche Print-Anweisung und eine 'if', 'elif' und 'else' Abfrage. Gäbe es eine Möglichkeit, dies alles zu verkürzen bzw zu vereinfachen?
mfg
Code: Alles auswählen
#!/usr/bin/env python
# coding: utf-8
from __future__ import print_function
import requests
from bs4 import BeautifulSoup
URL = 'http://www.euro-millionen.org'
def hole_ziehung():
soup = BeautifulSoup(requests.get(URL).text)
lottozahlen = [
int(n.string) for n in soup.select('div#results-content li')
]
result = [lottozahlen]
zusatz_zahlen = []
zusatz_zahlen.append(lottozahlen.pop(-2,))
zusatz_zahlen.append(lottozahlen.pop(-2,))
result.append(zusatz_zahlen)
return result
def vergleiche(tipp, ziehung):
return sorted(set(tipp[0]) & set(ziehung[0])), sorted(set(tipp[1]) & set(ziehung[1]))
def main():
#ziehung = hole_ziehung()
ziehung = [[20, 21, 27, 33, 40], [2, 6]]
print(ziehung)
tipps = [
[[1, 5, 21, 33, 48], [2, 6]],
[[14, 20, 32, 33, 40], [3, 7]],
]
for tipp_nr, tipp in enumerate(tipps, 1):
print('{0:>1}. Tipp:'.format(tipp_nr), end=' ')
richtige, sind_sterne_richtig = vergleiche(tipp, ziehung)
if len(richtige) >= 1 and len(sind_sterne_richtig) == 2:
print('{0} richtige Zahlen: "{1}": Sterne: "{2}"'.format(
len(richtige),
', '.join(map(str, richtige)),
'{0}'.format(', '.join(map(str, sind_sterne_richtig))) if sind_sterne_richtig else 'falsch'
)
)
elif len(richtige) >= 2:
print('{0} richtige Zahlen: "{1}": Sterne: "{2}"'.format(
len(richtige),
', '.join(map(str, richtige)),
'{0}'.format(', '.join(map(str, sind_sterne_richtig))) if sind_sterne_richtig else 'falsch'
)
)
else:
print('Leider kein Gewinn')
if __name__ == '__main__':
main()
Re: Datenstruktur für Lottozahl
Verfasst: Freitag 24. Oktober 2014, 17:58
von Sirius3
@lackschuh: in dem Du die beiden if per or in eines packst. Noch besser schreibst Du Dir eine Funktion, die ermittelt, ob gewonnen wurde oder nicht.
Re: Datenstruktur für Lottozahl
Verfasst: Freitag 8. Mai 2015, 09:23
von lackschuh
Hallo
Die Seite
http://www.euro-millionen.org/ wurde umgebaut.
Die Sterne bekomme ich als Liste mit:
Da in der untergeordneterer Liste nochmals eine Liste ``<li class="star">`` drinsteht, habe ich gerade Mühe, alles auf einmal zu parsern. Ideal wäre als Resultat eine verschachtelte Liste [[1, 10, 17, 20, 42], [8, 9]]. Für einen Tipp wäre ich dankbar
Code: Alles auswählen
<ul class="numbers">
<li>
1 </li>
<li>
10 </li>
<li>
17 </li>
<li>
20 </li>
<li>
42 </li>
<li class="star">
8 </li>
<li class="star">
9 </li>
</ul>