adivina tu número
Un guión simple que le pide que piense en un número entre 1 y 63, luego ofrece una lista de números y le pregunta si su número está en esa lista. ¿Se puede refactorizar esto aún más? ¿Existen mejores formas de crear listas? ¿Alguna mejora?
x= [xx for xx in range(1,64)]
num_i = [i for i in range(1,64,2)]
num_ii = x[1::16]+ x[2::16]+ x[5::16]+ x[6::16]+ \
x[9::16]+ x[10::16]+ x[13::16]+ x[14::16]
num_ii.sort()
num_iii= x[3::16]+ x[4::16]+ x[5::16]+ x[6::16]+ \
x[11::16]+ x[12::16]+ x[13::16]+ x[14::16]
num_iii.sort()
num_iv= x[7::16]+ x[8::16]+ x[9::16]+ x[10::16]+ \
x[11::16]+ x[12::16]+ x[13::16]+ x[14::16]
num_iv.sort()
num_v= x[15::32]+ x[16::32]+ x[17::32]+ x[18::32]+ \
x[19::32]+ x[20::32]+ x[21::32]+ x[22::32]+ \
x[23::32]+ x[24::32]+ x[25::32]+ x[26::32]+ \
x[27::32]+ x[28::32]+ x[29::32]+ x[30::32]
num_v.sort()
num_vi= [x for x in range(32,64)]
num_lists=[num_i,num_ii,num_iii,num_iv,num_v,num_vi]
addition_num= [1,2,4,8,16,32]
start_end= ["Think of a number between 1 and 63","I think the number you thought of was ..."]
intro= ["Is your number in the group of numbers below?",
"Is your number in this group of numbers ?","Is your number in this third group of numbers ?",
"Half way there. Is your number in this group of numbers ?",
"One more after this one. Is your number in this group of numbers ?",
"Last one. Is your number in this group of numbers ?"]
def format_list(xx):
for a,b,c,d,e,f,g,h in zip(xx[::8],xx[1::8],xx[2::8],xx[3::8],xx[4::8],xx[5::8],xx[6::8],xx[7::8]):
print('{:<8}{:<8}{:<8}{:<8}{:<8}{:<8}{:<8}{:<}'.format(a,b,c,d,e,f,g,h))
print('-'*62)
def main():
count=0
your_guess= 0
print(start_end[0])
ready= input('are you ready?(enter to quit or any key)')
if ready:
while count < 6:
print(intro[count])
format_list(num_lists[count])
reply = input("y/n ?")
if reply == "y" :
your_guess += addition_num[count]
count +=1
print(start_end[1] + str(your_guess))
replay= input('Play again? (enter to quit or any key)')
if replay:
main()
if __name__ == '__main__':
main()
Respuestas
Números mágicos
Como ya se mencionó en los comentarios, los números \$ 1, 2, \cdots \$parece ser completamente aleatorio para cualquiera que no esté seguro de cómo va a funcionar (o se supone que va a funcionar) la suma. La generación de las listas también es muy engorrosa. El mismo truco podría ampliarse a una selección de hasta \$ 127, 255, 511, \cdots, 2^{n} - 1 \$.
Recursivo main
Tienes una llamada recursiva a mainen caso de que el jugador quiera volver a jugar el juego. Las llamadas recursivas cuando nunca regresa pueden provocar desbordamientos de pila. En este escenario, la recursividad no es realmente necesaria de todos modos.
Uso excesivo de listas
Tienes casi todo dentro de listas. Esto incluye todos los números de \$ 1-63 \$, todos los gráficos generados a partir de estos números, agregación de todas las listas anteriores, lista de poderes de \$ 2 \$, y así.
Para algunos de ellos, una tupla (inmutable) es buena, otros no necesitan ser colocados en una lista de todos modos.
Denominación variable
x, xx, xxx, xxxx, .. no son realmente significativo. Utilice mejores nombres de variables.
Para la generación de listas numéricas:
for start in (2 ** i for i in range(6)):
l = [_ for _ in range(start, 64) if _ % (start * 2) >= start]
Volver a escribir:
INTROS = (
"Is your number in the group of numbers below?",
"Is your number in this group of numbers?",
"Is your number in this third group of numbers?",
"Half way there. Is your number in this group of numbers?",
"One more after this one. Is your number in this group of numbers?",
"Last one. Is your number in this group of numbers?",
# "Or maybe the following?",
# "Add more intro strings here",
# "to get larger guessing range",
)
COUNT = len(INTROS)
UPPER_LIMIT = 2 ** COUNT
def display_chart(index: int, columns: int = 8):
print(INTROS[index])
start = 1 << index
chart = [str(x) for x in range(start, UPPER_LIMIT) if x % (start * 2) >= start]
for i in range(len(chart) // columns):
print("\t".join(chart[i * columns : (i + 1) * columns]))
def game():
guess = 0
print(f"Think of a number between 1 and {UPPER_LIMIT - 1}")
for current in range(COUNT):
display_chart(current)
reply = input("y/n? ")
if reply == "y":
guess += 1 << current
print(f"I think the number you thought of was ... {guess}")
def main():
while True:
game()
character = input("Play again? (enter to quit or any key)")
if not character:
break
if __name__ == "__main__":
main()
La reescritura es de naturaleza completamente dinámica ahora. Si desea aumentar el rango, simplemente agregue otra sección a la INTROStupla.
Primer pase:
- Mover la mayor parte de la creación de listas a una función
- Correcciones de PEP8: estandarizar espacios, deshacerse de los escapes de continuación, espacios entre funciones
- Algunas tuplas inmutables en lugar de listas
def make_num_lists():
x = [xx for xx in range(1, 64)]
num_i = [i for i in range(1, 64, 2)]
num_ii = (x[ 1::16] + x[ 2::16] + x[ 5::16] + x[ 6::16] +
x[ 9::16] + x[10::16] + x[13::16] + x[14::16])
num_ii.sort()
num_iii = (x[ 3::16] + x[ 4::16] + x[ 5::16] + x[ 6::16] +
x[11::16] + x[12::16] + x[13::16] + x[14::16])
num_iii.sort()
num_iv = (x[ 7::16] + x[ 8::16] + x[ 9::16] + x[10::16] +
x[11::16] + x[12::16] + x[13::16] + x[14::16])
num_iv.sort()
num_v = (x[15::32] + x[16::32] + x[17::32] + x[18::32] +
x[19::32] + x[20::32] + x[21::32] + x[22::32] +
x[23::32] + x[24::32] + x[25::32] + x[26::32] +
x[27::32] + x[28::32] + x[29::32] + x[30::32])
num_v.sort()
num_vi = [x for x in range(32, 64)]
return [num_i, num_ii, num_iii, num_iv, num_v, num_vi]
num_lists = make_num_lists()
addition_num = (1, 2, 4, 8, 16, 32)
start_end = (
"Think of a number between 1 and 63",
"I think the number you thought of was ...",
)
intro = (
"Is your number in the group of numbers below?",
"Is your number in this group of numbers ?",
"Is your number in this third group of numbers ?",
"Half way there. Is your number in this group of numbers ?",
"One more after this one. Is your number in this group of numbers ?",
"Last one. Is your number in this group of numbers ?",
)
def format_list(xx):
for a,b,c,d,e,f,g,h in zip(xx[::8],xx[1::8],xx[2::8],xx[3::8],xx[4::8],xx[5::8],xx[6::8],xx[7::8]):
print('{:<8}{:<8}{:<8}{:<8}{:<8}{:<8}{:<8}{:<}'.format(a,b,c,d,e,f,g,h))
print('-'*62)
def main():
count = 0
your_guess = 0
print(start_end[0])
ready = input('are you ready?(enter to quit or any key)')
if ready:
while count < 6:
print(intro[count])
format_list(num_lists[count])
reply = input("y/n ?")
if reply == "y":
your_guess += addition_num[count]
count += 1
print(start_end[1] + str(your_guess))
replay = input('Play again? (enter to quit or any key)')
if replay:
main()
if __name__ == '__main__':
main()
Pero esto no es suficiente. Haz lo que sugirió @ hjpotter92.