Using the pre-loaded class Person
Using the Person class, write a function print_friend_info(person) which accepts a single argument, of type Person, and:
prints out their name
prints out their age
if the person has any friends, prints 'Friends with {name}'
Write a function create_fry() which returns a Person instance representing Fry. Fry is 25 and his full name is 'Philip J. Fry'
Write a function make_friends(person_one, person_two) which sets each argument as the friend of the other.
I have gotten the right output with what needs to be printed but when I try run the code through our code Analyzer it says this error:
"You need to print the name of the person's friend in print_friend_info"
class Person(object):
def __init__(self, name, age, gender):
"""Construct a person object given their name, age and gender
Parameters:
name(str): The name of the person
age(int): The age of the person
gender(str): Either 'M' or 'F' for male or female
"""
self._name = name
self._age = age
self._gender = gender
self._friend = None
def __eq__(self, person):
return str(self) == str(person)
def __str__(self):
if self._gender == 'M':
title = 'Mr'
elif self._gender == 'F':
title = 'Miss'
else:
title = 'Ms'
return title + ' ' + self._name + ' ' + str(self._age)
def __repr__(self):
return 'Person: ' + str(self)
def get_name(self):
"""
(str) Return the name
"""
return self._name
def get_age(self):
"""
(int) Return the age
"""
return self._age
def get_gender(self):
"""
(str) Return the gender
"""
return self._gender
def set_friend(self, friend):
self._friend = friend
def get_friend(self):
"""
(Person) Return the friend
"""
return self._friend
def print_friend_info(person):
person_name = person.get_name()
person_age = person.get_age()
person_gender = person.get_gender()
person_friend = person.get_friend()
print (person_name)
print (person_age)
if person_friend == None:
return
else:
friendd = person_friend
nameoffriend = friendd.get_name()
print ('Friends with', nameoffriend)
return
def create_fry():
fry = Person("Philip J. Fry", 25, "M")
return fry
def make_friends(person_one, person_two):
made_friend1 = person_one.set_friend(person_two)
made_friend2 = person_two.set_friend(person_one)
return
--------- Test 1 ---------
Expected Output: Code Analyser
Test Result:
----- Analysis Errors -----
You need to print the name of the person's friend in print_friend_info
Input: bob = Person('Bob Smith', 40, 'M')
--------- Test 2 ---------
Expected Output: print_friend_info(bob)
Code Output: Bob Smith 40
Test Result: Correct!
Input: ed = Person('Ed', 8, 'M')
--------- Test 3 ---------
Expected Output: bob.set_friend(ed)
Code Output: Bob Smith 40 Friends with Ed
Test Result: Correct!
Input: fry = create_fry()
--------- Test 4 ---------
Expected Output: str(fry) -> 'Mr Philip J. Fry 25'
Test Result: Correct!
Input: leela = Person('T. Leela', 22, 'F')
--------- Test 5 ---------
Expected Output: make_friends(fry, leela)
Test Result: Correct!
Related
I have a class name Student like this:
class Student:
def __init__(self, name = '', age = 0, test_score = 0):
self.name = name
self.age = age
self.test_Scores = test_score
def __str__(self):
return "({0},{1},{2})".format(self.name,self.age, self.test_Scores)
and class name Students:
class Students():
stds = list()
def __init__(self) -> None:
pass
def Input(self):
while True:
inputName = input('Enter name: ')
inputAge = int(input('Enter age: '))
inputTestScore = int(input('Enter test score: '))
std = Student(inputName, inputAge, inputTestScore)
if inputAge == 0:
break
self.stds.append(std)
def __str__(self):
return str(self.stds)
Here are some code print out a list of students:
stds = Students()
stds.Input()
print(stds)
With 2 elements in the list, the result after excute look like this:
[<main.Student object at 0x0000026EDEBC5FA0>, <main.Student object at 0x0000026EDEBC5CD0>]
I can't print out stds under a string, how can i fix it. And how to sort stds by the decreasing of age ?
Pls help me !
You shouldn't have class Students, you should have a list of Student. To get the data from the class variables override the __repr__ method. To sort the list you can use lambda with the attribute to sort by as key in sort() function
class Student:
def __init__(self, name='', age=0, test_score=0):
self.name = name
self.age = age
self.test_Scores = test_score
def __repr__(self):
return "({0},{1},{2})".format(self.name, self.age, self.test_Scores)
if __name__ == '__main__':
stds = list()
while True:
inputName = input('Enter name: ')
inputAge = int(input('Enter age: '))
inputTestScore = int(input('Enter test score: '))
std = Student(inputName, inputAge, inputTestScore)
if inputAge == 0:
break
stds.append(std)
stds.sort(key=lambda s: s.name)
print(stds)
You need to write the function str for students class.
def __str__(self):
return '\n'.join(self.stds)
try this =>
class Student:
def __init__(self, name = '', age = 0, test_score = 0):
self.name = name
self.age = age
self.test_Scores = test_score
def __str__(self):
return "({0},{1},{2})".format(self.name,self.age, self.test_Scores)
def __repr__(self):
return "({0},{1},{2})".format(self.name,self.age, self.test_Scores)
def __lt__(self, other):
return self.age < other.age
class Students():
stds = list()
def __init__(self) -> None:
pass
def Input(self):
while True:
inputName = input('Enter name: ')
inputAge = int(input('Enter age: '))
inputTestScore = int(input('Enter test score: '))
std = Student(inputName, inputAge, inputTestScore)
if inputAge == 0:
break
self.stds.append(std)
def __str__(self):
return str(self.stds)
stds = Students()
stds.Input()
print(stds)
stds.stds.sort(reverse=True)
print(stds)
Define a natural order for the students based on their age using #functools.total_ordering:
import functools
#functools.total_ordering
class Student:
def __init__(self, name='', age=0, test_score=0):
self.name = name
self.age = age
self.test_Scores = test_score
def __lt__(self, other):
return self.age < other.age
def __str__(self):
return "({0},{1},{2})".format(self.name, self.age, self.test_Scores)
def test_sorting_students():
alice: Student = Student("Alice", 21, 86)
bob: Student = Student("Bob", 19, 75)
caroline: Student = Student("Caroline", 20, 93)
students = [alice, bob, caroline]
students.sort()
assert students[0] == bob
assert students[1] == caroline
assert students[2] == alice
Then just sort them:
print(stds.sort())
I have a class (Student) with different attributes, such as studentId, address, and courses. My str method for the class returns all the information that the user put in. However, for the attributes that are lists, such as courses, the location of the information is printed out instead of the actual information. Here is the code (sorry it's a little long, there's a bunch of classes):
class Person:
__name = None
__age = None
__address = None
def __init__(self, name, age=0, address=None):
self.set_name(name)
self.set_age(age)
self.set_address(address)
def __str__(self):
return 'Name: ' + self.__name + '\n' + \
'Age: ' + str(self.__age) + '\n' + \
'Address: ' + str(self.__address)
def set_name(self, name):
self.__name = name
def get_name(self):
return self.__name
def set_age(self, age):
self.__age = age
def get_age(self):
return self.__age
def set_address(self, address):
self.__address = address
def get_address(self):
return self.__address
class Student(Person):
def __init__(self, name, studentID= None, age= 0, address= None):
super(Student, self).__init__(name, age, address)
self.set_studentID(studentID)
self.__courses =[]
def __str__(self):
result = Person.__str__(self)
result += '\nStudent ID:' + self.get_studentID()
for item in self.__courses:
result += '\n ' + str(item)
return result
def set_studentID(self, studentID):
if isinstance(studentID, str) and len(studentID.strip()) > 0:
self.__studentID = studentID.strip()
else:
self.__studentID = 'NA'
def get_studentID(self):
return self.__studentID
def add_course(self, course):
print('in add_course')
self.__courses.append(course)
def get_courses(self):
for i in range(len(self.__courses)):
return self.__courses[i]
class Course:
__courseName = None
__dept = None
__credits = None
def __init__(self, courseName, dept= 'GE', credits= None):
self.set_courseName(courseName)
self.set_dept(dept)
self.set_credits(credits)
def __str__(self):
return self.get_courseName() + '/' + self.get_dept() + '/' + str(self.get_credits())
def set_courseName(self, courseName):
if isinstance(courseName, str) and len(courseName.strip()) > 0:
self.__courseName = courseName.strip()
else:
print('ERROR: Name must be a non-empty string')
raise TypeError('Name must be a non-empty string')
def get_courseName(self):
return self.__courseName
def set_dept(self, dept):
if isinstance(dept, str) and len(dept.strip()) > 0:
self.__dept = dept.strip()
else:
self.__dept = "GE"
def get_dept(self):
return self.__dept
def set_credits(self, credits):
if isinstance(credits, int) and credits > 0:
self.__credits = credits
else:
self.__credits = 3
def get_credits(self):
return self.__credits
students = []
def recordStudentEntry():
name = input('What is your name? ')
age = input('How old are you? ')
studentID= input('What is your student ID? ')
address = input('What is your address? ')
s1 = Student(name, studentID, int(age), address)
students.append(s1)
s1.add_course(recordCourseEntry())
print('\ndisplaying students...')
displayStudents()
print()
def recordCourseEntry():
courses = []
for i in range(2):
courseName = input('What is the name of one course you are taking? ')
dept = input('What department is your course in? ')
credits = input('How many credits is this course? ')
c1 = Course(courseName, dept, credits)
print(c1)
courses.append(c1)
displayCourses(courses)
return courses
def displayCourses(courses):
print('\ndisplaying courses of student... ')
for c in range(len(courses)):
print(courses[c])
def displayStudents():
for s in range(len(students)):
print()
print(students[s])
recordStudentEntry()
This is how the code above prints out the 'displaying students...' part:
displaying students...
Name: sam
Age: 33
Address: 123 st
Student ID:123abc
[<__main__.Course object at 0x000002BE36E0F7F0>, <__main__.Course object at
0x000002BE36E0F040>]
I know that it is printing out the location because I need to index into the list. However, the length of the list will be different every time. Normally if I wanted to index into a list, for example, to print a list of names, I would do:
listOfNames = ['sam', 'john', 'sara']
for i in range(len(listOfNames)):
print(listOfNames[i])
or
listOfNames = ['sam', 'john', 'sara']
for i in listOfNames:
print(i)
(not sure what if any difference there is between the 2 ways since they both print out the same way:)
sam
john
sara
How can I write something like the indexing into a list technique shown here in my str method for my class so that it prints the information and not the location?
It would be good to keep to the standard conventions for Python, such as naming
private attributes for objects with single underscores, not double underscores.
The latter are reserved for Python "internal" attributes and methods.
Also, it is convention to use object attributes for objects with get/set methods,
not class attributes. This will make it easier to inspect your objects, while
still maintaining data hiding. Example:
class Course:
def __init__(self, courseName, dept= 'GE', credits= None):
self._courseName = None
self._dept = None
self._credits = None
self.set_courseName(courseName)
...
Your question about why the courses don't print out the way you expected
is rooted in a programming error with the way you programmed the recording
of courses. In recordCourseEntry(), you record two courses and put them
in a list. However, you pass that to your Student object using a method
intended for one course at a time. My suggested fix would be:
...
# s1.add_course(recordCourseEntry())
courses = recordCourseEntry()
for course in courses:
s1.add_course(course)
...
This will probably be enough to get you going. An example output I got was:
Name: Virtual Scooter
Age: 33
Address: 101 University St.
Student ID:2021
ff/GE/3
gg/GE/3
My homework question asks me to write the following functions using a predetermined class 'Person', it runs 5 tests, one code analyser that ensures it was done the way they want and 4 practical examples, my code passes the practical examples but the analyser fails me.
This is the question:
Using the Person class, write a function print_friend_info(person) which accepts a single argument, of type Person, and:
prints out their name
prints out their age
if the person has any friends, prints 'Friends with {name}'
class Person(object):
def __init__(self, name, age, gender):
self._name = name
self._age = age
self._gender = gender
self._friend = None
def __eq__(self, person):
return str(self) == str(person)
def __str__(self):
if self._gender == 'M':
title = 'Mr'
elif self._gender == 'F':
title = 'Miss'
else:
title = 'Ms'
return title + ' ' + self._name + ' ' + str(self._age)
def __repr__(self):
return 'Person: ' + str(self)
def get_name(self):
"""
(str) Return the name
"""
return self._name
def get_age(self):
"""
(int) Return the age
"""
return self._age
def get_gender(self):
"""
(str) Return the gender
"""
return self._gender
def set_friend(self, friend):
self._friend = friend
def get_friend(self):
"""
(Person) Return the friend
"""
return self._friend
def print_friend_info(person):
print(person._name)
print(person._age)
if person.get_friend() != None:
print("Friends with {}".format(person._friend._name))
All tests pass, including the print_friend_info tests, except for this test that outputs the following error:
----- Analysis Errors -----
You need to print the person's name in print_friend_info
You need to print the person's age in print_friend_info
You need to print the name of the person's friend in print_friend_info
I have tried your code and it works for me with Python3.6.6. I have some suggestions which could be problem. First of all your shouldn't use the protected attributes of your class (underscored variables). You have getter methods to get the data of object so use them. It seems to me that the output can fulfill the test what you mentioned in your question.
Changed part of code:
def print_friend_info(person):
print("Name: {}".format(person.get_name()))
print("Age: {}".format(person.get_age()))
if person.get_friend(): # You don't need to use "!= None". A simple if is enough.
print("Friends with {}".format(person.get_friend().get_name())
print("\n")
joe = Person("Joe", 42, "Male")
print_friend_info(joe)
mary = Person("Mary", 55, "Female")
print_friend_info(mary)
joe.set_friend(mary)
print_friend_info(joe)
Output:
>>> python3 test.py
Name: Joe
Age: 42
Name: Mary
Age: 55
Name: Joe
Age: 42
Friends with Mary
students = []
class Student:
school_name = 'Maharshi Science school'
def __init__(self,name,student_id=336):
self.name = name
self.student_id= student_id
students.append(self)
def __str__(self):
return "student: " + self.name
def get_name_capitalize(self):
return self.name.capitalize()
def get_school_name(self):
return self.school_name
class HighschoolStudent(Student):
school_name = 'Maharshi High School'
def get_school_name(self):
return "This is a high school student"
def get_name_capitalize(self):
original_value = super().get_name_capitalize()
return original_value + "-HighschoolStudent"
chirag = HighschoolStudent('chirag')
print(chirag.get_name_capitalize())
This error will only occur if you are using Python 2. To fix this, replace
super().get_name_capitalize()
with
super(HighschoolStudent, self).get_name_capitalize()
If you upgrade to Python 3, your code should work fine.
You are getting the error due to Python 2. Please try the below code:
students = []
class Student(object):
school_name = 'Maharshi Science school'
def __init__(self,name,student_id=336):
self.name = name
self.student_id= student_id
students.append(self)
def __str__(self):
return "student: " + self.name
def get_name_capitalize(self):
return self.name.capitalize()
def get_school_name(self):
return self.school_name
class HighschoolStudent(Student):
school_name = 'Maharshi High School'
def get_school_name(self):
return "This is a high school student"
def get_name_capitalize(self):
original_value = super(HighschoolStudent, self).get_name_capitalize()
return original_value + "-HighschoolStudent"
chirag = HighschoolStudent('chirag')
print(chirag.get_name_capitalize())
Output:
Chirag-HighschoolStudent
There are two changes in this:
class Student --> class Student(object)
Passing your class name as input in super as mandated by Python 2
I have an assignment which I can't get through. I'm a beginner at programming and I want to understand it better for my course. Can someone help me? I really don't understand it.
This is the assignment:
The BMI is defined as weight/length2. A BMI between 18,5 and 25 as ideal and considers people with such a BMI healthy.
The program receives input consisting of two persons with their name, sex, length and weight.
Jack Johnson M 1.78 83
Maria Miller V 1.69 60
Process this input into structured data. To achieve this, use an useful class with useful methods to enhance the structure of the program. Use this structured data to print for each person: an appropriate style of address, surname, the BMI and a statement whether this is considered healthy or not.
Example:
Mr. Johnson’s BMI is 26.2 and is unhealthy.
Mrs. Miller’s BMI is 21.0 and is healthy.
This is what I have:
class Person(object):
def __init__(self):
self.first_name = first_name
self.last_name = last_name
self.sex = sex
self.length = length #m
self.weight = weight #kg
def bmi(self):
return self.weight / self.length ** 2
def healthy(self):
if BODYMASSINDEX <25 and BODYMASSINDEX>18.5:
person = healthy
else:
person = unhealthy
return person
from person import Person
file = open("BMIInput.txt")
invoer = file.read().splitlines()
details_person1 = invoer[0].split()
details_person2 = invoer[1].split()
person1 = Person(details_person1)
person2 = Person(details_person2)
print "%s's BMI is %.1f and is %s" %(person1.name, person1.bmi, person1.healthy)
The BMI Input is:
Jack Johnson M 1.78 83
Maria Miller V 1.69 60
Add the arguments to the init
class Person(object):
def __init__(self, first_name, last_name, sex, length, weight):
self.first_name = first_name
self.last_name = last_name
self.sex = sex
self.length = length #m
self.weight = weight #kg
def bmi(self):
return self.weight / self.length ** 2
def healthy(self):
if BODYMASSINDEX <25 and BODYMASSINDEX>18.5:
person = healthy
else:
person = unhealthy
return person
Then unpack the list:
from person import Person
file = open("BMIInput.txt")
invoer = file.read().splitlines()
details_person1 = invoer[0].split()
details_person2 = invoer[1].split()
person1 = Person(*details_person1)
person2 = Person(*details_person2)
print "%s's BMI is %.1f and is %s" %(person1.name, person1.bmi, person1.healthy)
Comment question about int, float is more what you need:
Just to solve the issue this is not clean nor the right way but it will work:
Inside the init
self.length = float(length) if type(length) != float else length
self.weight = float(weight) if type(weight) != float else weight
What I'd do is :
details_person1 = invoer[0].split()
details_person1[3] = float(details_person1[3])
details_person1[4] = float(details_person1[4])
The same thing with details_person2