Answered step by step
Verified Expert Solution
Link Copied!
Question
1 Approved Answer

Learning Outcomes 1. Implement a class with many members 2. Implement properties, initializers, and class methods 3. Override methods inherited from object 4. Design

imageimageimageimageimageimageimageimageimageimageimageimageimageimageimageimage

Learning Outcomes 1. Implement a class with many members 2. Implement properties, initializers, and class methods 3. Override methods inherited from object 4. Design methods to avoid using mutable types Program Overview We will finish the 7 TODOs in the course.py file. The Course _init__() method wasn't creating new data structures for grades because a dictionary is a mutable type. Having mutable types as a default parameter is a design trap we need to avoid. Your goal is to redesign the course class to avoid this trap and also work with a Student class. Course objects will contain Students in their class roster. When creating a course, the user will enter the graded category items (e.g. assignment, quiz, exam, etc.) for the course along with the total points that item is worth. After all courses are entered the application will add students to each course and setup a data structure to hold each grade category and the points earned by the student on that graded item. After all students and earned scores are added, the application will print a list of all courses with a student report listing the student's name and earned points out of the total for each graded item. NOTE: All bold italic words in this document refer to a specific object/instance name or method. If the item is not in bold italics, it may just be a description of data to be used. Sample Output ******University System******* Enter semester and year for which you are creating courses: Spring 2023 Entering course information Enter course name: cis340 Enter grading categories for CIS340 5 letter max Category name: Quiz Enter total points for that Quiz: 10 Do you have more categories to enter (Y/N): y Enter grading categories for CIS340 5 letter max Category name: Exam Enter total points for that Exam: 20 Do you have more categories to enter (Y/N): n Add another course (Y/N)? y Enter course name: cis345 Enter grading categories for CIS345 5 letter max Category name: Asgnt Enter total points for that Asgnt: Do you have more categories to enter (Y/N): y Enter grading categories for CIS345 5 letter max Category name: Proj Enter total points for that Proj: 10 Do you have more categories to enter (Y/N): n Add another course (Y/N)? n Add students to CIS340 course How many students do you want to enroll? 2 Enter student first and last name: Sarah Connor Enter earned points for Quiz: 9 Enter earned points for Exam: 18 Enter student first and last name: Luke Cage Enter earned points for Quiz: 8 Enter earned points for Exam: 16 Add students to CIS345 course How many students do you want to enroll? 3 Enter student first and last name: Alex Shaw Enter earned points for Asgnt: 27 Enter earned points for Proj: 10 Enter student first and last name: Rick Parr Enter earned points for Asgnt: 28 Enter earned points for Proj: 9 Enter student first and last name: Lisa Lope Enter earned points for Asgnt: 25 Enter earned points for Proj: 10 Course Information for Spring 2013 Course 46198 - CIS340 has 2 students: Connor, Sarah Quiz: 9/10, Exam: 18/20, Cage, Luke - - Course 94055 - CIS345 has 3 students: Shaw, Alex Asgnt: 27/30, Proj: 10/10, Parr, Rick Asgnt: 28/30, Proj: 9/10, Lope, Lisa Asgnt: 25/30, Proj: 10/10, - Quiz: 8/10, Exam: 16/20, Instructions Create a PyCharm Project using standard naming convention. o Download course.py and copy to your PyCharm project O Rename to [ASUrite]_a4course.py When done, submit your completed python module only. Don't forget to put your name, class, class time, and assignment number in as a comment on Line 1 of all modules. PEP8 Conventions Class names are PascalCase otherwise known as CapWords convention Method and instance variables use snake_case Non public (aka private) instance variable names use name mangling Private instance variables are accessed using properties (getter & setter) In the course.py, you will develop code for the following UML Class Diagrams, which model a Course and Student. For this exercise, the instructions that follow are a written version of the UML diagram. You should be able to look at the diagram and develop the entire class in code without further instructions. In the future assignments, you will be given only the UML diagram! semester str section int Course name : str student count: int class roster list categories : dict _init (self, name : str, categories : dict) _str (self): str enter_categories(self): None enroll_students(self, number): None change_semester(cls, semester : str): None Figure 1. Course Class Diagram Note: Both classes will go in the same file. Python modules are meant to contain all classes, methods, and functions that relate to the module's name. Do not separate into multiple modules. 4 Course Class: 1. TODO - finish the init method. The instance variable categories will be a dictionary which is mutable. We avoid having defaulted arguments in functions and methods that are mutable. Change the parameter to default to None like we learned in lecture and create a decision that will do the following: a. If categories is None - initialize the object's categories attribute to a blank dictionary. Next call the object's enter_categories() method. b. Else assign the instance categories to the parameter categories. 2. TODO - Define the enter_categories() method that accepts one argument self. Body: a. Display to the user 'Enter grading categories for '. b. Ask the user to enter a 5-letter acronym for each grading category. C. Get the amount of points that item is worth (we are assuming that each item would be the same point value so every assignment is 30 points) d. Store the entered values in the dictionary categories within the course object where category is the key and total points is the value. Example: {Quiz' : 20} e. Prompt 'Do you have more categories to enter (Y/N): ' f. Clear screen g. Repeat a through f while the user has more categories to enter 3. TODO - Define the enroll_students method to add student objects to the class_roster instance variable. This method accepts two arguments self and number (the number of students to enroll in the course): a. Add number to the instance variable student_count and store the result. b. Start a loop that executes the value in number parameter amount of times C. Construct a Student object passing the instance variable categories to init and store the object in temp_student. d. Prompt 'Enter student first and last name: and store returned string in temp_student.fullname. e. Call enter_scores() within temp_student. f. Add temp_student to the course's class_roster g. Repeat b through f until all students are added 4. TODO - Override the dunder str method. To override, simply define it in your class. This method returns the string representation of Course objects so coding a course object name will call str method, ex. print(courseObject) will call str method: a. Declare a variable called message and initialize to 'Course {courseSection}- {courseName} has {courseStuentCount} students: ' b. Use a loop to go through all students in the course's class_roster and add to the message '{studentObject} - '. Recall studentObject will call the Student class _str () method. i. While looping through each student, loop through each category in the course object's categories and add to message these values from the indicated object: {category}: {studentObject.scores [category]} / {courseObject.categories [category]}, C. Within the loop going through all students in b above, but outside the loop going through categories, you will concatenate ' ' to message in order for each student to print on separate lines. Note: You are creating a really long concatenated string in message. This may require a bit of testing to get right (refer to screenshots to see what it should look like). End of class Course first: str last str scores: dict Student a. < > fullname : str _init (self, categories : dict, fname : str, lname : str) _str (self): str enter_scores(self): None Figure 2. Student Class Diagram TODO - Student Class. Add a class for student based on the above UML class diagram after the course class, but before your main program logic. 1. Define the dunder init method based on UML and default fname = 'Jane' and Iname = 'Doe' Declare all instance variables within and assign the appropriate parameter in method header. b. scores being a dictionary, cannot have a default parameter in order to avoid the trap. Instead it is not assigned any argument passed into the initializer method. Do the following for scores: Initialize to a blank dictionary Loop through all categories: Use each category as a key in the scores dictionary and assign a default value of zero. 2. Create a property, for fullname: a. Define the fullname property b. return '{studentLastName}, {studentFirstName}' 3. Create a setter, for fullname: a. Define the fullname setter and accept an argument called name b. Try the following and except ValueError, if ValueError occurs code pass C. We will split name into two variables called first and last using the below code: self.first, self.last name.split(' ') = Given split will take a string like 'John Smith' and split it on a space, it will return two strings in this order 'John' and 'Smith' being assigned to first and last respectively. If the string being assigned to fullname does not have a space or has more than one, a ValueError exception will occur and is handled by your try statement. Test this. 4. Override str for the Student class: return self.fullname 5. Define enter_scores(): a. Loop through all categories in the student object's scores variable to get scores b. Prompt 'Enter earned points for {gradeCategory}:' and store the numeric value C. Save the numeric entry into your student object within scores dictionary using the category as the key End of class Student Main Program Logic. We will be re-purposing some of the code from our previous exercise and modify it to work with the new design. Courses contain student objects within the course class roster. A course object also keeps track of how many students are in the roster along with the grading categories. Each student object contains name and scores for the grade categories. Let's write a simple program to test the two classes we have created. You will see we have code to display a program header and get the semester we our courses belong to. After that code you will see 3 commented lines that can be used to test without having to enter courses each time. Note the test code creates 1 course with several grade categories. I recommend testing the course entry first to ensure it works with your Course class. Once it does, comment out the while loop for 'Entering course information' and use the 3 lines of test code. You may also delete the test code and just enter courses each time. Regardless, ensure the course entry code is uncommented and the test code is deleted before submitting. 1. TODO: Create logic to add students to each course. a. After clearing the screen, loop through each course in courses and do the next steps display ' Add students to {courseName} course' b. Prompt user 'How many students do you want to enroll?' and store user entry Call enroll_students() within the course object and pass the above user entry. C. d. 2. TODO: Create logic to print each course and all students in the class roster with their scores. a. After clearing the screen, display ' Course Information for {Course.semester}' b. Loop through each course in courses and print(course) Learning Points Test exceptions where the student's name is just ted with no spaces. Should still work if and the student's name will be Jane Doe. We could expand this application to include our previous work of the Grade Calculator if we modified the attributes of our classes a little. You learned the importance of nesting objects within other objects and how overriding methods can make your code less complicated. It takes a bit of work up front to code these methods in the classes, but it pays off later when we re-use that code over and over. import random import os courses = [] class Course: # class variables semester = 'Fall 2025' def init _(self, name='', categories={}): """Create a course object. self refers to the object""" self.section = random.randint (10000, 100000) self.name = name value self.student_count = 0 self.class_roster = [] # Instance variable categories will hold a description and total point # TODO: Add decision for categories=None based on Requirements to avoid mutable trap @classmethod def change_semester (cls, semester): """Modify the text of the semester that all courses are being added to""" cls.semester = semester # TODO: Add enter_categories method to accept all categories for a course # TODO: Add method to enroll_students in course # TODO: Override _str_ method for course to print roster and scores # TODO: Create student class per UML Class Diagram # Main Logic print (f"{'University System' : *^30}") Course.change_semester (input('Enter semester and year for which you are creating courses: ')) # TODO: Create student class per UML Class Diagram # Main Logic print (f"{'University System' : *^30}") Course.change_semester (input('Enter semester and year for which you are creating courses: ')) enter_courses = 'y' # Below 3 lines is test data to avoid user input you may use to speed up development or not. # test_cats = {'PE': 10, 'Assignment': 30, 'Quiz': 20, 'Exam': 100} # course1 = Course ('CIS345', test_cats) # courses.append(course1) print(" Entering course information") while enter_courses == 'y': course_name = input('Enter course name: ').upper() new_course = Course (course_name) courses.append(new_course) enter_courses = input(" Add another course (Y/N)?").casefold() # Add students to each course using enroll_students() os.system ('cls') # TODO: Create logic to add students to each course using methods created within classes # Print Course Roster using Override methods to quickly display necessary data os.system('cls') print (f' Course Information for {Course. semester}') # TODO: Create logic to print each courses student roster

Step by Step Solution

There are 3 Steps involved in it

Step: 1

Given the comprehensive instructions and UML diagrams lets start implementing the Course and Student classes as per the requirements Step 1 Implementing the Course Class python import random import os ... blur-text-image
Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image_2

Step: 3

blur-text-image_3

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Systems Analysis And Design

Authors: Alan Dennis, Barbara Wixom, Roberta M. Roth

7th Edition

1119496489, 978-1119496489

Students also viewed these Programming questions

Question

What is a predicate transformer function?

Answered: 1 week ago