Python Forum
Feedback on my first program?
Thread Rating:
  • 1 Vote(s) - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Feedback on my first program?
#1
Hi. I've been using free online resources the past few days to learn Python and I was practicing what I had learned so far when I wrote this program, mainly focusing on functions though. There are many things I would do differently if I were to go back over it but this is what I came up with in probably an hour or so of creating my random idea. What am doing that I should do differently? Criticism is appreciated
I didn't use any sort of loops because I'm not that fluent yet and would've had to reference something and I just wanted to do what I could, plus I made it do what I wanted it to do without.
I also realize instead of using print then asking for input I could put input('text here').
import time
import random


gameList = ['Guess the Number','']

taskList = ['Play a Game?','Hear a joke?','Have your mind blown?']

#lightJoke = ['','','','','','']

darkJoke = ['What is red and bad for your teeth? A brick.']

mindBlow = ['The surface area of Russia is slightly larger than that of the surface area of Pluto.','Anne Frank and Martin Luther King Jr. were born in the same year.']




def wutNow():
    print('What would you like me to do now?')
    print(taskList)
    chosenTask = input().lower()
    if chosenTask == 'play a game' or chosenTask == 'game' or chosenTask == 'play':
        listGames()
    elif chosenTask == 'joke' or chosenTask == 'hear a joke' or chosenTask == 'hear' or chosenTask == 'tell jokes':
      tellJoke()
    elif chosenTask == 'have my mind blown' or chosenTask == 'mind blown' or chosenTask == 'have your mind blown':
        blowMind()


def intro():
                
    print('Nice to meet you ' + name + ',here is a list of things I can do.')
    thingsIcanDo = ['List Games','Tell Jokes','Blow your mind']
    print(thingsIcanDo)
    time.sleep(1)
    print('What would you like me to do?')
    choice = input().lower()
    
    if choice == 'game' or choice == 'play a game' or choice == 'play':
        print('Which game would you like to play?')
        print(gameList)
        chosenGame = input().lower()
        if chosenGame == 'guess' or chosenGame == 'guess the number':
            print("Great choice! Let's play!")
            guessGame()
    elif choice == 'tell a joke' or choice == 'tell' or choice == 'joke' or choice == 'hear a joke' or choice == 'tell jokes':
        tellJoke()
    elif choice == 'blow your mind' or choice == 'blow my mind' or choice == 'blow mind':
        blowMind()
    




#Function to list games and take fokn input
def listGames():
    print(gameList)
    print('Which game would you like to play ' + name + '?')
    gme = input().lower()
    
    if gme == 'guess the number' or gme == 'guess' or gme == 'number':
        guessGame()







def afterGame():
    print('Great game, would you like to play again?')
    answer = input().lower()
    
    if answer == 'y' or answer == 'yes':
        guessGame()
    elif answer == 'n' or answer == 'no':
        wutNow()


def tellJoke():
    print(random.choice(darkJoke))
    input()
    print('Would you like to hear another joke?')
    again = input()
    if again == 'y' or again == 'yes':
        tellJoke()
    else:
        wutNow()

def blowMind():
    print(random.choice(mindBlow))
    input()    
    print('Would you like to have your mind blown again?')
    mBlow = input().lower()
    if mBlow == 'y' or mBlow == 'yes':
        blowMind()
    else:
        wutNow()    
    
    

    


#Guessing game function
def guessGame():
    print('I am thinking of a number between 1 and 100 ' + name + '.')
    guesses = 0
    num = random.randint(1,100)
    
    for guesses in range(6):
        print('Take a guess.')
        guess = input()
        guess = int(guess)
       
       
        if guess < num:
            print('Too low!')
        if guess > num:
            print('Too high!')
        if guess == num:
       
        
            break
     
 
    if guess == num:
        guesses = str(guesses + 1)
        print('Great job! You guessed the number in '+ guesses + ' guesses.' )
        
    if guess != num:
        num = str(num)
        print('Nope! My number was ' + num + ',maybe next time!')
    afterGame()
    
print('Hello, my name is Monty, what is yours?')
name = input()
intro()
Reply
#2
My random thoughts (just nitpicking):

Naming of variables and functions. According to PEP-8: "Function names should be lowercase, with words separated by underscores as necessary to improve readability. Variable names follow the same convention as function names.". Therefore it would be nice to have variable game_list instead of gameList and function list_games instead of listGames.

if statements. You can do it also this way:

if chosen_task in ['play a game', 'game', 'play']:
However, you have used these choices two times. So it can make sense to have variable something like that:

play_choices = ['play a game', 'game', 'play']

if chosen_task in play_choices:
    # do something

if choice in play_choices:
    # do something
This way you can avoid typing mistakes which may occur if you type something two times and if you need to update choices you can do it in one place. I would have used loops too, but you mentioned that you didn't want to use them.

You mentioned yourself, that input can be done differently:

guess = int(input('Take a guess. ')
Just be beware, that if user enters something that cannot be converted into int your code crashes.

For readability purposes it could be an option to have intro() function as first (top-down style). You could name it main(), so it's clear where all the action is going on Smile
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#3
To add a small comment, you have many chains of if, elif, elif... without a final else.
This can do debugging your code really painful, as some function will silently do nothing.
In a set of if/elif conditions if the final option is something that you do not expect is a good idea to raise an error or at least inform the user:
    if answer in ('y', 'yes'):
        guessGame()
    elif answer in ('n', 'no'):
        wutNow()
    else:
        print(f'I do not understand {answer}. Please input yes or no')
If your real intention is to do nothing you can add a pass statement:
    if answer in ('y', 'yes'):
        guessGame()
    elif answer in ('n', 'no'):
        wutNow()
    else:
        # Ignore the user and continue with the program...
        pass
In this way is clear that your intention is to do nothing, not that you forgot a condition. Obviously this is important for nested if/elif. You can do the same for a normal if/else, but usually is not necessary.
Reply
#4
(Jun-12-2018, 06:35 AM)perfringo Wrote: My random thoughts (just nitpicking):

I really appreciate your random and informative thoughts, thank you!

(Jun-12-2018, 08:47 AM)killerrex Wrote: To add a small comment, you have many chains of if, elif, elif... without a final else.
This can do debugging your code really painful, as some function will silently do nothing.
Thank you very much for your input(), greatly appreciated!
Reply
#5
One afterthought as well Smile

You can go one step further. From lists I suggested previously to dictionary. Lists help get rid of long statements on if/elif rows. Using dictionary you can get rid of elif statements altogether. Following technique is useful when you want to run function based on allowed user inputs.

Instead of list you create dictionary like that:

execute = {
    **dict.fromkeys(['play a game', 'game', 'play'], list_games), 
    **dict.fromkeys(['joke', 'hear a joke', 'hear', 'tell jokes'], tell_jokes),
    **dict.fromkeys(['have my mind blown', 'mind blown', 'have your mind blown'], blow_mind)
    }
Now you have dictionary with key: value pairs where key is allowed user input and value is name of the function you want to run after receiving input. By having this data structure you can take advantage of How do I use strings to call functions/methods?

In function wutNow you can now do this way:

if chosen_task in execute.keys():
    execute[chosen_task]()
This will run function corresponding to user input, no need for additional elif statements.

NB - I used PEP-8 compliant variable/function names which differ from names in your code. You should make sure that function and variable names match if you want to try this.
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#6
(Jun-14-2018, 06:38 AM)perfringo Wrote: One afterthought as well Smile

Sorry for the late reply, but this is great advice, thank you! :)
Reply
#7
Hey,
I'm new to Python and programming so won't be of much help but for chosing the option, since you want to match keywords to the name of an option, why not try and use RE (Regular Expressions)? I've found them really useful in my own scripts.

Maybe with something along the lines of:
re.match(chosen_task, the_string_it_should_match) is not None:
    #do smth if anything matches
Couldn't help you further with RE since they're a dark spot for me too right now but if you type it into stackoverflow you'll get tons of handy examples.

One other thing that comes to my mind reading your code that I've been told numerous times to do, make your functions reusable. As beginners we often tend to want to cram a lot of things inside one function, we think it's better, faster... But seasoned programmers prefer having one-task functions that call other subfunctions, that makes them reusable in other bits of your code to do something else. I try to think of functions as bricks that shouldn't become entire walls. Of course it depends on the complexity of the program, if you're doing a top-notch thing maybe your "one-task" will be at least 10 functions calls and uses...

All the best, keep up learning!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  First program feedback xyzabc12310000 2 3,394 May-20-2018, 05:06 PM
Last Post: xyzabc12310000
  I need some feedback on this program tannishpage 3 3,086 Mar-22-2018, 05:31 AM
Last Post: tannishpage

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020