I made a guess the number game in Python I just started programming a week ago. Online tutorials aren't my thing, so I decided to just start projects and learn what I need for the project.

My first project is a guess the number game. The user is asked to guess a number between 0 and 20. If the user's guess is too high, they will be told it's high and likewise if it's too low. This will go on until the user guesses correctly.


print("Enter a random number between 0 and 20")
userInput = int(input())
random_number= random.randint(0,20)

def random_num_checker(num,guess):
    if num== guess:
        print('CORRECT')
    else:
        while guess != num:
            if guess &gt; 20:
                print('I said between 0 and 20')
            if guess &lt; num:
                print('too small')
            elif guess &gt; num:
                print('too big')
            guess=int(input())
        print('CORRECT')
random_num_checker(random_number,userInput)
Aside from the notes already given, here are two big ideas to think about:

Don't repeat yourself (DRY)

This is something you'll hear repeated a lot in discussions of code.  Any time you see the same "magic values" repeated more than one place (e.g. 0 and 20), or you see two lines of code that do exactly the same thing for exactly the same reason (e.g. your input() statements or the multiple CORRECT checks) it's a clue that you have an opportunity to share some code.

In the case of the magic numbers, one solution is to define them as constants at the top of the file.  The approach I'd prefer, personally, would be to make them parameters -- rather than hardcoding 0 and 20, have your function(s) take a range as a parameter.

In the case of the multiple "CORRECT" checks, this is just a matter of restructuring the loop a little.

Have each function do one thing well

This is significantly more subjective, but in looking at your function, I see two very separable things it's doing within its single main loop -- prompting the user for valid input, and giving them feedback on their guess.  If you have one piece of code that just has to get the input without having to worry about the game loop, and you have another that handles the game loop without having to worry about whether the input is valid, then both of them can be simpler.

When you start doing larger projects, breaking logic apart into simple functions makes it easier to test the individual units of your code independently.

I messed around with the code for a bit using those two principles and came up with this:

import random

def describe_range(numbers: range) -&gt; str:
    """Nice English-language description of a range."""
    return f"between {numbers[0]} and {numbers[-1]}"

def input_number(numbers: range) -&gt; int:
    """
    Prompt the user for a number within the range,
    retrying on invalid input.
    """
    while True:
        try:
            number = int(input())
            if not number in numbers:
                raise ValueError(f"The number needs to be {describe_range(numbers)}")
            return number
        except ValueError as e:
            print(e)

def guess_number(numbers: range) -&gt; None:
    """
    Play a guessing game with the user within a range of numbers.
    Tell them whether their guess is too big or too small.  
    They win when they get it right!
    """
    print("Enter a random number", describe_range(numbers))
    answer = random.choice(numbers)
    while True:
        guess = input_number(numbers)
        if guess &gt; answer:
            print("too big")
        elif guess &lt; answer:
            print("too small")
        else:
            print("CORRECT")
            break

if __name__ == "__main__":
    guess_number(range(21))


Note that I'm using Python 3's type annotations to say what type of argument each function takes and what it returns -- this is really handy because you can use the mypy tool to automatically check your code for errors (for example if you say a function returns an int and there's a line in that function that returns a str, mypy will throw an error), and therefore you don't need to worry as much about your code getting the wrong type at runtime.  The type annotations also serve as documentation for your functions so that human readers can easily see what sorts of values they should expect the code to be working with.