I'm having some issues regarding classes in Python because I'm in the need of refactoring some code.
The problem I'm facing is I have to refactor multiple similar scripts, so I decided to use Python classes but I have the following question
Say we have these two similar codes that need refactoring:
name = "Peter"
print(f"Bye! {name}"}
name.replace("e", "a")
print(f"Bye! {name} **replaced**"}
name = "Lisa"
print(f"Hi! {name}"}
name.replace("e", "a")
print(f"Hi! {name}"}
So a Python class:
class Greetings(object):
def __init__(self):
self.name = name
def say_hi_and_replace(self, name):
if name == "Lisa":
print(f"Hi! {name}"}
else:
print(f"Hi! {name}"}
self.name = self.name.replace("e", "a")
def say_goodbye(self, name):
if name == "Lisa":
print(f"Bye! {name}"}
else:
print(f"Bye! {name} **replaced**"}
Is there a better way to write this code? I'm sure there is.
Edit: Besides using ternary operators like Klaud suggested correctly.
def say_goodbye(self, name):
print(f"Bye! {name}"} if name == "Lisa" else print(f"Bye! {name} **replaced**"}
Edit: Sorry there was a typo in the "Bye!"
Thanks in advance.
Related
I am generating a class of persons and want to get information about a certain person by input. I would like to use the str funtction because I am trying to understand it better. My Idea goes as follows:
class Person:
__init__(self, f_name, l_name):
self.f_name = f_name
self.l_name = l_name
__str__(self):
return "The persons full name is:" + f_name + l_name
person1 = Person(Peter, Punk)
person2 = Person(Mia, Munch)
person = input("What persons full name would you like to know?")
print(person) #I am aware that this just fills in the string saved in person, but how do I connect it to the variable?
another idea was to do it as follows:
#class stays the same except:
__init__(self, f_name, l_name):
self.f_name = f_name
self.l_name = l_name
list.append(self)
#and then for the main:
list = []
person1 = Person(Peter, Punk)
person2 = Person(Mia, Munch)
person = input("What persons full name would you like to know?")
index = list(person)
print(list[index])
Thankful for any edvice since I am obviously new to Python :D
I think OP has some concept problems here which this answer may go some way to help with.
Start by building a robust class definition. Simple in this case as there are just 2 attributes. Note the use of setters, getters and str, repr and eq dunder overrides.
A small function that checks if a given Person can be found in a list of Persons and reports accordingly.
Create a list with 2 different Person instances
Create another Person that is known not to match anything already in the list.
Run check()
Modify the 'standalone' Person to make it equivalent to something previously constructed.
Run check()
class Person:
def __init__(self, forename, surname):
self._forename = forename
self._surname = surname
#property
def forename(self):
return self._forename
#forename.setter
def forename(self, forename):
self._forename = forename
#property
def surname(self):
return self._surname
#surname.setter
def surname(self, surname):
self._surname = surname
def __str__(self):
return f'{self.forename} {self.surname}'
def __repr__(self):
return f'{self.forename=} {self.surname=}'
def __eq__(self, other):
if isinstance(other, type(self)):
return self.forename == other.forename and self.surname == other.surname
return False
def check(list_, p):
if p in list_:
print(f'Found {p}')
else:
print(f'Could not find {p}')
plist = [Person('Pete', 'Piper'), Person('Joe', 'Jones')]
person = Person('Pete', 'Jones')
check(plist, person)
person.surname = 'Piper'
check(plist, person)
Output:
Could not find Pete Jones
Found Pete Piper
You probably want a mapping between a name and an object. This is what Python's dict dictionary structure is for:
people = {} # an empty dictionary
people[f'{person1.f_name} {person1.l_name}'] = person1
people[f'{person2.f_name} {person2.l_name}'] = person2
This is creating a string of the first and last name.
You can then lookup the Person object using the full name:
print(people['Peter Punk'])
You could do this with list comprehension like so (also allowing multiple people to have the same first name)
class Person:
__init__(self, f_name, l_name):
self.f_name = f_name
self.l_name = l_name
__str__(self):
return "The persons full name is:" + f_name + l_name
personList= []
personList.append(Person(Peter, Punk))
personList.append(Person(Mia, Munch))
personName = input("What persons full name would you like to know?")
print([str(person) for person in personList if person.f_name == personName])
I was trying to write a function in python to print out all the overlapping movie interests.
I wanted to write this program as a little classes and objects exercise. So this is what it looks like, right now:
def main():
class Person:
def __init__(self, Film):
self.Film = Film
like_it = "Film" , "Movie"
def likes(self, Film):
if (Film in like_it):
return Film
else:
print("no movies in common")
Person1 = Person("Movie")
print(Person1.likes)
I wanted to initialize different People as objects in the class "Person". The Program doesn't see any mistakes, but prints nothing. What is wrong here? Where should I look?
Thank you so much for your help!!
You aren't passing Film as an argument in the likes method.
Working with Classes
class Person:
def __init__(self, Film):
self.Film = Film
like_it = "Film" , "Movie"
def likes(self):
if (self.film in like_it):
return self.film
else:
return "no movies in common" #we are returning string instead of printing
Person1 = Person("Movie")
print(Person1.likes()) #likes is a method that has to be called
References:
Object Oriented Programming with python
Further Reading:
Converting methods to property
I want to use an object of a class in a function of another class. I know it's a really easy thing to solve, but I still can't figure it out.
I have the following class that is an object of players
class Players():
def __init__(self, name_player, surname, age, height, wheight):
self.name_player= name_player
self.surname = surname
self.age= age
self.height= height
self.wheight= wheight
def __repr__(self):
return "{}, {}, {}, {}, {} //".format(self.name_player,self.surname,self.age,self.height,self.wheight)
Then I have this class of teams
class Teams():
def __init__(self, name, points, goals_in_favour, goals_against):
self.name= name
self.points= points
self.goals_in_favour= goals_in_favour
self.goals_against= goals_against
def __repr__(self):
return "{} : {} : {}: {}".format(self.name,self.points,self.goals_in_favour,self.goals_against)
Now in the function 'ages' I want it to return a list of the players with an age less or equal to the one on the file. If I write 'i.Players.age' it sends me an error, which is the right way to spell it?
def ages(lists_teams,age):
list_players =""
return [list_players + i for i in list_teams if (i.Players.age <= age)]
(I have to write it in a list comprehension way).
Thanks a lot in advance.
To help you understand.
1.If list_teams is already an list of objects...you cannot call i.Players, because i here is already an object.
2.list_players="" you should change it to []...."" is not a list, you cannot add object on to it.
3.Try not use i for object, it is normally used to indicate an index..
def ages(list_teams,age):
list_players =[]
return [list_players + [player] for player in list_teams if (player.age <= age)]
I am new to Python, am just learning Classes, and am trying to write a "personal info" program:
This is my code:
class PersonalInfo():
def names(self, name):
name = raw_input("What is your name?")
self.names = name
def addresses(self, add):
add = raw_input("What is your adress?")
self.addresses = add
def ages(self, age):
age = raw_input("What is your age?")
self.ages = age
def numbers(self, number):
number = raw_input("What is your phone number?")
self.numbers = number
PersonalInfo()
def print_names():
info = PersonalInfo()
print "Name:", info.names(name)
print "Address:", info.addresses(add)
print "Age:", info.info.ages(age)
print "Phone number:", info.numbers(number)
print_names()
But when I run it it says this:
NameError: global name 'add' is not defined
Can someone please help me?
There are several issues with your code other than the NameError and I strongly suggest you read more on python classes:
https://docs.python.org/2/tutorial/classes.html
https://www.tutorialspoint.com/python/python_classes_objects.htm
https://en.wikibooks.org/wiki/A_Beginner's_Python_Tutorial/Classes
I'll run you through those issues.
First, the NameError occurs because the add variable was not defined. The same applies to all other arguments you provided in your print statements.
Second, there are issues with the way you define the class methods:
class PersonalInfo():
def names(self, name):
name = raw_input("What is your name?")
self.names = name
Here, you are re-assigning the name variable to the return value of raw_input so there's no sense in setting it as an argument in the first place. Also, by stating self.names = name you are re-assigning the class method to the string that is returned by raw_input!
Third, you have to decide whether you want to provide the information when calling the methods, or using raw_input. Here's a working example of your code, assuming you want to use raw_input
class PersonalInfo():
def names(self):
name = raw_input("What is your name?")
self.name = name
def addresses(self):
add = raw_input("What is your adress?")
self.address = add
def ages(self):
age = raw_input("What is your age?")
self.age = age
def numbers(self):
number = raw_input("What is your phone number?")
self.number = number
def print_names():
info = PersonalInfo()
# Get information
info.names()
info.addresses()
info.ages()
info.numbers()
# After getting the info, print it
print "Name:", info.name
print "Address:", info.address
print "Age:", info.age
print "Phone number:", info.number
print_names()
I'm Code doesn't seem to work, I am trying to get input of a job, category, and salary, and store the input
class Jobs:
def GetJob(self):
name = raw_input('Enter a Job Title: ')
category = raw_input('Enter what Category that Job is: ')
salary = raw_input('Enter the salary of that Job: ')
print name,category, salary
def __init__(self,name,category,salary):
self.name = Jobs.GetJob(name)
self.category = Jobs.GetJob(category)
self.salary = Jobs.GetJob(salary)
GetJob = Jobs()
print GetJob
Your code is totally out of good OOP practices, and the first part eandersson's answer too…
A class has for role to store values, get/set them and return (or apply) transformations to its encapsulated values. What you tried to achieve is totally nonsense: you're calling the GetJob method of the Jobs class inside another method. It could work if you would have written:
def __init__(self,name…):
self.name = Jobs.GetJob(self, name)
…
But that would be a wrong way to design your program. You'd better stick your class to hold your values and making it good at that, and make another function that helps populate your class:
class Jobs:
def __init__(self, name, category, salary):
self.name = name
self.category = category
self.salary = salary
def __repr__(self):
return "Jobs<%s,%s,%s>" % (self.name, self.category, self.salary)
def GetJob():
name = raw_input('Enter a Job Title: ')
category = raw_input('Enter what Category that Job is: ')
salary = raw_input('Enter the salary of that Job: ')
return Jobs(name, category, salary)
print GetJob()
I do not agree with eandersson's approach because it deceives the purpose of the constructor, by directly calling the GetJob method. Then GetJob is not useful. And one would want to be able to use the Job class without always having the raw inputs at construction. EDIT: valid only as a comment on the first part of his answer.
And finally, I think that you really misunderstands a lot about programming. You should better read thoroughly a python course like the ones on http://wiki.python.org/moin/BeginnersGuide/NonProgrammers, because there's really a lot of concepts you ignored to be able to write something like that.
go have a look at:
http://hetland.org/writing/instant-hacking.html
http://www.learnpython.org/
http://cscircles.cemc.uwaterloo.ca/
http://learnpythonthehardway.org/book/