programa para quinielas con python

Ideas sobre nuevas secciones, contenidos o actividades.

programa para quinielas con python

Notapor Dokan » Sab Dic 29, 2007 8:21 pm

Hace tres semanas me di cuenta que hacer un juego es más complicado de lo que parece, y más aún cuando no sabes programar, así que se me planteó la necesidad de empezar a hacer algo más simple con la intención de practicar. La mejor idea que tuve fue un programa para hacer quinielas reducidas (la quiniela es un juego de azar, o lotería, muy popular en España) puesto que hasta ahora no he encontrado ninguno que funcione en Ubuntu (ni siquiera con wine).
Por ahora va viento en popa y a toda vela, aunque por problemas familiares no tengo mucho tiempo (también he dejado de traducir pygame, de momento), pero siguiendo el consejo de Hugo en un post de hoy mismo a un compañero del foro voy a plantear aquí lo que estoy haciendo para que entre todos los que quieran colaborar el proyecto crezca, quien sabe si conseguiremos una versión decente que le pueda interesar a la gente.
En principio parece algo bastante sencillo. Opino que sólo hay que plantearlo bien, por eso he intentado concretar al máximo para tener las ideas bien claras. Lo que sigue es lo que he hecho hasta ahora, aunque algunas partes me dan errores, podeis probarlas y comentar lo que os parezca. Las reglas para hacer las reducciones las he extraído de la web de jagar donde explica un poco la teoría de las reducciones en la quiniela.
Código: Seleccionar todo
#! usr/bin/env python
# -*- coding: utf-8 -*-
"""
Programa para crear las reducciones con cualquier cantidad de multiples (dobles y triples).
Por ejemplo; reducciones de 4 dobles y 4 triples a 100 apuestas asegurando el premio de 2ª categoría.
Puede recibir;
- numero de dobles y/o triples a reducir,
- apuesta sencilla,
- ruta y nombre de archivo.

Deberia hacer;
- una lista con tuplas del tipo [(1,1),(1,x),(x,1),(x,x)] con todas las apuestas metodo directo - agrupar las apuestas del metodo directo segun las reglas de reducción,
- guardar las apuestas y los grupos en un archivo (txt, html, pdf, etc) que sera formateado segun la lista mostrada en ej anterior, para posterior lectura y ahorro de memoria,
- leer las apuestas y los grupos desde archivos,
- extraer el grupo de reduccion en la que esta incluida una apuesta sencilla e imprimirlo por pantalla o en un archivo.

Debe funcionar con cualquier cantidad de apuestas, una apuesta es una lista del tipo [1,1,1], segun dobles y triples hayan esta tendrá más elementos, sabiendo el numero total de apuestas que recibimos en la lista (len(columnas) podemos hacer unos calculos para saber;
- la cantidad de dobles y de triples,
- el numero de grupos,
- la cantidad de apuestas que habra en cada grupo, etc.(http://club.telepolis.com/jagar1/Reducciones3.htm)

Devuelve el grupo de reduccion que incluye la apuesta sencilla por pantalla o en un archivo (html, txt, pdf, etc).
"""
__author__ = "Dokan"
__version__ = "$Revision: 0.0.2 $"
__date__ = "$Date: 2007/12/06 13:39:19 $"
__copyright__ = "Copyright (c) 2007 Dokan"
__license__ = "GPLv2"

import sys, os


def compara( x, y ): # x e y son listas que se han de comparar 1ro con 1ro, 2do con 2do, etc...
    """Compara dos listas, 1º elemento con 1º elemento, 2º con 2º, etc.
Devuelve el numero de diferencias encontradas entre ambas, 0 si no las hay."""
    diferencias=0
    for i in range(len(x)):
        if x[i] != y[i]:
            diferencias += 1
    return diferencias

def formatea(ruta): #ruta incluye nombre de archivo: "/home/kike/python/quiniela/4d.txt"
    """Recibe una ruta con el nombre del archivo a tratar incluido(ej. "/home/kike/python/quiniela/4d.txt"), en principio solo txt, más adelante tal vez también otros formatos. El archivo debe incluir las apuestas del método directo, que son devueltas como una lista de tuplas (de momento solo lo he probado con el formato que copio&pego desde un html a un txt para luego procesarlo con esta funcion).
"""
    columnas=file(txt).read() #asigna el contenido del archivo a una variable.
    columnas = [tuple(elem.split()) for elem in columnas.split("\n")] #le damos el formato necesario
    if columnas[-1]==(): columnas.pop() #elimina la ultima lista de columnas si es una lista vacia, esto ocurre cuando el txt termina con salto de linea.
    return columnas

def multiples(apuestas): #recibe entero de len(apuestasMetDirecto())
        """Recibe un entero, el numero total de apuestas por el metodo directo (columnas de la lista).
Calcula el numero de multiples, separando dobles y triples, que se han combinado para obtener el numero de apuestas.
Devuelve dos enteros, el primero son los dobles y el segundo los triples.
apuestas = (2**dobles) * (3**triples)
"""
def multiples(apuestas):
    dobles, triples = 0,0
    while apuestas!=1:
        while apuestas%2!=0:
            apuestas/=2
            dobles +=1
        apuestas/=3
        triples+=1
    return dobles, triples

def apuestasMetDirecto(dobles, triples): #recibe dos enteros devueltos por multiples()
        """Recibe dos enteros, cantidad de dobles y triples en apuestas multiples.
Combina todas las apuestas del metodo directo.
Devuelve una lista de tuplas con todas las combinaciones del metodo directo.
Ap. Método Directo = (2**Dobles) * (3**Triples)
"""
    apDobles = 2**dobles
    apTriples = 3**triples
   

def premios(dobles, triples): #recibe dos enteros devueltos por multiples()
        """Recibe dos enteros, cantidad de dobles y triples en apuestas multiples.
Devuelve un entero, que es el numero de columnas con premios de 1ª y 2ª categoria que se obtendrian por el metodo directo y que determina el numero de grupos de reduccion.
premios = 1+dobles +(2*triples)
"""
    premios = 1 + dobles + (2 * triples)
    return premios

def limite(total, premios): #recibe dos enteros, len(apuestasMetDirecto()) y premios()
    """Recibe dos enteros, numero total de apuestas del metodo directo y numero de columnas con premios de 1ª y 2ª.
Es el numero de columnas minimo que garantizan un premio de 2ª categoria, por tanto es el numero de columnas que tendra cada grupo de reduccion. Si el resultado es entero (sin decimales) la reduccion se denomina perfecta, pero si no lo es (reduccion imperfecta) la reduccion tendra que tener mas columnas, para lo que se redondea el limite hacia arriba.
Devuelve un entero.
limite = Ap. Método Directo / Nº Premios
"""
    if total%premios > 0: limite = total/premios + 1
    else: limite = total/premios
    return limite

def gruposReduccion(premios, limite, columnas):# premios(), limite(), apMetDirecto()
    """Recibe dos enteros y una lista de tuplas, premios será el num. de grupos de reduccion y limite será el num. de columnas de cada grupo de reduccion, columnas será el total de apuestas del metodo directo.
Distribuye cada apuesta del metodo directo en grupos de reduccion segun un criterio dado.
Grupo de reduccion es el grupo de columnas minimo para garantizar el premio de 2ª categoria, de la union de todos los grupos de reduccion resulta el total de apuestas del metodo directo.
Las condiciones que ha de cumplir son:
- Todas las columnas de un grupo se diferencian entre si en al menos 3 signos.
- Todas las columnas que no pertenecen a un grupo coinciden en 2 signos con al menos una de las columnas de ese grupo.
- Todos los grupos de reduccion forman el total de las apuestas por el metodo directo.
No Devuelve nada, los grupos se guardan en globals().
"""

def agrupa(premios): #premios()
    """Recibe numero de grupos de reduccion y los agrupa en una unica tupla. Estos grupos estan en globals().
Devuelve todos los grupos de reducción en una unica tupla (((1,1),(x,x)),((1,x),(x,1))).
"""


if __name__ == '__main__':
    # Import Psyco if available
    try:
        import psyco
        psyco.full()
    except ImportError:
        pass
    __main__    # ...your code here...


Ya sabeis que espero vuestras críticas, constructivas a ser posible :)
Felices fiestas.
Última edición por Dokan el Lun Ago 16, 2010 2:03 pm, editado 1 vez en total
Avatar de Usuario
Dokan
 
Mensajes: 143
Registrado: Lun Dic 03, 2007 10:40 pm

Notapor Dokan » Dom Dic 30, 2007 4:08 pm

He modificado la funcion 'multiples()', ahora creo que es definitiva:
Código: Seleccionar todo
def multiples(apuestas): #recibe entero, de len(apuestasMetDirecto()) o introducido por user
    """Recibe un entero, el numero total de apuestas por el metodo directo (columnas de la lista).
Calcula el numero de multiples, separando dobles y triples, que se han combinado para obtener el numero de apuestas.
Devuelve dos enteros, el primero son los dobles y el segundo los triples.
apuestas = (2**dobles) * (3**triples)
"""
    dobles, triples = 0,0
    print "dobles = %d triples = %d" % (dobles, triples)
    while apuestas > 1:
        try:
            if apuestas%2 != 0 and apuestas%3 != 0: raise ValueError("El numero no es un multiple valido de la quiniela.")
        except ValueError: raise
        while apuestas%2 == 0:
            apuestas /= 2
            dobles += 1
            print "dobles = %d" % (dobles, )
        if apuestas%3 == 0:
            apuestas /= 3
            triples += 1
            print "triples = %d" % (triples, )
    try:
        if dobles + triples > 14: raise ValueError("El numero tiene mas de 14 multiples, no es una apuesta valida de la quiniela.")
    except ValueError: raise
    return dobles, triples


A ver si me podeis echar una mano con la funcion 'apMetDirecto()', es la que desarrolla las combinaciones de apuestas, por ejemplo, si tenemos 2 dobles y 0 triples esta funcion deberia devolver una lista de tuplas tal como esta; [('1','1'),('1','x'),('x','1'),('x','x')], resultado de la combinacion de dos dobles:
11xx
1x1x
para 2 dobles y 1 triple la lista es;
[('1','1','1'),('1','x','1'),('x','1','1'),('x','x','1'),
('1','1','x'),('1','x','x'),('x','1','x'),('x','x','x'),
('1','1','2'),('1','x','2'),('x','1','2'),('x','x','2')]
y la combinacion:
11xx 11xx 11xx
1x1x 1x1x 1x1x
1111 xxxx 2222
y así hasta 14 múltiples (suma de dobles y triples) que pueden hacerse (uno por partido de la quiniela, actualmente 14).
le he dado bastantes vueltas pero no se me ocurre la manera de hacer algo así, por eso hasta ahora las hacía a mano y las guardaba en txt para importarlas desde el programa y poder probarlo, pero para muchos múltiples es una locura.
¿Algún consejo?
Avatar de Usuario
Dokan
 
Mensajes: 143
Registrado: Lun Dic 03, 2007 10:40 pm

Probá con listas por comprensión

Notapor hugoruscitti » Dom Dic 30, 2007 9:36 pm

Saludos Dokan, lamentablemente no se nada de quinielas, sino intentaría
ayudar.

Igualmente veo que la función que quieres desarrollar se parece mucho
a una combinación, o producto cartesiano. Si es así, tal vez te sirva
utilizar listas por compresión: Hay mucha información en internet al
respecto, dado que esta es una característica de la programación
funcional muy interesante. Por ese motivo solo te dejo un ejemplo
medio-simple al respecto.

Mediante listas por comprensión puedes pedirle a python que construya listas
siguiendo algún criterio lógico, no tienes que preocuparte por algoritmos o
detalles de implementación, solo escribes una expresión lógica y listo.

Por ejemplo, imagina que tienes un grupo de letras como '1' y 'x', y te
interesa obtener todas las combinaciones entre sí. Lo único que quieres
es una lista de elementos de la forma (a, b) donde 'a' y 'b' son elementos
de este grupo... puedes abrir un terminal en tu sistema, escribir "python"
y en modo interactivo puedes probar lo siguiente:

Código: Seleccionar todo
>>> elementos = ['1', 'x']
>>> combinaciones = [(a, b) for a in elementos for b in elementos]
>>> print combinaciones
[('1', '1'), ('1', 'x'), ('x', '1'), ('x', 'x')]


Ten en cuenta que los ">>>" son parte del cursor que imprime python para
mostrar que el cursor se encuentra ahí, no es necesario escribirlos claro.

Intenta asignar mas elementos a la lista y verás como python hace todas
las combinaciones. Estas construcciones de listas por comprensión se suelen
mostrar con cosas mas sencillas, incluso en las universidades, así que
mejor veamos un ejemplo mas simple:

Imagina que quieres una lista de números y quieres otra lista con todas
las potencias de esos números. Podrías hacerlo así:

Código: Seleccionar todo
>>> numeros = [1, 2, 3, 4, 5]
>>> potencias = [x*x for x in numeros]
>>> print potencias
[1, 4, 9, 16, 25]
>>>


o bien, imagina que quieres tener una lista reducida incluyendo solo
los números pares:

Código: Seleccionar todo
>>> def es_par(x):
...     return x % 2 == 0
...
>>> es_par(1)
False
>>> es_par(4)
True
>>> numeros = [1, 2, 3, 4, 5, 6, 7, 8]
>>> solo_pares = [n for n in numeros if es_par(n)]
>>> print solo_pares
[2, 4, 6, 8]


Bueno, posiblemente viendo los ejemplos notarás si esto es lo que
necesitas para hacer esa función que estás haciendo, o si puedes usarlo
en otra oportunidad. De todas formas creo que está interesante
conocerlo, al menos para evitar muchos ciclos 'for' difíciles de seguir.

Mucha suerte, y veré si aprendo algo de quinielas con tu juego eh?...

Éxitos.
Avatar de Usuario
hugoruscitti
Site Admin
 
Mensajes: 1242
Registrado: Dom Jul 30, 2006 3:57 am
Ubicación: Buenos Aires, Argentina

Notapor Dokan » Vie Ene 04, 2008 3:12 am

Igualmente veo que la función que quieres desarrollar se parece mucho
a una combinación, o producto cartesiano. Si es así, tal vez te sirva
utilizar listas por compresión


¡¡Diste en el clavo!!
Llevo un par de días haciendo pruebas y aunque hasta ahora no había logrado sacar nada en claro (no tengo mucho tiempo y tampoco entiendo muy bien como funcionan susodichas listas), parece que empiezo a encontrarle el sentido. El primer ejemplo que muestras es justo lo que andaba buscando, aunque necesito que haga más combinaciones, pero de eso ya me encargo yo.
Próximamente publicaré el código de dicha función.
Muchas gracias por tu ayuda.

EDITO 08/01/2008 19:11h
Ya he conseguido resolver completamente el problema de las listas por comprensión y he avanzado mucho en la función, pero por su complejidad tengo varios errores que quiero resolver antes de postearla, posiblemente para el fin de semana la termine y podreis ver aquí el resultado.
Saludos!
Avatar de Usuario
Dokan
 
Mensajes: 143
Registrado: Lun Dic 03, 2007 10:40 pm

función apMetDirecto (apuestas metodo directo)

Notapor Dokan » Jue Ene 10, 2008 8:20 pm

Esta función se encarga de hacer el desarrollo de las apuestas múltiples por el método directo, es decir, todas las columnas apostadas al jugar dobles y/o triples. Es necesario para posteriormente hacer grupos de reducción o apuestas condicionadas. No me ha dado errores, sin embargo seguro que algo se me ha escapado. ¡Espero comentarios!

Código: Seleccionar todo
def apMetDirecto(dobles, triples): #recibe dos enteros, devueltos por multiples()
    """Recibe dos enteros, cantidad de dobles y triples en apuestas multiples, deben tener un valor entre 0 y 14, mínimo un múltiple (doble o triple).
Combina todas las apuestas del metodo directo.
Devuelve una lista de tuplas con todas las combinaciones del metodo directo.
Ap. Método Directo = (2**Dobles) * (3**Triples)
"""
    """ si uno o ambos solo tienen un multiple para no obtener errores hay que pasar la lista asi:
>>> l1d = [['1'],['x']]
>>> l1t = [['1'],['x'],['2']]
solo de este modo el resultado es correcto, si se pasa asi:
>>> l1d = [['1', 'x']]
>>> l1t = [['1', 'x', '2']]
el resultado incorrecto es el siguiente:
>>> l1dx1t
[['1', 'x', '1', 'x', '2']]
"""
    if dobles == 1: D = [['1'],['x']]# metodo directo para un doble, cada elemento de la lista es una apuesta
    else: D = ['1','x'] #lista para combinar varios dobles
    if triples == 1: T = [['1'],['x'],['2']] # metodo directo para un triple, cada elemento de la lista es una apuesta
    else: T = ['1','x','2'] #lista para combinar varios triples
    listaFinal = [] # creamos por si acaso una variable tipo lista para trabajar con ella
    tuplaFinal = [] # creamos por si acaso una variable tipo lista de tuplas, sera devuelta por la funcion al finalizar.
    def eligeMult(num):
        """Recibe entero, cantidad de dobles/triples para combinar.
Elige la funcion apropiada segun numero de dobles o triples para hacer la combinacion.
Devuelve el nombre de la funcion apropiada."""
        dicc = {1:'un', 2:'dos', 3:'tres', 4:'cuatro', 5:'cinco', 6:'seis', 7:'siete', 8:'ocho', 9:'nueve', 10:'diez', 11:'once', 12:'doce', 13:'trece', 14:'catorce'}
        nombreFuncion = '%sMult' % dicc[num]
        return nombreFuncion
    def unMult(lista):
        """Recibe lista ['1','x'] o ['1','x','2'] segun se combine dobles o triples.
Combina mediante listas por comprension (mapping list).
Devuelve lista con la combinacion de los elementos de la lista dada."""
        return lista
    def dosMult(lista):
        """Recibe lista ['1','x'] o ['1','x','2'] segun se combine dobles o triples.
Combina mediante listas por comprension (mapping list).
Devuelve lista con la combinacion de los elementos de la lista dada."""
        return [[a,b] for a in lista for b in lista] #lista 2 multiples
    def tresMult(lista):
        """Recibe lista ['1','x'] o ['1','x','2'] segun se combine dobles o triples.
Combina mediante listas por comprension (mapping list).
Devuelve lista con la combinacion de los elementos de la lista dada."""
        return [[a,b,c] for a in lista for b in lista for c in lista] #lista 3 multiples
    def cuatroMult(lista):
        """Recibe lista ['1','x'] o ['1','x','2'] segun se combine dobles o triples.
Combina mediante listas por comprension (mapping list).
Devuelve lista con la combinacion de los elementos de la lista dada."""
        return [[a,b,c,d] for a in lista for b in lista for c in lista for d in lista] #lista 4 multiples
    def cincoMult(lista):
        """Recibe lista ['1','x'] o ['1','x','2'] segun se combine dobles o triples.
Combina mediante listas por comprension (mapping list).
Devuelve lista con la combinacion de los elementos de la lista dada."""
        return [[a,b,c,d,e] for a in lista for b in lista for c in lista for d in lista for e in lista] #lista 5 multiples
    def seisMult(lista):
        """Recibe lista ['1','x'] o ['1','x','2'] segun se combine dobles o triples.
Combina mediante listas por comprension (mapping list).
Devuelve lista con la combinacion de los elementos de la lista dada."""
        return [[a,b,c,d,e,f] for a in lista for b in lista for c in lista for d in lista for e in lista for f in lista] #lista 6 multiples
    def sieteMult(lista):
        """Recibe lista ['1','x'] o ['1','x','2'] segun se combine dobles o triples.
Combina mediante listas por comprension (mapping list).
Devuelve lista con la combinacion de los elementos de la lista dada."""
        return [[a,b,c,d,e,f,g] for a in lista for b in lista for c in lista for d in lista for e in lista for f in lista for g in lista] #lista 7 multiples
    def ochoMult(lista):
        """Recibe lista ['1','x'] o ['1','x','2'] segun se combine dobles o triples.
Combina mediante listas por comprension (mapping list).
Devuelve lista con la combinacion de los elementos de la lista dada."""
        return [[a,b,c,d,e,f,g,h] for a in lista for b in lista for c in lista for d in lista for e in lista for f in lista for g in lista for h in lista] #lista 8 multiples
    def nueveMult(lista):
        """Recibe lista ['1','x'] o ['1','x','2'] segun se combine dobles o triples.
Combina mediante listas por comprension (mapping list).
Devuelve lista con la combinacion de los elementos de la lista dada."""
        return [[a,b,c,d,e,f,g,h,i] for a in lista for b in lista for c in lista for d in lista for e in lista for f in lista for g in lista for h in lista for i in lista] #lista 9 multiples
    def diezMult(lista):
        """Recibe lista ['1','x'] o ['1','x','2'] segun se combine dobles o triples.
Combina mediante listas por comprension (mapping list).
Devuelve lista con la combinacion de los elementos de la lista dada."""
        return [[a,b,c,d,e,f,g,h,i,j] for a in lista for b in lista for c in lista for d in lista for e in lista for f in lista for g in lista for h in lista for i in lista for j in lista] #lista 10 multiples
    def onceMult(lista):
        """Recibe lista ['1','x'] o ['1','x','2'] segun se combine dobles o triples.
Combina mediante listas por comprension (mapping list).
Devuelve lista con la combinacion de los elementos de la lista dada."""
        return [[a,b,c,d,e,f,g,h,i,j,k] for a in lista for b in lista for c in lista for d in lista for e in lista for f in lista for g in lista for h in lista for i in lista for j in lista for k in lista] #lista 11 multiples
    def doceMult(lista):
        """Recibe lista ['1','x'] o ['1','x','2'] segun se combine dobles o triples.
Combina mediante listas por comprension (mapping list).
Devuelve lista con la combinacion de los elementos de la lista dada."""
        return [[a,b,c,d,e,f,g,h,i,j,k,l] for a in lista for b in lista for c in lista for d in lista for e in lista for f in lista for g in lista for h in lista for i in lista for j in lista for k in lista for l in lista] #lista 12 multiples
    def treceMult(lista):
        """Recibe lista ['1','x'] o ['1','x','2'] segun se combine dobles o triples.
Combina mediante listas por comprension (mapping list).
Devuelve lista con la combinacion de los elementos de la lista dada."""
        return [[a,b,c,d,e,f,g,h,i,j,k,l,m] for a in lista for b in lista for c in lista for d in lista for e in lista for f in lista for g in lista for h in lista for i in lista for j in lista for k in lista for l in lista for m in lista] #lista 13 multiples
    def catorceMult(lista):
        """Recibe lista ['1','x'] o ['1','x','2'] segun se combine dobles o triples.
Combina mediante listas por comprension (mapping list).
Devuelve lista con la combinacion de los elementos de la lista dada."""
        return [[a,b,c,d,e,f,g,h,i,j,k,l,m,n] for a in lista for b in lista for c in lista for d in lista for e in lista for f in lista for g in lista for h in lista for i in lista for j in lista for k in lista for l in lista for m in lista for n in lista] #lista 14 multiples

    def combinaMult(listaD, listaT):
        """Recibe dos listas (compuestas de listas), la combinacion de los dobles y la combinacion de los triples, en este orden, y las combina para obtener la lista definitiva que sera devuelta."""
        try:
            if len(listaD) == 1 or len(listaT) == 1: raise ValueError("Alguna de las listas solo contiene una sublista. Recuerda, cada sublista es una apuesta, un doble son dos apuestas, un triple son tres apuestas, por tanto, l1d = [['1'],['x']] y l1t = [['1'],['x'],['2']].")
        except ValueError: raise
        listaC = []
        listaF = []
        for i in range(len(listaD)):
            lD = listaD[i] # sublista de dobles para manejo individual
            for e in range(len(listaT)):
                lT = listaT[e] #sublista de triples para manejo individual
                lF = lD + lT
                listaF.append(lF)
        return listaF
    try:
        if dobles == 0 and triples == 0: raise ValueError("No se puede combinar, dobles = 0 y triples = 0 no es una combinacion valida, debe haber al menos un multiple (doble o triple).")
    except ValueError: raise
    if dobles == 0:
        eligeFuncion = eligeMult(triples)
        nombreFuncion = locals()[eligeFuncion]
        listaFinal = nombreFuncion(T)
    elif triples == 0:
        eligeFuncion = eligeMult(dobles)
        nombreFuncion = locals()[eligeFuncion]
        listaFinal = nombreFuncion(D)
    else:
        eligeFuncionDobles = eligeMult(dobles)
        eligeFuncionTriples = eligeMult(triples)
        nombreFuncionDobles = locals()[eligeFuncionDobles]
        nombreFuncionTriples = locals()[eligeFuncionTriples]
        listaDobles = nombreFuncionDobles(D)
        listaTriples = nombreFuncionTriples(T)
        listaFinal = combinaMult(listaDobles, listaTriples)
    try:
        if listaFinal==[]: raise ValueError("La funcion apMetDirecto(dobles,triples) no ha conseguido combinar en una lista los multiples recibidos, por el motivo que sea dicha lista sigue vacia y no se puede seguir.")
    except ValueError: raise
    tuplaFinal = [tuple(elem) for elem in listaFinal] #es el nombre de la lista de tuplas devuelta por la funcion
    return tuplaFinal


¡saludos!
Avatar de Usuario
Dokan
 
Mensajes: 143
Registrado: Lun Dic 03, 2007 10:40 pm

Notapor Dokan » Mar Feb 12, 2008 3:04 pm

Hola a todos!!
Tengo poco tiempo por exámenes, pero aún estoy con la mosca detrás de la oreja a ver como puedo hacer la reducción de las apuestas múltiples en grupos de apuestas que se diferencien entre sí en al menos tres elementos.
Creo que se puede hacer con 'comprehension list' pero como no tengo ni idea y aún habiendo consultado por ahí no he conseguido mucha información sobre este tipo de listas he intentado hacer un algoritmo que resuelva el problema. Parece sencillo pero no lo es.
Hasta ahora sólo funciona (que yo haya probado) con siete dobles.
Código: Seleccionar todo
#! /usr/bin/env python
# -*- coding: utf-8 -*-

G=globals()

def reduccion(premios, limite, columnas):# premios(), limite(), apMetDirecto()
    """Recibe dos enteros y una lista de tuplas, premios será el num. de grupos de reduccion y limite será el num. de columnas de cada grupo de reduccion, columnas será el total de apuestas del metodo directo.
Distribuye cada apuesta del metodo directo en grupos de reduccion segun un criterio dado.
Grupo de reduccion es el grupo de columnas minimo para garantizar el premio de 2ª categoria, de la union de todos los grupos de reduccion resulta el total de apuestas del metodo directo.
Las condiciones que ha de cumplir son:
- Todas las columnas de un grupo se diferencian entre si en al menos 3 signos.
- Todas las columnas que no pertenecen a un grupo coinciden en 2 signos con al menos una de las columnas de ese grupo.
- Todos los grupos de reduccion forman el total de las apuestas por el metodo directo.
No Devuelve nada, los grupos se guardan en globals().
"""
    while columnas != []:
        print "columnas distinto de lista vacia"
        for i in range(premios):
            G['grupo%d' %i]= []
            print 'grupo%d' %i
            while len(G['grupo%d' %i]) < limite:
                #print 'grupo%d es menor que el limite' % i
                #print G['grupo%d' % i]#comprobacion
                print len(columnas)
                print len(G['grupo%d' % i])
                if G['grupo%d' %i]== []:
                    print 'grupo%d vacio, añado columna y sigo' %i
                    G['grupo%d' %i].append(columnas[0])
                    columna = columnas[0]
                    columnas.remove(columna)
                else:
                    #print 'grupo%d no está vacío, sigo evaluando' %i
                    rompobucle = 0
                    for e in range(len(columnas)):
                        #print 'columnas[%d]' %e
                        if rompobucle==1:
                            #print 'rompobucle == 1, break'
                            break
                        elif compara(G['grupo%d' % i][0],columnas[e]) > 2:
                            #print 'compara(grupo%d[0],columnas[%d]) mayor que 2, comparamos el resto del grupo' % (i,e)
                            #print 'por tanto comparamos el resto del grupo'
                            for a in range(len(G['grupo%d' % i])):
                                #print 'grupo%d[%d]' % (i,a)
                                if compara(G['grupo%d' % i][a],columnas[e]) < 3:
                                    #print 'compara(grupo%d[%d],columnas[%d]) menor que 3' %(i,a,e)
                                    #print 'no se cumplen los requisitos, rompobucle y sigo'
                                    #rompobucle = 1
                                    break
                                elif a == len(G['grupo%d' % i]) - 1: #posible error
                                    #print 'comparado ultimo elemento del grupo'
                                    #print 'se han cumplido los requisitos'
                                    #print 'ultimo elemento del grupo, añado columnas[%d] al grupo%d y la elimino de columnas' %(e,i)
                                    G['grupo%d' % i ].append(columnas[e])
                                    columna = columnas[e]
                                    columnas.remove(columna)
                                    #print 'el grupo%d queda como sigue' %i
                                    #print G['grupo%d' % i ]
                                    #print 'columnas queda como sigue'
                                    #print columnas
                                    #print 'tamaño de columnas:'
                                    #print len(columnas)
                                    rompobucle = 1

Las líneas comentadas son sentencias de control que he utilizado para comprobar donde estan los errores al ejecutarlo en línea de comandos, si quereis probarlo aconsejo descomentarlas.
Si quieres probarlo necesitaras el resto del programa guardado en dos archivos, y ejecutar:
Código: Seleccionar todo
import sys
sys.path.append("/home/kike/python/quiniela") # poned aquí el dir donde guardasteis todo
from quinielav004 import * #aqui tenemos todas las funciones menos la última
from reduccion3 import * #la última función en desarrollo
pre=premios(7,0) #podeis probar como no funciona para otras combinaciones (3,2) (5,1) etc.
ap= apMetDirecto(7,0) #lo mismo que en premios
lim=limite(len(ap),pre)
reduccion(pre,lim,ap)


Espero tener tiempo para resolver pronto el problema.
Si teneis algún consejo o alguna duda ya sabeis que serán bien recibidos.
Si habeis llegado hasta aquí es porque os interesa, os dejo un par de enlaces sobre las características que deben cumplir las reducciones por si os quereis comer la cabeza:
Reducción de quinielas al trece por jagar.
Página de la Organización Nacional de Loterías y Apuestas del Estado (ONLAE) de España donde se explica la teoría de la reducción al trece.

Gracias por el esfuerzo de comprensión.
¡Saludos!
Avatar de Usuario
Dokan
 
Mensajes: 143
Registrado: Lun Dic 03, 2007 10:40 pm

Notapor Dokan » Mar Mar 03, 2009 1:24 pm

mmm un viejo proyecto, que nostalgia.
A ver si lo retomo algún día, con más conocimiento, claro.
Avatar de Usuario
Dokan
 
Mensajes: 143
Registrado: Lun Dic 03, 2007 10:40 pm

Notapor endaramiz » Mar Mar 03, 2009 7:31 pm

Dokan escribió:mmm un viejo proyecto, que nostalgia.
A ver si lo retomo algún día, con más conocimiento, claro.

:shock: mmm un viejo forero, que nostalgia.
Me alegro de tu regreso después de estar más de medio año sin escribir nada. Aunque ya veo que has entrado con energía :lol:

Hombre.. personalmente, probaría con otro proyecto con gráficos y más emocionante. Este tampoco te puede servir mucho para practicar ya que la estructura y el funcionamiento de los juegos no suele parecerse a este tipo de programas.

Saludos.
Avatar de Usuario
endaramiz
 
Mensajes: 283
Registrado: Vie Ago 31, 2007 9:25 am
Ubicación: Barcelona

Notapor Dokan » Mar Mar 03, 2009 9:42 pm

mmm un viejo forero, que nostalgia.
Me alegro de tu regreso después de estar más de medio año sin escribir nada. Aunque ya veo que has entrado con energía


Gracias!! :wink:
También gracias por el consejo, así lo haré. De hecho ya estoy en marcha. Posiblemente en una semanita si el curro me lo permite empezaré a torear en estas plazas. :D
Avatar de Usuario
Dokan
 
Mensajes: 143
Registrado: Lun Dic 03, 2007 10:40 pm


Volver a Otros

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado