I'm just getting started with python and have run into a bit of trouble

Recommended Posts

I've begun to focus more on learning programming, rather than learning enough programming to attempt some of my projects.

step 1. learn to code in python and unity

step 2. build some small games implementing or at least attempting to iterate my ideas.

step 3. get better at coding

step 4. start building prototypes of my bigger ideas and producing practice prototypes - various website ideas including a robot game engine and space simulation social network, a 3rd person shooter mixed with a streets of rage-style platform beatemup structure to build an action-adventure game based on a story I'm writing, various other ideas.

step 5. get better at coding...

I am discovering the define method.

I have a problem with my program:

"I'm trying to figure out def methods: My program is not working."

#this is the start of my program:

def game():
    again = ""
    buy = ""
    wallet = 30
    attributes = {"Dexterity": 30, "Wisdom":30, "Health":30, "Strength":30}
def start ():
        print (attributes)
        while again != "n":
            if attributes == "":
                print("goodbye!")
            else: #program continues on for awhile, cut off here for brevity


#this is the end of my program
elif choice == 4:
                        #sell an attribute
                            sellAll = input ("which attribute would you like to sell all of?:")
                            if sellAll in attributes:
                                wallet += attributes[sellAll]
                                del attributes[sellAll]
                                print ("You have ", wallet, " dollars left"); print (attributes)
                            else: print ("that is not a legit attribute!")
                            again = input ("play again y/n")
                            if again == "y": start ()
                            if wallet <= 0: print ("you can't play anymore"); break

replay = input("Are you tough enough to play? y/n")
if replay == "y": game(), start ()
 

 

I clearly am trying to use define method when I don't fully understand how it works.

Originally the game worked, when I just used one define method - "def game ()"

But I started trying to use two to solve the problem that the game wasn't returning to the start of the program within the loop.

That's when I ran into problems.

Share this post


Link to post
Share on other sites

Hi. With Python the manual that comes with it is your best friend. There is a Python Tutorial in it.

# A define does a thing, it's a function
def SayHallo():
    print("hello") #This prints hello

def DoMath(InA,InB):
    print(InA + InB) #This prints the sum


#To use our code we just call it outside our function
SayHallo()
print("<--->" *8)
#We can reuse a function as much as we want
DoMath(5,10)
DoMath(15,70)
print("<--->" *8)
#Normally Enumerations are used for storing data. Python uses lists.
#There is no need to use dic for stats. You can just use vectors although dict are easier to use in the lng run
Stats =  {("Dexterity", 30),("Wisdom", 30), ("Health", 30), ("Strength", 30)}
for StatName, StatValue in Stats:
    print("Stats: "+ StatName + " = " + str(StatValue))


#Classes are used for complex objects
class Player():
    #This def is special as calling it allows us to define self
    #It is also a constructor
    def __init__(self, InPlayerName):
        #Defining The stat like this makes it easy to call
        self.Health = 30
        self.Name   = InPlayerName
        #Defining as list allows for call by name
        self.Stats  = {"Dexterity": 30,"Wisdom": 30, "Strength": 30}

    def PlayerTakeDamage(self,InAmount): #Because of init we need to add self to use 
        self.Health -= InAmount

    def GetWisdom(self):
            return self.Stats["Wisdom"]


Player1 = Player("Bob") # Things after the self in init are needed for construct
Player2 = Player("Piet")# These are instances that means they are copies
print("##"*16)
print(Player1.Name + "'s Health is " + str(Player1.Health)+ " and his wizdom is "
      + str(Player1.GetWisdom()))

#Also print player 2
print(Player2.Name + "'s Health is " + str(Player2.Health)+ " and his wizdom is "
      + str(Player2.GetWisdom()))
print("##"*16)

#We let the player take damage
Player1.PlayerTakeDamage(25)
#Print to see the change
print(Player1.Name + "'s Health is " + str(Player1.Health)+ " and his wizdom is "
      + str(Player1.GetWisdom()))

#Also print player 2
print(Player2.Name + "'s Health is " + str(Player2.Health)+ " and his wizdom is "
      + str(Player2.GetWisdom()))

I hope this helps. If not I will solve it for you however it looks like you want to do it on your own first.

Edited by Scouting Ninja

Share this post


Link to post
Share on other sites

wow that's really useful, thanks! I think i can have a go at getting my program working from here.

 

so am I getting closer?

how is my indentation? Do I need indentation or is there an alternative?

 

#program start

def stats():
    again = ""
    buy = ""
    wallet = 30
    attributes = {"Dexterity": 30, "Wisdom":30, "Health":30, "Strength":30}

def UI ():
    print (attributes)
    while again != "n":
        if attributes == "":
            print("goodbye!")
        else:
            choice = int(input("1 = exit \n 2 = spend money on attributes \n for your character. \n 3 = sell an attribute. \n 4 = sell off an entire attribute. \n Choose a number from 1-4:"))
            choices = {1, 2, 3, 4}
            while choice in choices:
                if choice == 1:
                    print ("Goodbye")
                    input ("press a key")
                elif choice == 2:
                #spend coin
                    buy = input ("what would you like to spend money on?:")
                    if buy in attributes:
                        attributes[buy] += 5
                        wallet -= 5
                        print ("You have ", wallet, " dollars left"); print (attributes)
                    else: print ("that is not a legit attribute!")
                    again = input ("play again y/n")
                    if again == "y": UI ()
                    if wallet <= 0: print ("you can't play anymore"); break

#end of program

replay = input("Are you tough enough to play? y/n")
if replay == "y": stats(), UI ()

I think if I want to get this right, the best way would to be to code out a whole adventure scenario and break it down into pseudocode blocks for each element eg  buying weapons, taking damage, entering the tavern. instead of trying to do the whole scenario in one or two define statements. It would be an interesting challenge, that would get me closer to making a game, might try this tomorrow.

Edited by WinterDragon

Share this post


Link to post
Share on other sites
3 hours ago, WinterDragon said:

so am I getting closer?

how is my indentation? Do I need indentation or is there an alternative?

Yep, you're getting closer :)

Indentation looks fine (4 spaces is recommended). I'd refrain from putting things after a colon, ie

if replay == "y":
    stats()
    UI()

instead of

if replay == "y": stats(), UI ()

Note: If you use the "<>" thing in the edit-bar, you get these code blocks, which preserve your indents better. (Copy code, press "<>", paste code in box, select "python" bottom right, press "insert" bottom left.)

The "," in your line is actually an error too, don't try to do more than one thing at a line, Python works best doing 1 thing at 1 line. (This holds for your multi-print lines too.)

 

When I run the program I get

$ python3 program.py
Are you tough enough to play? y/ny
Traceback (most recent call last):
  File "program.py", line 36, in <module>
    if replay == "y": stats(), UI ()
  File "program.py", line 10, in UI
    print (attributes)
NameError: name 'attributes' is not defined

The reason for this is that functions have local variables. See the following example:

def f():
  # Here x doesn't exist yet

  x = 1 # Construct 'x', and give it a value

  print(x) # x still exists as long as we are in function f


# Here we are outside f, and x doesn't exist

f() # Call the function, inside f, x exists for a while, but it disappears again when it returns here

print(x)  # Will give an error, as x only exists within function f.

How to do this instead? The standard solution is to return values to the caller, and store them in variables. The variables are then passed on to the next function:

 

def stats():
    again = ""
    buy = ""
    wallet = 30
    attributes = {"Dexterity": 30, "Wisdom":30, "Health":30, "Strength":30}

    return again, buy, wallet, attributes

def UI(again, buy, wallet, attributes):
  # Omitting all the other code


replay = input("Are you tough enough to play? y/n")
if replay == "y":
    again, buy, wallet, attributes = stats()
    UI(again, buy, wallet, attributes) 

I added a "return" statement at the end of "stats", which returns the 4 values that you create.

At the bottom of the file, I catch these values into variables, with "again, buy, wallet, attributes = stats()" so the main program gets the values. It then passes them on to the other function.

Other random things I noticed:

lines = ("1 = exit\n" +
         "2 = spend money on attributes\n" +
         "    for your character.\n" +
         "3 = sell an attribute.\n" +
         "4 = sell off an entire attribute.\n" +
         "Choose a number from 1-4:")
choice = int(input(lines))

The "input" line is long, you can break it into smaller pieces by first constructing the string as a separate statement, before asking for input. In my code, I spend 6 lines on making the menu, nicely putting each line under each other, so it's easy to see what it prints. Don't forget the parentheses here, or Python gets confused on missing values behind the "+".

Finally, you don't need to call the UI function, like you do:

while again != "n":
    # ...
    while choice in choices:
        # ...
        again = input ("play again y/n")
        if again == "y": UI ()

Instead, let the top-while handle that:

while again != "n":
    # ...
    while choice in choices:
        # ...
        again = input ("play again y/n")
        break # Break out of the "while choice in choices", so it jumps to the "while again != "n" statement, and loops back to the input.

 

Edited by Alberth

Share this post


Link to post
Share on other sites

wow you guys are great! thanks! I'm learning alot, I think I'm actually learning faster by asking for help than I have been just trying to crunch with the books by myself.

 

by the way I downloaded py2exe but it won't load it says there is a dll file missing, did I put it in the wrong place or is it just a faulty file that I downloaded or the wrong file - it may be the wrong file as my pc is a 64bit os and I accidentally downloaded the 32bit version, I don't know if that's why it won't work?

Edited by WinterDragon

Share this post


Link to post
Share on other sites
2 hours ago, WinterDragon said:

the 32bit version, I don't know if that's why it won't work?

Should still work. Chances are you have a dependency missing. Can you name the missing file?

Your code is making good progress. When creating a new mechanic you should attempt it on it's own first and then add it into your game.

So for example the buy and sell part, see if you can get it to work outside of the game first.

 

Share this post


Link to post
Share on other sites

MSVCR71.dll is the missing file. And thanks, yea I'll do that. I've got a bit of an idea of the different elements of the adventure game, so I'll have a go at writing, planning and coding them as separate programs before putting them together as a game.

Share this post


Link to post
Share on other sites

still not working...

I may have to hit the books again, or maybe you can explain what I've done and why it doesn't work?

def stats():
    again = ""
    buy = ""
    wallet = 30
    attributes = {"Dexterity": 30, "Wisdom":30, "Health":30, "Strength":30}

    return again, buy, wallet, attributes

def UI(again, buy, wallet, attributes):
    replay = input("Are you tough enough to play? y/n")
    again, buy, wallet, attributes = stats()
    while again != "n":
        print (attributes)
        print("1 = exit \n 2 = spend money on attributes \n for your character. \n 3 = sell an attribute. \n 4 = sell off an entire attribute. \n Choose a number from 1-4:")
        choices = {1, 2, 3, 4}
        choice = int(input ("what would you like to do?:"))
        if attributes == "":
            print("goodbye")
        else:
            while choice in choices:
                if choice == 1:
                    print ("Goodbye")
                    input ("press a key")
                elif choice == 2:  #etc...

Share this post


Link to post
Share on other sites

Having us debug your code doesn't scale very well, code gets too long, and we have huge problems understanding what "it" means in "it doesn't work", since we don't know what the intended functionality is. Last but not least, this is something you should be able to figure out, debugging a problem is a part of programming.

Please expand a report with a description of what is wrong. If it throws an error, show the error. If it lists line numbers, indicate what line it is. If it is not a crash, explain how it doesn't do what you expect, so we get a glimpse of intended behavior. (A program only gives real behavior, and since you have a problem with it, that is not the same as intended behavior, but only you know the latter.)

In this case, I can't do much, code looks ok at first sight, except for the last line, where it misses at least one line of code. Since it's incomplete, I can't run it, and you haven't supplied an error description at all, so I don't have a starting point.

 

As in a lesson about debugging, what do you make from the error message? What do you think the problem is? What have you tried?

 

 

Share this post


Link to post
Share on other sites

it (the program) focuses alot on indentation, so I've been fixing that alot. man I miss line numbers. But anyway, I'm trying to take some of your advice and not rely so heavily on having the whole thing be under def methods, using while loops more, but I think I may need to go back to the book about the correct way to use while loops and define functions/methods? the problem I keep having is defining stats, then defining user interface, which seems to work, then I have the core of the program (which won't run because I haven't done the define and use method properly) - which is the if elif - choices and resource trading which are both in the same section and I need them both to work at the moment either they both work but don't loop properly ie the program runs but the loop doesn't go back to choices only lets you reenter your resource trading choice within the selected choice (ie 1, 2, 3, 4, 5) or I get error messages.

 

error message: >>> t
Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    t
NameError: name 't' is not defined

 

the error I'm struggling with is it doesn't print anything on the screen when the program starts.

Edited by WinterDragon

Share this post


Link to post
Share on other sites
10 hours ago, WinterDragon said:

it (the program) focuses alot on indentation, so I've been fixing that alot.

It does indeed, I don't know how your editor reacts on TABs, but if they don't automagically expand to spaces, getting indentation right is complicated. Find a better editor if this is the case.

 

10 hours ago, WinterDragon said:

man I miss line numbers.

I don't know what text editor you use, but if the current one doesn't work for you, find a different one. I am not using Windows, but I heard Notepad++ to be nice, no doubt there are others too.

 

10 hours ago, WinterDragon said:

I may need to go back to the book about the correct way to use while loops and define functions/methods?

These things are independent of each other. A while loop repeats its inner body until the condition at the top becomes False, or you execute the "break" statement in that body.

A function definition gives a sequence of statements (a body) a name, so you can call (use) it from anywhere by saying the same name again. You leave a function body either by reaching the end of the body or by executing the "return" statement.

The problem of how to divide your code between different functions is not always clear, but there are general guide lines. A function definition should not be too long (a number is hard to give, but let's say 50-70 lines is usually a good maximum), and it should be mostly independent (so you don't have a zillion variables going in through the parameter list, and a zillion out through the return statement).

Functions work best if you need the same code at several places. You can then simply call that code by the name of the function instead of doing a verbatim copy of the code (which is pretty much deadly if you ever need to change the code).

10 hours ago, WinterDragon said:

the error I'm struggling with is it doesn't print anything on the screen when the program starts.

Maybe you only have "def" things, and no main code? ie

def myfunc():
  print("Hello!")
  other_func("world")
 
def other_func(w):
  print(w)

While this looks complete, there is no "myfunc()" call at the bottom, so it never starts.

 

 

EDIT: Maybe make a very small example, with 2 choices (1 is also possible, but a bit silly), and you can only buy 1 thing or so (or just print("buy thing") instead of the administration of actually buying anything). Having a small example is easier to understand and to discuss if you don't find the answer.

Edited by Alberth
added suggestion

Share this post


Link to post
Share on other sites

pretty stoked that I got a 106 IQ (proficient - middle range) score in python on pluralsight, considering I'm just starting and think of myself as a beginner.

The ranges are novice, proficient, expert.

I expected to get a novice but compared to my peers I'm middle range. Which motivates me even more to keep going with python, I've also decided to get started with unity and eventually learn c++ for unreal engine.

I know these goals are quite mountainous considering how much trouble I seem to be having so early on in the game.

But I have overcome greater obstacles in the past, I think my goals are realistic and I'm optimistic. I also don't consider myself a coder yet, only a designer. If I can get to expert level IQ and finish a game (even a reverse engineered platform or arcade game) then I will be able to say I'm a coder, not simply that I'm learning to code.

Thanks Alberth for your feedback that is all very helpful. I have a better understanding of what I'm doing now.

Okay I'll have a go at reusing some of my code to build a smaller program. And then refine it so it works and works well.

 

btw I use Idle because it came with python.

Edited by WinterDragon

Share this post


Link to post
Share on other sites
On 9/26/2017 at 12:48 AM, WinterDragon said:

btw I use Idle because it came with python.

No problem with this. It just doesn't have any tools build in. In fact for beginning this is better because it forces you to double check your code.

Good to here your still at it. Text adventure games are the basics of all games, so learning this will help you understand how all games work.

Share this post


Link to post
Share on other sites

okay so I've taken a break from my adventure game to study up on my fundamentals - been working my way through my first python book goal = 60pgs/wk by crunching down and working through 60pgs in one day, 1day/wk and any exercises and fixing bugs + asking questions, etc.

I got an assignment to create a fortune cookie simulator but I've only got a little bit of info about def methods. so I keep screwing them up. also I had to skip forward in the book (specifically from page 85 to page 356) to find out how to add a end_game feature which requires a  def method. Problem is the idle processor says there are no bugs but when I run it nothing happens. first thought of course was I haven't told it to do anything because one of my lines made it skip the rest. but I don't think that's what's happening, because I have 5 loops and rand.range calls 5 numbers from 0-4. so that checks out I think. any clues as to why it might not be doing anything? my instinct says the problem is in the end_game method itself.

 

import random

def end_game(self):
    end_message = games.Message(value = "game over",
                                size = 90,
                                color = color.red,
                                x = games.screen.width/2,
                                y = games.screen.height/2,
                                lifetime = 5 * games.screen.fps,
                                after_death = games.screen.quit)
    games.screen.add(end_message)
    
def game():
    nmCookie = random.randrange(5)
    begin = input ("cookie time, open your fortune cookie")
    if nmCookie < 1:
        print ("you are going to die someday")
        againPlay = input ("Still hungry")
        if againPlay != "Y" or "y":
            end_game()
        game()
        
    elif nmCookie == 1:
        print ("you just ate a cookie")
        againPlay = input ("Still hungry")
        if againPlay != "Y" or "y":
            end_game()
        game()

    elif nmCookie == 2:
        print ("you are going to eat another cookie")
        againPlay = input ("Still hungry")
        if againPlay != "Y" or "y":
            end_game()
        game()
        
    elif nmCookie == 3:
        print ("you like cookies")
        againPlay = input ("Still hungry")
        if againPlay != "Y" or "y":
            end_game()
        game()
        
    elif nmCookie == 4:
        print ("you will have a gargantuan legacy")
        againPlay = input ("Still hungry")
        if againPlay != "Y" or "y":
            end_game()
        game()
    else: end_game()
    

#added call game

game ()

edit: solved it - forgot to call "game"

 

#now it's telling me random not defined, but the book didn't tell me I needed to define random, am I missing something?

Edited by WinterDragon
doh yes it did - solved 2nd problem

Share this post


Link to post
Share on other sites

I got the game to work after a few edits:

but I still can't break out of the game.

break initiates the error message "break outside loop"

import random
	
def end_game():
    end_message = ("game over")
    print (end_message)
    
    
    
def game():
    nmCookie = random.randrange(5)
    begin = input ("cookie time, open your fortune cookie")
    if nmCookie < 1:
        print ("you are going to die someday")
        againPlay = input ("Still hungry")
        if againPlay != "Y" or againPLay != "y":
            end_game()
        game()
        
    elif nmCookie == 1:
        print ("you just ate a cookie")
        againPlay = input ("Still hungry")
        if againPlay != "Y" or againPLay != "y":
            end_game()
        game()
	    elif nmCookie == 2:
        print ("you are going to eat another cookie")
        againPlay = input ("Still hungry")
        if againPlay != "Y" or againPLay != "y":
            end_game()
        game()
        
    elif nmCookie == 3:
        print ("you like cookies")
        againPlay = input ("Still hungry")
        if againPlay != "Y" or againPLay != "y":
            end_game()
        game()
        
    elif nmCookie == 4:
        print ("you will have a gargantuan legacy")
        againPlay = input ("Still hungry")
        if againPlay != "Y" or againPLay != "y":
            end_game()
        game()
    else: end_game()
    
            
game()
	


 

Share this post


Link to post
Share on other sites

What break are you talking about?

You can't break out of functions, you can only break out of loops. If you want to 'break' out of a function, you can use a return statement. LIke this:

if againPlay != "Y" or againPLay != "y":
	end_game()
	return
game()

The return statement stops the execution of the function and returns a value. But in this case, we don't want to return any value, just stop the execution.

This will achieve the same result as writing:

if againPlay != "Y" or againPLay != "y":
	end_game()
else:
	game()

The problem with your code is that 'end_game' (whatever the name might say) isn't really ending the game or 'breaking' out of the code. You are still calling the game() function again. If you get confused then it's a good practice usually to use names that better describe the function. LIke, in this case, 'printEndMessage' or 'endGameMessage', for example.

Share this post


Link to post
Share on other sites

It's normal to use a while loop for this:

#So while the GameRun is true it keeps playing the game but when it's false the game stops
def while(GameRun == True):
  GameHere();
  GameRun = False;

 

Attached is a game I made as practice. I stopped when I got to the boring part and never finished it.

AdventureGame.py

The game loop is at the bottom and looks like this:

#This is the game loop
def GameLoop(InPlayer):
    while(InPlayer.GameRun == True):
        InPlayer.PlayerPromt()
        print("#"*5)

It takes a prompt from the player and if it's "Q" the game quits.

Take a look at the python file, it shows a basic structure for a game.

 

Edit: Double clicking the file should run it.

Edited by Scouting Ninja

Share this post


Link to post
Share on other sites

yea thanks that's all really helpful. I haven't actually got upto GUIs yet. so I guess there will be more about that when I do.

 

I just ran the game, I'll have a look at the code now and it will give me more insight.

Edited by WinterDragon
viewing code

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now