Eval è proibito?

R
Raffaele (3850 points)
11 24 48
asked Nov 11, 2020 in HW4 obbligatorio by Raffaele (3,850 points)
recategorized Nov 12, 2020 by andrea.sterbini
Facendo i test sul programma ho notato che stranamente la funzione eval() è proibita, non capisco la ragione considerando che non sto importando librerie ed è una funzione built in.
356 views

2 Answers

Best answer
O
Oakandrew (6400 points)
4 26 63
answered Nov 12, 2020 by Oakandrew (6,400 points)
selected Nov 12, 2020 by Raffaele
Perche puoi eseguire il codice come la stringa(per esempio for loop) dentro di eval() e praticamente ridurre cc. La stessa cosa anche con exec()
R
Raffaele (3850 points)
11 24 48
commented Nov 12, 2020 by Raffaele (3,850 points)
Exec non me lo dà proibito comunque
Romitoskj (8920 points)
4 8 40
commented Nov 12, 2020 by Romitoskj (8,920 points)
Giusto non ci avevo pensato, se si scrive tutto il codice dentro un eval la cc è sempre 1 e non viene incrementata.
O
Oakandrew (6400 points)
4 26 63
commented Nov 12, 2020 by Oakandrew (6,400 points)
Cmq non mi sembra giusto che 100 cicli for  darebbero cc uguale a 1
andrea.sterbini (172780 points)
513 935 1789
commented Nov 12, 2020 by andrea.sterbini (172,780 points)
Giusto, lo aggiungo sulla VM.
R
Raffaele (3850 points)
11 24 48
commented Nov 12, 2020 by Raffaele (3,850 points)
Comunque si non sarebbe giusto lasciarli usare.. Non avevo considerato la possibilità di abbassare la cc in quel modo.
twgever (15190 points)
7 27 105
commented Nov 12, 2020 by twgever (15,190 points)
non abbassa la cc nella stessa maniera anche usare map(lambda) ? sempre è una maniera per aggirare il for, no?
Romitoskj (8920 points)
4 8 40
commented Nov 12, 2020 by Romitoskj (8,920 points)

@twgever  si ma in quel caso aggiri solo uno statement, se scrivessi un intera funzione in un eval o un exec aggireresti tutti gli statement presenti nella funzione.

O
Oakandrew (6400 points)
4 26 63
commented Nov 12, 2020 by Oakandrew (6,400 points)
edited Nov 12, 2020 by Oakandrew

Si puo scrivere map() dentro un'altra map(). map() ti costringe di avere approccio funzionale, invece in exec() potresti avere imperativo.

A parte di questo la metrica cc secondo me valuta complessità del codice molto bene. Come già scritto in definizione di complessità ciclomatica(McCabe),su quale basato approccio di radon:

The cyclomatic complexity of a section of source code is the number of linearly independent paths within it—where "linearly independent" means that each path has at least one edge that is not in one of the other paths

Da questo punto sembra che map() dovrebbe aggiungere 1 a complessità ciclomatica. Ma non è cosi semplice.

La formula per contare complessità ciclomatica di operazioni dentro funzione è:

M = E − N + 2P

dove: 

E- quantità di lati

N- quantità di nodi

P-è il numero di componenti connessi(nel nostro caso uguale a 1,numero di elementi connessi)

Per esempio se consideri un semplice for con print(indice)  dentro avrai:

2 lati - 2 nodi+2=2

da quello che ho capito,in caso di map():

1 lato-2 nodi+2=1

perche non verifica nessuna condizione

In exec() invece nascondi complessita ciclomatica perchè radon lo considera come la stringa

In teoria dovrebbe essere anche un'altra metrica come readability(funzionamento identico come in PA) del codice(per evitare 100 funzioni map una dentro l'altra), che a sua volta potrebbe essere implementata dopo PA di ogni homework.

Romitoskj (8920 points)
4 8 40
answered Nov 12, 2020 by Romitoskj (8,920 points)
Precisamente non lo so, ma non capisco il motivo per cui utilizzarla in questo hw.

In ogni caso funzioni eval si tendono ad evitare perché possono causare facilmente errori dato che il codice passato come parametro potrebbe non essere corretto. Potrebbe essere stata proibita proprio perché "non è una buona soluzione".
R
Raffaele (3850 points)
11 24 48
commented Nov 12, 2020 by Raffaele (3,850 points)
Io in realtà avrei abbassato i tempi del 40% utilizzandola... Quindi direi che farebbe comodo, già non abbiamo le regular expression..

Stiamo praticamente usando un python monco
Romitoskj (8920 points)
4 8 40
commented Nov 12, 2020 by Romitoskj (8,920 points)

Ahahaha, assolutamente vero. La mancanza delle RE si fa sentire...

Più che una brutta soluzione in termini di efficienza è una brutta soluzione in termini di sicurezza, credo sia questo il motivo.

Come citato in questo articolo:

Although it has an almost unlimited number of uses, Python’s eval() also has important security implications. eval() is considered insecure because it allows you (or your users) to dynamically execute arbitrary Python code.