Pensare da informatico/Listati dei programmi

Indice del libro

class Punto

modifica
class Punto: 
  def __init__(self, x=0, y=0): 
    self.x = x 
    self.y = y 

  def __str__(self): 
    return '(' + str(self.x) + ', ' + str(self.y) + ')' 

  def __add__(self, AltroPunto): 
    return Punto(self.x + AltroPunto.x, self.y + AltroPunto.y) 

  def __sub__(self, AltroPunto): 
    return Punto(self.x - AltroPunto.x, self.y - AltroPunto.y) 

  def __mul__(self, AltroPunto): 
    return self.x * AltroPunto.x + self.y * AltroPunto.y 

  def __rmul__(self, AltroPunto): 
    return Punto(AltroPunto * self.x,  AltroPunto * self.y) 

  def reverse(self): 
    self.x , self.y = self.y, self.x 

  def DirittoERovescio(Stringa): 
    import copy 
    Rovescio = copy.copy(Stringa) 
    Rovescio.reverse() 
    print str(Stringa) + str(Rovescio)

class Tempo

modifica
# ------------------- 
# Versione funzionale 
# ------------------- 
#   t = Tempo(3,14) 
#   s = Tempo(8,12,15) 
#   print SommaTempi(s, t) 

def ConverteInSecondi(Orario): 
  Minuti = Orario.Ore * 60 + Orario.Minuti 
  Secondi = Minuti * 60 + Orario.Secondi 
  return Secondi 

def ConverteInTempo(Secondi): 
  Orario = Tempo() 
  Orario.Ore = Secondi / 3600 
  Secondi = Secondi - Orario.Ore * 3600 
  Orario.Minuti = Secondi / 60 
  Secondi = Secondi - Orario.Minuti * 60 
  Orario.Secondi = Secondi 
  return Orario 

def SommaTempi(Tempo1, Tempo2): 
  Secondi = ConverteInSecondi(Tempo1) + ConverteInSecondi(Tempo2) 
  return ConverteInTempo(Secondi) 

# ------------------ 
# Versione a oggetti 
# ------------------ 
# con modifica di uno degli oggetti: 
#   t = Tempo(3,14) 
#   s = Tempo(8,12,15) 
#   t.AggiungiTempo(s) 
#   print t 
# in alternativa, senza modificare t: 
#   a = Tempo() 
#   a.SommaTempi(t, s) 
#   print a 

class Tempo: 
  def __init__(self, Ore=0, Minuti=0, Secondi=0): 
    self.Ore = Ore 
    self.Minuti = Minuti 
    self.Secondi = Secondi 

  def __str__(self): 
    return str(self.Ore) + ":" + str(self.Minuti) + ":" + \ 
                                 str(self.Secondi) 

  def Incremento(self, Secondi): 
    Secondi = Secondi + self.Secondi + self.Minuti*60 + \ 
              self.Ore*3600 
    self.Ore = Secondi / 3600 
    Secondi = Secondi % 3600 
    self.Minuti = Secondi / 60 
    Secondi = Secondi % 60 
    self.Secondi = Secondi 

  def ConverteInSecondi(self): 
    Minuti = self.Ore * 60 + self.Minuti 
    Secondi = Minuti * 60 + self.Secondi 
    return Secondi 

  def ConverteInTempo(self, Secondi): 
    self.Ore = Secondi / 3600 
    Secondi = Secondi - self.Ore * 3600 
    self.Minuti = Secondi / 60 
    Secondi = Secondi - self.Minuti * 60 
    self.Secondi = Secondi 

  def AggiungiTempo(self, Tempo2): 
    Secondi = self.ConverteInSecondi() + \ 
              Tempo2.ConverteInSecondi() 
    self.ConverteInTempo(Secondi)  # l'oggetto self e' stato  
                                   # modificato! 

  def SommaTempi(self, Tempo1, Tempo2): 
    Secondi = Tempo1.ConverteInSecondi() + \ 
              Tempo2.ConverteInSecondi() 
    self.ConverteInTempo(Secondi)

Carte, mazzi e giochi

modifica
import random 

class Carta: 

  ListaSemi = ["Fiori", "Quadri", "Cuori", "Picche"] 
  ListaRanghi = ["impossibile", "Asso", "2", "3", "4", "5", "6", 
                 "7", "8", "9", "10", "Jack", "Regina", "Re"] 

  def __init__(self, Seme=0, Rango=0): 
    self.Seme = Seme 
    self.Rango = Rango 

  def __str__(self): 
    return (self.ListaRanghi[self.Rango] + " di " + \ 
            self.ListaSemi[self.Seme]) 

  def __cmp__(self, Altro): 

    # controlla il seme 
    if self.Seme > Altro.Seme: return 1 
    if self.Seme < Altro.Seme: return -1 

    # se i semi sono uguali controlla il rango 
    if self.Rango > Altro.Rango: return 1 
    if self.Rango < Altro.Rango: return -1 

    # se anche i ranghi sono uguali le carte sono uguali! 
    return 0 

class Mazzo: 

  def __init__(self): 
    self.Carte = [] 
    for Seme in range(4): 
      for Rango in range(1, 14): 
        self.Carte.append(Carta(Seme, Rango)) 

  def StampaMazzo(self): 
    for Carta in self.Carte: 
      print Carta 

  def __str__(self): 
    s = "" 
    for i in range(len(self.Carte)): 
      s = s + " "*i + str(self.Carte[i]) + "\n" 
    return s 

  def Mischia(self): 
    import random 
    NumCarte = len(self.Carte) 
    for i in range(NumCarte): 
      j = random.randrange(i, NumCarte) 
      self.Carte[i], self.Carte[j] = self.Carte[j], self.Carte[i] 

  def RimuoviCarta(self, Carta): 
    if Carta in self.Carte: 
      self.Carte.remove(Carta) 
      return 1 
    else: 
      return 0 

  def PrimaCarta(self): 
    return self.Carte.pop() 

  def EVuoto(self): 
    return (len(self.Carte) == 0) 

  def Distribuisci(self, ListaMani, NumCarte=999): 
    NumMani = len(ListaMani) 
    for i in range(NumCarte): 
      if self.EVuoto(): break         # si ferma se non ci sono  
                                      # piu` carte 
      Carta = self.PrimaCarta()       # prende la carta  
                                      # superiore del mazzo 
      Mano = ListaMani[i % NumMani]   # di chi e` il prossimo  
                                      # turno? 
      Mano.AggiungiCarta(Carta)       # aggiungi la carta  
                                      # alla mano 


class Mano(Mazzo): 

  def __init__(self, Nome=""): 
    self.Carte = [] 
    self.Nome = Nome 

  def AggiungiCarta(self,Carta) : 
    self.Carte.append(Carta) 

  def __str__(self): 
    s = "La mano di " + self.Nome 
    if self.EVuoto(): 
      s = s + " e' vuota\n" 
    else: 
      s = s + " contiene queste carte:\n" 
    return s + Mazzo.__str__(self) 


class GiocoCarte: 

  def __init__(self): 
    self.Mazzo = Mazzo() 
    self.Mazzo.Mischia() 


class ManoOldMaid(Mano): 

  def RimuoviCoppie(self): 
    Conteggio = 0 
    CarteOriginali = self.Carte[:] 
    for CartaOrig in CarteOriginali: 
      CartaDaCercare = Carta(3-CartaOrig.Seme, CartaOrig.Rango) 
      if CartaDaCercare in self.Carte: 
        self.Carte.remove(CartaOrig) 
        self.Carte.remove(CartaDaCercare) 
        print "Mano di %s: %s elimina %s" % \ 
               (self.Nome,CartaOrig,CartaDaCercare) 
        Conteggio = Conteggio + 1 
    return Conteggio 

class GiocoOldMaid(GiocoCarte): 

  def Partita(self, Nomi): 

    # rimozione della regina di fiori 
    self.Mazzo.RimuoviCarta(Carta(0,12)) 

    # creazione di una mano per ogni giocatore 
    self.Mani = [] 
    for Nome in Nomi: 
      self.Mani.append(ManoOldMaid(Nome)) 

    # distribuzione delle carte 
    self.Mazzo.Distribuisci(self.Mani) 
    print "---------- Le carte sono state distribuite" 
    self.StampaMani() 

    # toglie le coppie iniziali 
    NumCoppie = self.RimuoveTutteLeCoppie() 
    print "---------- Coppie scartate, inizia la partita" 
    self.StampaMani() 

    # gioca finche' sono state fatte 50 coppie 
    Turno = 0 
    NumMani = len(self.Mani) 
    while NumCoppie < 25: 
      NumCoppie = NumCoppie + self.GiocaUnTurno(Turno) 
      Turno = (Turno + 1) % NumMani 

    print "---------- La partita e' finita" 
    self.StampaMani() 

  def RimuoveTutteLeCoppie(self): 
    Conteggio = 0 
    for Mano in self.Mani: 
      Conteggio = Conteggio + Mano.RimuoveCoppie() 
    return Conteggio 

  def GiocaUnTurno(self, Giocatore): 
    if self.Mani[Giocatore].EVuoto(): 
      return 0 
    Vicino = self.TrovaVicino(Giocatore) 
    CartaScelta = self.Mani[Vicino].SceltaCarta() 
    self.Mani[Giocatore].AggiungeCarta(CartaScelta) 
    print "Mano di", self.Mani[Giocatore].Nome, ": scelta", \ 
          CartaScelta 
    Conteggio = self.Mani[Giocatore].RimuoveCoppie() 
    self.Mani[Giocatore].Mischia() 
    return Conteggio 

  def TrovaVicino(self, Giocatore): 
    NumMani = len(self.Mani) 
    for Prossimo in range(1,NumMani): 
      Vicino = (Giocatore + Prossimo) % NumMani 
      if not self.Mani[Vicino].EVuoto(): 
        return Vicino

Liste linkate

modifica
def StampaLista(Nodo): 
    while Nodo: 
      print Nodo, 
      Nodo = Nodo.ProssimoNodo 
    print 

def StampaInversa(Lista): 
    if Lista == None: return 
    Testa = Lista 
    Coda = Lista.ProssimoNodo 
    StampaInversa(Coda) 
    print Testa, 

def StampaInversaFormato(Lista) : 
    print "[", 
    if Lista != None : 
      Testa = Lista 
      Coda = Lista.ProssimoNodo 
      StampaInversa(Coda) 
      print Testa, 
    print "]", 

def RimuoviSecondo(Lista): 
    if Lista == None: return 
    Primo = Lista 
    Secondo = Lista.ProssimoNodo 
    # il primo nodo deve riferirsi al terzo 
    Primo.ProssimoNodo = Secondo.ProssimoNodo 
    # separa il secondo nodo dal resto della lista 
    Secondo.ProssimoNodo = None 
    return Secondo 

class Nodo: 

  def __init__(self, Contenuto=None, ProssimoNodo=None): 
    self.Contenuto = Contenuto 
    self.ProssimoNodo  = ProssimoNodo 

  def __str__(self): 
    return str(self.Contenuto) 

  def StampaInversa(self): 
    if self.ProssimoNodo != None: 
      Coda = self.ProssimoNodo 
      Coda.StampaInversa() 
    print self.Contenuto, 

class ListaLinkata: 
  def __init__(self) : 
    self.Lunghezza = 0 
    self.Testa = None 

  def StampaInversa(self): 
    print "[", 
    if self.Testa != None: 
      self.Testa.StampaInversa() 
    print "]", 

  def AggiuntaPrimo(self, Contenuto): 
    NodoAggiunto = Nodo(Contenuto) 
    NodoAggiunto.ProssimoNodo = self.Testa 
    self.Testa = NodoAggiunto 
    self.Lunghezza = self.Lunghezza + 1

class Pila

modifica
class Pila: 
  def __init__(self): 
    self.Elementi = [] 

  def Push(self, Elemento) : 
    self.Elementi.append(Elemento) 

  def Pop(self): 
    return self.Elementi.pop() 

  def EVuota(self): 
    return (self.Elementi == []) 

def ValutaPostfissa(Espressione): 
  import re 
  ListaToken = re.split("([^0-9])", Espressione) 
  Pila1 = Pila() 
  for Token in ListaToken: 
    if  Token == '' or Token == ' ': 
      continue 
    if  Token == '+': 
      Somma = Pila1.Pop() + Pila1.Pop() 
      Pila1.Push(Somma) 
    elif Token == '*': 
      Prodotto = Pila1.Pop() * Pila1.Pop() 
      Pila1.Push(Prodotto) 
    else: 
      Pila1.Push(int(Token)) 
  return Pila1.Pop()
class Albero: 
  def __init__(self, Contenuto, Sinistra=None, Destra=None): 
    self.Contenuto = Contenuto 
    self.Sinistra  = Sinistra 
    self.Destra = Destra 

  def __str__(self): 
    return str(self.Contenuto) 

  def OttieniContenuto(self): return self.Contenuto 
  def RamoDestro(self):       return self.Destra 
  def RamoSinistro(self):     return self.Sinistra 

  def SettaContenuto(self, Contenuto): self.Contenuto = Contenuto 
  def SettaRamoDestro(self, Nodo):     self.Destra = Nodo 
  def SettaRamoSinistro(self, Nodo):   self.Sinistra = Nodo 

def Totale(Albero): 
  if Albero == None: return 0 
  return Albero.Contenuto + Totale(Albero.Sinistra) + \ 
                            Totale(Albero.Destra) 

def StampaAlberoPre(Albero): 
  if Albero == None: return 
  print Albero.Contenuto, 
  StampaAlberoPre(Albero.Sinistra) 
  StampaAlberoPre(Albero.Destra) 

def StampaAlberoPost(Albero): 
  if Albero == None: return 
  StampaAlberoPost(Albero.Sinistra) 
  StampaAlberoPost(Albero.Destra) 
  print Albero.Contenuto, 

def StampaAlberoIn(Albero): 
  if Albero == None: return 
  StampaAlberoIn(Albero.Sinistra) 
  print Albero.Contenuto, 
  StampaAlberoIn(Albero.Destra) 

def StampaAlberoIndentato(Albero, Livello=0): 
  if Albero == None: return 
  StampaAlberoIndentato(Albero.Destra, Livello+1) 
  print '  '*Livello + str(Albero.Contenuto) 
  StampaAlberoIndentato(Albero.Sinistra, Livello+1) 

def ControllaToken(ListaToken, TokenAtteso): 
  if ListaToken[0] == TokenAtteso: 
    del ListaToken[0] 
    return 1 
  else: 
    return 0 

def ControllaNumero(ListaToken): 
  if ControllaToken(ListaToken, '('): 
    x = EsprSomma(ListaToken)               # ricava la  
                                            # sub-espressione 
    if not ControllaToken(ListaToken, ')'): # rimuove la  
                                            # parentesi chiusa 
      raise 'BadExpressionError', 'manca la parentesi' 
    return x 
  else: 
    x = ListaToken[0] 
    if type(x) != type(0): return None 
    ListaToken[0:1] = [] 
    return Albero(x, None, None) 

def EsprProdotto(ListaToken): 
  a = ControllaNumero(ListaToken) 
  if ControllaToken(ListaToken, '*'): 
    b = EsprProdotto(ListaToken) 
    return Albero('*', a, b) 
  else: 
    return a 

def EsprSomma(ListaToken): 
  a = EsprProdotto(ListaToken) 
  if ControllaToken(ListaToken, '+'): 
    b = EsprSomma(ListaToken) 
    return Albero('+', a, b) 
  else: 
    return a

Indovina l'animale

modifica
def RispostaAffermativa(Domanda): 
  from string import lower 
  Risposta = lower(raw_input(Domanda)) 
  return (Risposta[0] == 's') 


def Animale(): 
  # parte con una lista composta di un solo elemento 
  Radice = Albero("uccello") 

  # continua finche' l'operatore non abbandona 
  while 1: 
    print 
    if not RispostaAffermativa("Stai pensando ad un \ 
           animale? "): break 

    # percorre l'albero 
    SottoAlbero = Radice 
    while SottoAlbero.RamoSinistro() != None: 
      Messaggio = SottoAlbero.OttieniContenuto() + "? " 
      if RispostaAffermativa(Messaggio): 
        SottoAlbero = SottoAlbero.RamoDestro() 
      else: 
        SottoAlbero = SottoAlbero.RamoSinistro() 

    # prova a indovinare 
    Ipotesi = SottoAlbero.OttieniContenuto() 
    Messaggio = "E' una " + Ipotesi + "? " 
    if RispostaAffermativa(Messaggio): 
      print "Ho indovinato!" 
      continue 

    # ottiene nuove informazioni 
    Messaggio = "Qual è il nome dell'animale? " 
    Animale  = raw_input(Messaggio) 
    Messaggio  = "Che domanda permette di distinguere tra un %s \ 
                  e un %s? " 
    Domanda = raw_input(Messaggio % (Animale, Ipotesi)) 

    # aggiunge le nuove informazioni all'albero 
    SottoAlbero.SettaContenuto(Domanda) 
    Messaggio = "Se l'animale fosse un %s quale sarebbe la \ 
                                          risposta? " 
    if RispostaAffermativa(Messaggio % Animale): 
      SottoAlbero.SettaRamoSinistro(Albero(Ipotesi)) 
      SottoAlbero.SettaRamoDestro(Albero(Animale)) 
    else: 
      SottoAlbero.SettaRamoSinistro(Albero(Animale)) 
      SottoAlbero.SettaRamoDestro(Albero(Ipotesi))

class Frazione

modifica
def MCD(m, n): 
  if m % n == 0: 
    return n 
  else: 
    return MCD(n, m%n) 

class Frazione: 

  def __init__(self, Numeratore, Denominatore=1): 
    mcd = MCD(Numeratore, Denominatore) 
    self.Numeratore   = Numeratore / mcd 
    self.Denominatore = Denominatore / mcd 

  def __str__(self): 
    return "%d/%d" % (self.Numeratore, self.Denominatore) 

  def __mul__(self, Altro): 
    if type(Altro) == type(1): 
      Altro = Frazione(Altro) 
    return Frazione(self.Numeratore * Altro.Numeratore, \ 
                    self.Denominatore * Altro.Denominatore) 
  __rmul__ = __mul__ 

  def __add__(self, Altro): 
    if type(Altro) == type(5): 
      Altro = Frazione(Altro) 
    return Frazione(self.Numeratore   * Altro.Denominatore +  
                    self.Denominatore * Altro.Numeratore,  
                    self.Denominatore * Altro.Denominatore) 

  __radd__ = __add__ 

  def __cmp__(self, Altro): 
    Differenza = (self.Numeratore  * Altro.Denominatore - \ 
            Altro.Numeratore * self.Denominatore) 
    return Differenza 

  def __repr__(self): 
    return self.__str__()