Notizia:
  • Rilasciata Ubuntu 14.04 LTS Trusty Tahr. Per ottenerla, visitate questa pagina oppure visualizzate la dimostrazione.
  • È uscito il numero 15 della Newsletter italiana di Ubuntu. Lo trovate a questo indirizzo.
  • È uscito il numero 79 di Full Circle Magazine in italiano. Lo trovate a questo indirizzo.

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

Linguaggi di programmazione: php, perl, python, C, bash, ecc.

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

Messaggioda BlueEyes » domenica 13 maggio 2012, 10:44

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()
Ultima modifica di BlueEyes il lunedì 14 maggio 2012, 19:28, modificato 1 volta in totale.
Avatar utente
BlueEyes Non specificato
Entusiasta Emergente
Entusiasta Emergente
 
Messaggi: 1094
Iscrizione: marzo 2012

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

Messaggioda Bakuriu » domenica 13 maggio 2012, 12:30

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)).
Bakuriu Non specificato
Entusiasta Emergente
Entusiasta Emergente
 
Messaggi: 1153
Iscrizione: ottobre 2009
Distribuzione: Kubuntu 12.04 LTS - x86_64
Desktop: KDE4

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

Messaggioda BlueEyes » domenica 13 maggio 2012, 20:30

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.
Avatar utente
BlueEyes Non specificato
Entusiasta Emergente
Entusiasta Emergente
 
Messaggi: 1094
Iscrizione: marzo 2012

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

Messaggioda Bakuriu » lunedì 14 maggio 2012, 11:08

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.
Bakuriu Non specificato
Entusiasta Emergente
Entusiasta Emergente
 
Messaggi: 1153
Iscrizione: ottobre 2009
Distribuzione: Kubuntu 12.04 LTS - x86_64
Desktop: KDE4

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

Messaggioda BlueEyes » lunedì 14 maggio 2012, 13:18

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   
Avatar utente
BlueEyes Non specificato
Entusiasta Emergente
Entusiasta Emergente
 
Messaggi: 1094
Iscrizione: marzo 2012

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

Messaggioda Bakuriu » martedì 15 maggio 2012, 8:10

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
Bakuriu Non specificato
Entusiasta Emergente
Entusiasta Emergente
 
Messaggi: 1153
Iscrizione: ottobre 2009
Distribuzione: Kubuntu 12.04 LTS - x86_64
Desktop: KDE4

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

Messaggioda BlueEyes » martedì 15 maggio 2012, 9:09

Per brevità ... ho scritto quel codice, ma il pedantissimo pistolotto sui vari usi di input() potevi evitarlo. Semplicemnte ... disturba!
Avatar utente
BlueEyes Non specificato
Entusiasta Emergente
Entusiasta Emergente
 
Messaggi: 1094
Iscrizione: marzo 2012

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

Messaggioda Bakuriu » martedì 15 maggio 2012, 13:08

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).
Bakuriu Non specificato
Entusiasta Emergente
Entusiasta Emergente
 
Messaggi: 1153
Iscrizione: ottobre 2009
Distribuzione: Kubuntu 12.04 LTS - x86_64
Desktop: KDE4


Torna a Programmazione

Chi c’è in linea

Visualizzano questa sezione: 0 utenti registrati e 3 ospiti