Next Up Previous Hi Index

Appendix C

Listados Completos de Python

Clase 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, otro):
    return Punto(self.x + otro.x, self.y + otro.y)

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

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

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

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

  def delDerechoYDelReves(derecho):
    from copy import copy
    reves = copy(derecho)
    reves.reverse()
    print str(derecho) + str(reves)

Clase Hora

class Hora:
  def __init__(self, horas=0, minutos=0, segundos=0):
    self.horas = horas
    self.minutos = minutos
    self.segundos = segundos

  def __str__(self):
    return str(self.horas) + ":" + str(self.minutos) \
           + ":" + str(self.segundos)

  def convierteASegundos(self):
    minutos = self.horas * 60 + self.minutos
    segundos = self.minutos * 60 + self.segundos
    return segundos

  def incrementa(self, segs):
    segs = segs + self.segundos

    self.horas = self.horas + segs/3600
    segs = segs % 3600
    self.minutos = self.minutos + segs/60
    segs = segs % 60
    self.segundos = segs

  def haceHora(segs):
    hora = Hora()
    hora.horas = segs/3600
    segs = segs - hora.horas * 3600
    hora.minutos = segs/60
    segs = segs - hora.minutos * 60
    hora.segundos = segs
    return hora

Cartas, mazos y juegos

import random

class Carta:
  listaDePalos   = ["Tréboles", "Diamantes", "Corazones",
              "Picas"]
  listaDeValores = ["nada", "As", "2", "3", "4", "5", "6", "7",
              "8", "9", "10", "Sota", "Reina", "Rey"]

  def __init__(self, palo=0, valor=0):
    self.palo = palo
    self.valor = valor

  def __str__(self):
    return (self.listaDeValores[self.valor] + " de " +\
            self.listaDePalos[self.palo])

  def __cmp__(self, otro):
    # controlar el palo
    if self.palo > otro.palo: return 1
    if self.palo < otro.palo: return -1
    # si son del mismo palo, controlar el valor
    if self.valor > otro.valor: return 1
    if self.valor < otro.valor: return -1
    # los valores son iguales, es un empate
    return 0

class Mazo:
  def __init__(self):
    self.cartas = []
    for palo in range(4):
      for valor in range(1, 14):
        self.cartas.append(Carta(palo, valor))

  def muestraMazo(self):
    for carta in self.cartas:
      print carta

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

  def mezclar(self):
    import random
    nCartas = len(self.cartas)
    for i in range(nCartas):
      j = random.randrange(i, nCartas)
      self.cartas[i], self.cartas[j] =\
        self.cartas[j], self.cartas[i]

  def eliminaCarta(self, carta):
    if carta in self.cartas:
      self.cartas.remove(carta)
      return 1
    else: return 0

  def darCarta(self):
    return self.cartas.pop()

  def estaVacio(self):
    return (len(self.cartas) == 0)

  def repartir(self, manos, nCartas=999):
    nManos = len(manos)
    for i in range(nCartas):
      if self.estaVacio(): break   # fin si se acaban las cartas
      carta = self.darCarta()      # da la carta superior
      mano  = manos[i % nManos]    # a quién le toca?
      mano.agregaCarta(carta)      # agrega la carta a la mano

class Mano(Mazo):
  def __init__(self, nombre=""):
    self.cartas = []
    self.nombre = nombre

  def agregaCarta(self,carta) :
    self.cartas.append(carta)

  def __str__(self):
    s = "La mano de " + self.nombre
    if self.estaVacio():
      s = s + " está vacía\n"
    else:
      s = s + " contiene\n"
    return s + Mazo.__str__(self)

class JuegoDeCartas:
  def __init__(self):
    self.mazo = Mazo()
    self.mazo.mezclar()

class ManoDeLaMona(Mano):
  def eliminaCoincidencias(self):
    cant = 0
    cartasOriginales = self.cartas[:]
    for carta in cartasOriginales:
      empareja = Carta(3 - carta.palo, carta.valor)
      if empareja in self.cartas:
        self.cartas.remove(carta)
        self.cartas.remove(empareja)
        print "Mano %s: %s con %s" % (self.nombre,carta,empareja)
        cant = cant + 1
    return cant

class JuegoDeLaMona(JuegoDeCartas):
  def jugar(self, nombres):
    # quitamos la Reina de Tréboles
    self.mazo.eliminaCarta(Carta(0,12))

    # construimos una mano para cada jugador
    self.manos = []
    for nombre in nombres :
      self.manos.append(ManoDeLaMona(nombre))

    # repartimos los naipes
    self.mazo.repartir(self.manos)
    print "----- Se han repartido las cartas."
    self.muestraManos()

    # eliminamos las coincidencias iniciales
    emparejadas = self.eliminaTodasLasCoincidencias()
    print "----- Coincidencias eliminadas, el juego comienza."
    self.muestraManos()

    # se juega hasta que se han descartado las 50 cartas
    turno = 0
    cantManos = len(self.manos)
    while emparejadas < 25:
      emparejadas = emparejadas + self.jugarUnTurno(turno)
      turno = (turno + 1) % cantManos

    print "----- El juego terminó."
    self.muestraManos()
 
  def eliminaTodasLasCoincidencias(self):
    cant = 0
    for mano in self.manos:
      cant = cant + mano.eliminaCoincidencias()
    return cant

  def jugarUnTurno(self, i):
    if self.manos[i].estaVacio():
      return 0
    vecino = self.encuentraVecino(i)
    cartaElegida = self.manos[vecino].darCarta()
    self.manos[i].agregaCarta(cartaElegida)
    print "Mano", self.manos[i].nombre, "eligió", cartaElegida
    cant = self.manos[i].eliminaCoincidencias()
    self.manos[i].mezclar()
    return cant

  def encuentraVecino(self, i):
    cantManos = len(self.manos)
    for proximo in range(1,cantManos):
      vecino = (i + proximo) % cantManos
      if not self.manos[vecino].estaVacio():
        return vecino

  def muestraManos(self) :
    for mano in self.manos :
        print mano

Lists Enlazadas

  def imprimeLista(nodo):
    while nodo:
      print nodo,
      nodo = nodo.siguiente
    print

  def
imprimeAlReves(lista):
    if lista == None: return
    cabeza = lista
    cola = lista.siguiente
    imprimeAlReves(cola)
    print cabeza,

  def imprimeAlRevesBonito(lista) :
    print "[",
    if lista != None :
      cabeza = lista
      cola = lista.siguiente
      imprimeAlReves(cola)
      print cabeza,
    print "]",

  def eliminaSegundo(lista):
    if lista == None: return
    primero = lista
    segundo = lista.siguiente
    primero.siguiente = segundo.siguiente
    segundo.siguiente = None
    return segundo

class Nodo:
  def __init__(self, carga=None, siguiente=None):
    self.carga = carga
    self.siguiente = siguiente

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

  def imprimeAlReves(self):
    if self.siguiente != None:
      cola = self.siguiente
      cola.imprimeAlReves()
    print self.carga,

class ListaEnlazada :
  def __init__(self) :
    self.longitud = 0
    self.cabeza   = None

  def imprimeAlReves(self):
    print "[",
    if self.cabeza != None:
      self.cabeza.imprimeAlReves()
    print "]",

  def agregaPrimero(self, carga):
    nodo = Nodo(carga)
    nodo.siguiente = self.cabeza
    self.cabeza = nodo
    self.longitud = self.longitud + 1

Clase Pila

class Pila :              # implem. con listas de Python
  def __init__(self) :
    self.elementos = []

  def push(self, elemento) :
    self.elementos.append(elemento)

  def pop(self) :
    return self.elementos.pop()

  def isEmpty(self) :
    return (self.elementos == [])

  def evalPostfijo(expr):
    import re
    listaTokens = re.split("([^0-9])", expr)
    pila = Pila()
    for token in listaTokens:
      if token == '' or token == ' ':
        continue
      if
token == '+':
        suma = pila.pop() + pila.pop()
        pila.push(suma)
      elif token == '*':
        producto = pila.pop() * pila.pop()
        pila.push(producto)
      else:
        pila.push(int(token))
    return pila.pop()

Colas y colas priorizadas

class Cola :
  def __init__(self) :
    self.longitud = 0
    self.cabeza   = None

  def vacia(self) :
    return (self.longitud == 0)

  def inserta(self, carga) :
    nodo = Nodo(carga)
    nodo.siguiente = None
    if self.cabeza == None :
        # Si la lista está vacía nuestro nuevo nodo es el primero
        self.cabeza = nodo
    else :
        # Encuentra el último nodo de la lista
        ultimo = self.cabeza
        while ultimo.siguiente : ultimo = ultimo.siguiente
        # Añada el nuevo nodo
        ultimo.siguiente = nodo
    self.longitud = self.longitud + 1

  def quita(self) :
    carga = self.cabeza.carga
    self.cabeza = self.cabeza.next
    self.longitud = self.longitud - 1
    return carga

class ColaMejorada :
  def __init__(self) :
    self.longitud = 0
    self.cabeza   = None
    self.ultimo   = None

  def vacia(self) :
    return (self.longitud == 0)

  def inserta(self, carga) :
    nodo = Nodo(carga)
    nodo.siguiente = None
    if self.longitud == 0 :
        # Si la lista está vacía nuestro nuevo nodo es el primero
        self.cabeza = self.ultimo = nodo
    else :
        # Encuentra el ultimo nodo de la lista
        ultimo = self.ultimo
        # Añade nuestro nodo nuevo
        ultimo.siguiente = nodo
        self.ultimo = nodo
    self.longitud = self.longitud + 1

  def quita(self) :
    carga    = self.cabeza.carga
    self.cabeza = self.cabeza.siguiente
    self.longitud = self.longitud - 1
    if self.longitud == 0 : self.ultimo = None
    return carga

class ColaPriorizada :
  def __init__(self) :
    self.elementos = []

  def vacia(self) :
    return self.elementos == []

  def inserta(self, elemento) :
    self.elementos.append(elemento)

  def quita(self) :
    maxi = 0
    for i in range(1,len(self.elementos)) :
       if self.elementos[i] > self.elementos[maxi] :
         maxi = i
    elemento = self.elementos[maxi]
    self.elementos[maxi:maxi+1] = []
    return elemento

class Golfista :
  def __init__(self, nombre, puntos) :
    self.nombre = nombre
    self.puntos = puntos

  def __str__(self) :
    return "%-15s: %d" % (self.nombre, self.puntos)

  def __cmp__(self, otro) :
    if self.puntos < otro.puntos : return  1   # menos es más
    if self.puntos > otro.puntos : return -1
    return 0

Árboles

class Arbol :
  def __init__(self, carga, izquierda=None, derecha=None) :
    self.carga = carga
    self.izquierda  = izquierda
    self.derecha = derecha

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

  def tomaCarga(self): return self.carga
  def tomaIzquierda(self): return self.izquierda
  def tomaDerecha(self): return self.derecha

  def ajustaCarga(self, carga):  self.carga = carga
  def ajustaIzquierda (self, izquierda):  self.left = izquierda
  def ajustaDerecha(self, derecha):  self.derecha = derecha

def total(arbol) :
  if arbol == None : return 0
  return total(arbol.izquierda) + total(arbol.derecha) + arbol.carga

def imprimeArbol(arbol):
  if arbol == None: return
  print
arbol.carga,
  imprimeArbol(arbol.izquierda)
  imprimeArbol(arbol.derecha)

def imprimeArbolPosfijo(arbol):
  if arbol == None: return
  imprimeArbolPosfijo(arbol.izquierda)
  imprimeArbolPosfijo(arbol.derecha)
  print arbol.carga,

def imprimeArbolInfijo(arbol):
  if arbol == None: return
  imprimeArbolInfijo(arbol.izquierda)
  print arbol.carga,
  imprimeArbolInfijo(arbol.derecha)

def imprimeArbolSangrado(arbol, nivel=0):
  if arbol == None: return
  imprimeArbolSangrado(arbol.derecha, nivel+1)
  print '  '*nivel + str(arbol.carga)
  imprimeArbolSangrado(arbol.izquierda, nivel+1)

Árboles de expresión

def tomaToken(listaToken, esperado):
  if listaToken[0] == esperado:
    listaToken[0:1] = []   # quita el token
    return 1
  else:
    return 0

def obtieneProducto(listaToken) :
  a = obtieneNumero(listaToken)
  if tomaToken(listaToken, '*') :
    b = obtieneProducto(listaToken)
    return Arbol('*', a, b)
  else :
    return a

def obtieneSuma(listaToken) :
  a = obtieneProducto(listaToken)
  if tomaToken(listaToken, '+') :
    b = obtieneSuma(listaToken)
    return Arbol('+', a, b)
  else :
    return a

def obtieneNumero(listaToken):
  if tomaToken(listaToken, '(') :
    x = obtieneSuma(listaToken)      # obtiene subexpresión
    tomaToken(listaToken, ')')    # se come el cierre de paréntesis
    return x
  else :
    x = listaToken[0]
    if type(x) != type(0) : return None
    listaToken[0:1] = []   # quita el token
    return Arbol(x, None, None)    # devuelve una hoja sin el número

Adivina el animal

def animal():
  # empezar con un nodo suelto
  raiz = Arbol("pájaro")

  # bucle hasta que el usuario salga
  while 1:
    print
    if not
si("Estás pensando en un animal? "): break

    # recorrer el árbol
    arbol = raiz
    while arbol.tomaIzquierda() != None:
      indicador = arbol.tomaCarga() + "? "
      if si(indicador):
        arbol = arbol.tomaDerecha()
      else:
        arbol = arbol.tomaIzquierda()

    # intentar adivinar
    adivina = arbol.tomaCarga()
    indicador = "Es un " + adivina + "? "
    if si(indicador):
      print "¡Soy el más grande!"
      continue

    # obtener información nueva
    indicador  = "Cómo se llama el animal? "
    animal  = raw_input(indicador)
    indicador  = "Qué pregunta distinguiría a un %s de un %s? "
    pregunta = raw_input(indicador % (animal,adivina))

    # añadir información nueva al árbol
    arbol.ponCarga(pregunta)
    indicador = "Si el animal fuera un %s, cuál sería la respuesta? "
    if si(indicador % animal):
      arbol.ponIzquierda(Arbol(adivina))
      arbol.ponDerecha(Arbol(animal))
    else:
      arbol.ponIzquierda(Arbol(animal))
      arbol.ponDerecha(Arbol(adivina))

def si(preg):
  from string import lower
  resp = lower(raw_input(preg))
  return (resp[0:1] == 's')

Fraction class

class Fraccion:
  def __init__(self, numerador, denominador=1):
    m = mcd (numerador, denominador)
    self.numerador   =   numerador / m
    self.denominador = denominador / m

  def __mul__(self, otro):
    if type(otro) == type(5):
      otro = Fraccion(otro)
    return Fraccion(self.numerador   * otro.numerador,
                    self.denominador * otro.denominador)

  __rmul__ = __mul__

  def __add__(self, otro):
    if type(otro) == type(5):
      otro = Fraccion(otro)
    return Fraccion(self.numerador   * otro.denominador +
                    self.denominador * otro.numerador,
                    self.denominador * otro.denominador)

  __radd__ = __add__

  def __cmp__(self, otro):
    if type(otro) == type(5):
      otro = Fraccion(otro)

    dif = (self.numerador * otro.denominador -
           otro.numerador * self.denominador)
    return dif

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

  def __str__(self):
    return "%d/%d" % (self.numerador, self.denominador)

def mcd(m,n):
  "devuelve el máximo común denominador de dos enteros"
  if m % n == 0:
    return n
  else:
    return mcd(n,m%n)


Next Up Previous Hi Index