I am looking for some way to improve my code. It works but it doesn't look good and I am almost sure that lot of Best Practices rules are violated.
The save_session()
function, creates dictionary with other dictionaries nested in. At the end the dictionary is dump to .json file.
I will appreciate any suggestions and advice for improvement of this code.
For better understanding the code of save_session()
:
workouts_instances
is the list of current WorkoutPlan
instances,
WorkoutPlan
stores instances of Training
and Exercise
,
Training
stores instances of Exercise
,
class WorkoutPlan:
def __init__(self, name, trainings=list(), exercises=list()):
self.name = name
self.trainings = trainings
self.exercises = exercises
...
class Training:
def __init__(self, name, exercises=list()):
self.name = name
self.exercises = exercises
...
class Exercise:
def __init__(self, name, details=dict()):
self.name = name
self.details = details
...
Here is the code of save_session()
:
def save_session():
"""Exports current data to .json file."""
data_to_save = {}
# add workout plans
for workout in workouts_instances:
data_to_save[workout.name] = {}
# add trainings
if workout.trainings:
data_to_save[workout.name]["trainings"] = {}
for training in workout.trainings:
data_to_save[workout.name]["trainings"][training.name] = {}
# add training exercises
if training.exercises:
data_to_save[workout.name]["trainings"][training.name]['exercises'] = {
exercise.name: {} for exercise in training.exercises
}
for exercise in training.exercises:
if exercise.details:
data_to_save[workout.name]["trainings"][training.name]['exercises'][exercise.name][
'details'] = {detail: value for detail, value in
exercise.details.items()}
# add exercises
if workout.exercises:
data_to_save[workout.name]["exercises"] = {}
exercises_to_save = data_to_save[workout.name]["exercises"]
for exercise in workout.exercises:
exercises_to_save[exercise.name] = {}
if exercise.details:
details = exercise.details
exercises_to_save[exercise.name]['details'] = {detail: value for detail, value in details.items()}
with open(WORKOUTS_FILE, 'w') as json_file:
json.dump(data_to_save, json_file, indent=4)
and here is the example of output, data stored in .json file:
{
"FBV - Full Body Workout": {
"trainings": {
"Training A": {
"exercises": {
"squats": {
"details": {
"description": "squats with barbell",
"series": 4,
"repeats": 4,
"load": 70
}
}
}
}
},
"exercises": {
"some exercise name": {
"details": {
"description": "some description",
"series": 5,
"repeats": 5,
"load": 60
}
},
"bench press - wide": {
"details": {
"description": "bench press with wide grip",
"series": 5,
"repeats": 5,
"load": 60
}
}
}
}
}
1 Answer 1
Some suggestions:
- Do not use mutable default arguments, they will mess with your subsequent calls. There are some very rare cases where mutable default arguments make sense, but this does not look like one of those.
- Split generation of data from saving that data to a file. That way either method can be reused. If you also pull out the file handle to a
main
method you can dependency inject the file handle and test the whole functionality. details
have the same pattern everywhere, so they should also be a class or should be part ofExercise
.- Like most Python code this could benefit from type annotations using MyPy.
save_session()
is one of the menu options in console app. All it has to do is to write data into dictionaries and dump it to .json later. All I want to know is how to build this dictionary of nested dictionaries in more proper way than it is right now. \$\endgroup\$