Open montesmariana opened 1 year ago
Thank you for the explanations! I think I understand, I'll try to incorporate it into my script as soon as I'm done with the passing requirements and I'll let you know if it turns out that I didn't understand it well enough to make it work.
After trying to implement it, I run into two problems:
I worked in the Jupyter Notebook "Final-assignement_trial-and-error_7_linking classes" for this part.
Many thanks in advance!
For the first problem: your file (especially if you want it to be readable beyond your module) won't know that something is from class Freelancer. But you can have the data of the freelancer as a nested dictionary OR use an id.
Nested dictionary = when you store the JSON of the project, the "translator" and "reviewer" don't have a string as value but an object with all the properties of the Freelancer class (attributes, not classes) ID = if your freelancer data has a unique ID for each translator/reviewer, you can use that as the string value of "translator" / "reviewer" in the JSON of your project, and that already lets you know how to retrieve the freelancer's information from their database.
Is that clear? (If you need we can chat)
For the second question: you can use a comprehension list instead. For loops are for dealing with one item at a time. If you want to "transform" your list, e.g. turn your list of dictionaries into a list of Project instances, you can use a comprehension list, e.g:
my_projects = [Project(x) for x in my_dictionary]
And then my_projects
is a list of Project
instances. You could also make it a dictionary instead. Say that each element in my_dictionary
is a dictionary that you use to instantiate the Project
AND it has a name
attribute that is unique. You can do:
my_projects = { x['name'] : Project(x) for x in my_dictionary }
And if you have a project with name
project_00
, then my_projects['project_00']
will be that Project
instance.
Let me know if anything is not clear!
It's a bit tough to comment on a Jupyter Notebook via the PR because it's not really plain text, so I'll leave here some notes about "Final-assignement_trial-and-error_7_linking classes".
id
as a variable / function argument (you can see that Python already gives it a different color: it's a reserved word, like if
)for key, value in dictionary.items():
setattr(self, key, value)
It is not a bad idea BUT it is less robust in that it doesn't offer any validation if the inputted data is wrong. You are not adding validation in this class anyways yet (as long as you have validation in the other class AND you mention it in the docs as "future feature", that's fine), but it will make it harder to add it later, I find.
If you want to provide a dictionary instead of many separated arguments, you can use **kwargs
(which I did not teach because it was a bit too much, but I think you can handle it. You seem to have the need for it.) - Some docs
So: in your case you could keep the class like Freelancers', but with
kwargsas argument, then check for each argument and validate (eventually, not necessarily for this submission), so that a user can either do
Freelancers(name = "Some name", email = "email@email.com")or
Freelancers(my_dictionary)and both would do the same. You can also apply that to your
Project` class. Let me know if anything is not clear!
Ok, now looking at your notebook a bit more I finally understand why you want to put everything in one JSON. Don't! You don't need that.
My suggestion was something like this:
You have one JSON with a list of projects, or one JSON per project (or a csv with one row per project, whatever). Think what makes the most sense in practice, and if you're still unsure of how to implement it, hit me up. Say that you have one JSON per project, such as "lit_translation_001.json", "tech_translation_002.json", etc.
Then you have another JSON (or csv with one row per person) that has the information of each translator. So that the info of each translator is registered only once, in one place: you don't repeat it in the file of the projects. Say this is called "freelancers.json".
So, in the project's JSON, the translator / reviewer will be just a string with a unique ID, which can be some randomly generated ID or the person's name, as long as it's unique. You are already trying to use ID, so let's say you use ID (and thus allow for different people with the same name and/or email).
When you instantiate your Project, the data that you receive from the JSON is just that ID. But if you also have the JSON of the translators, you can retrieve the right freelancer based on that ID. For example:
with open('freelancers.json', 'r') as f:
my_freelancers = {x.id : x for x in json.load(f)} # if the json is a list of dictionaries
with open('lit_translation_001.json', 'r') as f2:
project_dict = json.load(f2)
if 'translator' in project_dict and project_dict['translator'] in my_freelancers:
project_dict['translator'] = Freelancer(**my_freelancers[project_dict['translator']])
if 'reviewer' in project_dict and project_dict['reviewer'] in my_freelancers:
project_dict['reviewer'] = Freelancer(**my_freelancers[project_dict['reviewer']])
project = Project(**project_dict) # of course you have to allow
Then you should also check that translator
and reviewer
are either strings (your default) or of class Freelancer (type(translator) == str or type(translator) == Freelancer
).
The if
statements I added check that there is a 'translator' / 'reviewer' value in your dictionary and that the value is one of the IDs in the freelancers database.
Just an update to let you know that linking these two classes now works! Many thanks for your help! :)
The idea as I suggested it (but keep asking if it's still not clear) is to create a class that represents a translator (
FreeLancer
) and have the values oftranslator
andreviewer
be instances of that class. Whether the employee is "Internal" could be an attribute ofFreeLancer
.I will not write the class for you, but only describe the behaviour as I'm envisioning it. Note that in this case the
translator
andreviewer
attributes of yourProject
class (exTranslation_agency
?) would not be class attributes but instance attributes (because they are specific of each project), and instead of strings they would be instances ofFreeLancer
. So you would have something like this:As we discussed in class, maybe the translator, reviewer, or other arguments are set at initialization (as arguments when you instantiate the class), or with methods. I illustrated here with methods but you could have
translator = tr, reviewer = rev
inside yourProject()
call. Then when you callproject.reviewer
you get an instance of theFreeLancer
class, which maybe has its own print statement.project.reviewer.name
will print the name,project.reviewer.is_internal
whether they are internal (so, "Mariana Montes" andTrue
respectively, in this example)... And when designing what you print in the__str__()
call of theProject
class, you can access the information from within withself.reviewer.name
,self.reviewer.is_internal
, etc...Is that a bit more clear?