Implementare validare CIF in Python, asistat de AI

Încă o dată Python m-a dat pe spate cu cât de concis se poate scrie un algoritm relativ complex:

Pas preliminar: Se testează dacă codul respectă formatul unui cod de identificare fiscală (CIF). Adică lungimea maximă să fie de 10 cifre și să conțină doar caractere numerice.

Pas 1: Se folosește cheia de testare “753217532”. Se inversează ordinea cifrelor codului precum și a cheii de testare.

Pas 2: Se ignoră prima cifra din codul inversat (aceasta este cifra de control) și se înmulțește fiecare cifră cu cifra corespunzătoare din cheia de testare inversată.

Pas 3: Se adună toate produsele obținute. Suma rezultată se înmulțește cu 10 și produsul este împărțit la 11. Cifra obținută, în urma operației MODULO 11, reprezintă cifra de verificare. Dacă în urma împărțirii s-a obținut restul 10 atunci cifra de verificare va fi 0.

Pas 4: Pentru un CIF valid cifra de verificare va trebui să corespundă cu cifra de control a CIF inițial.

Cod de identificare fiscală - Wikipedia

ChatGPT nu a fost în stare să implementeze cerința, dar Copilot a fost capabil să vină cu ideea cu sum(zip(...)), rezultatul final fiind acesta:

def validate_cif(cif):
    cif = cif.upper().strip()
    cif = cif.replace(" ","")

    if cif.startswith("RO"):
        cif = cif[2:]

    if not cif.isdigit() or len(cif) < 2 or len(cif) > 10:
        return None

    reversed_cif = [int(i) for i in cif[::-1]]
    check_digit = reversed_cif.pop(0)
    result = sum([a*b for a,b in zip(reversed_cif, (2, 3, 5, 7, 1, 2, 3, 5, 7))]) * 10 % 11

    return cif if (check_digit == result) or (result == 10 and check_digit == 0) else None
1 Like

Te rog eu nu scrie cod de genul chiar daca poti :smiley:

Bine inafara de result = sum([a*b for a,b in zip(reversed_cif, (2, 3, 5, 7, 1, 2, 3, 5, 7))]) * 10 % 11 restul e usor de inteles.

De ce nu, sunt sigur că pentru pythonist nu e deloc greu de înțeles ce face acel sum :slight_smile: Cel mult aș scoate acel reversed key in afară, de genul:

reversed_key = (2, 3, 5, 7, 1, 2, 3, 5, 7)
result = sum([a*b for a,b in zip(reversed_cif, reversed_key)]) * 10 % 11
1 Like

ce face? [1]


  1. nu-s pitonist ↩︎

reversed_cif si reversed_key sunt niste array-uri de integeri. zip() face un soi de join, creaza un array de perechi intre elementele lui cif si key.

Intre paranteleze drepte se parcurge acel array de perechi si inmulteste intre ele elementele din fiecare pereche, rezultand un array de produse.

sum() parcurge array-ul de produse, rezultand o suma.

Suma se imulteste cu 10 si la rezultat se aplica modulo 11.

Simplu ca buna ziua :slight_smile:

zip se refera la
image

1 Like

Doua lucruri as schimba:

  • Regex pentru validare dintr-un foc. E fi suficient de simplu cat sa fie mai lizibil decat toate acele conditii pentru prefix si lungime
  • reversed in loc de ::-1