Console-based Guess the Number I started learning Python and wrote my first program. This is a console game based on guessing the number. Can you take a look and tell me if I'm doing it right or give me any advice? Here is the code: https://github.com/theriseq/GuessTheNumber

Is it a good way of doing this or can I simplify it?

Thank you.

main.py

from can_convert import check
import random

welcome_msg = """Welcome to GuessTheNumber Game!
I\'m thinking of a number between 1 and 100.
Can you guess this number?

[?] Type \'pass\' to exit game.
"""
print(welcome_msg)

number_to_guess = random.randrange(1, 101)
attemps = 0

while True:
    user_inp = str(input("Your choice: "))
    if user_inp != "pass":
        if check(user_inp):
            attemps += 1
            # print('is int')
            if int(user_inp) &lt; number_to_guess:
                print("Your guess is too small.")
            elif int(user_inp) &gt; number_to_guess:
                print("Your guess is too high.")
            else:
                print("Correct! You won the game!")
                print(f"Attemps: {attemps}")
                break
        else:
            print('Enter numbers only!')
    else:
        break


can_convert.py

def check(to_check):
    try:
        int(to_check)
        return True
    except ValueError:
        return False
Here is a list of found issues, in order of occurrence:


importing from your custom can_convert is fine. You should stick to modularization like that for bigger projects. However, here, it actually seems to be in the way of things. It checks if the string can be converted, but does not actually do any conversion. We later have to do the conversion again anyway. This can be combined.
Currently, the welcome message and actual random range can deviate. You already know what f-strings are, so they should be used to keep that in line.
Use randint to include both bounds, as opposed to randrange, which would stop one short of upper_bound, as you already noted.
input will already return a string, no need to convert via str.
By inverting the logic in checking for "pass", a whole block of indentation can be spared. Just check if user_inp == "pass" and break if True. All following code can be one level less indented, since no else statement is required.
Now for the main logic. The try block has moved here, away from the import. Notice that the logic is still the same. However, we assign to number immediately without checking first. If this fails, the except block is triggered.


Note that int("2.2") will also be a ValueError despite "2.2", to humans, clearly being a number. So the error message should specify whole numbers to be more precise.
The added else block is run if no exception was raised, so in the normal game.
number is now available, so no need to call int conversion repeatedly.


Keep try blocks short and concise and never leave an except statement bare. You did this fine! Lastly, try to not nest try/except blocks.
There was a typo for attempts.


import random

upper_bound = 100
lower_bound = 1

welcome_msg = f"""Welcome to GuessTheNumber Game!
I'm thinking of a number between {lower_bound} and {upper_bound}.
Can you guess this number?

[?] Type 'pass' to exit game.
"""
print(welcome_msg)

number_to_guess = random.randint(lower_bound, upper_bound)
attempts = 0

while True:
    user_inp = input("Your choice: ")
    if user_inp == "pass":
        break
    try:
        number = int(user_inp)
    except ValueError:
        print('Enter whole numbers only!')
    else:  # no exception occurred
        attempts += 1
        if number &lt; number_to_guess:
            print("Your guess is too small.")
        elif number &gt; number_to_guess:
            print("Your guess is too high.")
        else:
            print("Correct! You won the game!")
            print(f"Attempts: {attempts}")
            break