Pagina 1 di 1

[Risolto] Migrazione a Python3: non solo () per print!

Inviato: martedì 11 aprile 2017, 8:59
da BlueEyes
Fino a ieri credevo che il passaggio di programmi da Python-2 a Python-3 fosse circoscritto a piccoli dettagli di natura sintattica, quali l'accorpamento dei contenuti di print tra parentesi tonde () ed altre sottigliezze, almeno per l'uso basilare che ne faccio io.
Ho invece scoperto che questo semplice programmino si blocca:

Codice: Seleziona tutto

# ------------- sum.py ------------
a = 1
s = 0
print ('Enter Numbers to add to the sum.')
print ('Enter 0 to quit.')
while a != 0 :
        print ('Current Sum:',s)
        a = input('Number? ')
        s = s + a
print ('Total Sum =',s)
# ------ EOF: sum.py ----------------

così:

alfabeta@ubuntu:~/Scrivania$ python3 sum.py
Enter Numbers to add to the sum.
Enter 0 to quit.
Current Sum: 0
Number? 10
Traceback (most recent call last):
  File "sum.py", line 8, in <module>
    s = s + a
TypeError: unsupported operand type(s) for +: 'int' and 'str'
-------------------
alfabeta@ubuntu:~/Scrivania$ python3 -V
Python 3.5.2
-------------------
Qualcuno può aiutarmi a correggerlo in modo che possa girare su Python3? Nei miei vecchi codici Py2 faccio largo uso del ciclo while. Grazie anticipate

Edit. Stessi costrutti su file di Py2

Codice: Seleziona tutto

Python 2.6.5
----------
$python sum.py
Enter Numbers to add to the sum.
Enter 0 to quit.
Current Sum: 0
Number? 10
Current Sum: 10
Number? -0.5
Current Sum: 9.5
Number? 0
Total Sum = 9.5

Re: Migrazione a Python3: non solo () per print!

Inviato: martedì 11 aprile 2017, 9:02
da SuperStep

Codice: Seleziona tutto

TypeError: unsupported operand type(s) for +: 'int' and 'str'
a diventa una stringa, quindi:

Codice: Seleziona tutto

s = str(s) + a
ottieni quindi una concatenazione di stringhe

Codice: Seleziona tutto

s = s + int(a)
ottieni la somma di s + a

Re: Migrazione a Python3: non solo () per print!

Inviato: martedì 11 aprile 2017, 11:32
da BlueEyes
Grazie per la risposta, SuperStep. Ho sostituito la riga della somma con s = s +float(a) e la cosa funziona, anche se a dire il vero l'uscita bisogna farla manualmente poichè il while tratta la variabile (a) come intera.

Codice: Seleziona tutto

Enter Numbers to add to the sum.
Enter 0 to quit.
Current Sum: 0
Number? 2.5
Current Sum: 2.5
Number? -6.987
Current Sum: -4.487
Number? 0
Current Sum: -4.487
Number? 0.0
Current Sum: -4.487
Number? 0
Current Sum: -4.487
Number?
Per completezza di informazione aggiungo la fonte da dove ho prelevato lo script, questa. A Python-2 che la variabile (a) sia intera o decimale importa poco, da cui si riesce a intuire il motivo dell'upgrading: python-3 è più "completo" in tal senso. Adesso metto il tag [Risolto] sul post d'apertura. Ciao, e ancora grazie.

Re: [Risolto] Migrazione a Python3: non solo () per print!

Inviato: martedì 11 aprile 2017, 19:15
da crap0101
la differenza è che su python2 input() valuta ciò che gli passi come fosse una qualsiasi espressione, motivo per cui il numero '0' viene appunto interpretato come zero (e motivo per cui non andrebbe usato in casi come questo quando ci sono alternative).
In python3 input() è identico al 'vecchio' raw_input() (che non esiste più) e quello che ti restituisce è sempre una stringa, che è anche il motivo per cui il while non termina mai... perchè 'a' è sempre una stringa e per definizione mai uguale a un float o a un int.

btw, con l' installazione di python, c'è anche uno script di nome 2to3 che serve per convertire i programmi versione 2 nella versione 3 automaticamente (per certe cose bisogna darci un occhio comunque, ma è comodo per le cose noiose, tipo se bisogna sostituire un sacco di print in print(), eccezioni e altro.

Re: [Risolto] Migrazione a Python3: non solo () per print!

Inviato: mercoledì 12 aprile 2017, 7:19
da BlueEyes
crap0101 [url=http://forum.ubuntu-it.org/viewtopic.php?p=4973191#p4973191][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:... con l' installazione di python, c'è anche uno script di nome 2to3 che serve per convertire i programmi versione 2 nella versione 3 automaticamente ...
Grazie mille crap0101! Sfrutterò certamente il tuo suggerimento spiegato qui in dettaglio, tenendo presente che conviene sempre rivedere il file dopo la conversione, come mi hai consigliato. Ciao, e alla prossima

Edit. Ecco le istruzioni d'uso:
Spoiler
Mostra

Codice: Seleziona tutto

$ 2to3 --help
Usage: 2to3 [options] file|dir ...

Options:
  -h, --help            show this help message and exit
  -d, --doctests_only   Fix up doctests only
  -f FIX, --fix=FIX     Each FIX specifies a transformation; default: all
  -j PROCESSES, --processes=PROCESSES
                        Run 2to3 concurrently
  -x NOFIX, --nofix=NOFIX
                        Prevent a transformation from being run
  -l, --list-fixes      List available transformations
  -p, --print-function  Modify the grammar so that print() is a function
  -v, --verbose         More verbose logging
  --no-diffs            Don't show diffs of the refactoring
  -w, --write           Write back modified files
  -n, --nobackups       Don't write backups for modified files
  -o OUTPUT_DIR, --output-dir=OUTPUT_DIR
                        Put output files in this directory instead of
                        overwriting the input files.  Requires -n.
  -W, --write-unchanged-files
                        Also write files even if no changes were required
                        (useful with --output-dir); implies -w.
  --add-suffix=ADD_SUFFIX
                        Append this string to all output filenames. Requires
                        -n if non-empty.  ex: --add-suffix='3' will generate
                        .py3 files.
Edit2.Testato (2to3), che ha cambiato il file del post d'apertura come segue:

Codice: Seleziona tutto

# -------- sum.py (adesso gira su Python-3) ---------
a = 1
s = 0
print('Enter Numbers to add to the sum.')
print('Enter 0 to quit.')
while a != 0 :
        print('Current Sum:',s)
        a = eval(input('Number? ')) # correzione ottenuta con (2to3)
        s = s + a
print('Total Sum =',s)
# --- EOF: sum.py ---------
Ed avviandolo si ottiene:

Codice: Seleziona tutto

$python sum.py
Enter Numbers to add to the sum.
Enter 0 to quit.
Current Sum: 0
Number? 2.6987
Current Sum: 2.6987
Number? -7.254
Current Sum: -4.555299999999999
Number? 10
Current Sum: 5.444700000000001
Number? 0
Total Sum = 5.444700000000001