adivinhe seu número
Um script simples que pede que você pense em um número entre 1 e 63 oferece uma lista de números e pergunta se o seu número está nessa lista. Isso pode ser refatorado ainda mais? Existem maneiras melhores de criar listas? Alguma melhoria?
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()
Respostas
Números mágicos
Como já mencionado nos comentários, os números \$ 1, 2, \cdots \$parecem ser completamente aleatórios para qualquer pessoa que não tenha certeza sobre como o somatório vai (ou deveria) funcionar. A geração das listas também é muito complicada. O mesmo truque pode ser expandido para uma seleção até \$ 127, 255, 511, \cdots, 2^{n} - 1 \$.
Recursiva main
Você tem uma chamada recursiva para maincaso o jogador queira repetir o jogo. Chamadas recursivas quando você nunca retorna podem levar a estouros de pilha. Nesse cenário, a recursão não é realmente necessária de qualquer maneira.
Uso excessivo de listas
Você tem quase tudo colocado em listas. Isso inclui todos os números de \$ 1-63 \$, todos os gráficos gerados a partir desses números, agregação de todas as listas acima, lista de poderes de \$ 2 \$, e assim por diante.
Para alguns deles, uma tupla (imutável) é boa, outros não precisam ser colocados em uma lista de qualquer maneira.
Nomenclatura de variável
x, xx, xxx, xxxx, .. não são realmente significativa. Use nomes de variáveis melhores.
Para geração das listas numéricas:
for start in (2 ** i for i in range(6)):
l = [_ for _ in range(start, 64) if _ % (start * 2) >= start]
Reescrever:
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()
A reescrita é completamente dinâmica por natureza agora. Se você quiser aumentar o intervalo, basta adicionar outra seção à INTROStupla.
Primeira passagem:
- Mova a maior parte do material de criação de lista para uma função
- Correções do PEP8: padronizar espaços, livrar-se de escapes de continuação, espaços entre funções
- Algumas tuplas imutáveis em vez 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()
Mas isso não é suficiente. Faça o que @ hjpotter92 sugeriu.