Jump to content

[PYCHARM]need help figuring out how to "send" a stat to be used in a different Def

ketchupspill
Go to solution Solved by colonel_mortis,

Pycharm is just a regular python editor, so for future reference you don't need to specify it.

 

The interesting part here is what you're doing in the code that calls those functions. At a guess based on what you're saying, I think that code looks like

healthStat = 0
armorStat = 0
damageStat = 0
totalStat = healthStat + armorStat + damageStat

createCustom(healthStat, armorStat, damageStat, totalStat)

beginning(healthStat, armorStat, damageStat)

In python (and most languages), each variable is scoped to the function that it lives in, and when you pass it to another function it creates a copy*. To solve that, you have to store the results (which you're already returning from the function) back into the variables, which you would do with something like

healthStat = 0
armorStat = 0
damageStat = 0
totalStat = healthStat + armorStat + damageStat

healthStat, armorStat, damageStat, totalStat = createCustom(healthStat, armorStat, damageStat, totalStat)

beginning(healthStat, armorStat, damageStat)

You never read the values of the input to createCustom though, so you don't need to be passing those as arguments. That would make the code look like

healthStat, armorStat, damageStat, totalStat = createCustom()

beginning(healthStat, armorStat, damageStat)

In createCustom, you just remove the arguments from the top of the function, so it looks like

def createCustom():
    print("...")

 

You also need to do something similar with the error case when the user enters the wrong value. You can assign the results to all of the variables again, so it becomes

if totalStat != 20:
    print("...")
    healthStat, armorStat, damageStat, totalStat = createCustom()

but if you do that then it will run the next line, where you print out a summary of their stats, once for each time they entered the values wrongly. You can fix that, and make the code neater, by immediately returning the result of createCustom:

if totalStat != 20:
    print("...")
    return createCustom()

 

 

* it's a bit more subtle than this in practice, because if you pass an array then changes to the array will be reflected in the original array too. What is really not propagated to the caller is assignment, where you do myVar = something, so in-place modification (like myVar[0] = something) still works.

so im currently on summer break and i wanted to practice some coding (only been learning for a year anyhow)

 

so im making a text based RPG, and i set the character creation and the beginning of the game as two different "def" functions.

 

my problem is that when i create a character in the cc part, it works fine and shows the stats, etc, but then when i start the beginning of the game i inserted a test, its print(totalStat) just to see if it transfers over and it doesnt. im confused as to what to do, the only idea i had was at the end of the cc area i added return(healthStat, armorStat, damageStat, totalStat) thinking it would "send" the numbers back into the "main" def and then could be used in the beginning def, but that didnt work.

 

help?

 

PS using PyCharm, not sure if its different from normal python

1527432585_Screenshot(5).thumb.png.786331ea8855652a9e15eac173e973c1.png
 

stuff is cool. stuff that has fancy lighting is cooler. stuff that has fancy lighting and works is the coolest.

 

i game so i know a bit abt gaming tech, not much abt professional tech.

 

writing this as i finish a 3 hour D2 sesh so excuse anything wrong.

Link to comment
Share on other sites

Link to post
Share on other sites

Pycharm is just a regular python editor, so for future reference you don't need to specify it.

 

The interesting part here is what you're doing in the code that calls those functions. At a guess based on what you're saying, I think that code looks like

healthStat = 0
armorStat = 0
damageStat = 0
totalStat = healthStat + armorStat + damageStat

createCustom(healthStat, armorStat, damageStat, totalStat)

beginning(healthStat, armorStat, damageStat)

In python (and most languages), each variable is scoped to the function that it lives in, and when you pass it to another function it creates a copy*. To solve that, you have to store the results (which you're already returning from the function) back into the variables, which you would do with something like

healthStat = 0
armorStat = 0
damageStat = 0
totalStat = healthStat + armorStat + damageStat

healthStat, armorStat, damageStat, totalStat = createCustom(healthStat, armorStat, damageStat, totalStat)

beginning(healthStat, armorStat, damageStat)

You never read the values of the input to createCustom though, so you don't need to be passing those as arguments. That would make the code look like

healthStat, armorStat, damageStat, totalStat = createCustom()

beginning(healthStat, armorStat, damageStat)

In createCustom, you just remove the arguments from the top of the function, so it looks like

def createCustom():
    print("...")

 

You also need to do something similar with the error case when the user enters the wrong value. You can assign the results to all of the variables again, so it becomes

if totalStat != 20:
    print("...")
    healthStat, armorStat, damageStat, totalStat = createCustom()

but if you do that then it will run the next line, where you print out a summary of their stats, once for each time they entered the values wrongly. You can fix that, and make the code neater, by immediately returning the result of createCustom:

if totalStat != 20:
    print("...")
    return createCustom()

 

 

* it's a bit more subtle than this in practice, because if you pass an array then changes to the array will be reflected in the original array too. What is really not propagated to the caller is assignment, where you do myVar = something, so in-place modification (like myVar[0] = something) still works.

HTTP/2 203

Link to comment
Share on other sites

Link to post
Share on other sites

  • 2 weeks later...
On 8/11/2020 at 5:54 AM, colonel_mortis said:

Pycharm is just a regular python editor, so for future reference you don't need to specify it.

 

The interesting part here is what you're doing in the code that calls those functions. At a guess based on what you're saying, I think that code looks like


healthStat = 0
armorStat = 0
damageStat = 0
totalStat = healthStat + armorStat + damageStat

createCustom(healthStat, armorStat, damageStat, totalStat)

beginning(healthStat, armorStat, damageStat)

In python (and most languages), each variable is scoped to the function that it lives in, and when you pass it to another function it creates a copy*. To solve that, you have to store the results (which you're already returning from the function) back into the variables, which you would do with something like


healthStat = 0
armorStat = 0
damageStat = 0
totalStat = healthStat + armorStat + damageStat

healthStat, armorStat, damageStat, totalStat = createCustom(healthStat, armorStat, damageStat, totalStat)

beginning(healthStat, armorStat, damageStat)

You never read the values of the input to createCustom though, so you don't need to be passing those as arguments. That would make the code look like


healthStat, armorStat, damageStat, totalStat = createCustom()

beginning(healthStat, armorStat, damageStat)

In createCustom, you just remove the arguments from the top of the function, so it looks like


def createCustom():
    print("...")

 

You also need to do something similar with the error case when the user enters the wrong value. You can assign the results to all of the variables again, so it becomes


if totalStat != 20:
    print("...")
    healthStat, armorStat, damageStat, totalStat = createCustom()

but if you do that then it will run the next line, where you print out a summary of their stats, once for each time they entered the values wrongly. You can fix that, and make the code neater, by immediately returning the result of createCustom:


if totalStat != 20:
    print("...")
    return createCustom()

 

 

* it's a bit more subtle than this in practice, because if you pass an array then changes to the array will be reflected in the original array too. What is really not propagated to the caller is assignment, where you do myVar = something, so in-place modification (like myVar[0] = something) still works.

hey, heres the source code

 

def main() :
      print("Welcome to D&D! Please choose a class. The available classes are:")
      print("Knight, Rogue, Mage. Or, you can make a custom class.")
      print("Enter Knight, Rogue, Mage, or Custom to create your own class. ")
      classPicked = input().capitalize()
      pickClass(classPicked,health,armor,damage)
      beginning(health,armor,damage)



def pickClass(classPicked, health, armor, damage):
      if classPicked == "Knight":
            print("You picked the Knight. This character has 9 health, 8 armor, and deals 3 damage.")
            health = 9
            armor = 8
            damage = 3
            return (health,armor,damage)
      if classPicked == "Rogue":
            print("You picked the Rogue. This character has 5 health, 5 armor, and deals 10 damage.")
            health = 5
            armor = 5
            damage = 10
      if classPicked == "Mage" :
            print("You picked the Mage. This character has 7 health, 7 armor, and deals 6 damage.")
            health = 7
            armor = 7
            damage = 6
      if classPicked == "Custom":
            print("You will now enter stat customisation")
            createCustom(health, armor, damage, total)


def createCustom(health, armor, damage, total):
      print("You have 20 skill points available. It can be spent on 3 stats:")
      print("Health, Armor, and Damage.")
      print("Armor and Health determines how much damage you can take before you die.")
      print("Damage determines how much damage you can inflict.")
      print("Please input how many points you want to spend on Health.")
      health = input()
      print("Your health stat is at " + health)
      print("Please input how many points you want to spend on Armor.")
      armor = input()
      print("Your  armor stat is at " + armor)
      print("Please input how many points you want to spend on Damage.")
      damage = input()
      print("Your damage stat is at " + damage)
      totalStat = int(health) + int(armor) + int(damage)
      if totalStat != 20:
            print("Sorry, your total of " + str(total) + " is either more or less than 20. Please try again.")
            createCustom(health, armor, damage, total)
      print("Your total is at " + health + " health, " + armor + " armor, " + damage + " damage.")




def beginning(health,armor,damage):
      print(health + armor + damage)



main()

 

there are a couple things above(armor=, import random etc not important)

 

this is what im using right now and it doesnt work..

 still not sure what to change?

stuff is cool. stuff that has fancy lighting is cooler. stuff that has fancy lighting and works is the coolest.

 

i game so i know a bit abt gaming tech, not much abt professional tech.

 

writing this as i finish a 3 hour D2 sesh so excuse anything wrong.

Link to comment
Share on other sites

Link to post
Share on other sites

On 8/19/2020 at 7:01 AM, ketchupspill said:

      pickClass(classPicked,health,armor,damage)
      beginning(health,armor,damage)

 

Variables don't work like that - the changes that you make to health, armor and damage in pickClass don't change their values in main, so they're still empty when you pass them to beginning. Instead, you have to return the results from createCustom, and store the results. I went into a bit more detail about that in my previous post, but I guess I was too abstract. To emphasise that point,

def my_function(x):
  print(x) # => 3
  x = x + 1
  print(x) # => 4
  return x

def main():
  x = 3
  print(x) # => 3 (surprise!)
  
  y = my_function(x)
  
  print(x) # => 3 still, because the value of x is copied to my_function, and changes there only affect that copy
  print(y) # => 4 because we returned the result, and stored it in y (note that because the variables are in
           #      different functions, it doesn't matter if they have the same or different names)

 

For your code, the effect of that is

def main() :
      # ...
      classPicked = input().capitalize()
      health, armor, damage = pickClass(classPicked) # their values only change if you use = on them
      beginning(health, armor, damage)



def pickClass(classPicked): # No need to pass health, armor and damage here
      if classPicked == "Knight":
            print("You picked the Knight. This character has 9 health, 8 armor, and deals 3 damage.")
            health = 9
            armor = 8
            damage = 3
      # ...
      if classPicked == "Custom":
            print("You will now enter stat customisation")
            health, armor, damage = createCustom()
      return (health,armor,damage) # Have to return the values here for them to take effect


def createCustom(): # Don't need to pass things here
      # ...
      print("Your total is at " + health + " health, " + armor + " armor, " + damage + " damage.")
      return (health, armor, damage) # Again, have to return here

def beginning(health,armor,damage):
      print(health + armor + damage)

main()

 

(Use the <> button to format code nicely)

HTTP/2 203

Link to comment
Share on other sites

Link to post
Share on other sites

On 8/21/2020 at 7:14 AM, colonel_mortis said:

Variables don't work like that - the changes that you make to health, armor and damage in pickClass don't change their values in main, so they're still empty when you pass them to beginning. Instead, you have to return the results from createCustom, and store the results. I went into a bit more detail about that in my previous post, but I guess I was too abstract. To emphasise that point,


def my_function(x):
  print(x) # => 3
  x = x + 1
  print(x) # => 4
  return x

def main():
  x = 3
  print(x) # => 3 (surprise!)
  
  y = my_function(x)
  
  print(x) # => 3 still, because the value of x is copied to my_function, and changes there only affect that copy
  print(y) # => 4 because we returned the result, and stored it in y (note that because the variables are in
           #      different functions, it doesn't matter if they have the same or different names)

 

For your code, the effect of that is


def main() :
      # ...
      classPicked = input().capitalize()
      health, armor, damage = pickClass(classPicked) # their values only change if you use = on them
      beginning(health, armor, damage)



def pickClass(classPicked): # No need to pass health, armor and damage here
      if classPicked == "Knight":
            print("You picked the Knight. This character has 9 health, 8 armor, and deals 3 damage.")
            health = 9
            armor = 8
            damage = 3
      # ...
      if classPicked == "Custom":
            print("You will now enter stat customisation")
            health, armor, damage = createCustom()
      return (health,armor,damage) # Have to return the values here for them to take effect


def createCustom(): # Don't need to pass things here
      # ...
      print("Your total is at " + health + " health, " + armor + " armor, " + damage + " damage.")
      return (health, armor, damage) # Again, have to return here

def beginning(health,armor,damage):
      print(health + armor + damage)

main()

 

(Use the <> button to format code nicely)

ohhhhhhhhhh

 

finally figured it out!

 

thanks so much!!!

stuff is cool. stuff that has fancy lighting is cooler. stuff that has fancy lighting and works is the coolest.

 

i game so i know a bit abt gaming tech, not much abt professional tech.

 

writing this as i finish a 3 hour D2 sesh so excuse anything wrong.

Link to comment
Share on other sites

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

×