I have 2 classes, one inherits from the other. I need instances of WOFPlayer to take 1 required parameter - name, 2 optional and instances of WOFComputerPlayer to take 2 required parameters - name and difficulty and 2 optional as in the WOFPlayer. How do I do that?
Here's what I have tried
class WOFPlayer:
def __init__(self, name, prizeMoney = 0, prizes = []):
self.name = name
self.prizeMoney = prizeMoney
self.prizes = prizes[:]
class WOFComputerPlayer(WOFPlayer):
def __init__(self, difficulty):
WOFPlayer.__init__(self, name, prizeMoney = 0, prizes = [])
self.difficulty = difficulty
Thanks in advance
I need instances of WOFPlayer to take 1 required parameter - name, 2 optional
I would strongly suggest you don't use a mutable object (the list in this case) as a default argument. Here's why.
and instances of WOFComputerPlayer to take 2 required parameters - name and difficulty and 2 optional as in the WOFPlayer
You need to pass in the values from WOFComputerPlayer to its base class. That is, pass in name to WOFComputerPlayer.
class WOFComputerPlayer(WOFPlayer):
def __init__(self, name, difficulty, prize_money=0, prizes=None):
WOFPlayer.__init__(self, name, prizeMoney=prize_money, prizes=prizes)
self.difficulty = difficulty
You are closer than you think.
class WOFPlayer:
def __init__(self, name, prizeMoney=0, prizes=None):
self.name = name
self.prizeMoney = prizeMoney
if prizes is None:
prizes = []
self.prizes = prizes[:]
class WOFComputerPlayer(WOFPlayer):
def __init__(self, name, difficulty, prizeMoney=0, prizes=None):
super().__init__(name, prizeMoney, prizes)
self.difficulty = difficulty
Note that I replaced passing a mutable value as a default argument. [] as default argument will mutate anytime that value is mutated, which can be a recipe for a bug. But the rest of the code is yours.
Related
I have a parent class as follows:
class student:
def __init__(self, name, age, field):
self.name = name
self.age = age
self.field = field
def abilities(self):
abs = ["study", "drink", "party"]
action = np.random.choice(abs, replace = True)
return(action)
Now upon graduation this student becomes a grown-up and his abilities change:
class adult(student):
def abilities(self):
super().abilities()
abs.append("work")
abs.remove("party")
if action == work:
print("paying off that student loan")
This does not work. The error I get is: name 'abs' is not defined.
Now I tried to access the abilities method in the parent class by using super().abilities.abs but then I am referring to the object the function returns and with self.abilities.abs, but then I refer to the class.
Any suggestions as to how to access the array within the parent method from the child are much appreciated.
There are a few flaws in the code you wrote:
You are overwritting a built in function abs in your code. This should not be done.
You are calling super().abilities(), which returns a value without storing and using it.
When calling abs.append("work") you are trying to assign a value to a build in function and not the local variable abs from the parent. Extracting this to a object variable solves the issue. See, self.abs in the constructor
The adult abilities method is not returning anything.
You are not calling the super constructor in adult, which results in adult not storing any of the values passed in the constructor.
A fixed version could look as follows:
import numpy as np
class student:
def __init__(self, name, age, field):
self.name = name
self.age = age
self.field = field
self.abs = ["study", "drink", "party"]
def abilities(self):
action = np.random.choice(self.abs, replace = True)
return action
class adult(student):
def __init__(self, name, age, field):
super(adult, self).__init__(name, age, field)
self.abs.append("work")
self.abs.remove("party")
def abilities(self):
action = super().abilities()
if action == "work":
print("paying off that student loan")
return action
In addition to solving this issue, you should review the object inheritance structure as mentioned in the comment by #chepner.
I want to make a method whose arguments are an arbitrary class and a list of instances.
let's say the name of the class is 'Price' and the name of the list is 'price_list'
def CreateHTML(_class, _list):
one_instance = _class
list_members = list(one_instance.__dict__) ##to get the list of member variables' names
n= len(list_members)
CreateHTML(Price(), price_list)
but the problem is that it works well only if I initially set 'None' values to all arguments of 'Price' class.
class Price:
def __init__(self, name= None, data = None):
self.name = name
self.data = data
is there any ways that the assignment of 'None' values can be automatically handled inside the CreateHTML method??? so that i don't need to initially set Nones to the class. (like below)
class Price:
def __init__(self, name, data):
self.name = name
self.data = data
Thanks!!!
CreateHTML(Price(), price_list) : here Price is expecting 2 items 'name' and 'data'. You have to either pass it while calling the Price('name', 'data') or you have to pass None in your init
As also noted in my comment above, Price() isn't a class, it is an instance of the class Price. By calling Price() you are essentially instantiating Price with all variables as None. This will only work if Price has default argments such as is set with def __init__(self, name= None, data = None).
If you want a general method with which to instantiate arbitrary classes, you can create something like the following, which takes an arbitrary class and instantiates it will arbitrary arguments (*args) and keyword arguments (**kwargs):
class Price:
def __init__(self, name, data):
self.name = name
self.data = data
def create_instance(my_class, *args, **kwargs):
return my_class(*args, **kwargs)
def CreateHTML(one_instance):
list_members = list(one_instance.__dict__) ##to get the list of member variables' names
n= len(list_members)
print(f"This instance has {n} members")
one_instance1 = create_instance(Price, name="Hello", data="World")
one_instance2 = create_instance(Price, name=None, data=None)
CreateHTML(one_instance1)
CreateHTML(one_instance2)
You can use create_instance for any class and any arguments, e.g.:
class SomeClass:
def __init__(self, foo, bar):
self.foo = foo
self.bar= bar
one_instance3 = create_instance(SomeClass, "hello", bar="World")
Although to be honest, you don't really gain some much from this. Might as well just use:
one_instance1 = Price(name="Hello", data="World")
one_instance2 = Price(name=None, data=None)
one_instance3 = SomeClass("hello", bar="World")
So I'm reading through An Introduction to Programming Using Python and doing the exercises for my own edification. I'm learning about custom classes and get to a part where it states: "The program should use a class named Quizzes that has an instance variable to hold a list of the six grades..." So I tried the following:
class Quizzes:
def __init__(self, grade1=0):
self._grade1 = grade1
def setGrade1(self, grade1):
self._grade1 = grade1
def getGrade1(self):
return self._grade1
def grades(self):
return []
def gradeInsert(self, a=grades()):
a.append(self._grade1)
In this case, I get "TypeError: grades() missing 1 required positional argument: 'self'.
I've also tried:
def __init__(self, grade1=0, grades=[]):
self._grade1 = grade1
self._grades = grades
def setGrade1(self):
self._grade1 = grade1
def setGrades(self):
self._grades = [self.getGrade1()]
def getGrades(self):
return self._grades
But I get a blank [ ]. Any modification I do to grades=[ ] in _ init _ reflects in my getGrades call. So how do I get setGrades to actually set? Or am I totally off the mark?
Instance variables should be initialized inside of __init__
class Quizzes:
def __init__(self):
self._grades = [] # Here, we initialize the list
def grades(self):
return self._grades # We can return the instance variable here
def gradeInsert(self, a): # No reason for a default argument here
self._grades.append(a) # Add the value to the list
In your first example you try to call grades() which is a member function of the Quizzes class. Member functions expect the instance as the first argument, either before the dot (the_instance.grades()) or as (less common) as an explicit argument (grades(the_instance)). You provide neither and thus Python complains.
In your second example it is not clear what you actually do after the class is defined.
In general, the two classes do not have much to do with the exercise, which would be solved by the following:
class quizzes(object):
def __init__(self, grades = None):
if grades is None:
self.grades = [0]*6
else:
self.grades = grades[:6]
BTW: it is not recommended to use a mutable object as default argument as this object is shared between all invocations.
So I have this code:
class vehicle(object):
def __init__(self):
self.age = 6
self.make = 8
self.colour = 'colour'
self.cost = 'cost'
class car(vehicle):
def __init__(self):
vehicle.__init__(self)
self.type = 'car'
car1 = car()
print car1.make, car1.colour, car1.cost, car1.type, car1.age
n = raw_input()
dic = {'name' : n}
dic['name'] = car()
print dic['name'].make
In the last bit, I was able to resolve a previous issue I had: Creating an instance of the car class with its name being one that the user inputs in n
Now, say I wanna ask the user to input a name and now I have to find the class' instance that has that name.
For example if at one point an instance with the name car2 was created. Now user wants to get info about car2 and inputs 'car2'. how can I use this input to access attributes of the instance called car2?
I tried:
a = raw_input()
dic['fetch'] = a
dic['fetch'].make
does not work.
It seems to me you have a fair bit of misunderstanding. The way you're assigning the input into the dictionary doesn't make sense. Your description indicates that you want a dictionary that maps a "name" to a car description.
Your initial creation of the dictionary is off. The way you're currently doing it, you're actually losing the name the user inputs when you assign the car data. Some better variable naming might help you. Create your dictionary like this:
cars_by_name = dict()
name = raw_input()
cars_by_name[name] = car()
So now you have a name (given by the user) that maps to a car description.
Now you need to fetch that same car instance again. You do it by using the name as the key in the dictionary:
name2 = raw_input()
print cars_by_name[name2].make
Next, let's look at your classes. My first question: why do you need a vehicle and a car class? If you're never going to have classes other than car inheriting from vehicle, you don't really need them both. Even if you do plan the have more subclasses, I would probably still recommend against inheritance here. Your vehicle has no behavior (methods) for subclasses to inherit. It's just a data object. With duck typing so strongly encouraged in Python, inheriting from a class with no methods doesn't buy you anything. (What a base class would buy you with methods is that you'd only have to define the method in one place, making it easier to modify later on.) Particularly in your case, there doesn't seem to be any motivation to create a subclass at all. A single class for all vehicles will work just fine. So let's simplify your classes:
class Vehicle(object):
def __init__(self):
self.age = 6
self.make = 8
self.colour = 'colour'
self.cost = 'cost'
self.type = 'car'
(Also, note that class names are usually given in camel case in Python.) Now there's one more problem here: those constants. Not all Vehicles are going to have those same values; in fact, most won't. So lets make them arguments to the initializer:
class Vehicle(object):
def __init__(self, age, make, colour, cost, type):
self.age = age
self.make = make
self.colour = colour
self.cost = cost
self.type = type
Then you create one like this:
v = Vehicle(6, 8, 'colour', 'cost', 'car')
Good luck in your endeavors learning. Hope this helps.
If I understand you correctly and you want to map string names to instances:
n = raw_input()
dic = {n: car()}
print dic[n].make
print(dic)
dic[n].cost = 10000
print(dic[n].cost)
Another option would be to take a name for each car instance and have a class attribute dict mapping names to self.
In [13]: paste
class vehicle(object):
def __init__(self):
self.age = 6
self.make = 8
self.colour = 'colour'
self.cost = 'cost'
class car(vehicle):
dic = {}
def __init__(self, name):
vehicle.__init__(self)
car.dic = {name: self}
self.type = 'car'
self.name=name
car1 = car("car1")
car2 = car("car2")
car2.colour="blue"
print car1.make, car1.colour, car1.cost, car1.type, car1.age
n = raw_input()
print car.dic[n]
print car.dic[n].make
print car.dic[n].colour
## -- End pasted text --
8 colour cost car 6
car2
<__main__.car object at 0x7f823cd34490>
8
blue
I have no idea what is wrong! This is a very simple program and I have done a lot head banging! Please someone enlighten me!
This a lab problem from the CSE 111 - Programming Language II course. They teach Java at the university and the code I wrote in Java works fine.
I just have to create a Student class with some fields to hold the basic information about a student with methods to get and set the attributes. Then create an instance of that class and tryout the methods.
But every time I run this program the following error occurs:
TypeError: set_name() takes exactly 1 positional argument (2 given)
Here is the code I wrote.
class Student:
'''Student class'''
name = None
id = 0
address = None
cgpa = None
def get_name():
return name
def set_name(n):
name = n
def get_id():
return id
def set_id(i):
id = i
def get_address():
return address
def set_address(a):
address = a
def get_cgpa():
return cgpa
def set_cgpa(c):
cgpa = c
#An object of Student class
jack = Student()
jack.set_name('jacky')
print(jack.get_name())
You're not accepting a reference to your instance as the first argument to that method, i.e. your set_name() should be written:
def set_name(self, n):
self.name = n
This is somewhat different from other languages where there is a built-in keyword (such as this) that refers to the current object. Python passes that reference explicitly, as an argument to the method.
All your other methods must be modified similarly.
Note that just setting name = n sets a local variable name which goes away when the method ends; it does not set anything on the instance. You have to explicitly set self.name if you want an instance attribute.
Also, and this is a matter of style, but you do not usually write set and get methods in Python. It is normal practice to set and get attributes directly. If you want to do validation of values, use a property instead. So basically, none of your methods are actually necessary in good style.
However, you don't have an __init__() method. Usually you would pass the desired attributes of the instance when instantiating the class and save these on the instance.
class Student:
def __init__(self, name, id, address, cgpa):
self.name = name
self.id = id
self.address = address
self.cgpa = cgpa
herman = Student("Herman Munster", 12345, "1313 Mockingbird Lane", 4.0)
Try this:
import sys
class Student:
'''Student class'''
self.name = None
self.id = 0
self.address = None
self.cgpa = None
def get_name(self):
return self.name
def set_name(self, n):
self.name = n
def get_id(self):
return self.id
def set_id(self, i):
self.id = i
def get_address(self):
return self.address
def set_address(self, a):
self.address = a
def get_cgpa(self):
return self.cgpa
def set_cgpa(self, c):
self.cgpa = c
You need to pass self as the first argument to each member function of the class. Member variables must then be referred to with self, i.e. self.name. Furthermore, you may wish to include an __init__() function; this serves usually to initialize any member variables, and is called at the instantiation of the class.
Take a look at the Python documentation here for some examples on well-formed classes: http://docs.python.org/tutorial/classes.html#random-remarks
In Python, you need to pass in self for each of your member functions. You also need to reference class variables as self.x, if you want them to take an effect.
Here are a couple examples that you need to apply to the rest of your code.
def set_name(self, n):
self.name = n
def get_cgpa(self):
return self.cgpa
There is some explanation for why this is the case in the documentation.
This is because first argument of methods is self - the class instance.
See What is the purpose of self?
and http://docs.python.org/tutorial/classes.html#class-objects