Beginner, Python Class Not Printing - python

I'm a beginner. I'm doing my best. Please go easy on me. My task is to create a class called "person" with one method "hello" and one attribute "name" which represents the name of a person. In the end it should print "My name is X and I am a Y, where X is the sys.argv[1] name and Y is the name of the class. I'm supposed to instantiate an object of the class, run the hello method and print the name of the class. My brain is a bit fried and I'm at a loss. Please help. I feel like I'm moving in circles and getting no where. Here's what I've got so far:
import sys
class person():
def __init__(self, name):
self.name = name
def hello(self):
print(f'My name is {self.name} and I am a {__class__.__name__}.')
print(person1.hello())
person(sys.argv[1])
person1=person(sys.argv[1])
print(str(person.__class__))
So far its not printing anything at all.

This one is working.
class Person():
def __init__(self, name):
self.name = name
def hello(self):
print(f'My name is {self.name} and I am a {__class__.__name__}.')
my_person = Person('John')
my_person.hello()
The Output:
My name is John and I am a person.
Suggestion:
For convention classes are named with first letter Capital to distinguish of the instances.

Related

What happens when python imports a class with composition?

Despite of this question being answered:
How to import a class with composition from a module?
I still don't understand the functioning of importing composite classes in python.
The following is a kind of long code but very basic. In a file called example.py there are three classes, Employee, Car and Company. Company calls Employee and employee calls Car.
Employee has a static method which does not work, simply returns a variable that does not exists.
example.py:
class Employee():
def __init__(self,name):
self.name = name
def add_employee_atribute(self):
if ' ' in self.name:
self.completename='created with method class: ^' + self.name.title()
def upperit(self):
return self.name.upper()
#staticmethod
def empstatic(myname):
return myname+myname
#staticmethod
def empstatic_wrong():
# this is wrong
return ERROR
def add_car(self,make):
self.car = Car(make)
class Car():
def __init__(self, make):
self.car = make
class Company():
def __init__(self,name,people):
self.name=name
self.employees=[]
for person in people:
self.employees.append(Employee(person))
def get_all_employess(self):
return 'These are all: ' + ', '.join([e.name for e in self.employees])
def get_employee(self,name):
for e in self.employees:
if e.name == name:
return e
Now if I want to use Company in a file I go:
work.py:
from example import Company
C = Company('kodak',['peter','john smith'])
C.employees[1].add_employee_atribute()
C.get_all_employess()
peter = C.get_employee('peter')
peter.add_car('BMW')
This all works.
Python seems to evaluate the imported code (Company) in work.py in a way that realises that Company needs Employee and Employee needs Car. Very clever. So it looks like python looks for the classes when they are called. Nevertheless python does not realise that the variable 'ERROR' does not exist.
So what puzzles me is the fact that python is able to distinguish, look for the composite classes but not for the variables.
Some explanation about this?

Python3 Class method inputs; clean solution

I'am using more class based programs, however in some cases it's not handy to provide all self.paramets into a class.
In those cases I want to use a regular input into a function in a class. I figured out a way to achieve both inputs, let me show this in following script:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def myfunc(a):
if (type(a) == str):
name = a
else:
name = a.name
print("Hello my name is " + name)
p1 = Person("John", 36)
p1.myfunc()
print("---------------------")
Person.myfunc("Harry")
Output:
Hello my name is John
---------------------
Hello my name is Harry
First, the name is initialized by the classes self.params.
Second, the name is provided in the method within the class as a string.
So a type check is necessary.
However I don't think this is a clean approach, because when I have >30 methods I need to implement these type checks again, including upcoming type-error results.
Does anyone know a better approach?
The simplest solution is to implement a __str__ method for your class. This method will be called whenever something tries to convert an instance of the class to a string.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return self.name
p = Person('Jane', 25)
print('Hello', p)
'Hello Jane'

Messing around with OOP in Python

I'm playing around with OOP in Python and I am trying to figure out some stuff related to inheritance. . I have some code here that has a few classes. A class called Blacksmith which behaves as expected and a class called Hero which I am trying to call a function from but I recieve an unexpected output.
class Character(object):
def __init__(self,name):
self.health=100
self.name = name
# self.player = player
def printName(self):
print self.name
#def printPlayerName(self):
# print self.player
class Blacksmith(Character):
def __init__(self,name, forgeName):
super(Blacksmith, self).__init__(name)
#self.name = "Billy"
self.forge = Forge(forgeName)
class Hero(Character):
playerName = "Player"
def __init__(self,name):
super(Hero, self).__init__(name)
def setplayername(self,inputplayername):
playerName = inputplayername
class Forge:
def __init__(self,forgeName):
self.name = forgeName
bs = Blacksmith("Billy", "Billy's Forge")
print bs.health
bs.printName()
print bs.forge.name
player1 = Hero("Methos")
print player1.name
player1.setplayername("Chris")
#print playher1.playerName
print player1.playerName
Output is:
raina#DESKTOP-291MTC0 ~/python
$ python learningoopclasses01.py
100
Billy
Billy's Forge
Methos
Player
Can anyone explain why this output says "Player" and not "Chris". Another question I have is I am not entirely sure how the init methods work. What does super do in these cases? What does calling init with a name value do exactly? Thanks.
__init__ is called when an object of that Class is created. With this method, we will also use the self variable to represent the instance of the object itself. It has to be explicitly declared in Python to be defined on an object.
For example,
class Student():
def __init__(self, score1, score2, score3):
self.scores = [score1, score2, score3]
If you want to assign scores to Student 1, you would only need to use because stu_1 already has score as an attribute in it:
stu_1 = Student(80, 90, 85)
In addition, __init__ also will notify you if any parameters are entered incorrectly according to what it has been set up.
super() is used to first call the parent(super) class of Blacksmith, which is Character, and allows you access Character's property.
The call to super() in Blacksmith's __init__ method is equal to its superclass, which in this case is Character.
You could also replace super(Blacksmith, self).__init__(name) with Character.__init__(self, name). The two are equivalent.
A slight adjustment to
def setplayername(self,inputplayername):
self.playerName = inputplayername
In the Hero class will fix it, if you don't want to change anything else.

Multiple values for same variable when designing Objects (use of self in Python)

I'm new to python (not new to programming), and I've been messing around with the idea of 'self'. I was making great strides, but then I found something interesting with messing around with a small program I made. I created an object called Person. Here's the code of my entire program.
class Person():
name = "temp"
def __init__(self, aname):
global name
print("A Person is created!")
name=aname
self.test()
def test(self):
print(name)
print(self.name)
p1 = Person("Tim")
As you can see, I create a variable called 'name'. In the constructor, I pass in a variable called 'aname' and assign it to the variable 'name'. At the end of the constructor, I call a method called test which prints out two things. The first actually prints what I set name to in the constructor (in this case, "Tim", as you can see by the last line of the code) but the second prints "temp", which is what I initialize 'name' to. Shouldn't the values be the same? What's the difference between using and not using self in my scenario?
Just for reference, here's what is printed out,
A Person is created!
Tim
temp
That name variable which you assign aname to in init is actually not the same one you initially declare as tmp -- it's a whole new global variable. For example, you can add print name at the end of your code:
class Person():
name = "temp"
def __init__(self, aname):
global name
print("A Person is created!")
name=aname
self.test()
def test(self):
print(name)
print(self.name)
p1 = Person("Tim")
print name
And your output will be:
A Person is created!
Tim
temp
Tim
Another way to illustrate this is to change the name of the variable altogether:
class Person():
name = "temp"
def __init__(self, aname):
global asd
print("A Person is created!")
asd=aname
self.test()
def test(self):
print(asd)
print(self.name)
p1 = Person("Tim")
Will also print:
A Person is created!
Tim
temp
To accomplish what I assume you wish to accomplish -- which is to have a name property assigned to each person, use self.name to set the property.
class Person():
name = "temp"
def __init__(self, aname):
print("A Person is created!")
self.name=aname
self.test()
def test(self):
print(self.name)
p1 = Person("Tim")
(Note that trying to print(name) in test() will fail, because there is no in-scope property with that name.)

Object with __init__ in python

I have written some python code:
class key(object):
def __init__(self,name):
object.__init__(self,age)
this.name = name
this.age = age
def somefunction(self):
print "yay the name is %d" % self.name
baby = key('radan',20)
baby.somefunction()
When I create an instance of key with baby = key('radan',20), I got a TypeError. I don't know why I am getting this error. Is it because of object.__init__(self,age)?
If yes, please help me in explaining why we use object.__init__(self,age) and what the purpose of that is and help me solve this code.
Some pointers:
class Key(object): # in Python, classes are usually named with a starting capital
def __init__(self, name, age): # name all your arguments beside self
self.name = name # use self.name, not this.name
self.age = age
def somefunction(self):
print "yay the name is %s" % self.name
baby = Key('radan',20)
baby.somefunction()
# output: yay the name is radan
Actually, you can can name the self instance parameter whatever you like in Python (even this), but it makes the code harder to read for other people, so just use self.
You don't have to use object.__init__(self, name, age) here. If you remove that line and implement the changes above, your code will work just fine.
Your code contains several errors:
class key(object):
def __init__(self, name, age): # where's your age?
self.name = name # no need to call object.__init__
self.age = age # there is no such thing called "this", use self
def somefunction(self):
print "yay the name is %s" % self.name # use %s as the comment says
baby = key('radan', 20)
baby.somefunction()
output:
>>> baby = key('radan', 20)
>>> baby.somefunction()
yay the name is radan
When you do baby = key('radar', 20) you are actually passing three arguments: the instance, the name and the age. However your initialiser is defined to take exactly two arguments so you get a TypeError.
self is the argument implicitly passed when referring to an instance of an object.
For your __init__ function, I would just do:
def __init__(self, name, age):
self.name = name
self.age = age
So we can assign the arguments passed as attributes to the current instance, conventionally called self.
It makes no sense here to call object.__init__ at all, just remove that line.
Apart from that, everything works fine (except use %s instead of %d).
Testing:
>>> baby = key('radan', 20)
>>> baby.somefunction()
yay the name is radan

Categories

Resources