Beeeeeeep... Bugs Alert, this is not a drill... I repeat... Bugs Alert, this is not drill...
Python:
influences = {
("Monday", "Morning"): lambda: jump(Room1_Monday_Morning_Influence) if RubyI >= 1 else None,
("Monday", "Morning", 5): lambda: jump(Room1_Monday_Morning_Five_Influence) if RubyI >= 5 else None,
("Monday", "Noon"): lambda: jump(Room1_Monday_Noon),
("Monday", "Afternoon"): lambda: jump(Room1_Monday_Afternoon),
("Tuesday", "Morning"): lambda: jump(Room1_Tuesday_Morning)
}
if clock.weekday, clock.time in influences:
influences[(clock.weekday, clock.time)]()
else:
[...]
Firstly:
Your
influences[(clock.weekday, clock.time)]()
will only match one entry:
("Monday", "Morning"): lambda: jump(Room1_Monday_Morning_Influence) if RubyI >= 1 else None
The second entry,
("Monday", "Morning", 5): lambda: jump(Room1_Monday_Morning_Five_Influence) if RubyI >= 5 else None
is never addressed because of the third entity in the tuple that serve as key.
Firstly dot five:
Like dictionaries are unordered, even if the code was working, you would have cases where the code branch you to "Room1_Monday_Morning_Influence" despite
RubyI
being superior or equal to 5. This just because it would be the first match found by Python, and therefore the one tested.
Secondly:
Lambdas expect Python statement,
jump()
is not a Python statement, nor is it a Ren'Py one.
Thirdly:
The
else
will only catch cases where the day and period aren't used as key for the dictionary, not the case where the lambda will return
None
.
Add to this the fact that:
Firstly:
You forgot the entry for Monday Morning when RubyI is lower than 1.
Secondly:
You need 10 lines, 11 if you add the missing Monday Morning, 26 if you include the default branching for the rest of the days. Against 7 lines in my example, even when including the default branching for the rest of the days.
And the difference grow further and further the more room and exceptions there's to handle. Your approach need to explicitly declare all day/period couple even when there's no exceptions, mine have them handled by default in the code.
A solution that need at least three times more lines, and is so much prone to bugs is
not a simplification.
Thirdly:
RubyI
isn't necessarily the only secondary branching condition. Therefore you can't correct your code with something like
if clock.weekday, clock.time, RubyI in influences:
.
Instead, you need a branching depending on the optional third condition. What imply that you also need to find a way to discriminate this in your dict, because
RubyI >= 5
isn't the same than
RubyC >= 5
, while, as it is defined, both would lead to a dictionary entry labeled
( "Monday", "Morning", 5 )
.
Fourthly:
In your example there's no reason to have the jump as lambda (even when done right), you could perfectly just have the label.
Without the exception to simply the explanation:
Python:
influences = {
("Monday", "Morning"): "Room1_Monday_Morning",
("Monday", "Noon"): "Room1_Monday_Noon",
("Monday", "Afternoon"): "Room1_Monday_Afternoon",
("Tuesday", "Morning"): "Room1_Tuesday_Morning"
}
if clock.weekday, clock.time in influences:
jump exception influences[(clock.weekday, clock.time)]
else:
[...]
With the exception:
Python:
influences = {
("Monday", "Morning"): lambda: "Room1_Monday_Morning_Five_Influence" if RubyI >=5 else ( "Room1_Monday_Morning_Five_Influence" if RubyI >= 1 else "Room1_Monday_Morning_Influence" ),
("Monday", "Noon"): lambda: "Room1_Monday_Noon",
("Monday", "Afternoon"): lambda: "Room1_Monday_Afternoon",
("Tuesday", "Morning"): lambda: "Room1_Tuesday_Morning"
}
if clock.weekday, clock.time in influences:
jump exception influences[(clock.weekday, clock.time)]()
else:
[...]
In both case it's still more lines since the example I gave in my previous post; an example that works
exactly the same without the need of a dictionary. And, of course, when the exception enter the scene it lead to way too complex lambdas.
Fifthly:
You totally misunderstood how porting
switch
/
case
into Python should be done.
Python:
define dayRoom1 = {
"clock.weekday == 'Monday' and clock.time == 'Morning' and 1 <= RubyI < 5": "Room1_Monday_Morning_Influence",
"clock.weekday == 'Monday' and clock.time == 'Morning' and RubyI >= 5": "Room1_Monday_Morning_Five_Influence",
"clock.weekday == 'Monday' and clock.time == 'Morning'": "Room1_Monday_Morning",
"clock.weekday == 'Monday' and clock.time == 'Noon'": "Room1_Monday_Noon",
"clock.weekday == 'Monday' and clock.time == 'Afternoon'": "Room1_Monday_Afternoon",
"clock.weekday == 'Thuesday' and clock.time == 'Noon'": "Room1_Thuesday_Noon",
}
menu:
"room1:
python:
jumpingLabel = "Default_label_in_case_of_error"
for condition in dayRoom1:
if eval( condition ):
jumpingLabel = dayRoom1[atom]
break
jump expression jumpingLabel
What is still heavier than the code I gave, but can be lightened. For this you just need to care about the exception in the dictionary, and rely on a generic function working for all rooms:
Python:
init python:
def labelFinder( room, specialCases ):
retVal = ""
for atom in specialCases:
if eval( atom ):
retVal = specialCases[atom]
break
# No exception have been found for that day at that period, therefore
# use the default label matching that day and period.
# This present the advantage to not need a default label in case of error.
if retVal == "":
retVal = "{}_{}_{}".format( room, clock.weekday, clock.time )
return retVal
# The conditions matching the special cases for room 1.
define dayRoom1 = {
"clock.weekday == 'Monday' and clock.time == 'Morning' and 1 <= RubyI < 5": "Room1_Monday_Morning_Influence",
"clock.weekday == 'Monday' and clock.time == 'Morning' and RubyI >= 5": "Room1_Monday_Morning_Five_Influence",
}
# The conditions matching the special cases for room 2.
define dayRoom2 = { [...] }
menu:
"room 1":
jump expression labelFinder( "Room1", dayRoom1 )
"room 2
jump expression labelFinder( "Room2", dayRoom2 )
It need 13 lines against your 11 lines. But it will still only need those 13 lines if you add the 5 missing days and their three periods, against 26 lines for your example. This because here you don't have to add entries for the days and period that don't have exceptions.
The condition are a bit heavy, but they can be simplified too:
[I use the opportunity to also reduce the /labelFinder/ part]
Python:
init python:
def labelFinder( room, specialCases ):
retVal = ""
for atom in specialCases[(clock.weekday,clock.time)]:
# You don't really need the /break/, browsing all the entries will not
# need much time since you limits by the day and period.
if eval( atom ): retVal = specialCases[atom]
return retVal if retVal != "" else "{}_{}_{}".format( room, clock.weekday, clock.time )
# The conditions matching the special cases for room 1.
define dayRoom1 = {
( "Monday", "Morning" ): { "1 <= RubyI < 5": "Room1_Monday_Morning_Influence",
"RubyI >= 5": "Room1_Monday_Morning_Five_Influence" },
( "Monday", "Noon" ): { [exception for Monday Noon] },
[...]
# The conditions matching the special cases for room 2.
define dayRoom2 = { [...] }
menu:
"room 1":
jump expression labelFinder( "Room1", dayRoom1 )
"room 2
jump expression labelFinder( "Room2", dayRoom2 )
We now drop to 10 lines, including the default branching for all days and periods, against your broken 11 lines that only applied for 1 days plus one period of another day.
Simpler, lighter, bug free(minus the errors possibly made in the conditions themselves), and apply for all periods of all days of all rooms without needing to add more than one line by exception.
This is how you do a
switch
/
case
in Python and with Ren'Py.