Class objects (instances) into dictionary in Python - python

I would like to create multiple instances of the Product Class and convert each instance as a new item in a dictionary.
I'm not pretty sure how to append the new object and its attribute values to the dictionary
This is my class:
class Product():
def __init__(self, id, name, descr):
self.name = name
self.id = id
self.descr = descr
This is the part that creates the Product objects and inserts them into the dictionary:
addProductToDict(id, name, descr, product_dict):
new_product = Product(id, name, descr)
# insert new product instance into dict
product_dict <--- new_product ### pseudo code
return product_dict
product_dict = {}
while True:
print(" Give the products id, name and description")
id = input("Give id: ")
name = input("Give name: ")
descr = input("Give descr: ")
product_dict = addProductToDict(id, name, descr, product_dict)
Desired dictionary format:
my_dict = {'1': {'id': '1', 'name': 'TestName1', 'descr': 'TestDescription1'}, '2': {'id': '2', 'name': 'TestName2', 'descr': 'TestDescription2'}, '3': {'id': '3', 'name': 'TestName3', 'descr': 'TestDescription3'}}

Given your desired output, I have modified my answer.
pprint(vars(new_product))
class Product():
def __init__(self, id, name, descr):
self.name = name
self.id= id
self.descr= descr
product_dict = {}
new_product = Product(1, 'Test Name', 'Test Description')
product_dict = pprint(vars(new_product))
This will give you the desired format but I think you will have issues if you have more than one item in your dictionary.

Perhaps you want to store them in a list instead of a dictionary, unless you have a key for each object
products = []
products.append(Product(1, 'Test Name', 'Test Description'))
edit
so, if you have a key
products = {}
_id = 1
products[_id] = Product(_id, 'Test Name', 'Test Description')

Related

How to receive any combination of an object's attributes and return the matching objects from a list of objects in Python?

I am sorry if this was answered before, but I could not find any answer for this problem at all.
Let's say I have this class and list of objects:
def Person:
def __init__(self, name, country, age):
self.name = name
self.country = country
self.age = age
persons = [Person('Tom', 'USA', 20), Person('Matt', 'UK', 19), Person('Matt', 'USA', 20)]
Now I would like the user to search for a person by entering any combination of attribute values and I want to return the objects that have all these values exclusively. For example, if the user enters: 'Matt', 'USA' and no age, I want the program to return the third person only who's Matt and is from the USA and not return all three objects because all of them have some of the entered combination of attribute values.
My implementation currently uses an if statement with the or operator which would return all the objects since the usage of or would return all the objects if one statement is True, which is what I am trying to solve.
Thanks in advance.
You can use a list comprehension for the task. And the if condition should check if the value is None else check in the list.
class Person:
def __init__(self, name, country, age):
self.name = name
self.country = country
self.age = age
def __repr__(self):
return "[{},{},{}]".format(name, country, str(age))
persons = [Person('Tom', 'USA', 20), Person('Matt', 'UK', 19), Person('Matt', 'USA', 20)]
name = "Matt"
country = "USA"
age = None
result = [
p for p in persons
if (name == None or p.name == name) and
(country == None or p.country == country) and
(age == None or p.age == age)
]
print(result) #[[Matt,USA,None]]

Is there a way to turn a many to many object relationship into a dictionary?

I have two classes
Club with property id and name
Student with property id, name and clubs (list)
One student can be part of multiple clubs.
One club can have multiple students
class Club:
def __init__(self, id, name):
self.id = id
self.name = name
class Student:
def __init__(self, id, name, clubs):
self.id = id
self.name = name
self.clubs = clubs
I want to have a dictionary where the key is club name and value is list of students.
I have around 30 different many to many relationships in the application.
Is there a way to do it in a generic way?
A crude inverter could be like below.
def reverse(elems, array_name, i_key):
dic = {}
for elem in elems:
for elem_field in elem[array_name]:
key = elem_field[i_key]
if key not in dic:
dic[key] = []
dic[key].append(elem)
return dic
club_a = { 'name': 'a'}
club_b = { 'name': 'b'}
club_c = { 'name': 'c'}
stud_a = { 'id': 1, 'clubs': [club_a, club_b]}
stud_b = { 'id': 2, 'clubs': [club_b, club_c]}
print(reverse([stud_a, stud_b], 'clubs', 'name'))
# a: stud_a
# b: stud_a, stud_b
# c: stud_b

Linking two lists based on a common value and

I am new to Python 2.7 and I want the 1st column as the key column in employees and it has to check on dept 1st column and generate results.
Employees comes from a text file and dept comes from a database. I tried a lot but didn't get an easy answer. What is wrong with my code?
**Inputs :**
employees=['1','peter','london']
employees=['2','conor','london']
employees=['3','ciara','london']
employees=['4','rix','london']
dept=['1','account']
dept=['2','developer']
dept=['3','hr']
**Expected Output :**
results=['1','peter','london','account']
results=['2','conor','london','developer']
results=['3','ciara','london','hr']
results=['4','rix','london',null]
your input makes no sense. Each line overwrites the previous one data-wise. Here it seems that the digits (as string) are the keys, and some default action must be done when no info is found in dept.
To keep the spirit, just create 2 dictionaries, then use dictionary comprehension to generate the result:
employees = dict()
dept = dict()
employees['1'] = ['peter','london']
employees['2'] = ['conor','london']
employees['3'] = ['ciara','london']
employees['4'] = ['rix','london']
dept['1']=['account']
dept['2']=['developer']
dept['3']=['hr']
result = {k:v+dept.get(k,[None]) for k,v in employees.items()}
print(result)
which yields a dictionary with all the info. Note that null is None in python:
{'1': ['peter', 'london', 'account'], '4': ['rix', 'london', None], '3': ['ciara', 'london', 'hr'], '2': ['conor', 'london', 'developer']}
You could go for a class. Consider this:
class Employee:
def __init__(self, number, name, location, dept):
self.number = str(number)
self.name = name
self.location = location
self.dept = dept
def data(self):
return [self.number,
self.name,
self.location,
self.dept]
peter = Employee(1, 'peter', 'london', 'account')
print(peter.data())
['1', 'peter', 'london', 'account']
>>>

Django How to iterate over list returned from ldap to save new object

I have the following model:
class SystemUsers(models.Model):
username = models.CharField(max_length=25)
displayName = models.CharField(max_length=100)
phoneNumber = models.BigIntegerField(max_length=10)
emailAddress = models.EmailField(max_length=100)
employeeNumber = models.CharField(max_length=7)
firstName = models.CharField(max_length=20)
lastName = models.CharField(max_length=30)
I have an ldap query that is returning the following from active directory:
user_details = []
for entry in results:
user_details.append(entry[1]['sAMAccountName'][0].lower())
user_details.append(entry[1]['displayName'][0].replace(",", " "))
user_details.append(entry[1]['telephoneNumber'][0].replace("-", ""))
user_details.append(entry[1]['mail'][0].lower())
user_details.append(entry[1]['employeeID'][0].lower())
user_details.append(entry[1]['givenName'][0])
user_details.append(entry[1]['sn'][0])
return user_details
I am getting results as expected but I can't parse out the list to put it into a SystemUser(....).save() block to save it to the database. All I get is a list I can't loop over or set variables for.
When I do a
for item in user_details:
print(item)
All I have are 7 lines of values. I can't get it so that item[0] is username, item[1] is displayname, etc, etc
You can create the dict with the user data and use the kwargs magic:
field_names = ('username', 'displayName', 'phoneNumber', 'emailAddress',
'employeeNumber', 'firstName', 'lastName', )
data = dict(zip(field_names, user_details)
SystemUser.objects.create(**data)
BTW may be it is a better idea to get the user_details as a dictionary from the beginning?
user_details = {
'username': entry[1]['sAMAccountName'][0].lower(),
'displayName': entry[1]['displayName'][0].replace(",", " "),
'phoneNumber': entry[1]['telephoneNumber'][0].replace("-", ""),
'emailAddress': entry[1]['mail'][0].lower(),
'employeeNumber': entry[1]['employeeID'][0].lower(),
'firstName': entry[1]['givenName'][0],
'lastName': entry[1]['sn'][0],
}
SystemUser.objects.create(**user_details)

Passing dictionary values as constructor's arguments

I am a newbie to Python. I need to create a simple student class which includes first name, last name, id, and a dictionary which maps course name to its grade.
class Student:
def __init__(self, firstName, lastName, id, _____ (dictionary values)):
self._firstName = firstName;
self._lastName = lastName;
self._id = id;
self.
My question is how can I initizalize the dictionary values inside the constructor?
For example, let`s say I would like to add 3 course to grade mappings:
"math: 100"
"bio: 90"
"history: 80"
For example:
student1 = Student("Edward", "Gates", "0456789", math: 100, bio: 90, history: 80)
The last 3 values should go into the dictionary.
Since the number of key-value which can be part of the dictionary can vary, what should I write in the constructor parameter signature?
I want to send all the student values when I call the constructor...
If you are looking to add a dictionary Mathias' answer suffices with the key word arguments in python.
However, if you wish to add object variables from the key word arguments, you require setattr
For example, if you want something like this:
student1 = Student("Edward", "Gates", "0456789", {'math': 100, 'bio': 90, 'history': 80})
print student1.math #prints 100
print student1.bio #prints 90
Then this will do the trick:
class Student(object):
def __init__(self, first_name, last_name, id, **kwargs):
self.first_name = first_name
self.last_name = last_name
self.id = id
for key, value in kwargs.iteritems():
setattr(self, key, value)
student1 = Student("Edward", "Gates", "0456789", {'math': 100, 'bio': 90, 'history': 80})
Note that **kwargs will unpack only something like dictionary or tuple of tuples. If you wish to send a list of values without keys, you should use *args. Check here to know more.
Python collects all keyword arguments for you.
class Student:
def __init__(self, firstName, lastName, id, **kwargs):
self._firstName = firstName;
self._lastName = lastName;
self._id = id;
self. _grades = kwargs
Here is an excellent explanation about kwargs in python
Why not send the complete grades dictionary to the your class and store it in a variable.
(Also please note that in Python there is no semicolon at the end of the line)
class Student:
def __init__(self, firstName, lastName, id, grade_dict):
self._firstName = firstName
self._lastName = lastName
self._id = id
self._grades = grade_dict
def get_grades(self):
return self._grades
and then when you want to initialize and use the grades:
student1 = Student("Edward", "Gates", "0456789", {'math': 100, 'bio': 90, 'history': 80})
grades = student1.get_grades()
for key, value in grades.items():
print 'Marks in {}: {}'.format(key, str(value))
Which prints:
Marks in bio: 90
Marks in math: 100
Marks in history: 80
You can try something like:
student = Student("Edward", "Gates", "0456789", {"math": 100, "bio": 90, "history": 80})
And inside your constructor you can copy these values to a new dictionary:
class Student:
def __init__(self, firstName, lastName, id, grades):
self._firstName = firstName;
self._lastName = lastName;
self._id = id;
self._grades = grades.copy()
Notice that we're copying the dictionary to a new attribute because we want to avoid keeping a reference.
First, make sure to remove the semicolon ; from your code - it won't compile!
Second, I believe you're looking to do something like:
class Student:
def __init__(self, first_name, last_name, _id, **courses):
self._first_name = first_name
self._last_name = last_name
self._id = _id
self.courses = courses
def print_student(self):
print self._first_name
print self._last_name
print self._id
for key in self.courses:
print key, self.courses[key]
courses = {'math': 100, 'bio': 90, 'history': 80}
s = Student("John", "Smith", 5, **courses)
s.print_student()
OUTPUT
John
Smith
5
bio 90
math 100
history 80

Categories

Resources