One-line fp_hash (euplatesc) în Python

Am nevoie să fac integrare cu euplatesc.ro într-un proiect scris în Flask, aşa că mi-am pus ambiţia să fac calculul pentru fp_hash într-o singură linie. Probabil după câteva zile n-o să înţeleg nici eu ce naiba face codul ăla :slight_smile:

Nu ştiu cum se numeşte construcţia aia inline a array-ului, dar e un syntactic sugar foarte cool.

import hmac

mid = 'testaccount';
key = '00112233445566778899AABBCCDDEEFF';

data = {
    'amount'      : '1.00',
    'curr'        : 'RON',
    'invoice_id'  : '2000',
    'order_desc'  : 'Test order',
    'merch_id'    : mid,
    'timestamp'   : '20190101000000', 
    'nonce'       : 'f7d93357a7040619bc416881c479687f',
}


if __name__ == "__main__":
    fp_hash = hmac.new(bytes.fromhex(key), "".join([ str(len(item)) + item if item else "-" for item in data.values() ]).encode("utf-8"), "md5").hexdigest().upper()
    print(fp_hash)

List comprehension (cred)

Si urmatoarea persoana care sa uita la cod nu va intelege nimic.

Scrieti cod pe mai multe linii, separat logic. Pentru compilator/interpretor e indiferent ca e o linie sau sunt 50. Tot rapid le executa.

3 Likes

Da, aia pare să fie, thx. Mişto invenţie.

Ştiu, am făcut-o din pur amuzament, doar pentru că se poate :slight_smile:

1 Like

Poți scoate parantezele drepte și (1) o să meargă și (2) o să fie ceva mai eficient că nu trebuie sa aloci o lista nouă. Creezi un iterator cum ar veni cu o expresie de tipul comprehension.

TBF, nu-i cod deosebit de greoi. As zice poate chiar idiomatic pentru Python. După ce te obișnuiești ceva cu limbajul, că altfel arata ascii-art-ish.

2 Likes

Aaa, interesant, deci ăla e un tip de fapt. Iniţial mă gândeam că aş putea construi direct un string în felul ăsta (fără să fac array la care să fac join), dar aparent ceream pare mult.

L.E.

Ca să înţeleagă şi cei care citesc în viitor despre ce vorbim, expresia ar arăta aşa:

fp_hash = hmac.new(bytes.fromhex(key), "".join(str(len(item)) + item if item else "-" for item in data.values()).encode("utf-8"), "md5").hexdigest().upper()

Unul dintre lucrurile care-mi displac la python este că nu are ternary operator.

În loc de one-linere de genul:

foo = A ? B : C

Ai:

foo = B if A else C

Pe lângă faptul că e un pic mai lung, yoda talk mi se pare obositor. Dar hey, e o părere personală:D

3 Likes

Mie mi se pare că sună oarecum natural (sau măcar descriptiv), de exemplu dacă citeşti genul ăsta de statement:

print "red" if temperature > 40 else "green"

2 Likes

Îi fain dar Simple is better than complex.