venerdì 22 febbraio 2013

Python - numeri e format()

Ebbene sì! sono ripetitivo. E noioso. Lo so ma continuo lo stesso, parlo ancora di format(), discorso iniziato qui.


Oggi si parla di numeri (n0.py):

#!/usr/bin/python
# -*- coding: utf-8 -*-

n_num = 8.0
n_den = 7
res =  n_num / n_den
print n_num, '/', n_den, '=', res
OK? Chi ha detto che fa schifo? Ha perfettamente ragione.
Vediamo come si può miglorare. Intanto un errore dovuto a un'eccessiva semplificazione potrebbe essere questo (n1.py):

#!/usr/bin/python
# -*- coding: utf-8 -*-

n_num = 8
n_den = 7
res =  n_num / n_den #divisione fra interi
print n_num, '/', n_den, '=', res
Ops! la divisione fra interi tronca il risultato, eliminando la parte decimale. Questo non sarà più vero nella versione 3.x (che in effetti c'è da tempo ma nessuno usa), esempio (n1_3.py):

#!/usr/bin/python
# -*- coding: utf-8 -*-

n_num = 8
n_den = 7
res =  n_num / n_den
print (n_num, '/', n_den, '=', res)
print()
print('per avere la divisione fra interi devo usare //')
res =  n_num // n_den
print (n_num, '//', n_den, '=', res)
Notare che nella versione 3 print è una funzione e non un'istruzione e sono quindi necessarie le parentesi.

Ricordo inoltre che è sempre disponibile l'operatore modulo %, resto (m.py):

#!/usr/bin/python
# -*- coding: utf-8 -*-

n_num = 8
n_den = 5
res1 = n_num / n_den
res2 = n_num % n_den
print n_num, '/', n_den, '=', res1
print n_num, '%', n_den, '=', res2


che per la 3.x diventa (m_3.py)

#!/usr/bin/python
# -*- coding: utf-8 -*-

n_num = 8
n_den = 5
res1 = n_num // n_den
res2 = n_num % n_den
print(n_num, '//', n_den, '=', res1)
print(n_num, '%', n_den, '=', res2)


Tornando al caso iniziale vediamo cosa si può fare (n2.py):

#!/usr/bin/python
# -*- coding: utf-8 -*-

n_num = 8.0
n_den = 7
res =  n_num / n_den
print '{:d} / {:d} = {:5.3f}'.format(int(n_num), n_den, res)
print 'oppure'
print '{:5.3f} / {:5.3f} = {:5.3f}'.format(n_num, n_den, res)

Problema: produrre 7 cosini ci costa 8 € e vogliamo avere un guadagno del 20% e coprire i rischi del 15%. Avremo (n3.py)

#!/usr/bin/python
# -*- coding: utf-8 -*-

n_num = 8.0
n_den = 7
costo =  n_num / n_den
prezzo = costo * 1.20 * 1.15

print 'costo: {:d} / {:d} = {:5.2f}'.format(int(n_num), n_den, costo)
print 'prezzo: {:5.2f} €'.format(prezzo)

ma attenzione, quelli della contabilità vogliono sapere per 1000 pezzi, abbiamo (n4.py):

#!/usr/bin/python
# -*- coding: utf-8 -*-

n_num = 8.0
n_den = 7
costo =  n_num / n_den
prezzo = costo * 1.20 * 1.15

print 'costo: {:d} / {:d} = {:5.2f}'.format(int(n_num), n_den, costo)
print 'prezzo: {:5.2f} €'.format(prezzo)

importo1000 = prezzo * 1000
print importo1000
print 'per 1000 pezzi: {:8.2f} €'.format(importo1000)

OK? No! sapete come sono quelli della contabilità:
I conti non tornano, ci sono 2 € e 86 ¢ di differenza, dobbiamo far quadrare!

Ci sarebbero due vie: quella sbagliata ve la dico subito ma poi la dimentichiamo (n5e.py):

#!/usr/bin/python
# -*- coding: utf-8 -*-

n_num = 8.0
n_den = 7
costo =  n_num / n_den
prezzo = costo * 1.20 * 1.15

print 'costo: {:d} / {:d} = {:5.2f}'.format(int(n_num), n_den, costo)
st_prezzo = '{:5.2f}'.format(prezzo)
prezzo_ok = float(st_prezzo)
print 'prezzo: {:5.2f} €'.format(prezzo_ok)

importo1000 = prezzo_ok * 1000
print 'per 1000 pezzi: {:8.2f} €'.format(importo1000)

Abbiamo cioè creato la stringa st_prezzo e da questa ricavato il suo valore prezzo_ok, con 2 cifre decimali come richiesto. Questo metodo non funziona per numeri grossi e poi è macchinoso. Ne esiste un altro molto migliore, usando round(). Facciamo un po' di pratica (r.py):

#!/usr/bin/python
# -*- coding: utf-8 -*-

import math

num = 20.0
den = 7

div = num / den
print num, '/', den, '=', div 
rdiv = round(div)
print 'arrotondato a', rdiv
print 'compreso tra', math.floor(div), 'e', math.ceil(div)  
print

num = 16.0
div = num / den
print num, '/', den, '=', div 
rdiv = round(div)
print 'arrotondato a', rdiv
print 'compreso tra', math.floor(div), 'e', math.ceil(div)  

print
print 'si può fare anche', div, '\napprossimato a', round(div, 2) 

OK? quindi per i nostri contabili la soluzione sarà (n5p.py):

#!/usr/bin/python
# -*- coding: utf-8 -*-

n_num = 8.0
n_den = 7
costo =  n_num / n_den
prezzo = costo * 1.20 * 1.15

print 'costo: {:d} / {:d} = {:5.2f}'.format(int(n_num), n_den, costo)
prezzo_ok = round(prezzo, 2)
print 'prezzo: {:5.2f} €'.format(prezzo_ok)

importo1000 = prezzo_ok * 1000
print 'per 1000 pezzi: {:8.2f} €'.format(importo1000)


OK, basta è tutto! (ve l'ho detto che era un post noioso).

L'indice di Mission Python lo trovate qui.

Nessun commento:

Posta un commento