Python2 for beginners (P4B)

Luca Ferroni

**Software Libero per i territori**

CAPITOLO 1: base

Installazione su Windows

  • Python con Anaconda (v. sito ufficiale di python), per ottenere:
    • l'interprete python e l'installatore di pacchetti pip
    • la shell interattiva IPython
  • Un editor di testo, consigliati:
    • Notepad++
    • Eclipse
    • PyCharm
    • Sublime o forse meglio Atom
    • Spe?
  • Git for Windows (http://git-scm.com)
    • include Git bash
  • Account GitHub http://github.com

Python's mantras

WARNING

  • Python non si riferisce al serpente
  • Ma al Monthy Python Flying Circus

E ora... "The hello tour!"

Il mio primo codice python


In [1]:
# This is hello_who.py

def hello(who):
    print("Hello {}!".format(who))

if __name__ == "__main__":
    hello("mamma")


Hello mamma!

IPython compagno di sviluppo

$ ipython
Python 2.7.12 (default, Jun 28 2016, 08:31:05) Type "copyright", "credits" or "license" for more information. IPython 5.0.0 -- An enhanced Interactive Python. ? -> Introduction and overview of IPython's features. %quickref -> Quick reference. help -> Python's own help system. object? -> Details about 'object', use 'object??' for extra details. In [1]: %run hello_who.py Hello mamma! In [2]: !cat src/hello_who.py def hello(who): print("Hello {}!".format(who)) if __name__ == "__main__": hello("mamma")

Tip: scopri lo Zen di Python PEP 20


In [2]:
# This is hello_who.py                # <-- i commenti iniziano con `#`
                                      #     possono essere all'inizio o a fine riga
def hello(who):                       # <-- la funzione di definisce con `def`
    print("Hello {}!".format(who))    # <-- la stampa con `print` e le stringhe con `format`

if __name__ == "__main__":            # <-- [verifica di esecuzione e non di import](https://docs.python.org/2/library/__main__.html)
    hello("mamma")                    # <-- invoco la funzione con il valore


Hello mamma!

La leggibilità conta

  • Le linee guida di stile sono nel PEP 8
    • ogni azienda può averne di differenti

Le classiche sono:

  • Indentazione con 4 spazi, e non : settate il vostro editor!
  • Lunghezza della riga <= 79 caratteri
  • Spazi intorno agli operatori

Le convenzioni per le docstring sono descritte nel PEP 257 in particolare:

  • Se monolinea scrivere tutto su una riga
  • Se multilinea il separatore finale (""") deve essere su una linea separata.

Mie convenzioni:

  • classi CamelCase e funzioni + variabili minuscole con _
  • il codice è scritto in inglese, in particolare i nomi delle variabili

In [4]:
cat '../src/hello/hello_who_3.py'


  File "<ipython-input-4-987dd684d3d4>", line 1
    cat '../src/hello/hello_who_3.py'
                                    ^
SyntaxError: invalid syntax

In [30]:
# -*- coding: utf-8 -*-

# This is hello_who_3.py
import sys                            # <-- importo un modulo


def compose_hello(who, force=False):   # <-- valore di default
    """
    Get the hello message.
    """ 
    try:                                     # <-- gestione eccezioni `Duck Typing`
        message = "Hello " + who + "!"
    except TypeError:                       # <-- eccezione specifica
    # except TypeError as e:                       # <-- eccezione specifica su parametro e
        print("[WARNING] Il parametro `who` dovrebbe essere una stringa")
        if force:                            # <-- controllo "if"
            message = "Hello {}!".format(who)
        else:
            raise                            # <-- solleva eccezione originale
    except Exception:
        print("Verificatasi eccezione non prevista")
    else:
        print("nessuna eccezione")
    finally:
        print("Bye")
    
    return message


def hello(who='world'):               # <-- valore di default
    print(compose_hello(who))


if __name__ == "__main__":
    hello("mamma")


Bye
Hello mamma!

In [20]:
hello("pippo")


Bye
Hello pippo!

In [24]:
hello(1)


[WARNING] Il parametro `who` dovrebbe essere una stringa
Bye
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-24-e35132e5d1c7> in <module>()
----> 1 hello(1)

<ipython-input-23-1d38d063a697> in hello(who)
     38     :param str who: The person to say Hello
     39     """
---> 40     print(compose_hello(who))
     41 
     42 

<ipython-input-23-1d38d063a697> in compose_hello(who, force)
     17 
     18     try:                                     # <-- gestione eccezioni `Duck Typing`
---> 19         message = "Hello " + who + "!"
     20     except TypeError:                       # <-- eccezione specifica
     21     # except ValueError as e:                       # <-- eccezione specifica su parametro e

TypeError: cannot concatenate 'str' and 'int' objects

In [25]:
ret = compose_hello(1, force=True)
print("Ha composto {}".format(ret))


[WARNING] Il parametro `who` dovrebbe essere una stringa
Bye
Ha composto Hello 1!

In [29]:
try:
    hello(1)
except TypeError as e:
    print("{}: {}".format(type(e).__name__, e))
    print("Riprova")


[WARNING] Il parametro `who` dovrebbe essere una stringa
Bye
TypeError: cannot concatenate 'str' and 'int' objects
Riprova

In [ ]:
fib(0) --> 0
fib(1) --> 1
fib(2) --> 1
fib(3) --> 2
fib(n) --> fib(n-1) + fib(n-2)

In [ ]:
import pytest
from myprogram import fib

def test_fib_ok_small():
    assert fib(0) == 0
    assert fib(1) == 1
    assert fib(2) == 1
    assert fib(3) == 2
    
def test_fib_raise_if_string():
    with pytest.raises(TypeError):
        fib("a")

def test_fib_raises_lt_zero():
    with pytest.raises(ValueError):
        fib(-1)