4
\$\begingroup\$

I wrote this dice game as beginner practice. This is working code, but I would like to improve it by adding more functions. Though, since I am still a beginner, I don't know how, so help would be appreciated!

import random

print('Time to go gambling! Press ctrl + enter, or RUN (the big red button), to roll!')
dice = random.randint (1,20)
print(str(dice))
count = 1
while dice != 20:
  dice = random.randint (1,20)
  print(str(dice))
  count +=1
if count == 1:
  print('It took you ' + str(count) + ' try to get a 20... average.')
else:
  print('It took you ' + str(count) + ' tries to get a 20... embarrassing.')
New contributor
cyan is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
\$\endgroup\$
3
  • \$\begingroup\$ For some reason, every time I try to say hello on the first line of my question, it deletes it... \$\endgroup\$ Commented yesterday
  • 2
    \$\begingroup\$ There is no need to say "hello", and that text would be edited out anyway. \$\endgroup\$ Commented yesterday
  • 8
    \$\begingroup\$ "I would like to improve it by adding more functions. ..., I don't know how" please can you clarify if you're asking how to improve the existing code, or are you asking for ideas on what next to do? \$\endgroup\$ Commented yesterday

5 Answers 5

8
\$\begingroup\$

First Impressions

You print out a message, 'Time to go gambling! Press ctrl + enter, or RUN (the big red button), to roll!', but the program does not wait for any user input (and there is no RUN button). This is a bit disconcerting. If these are features that you plan on adding later, then your code might comment on that. But it should not be putting this message out prematurely.

It is also not clear at this stage of coding what the actual game you are playing is and how it would work with a user. If you are looking for suggestions for what you should be adding to this code, we need to know a but more about the game.

Read the PEP 8 – Style Guide for Python Code

You should familiarize yourself with this guide, particularly the following areas:

  1. Comments
  2. Docstrings
  3. Indentation

Coding Suggestions

You have print(str(dice). This can be just print(dice) since print will automatically convert each argument to its string representation before outputting the value.

When count is 1, the print statement should be:

print('It took you 1 try to get a 20... average.')

In all other cases you should have:

print('It took you', count, tries to get a 20... embarrassing.')

print will by default output each argument separated by a space. That is, doing your own string concatenation is completely unnecessary. You could also use an f-string:

print(f'It took you {count} tries to get a 20... embarrassing')
\$\endgroup\$
3
  • 1
    \$\begingroup\$ I was using OneCompiler which has a red button titled "RUN". \$\endgroup\$ Commented yesterday
  • 1
    \$\begingroup\$ So is that simply to start the script or for some other purpose? If it's to start the script the print statement will be executing only after you press the red button, so there is no point printing that message. \$\endgroup\$ Commented yesterday
  • \$\begingroup\$ No, the program automatically runs once the tab opens. So, the user sees the instruction. \$\endgroup\$ Commented 16 hours ago
8
\$\begingroup\$

I would be inclined to make a function which acts as a generator to toss dice.

def toss_dice():
    while True:
        yield random.randint(1, 20)

We can now get our tossed dice until we roll a 20. It would also be an improvement to create a function to run a game, and then to ensure that function is only run if we're actually executing the file as a program, rather than importing it into another program.

import random

def toss_dice():
    while True:
        yield random.randint(1, 20)

def play_dice_game():
    count = 0
    
    for roll in toss_dice():
        print(f'{roll}')
        count += 1

        if roll == 20:
            break

    if count == 1:
        print(f'It took you 1 try to get a 20... average.')
    else:
        print(f'It took you {count} tries to get a 20... embarrassing')  

if __name__ == '__main__':
    play_dice_game() 
\$\endgroup\$
1
  • 1
    \$\begingroup\$ For a more advanced programmer, the generator could allow us to enumerate() the die rolls, and eliminate the need for separate counting. \$\endgroup\$ Commented 17 hours ago
6
\$\begingroup\$

UX

When I run the code, I see this message printed first:

... Press ctrl + enter, or RUN (the big red button), to roll!

The message seems to indicate that I need to take action for the code to do something, but the code just runs automatically to completion. That is confusing to me. I think you should change or delete that message.

It can be replaced to show what the remaining output signifies (rolls of the dice).

Layout

The code uses 2-space indent, but it is easier to read and understand using the more common 4-space indentation. The black program can be used to automatically indent the code for you. It will also adjust whitespace around operators according to norms.

You should also add blank lines to separate sections of code. For example, add a blank line before and after the while loop.

Documentation

The PEP 8 style guide recommends adding docstring at the top of the code to summarize its purpose. For example:

"""
Dice roll game.

Add more details here...
"""

Simpler

This code:

print('It took you ' + str(count) + ' try to get a 20... average.')

is simpler using an f-string:

print(f'It took you {count} try to get a 20... average.')

You can change "try" to "tries" for improved grammar. You can also change the code to account for the case of one try.

Magic number

The number "20" is used in several places. You should assign it to a constant which can be used everywhere. The PEP 8 style guide recommends upper case for constant names:

MAX_VAL = 20

//...

dice = random.randint (1, MAX_VAL)

This also make the code more scalable to other maximum values.

\$\endgroup\$
0
\$\begingroup\$

Place for questions and studies

It’s good that you came to the Stack Exchange, even if you are an beginner. It will help you learn more about Python, and any other programming languages you want. It can be difficult at first, but keep looking for more information and you will get better over time. Look also at Stack Overflow, which is for codes with errors.

Another version of the code with explanations.

This is a version of your program with explanations about functions and details that are basic and you can learn, so read it slow, don't rush.

program_run = True
#Dont put 1-letter or 1-word names on variables,
#it will be harder to remenber what
# it does on the code.
#and use "_" between words,
try:
    #You use this function when knows this part
    # can raise an Exception, so you can try fix.
    #if you use an "try:", you need to use an "except:".
    import random
except ImportError:
    #There are many python defalt Exceptions, like:
    # ImportError, ValueError, OverflowError, and many others.
    print("Nescessary module(s) not found.\nNeeds: random.")
    program_run = False
    #This is something you can make, so if someone tries to run this code,
    # but doesn't have the nescessary modules,
    # the program dont sudenlly crash, and tells what modules it needs to run.

#allways try to make the functions up in the code, under the modules imported.
def dice_game_code(Dice_faces: int) -> int:
    #When creating an function, it's good you make like this:
    #   1. Name your function with an good explainer name.

    #   2. When putting an Parameter (Like the Dice_faces),
    #   its good to write the Type that this parameter
    #   needs to be. In this example, Dice_faces
    #   needs to be an integer.

    #   3. After the end of the () add an "-> 'return type'",
    #   telling the type of information this function returns.
    #   if it returns nothing:
    #   put "None"

    #   4. Right under, but into, the function, add an Docstring:
    #   This is an comment text explaining the Parameters, what returns,
    #   and what this function do.
    #   You can make this using """..."""
    """Code for the dice game.
    It runs till the dice is the same as the Dice_faces,
    wich is the max value it can get.

    Dice_faces: It's the total number of faces (in int Type) of the dice.

    Return: Returns the number of attempts needed to reach max value (in int Type)."""
    attempt = 0
    while True:
        dice = random.randint(1, Dice_faces)
        attempt += 1
        if dice == Dice_faces:
            #The "return" function is used on User functions to:
            #   1. To exit the function with value "None", when the
            #   "return" is alone.
            #   2. To exit the function with some information
            #   from inside the function. Like this example:
            return attempt
        print(f"{attempt}º attempt: {dice}")
if __name__ == "__main__":
    #This is an barrier that only alloys pass
    #when the actual program is running.
    #because, if you imports the dice_game_code()
    #to an different code, the entire program is read an ran.
    #but with this, only what is outside this indentation is read.
    if program_run:
        #Since the "program_run" has an boolean information,
        # the actuall variable is an boolean test.
        start_choice = input('Time to go gambling!\nPress [S]tart or [Q]uit!\n> ').lower().strip()
        #".lower()",  ".strip()", and ".upper()"
        # are some methods that you can use on strings, to:
        # 1. make all string lower-case
        # 2. removes characters in the string
        # (if let blank, it only removes all spaces in string)
        # 3. make all string upper-case
        if start_choice == "s":
            while True:
                #The dice_game_code() returns an value that i need outside,
                # so, to get this value, i need to put it into an variable.
                attempt = dice_game_code(20)
                # since i have put an Parameter on the function,
                # i need to give the information it needs to run.
                # otherwise it will raise an exception.
                end_text = "average." if attempt <= 5 else "embarrassing."
                #you can put If...else statements into variables and lists
                #to change then by the enviroment or set an rule to then.
                replay_choice = input(f"""It took you {attempt} attempt(s) to get 20... {end_text}
                \nWants to try again? (Y/N)\n> """).upper().strip()
                if replay_choice == "Y":
                    continue
                break
        print("\nBye!\n")

You can copy and paste this code to see it working.

here is the code with no comments, so its better to read the actual code:

program_run = True
try:
    import random
except ImportError:
    print("Nescessary module(s) not found.\nNeeds: random.")
    program_run = False
def dice_game_code(Dice_faces: int) -> int:
    """Code for the dice game.
    It runs till the dice is the same as the Dice_faces,
    wich is the max value it can get

    Dice_faces: It's the total number of faces (in int Type) of the dice.

    Return: Returns the number of attempts needed to reach max value (in int Type)."""
    attempt = 0
    while True:
        dice = random.randint(1, Dice_faces)
        attempt += 1
        if dice == Dice_faces:
            return attempt
        print(f"{attempt}º attempt: {dice}")
if __name__ == "__main__":
    if program_run:
        start_choice = input('Time to go gambling!\nPress [S]tart or [Q]uit!\n> ').lower().strip()
        if start_choice == "s":
            while True:
                attempt = dice_game_code(20)
                end_text = "average." if attempt <= 5 else "embarrassing."
                replay_choice = input(f"""It took you {attempt} attempt(s) to get 20... {end_text}
                \nWants to try again? (Y/N)\n> """).upper().strip()
                if replay_choice == "Y":
                    continue
                break
    print("\nBye!\n")
\$\endgroup\$
5
  • 2
    \$\begingroup\$ random is a built-in library, so why would import fail? The lib exists even in MicroPython. \$\endgroup\$ Commented 10 hours ago
  • 1
    \$\begingroup\$ Use of whitespace/newlines in this code is rather suspect. \$\endgroup\$ Commented 10 hours ago
  • \$\begingroup\$ @Chris All the "\n" are just to look a little better on the Comand Prompt, since it doesn't have an GUI. \$\endgroup\$ Commented 10 hours ago
  • 1
    \$\begingroup\$ @Unknown, not in the string literals, though you could use multi-line string literals, but rather in the code itself. \$\endgroup\$ Commented 10 hours ago
  • \$\begingroup\$ If you are going to handle random not being imported, wouldn't it make more sense to exit the program there rather than set a flag that has to be checked later to prevent the rest of the program from being executed? \$\endgroup\$ Commented 8 hours ago
0
\$\begingroup\$

Avoid repeating logic with better defaults

Instead of these three lines:

dice = random.randint (1,20)
print(str(dice))
count = 1

You can just initialize dice to 0 and count to 0 and let the while loop do the job for you.

Friendly messages

if count == 1:
  print('It took you ' + str(count) + ' try to get a 20... average.')
else:
  print('It took you ' + str(count) + ' tries to get a 20... embarrassing.')

Is it really that embarrassing to use two or more tries to get a 20 ? I think not. I would print the "average" message if there's around 18-22 tries, and possibly "embarrassing" if it takes more than that. But if so also include an "impressive!" message if it takes fewer tries than expected. Perhaps an idea for what to do next for you, to add a bunch of different "rating" strings (and do it in a clean way, of course!). You could even introduce something funny like checking if it's an odd number of tries and say "that's odd".

I would still argue against putting "embarrassing" in text facing the user, especially when it's not anything the user has control over.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.