Pagina 1 di 1

[Risolto][Python] La funzione 'floor' della libreria 'math'

Inviato: domenica 13 maggio 2012, 10:44
da BlueEyes
Non riesco a capire perché trovo gli strani errori elencati nell'output del codice. Se io assegno alla variabile n un numero pari, per esempio 6, mi aspetto che la funzione op mi restituisca la sua metà', ovvero 3. Mentre per n dispari (=7) dall'else dovrei ricavare il valore 22. Dove sbaglio? Grazie anticipate.

Codice: Seleziona tutto

#-------- op.py ----------
#
from math import floor        # floor, dalla libreria math 

def jump(n):
   steps = 0.0
   while n > 1:
      steps = steps + 1       # incremento di steps
      if floor(n/2) == n/2:   # n pari
         n = n/2         
      else:                   # n dispari
         n = 3*n + 1
   return steps 
Risultati:

Codice: Seleziona tutto

$ python
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:05:24) 
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import op
>>> op.jump(2)
1.0
>>> op.jump(4)
2.0
>>> op.jump(6)
2.0
>>> op.jump(8)
3.0
>>> op.jump(3)
1.0
>>> op.jump(5)
2.0
>>> op.jump(7)
2.0
>>> quit()

Re: [Python] La funzione 'floor' della libreria 'math'

Inviato: domenica 13 maggio 2012, 12:30
da Bakuriu
Il codice che hai postato è corretto. Infatti tu ritorni "steps" e non "n".

Ad esempio jump(6) prima divide n per 2 -> n=3 poi lo divide ancora per 2 -> n=1 a quel punto n <= 1 e quindi esce dal while e steps vale 2.0
Tra parentesi su python2 utilizzare floor in quel modo è inutile:

Codice: Seleziona tutto

giacomo@Giacomo-PC:~$ python
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53) 
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 3/2
1
>>> 
giacomo@Giacomo-PC:~$ python3
Python 3.2 (r32:88445, Dec  8 2011, 15:26:58) 
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 3/2
1.5
Per cui floor(n/2) == n/2 sarà sempre vera. Dovresti fare n//2 == n/2.0 (// -> forza la divisione intera sia su python2 che su python3)

edit: sostanzialmente la tua funzione jump calcola il floor del logaritmo in base 2 dell'argomento(infatti jump(4) -> 2, jump(8) -> 3, jump(16) -> 4 e jump(n) -> k se jump(2**k) < k < jump(2**(k+1)).

Re: [Python] La funzione 'floor' della libreria 'math'

Inviato: domenica 13 maggio 2012, 20:30
da BlueEyes
Il tuo ragionamento è corretto. Così come è impostato il codice, ciò che python restituisce non può che essere quello calcolato (anche con la forzatura di n//2).
E' importante sapere da dove l'ho prelevato. Da questa discussione del forum di Geogebra 5.0, che in fase Beta sta cercando di utilizzare delle routine Python. Lo svedese che ha aperto il topic (io sono l'altro!) ha posto quel quesito ed ha trovato una discrepanza (che ha poi corretto all'interno di Geogebra), ma ponendosi dei dubbi sull'applicabilità di funzioni provenienti da librerie esterne a Geogebra. Io gli ho solo fatto notare che anche con Python stand-alone il risultato è errato.
Ora ho capito che, concettualmente, con quel codice non si possono ottenere i risultati desiderati: numeri pari divisi per due, dispari moltiplicati per 3 a cui va sommato 1.
Spero di essermi spiegato bene e, se hai altre osservazioni, proseguiamo. Altrimenti metto il tag [risolto] sul primo post.
Ciao e grazie.

Re: [Python] La funzione 'floor' della libreria 'math'

Inviato: lunedì 14 maggio 2012, 11:08
da Bakuriu
A mio avviso state ragionando in modo scorretto...

Se usati i float allora semplicemente non esistono numeri pari e numeri dispari.
Se usate gli interi allora è sufficiente fare "not n % 2" per determinare se il numero è pari(e quindi anche se è dispari).

Forse nel caso di Geogebra tutti i numeri sono passati come float, ma allora forse la cosa più semplice è convertirli in int.

Re: [Python] La funzione 'floor' della libreria 'math'

Inviato: lunedì 14 maggio 2012, 13:18
da BlueEyes
Sì, direi che qualcosa del genere va meglio.

Codice: Seleziona tutto

n = input("numero intero= ")
if n%2 == 0 :
	print n/2
else:
	print 3*n+1    

Re: [Python] La funzione 'floor' della libreria 'math'

Inviato: martedì 15 maggio 2012, 8:10
da Bakuriu
BlueEyes ha scritto:Sì, direi che qualcosa del genere va meglio.

Codice: Seleziona tutto

n = input("numero intero= ")
if n%2 == 0 :
	print n/2
else:
	print 3*n+1    
No, usare "input" in python2 è sconsigliatissimo. Se vuoi un intero come input usa int(raw_input(...)).
Questo perchè input esegue il codice python che gli viene passato... il fatto che possa ritornare interi è solo una conseguenza di questo:

Codice: Seleziona tutto

>>> input()
5
5
>>> input()
"ciao"   #ritorna una stringa
'ciao'
>>> input()
[1,2,3]   #ritorna una lista
[1, 2, 3]
>>> input()
__import__('os').system('ls')   #esegue codice arbitrario! (qui potrebbe essere passato rm ...)
android-release-key.keystore  firestarter.sh.backup  Modelli                               prova.py~
CodeGolf                      Home                   modificati.txt                        prova.pyc
Desktop                       hostapd.conf           moodbar.sh                            Pubblici
distributore.py               hostapd.conf.backup    Musica                                racket
distributore.py~              hostapd-minimal.conf   NuSMV-2.5.4-x86_64-unknown-linux-gnu  res.txt
distributore.pyc              IdeaProjects           Progetti                              Scaricati
Documenti                     Immagini               prova2.py                             University
Dropbox                       ip_forward.backup      prova2.py~                            usr
dwhelper                      limits.conf            prova2.pyc                            Video
eclipse-workspaces            Matematica-varie       prova.py

Re: [Risolto][Python] La funzione 'floor' della libreria 'ma

Inviato: martedì 15 maggio 2012, 9:09
da BlueEyes
Per brevità ... ho scritto quel codice, ma il pedantissimo pistolotto sui vari usi di input() potevi evitarlo. Semplicemnte ... disturba!

Re: [Risolto][Python] La funzione 'floor' della libreria 'ma

Inviato: martedì 15 maggio 2012, 13:08
da Bakuriu
BlueEyes ha scritto:Per brevità ... ho scritto quel codice, ma il pedantissimo pistolotto sui vari usi di input() potevi evitarlo. Semplicemnte ... disturba!
"Per brevità" non mi sembra una "giustificazione" valida.. ti costa solo qualche carattere e secondo in più scrivere la versione "corretta".
Poi ogniuno fa ciò che vuole.

Mi capita troppo spesso di vedere principianti abusare input, anche perchè esistono guide che lo utilizzano a casaccio(normalmente cattive guide).
Quindi credo che riprendere questa bad-practice non sia inutile(perchè può aiutare che leggendo il codice che hai postato crede che input faccia una cosa mentre ne fa un'altra), e da persone che conoscono già questa differenza il mio ultimo messaggio può semplicemente essere ignorato.

La mia non era un richiamo pignolo a te, ma una spiegazione a chi non conosce la semantica di input in python2(tra cui potevi benissimo esserci anche tu, non mi è dato sapere).