Once the Station list has been fed into the database, along with the associated properties (next and previous), the Trains can be added to the database as well. The Timing objects for each station can be created automatically once a train has been added. The concept of up/down as directions amongst trains is a trivial, but useful one.
While adding the train, it's timing, train_no, initial station and destination will be the inputs. The ID will be assigned automatically by the system since we have no need to set it explicitly.
post_save for Train: if train.initial_station.id > train.destination.id: # direction is UP lonavala to pune add_up_train(train) else: # direction is DOWN: pune to lonavala add_down_train(train) add_up_train: station_list = [ stations where id<=train.initial_station.id and id>=train.destination ] ( order in descending order ) time = train.time # start time for station in station_list: timing.train = train timing.station = station timing.time = time time = time + station.time_to_next add_down_train: station_list = [ stations where id<=train.destination and id>=train.initial_station ] ( order in ascending order ) time = train.time # start time for station in station_list: timing = Timing() timing.train = train timing.station = station timing.time = time timing.save() time = time + station.time_to_prev
This will populate the train timings based on the train (up/down). It can be further refactored using abstraction for getting the station list and calculating the time between stops. For example, lambdas can be used and passed to a generic add_train function:
add_train(train): if train.initial_station.id > train.destination.id: # UP top = train.initial_station.id bottom = train.destination.id ordering = descending stop = lambda station: station.time_to_next else: # DOWN top = train.destination.id bottom = train.initial_station.id ordering = ascending stop = lambda station: station.time_to_prev station_list = [ stations where id<=top and id>=bottom ] ( order by ordering ) time = train.time for station in station_list: timing.train = train timing.station = station timing.time = time timing.save() time = time + stop(station)
This results in roughly the same code, but saves duplication where unnecessary. If the train is being modified, then instead of modifying all the timings, it is easier to delete them all and repopulate the timing table with the new entries.
add_train(train): if train in [ select train in timings ] ( group by train ) # train already has timings, so let's remove them first delete all timings where train=train # ... rest of the code remains the same