Search code examples
pythonvariablesconcatenation

How to combine / concatenate a variable and "object path" in a for loop?


I am working on a script than can transform a .json format into a .idf format for energy simulations in EnergyPlus. As part of this script, I need to create schedules based on a number of points in time and values until that given time. As an example, this is on of the .json elements I am trying to convert:

"BOT": {"SpacesInModel": [
               {"IndoorClimateZone": {
                     "Schedules": {
                           "PeopleSchedule": {"Timer": [
                                { "$numberInt": "0" },
                                { "$numberInt": "10" },
                                { "$numberInt": "20" },
                                { "$numberInt": "24" }
                            ],
                            "Load": [{ "$numberDouble": "0.5" }, { "$numberInt": "1" }, { "$numberDouble": "0.5" }]
}

I have currently created the following code that reads and writes the required input for the .idf file, but I would like to do this as a for loop rather than a number of if statements

### Define helper function determining the number format
def IntOrDouble(path_string):
    try:
        return_value = path_string["$numberInt"]
    except Exception:
        return_value = path_string["$numberDouble"]
    return(return_value)

### Create .idf object and loop over .json format extracting schedule inputs

for item in data['BOT']['SpacesInModel']:
    InputFile.newidfobject("Schedule:Day:Interval") #.idf object
    DailySchedule = InputFile.idfobjects["Schedule:Day:Interval"][-1]
    
    People_Time = item["IndoorClimateZone"]["Schedules"]["PeopleSchedule"]["Timer"]
    People_Load = item["IndoorClimateZone"]["Schedules"]["PeopleSchedule"]["Load"]

    if len(People_Time) >= 0 and len(People_Time) != 0:
        DailySchedule.Time_2 = IntOrDouble(People_Time[0]) 
        
    if len(People_Time) >= 1 and len(People_Time) != 1:
        DailySchedule.Time_2 = IntOrDouble(People_Time[1])
        DailySchedule.Value_Until_Time_2 = IntOrDouble(People_Load[0])
        
    if len(People_Time) >= 2 and len(People_Time) != 2:
        DailySchedule.Time_3 = IntOrDouble(People_Time[2])
        DailySchedule.Value_Until_Time_3 = IntOrDouble(People_Load[1])

    if len(People_Time) >= 3 and len(People_Time) != 3:
        DailySchedule.Time_4 = IntOrDouble(People_Time[3])
        DailySchedule.Value_Until_Time_4 = IntOrDouble(People_Load[2])

    if len(People_Time) >= 4 and len(People_Time) != 4:
        DailySchedule.Time_5 = IntOrDouble(People_Time[4])
        DailySchedule.Value_Until_Time_4 = IntOrDouble(People_Load[3])

My problem is that I do not know how to "concatenate" the variable DailySchedule with the changeable object name /path e.g. Time_1 or Load_4. The index of Time_i Load_i would have to follow the index of the for loop. As of now, this is the closest I got (knowing that this is not a real solution :-) )

for i in range(len(People_Time)):
        DailySchedule."Time_{0}".format(i+1) = IntOrDouble(People_Time[i+1])
        DailySchedule."Load_{0}".format(i+1) = IntOrDouble(People_Load[i]) 

Solution

  • You can use pythons "F-strings" to add a variable to the string and square bracket notation to access the item in the dictionary.

    for i in range(len(People_Time)):
        DailySchedule[f"Time_{i+1}"] = IntOrDouble(People_Time[i+1])
        DailySchedule[f"Time_{i}"] = IntOrDouble(People_Load[i])