indovina il tuo numero

Oct 17 2020

Semplice script che ti chiede di pensare a un numero compreso tra 1 e 63, quindi offre un elenco di numeri e ti chiede se il tuo numero è in quell'elenco. Questo può essere ulteriormente modificato? Esistono modi migliori per creare elenchi? Qualche miglioramento?

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()

Risposte

10 hjpotter92 Oct 17 2020 at 23:17

Numeri magici

Come già accennato nei commenti, i numeri \$ 1, 2, \cdots \$sembrano essere completamente casuali per chiunque non sia sicuro di come funzionerà (o dovrebbe) la somma. Anche la generazione delle liste è molto macchinosa. Lo stesso trucco potrebbe essere esteso a una selezione fino a \$ 127, 255, 511, \cdots, 2^{n} - 1 \$.

Ricorsivo main

Hai una chiamata ricorsiva a mainnel caso in cui il giocatore desideri rigiocare il gioco. Le chiamate ricorsive quando non torni mai potrebbero portare a overflow dello stack. In questo scenario, comunque, la ricorsione non è realmente necessaria.

Uso eccessivo di elenchi

Hai quasi tutto messo negli elenchi. Questo include tutti i numeri da \$ 1-63 \$, tutti i grafici generati da questi numeri, aggregazione di tutti gli elenchi precedenti, elenco delle potenze di \$ 2 \$, e così via.

Per alcuni di questi, una tupla (immutabile) è buona, altri non devono comunque essere inseriti in un elenco.

Denominazione delle variabili

x, xx, xxx, xxxx, .. non sono veramente significativo. Usa nomi di variabile migliori.


Per la generazione delle liste numeriche:

for start in (2 ** i for i in range(6)):
    l = [_ for _ in range(start, 64) if _ % (start * 2) >= start]

Riscrivere:

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 riscrittura è di natura completamente dinamica ora. Se vuoi aumentare l'intervallo, aggiungi semplicemente un'altra sezione alla INTROStupla.

3 Reinderien Oct 17 2020 at 23:33

Primo passaggio:

  • Sposta la maggior parte delle cose per la creazione di elenchi in una funzione
  • Correzioni PEP8: standardizza gli spazi, elimina le fughe di continuazione, gli spazi tra le funzioni
  • Alcune tuple immutabili invece di elenchi
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()

Ma questo non è sufficiente. Fai ciò che @ hjpotter92 ha suggerito.