ugrás a tartalomhoz

Leépülés (wordle átirat)

mind1 valami név · Ápr. 5. (K), 09.33
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? :)
 
1

Mit használnál json helyett

Endyl · Ápr. 5. (K), 09.56
Mit használnál json helyett az eredmény közlésére?

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.)
2

Ötkaraktetes stringet.

mind1 valami név · Ápr. 5. (K), 10.07
Ö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]))
3

Ebben az esetben ez a string

Endyl · Ápr. 5. (K), 10.52
Ebben az esetben ez a string válasz tényleg jobb lehet :)

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
4

Hogy mi a probléma?

mind1 valami név · Ápr. 6. (Sze), 12.52
Hát az, hogy napok óta nem vagyok képes egy ennyire primitív dolgot készre megírni. Meg az, hogy ezt a posztot kellett megirni ahhoz, hogy a sok hülyeség, mint pl a felesleges json előjöjjön. A poén a dologban, hogy az adatok json formára konvertálásának módszereiről olvasgatva jutott eszembe ez a programötlet :)
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.
5

Tranzakció... ehhez. :D (insert if doesn't exist)

mind1 valami név · Ápr. 11. (H), 17.37
Én is tudom bonyolítani az életet feleslegesen.
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)

begin_transaction()
puzzle=read_by_key(today)
if not puzzle:   # puzzle==None ha nem talált
    puzzle=generate_new()
    insert_to_db(puzzle)
try:
  commit()
expect IntegrityError:
  puzzle=read_by_key(today)
  commit()
except AnyOther:
  rollback()
  return ISE500
Ezt így szokás? Tranzakció indul, beolvasom, ha nincs, akkor generálok egy újat, beszúrom, ha duplicate key, akkor újra kiolvasom?
6

Talán kevésbé erőforrás

kuka · Ápr. 12. (K), 07.11
Talán kevésbé erőforrás igényes egy állományrendszer szintű lock. Csak a PHPs flock()-kal van tapasztalatom, azzal viszont jó. Hogy Pythonban fcntl.flock() vagy fcntl.lockf() a nyerő, azt nálam okosabbakra bízom.
puzzle = read_by_key(today)
if not puzzle:
    lock_file = open('lock.file', 'w')
    fcntl.flock(lock_file.fileno(), fcntl.LOCK_EX)

    puzzle = read_by_key(today)
    if not puzzle:
        puzzle = generate_new()  
        insert_to_db(puzzle)  

    fcntl.flock(lock_file.fileno(), fcntl.LOCK_UN)
7

De ez rdbms(sqlite) :)

mind1 valami név · Ápr. 12. (K), 10.38
De ez rdbms(sqlite), max. tábla szintű lock jöhetne szóba. ;)

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
8

Mint említettem, ez PHP

kuka · Ápr. 12. (K), 10.48
Mint említettem, ez PHP tapasztalat, de az 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.)
9

Úgy képzeltem, hogy az

mind1 valami név · Ápr. 12. (K), 12.21
Úgy képzeltem, hogy az adatbázisban tárolom a találgatásokat és az eredményeket is, innen jött az egész túlbonyolítás.
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. :(
10

Nagy csalódás a wordle magyar verziója :)

mind1 valami név · Ápr. 15. (P), 15.49
Meg akartam nézni a szerverrel folytatott kommunikációt.
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. :)
12

Az eredeti wordle sem

Endyl · Ápr. 17. (V), 23.12
Az eredeti wordle sem társalog a szerverrel :) Még feladvány generálás miatt sem. Minden megvan előre.
13

:) Ez egyébként hol látszik?

mind1 valami név · Ápr. 18. (H), 21.04
:)
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.
14

Eddig magam sem jártam utána,

Endyl · Ápr. 19. (K), 09.00
Eddig magam sem jártam utána, csak olvastam róla, meg néztem videókat, de ha beautifier.io-ba berakod az egyetlen js fájlját, akkor a 4990-4991 sorban láthatod a "mo" változóban a megoldásokat, a "fo"-ban pedig gondolom az elfogadott szavak listáját.

A megoldások elővétele meg itt van (kiválogatva a megfelelő részeket a kódból):

function xo(e, t) {
	var n = new Date(e),
		a = new Date(t).setHours(0, 0, 0, 0) - n.setHours(0, 0, 0, 0);
	return Math.round(a / 864e5)
}

function So(e) {
	var t, n = zo(e);
	return t = n % mo.length, mo[t]
}

function zo(e) {
	return xo(_o, e)
}

// ...

var e = {};
e.today = new Date;

e.solution = So(e.today)
15

Köszi. Én githubos forrásokat

mind1 valami név · Ápr. 19. (K), 09.10
Köszi. Én githubos forrásokat nézegettem, azokban nem láttam. Igaz, célzottan nem is keresgéltem. :)
11

Ellenőrizném, hogy a kliens tud-e cookie-t használni...

mind1 valami név · Ápr. 17. (V), 19.33
Mert ugye ez egy egészen primitív feladvány. Csakhát a kliensekkel csak a cookie-k segítségével tudok kapcsolatot tartani, ha nem akarok valami nagyon durva dologba belemenni (pl. websocket).
Ú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. :(
16

redirect kódok... (ti tudtátok?)

mind1 valami név · Ápr. 21. (Cs), 00.12
Keresgéltem a megoldást arra, hogy egy redirect után hogyan tudnám megőrizni a POST adatokat.
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?