Next Up Previous Hi Index

Appendix C

Listati dei programmi

class Punto

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

# -------------------
# 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

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

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

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()

Alberi

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

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' un " + Ipotesi + "? "
    if RispostaAffermativa(Messaggio):
      print "Ho indovinato!"
      continue

    # ottiene nuove informazioni
    Messaggio = "Qual e' 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

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__()


Next Up Previous Hi Index