Só um detalhe. No seu código vc usa isdigit
para verificar se foi digitado um número, e depois converte usando int
:
if menuOption.isdigit():
if int(menuOption) == 0:
etc
O que serve para a maioria dos casos. Mas como o usuário pode digitar qualquer coisa, então existem situações que podem dar problema. Pois para determinados caracteres, isdigit()
retorna True
, mas dá erro ao converter para int
. Fiz um programa para demonstrar isso:
from unicodedata import name
for i in range(0x10ffff + 1):
s = chr(i)
if s.isdigit():
try:
int(s)
except ValueError:
print(f'{i:06X} - {s} - {name(s, "")}')
Basicamente, o programa faz um loop por todos os caracteres Unicode (0x10ffff
é valor máximo suportado), e caso isdigit()
retorne True
, tenta converter para int
. Se der erro na conversão, imprime os dados do caractere.
Testei com Python 3.11.4, que segundo a documentação, usa a versão 14 do Unicode. Diferentes versões do Python podem usar outras versões do Unicode, então a lista abaixo pode não ser exatamente igual, mas enfim, usando esta versão foram encontrados 128 caracteres:
0000B2 - ² - SUPERSCRIPT TWO
0000B3 - ³ - SUPERSCRIPT THREE
0000B9 - ¹ - SUPERSCRIPT ONE
001369 - ፩ - ETHIOPIC DIGIT ONE
00136A - ፪ - ETHIOPIC DIGIT TWO
00136B - ፫ - ETHIOPIC DIGIT THREE
00136C - ፬ - ETHIOPIC DIGIT FOUR
00136D - ፭ - ETHIOPIC DIGIT FIVE
00136E - ፮ - ETHIOPIC DIGIT SIX
00136F - ፯ - ETHIOPIC DIGIT SEVEN
001370 - ፰ - ETHIOPIC DIGIT EIGHT
001371 - ፱ - ETHIOPIC DIGIT NINE
0019DA - ᧚ - NEW TAI LUE THAM DIGIT ONE
002070 - ⁰ - SUPERSCRIPT ZERO
002074 - ⁴ - SUPERSCRIPT FOUR
002075 - ⁵ - SUPERSCRIPT FIVE
002076 - ⁶ - SUPERSCRIPT SIX
002077 - ⁷ - SUPERSCRIPT SEVEN
002078 - ⁸ - SUPERSCRIPT EIGHT
002079 - ⁹ - SUPERSCRIPT NINE
002080 - ₀ - SUBSCRIPT ZERO
002081 - ₁ - SUBSCRIPT ONE
002082 - ₂ - SUBSCRIPT TWO
002083 - ₃ - SUBSCRIPT THREE
002084 - ₄ - SUBSCRIPT FOUR
002085 - ₅ - SUBSCRIPT FIVE
002086 - ₆ - SUBSCRIPT SIX
002087 - ₇ - SUBSCRIPT SEVEN
002088 - ₈ - SUBSCRIPT EIGHT
002089 - ₉ - SUBSCRIPT NINE
002460 - ① - CIRCLED DIGIT ONE
002461 - ② - CIRCLED DIGIT TWO
002462 - ③ - CIRCLED DIGIT THREE
002463 - ④ - CIRCLED DIGIT FOUR
002464 - ⑤ - CIRCLED DIGIT FIVE
002465 - ⑥ - CIRCLED DIGIT SIX
002466 - ⑦ - CIRCLED DIGIT SEVEN
002467 - ⑧ - CIRCLED DIGIT EIGHT
002468 - ⑨ - CIRCLED DIGIT NINE
002474 - ⑴ - PARENTHESIZED DIGIT ONE
002475 - ⑵ - PARENTHESIZED DIGIT TWO
002476 - ⑶ - PARENTHESIZED DIGIT THREE
002477 - ⑷ - PARENTHESIZED DIGIT FOUR
002478 - ⑸ - PARENTHESIZED DIGIT FIVE
002479 - ⑹ - PARENTHESIZED DIGIT SIX
00247A - ⑺ - PARENTHESIZED DIGIT SEVEN
00247B - ⑻ - PARENTHESIZED DIGIT EIGHT
00247C - ⑼ - PARENTHESIZED DIGIT NINE
002488 - ⒈ - DIGIT ONE FULL STOP
002489 - ⒉ - DIGIT TWO FULL STOP
00248A - ⒊ - DIGIT THREE FULL STOP
00248B - ⒋ - DIGIT FOUR FULL STOP
00248C - ⒌ - DIGIT FIVE FULL STOP
00248D - ⒍ - DIGIT SIX FULL STOP
00248E - ⒎ - DIGIT SEVEN FULL STOP
00248F - ⒏ - DIGIT EIGHT FULL STOP
002490 - ⒐ - DIGIT NINE FULL STOP
0024EA - ⓪ - CIRCLED DIGIT ZERO
0024F5 - ⓵ - DOUBLE CIRCLED DIGIT ONE
0024F6 - ⓶ - DOUBLE CIRCLED DIGIT TWO
0024F7 - ⓷ - DOUBLE CIRCLED DIGIT THREE
0024F8 - ⓸ - DOUBLE CIRCLED DIGIT FOUR
0024F9 - ⓹ - DOUBLE CIRCLED DIGIT FIVE
0024FA - ⓺ - DOUBLE CIRCLED DIGIT SIX
0024FB - ⓻ - DOUBLE CIRCLED DIGIT SEVEN
0024FC - ⓼ - DOUBLE CIRCLED DIGIT EIGHT
0024FD - ⓽ - DOUBLE CIRCLED DIGIT NINE
0024FF - ⓿ - NEGATIVE CIRCLED DIGIT ZERO
002776 - ❶ - DINGBAT NEGATIVE CIRCLED DIGIT ONE
002777 - ❷ - DINGBAT NEGATIVE CIRCLED DIGIT TWO
002778 - ❸ - DINGBAT NEGATIVE CIRCLED DIGIT THREE
002779 - ❹ - DINGBAT NEGATIVE CIRCLED DIGIT FOUR
00277A - ❺ - DINGBAT NEGATIVE CIRCLED DIGIT FIVE
00277B - ❻ - DINGBAT NEGATIVE CIRCLED DIGIT SIX
00277C - ❼ - DINGBAT NEGATIVE CIRCLED DIGIT SEVEN
00277D - ❽ - DINGBAT NEGATIVE CIRCLED DIGIT EIGHT
00277E - ❾ - DINGBAT NEGATIVE CIRCLED DIGIT NINE
002780 - ➀ - DINGBAT CIRCLED SANS-SERIF DIGIT ONE
002781 - ➁ - DINGBAT CIRCLED SANS-SERIF DIGIT TWO
002782 - ➂ - DINGBAT CIRCLED SANS-SERIF DIGIT THREE
002783 - ➃ - DINGBAT CIRCLED SANS-SERIF DIGIT FOUR
002784 - ➄ - DINGBAT CIRCLED SANS-SERIF DIGIT FIVE
002785 - ➅ - DINGBAT CIRCLED SANS-SERIF DIGIT SIX
002786 - ➆ - DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN
002787 - ➇ - DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT
002788 - ➈ - DINGBAT CIRCLED SANS-SERIF DIGIT NINE
00278A - ➊ - DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE
00278B - ➋ - DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO
00278C - ➌ - DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE
00278D - ➍ - DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR
00278E - ➎ - DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE
00278F - ➏ - DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX
002790 - ➐ - DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN
002791 - ➑ - DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT
002792 - ➒ - DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE
010A40 - 𐩀 - KHAROSHTHI DIGIT ONE
010A41 - 𐩁 - KHAROSHTHI DIGIT TWO
010A42 - 𐩂 - KHAROSHTHI DIGIT THREE
010A43 - 𐩃 - KHAROSHTHI DIGIT FOUR
010E60 - 𐹠 - RUMI DIGIT ONE
010E61 - 𐹡 - RUMI DIGIT TWO
010E62 - 𐹢 - RUMI DIGIT THREE
010E63 - 𐹣 - RUMI DIGIT FOUR
010E64 - 𐹤 - RUMI DIGIT FIVE
010E65 - 𐹥 - RUMI DIGIT SIX
010E66 - 𐹦 - RUMI DIGIT SEVEN
010E67 - 𐹧 - RUMI DIGIT EIGHT
010E68 - 𐹨 - RUMI DIGIT NINE
011052 - 𑁒 - BRAHMI NUMBER ONE
011053 - 𑁓 - BRAHMI NUMBER TWO
011054 - 𑁔 - BRAHMI NUMBER THREE
011055 - 𑁕 - BRAHMI NUMBER FOUR
011056 - 𑁖 - BRAHMI NUMBER FIVE
011057 - 𑁗 - BRAHMI NUMBER SIX
011058 - 𑁘 - BRAHMI NUMBER SEVEN
011059 - 𑁙 - BRAHMI NUMBER EIGHT
01105A - 𑁚 - BRAHMI NUMBER NINE
01F100 - 🄀 - DIGIT ZERO FULL STOP
01F101 - 🄁 - DIGIT ZERO COMMA
01F102 - 🄂 - DIGIT ONE COMMA
01F103 - 🄃 - DIGIT TWO COMMA
01F104 - 🄄 - DIGIT THREE COMMA
01F105 - 🄅 - DIGIT FOUR COMMA
01F106 - 🄆 - DIGIT FIVE COMMA
01F107 - 🄇 - DIGIT SIX COMMA
01F108 - 🄈 - DIGIT SEVEN COMMA
01F109 - 🄉 - DIGIT EIGHT COMMA
01F10A - 🄊 - DIGIT NINE COMMA
Alguns foram mostrados como ?
por não serem suportados no meu terminal.
Claro que na grande maioria dos casos será pouco provável que o usuário digite algum dos caracteres acima. Mas se qualquer coisa pode ser digitada (pois input()
aceita qualquer caractere Unicode), então o programa deveria estar preparado para receber qualquer coisa.
Neste caso, o mais garantido é simplesmente tentar converter direto para int
e capturar o erro:
try:
# já tenta converter para int
menuOption = int(input(">>> "))
# se chegou aqui, é porque a conversão deu certo, então prossegue
if menuOption == 0:
print(msgBreak) #mensagem para finalizar
break
if menuOption < len(options) + 1:
action = options[menuOption - 1][1]()
print(action)
except ValueError: # se deu erro, mostra mensagem
print(msgInvalidOption)
Outra vantagem é que agora eu só faço a conversão para int
apenas uma vez, logo após a leitura (no seu código vc faz int(menuOption)
várias vezes, sendo que poderia fazer apenas uma vez antes de começar a usar o valor).
Outra solução é usar isdecimal()
no lugar de isdigit()
, já que todos os caracteres para os quais isdecimal()
retorna True
podem ser convertidos para int
. Mas eu ainda faria a conversão para int
apenas uma vez:
menuOption = input(">>> ")
if menuOption.isdecimal():
menuOption = int(menuOption) # converte para int apenas uma vez
if menuOption == 0:
print(msgBreak) #mensagem para finalizar
break
if menuOption < len(options) + 1:
action = options[menuOption - 1][1]()
print(action)
else:
print(msgInvalidOption)
Para entender melhor essa história de isdigit
e int
nem sempre estarem "sincronizados", leia aqui.
O fato de ser pouco provável é o maior problema. Porque passa a ideia que está certo, quando apenas "funciona". E funciona porque alguém não digitou o que dá problema. E o teste básico não pega o erro, e faz a pessoas terem a crença que está bom.
Farei algo que muitos pedem para aprender a programar corretamente, gratuitamente. Para saber quando, me segue nas suas plataformas preferidas. Quase não as uso, não terá infindas notificações (links aqui).
Obrigado pela explicação @kht, vou tentar melhora essa parte. Entendi perfeitamente, não tinha esse conhecimento. Muito obrigado 🤓👍🏼