Leépülés (wordle átirat)
Hát már ennyire leépültem agyilag.
Múlt héten felmerült bennem az ötlet, hogy azt a wordle nevű játékot (magyarul szozat.miklosdanka.com, jealoudmarkup.xyz/szofejto) megírom pythonban, json alapú kommunikációra építve, így automatizálni tudom a játékot, plusz bármilyen UI illeszthető hozzá:
- kell egy program, ami a feladványt generálja és fogadja a tippeket, válaszként elküldi, hogy milyen egyezéseket talál. Input akár egy sima string is lehet, output json formátumban az egyes betűkhöz tartozó jelzéssel, hogy van találat, a pozíció is helyes vagy semmi.
- kell egy másik, amelyik ugyanabból a szótárból dolgozik, amiből a játék motorja. Ez egy folyamatosan szűkülő listát generál a válaszok alapján és így találgat, első körben stratégia nélkül.
Problémák:
1. Minek ehhez a json? (És mióta felmerült a program ötlete, eszembe sem jutott, hogy hóttfelesleges)
2. Kulturált formában megírni a tippeket kiértékelő algoritmust. Egyelőre ott tartok, hogy betűnként ellenőrizni, van-e pozíció szerinti egyezés. De mit csináljak a rossz helyen lévő, esetleg ismétlődő betűkkel? Kulturált megoldás lenne, hogy a pozíció egyezésekor törlöm az adott betűt a feladványból és a tippből is? És ez részben nyelvi gond, mert pythonban írom és a pythonosok csúnyán néznek, ha nem hasznalom ki a nyelv lehetőségeit. :)
...
És akkor hol van még a megfejtést generáló program? :)
■ Múlt héten felmerült bennem az ötlet, hogy azt a wordle nevű játékot (magyarul szozat.miklosdanka.com, jealoudmarkup.xyz/szofejto) megírom pythonban, json alapú kommunikációra építve, így automatizálni tudom a játékot, plusz bármilyen UI illeszthető hozzá:
- kell egy program, ami a feladványt generálja és fogadja a tippeket, válaszként elküldi, hogy milyen egyezéseket talál. Input akár egy sima string is lehet, output json formátumban az egyes betűkhöz tartozó jelzéssel, hogy van találat, a pozíció is helyes vagy semmi.
- kell egy másik, amelyik ugyanabból a szótárból dolgozik, amiből a játék motorja. Ez egy folyamatosan szűkülő listát generál a válaszok alapján és így találgat, első körben stratégia nélkül.
Problémák:
1. Minek ehhez a json? (És mióta felmerült a program ötlete, eszembe sem jutott, hogy hóttfelesleges)
2. Kulturált formában megírni a tippeket kiértékelő algoritmust. Egyelőre ott tartok, hogy betűnként ellenőrizni, van-e pozíció szerinti egyezés. De mit csináljak a rossz helyen lévő, esetleg ismétlődő betűkkel? Kulturált megoldás lenne, hogy a pozíció egyezésekor törlöm az adott betűt a feladványból és a tippből is? És ez részben nyelvi gond, mert pythonban írom és a pythonosok csúnyán néznek, ha nem hasznalom ki a nyelv lehetőségeit. :)
...
És akkor hol van még a megfejtést generáló program? :)
Mit használnál json helyett
A tippből miért kell törölni? A feladványban le lehet cserélni olyan karakterre, ami nem szerepelhet a tippekben (pl. _), ha így ellenőrzöl, és akkor konzisztensek maradnak a betűk pozíciói. (Mondom ezt úgy, hogy nem gondoltam át, hogy lenne a legjobb megcsinálni az ellenőrzést.)
Ötkaraktetes stringet.
Pl:
Feladvány: 'tarol'
Kérdés: requests.get('https://szerver/talalgato?tipp=telek')
Erre a válasz:
'*.+..'
A kliens tudja, mit küldött be, simán össze tudja párosítani a válasszal:
telek
*.+..
Törölni azért, hogy ami már megvan találatként, azt ne ellenőrizzem újra és ne kelljen azzal foglalkozni, hogy amit ellenőrzök, az betű vagy már elhasznált helyet jelölő karakter.
Azért is fontos, hogy python, mert itt listából (string is az) könnyű törölni (del(lista[2]))
Ebben az esetben ez a string
Azt miért kéne ellenőrizned, hogy betű, vagy elhasznált hely? Egyszerűen nem illeszkedik rá az ellenőrzött karakter és kész. Persze nem tudom, hogy pontosan hogyan ellenőrzöl. Ha lényegtelenek a karakter indexek, akkor a törölgetés is jó lehet.
De ha mindenre megvan a megoldás, akkor mi a probléma? :D
Hogy mi a probléma?
Tegnap úgy félórám ráment, hogy megkeressem a base64 kifejezést,mert nem jutott eszembe, hogy hogyan kell egy bináris adatot textbe pakolni. (A http request headert akartam visszaküldeni jsonként, de sok mező nem kerülhet konvertálás nélkül json-be, bár nem tiszta, hogy miért)
És 22 éve még programozóként dolgoztam. :(
update: no meg olyan apróságok, hogy nem gondoltam bele, a flask mögé kell egy több szálból/processzből álló szerver és ha be is állítok valami globális értéket a kitalálandó szónak, az csak ahhoz a processzhez fog tartozni, így mind másik szóval indulna. Ergo marad, hogy még adatbázis is kéne mögé. :D Ennyit a primitív feladatokról.
Tranzakció... ehhez. :D (insert if doesn't exist)
Ugye a feladat az lenne, hogy minden napra egy darab ötbetűs szóval próbálkozhat a kliens.
Csakhogy adott egy fix környezet, ahová nem tudok szoftvert telepíteni (pl redis, memcached), marad, hogy sqlite adatbázisba teszem. Viszont a program min. négy független szálon fut amiknek azonos feladványt kell kiadni mindenkinek egy napon belül.
Elképzelés: benéz az adatbázisba, ha van a "mai" napra felvéve szó, akkor azzal dolgozik, ha nincs, generál egyet és felveszi.
Egyszerű. Míg bele nem gondolok, hogy több példányban fut a program.
O.K., primary key megoldja, hogy ne legyen egy napra több feladvány. De az mennyire kulturált, hogy (pseudo kód)
Talán kevésbé erőforrás
flock()
-kal van tapasztalatom, azzal viszont jó. Hogy Pythonbanfcntl.flock()
vagyfcntl.lockf()
a nyerő, azt nálam okosabbakra bízom.De ez rdbms(sqlite) :)
No igen... A szokásos, amiért felhagytam a szakmával: már megint túlgondolom. Ha már adatbázis, akkor minden napra egy új sor. De ha az egész táblát lockolom, akkor közben a többi user várakozni kényszerül, az úgy nem jó (Ja, hogy kb egy useres és kb egy-öt ezredmásodperc a lock teljes ideje/nap? Hát van ez így :D)
Update: hogy tovább cifrázzam... Pythonban egy sqlalchemy nevű ORM modult használok adatbázisok elérésére. A google a "sqlalchemy table lock" kifejezésre nem ad használható találatot. Egyetlen tipp: direktben sql-ből lockolni.
Update 2: https://stackoverflow.com/questions/71839414/insert-if-doesnt-exist-in-pythonsqlalchemy - mínuszolni elsőrendűen tudnak. Kérdést értelmezni kevésbé :D
Mint említettem, ez PHP
flock()
jobban bejött mint az adatbázisos bűvészkedések.Egyébként miért nem generálsz le hétfő éjfélkor cronból 10 napot előre, oszt volt lock nincs lock?
(Apró megjegyzés, hogy én úgy vettem észre, hogy az eredeti Wordle-ben nem napra vannak a szavak, hanem nap+időzónára.)
Úgy képzeltem, hogy az
Futtatni meg a pythonanywhere.com-on terveztem, ott macerás minden külső eszköz használata. Azt így hirtelen nem tudom, hogy a cron csak fizetős ügyfelek számára van, vagy ingyenesen is elérhető.
Egyébként nem wordle átirat, csak annyi köze van hozzá, hogy a "játékszabályok" azonosak. Csak megint az említett túlbonyolítás akadályoz.
A poén ebben az lenne, hogy megvalósulna Hidvégi Gábor (? asszem, ő volt) álma, miszerint a szerver csak adatokkal bombáz, a UI, a megjelenés a kliens hatásköre, így lehet a kliens egy automata is, mindenféle html parse-olás nélkül.
Ui: a poén, hogy a sqlite nem tud explicit lockolást... ezt nem is tudtam. :(
Nagy csalódás a wordle magyar verziója :)
De nincs.
WTF??
Hát azért nincs, mert local storage-ben tárolja az eredményeket és a feladványt is. :)
Ha változott a dátum, akkor kéri az újat a szerverről, az elküldi, a kliens lerakja local storage-be, oszt jónapot!
Én meg azt képzeltem, hogy a szerverrel társalog folyamatosan. :)
Az eredeti wordle sem
:) Ez egyébként hol látszik?
Ez egyébként hol látszik? (Hogy előre le van generálva)
Nem vagyok egy JS mágus, de én csak annyit láttam,hogy amikor új feladvány jön, akkor local storage-be letesz egy tömböt nulla próbálkozással és a megoldással.
Eddig magam sem jártam utána,
A megoldások elővétele meg itt van (kiválogatva a megfelelő részeket a kódból):
Köszi. Én githubos forrásokat
Ellenőrizném, hogy a kliens tud-e cookie-t használni...
Úgy képzeltem, hogy a kísérletezőknek generálok egy uuid-t, amit megtartok a kliens oldalon egy sütiben és a próbálkozásokat ezzel regisztrálom. Na ja, de mi van az automatizált kliensekkel? Minden próbához kapna egy új id-t, mert nem tárol cookie-t. Ezzel viszont simán DoS-olható az egész, mert pillanatok alatt felzabálja a rendelkezésre álló adatbázist néhány vicces kedvű egyén. :)
Jöhet, hogy ahol nincs cookie, ott nem regisztrálom a próbákat.
Aham... csak honnan tudja azt a szerver oldal, hogy a kliens nem tárol cookie-t?
Mert ami ötletet találtam, az kb. demonak jó, de végtelen ciklusba viszi az egészet. :(
redirect kódok... (ti tudtátok?)
Az előbb fedeztem fel, hogy a http 1.1 bevezetésével megjelent 307/308 redirect megőrzi a http metódust ha a szabványhoz igazodó böngészőt használok. (ha jól értem, eredetileg is így kellett volna működniük a böngészőknek, csak valamiért hanyagolták és következetesen GET-tel mentek tovább)
Mondjuk az nem teljesen tiszta, hogy melyiket kell használni olyankor, ha egy előzetes feldolgozás után dobom át a kérést egy másik címre. Mert ha az oldal költözött, akkor egyértelműen a permanens kell. De pl. egy automata login esetében?