Variables and math

Kaffekop

Member
Game Developer
Jul 23, 2017
442
3,155
And you take your diner at... I really need to sleep, I have initially seen 6AM, but it's 6PM. You're not to far from me in fact.
Usually around 6 pm.

On a slightly diffrent note, I have another issue that will become a problem in the future.
I have quite a few characters and all of these have a lust and trust variable:

Code:
default MomTrust = 0
default MomLust = 0
default NatTrust = 0
default NatTrust = 0
And the list goes on like that.
Now the problem, as I see it, is that these variables are going to be capped at ... say ... 50, and extrapolating from what you have previously shown me I got this working:

Code:
    def iLust():
        if MomLust > 50:
            return 50
        return MomLust

    def sLust():
        return str( iLust() )
My question is: Would I need to do this for every variable I've made or is there some more effecient way of doing this? Like putting them all into the same function:
Code:
    def iLust():
        if MomLust > 50:
            return 50
        return MomLust
        
        if NatLust > 50:
            return 50
        return NatLust

etc ... etc ...
If the above works, then how do I get the verious Lust to be displayed like before using the:
Code:
    def sLust():
        return str( iLust() )
or something similar?

Hope that you can help me.

Cheers - Kaffekop
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,620
15,601
My question is: Would I need to do this for every variable I've made or is there some more effecient way of doing this?
If all the variable names share the same "Nickname of character" + "Lust" structure, you can do this with a single function in place of all the $ momLust += x and other $ natLust += x :

Code:
init python:

    # Change the lust value for any character.
    #  - who -> Nickname of the character.
    #  - step -> Value to add to the actual lust ; 1 by default.
    def lustChange( who, step=1 ):
        # build the name of the variable for this character.
        attr = who + "Lust"
        #  Validate that the variable exist. If not, throw an 
        # exception to show you your error.
        if not hasattr( store, attr ): raise SyntaxError( "Unknown character '{}'".format( who ) )
        # Increment the actual value.
        value = getattr( store, attr ) + step
        # Limit it between 0...
        if value < 0: value = 0
        # and 50.
        if value > 50: value = 50
        # And store it back into the variable.
        setattr( store, attr, value )


# Define the variable as usual.
default momLust
default natLust
[...]

label blabla:
    menu: 
        "You're beautifull mom.":
            # Increase the lust of the mother by 1
            $ lustChange( "mom" )
            [...]
        "Wow, this dress really suit you. It make you look like a goddess.":
            # Increase the lust of the mother, but by 2
            $ lustChange( "mom", 2 )
            [...]
    [...]
    menu:
        "Compliment Nat.":
            # Increase the lust for nat by 2
            $ lustChange( "nat", 2 )
        "Tell her that she look like shit today.":
            # Decrease the lust for nat by 5
            $ lustChange( "nat", -5 )
        "Say nothing.":
            [...]
It will replace all the assignation (+= and -=) by a single function that will change the value, validate that you didn't made a syntax error, and limit the value between 0 and 50.
 
  • Like
Reactions: Kaffekop

Kaffekop

Member
Game Developer
Jul 23, 2017
442
3,155
anne O'nymous
It bloody works! Thank you so much, now I owe you another beer!
Before I'm done with my project I might even owe you dinner!

Cheers - Kaffekop
 

the66

beware, the germans are cumming
Modder
Donor
Respected User
Jan 27, 2017
7,748
24,118
here is a little code snippet if you often have to limit a value in a range.
Python:
def clamp(value,minimum=0,maximum=100):
  return min(max(value, min(minimum, maximum)), max(minimum, maximum))
works for integer, float or a mix of both. you only have to input your value, the range defaults to 0 and 100. you can use the kwargs minimum and/or maximum to define the range (or the complete function call with 2 or 3 arguments). you even can effectively use minimum > maximum, doesn't matter.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,620
15,601
Python:
def clamp(value,minimum=0,maximum=100):
  return min(max(value, min(minimum, maximum)), max(minimum, maximum))
Isn't it a little overkill ? Both and are designed to return the lowest (min) or highest (max) value among the list of values passed in arguments.
Basically speaking, min( arg1, arg2, *args [, key] ) translate into (I keep outside the optional key argument and the ability to works with string) :
Code:
val = *args[0]
for x in *args[1:]:
    if val < x:
       val = x
When you deal with a list of values, using min will be interesting, because what's behind is obviously more optimized that this. But when you use it to only have the lowest of two values, you'll still have the equivalent of this iteration. This is useless in this particular case, min( 15, 0) being translated into :
Code:
val = 15
for x in ( 0, ):
    if val < x:
       val = x
When you want to just limit a single value between two boundaries, it's faster to just do a simple comparison.


If really you want it to be a one liner, this is better (the parenthesis are optional, it just facilitate human reading):
Code:
def clamp( value, min=0, max=100):
    return max if value > max else ( value if value > min else min )
Even when used it directly as value, a one line if structure will be faster than min or max:
Code:
screen whatever:
    add myBackground:
        xsize ( bgWidth if bgWidth < config.screen_width / 2 else config.screen_width / 2 )
        ysize ( bgHeight if bgHeight < config.screen_height / 2 else config.screen_height / 2 )
        xalign 0.5 yalign 0.5
And you can even still have your initial clamp with just one line (here the parenthesis are mandatory) :
Code:
def clamp(value,min=0,max=100):
    return max if value > ( min if min > max else max ) else value if value > ( max if max < min else min ) else min
It's not really pythoner, because less easy to understand at first reading, but faster than your four embedded min/max[.icode].

Edit: Messed the links
 

the66

beware, the germans are cumming
Modder
Donor
Respected User
Jan 27, 2017
7,748
24,118
yeah, overkill is my 2nd name and you're absolutely right, your if construct is measured 5-6 times faster but i simply don't like these nested if statements. :)
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,620
15,601
yeah, overkill is my 2nd name and you're absolutely right, your if construct is measured 5-6 times faster but i simply don't like these nested if statements. :)
Don't worry, it wasn't a critic. I come from Perl, so I tend to nest many things, especially if. But I fully understand that I'm now more a dinosaur than the future of coding :D