0

Code first so you'll understand what I'm talking about :

goal = False
count = 0
def function():
    if goal==True:
        return True
    else:
        return False
def func():
    if dict1["A"]==True:
        return True
    else:
        return False
dict1 = {"A":function()}
dict2 = {"B":func()}
list = [dict1,dict2]
goal = True
for i in list:
    count = 0
    for x,y in i.items():
        if y==True:
            count+=1
    if count==len(i):
        print("Works")
    else:
        print(i)

>>>{"A":False}
>>>{"B":False}

This is not my current code, but it is the actual issue. This is where I'm asking, how can I update the values in the dicts. Should I do something like :

for i in list:
    for x,y in i.items():
        y()

?

My current project is used in Ren'Py (.rpy) but as I'm using python blocks, the code works exactly as normal Python. Within a class named Event, my elements are exactly as it follows:

def ev_check(self):
    if self.done==False:
        self.count = 0
        for x,y in self.conditions.items():
            if y==True:
                self.count+=1
            else:
                pass
        if self.count==len(self.conditions):
            self.valid = True
        else:
            self.valid = False
    else:
        self.valid = False

def own_office():
    if Promotion_1.done==True: #Once the event is played, .done gets True
        return True
    else:
        return False

def times_worked(x):
    if You.worked < x:
        return False
    else:
        return True

Promotion_1.conditions = {"Work 2 times" : times_worked(2)}
Meet_Tigerr.conditions = {"Own office" : own_office()}
#External event that adds a value to the data named You.worked to get it to 2
print(Promotion_1.conditions["Work 2 times"])

>>> False

Expected result : True Result : False

  • 1
    the values in the dict are functions. Can you explain what you mean by "updating" a function? – rdas Apr 12 '19 at 16:23
  • update what they return. When they get defined first, they receive what the functions returns (False in this case), but I want them to return True when their function gets True – Phoenix iz Fire Apr 12 '19 at 16:26
  • BTW: if variable keeps `True/False` then you don't need `if/else` to return `True/False` - ie. `def own_office(): return Promotion_1.done` – furas Apr 12 '19 at 16:26
  • @PhoenixizFire You want to change the definition of a function at runtime? – rdas Apr 12 '19 at 16:27
  • Once you `return` from a function and asssign the result to a variable, the only way to update the variable is to re-run the function and assign the output to the variable again...is that what you're asking? – G. Anderson Apr 12 '19 at 16:28
  • when you define dictionary `dict1 = {"A":function()}` then it runs function and it will never run it again. You would have to later do manually `dict1["A"] = function()` to change value in dictionary. It can be better if you assing only name of function without `()` and paramters (it is called `callback`) `dict1 = {"A":function}` and later you can get new value using `()` - `dict["A"]()` – furas Apr 12 '19 at 16:28
  • furas Thanks for this, I'll update that DroidX86 I just want it to update itself automatically, but as G. Anderson and furas are saying, looks like it can't update itself. So is there a way with a for loop to update it ? I'm building a class based on dictionnaries and I wanted every value to have a function, but if those doesn't update automatically this would just have me put a ton of lines of code instead of a simple loop :/ – Phoenix iz Fire Apr 12 '19 at 16:34
  • @furas the {"A":function} method works perfectly !!! Thanks a lot and thanks everyone for helping :) – Phoenix iz Fire Apr 12 '19 at 16:48
  • if you have to assign function with parameters then use `lambda` to create function without parameters - ie. `{"Work 2 times": lambda:times_worked(2) }` – furas Apr 12 '19 at 16:53

1 Answers1

0

You can create your custom dict and have this feature. You may try something like this:

class MyDict(dict):

    def __getitem__(self, item):
        val = super().__getitem__(item)
        if callable(val):
            return val()
        return val

It will work exactly like a dict, except that it will call the callable values for you every time.

d = MyDict()
d['m'] = 1
d['m']
Out[28]: 1
task
Out[33]: <function __main__.task()>
task()
Out[34]: True
d['t'] = task
d['t']
Out[36]: True

EDITED : Modified the code a bit to show how you can even have argument values passed for your parameterized functions:

def func():
    return True


def param_func(i):
    return 2*i


def param_func2(i, j):
    return i*j


class MyDict(dict):

    def __getitem__(self, key):
        if isinstance(key, tuple):
            super_key = key[0]
        else:
            super_key = key
        super_val = super().__getitem__(super_key)
        if callable(super_val):
            if isinstance(key, tuple):
                args = key[1:]
                return super_val.__call__(*args)
            else:
                return super_val.__call__()
        return super_val


if __name__ == "__main__":
    d = MyDict()
    d['num'] = 1
    print(d['num'])
    d['func'] = func
    print(d['func'])
    d['param_func'] = param_func
    print(d['param_func', 2])
    d['param_func2'] = param_func2
    print(d['param_func2', 2, 6])

Output :

1

True

4

12

Prashanti
  • 174
  • 7