'''
ARGOMENTI:
---------------------------------------------------------------------
        - tipi di dato standard

                "Python 3" ha quattro tipi di dati standard -

                SEMPLICI
                    interi (int)
                    
                    numeri in virgola mobile (float)
                        Bisogna sempre considerare i numeri in virgola mobile come
                        numeri approssimati. La funzione "repr" ci mostra la
                        rappresentazione interna del numero.
                    
                    numeri complessi (complex)
                    
                    valori booleani (bool)
                        Il tipo "bool" fa parte della famiglia  dei tipi numerici
                        in quanto derivato dal tipo "int". True e False, nelle
                        operazioni matematiche, vengono valutati come 1 e 0.

                SEQUENZE IMMUTABILI
                    stringhe (str)
                        La stringa e' un tipo di dato composto. 
                        E' possibile trattarla come un tipo composto o agire sulle
                        sue singole parti. Le stringhe sono immutabili: str[0] = 'A'
                        produce un errore
                        
                    tuple (tuple)
                    
                    insiemi immutabili (frozenset)

                SEQUENZE MUTABILI
                    liste (list),
                    dizionari (dict)
                    insiemi (set)
                    file (file)
                  
                    
                Oltre a liste, tuple, e dizionari, Python fornisce altri due 
                contenitori built-in: set e frozenset. I set (insiemi) vengono usati 
                per rappresentare un set non ordinato di oggetti unici. Questa 
                sequenza e' mutabile nel caso di set, e immutabile nel caso di frozenset.

'''



# INTERI
#-------------------------------------------------------------------------------------
n_decimaleA = 15
n_decimaleB = 15
n_binarioA = 0b1101
n_binarioB = 0b1000
n_ottaleA=0o76
n_ottaleB=0o20
n_esadecimaleA = 0xF3
n_esadecimaleB = 0x1A


print("----------------------------")
print("Tipi:")
print("----------------------------")
print (type(19))
print (type(n_binarioA))
print (type(0o20))
print (type(n_esadecimaleB))

print("----------------------------")
print("Valori")
print("----------------------------")
print (int(n_binarioA))
print (bin(33))
print (oct(n_esadecimaleB))
print (hex(123))

print("----------------------------")
print("Operatori aritmetici")
print("----------------------------")
print(n_decimaleA - 2)
print(n_binarioA + n_binarioB)          # risultato decimale
print(n_decimaleA + n_binarioB)         # risultato decimale
print(n_decimaleA / 4)                  # "vera" se Python 3 (float) - "floor" se Python 2 (int)
print(n_decimaleA // 4)                 # floor (int)
print(5* n_decimaleB)                   # prodotto
print(n_decimaleB**2)                   # potenza
print(18%5)                             # modulo

print("----------------------------")
print("Operatori booleani")
print("----------------------------")
print(n_decimaleA==3)                   # confronto contenuto
print(n_decimaleA is n_decimaleB)       # confronto sull'oggetto: "true" perchè python predilige il riutilizzo di oggetti   
print(7>5)                              
print(7<5)
print(n_decimaleA<=15)   
print(n_decimaleB>=15)        
print(n_decimaleA!=15) 
print(4<6<8) 
print(2>5>7)

print("----------------------------")
print("Operatori binari")
print("----------------------------")   
print(bin(0b1010))
print(bin(0b1011))   
print(bin(0b1010>>3))                   # shift a DX di 3 posizioni
print(bin(0b1011<<3))                   # shift a SX di 3 posizioni
print(bin(~0b1101011))                  # inverte i bit
print(bin(0b1010 & 0b1001))             # AND bit per bit
print(bin(0b1010 | 0b1001))             # OR bit per bit
print(bin(0b1010 ^ 0b1001))             # OR ESCLUSIVO bit per bit




# FLOAT
#-------------------------------------------------------------------------------------
n_floatA = 15.3
n_floatB = -0.07
print("----------------------------")
print("Float")
print("----------------------------") 
print(n_floatA + n_floatB)
print(n_floatA - n_floatB)


# COMPLESSI
#-------------------------------------------------------------------------------------
n_complexA = (15+3j)
n_complexB = (-2+1j)
print("----------------------------")
print("Complessi")
print("----------------------------") 
print(n_complexA + n_complexB)
print(n_complexA - n_complexB)
print(n_complexA * n_complexB)
print(n_complexA / n_complexB)
print(n_complexA.real)
print(n_complexA.imag)
print(n_complexA.conjugate())

# BOOLEANI
#-------------------------------------------------------------------------------------
n_boolA = True
n_boolB = False
print("----------------------------")
print("Booleani")
print("----------------------------") 
print (type(n_boolA))
print (type(n_boolB))
print (12+n_boolA)
print (12+n_boolB)
print (n_boolA or n_boolB)
print (n_boolA and n_boolB)
print (not n_boolA)


# STRINGHE
#-------------------------------------------------------------------------------------
strA = "Milano"
strB = "Roma"
strC = "'Viterbo'"
strD = '"Rho"'
print("----------------------------")
print("Stringhe")
print("----------------------------") 
print (type(strA))
print (strA + strB +   strC +  strD)
print (strA + " " +  strB + " " +  strC + " " +  strD)
print (strA, strB, strC, strD)
print (strA[0], strA[3], strA[5])
lunghezza=len(strA)
print (lunghezza)
print (strA[lunghezza-1])                           # ultimo elemento
tutte=strA + strB +   strC +  strD
print(tutte)
print(tutte[6:10])                                  # primo incluso, secondo escluso
print(strA[:2])                                     # escluso
print(strA[2:])                                     # incluso
print (strA<strB)
print ("aa">"bb")
print (strA=='Milano')
print (strA=='milano')
print (strA!=strB)

# TUPLE
#-------------------------------------------------------------------------------------
tuplaA = 'c','i','a','o'                    
tuplaB = ('123','3.5','ciao','d.=&$')       # assegnazione consigliata -> con parentesi
tuplaC =('X',)                              # con virgola -> tupla con un elemento
notupla =  ('X')                            # senza virgola -> stringa
print("----------------------------")
print("Tuple")
print("----------------------------") 
print (type(tuplaA))
print (type(tuplaC))
print (type(notupla))
print (tuplaA)
print (tuplaB)
print (tuplaC)


# SET e FROZENSET
#-------------------------------------------------------------------------------------
setA = {1, 2, 3, 4, 1, 2, 6}                   
setB = {'a', 'b', 'c'}  
fsetA= frozenset ({10,11,12,13})
fsetB  = frozenset(setB)          
setC  = set(fsetA)  
print("----------------------------")
print("Set e Frozenset")
print("----------------------------") 
print (type(setA))                  # Notare eliminazione duplicati  
print (type(setB))                  # Notare NON ordinamento
print (type(fsetA))
print (type(fsetB))
print (type(setC))
print (setA)
print (setB)
print (setC)
print (fsetA)
print (fsetB)
dizVUOTO = {}                       # nuovo dizionario vuoto
setVUOTO = set()                    # nuovo set vuoto
fsetVUOTO = frozenset()             # nuovo frozenset vuoto
print (type(dizVUOTO))
print (type(setVUOTO))
print (type(fsetVUOTO))

print (len(setA) )                   # numero di elementi
print (min(setA) )                   # elemento più piccolo
print (max(setA) )                   # elemento più grande

setA.add(120)                       # aggiunge 120
setA.add(7)                         # aggiunge 120
print (setA)
setA.remove(1)                      # rimuove 1, la rimozione di un elemento non appartenente 
                                    # ... all'insieme produce un errore
setA.discard(7)                     # rimuove 7, la rimozione con 'discard' di un elemento  
                                    # ...non appartenente all'insieme NON produce un errore
setA.discard(7)

print (setA)
print (setA.pop())                  # rimuove e restituisce un elemento arbitrario
print (setA)
setA.clear()                        # rimuove tutti gli elementi
print (setA)
'''
https://www.python.it
https://it.wikibooks.org/wiki/Python
Programmare con Python - Marco Buttu - Edizioni LSWR


SEQUENZE MUTABILI ---> successivamente
'''
