# perdiendo.org/museodemetralla

entraron en mi cabeza (191) | libros (15) | me lo llevo puesto (7) | pelis (1) | Renta básica (8) | series (4) | freakeando (83) | arduino (1) | autoreferencial (9) | bici (1) | esperanto (4) | eve online (3) | git (2) | GNU/linux (3) | markdown (7) | nexus7 (2) | python (6) | raspberry pi (3) | vim (1) | zatchtronics (3) | hago (671) | canciones (102) | cover (22) | el extremo inútil de la escoba (2) | guitarlele (11) | ruiditos (6) | fotos (37) | nanowrimo (3) | novela (26) | criaturas del pantano (5) | el año que no follamos (12) | huim (5) | rehab (4) | poemas (333) | Anclajes (15) | andando (3) | B.A.R (7) | Canción de cuna para un borracho (38) | Cercos vacíos (37) | Cien puentes en la cabeza (7) | Conejo azul (6) | Contenido del juego (5) | De tiendas (3) | del pantano (3) | Epilogo (4) | Fuegos de artificio (5) | Imposible rescate (15) | Jugando a rojo (7) | Lo que sé de Marte (11) | Los cuentos (21) | Montaje del juego (5) | Orden de salida (4) | palitos (23) | Piernas abiertas (7) | Poemas medianos (12) | Privado de sueño (7) | Tanto para nada (17) | Todo a 100 (2) | Uno (4) | relatos (85) | anatemas (8) | orbital (2) | vindicaciones (103) | perdiendo (1.514) | atranques (1) |

listas anidadas

Las listas se pueden anidar hasta el infinito y más allá.

hola = 'saludo salido terciario nacido' .split()
torna = 'dumba etna locura principio' .split()
silencio = 'soldado fraguado lenguado' .split()
macaco = 'guardapolvo fresado basurilla nacido' .split()

monte = [hola, torna]
tardo = [silencio, macaco]

supra = [monte, tardo]

print(hola)

print(torna)

print(silencio)

print(macaco)

print(monte)

print(tardo)

print(supra)

for i in hola:
    print(i)

for i in supra:
    print(i)

print(hola, supra)

Y eso acaba de hacer que me explote la cabeza (aunque no debería, pero está bien que lo haga, más hype).

multi dado

¡Qué bien sienta que me empiecen a salir estas cositas, por muy básicas que sean!

Me estaba preguntando si podría hacer un multi dado en el que poder elegir tanto el número de dados como el número de caras. Es una tontada, pero me ha alegrado el día.

import random

# función de cada tirada de cada dado
def tirada(caras): 
    sale = random.randint(1, caras)
    return sale

# evitamos que explote el programa cuando meten números negativos o letras
def real_positivo(dados_caras): # dados caras sólo indica el parámetro del que hablar
    while True: # bucle infinito hasta que meta un valor válido
        numero = input(f'''
        ¿De qué número de {dados_caras} estaríamos hablando?

        ''')
        if numero[0] == '-' and numero[1:].isdigit():
            print(f'''
        Cuidado, un número negativo de {dados_caras} rompería el espacio-tiempo.''')        
        elif numero.isdigit():
            numero = int(numero)
            if numero > 0:
                return numero
            else:
                print(f'''
        Poco vamos a hacer con 0 {dados_caras}''')
        else:
            print('''
        Eso va a ser que no es un número entero positivo''')

caras, dados = 6 ,1 # establecemos por defecto 6 caras y 1 dado

while True: # bucle infinito hasta que el usuario quiera dejar de usar los dados

    menu = input(f'''
    M U L T I   D A D O

    1. Dados | 2. Caras | 3. Tirada | 4. Salir

    === Dados {dados}, caras {caras}

    Elige: ''')

    if menu == '1':
        dados = real_positivo('dados')
        print('''
        === Configurado ===''')

    elif menu == '2':
        caras = real_positivo('caras')
        print('''
        === Configurado ===''')

    elif menu == '3':
        suma = 0 # arriba junto con las demás supondría reiniciarlo debajo en cada fin de 3
        for cada in range(1, dados + 1):
            resultado = tirada(caras)
            suma = suma + resultado
            print(f'''
            Dado {cada} > saca {resultado}''')
        print(f'''
        Total de la tirada: {suma}''')

    elif menu == '4':
        break

    else:
        print('''
        === Eso no es una opción del menú ===''')

el ahorcado

Es divertido, mucho. Pero después de reventarme contra ello es de esas cosas que sé que puedo entender si la reviso, pero no sé si sería capaz de crearlo por mí mismo (dudo mucho que fuera capaz).

# el famosísimo internacionalmente juego del ahorcado versión mimismo

import random # importamos el módulo para elegir posteriormente entre las palabras de la variable "palabras"

'''
Cadena multi-línea: comillas triples en una variable permiten meter varias líneas sin tener que utilizar \n

Lista: contiene varios valores a los que se puede acudir por número de izq a der empezando desde el 0,
en la de abajo IMÁGENES_AHORCADO cada elemento de la lista es una cadena multi-línea

Constantes: para variables constantes como IMÁGENES_AHORCADO la convención es que vayan escritas en mayúscula
(una "variable constante" es un contrasentido como un piano, yo diría "constante" sin más)

'''

IMÁGENES_AHORCADO = [''' 

  +---+
  |   |
      |
      |
      |
      |
=========''', '''

  +---+
  |   |
  O   |
      |
      |
      |
=========''', '''

  +---+
  |   |
  O   |
  |   |
      |
      |
=========''', '''

  +---+
  |   |
  O   |
 /|   |
      |
      |
=========''', '''

  +---+
  |   |
  O   |
 /|\  |
      |
      |
=========''', '''

  +---+
  |   |
  O   |
 /|\  |
 /    |
      |
=========''', '''

  +---+
  |   |
  O   |
 /|\  |
 / \  |
      |
=========''']

palabras = 'hormiga babuino tejon murcielago oso castor camello gato almeja cobra pantera coyote cuervo ciervo perro burro pato aguila huron zorro rana cabra ganso halcon leon lagarto llama topo mono alce raton mula salamandra nutria buho panda loro paloma piton conejo carnero rata cuervo rinoceronte salmon foca tiburon oveja mofeta perezoso serpiente araña cigüeña cisne tigre sapo trucha pavo tortuga comadreja ballena lobo wombat cebra'.split()

# el método .split() devuelve una lista en la que cada palabra en la cadena es un elemento aparte, separa en cada hueco en blanco. 
# "palabras" pasa a ser una lista igual que si hubiéramos escr
# con ListaDePalabras defines un parámetro, dices que al lanzar la función obtenerPalabraAlAzar le incluirás una lista entre (). ito palabras = ['hormiga', 'babuino'] etcetc.

# recordatorio personal: definir funciones no pone en marcha nada, simplemente las define para un futuro

# no es que estés creando otra lista, sino que le indicas que trabajará con una lista de palabras que proporcionas, en este caso 'palabras'
# eso mola porque la función utilizará listaDePalabras para manipularlas se llame como se llame la lista que le metas
# lo que me ha costado comprender esto, todo está relacionado con las variables globales y las variables locales
# si dentro de la función substituyes listaDePalabras por palabras todo seguiría funcionando igual, de hecho lo hace en la función siguiente
def obtenerPalabraAlAzar(listaDePalabras):
    índiceDePalabras = random.randint(0, len(listaDePalabras) - 1) # el número que se usará para elegir de la lista palabras[x]
# -1 porque el elemento 1 es el 0 en la asignación, así que la cuarta palabra en la lista estará en la posición 3
# elige entre 0 y la longitud de la lista -1
    return listaDePalabras[índiceDePalabras]
# devuelve listaDePalabras (que en este caso es palabras, el nombre de la lista) y [el índice]: palabras[x]

# en esta función las variables locales se llaman igual que las globales, aunque no son las mismas
def mostrarTablero(IMÁGENES_AHORCADO, letrasIncorrectas, letrasCorrectas, palabraSecreta):
    print(IMÁGENES_AHORCADO[len(letrasIncorrectas)]) # imprime de la lista de imágenes la que está en la posición de las letras incorrectas
    print() # imprimimos una línea en blanco

    print('Letras incorrectas:', end=' ') # imprime el texto y no salta a la línea de abajo
    for letra in letrasIncorrectas: # letra es una nueva variable for hace que "deletree" las letras que pertenecen a incorrectas y las guarda en cada ciclo en letra
        print(letra, end=' ') # la secuencia for imprime letra sin saltar a la linea de abajo
    print() # imprimimos una línea en blanco

    espaciosVacíos = '_' * len(palabraSecreta) # las líneas de la palabra, imprime tantos _ como su longitud

    for i in range(len(palabraSecreta)): # nueva variable i en la que se acumula toda la longitud de palabraSecreta, si tiene 7 letras se moverá entre el 0-6
        if palabraSecreta[i] in letrasCorrectas: # si la letra que toca está en letras correctas... (cualquier variable es tb una lista de letras, guardas 'hola' y palabraSecreta[0] será h)
            espaciosVacíos = espaciosVacíos[:i] + palabraSecreta[i] + espaciosVacíos[i+1:]
            ''' vamos a actualizar espaciosVacíos por las letras descubiertas con un corte de lista
                corte de lista [a:c] marca las palabras que se van a incluir con desde-hasta, y el hasta no incluye, en hola[1:3] sería ol, las pos 1 y 2
                1. espaciosVacíos[:i] metemos los valores de espacios vacíos hasta i (para no modificar los anteriores bucles de _ vacíos y letras descubiertas)
                el hasta del corte llega hasta justo la posición anterior a i
                2. palabraSecreta[i] metemos la letra que ha sido correcta en i
                3. espaciosVacíos[i+1:] metemos desde i en adelante lo que hubiera (_ vacíos y letras descubiertas)
                de espaciosVacíos nos interesan los _ y las letras descubiertas en bucles anteriores, y de palabraSecreta sólo la letra correcta
            '''

    for letra in espaciosVacíos: # generamos letra con todo lo que esté en spaciosVacíos
        print(letra, end=' ') # imprimimos las letras y los _ (letra es la variable que creamos cada ciclo) y no saltamos de línea
    print() # imprimimos una línea en blanco

# nueva función para recibir la nueva letra, le metemos letrasProbadas con las letras que hemos metido con anterioridad como parámetro
def obtenerIntento(letrasProbadas):
    while True: # jaja, siempre es true hasta que sales con return
        print('Adivina una letra.') # imprimimos Adivina...
        intento = input() # le pedimos que meta una letra y la guardamos en intento
        intento = intento.lower() # la ponemos en minúscula
        if len(intento) != 1: # si la longitud de intento es más de uno es que ha metido más de una letra y no mola
            print('Por favor, introduce una letra.') # le decimos lo que ha pasado
        elif intento in letrasProbadas: # tb si la letra ya la ha metido antes 
            print('Ya has probado esa letra, elige otra.') # le decimos que ya lo ha hecho
        elif intento not in 'abcdefghijklmnñopqrstuvwxyz': # si no está en el abecedario
            print('Por favor, ingresa una LETRA.') # se lo recordamos
        else: # en cualquier otro caso
            return intento # devolvemos el resultado metiéndolo en la variable global intento

# función para volver a jugar o salir
def jugarDeNuevo(): # definimos, no necesita parámetro
    print('¿Quieres jugar de nuevo (sí o no)') # imprimimos la pregunta
    return input().lower().startswith('s') # ponemos input en minúsculas, si empieza por s devuelve True (s no es lo mismo que S)

# y empieza el juego!
print('A H O R C A D O') # imprimimos el nombre
letrasIncorrectas = '' # creamos la variable letrasIncorrectas
letrasCorrectas = '' # creamos la variable #letrasCorrectas
# la única vez que se invoca "palabras" es para meterla dentro de la función obtenerPalabraAlAzar
# le estás diciendo a la función el nombre de la lista que tiene que utilizar
palabraSecreta = obtenerPalabraAlAzar(palabras) # creamos la palabra correcta
juegoTerminado = False # establecemos el status para salir del juego en False

while True: # repite el bucle indefinidamente hasta que algo le saca
    mostrarTablero(IMÁGENES_AHORCADO, letrasIncorrectas, letrasCorrectas, palabraSecreta) # invocas mostrarTablero con sus variables

    intento = obtenerIntento(letrasIncorrectas + letrasCorrectas) # creas intento invocando a la función obtenerIntento, con las letrasIncorrectas y las letrasCorrectas como variables que se meterán en la variable local letrasProbadas

    if intento in palabraSecreta: # aquí la función obtenerIntento ya ha devuelto la letra que ha metido el tipo, así que si está en la palabraSecreta...
        letrasCorrectas = letrasCorrectas + intento # la añadimos a letrasCorrectas manteniendo las anteriores, en intento sigue estando la letra que ha metido el tipo

        encontradoTodasLasLetras = True # marcamos el status de encontradoTodasLasLetras como verdadero, tendrá sentido en el siguiente if
        for i in range(len(palabraSecreta)): # bucle for para testar las letras
            if palabraSecreta[i] not in letrasCorrectas: # si una de las letras de palabraSecreta no está en letrasCorrectas
                encontradoTodasLasLetras = False # cambiamos el status de encontradoTodasLasLetras a False
                break # rompemos el for, así que pasará a else:
        if encontradoTodasLasLetras: # si encontradoTodasLasLetras es True
            print('¡Sí! ¡La palabra secreta es "' + palabraSecreta + '"! ¡Has ganado!') # imprimes el final
            juegoTerminado = True # y creas juego terminado y le das valor True
    else:
        letrasIncorrectas = letrasIncorrectas + intento # si la letra no estaba en la palabra secreta, la añadimos a letras incorrectas

        if len(letrasIncorrectas) == len(IMÁGENES_AHORCADO) - 1: # ojo, si la longitud de letrasIncorrectas es igual a IMÁGENES_AHORCADO - 1 (len empieza en 1, las listas en 0)
            mostrarTablero(IMÁGENES_AHORCADO, letrasIncorrectas, letrasCorrectas, palabraSecreta) # invocamos mostrarTablero con sus parámetros
            print('¡Te has quedado sin intentos!\nDespués de ' + str(len(letrasIncorrectas)) + ' intentos fallidos y ' + str(len(letrasCorrectas)) + ' aciertos, la palabra era "' + palabraSecreta + '"')
            # imprimimos msg + el número de letras incorrectas + msg + el número de letras correctas + msg + la palabra secreta que había que adivinar
            juegoTerminado = True # y establecemos juegoTerminado en True

    if juegoTerminado: # invocamos juegoTerminado, y si devuelve True 
        if jugarDeNuevo(): # si el tipo ha contestado cualquier cosa que empiece por s, incluido soplapollas
                           # atención a cómo juegoTerminado, que no es una función, no tiene (), mientras que jugarDeNuevo, que sí lo es, sí los tiene
            letrasIncorrectas = '' # ponemos a cero letrasIncorrectas
            letrasCorrectas = '' # ponemos a cero letrasCorrectas
            juegoTerminado = False # convertimos juegoTerminado a False
            palabraSecreta = obtenerPalabraAlAzar(palabras) # obtenemos una nueva palabraSecreta
        else: # si jugarDeNuevo devuelve false
            break # cerramos el programa