Is there a way to get an object by matching it up with its attributes?
For example:
class band:
def __init__(self, name, number):
self.name = name
self.number = number
rivers = band("rivers", 1)
patrick = band("pat" , 2)
brian = band("brian" , 3)
scott = band("scott", 4)
In this code, is there a way for me to use a number(lets say 1), to find the object rivers within the band class and get its name attribute?
Thank you for taking your time to read this and have a nice day.
In this code, is there a way for me to use a number(lets say 1), to find the object rivers within the band class and get its name attribute?
In this code, NO. Because you do not save the value of name to the class property.
However, if your class structure was like:
class band:
def __init__(self, name, number):
self.number = number
self.name = name # <--- Here is the difference
you could have done it. Let say rivers, patrick, brian and scott are part of the list as:
my_list = [rivers, patrick, brian, scott]
Iterate over the list and print the name of class for which value of number is 1 as:
for item in my_list:
if item.number == 1:
print item.name
You may store a dictionary mapping number to band in order to achieve that.
For example
bands = {}
class band:
def __init__(self, name, number):
self.number = number
self.name = name
bands[number] = self
def getBandFromNumber(number):
return bands[number]
Related
I have just started learning OOP in python and I have learned basics like creating class and it's methods, variables and Constructors. Now to create an object we use following steps.
class Example: #Class
name = None
number = None
def __init__(self, name, number): #Constructor
self.name = name
self.number = number
#Step 1
harry = Example("Harry", 45) #Creates an Object
Now here we have manually created Object of Example class named harry.
I have a question that how to create an object with a function.
Like we created a function outside the class and we passed arguments to like name and number and when that function is called it will create a Object of class.
Are you looking for something like this ?
def build_object(name, number):
# returns Example object initialized with name and number
return Example(name, number)
You're talking about Factory Methods
To create objects in functions and returning it would be like:
class Example:
def __init__(self, name, number):
self.name = name
self.number = number
def object_creator(name, number):
new_obj = Example(name, number)
return new_obj
if __name__ == "__main__":
example_object = object_creator("Iago", 1)
print(example_object.name)
print(example_object.number)
Not sure what do you mean exactly.
in oop you can create a function/method then you can from it's object or class.
class Example: #Class
name = None
number = None
def __init__(self, name, number): #Constructor
self.name = name
self.number = number
def your_function(self, x, y):
return x + y
#Step 1
harry = Example("Harry", 45) #Creates an Object
result = harry.your_function(5, 2)
print (result)
output : 7
I'm new to python and as I was doing an assignment for class, I got stuck using init method.
class Customer(object):
def __init__(self, number, name):
self.name = name
self.number = number
self.orders = []
def addorder(self, order):
self.orders.extend(order)
return self.orders
def __str__(self):
return str(self.orders)
Customer('308','John').addorder((1,2,3,4))
print(Customer('308','John'))
The output is an empty list [].
I want the output to be [1,2,3,4]
What am I doing wrong here?
The issue is that you have two Customer objects. I.e. your print line:
print(Customer('308','John'))
Is creating a new Customer object with a number of '308' and a name of 'John'. It's completely unrelated to the customer on the previous line.
To fix this, you should assign your first object to a variable (think of it like a handle, that lets you access the object), and then print that:
john = Customer('308','John')
john.addorder((1,2,3,4))
print(john)
You're creating two instances of the class
class Customer(object):
def __init__(self, number, name):
self.name = name
self.number = number
self.orders = []
def addorder(self, order):
self.orders.extend(order)
return self.orders
def __str__(self):
return str(self.orders)
customer = Customer('308','John')
customer.addorder((1,2,3,4))
print(customer)
Keep in mind that each time you "call" a class, you instantiate a new object (this is why in many languages other than Python, this actually requires the keyword new). So, in your example, you're instantiating two different objects (that don't share their properties). Instead, you should save them in a variable:
customer = Customer("308", "John")
customer.addorder((1, 2, 3, 4))
print(customer)
I have defined a python class that has name and age attributes. I'm trying to print the oldest and longest name of objects in this class.
the oldest works fine but to find the longest name I can't use one function with len() and max() since len() does not take more than one argument . I have to define the name length as an attribute first and then define the max. Copy of my code is below. I appreciate your help :)
class NewClass:
def __init__(self, name, age):
self.name = name
self.age = age
self.length = len(name)
def Oldest(*args):
return max(args)
# def Longets(*args): this doesn't work since len takes one argument only
# return max(len(args))
def Longest(*args):
return max(args)
person1 = NewClass('Cindy', 24)
person2 = NewClass('Amy', 28)
person3 = NewClass('fifififi', 27)
print(f'The oldest person is {Oldest(person1.age,person2.age,person3.age)} years old')
print(f'longest name has {Longest(person1.length,person2.length,person3.length)} character')
You can use a list comprehension:
def Longets(*args):
return max([len(arg) for arg in args])
I am generating a list of employees and managers. However, I obtained this weird output after trying sort them by last name (my initial class employee only contains "name" but not divide into first name and last name. Then, I use [1] to indicate the last name). What's wrong with my code since I can't see my list of employees.
class Employee:
def __init__(self, name, socialSecurityNumber, salary):
"""
Set name, socialSecurityNumber, and salary to itself.
"""
self.name = name
self.socialSecurityNumber = socialSecurityNumber
self.salary = salary
employeeList = []
employee1 = Employee("Banny Chu", "777-88-9999", 45000)
employee2 = Employee("Luffy Monkey", "555-66-9999", 32000)
employee3 = Employee("Zoro Nonoroa", "222-00-3333", 37000)
manager1 = Manager("Scalt Haight", "444-33-1111", 60000, "Lab", 2300)
manager2 = Manager("Kapu Ro", "333-44-2222", 65000, "General", 2600)
manager3 = Manager("Nami Swan", "111-77-6666", 80000, "HR", 3000)
employeeList.append(employee1)
employeeList.append(employee2)
employeeList.append(employee3)
employeeList.append(manager1)
employeeList.append(manager2)
employeeList.append(manager3)
print (sorted(employeeList, key=lambda employee: employee.name[1].lower()))
Output as below (strange output since I can't see my employeeList in the correct format even though I type print(employeeList) and gave the same format as below.
[<employee8.Employee object at 0x105a48b00>, <manager8.Manager object at 0x1054290f0>, <manager8.Manager object at 0x1054290f0>, <manager8.Manager object at 0x1054290f0>, <manager8.Manager object at 0x1054290f0>]
What should I modify it so that I can see my sorted list in the way that I can clearly see them?
By default, user-defined objects will be represented as a class instance at a location in memory:
<__main__.Employee instance at 0x02A39940>
You will need to add a special method for object representation in your Employee class:
class Employee:
def __init__(self, name, socialSecurityNumber, salary):
"""
Set name, socialSecurityNumber, and salary to itself.
"""
self.name = name
self.socialSecurityNumber = socialSecurityNumber
self.salary = salary
def __repr__(self):
return self.name # represents object with name
You're missing the point that sorted returns a permutation of the list that got sorted based on the criteria you sent it. It doesn't automagically return just the keys you sorted them on if that's what you were expecting?
sort = sorted(employeeList, key=lambda employee: employee.name[1].lower())
print([emp.name.split()[1] for emp in employeeList])
Output (I was lazy and only copy pasted 3 of your employees):
['Chu', 'Monkey', 'Nonoroa']
You were also missing a split, because you save your name in a single string. Indexing a single string will return a single character at that location in a string.
If your goal wasn't to print out just the last names, then you have to override either the __str__ or __repr__ method. (Read about what exact difference is between the methods here.)
You forgot to split the name in the key function: employee.name.split(' ')[1].
Python calls __repr__ on the sorted list which prints '[' and ']' at the beginning and end and then calls __repr__ on each list element. The default __repr__ prints the object type and address. If you want to see something else, you have to give python another __repr__ to call.
class Employee:
def __init__(self, name, socialSecurityNumber, salary):
"""
Set name, socialSecurityNumber, and salary to itself.
"""
self.name = name
self.socialSecurityNumber = socialSecurityNumber
self.salary = salary
def __repr__(self):
return "{} {} {}".format(self.name, self.socialSecurityNumber, self.salary)
class Manager(Employee):
def __init__(self, name, socialSecurityNumber, salary, department, unknown):
super().__init__(name, socialSecurityNumber, salary)
employeeList = []
employee1 = Employee("Banny Chu", "777-88-9999", 45000)
employee2 = Employee("Luffy Monkey", "555-66-9999", 32000)
employee3 = Employee("Zoro Nonoroa", "222-00-3333", 37000)
manager1 = Manager("Scalt Haight", "444-33-1111", 60000, "Lab", 2300)
manager2 = Manager("Kapu Ro", "333-44-2222", 65000, "General", 2600)
manager3 = Manager("Nami Swan", "111-77-6666", 80000, "HR", 3000)
employeeList.append(employee1)
employeeList.append(employee2)
employeeList.append(employee3)
employeeList.append(manager1)
employeeList.append(manager2)
employeeList.append(manager3)
for employee in sorted(employeeList, key=lambda employee: employee.name.split(' ')[1].lower()):
print(employee)
I need to extract data from external source. I build a base clas with some structure. I need objects with type of myBase class but with a name which automatically describes how many times I iterate over the source. I build a class which stores this number and with a call method which returns the object I need. I can't find a way to have a string as the name for the object but automatically differ every time I build new object.
I simplified the code for this example:
class myBase:
def __init__(self):
iteratedValue = None
class myIterator:
def __init__(self):
self.k = 0
def __call__(self, s):
self.k += 1
self.name = 'myData' + str(self.k)
# create an object named myData1, myData2 ...
self.name = myBase()
self.name.iteratedValue = s
print '%s name is %s for k = %i' % (self.name, self.name.iteratedValue, self.k)
# return object named myData1 type of myBase
return self.name
def DataExtraction():
# function to extract data form external source
data = myIterator()
data('Alice')
data('Ben')
DataExtraction()
My output is:
<__main__.myBase instance at 0x7f261b6dc6c8> name is Alice for k = 1
<__main__.myBase instance at 0x7f261b6dc6c8> name is Ben for k = 2
I need to return an object with a specific name and I expect an output:
myData1 name is Alice for k = 1
myData2 name is Ben for k = 2
The original problem is much more complicated. I have external data and every time they come I want to extract some values from this data. Every time I am doing this I need an object to work with it but I need this object with different names because on the end I store them in dict for another methods. In other words I work with data and store my results in the object myData1 when the original data change I work with it again and store the results in myData2 etc. After all I need all myData objects and do statistics on them to see how the change. I do not have access to original data any more. I need automatic name convention for myData and the best if it will express iterator.
How can I have a string in place of self.name as the name for an object?
It looks like you would be better off using generators. Here's some example code that reads data (actually it's hard-coded like in your example), and then construct Datum objects with the indexed name.
class Datum(object):
def __init__(self, index, value):
self.name = 'myData%d' % (index + 1)
self.value = value
def read_data():
yield 'Alice'
yield 'Ben'
def enumerate_data():
for i, value in enumerate(read_data()):
yield Datum(i, value)
for d in enumerate_data():
print d.name, d.value
You're already doing it with self.name = 'myData' + str(self.k). The problem is that you immediately overwrite it with self.name = myBase(). I'm not sure what you're trying to do with that myBase(), but you probably want to separate it from the name. self.name can be either a string or a myBase object, but it can't be both.
Perhaps you can do:
self.name = 'myData' + str(self.k)
self.base= myBase()
self.base.iteratedValue = s
print '%s name is %s for k = %i' % (self.name, self.baseiteratedValue, self.k)
This way you can have both the name and the "base", as separate attributes self.name and self.base.
Alternatively, you can give the myBase class a __str__ method. This will affect what shows up when you use print on a myBase object. However, to do that you'll have to pass in the desired name when you instantiate myBase, something like:
class myBase(object):
def __init__(self, name, iteratedValue):
self.name = name
iteratedValue = iteratedValue
def __str__(self):
return self.name
class myIterator(object):
def __init__(self):
self.k = 0
def __call__(self, s):
self.k += 1
name = 'myData' + str(self.k)
self.name = myBase(name, s)
print '%s name is %s for k = %i' % (self.name, self.name.iteratedValue, self.k)
# return object named myData1 type of myBase
return self.name
I'm not sure which of these ways (or perhaps some other way) is what you're looking for. What's puzzling is that you are making the "name" of the object be a myBase instance. I'm not sure what you're intending the "name" of your object to represent, but I wouldn't usually expect an object's name to be some other object.
Incidentally, it looks like you're using Python 2, in which case you should define your class with class someClass(object). Including the object makes your classes new-style classes, which is basically what you always want.
Edit: If what you're trying to do is actually create a variable called myData1 based on the string, so you can do myData('Alice') and then somehow magically have the variable myData1 refer to that object, the answer is "Don't do that." If you want to create a bunch of objects and access them in a structured way by numbers or other labels, use a list or a dictionary.
Why worry about naming your objects at all, why not just put them in a dict?
myObjects = {1:Alice(), 2:Bob()}