New OOTS products from CafePress
New OOTS t-shirts, ornaments, mugs, bags, and more
Results 1 to 12 of 12
  1. - Top - End - #1
    Bugbear in the Playground
     
    NecromancerGuy

    Join Date
    Mar 2014
    Location
    Scotland
    Gender
    Male

    Default Name can be Undefined (python3)

    I am fairly new at coding and am putting together a system where I can apply a bonus and a penalty to a dice roll the system is working, but PyCharm is giving me a warning that reads 'Name 'mod_bonus' can be undefined' and I cannot find information on what exactly this means and what to do about it.

    I think the warning is referring to it detecting the possibility 'mod_bonus' may end up undefined, to judge by the wording, but I think the loop on it would prevent that?

    The relevant section of code is the following:
    Spoiler
    Show

    Code:
    # Takes result of dice roll and then offers to apply a further modifier.
    while True:
        apply_mod = input("Apply Modifier? yes/no")
        if apply_mod == "yes":
            # finds bonus
            while True:
                try:
                    mod_bonus = int(input("Input Bonus"))
                    break
                except ValueError:
                    continue
    # finds penalty
            while True:
                try:
                    mod_penalty = int(input("Input Penalty"))
                except ValueError:
                    continue
    # finds modifier and adds to prior roll
                final_modifier = int(dice + mod_bonus - mod_penalty)
                print("Modified roll is: " + str(final_modifier))
                break
        elif apply_mod == "no":
            print("Random Selected Number is: " + str(dice))
        break
    my homebrew signature:
    here on page 9

  2. - Top - End - #2
    Troll in the Playground
     
    DeTess's Avatar

    Join Date
    May 2017
    Gender
    Female

    Default Re: Name can be Undefined (python3)

    If I'm not mistaken, the error is caused by those 'try' blocks. i think they make it possible to arrive at the final_midifier calculation without defining mod_bonus, which cause the error.

    I'm not at my computer though, so I can't check this suspicion.
    Jasnah avatar by Zea Mays

  3. - Top - End - #3
    Titan in the Playground
     
    ElfRangerGuy

    Join Date
    Aug 2007
    Location
    Imagination Land
    Gender
    Male

    Default Re: Name can be Undefined (python3)

    I think DeTess is right. If the entry of mod_bonus fails, it will be undefined later on. You might be able to fix this by initializing the variable to 0. Probably should do the same for mod_penalty as well, just to be safe. Or set them to 0 as part of the failure exception?

    Also, you should check your math or your input of of mod_penalty to see if the user enters a positive or negative number. I would expect to put in a negative number for a penalty, but then you're subtracting it when you do the math part (a double negative). Easiest fix is to subtract the absolute value of mod_penalty using abs(mod_penalty).

    EDIT: Alright, I'm not a Python expert. I noticed the extra while loops and you might be correct that the first try should repeat until it succeeds. In that case, I'm not sure how the variable could be undefined. I also could not find how ValueError works, but I'm guessing it fails if the input is not an integer?

    EDIT 2: Oh, wait, it's just a warning? Warnings can be ignored sometimes. Does the code compile and execute correctly? Your interface tries its best, and it sees a variable being defined inside a try statement, but it might not understand that the loop will prevent the failure.
    Last edited by KillianHawkeye; 2020-12-01 at 01:13 PM.
    "Nothing you can't spell will ever work." - Will Rogers

    Watch me draw and swear at video games.

  4. - Top - End - #4
    Troll in the Playground
     
    DwarfClericGuy

    Join Date
    Jun 2007

    Default Re: Name can be Undefined (python3)

    Quote Originally Posted by KillianHawkeye View Post
    Your interface tries its best, and it sees a variable being defined inside a try statement, but it might not understand that the loop will prevent the failure.
    That's pretty much it.

    Dice comes in with a value, it's okay.

    mod_bonus isn't, and is in the try loop to keep people from giving an erroneous input. It breaks the try on a successful conversion to integer.

    Oh, and check the mod_penalty loop. The condition is always true, there's no break.
    May you get EXACTLY what you wish for.

  5. - Top - End - #5
    Barbarian in the Playground
     
    PaladinGuy

    Join Date
    Sep 2016

    Default Re: Name can be Undefined (python3)

    Quote Originally Posted by sihnfahl View Post
    That's pretty much it.

    Dice comes in with a value, it's okay.

    mod_bonus isn't, and is in the try loop to keep people from giving an erroneous input. It breaks the try on a successful conversion to integer.

    Oh, and check the mod_penalty loop. The condition is always true, there's no break.
    I think there is, there's a comment in the middle of the loop, and after the comment it only unindents the try-except.

    I don't like something about the loop structure. Somehow it all looks a bit backwards. I'm not sure how to I would like it, and can't think of an easy way to avoid it.


    One possible possibility would be putting that section into it's own function "inputint", that way you can forget about it in it's code, (and it might be easier for the checker to work out what's going on). but I'm not sure it's any clearer.
    In any case the way you did it made you think about how loops and trys work.

    Code:
    def input_int(message):
        while true:
            try:
                return int(input(message))
    
    modBonus=input_int(" ...")
    modPenalty=input_int("...")
    ...
    Last edited by jayem; 2020-12-01 at 06:58 PM.

  6. - Top - End - #6
    Troll in the Playground
     
    DwarfClericGuy

    Join Date
    Jun 2007

    Default Re: Name can be Undefined (python3)

    Quote Originally Posted by jayem View Post
    I think there is, there's a comment in the middle of the loop, and after the comment it only unindents the try-except.
    I think that was what was throwing me; the indentation. Still not 100% on python.

    Cause in my mind, the penalty code would be the same as the modifier, in that it wouldn't proceed until a valid number was entered.

    so somewhere between ...

    Code:
            while True:
                try:
                    mod_penalty = int(input("Input Penalty"))
                    final_modifier = int(dice + mod_bonus - mod_penalty)
                    print("Modified roll is: " + str(final_modifier))
                    break
                except ValueError:
                    continue
    and
    Code:
            while True:
                try:
                    mod_penalty = int(input("Input Penalty"))
                    break
                except ValueError:
                    continue
    
            final_modifier = int(dice + mod_bonus - mod_penalty)
            print("Modified roll is: " + str(final_modifier))
    May you get EXACTLY what you wish for.

  7. - Top - End - #7
    Troll in the Playground
    Join Date
    Jan 2007

    Default Re: Name can be Undefined (python3)

    Quote Originally Posted by sihnfahl View Post
    I think that was what was throwing me; the indentation. Still not 100% on python.

    Cause in my mind, the penalty code would be the same as the modifier, in that it wouldn't proceed until a valid number was entered.

    so somewhere between ...

    Code:
            while True:
                try:
                    mod_penalty = int(input("Input Penalty"))
                    final_modifier = int(dice + mod_bonus - mod_penalty)
                    print("Modified roll is: " + str(final_modifier))
                    break
                except ValueError:
                    continue
    and
    Code:
            while True:
                try:
                    mod_penalty = int(input("Input Penalty"))
                    break
                except ValueError:
                    continue
    
            final_modifier = int(dice + mod_bonus - mod_penalty)
            print("Modified roll is: " + str(final_modifier))
    I think you are right, since as it is I think the loop will print out the results even on a failed mod_penalty input try and break the loop without trying again.
    In a war it doesn't matter who's right, only who's left.

  8. - Top - End - #8
    Barbarian in the Playground
     
    PaladinGuy

    Join Date
    Sep 2016

    Default Re: Name can be Undefined (python3)

    Quote Originally Posted by Radar View Post
    I think you are right, since as it is I think the loop will print out the results even on a failed mod_penalty input try and break the loop without trying again.
    The "continue" (IIUC) should restart the while loop (if there is an invalid entry), so if the input is invalid it doesn't reach the break

    Personally, I find either of sihnfahl's much easier to follow. When you get the "final_modifier = ...", in the initial code you are having to take into account the While, Try, Except, Break & Continue all 'interacting' with the program flow. Also, as a bonus, it's possibly easier for PyCharm to know what's going on for the same reasons.

    But at the middle of the day, if it works it works.

  9. - Top - End - #9
    Troll in the Playground
    Join Date
    Jan 2007

    Default Re: Name can be Undefined (python3)

    Quote Originally Posted by jayem View Post
    The "continue" (IIUC) should restart the while loop (if there is an invalid entry), so if the input is invalid it doesn't reach the break

    Personally, I find either of sihnfahl's much easier to follow. When you get the "final_modifier = ...", in the initial code you are having to take into account the While, Try, Except, Break & Continue all 'interacting' with the program flow. Also, as a bonus, it's possibly easier for PyCharm to know what's going on for the same reasons.
    True, I misinterpreted the continue.

    Quote Originally Posted by jayem View Post
    But at the middle of the day, if it works it works.
    This... I am not so sure anymore. Writing a given piece of code is rarely a one time work. You or someone else will have to revisit it at some point. Any unclear structure or an "ugly but working" quick-fix will always come back to bite you. Also, debugging becomes that much more difficult.

    It might look innocent at the beginning, but...
    In a war it doesn't matter who's right, only who's left.

  10. - Top - End - #10
    Titan in the Playground
     
    ElfRangerGuy

    Join Date
    Aug 2007
    Location
    Imagination Land
    Gender
    Male

    Default Re: Name can be Undefined (python3)

    Quote Originally Posted by Radar View Post
    Writing a given piece of code is rarely a one time work. You or someone else will have to revisit it at some point. Any unclear structure or an "ugly but working" quick-fix will always come back to bite you. Also, debugging becomes that much more difficult.
    Truth.

    Hacking together an ugly code to get it to run only works in the short term. It's better to learn to write code that will be readable and understandable when you look at it again six months or a year down the road. Code you can read is code you can debug, after all.

    In addition to making things easier on your future self, establishing good habits when you're doing small indie programming projects will help you immensely if you ever get into doing programming collaboratively.
    "Nothing you can't spell will ever work." - Will Rogers

    Watch me draw and swear at video games.

  11. - Top - End - #11
    Ettin in the Playground
     
    Telok's Avatar

    Join Date
    Mar 2005
    Location
    61.2° N, 149.9° W
    Gender
    Male

    Default Re: Name can be Undefined (python3)

    Quote Originally Posted by KillianHawkeye View Post
    Truth.

    Hacking together an ugly code to get it to run only works in the short term. It's better to learn to write code that will be readable and understandable when you look at it again six months or a year down the road. Code you can read is code you can debug, after all.

    In addition to making things easier on your future self, establishing good habits when you're doing small indie programming projects will help you immensely if you ever get into doing programming collaboratively.
    Very truth.

    The bane of your programming existence, should you choose to go past the minor hobbyist level, will be undocumented hacks that work "well enough" for the original author. Especially the ones in the half documented, not-fully-implemented, that-function-is-just-a-placeholder APIs from major commercial corporations.[/rant]

  12. - Top - End - #12
    Bugbear in the Playground
     
    NecromancerGuy

    Join Date
    Mar 2014
    Location
    Scotland
    Gender
    Male

    Default Re: Name can be Undefined (python3)

    Quote Originally Posted by KillianHawkeye View Post
    Also, you should check your math or your input of of mod_penalty to see if the user enters a positive or negative number. I would expect to put in a negative number for a penalty, but then you're subtracting it when you do the math part (a double negative). Easiest fix is to subtract the absolute value of mod_penalty using abs(mod_penalty).
    I could try some of these ideas. My original idea was to use subtraction rather than adding a negative number because, input wise, the non-negative number is slightly faster to type. I am far from mathematically inclined but on looking it up I think I can make mod_penalty run off of absolute value so it accepts positive and negive numbers with the current system, That's something at the very least.

    Quote Originally Posted by KillianHawkeye View Post
    EDIT: Alright, I'm not a Python expert. I noticed the extra while loops and you might be correct that the first try should repeat until it succeeds. In that case, I'm not sure how the variable could be undefined. I also could not find how ValueError works, but I'm guessing it fails if the input is not an integer?
    Yes.

    Quote Originally Posted by KillianHawkeye View Post
    EDIT 2: Oh, wait, it's just a warning? Warnings can be ignored sometimes. Does the code compile and execute correctly? Your interface tries its best, and it sees a variable being defined inside a try statement, but it might not understand that the loop will prevent the failure.
    I assumed that it wasn't something significant, I'm just going by the thought that if it's considered worth mentioning I best look into it before there works out being some background oddity that can mess something up in the future. The code itself does what I want it to.


    Quote Originally Posted by sihnfahl View Post
    Oh, and check the mod_penalty loop. The condition is always true, there's no break.
    Honestly that's a bit that confuses me. I had the break there at first but the code was not working as intended, I removed it on a gut feeling and it started behaving as I wanted and the loop has no issues.

    Quote Originally Posted by sihnfahl View Post
    I think that was what was throwing me; the indentation. Still not 100% on python.

    Cause in my mind, the penalty code would be the same as the modifier, in that it wouldn't proceed until a valid number was entered.

    so somewhere between ...

    Code:
            while True:
                try:
                    mod_penalty = int(input("Input Penalty"))
                    final_modifier = int(dice + mod_bonus - mod_penalty)
                    print("Modified roll is: " + str(final_modifier))
                    break
                except ValueError:
                    continue
    and
    Code:
            while True:
                try:
                    mod_penalty = int(input("Input Penalty"))
                    break
                except ValueError:
                    continue
    
            final_modifier = int(dice + mod_bonus - mod_penalty)
            print("Modified roll is: " + str(final_modifier))
    After a quick try both of these have the same results. The warning now highlights both mod_bonus and mod_penalty and code function does not appear noticeably changed.


    Quote Originally Posted by jayem View Post
    One possible possibility would be putting that section into it's own function "inputint", that way you can forget about it in it's code, (and it might be easier for the checker to work out what's going on). but I'm not sure it's any clearer.
    In any case the way you did it made you think about how loops and trys work.

    Code:
    def input_int(message):
        while true:
            try:
                return int(input(message))
    
    modBonus=input_int(" ...")
    modPenalty=input_int("...")
    ...
    I considered something like this early on actually. I 'll try it out once I've more time.

    Edit:
    If nothing else, I got my original bit of code to stop showing the warning.
    Spoiler
    Show

    Code:
    mod_bonus = 0
    mod_penalty = 0
    
    # Takes result of dice roll and then offers to apply a further modifier.
    while True:
        apply_mod = input("Apply Modifier? yes/no")
        if apply_mod == "yes":
            # finds bonus
            while True:
                try:
                    mod_bonus = int(input("Input Bonus"))
                    break
                except ValueError:
                    continue
    # finds penalty
            while True:
                try:
                    mod_penalty = int(input("Input Penalty"))
                    break
                except ValueError:
                    continue
    # finds modifier and adds to prior roll
            final_modifier = int(dice + mod_bonus - mod_penalty)
            print("Modified roll is: " + str(final_modifier))
        elif apply_mod == "no":
            print("Random Selected Number is: " + str(dice))
        break


    Meanwhile I've been playing around with functions and gotten to this:
    Spoiler
    Show

    Code:
    # collects and applys bonus and penalty to apply to dice roll
    def dice_ajst():
        while True:
            try:
                add_this = int(input("Input Bonus"))
                sub_input = input("Input Penalty")
                sub_this = int(sub_input)
                final = dice + add_this + sub_this
                print(final)
                break
            except ValueError:
                continue
    
    
    dice_ajst()

    which has lead me to the WIP version three of the code where I want it to have the same effect as the loops in v1 but be concise and readable like v2.
    Last edited by ThreadNecro5; 2020-12-08 at 03:22 PM.
    my homebrew signature:
    here on page 9

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •