Python Listenprogramm mit Suchfunktion und randomfunktion

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.
Antworten
coffeeyay
User
Beiträge: 3
Registriert: Mittwoch 28. Oktober 2015, 12:49

Ich beschäftige mich zurzeit mit einem privaten Projekt und benötige ein wenig Hilfe. Vielleicht kennen sich hier ja einige sehr gut aus.
Würde es mit ipython schreiben, bzw. damit habe ich es versucht.

Mein Programm soll 5 Listen durchsuchen mit jeweils 3 Unterlisten,jedoch nicht aufeinmal immer nur 3 aufeinmal. Also insgesamt 15 Listen. Jedoch wollte ich nur insgesamt 5 Listen und in den 5Listen dann jeweils noch 3 andere implementieren. Sprich 5 Listen(A,B,C,D,E) und in den jeweiligen Listen sind jeweils noch 3 andere listen(R,L,S).
In den Listen befindet sich eine Aufzählung von Buchstaben und Zahlenkombinationen mit Wahrscheinlichkeit. Könnte so aussehen
A= [[L=AA,KK,QQ(0.75),JJ(0.25),TT(0.5),AKo(0.25)] [R=Ako(0,75)]]
DIe Zahl in () dahinter soll die Wahrscheinlichkeit bedeutet, sprich wenn nichts dort steht ist die Wahrscheinlichkeit 100%, bei 0,25= 25%.

Nun würde ich gerne eine Suchfunktion erstellen. Z.B ich gebe ein Liste A,AKo nun soll mir das Porgramm L=AKo(0,25) und R= AKo(0,75) ausgeben.

Am besten wäre natürlich noch wenn es mit der Suchfunktion eine randomfunktion mitberechnen würde und mir dann nur zb L=AKo anzeigt wenn die random Zahl zwischen 1 und 25 liegt
ansonsten zeigt es mir R=AKo(0,75) an wenn die random zahl zwischen 26 und 100 liegt. Aber glaube das würde meine jetzigen Kompetenzen bei weitem sprengen.

Daher zur not kann ich auch einfach
import random
print(random.randint(1,100))
benutzen und mir dann einfach wenn ich etwas suche jedesmal eine random zahl ausgeben lassen und dann meine entscheidung selbst wählen zb durch
print(random.randint(1,100)), und hier eben meine Suchfunktion bzw. Suchbefehl

Also meine Frage ist eigentlich nur. Gibt es in ipython irgendeine Suchfunktion die meine ausgewühle Liste und alle Unterlisten auf eine Eingabe durchsucht und mir dann jeden Treffen
anzeigt. Also suchanfrage AKo und er zeigt mir dann die jeweiligen Treffer in den UNterlisten an. Also zb
search A AKo,print(random.randint(1,100)) und es gibt mir aus (L=Ako(0.25),R=(AKo(0.75), randomzahl 1-100 aus

lg
BlackJack

@coffeeyay: Mach doch erst einmal das mit der Datenstruktur konkreter, denn das was Du da zeigst ist kein syntaktisch korrektes Python und die Zahlen in den Klammern sind mindestens mal komisch. So wie es aussieht sollte auch ein einzelnes Element noch einmal eine Datenstruktur sein die mindestens zwei Elemente enthält: einen Namen und eine Wahrscheinlichkeit. Und die sollte dann auch 1 oder 100% sein bei denen wo im Beispiel keine Klammern stehen. Dann braucht man diese Elemente nicht gesondert behandeln. `collections.namedtupel()` wäre hier vielleicht einen Blick wert. Auch die drei Listen sollten eventuell nicht nur einfache Listen sein wenn sie zusätzlich noch einen Namen haben sollen der bei der Ausgabe eine Rolle spielt.

So eine exotische Funktion gibt es natürlich nicht fertig, die muss man selber programmieren. Wenn Du die Datenstruktur entworfen und vorliegen hast, dann Teil das Problem in kleinere Teilprobleme auf, solange bis sich die Teilprobleme einfach mit jeweils einer kleinen Funktion lösen lassen. Das machst Du dann, testest die Teillösungen und baust sie dann zu einer Gesamtlösung zusammen.
coffeeyay
User
Beiträge: 3
Registriert: Mittwoch 28. Oktober 2015, 12:49

@ Blackjack
Schonmal vielen lieben dank für deine Antwort.
Ja die Datenstruktur muss noch in ein günstiges Format gebracht werden.
In der UNi programmieren wir leider nur C++ ):, daher kenne ich mich mit python noch nicht so gut aus, finde ipython aber aufgrund seiner einfachheit für mein Problem besser geeignet.

Doch ich glaube es ist am besten wenn ich vorher noch etwas das Prgramm erläutere und es nicht zu abstrakt mache.
Es soll ein Programm sein was strategische Entscheidungen für ein Pokerspiel liefert.
Es gibt 5 Listen, weil es 5 unterschiedliche Stacksizes gibt(Stackgröße, also die chipanzahl) A= 7chips, B=10chips, C=15, D=20 und E=25. Nun gibt es im Poker 3 Entscheidungen preflop. Ich kann die Hand raisen, ich kann sie limpen, und kann sie direkt allin stellen(shoven). (R,L,S). Für jede Stacksize unterscheiden sich nun diese 3 Strategischenmöglichkeiten. Bei 10BB ist zb AKo zu 100% limp, bei 15BB zu 100% ein raise.

Da ich weiss wiegroß meine chipanzahl ist kann ich zu beginn entscheiden welche Liste ich nutzen/abfragen möchte (A,B,C,D,E). Z.B ich habe 16 chips dann wähle ich Liste C(15chips). Nun tippe ich meine Handkombination ein zb. AKo oder AKs ( o bedeutet offsuited, also unterschiedlich, zb Ass in Herz und König in Pick, s bedeutet suited also gleiche farbe Ass herz und König herz)
Nun stehen in meiner C Liste noch 3 Unterlisten.
Eine für raise,limp und shove. Vllt steht in der raise Liste AKo(25%), in der limp liste Ako(25%) und in der shove liste Ako(50%). Diese werden mir nun angezeigt und da ich mit der Suchfunktion noch meine random1-100 funktion mitausgeführt habe wird mir nun noch eine random zahl zwischen 1-100 ausgegeben. Nun kann ich wenn ich zb eine 80 bekommen habe entscheiden das 51-100 shove ist und habe somit ein Ergebniss.

Vllt lässt sich eine Suchfunktion irgendwie durch einen Vergleich der ersten 2 Ziffern realisieren. Mal in Pseudocodeform if eingabeposition.at(0,1) == position.at(0,1) of object in the list, then print the object ^^

Aber wie Blackjack schon meine , ich fang am besten erstmal mit der Datenstruktur an.
Meine Eingabe liegt in folgender Form vor:( das könnte zb eine Liste für 20BB limp sein, also Liste D unterliste l)

AA,KK,QQ:0.75,JJ:0.25,TT:0.5,99:0.25,88:0.25,77:0.25,66:0.25,55:0.25,44:0.25,33:0.25,AKs:0.75,AKo:0.25,AQs,
AQo:0.5,AJs:0.75,AJo:0.25,ATs:0.75,ATo:0.25,A9s:0.25,A8s:0.5,A7s:0.5,A7o:0.25,A6:0.25,A5:0.25,A4:0.25,A3s:0.5,A3o:0.25,
A2s:0.5,KQ:0.5,KJ:0.5,KTs:0.25,KTo:0.5,K9:0.5,K8:0.5,K7s:0.5,K7o:0.25,K6s:0.5,K6o:0.25,K5:0.25,K4s:0.25,K3o:0.25,QJo:0.5,
QTo:0.5,Q9s:0.25,Q9o:0.5,Q8s:0.5,Q8o:0.25,Q7s:0.5,Q7o:0.25,Q6s:0.5,Q6o:0.25,Q5:0.25,Q4:0.25,Q3s:0.25,Q2s:0.25,JTs:0.5,
JTo:0.25,J9o:0.25,J8s:0.5,J8o:0.25,J7:0.25,J6:0.25,J5:0.25,J4:0.25,J3s:0.25,J2s:0.25,T9s:0.5,T9o:0.25,T8o:0.5,T7o:0.25,T6o:0.25,
T5s:0.5,T4s:0.5,T3s:0.25,T2:0.25,98s:0.5,98o:0.25,97s:0.25,97o:0.5,96:0.25,95s:0.5,95o:0.25,94s:0.25,93s:0.5,92s:0.25,
87:0.25,86:0.25,85s:0.5,84s:0.5,83s:0.25,82s:0.25,76:0.25,75s:0.5,75o:0.25,74s:0.5,73s:0.25,72s:0.25,65s:0.5,65o:0.25,64s:0.25,63s:0.5,
63o:0.25,62s:0.25,54s:0.5,54o:0.25,53s:0.5,53o:0.25,52s:0.5,43:0.25,42s:0.25,32s:0.25

Die Zahl nach dem : ist immer die Prozentzahl. Wenn nichts steht ist es 100% bzw. 1.0.
Ist natürlich ein schlechtes Format für eine Pythonliste. Daher habe ich den : schonmal durch eine () ersetzt wie inmeinem Eingangspost. Aber scheint wohl auch noch nicht das wahre zu sein.
Ich kann die Listen selbstständig in ein passendes Format umschreiben, sie sind nicht besondern lang, also daran soll es nicht scheitern.

Ist eben nun die Frage, was das beste Format ist. Aber die Frage kann ich ja schlecht beantworten wenn ich nicht direkt weiss wie ich meine Suchfunktion aufbauen.
Wenn ich die Suchfunktion aufbaue das sie zb die ersten 2 oder 3 Ziffern vergleicht wäre doch die Form AKs(75%) gut oder?
Bzw man könnte auch noch AKs(75% R,L oder S) draussmachen dann müsste man die Unterliste bei der Ausgabenicht mehr explizit angeben.
Testdurchlauf: unbekannte suchfunktion Liste A ,print(random.randint(1,100))
und würde man z.B als Ausgabe
AKs(75%R) AKs(25%L) randomzahl1-100
bekommen und wäre zufrieden
lg
coffeeyay
User
Beiträge: 3
Registriert: Mittwoch 28. Oktober 2015, 12:49

Habe nun mal meine Liste in ein Format gewandelt was funktionieren könnte.
A=['QQ(0.25)','JJ(0.75)','32s(R 0.75)',['32s(L 0.25)']]
Ist es nun möglich eine Suchfunktion zu schreiben das ich die ersten 3 Ziffern eingebe und er mir dann alle Inhalte die mit den gleichen Buchstaben anfangen postet?
In etwa so
Ich gebe 32s ein. Die Funktion vergleicht Liste A und alle Unterlisten auf Inhalte welche mit 32s anfangen und gibt sie mir dann aus.
if eingabe == position(0,1,2)of any object in List A then print the objects
Sprich ich gebe A32s ein und bekomme als Ausgabe 32s(R 0.75) 32s(L 0.25)
BlackJack

@coffeeyay: Natürlich ist das möglich, aber das möchte man IMHO nicht. Zuerst mal ist das mit drei Zeichen problematisch weil ja nicht alle Hand-Beschreibungen drei Zeichen haben. Das 's'/'o' kann anscheinend ja auch wegfallen. Und dann operierst Du da auf Zeichenketten herum die aus mehreren Werten zusammengesetzt sind und davon sind noch nicht einmal alle Werte von ihrer Natur her gesehen Zeichenketten. Und Du brauchst diese Werte für das Programm. Warum matscht Du die dann zu einer Zeichenkette zusmammen wo man sie erst heraus holen und umwandeln muss um sie benutzen zu können?

Da Du die Ausgangsdaten sowieso alle einmal anfassen musst um die in *diese* Form zu bringen, hätte man die auch gleich in eine passendere Struktur überführen können. Wenn man über Kartennamen + 's'/'o' auf den Wahrscheinlichkeitswert zugreifen möchte, dann würde sich auch ein Wörterbuch viel eher als eine Liste anbieten, dann wird die Suche nämlich deutlich einfacher und effizienter.

Ein mal schnell hingehackter Ansatz:

Code: Alles auswählen

from itertools import imap
from random import random


DATA = '''\
AA,KK,QQ:0.75,JJ:0.25,TT:0.5,99:0.25,88:0.25,77:0.25,66:0.25,55:0.25,44:0.25,
33:0.25,AKs:0.75,AKo:0.25,AQs, AQo:0.5,AJs:0.75,AJo:0.25,ATs:0.75,ATo:0.25,
A9s:0.25,A8s:0.5,A7s:0.5,A7o:0.25,A6:0.25,A5:0.25,A4:0.25,A3s:0.5,A3o:0.25,
A2s:0.5,KQ:0.5,KJ:0.5,KTs:0.25,KTo:0.5,K9:0.5,K8:0.5,K7s:0.5,K7o:0.25,K6s:0.5,
K6o:0.25,K5:0.25,K4s:0.25,K3o:0.25,QJo:0.5,QTo:0.5,Q9s:0.25,Q9o:0.5,Q8s:0.5,
Q8o:0.25,Q7s:0.5,Q7o:0.25,Q6s:0.5,Q6o:0.25,Q5:0.25,Q4:0.25,Q3s:0.25,Q2s:0.25,
JTs:0.5,JTo:0.25,J9o:0.25,J8s:0.5,J8o:0.25,J7:0.25,J6:0.25,J5:0.25,J4:0.25,
J3s:0.25,J2s:0.25,T9s:0.5,T9o:0.25,T8o:0.5,T7o:0.25,T6o:0.25,T5s:0.5,T4s:0.5,
T3s:0.25,T2:0.25,98s:0.5,98o:0.25,97s:0.25,97o:0.5,96:0.25,95s:0.5,95o:0.25,
94s:0.25,93s:0.5,92s:0.25, 87:0.25,86:0.25,85s:0.5,84s:0.5,83s:0.25,82s:0.25,
76:0.25,75s:0.5,75o:0.25,74s:0.5,73s:0.25,72s:0.25,65s:0.5,65o:0.25,64s:0.25,
63s:0.5,63o:0.25,62s:0.25,54s:0.5,54o:0.25,53s:0.5,53o:0.25,52s:0.5,43:0.25,
42s:0.25,32s:0.25
'''

class Hand(object):

    def __init__(self, cards, suited, probability):
        self.cards = cards
        self.suited = suited
        self.probability = probability

    def __str__(self):
        if self.suited is None:
            suited_string = ''
        else:
            suited_string = 's' if self.suited else 'o'
        
        return '{0}{1}{2}'.format(
            self.cards,
            suited_string,
            '' if self.probability == 1
                else ':{0:0.2f}'.format(self.probability)
        )

    def _key(self):
        return (self.cards, self.suited)

    def __cmp__(self, other):
        return cmp(self._key(), other._key())

    def __hash__(self):
        return hash(self._key())

    def random_test(self):
        return random() <= self.probability

    @classmethod
    def parse(cls, source):
        cards, colon, probability = source.strip().partition(':')
        cards, suited = cards[:2], cards[2:]
        assert len(cards) == 2
        probability = float(probability) if colon else 1.0
        assert 0 <= probability <= 1
        return cls(
            cards, {'': None, 's': True, 'o': False}[suited], probability
        )


class Hands(object):

    def __init__(self, hands):
        self.hand2hand = dict((h, h) for h in hands)

    def __len__(self):
        return len(self.hand2hand)

    def __getitem__(self, hand_string):
        return self.hand2hand[Hand.parse(hand_string)]

    def __str__(self):
        return ','.join(sorted(imap(str, self.hand2hand.itervalues())))

    @classmethod
    def parse(cls, source):
        parts = source.split(',')
        result = cls(imap(Hand.parse, parts))
        assert len(parts) == len(result)
        return result


def main():
    hands = Hands.parse(DATA)
    print hands
    print hands['AKo'].random_test()  # 25% probability of `True`.


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