148H1S-csc148代写-Assignment 1
时间:2023-03-04
3/2/23, 8:49 PM Assignment 1: CSC148H1S 20231 (All Sections): Introduction to Computer Science
https://q.utoronto.ca/courses/292974/pages/assignment-1 1/16
Assignment 1
Assignment 1: Forming Optimal Groups
Due date: Tuesday, March 7th, at 1:00 pm sharp.
You may complete this assignment individually or with a partner, who can be from any section of the
course.
Introduction
In the field of teaching university courses, a question that has received considerable attention is this:
What is the best way to put students into groups?
There are arguments for making groups heteregenous, and other arugments for making them
homogeneous. What is best may depend on the kind of work, the size of the group, or what attributes
we are basing the grouping on. For example, we might want groups with heterogeneous programs of
study, so students bring different perspectives. Or we might want homogeneous neighbourhoods, so
students from who live nearby can meet to work together in person. Or we may want a combination
of these criteria. Of course, to apply criteria like these, we need the relevant information about the
students (their program of study, or college, for instance). We can get that by surveying the students.
Luckily, with your extensive programming knowledge that you have acquired from taking CSC148,
you will be able to write a program that lets an instructor form student groups in the way that they
think is best.
Your task is to complete a program that analyzes an instructor’s criteria for good groups, plus data
extracted from a student survey, to make groups that are optimal with respect to the criteria. We have
broken down the assignment into several tasks that are outlined in detail in this handout.
Learning Goals
By the end of this assignment you should be able to:
read complex code you didn’t write and understand its design and implementation, including:
understanding the class and method docstrings in detail (including attributes, representation
invariants, preconditions, etc.)
determining relationships between classes, by applying your knowledge of composition and
inheritance
given a partial implementation of a class, complete it, including:
3/2/23, 8:49 PM Assignment 1: CSC148H1S 20231 (All Sections): Introduction to Computer Science
https://q.utoronto.ca/courses/292974/pages/assignment-1 2/16
understanding the representation invariants and enforcing them
understanding the preconditions and appropriately factoring them in both when writing the
body of the method and when writing client code
implementing the required methods according to their docstrings
using inheritance to define a subclass
perform unit testing on a program with many interacting classes
General Guidelines
You may complete this assignment individually or with a partner.
Please read this handout carefully and ask questions if there are any tasks you do not
understand.
The tasks are not designed to be equally difficult, or even in increasing order of difficulty. They are
just laid out in logical order.
Although implementing a complex application can be challenging at first, we will guide you
through a progression of tasks, in order to gradually build pieces of your implementation. Your
responsibility includes reading through this handout and the starter code we provide, carefully,
and understanding how the classes work together in the context of the application.
Coding Guidelines
These guidelines are designed to help you write well-designed code that will adhere to the interfaces
we have defined (and thus will be able to pass our test cases).
You must:
write each method in such a way that the docstrings you have been given in the starter code
accurately describe the body of the method.
write test methods where indicated. These will be marked, but we will not assess their
thoroughness or their ability to fail on buggy code (as we have required on some of your Preps).
We recommend that you go farther and write tests for all methods that you implement, even
private ones.
You do NOT need to write doctests for the functions and methods in this assignment. The
setup required to do the testing would create disruptively long docstrings.
incorporate inheritance into your code, as described in the Your Task section.
avoid writing duplicate code.
You must NOT:
modify any code that you are given. In particular, you must not not:
change the parameters, parameter type annotations, or return types in any of the methods
you have been given in the starter code.
add or remove any parameters in any of the methods you have been given in the starter code.
3/2/23, 8:49 PM Assignment 1: CSC148H1S 20231 (All Sections): Introduction to Computer Science
https://q.utoronto.ca/courses/292974/pages/assignment-1 3/16
change the type annotations of any public or private attributes you have been given in the
starter code.
create any new public attributes.
create any new public methods that do not override or extend a method of the same name in a
parent class.
create any new top-level functions, that is, functions defined outside any class.
write code that mutates objects unnecessarily.
add any more import statements to your code.
create an alias between an attribute (that is of a mutable type) of a class and a parameter to a
method; this could lead to nasty side effects. However, as discussed in Tasks 7 and 8, you will
sometimes make a “shallow copy” that is not itself an alias but has aliasing within it.
You may need to:
create new private methods for the classes you have been given.
if you create new private methods you must provide type annotations for every parameter and
return value. You must also write a full docstring for this method as described in the function
design recipe (https://q.utoronto.ca/courses/292974/files/24917046?wrap=1)
(https://q.utoronto.ca/courses/292974/files/24917046/download?download_frd=1) , except that
you do not need to write any doctests, as noted above.
create new private attributes for the classes you have been given.
if you create new private attributes you must give them a type annotation and include a
description of them in the class’s docstring as described in the class design recipe
(https://q.utoronto.ca/courses/292974/files/24917049?wrap=1)
(https://q.utoronto.ca/courses/292974/files/24917049/download?download_frd=1) .
import more objects from the typing module
While writing your code you can assume that all arguments passed to the methods you have been
given in the starter code will respect the preconditions outlined in the methods’ docstrings.
We have included a docstring for a __str__ method in many of the classes you will write. We have
not specified what a string representation of these objects will look like; this is up to you to pick
something that is useful to you in your debugging process. We will not be grading for any particular
string representation.
Your Task
Complete the classes and methods given to you in the starter code to create a piece of software that
keeps track of survey data and uses the results of that data to make optimal groups of students
according to provided criteria.
You are encouraged to complete this assignment in the order outlined in the tasks below but you may
choose a different order if you wish.
3/2/23, 8:49 PM Assignment 1: CSC148H1S 20231 (All Sections): Introduction to Computer Science
https://q.utoronto.ca/courses/292974/pages/assignment-1 4/16
Make sure you complete each “Test your code!” section before moving on to the next task to make
sure that your code works as expected.
In each of the tasks below you are encouraged to read questions in the “Something to think about”
sections. You are not required to answer these questions for this assignment but thinking about them
might help you write better code!
Task 1: Get the starter code and read the documentation
1. Download the file a1.zip (to be provided shortly) that contains the starter code
2. Unzip the file and place the contents in pycharm in your a1 folder (remember to set your a1
folder as a sources root)
3. You should see the following files:
course.py
criterion.py
grouper.py
survey.py
tests.py
example_tests.py
example_usage.py
a folder called data containing several .json files ( example_course.json , example_survey.json ,
generated_course_hetero.json , generated_course_lonely.json , generated_course.json ,
longer_survey_hetero.json , longer_survey_lonely.json , and longer_survey.json ).
For this assignment, you will be required to edit and submit the files that do not start with example_ .
If you look at these files you will notice that you have been given the headers and docstrings for
many classes and methods, which describe how you are expected to implement them. You will
complete them in the rest of this assignment’s tasks.
A picture!
It might be difficult to imagine how all the classes defined in these files will interact before you start
writing the code itself. To help you out, here is a diagram of all the classes you will be asked to
contribute to for this assignment. This diagram is a bit complicated, but we think it will be a helpful
3/2/23, 8:49 PM Assignment 1: CSC148H1S 20231 (All Sections): Introduction to Computer Science
https://q.utoronto.ca/courses/292974/pages/assignment-1 5/16
reference as you work through the assignment.
Legend:
A dashed lines from class A to class B indicates a composition relationship: class A "has-a" B.
3/2/23, 8:49 PM Assignment 1: CSC148H1S 20231 (All Sections): Introduction to Computer Science
https://q.utoronto.ca/courses/292974/pages/assignment-1 6/16
A solid line from class A to class B indicates an inheritance relationship: class B is a child of (or
"isa") class A
A solid circle around a group of classes indicates that there exists an inheritance relationship
between these classes but it is not defined (you get to decide!)
Note that the attributes and methods shown in this diagram are only the ones that we have given you
in the starter code. You may need to define additional private attributes or private helper methods.
We have also included some private attributes and methods here. We wouldn’t typically include this
information in docstrings or class diagrams – this is just to help you understand what to do.
Test your code!
Each task has a section about testing your code.
In the tests.py file, you will write your own tests for your code as you work through the
assignment. You will submit this file, but it’s empty right now!
The file example_tests.py contains some tests we have written for you. This is not a complete set
of tests, but will help you a little. Right now all of the tests should fail because you haven’t written
any code yet!
The example_usage.py file should also raise an error since you haven’t written any code yet! You
can look at this file for examples of how the code you write will be used.
Something to think about!
Unlike in Assignment 0, you will be submitting code split across multiple files. Open up each of the
files and look at which functions and classes are defined in each file. Why do you think the files were
organized in this way? Is there a different way we could have organized these files?
Task 2: Complete the Student class in course.py
The Student class represents a student who can be enrolled in a university course.
What to do
1. Implement the methods in the Student class as described in its method docstrings.
2. Write your own tests for each public method in the Student class in tests.py . You should have at
least one test for each public method (other than __init__ and __str__ ).
3. None of the tests in example_tests.py will pass at this point.
Remember: you may need to define additional private attributes or private helper methods!
Note: The Student.has_answer method asks you to check if a student has a valid answer to a given
question. We don’t yet have a way to determine if an answer is valid, and we won’t until we complete
Task 5. You may need to come back and finish this method after completing Task 5.
Task 3: Complete the Course class in course.py
3/2/23, 8:49 PM Assignment 1: CSC148H1S 20231 (All Sections): Introduction to Computer Science
https://q.utoronto.ca/courses/292974/pages/assignment-1 7/16
The Course class represents a university course.
What to do
1. Implement the methods in the Course class as described in its method docstrings. You may find
the function sort_students helpful.
2. Write your own tests for each public method in the Course class in tests.py . You should have at
least one test for each public method (other than __init__ ).
3. Run the tests in example_tests.py , and ensure that TestCourse.test_enroll_students and
TestCourse.test_get_students have passed. None of the other tests will pass yet.
Note: The Course.all_answered method asks you to check if all students have a valid answer for every
question in a Survey . You may have to come back later to finish the Course.all_answered method after
you have completed the Survey class.
Task 4: Complete the question classes in survey.py
The file survey.py contains an abstract Question class, and the following classes for representing
different types of questions that you might find on a survey:
MultipleChoiceQuestion
NumericQuestion
YesNoQuestion
CheckboxQuestion
Each of these classes defines the text of a question, and specifies what are valid answers to that
particular type of question.
We have not defined any inheritance hierarchy between these classes. You get to decide what it
should be.
What to do
1. Define an inheritance hierarchy between these classes, following these rules:
a. The abstract class Question must be a superclass of all the others.
b. All other question classes must inherit from the abstract class Question either directly or indirectly.
c. At least one non-abstract question class should inherit from another non-abstract question class.
This means that your inheritance hierarchy will have more than two levels.
There are many possible inheritance structures you could choose. Remember that one of the
requirements for this assignment is to avoid writing duplicate code. Think about which sort of
inheritance structure best lets you avoid duplicate code.
2. Implement the methods in each of the question classes, as described in their method docstrings.
You may remove a method that we included in the starter code in a child class if you want
3/2/23, 8:49 PM Assignment 1: CSC148H1S 20231 (All Sections): Introduction to Computer Science
https://q.utoronto.ca/courses/292974/pages/assignment-1 8/16
to inherit the method directly from the parent class, rather than override/extend it. Note: You may
find the Python set type to be useful.
3. In tests.py , write your own tests for each public method in the YesNoQuestion class. You should
have at least one test for each public method (other than __init__ and __str__ ). You need to
write tests for inherited methods, even if they are not overridden in the YesNoQuestion class.
For example, even if you structure your code so that the YesNoQuestion class inherits its
validate_answer method without modification from another class, you still need to write tests for
the validate_answer method when called on an instance of YesNoQuestion .
4. Optional but recommended: Write your own tests in tests.py for each public method in the other
question classes (except for the abstract class Question ).
5. Run the tests in example_tests.py , and ensure that TestStudent.test_set_answer and
TestStudent.test_get_answer also now pass.
Note: The validate_answer methods ask you to check if an answer is a valid answer for this question.
You might not have enough information about the Answer class in order to complete this method now,
and you may need to come back and finish this method after completing Task 5.
Task 5: Complete the Answer class in survey.py
The Answer class represents an answer to one of the questions you wrote classes for in Task 4. (By
“answer” we mean a response someone might give to the question, not the correct answer. Notice
that we don’t record a correct answer anywhere! This is because our surveys are meant to gather
information about students, not as tests.)
What to do
1. Implement the methods in the Answer class as described in its method docstrings.
2. Write your own tests for the public method Answer.is_valid in tests.py .
3. If you have not implemented the validate_answer methods in the question classes, or the
Course.all_answered and the Student.has_answer methods yet, go back and finish them now.
4. Run the tests in example_tests.py , and ensure that all tests in the TestStudent , TestAnswer ,
TestMultipleChoiceQuestion , TestNumericQuestion , TestYesNoQuestion , and TestCheckboxQuestion
classes now pass.
Something to think about!
The Answer class is one of the simplest classes that we will implement in this assignment. What is
the advantage of creating such a simple class? Are there any disadvantages?
Task 6: Complete the criterion classes in criterion.py
A criterion is a way of judging the quality of a group based on the group members’ answers to a
particular question. (The plural of criterion is criteria.) For example, one criterion could be to want
3/2/23, 8:49 PM Assignment 1: CSC148H1S 20231 (All Sections): Introduction to Computer Science
https://q.utoronto.ca/courses/292974/pages/assignment-1 9/16
groups with homogeneous (i.e. the same) answers to a question asking what year they are in.
Another criterion could be to want groups to have heterogeneous (i.e. different) answers to another
question.
The criterion classes are the following:
Criterion
HomogeneousCriterion
HeterogeneousCriterion
LonelyMemberCriterion
We have not defined any inheritance hierarchy between these classes. You get to decide what it
should be.
What to do
1. Define an inheritance hierarchy between these classes, following these rules:
a. The abstract class Criterion must be a superclass of all the others.
b. All other criterion classes should inherit from the abstract class Criterion , either directly or
indirectly.
c. At least one non-abstract criterion class should inherit from another non-abstract criterion
class. This means that your inheritance hierarchy will have more than two levels.
There are many possible inheritance structures you could choose. Remember that one of the
requirements for this assignment is to avoid writing duplicate code. Think about which sort of
inheritance structure best lets you avoid duplicate code.
2. Implement the score_answers method in each of the criterion classes, as described in their method
docstrings. You should NOT implement an initializer for these classes. Consequently, you
shouldn’t define any additional public or private attributes for any of these classes.
Remember: You may remove a method defined in a child class if you wish to simply inherit the
parent’s method directly.
3. Write your own tests for the HomogeneousCriterion.score_answers method in tests.py . You need to
write these tests even if you decide to inherit score_answers from its parent class without
overriding it.
4. Optional but recommended: Write your own tests in tests.py for the score_answers method in the
other criterion classes (except for the abstract class Criterion ).
5. Run the tests in example_tests.py , and ensure the tests in the TestHomogeneousCriterion ,
TestHeterogeneousCriterion , and TestLonelyMemberCriterion classes now pass.
3/2/23, 8:49 PM Assignment 1: CSC148H1S 20231 (All Sections): Introduction to Computer Science
https://q.utoronto.ca/courses/292974/pages/assignment-1 10/16
Something to think about!
You are asked not to implement an initializer for the Criterion classes. Why is an initializer not
necessary for these classes? If the Criterion classes do not define an initializer, will it be impossible
to create instances of these classes?
Task 7: Complete the Group class in grouper.py
The Group class represents a collection of one or more students.
What to do
1. Implement the methods in the Group class as described in its method docstrings.
2. Write your own tests for each public method in the Group class in tests.py , other than __init__
and __str__ .
3. Run the tests in example_tests.py and ensure the tests in the TestGroup class now pass.
Note: You may find the Python set type to be useful.
The Group.get_members method asks you to return a shallow copy of the _members private attribute
instead of simply returning the list that _members refers to. A shallow copy of an object is a new object
(with a different id ) but whose contents are the same. For example,
>>> dict_list = [{1: 2, 3: 9}, {5: 18}, {"adieu": 7}]
>>> copy_list = []
>>> for item in dict_list:
... copy_list.append(item)
...
>>> # dict_list and copy_list are two different objects
>>> id(dict_list)
4485971264 # id1
>>> id(copy_list)
4485971200 # id2
>>> # But each item in copy_list is an alias for an item in dict_list
>>> For example:
>>> id(dict_list[2])
4486046896 # id3
>>> id(copy_list[2])
4486046896 # id3 -- the same id we saw in dict_list
>>> # With a Python list, any time we slice we get a new list.
>>> # This provides an easy way to make a shallow copy.
>>> another_copy = dict_list[:]
>>> id(another_copy)
4485971008 # id4
>>> id(another_copy[2])
4486046896 # id3 -- the same id we saw in dict_list and copy_list
By returning a shallow copy, the Group.get_members method allows the client code to mutate the
individual Student objects but not the Group object itself. The same reasoning holds for the
Grouping.get_groups method in the next task.
Something to think about!
3/2/23, 8:49 PM Assignment 1: CSC148H1S 20231 (All Sections): Introduction to Computer Science
https://q.utoronto.ca/courses/292974/pages/assignment-1 11/16
In contrast to a shallow copy, a deep copy has new objects at every level, so it contains no aliases.
What would you need to be able to make a deep copy of a list of Student objects?
Task 8: Complete the Grouping class in grouper.py
The Grouping class represents a collection of Group instances. An instance of a Grouping class can
be used to represent every student in a course, divided up into groups.
What to do
1. Implement the methods in the Grouping class as described in its method docstrings.
2. Write your own tests for the Grouping.add_group method in tests.py .
3. Optional but recommended: Write your own tests in tests.py for the __len__ and get_groups
methods from the Grouping class.
4. Run the tests in example_tests.py and ensure the tests in the TestGrouping class now pass.
Note: You may find the Python set type to be useful in this task also.
Something to think about!
An instance of the Grouping class starts out containing zero groups and more can be added later
using the Grouping.add_group . On the other hand, an instance of the Group class starts out with some
members and more cannot be added later. How might we have chosen to implement these classes
differently? What does this design choice tell us about how these classes are intended to be used?
Task 9: Complete the Survey class in survey.py
The Survey class represents a collection of questions. It also associates each question with a
criterion (indicating how to judge the quality of a group based on their answers to the question) and a
weight (indicating the importance of this question in deciding how to group students).
What to do
1. Implement the methods in the Survey class as described in its method docstrings.
Hint: Read the documentation for Survey._get_criterion and Survey._get_weight carefully before
you implement the initializer.
2. Write at least one of your own tests for each public method in the Survey class in tests.py , other
than the __init__ , __str__ , __len__ , and __contains__ methods.
3. Run the tests in example_tests.py , and ensure that all tests in the TestSurvey and TestCourse
classes now pass.
Note: The weights associated with the questions in a survey do NOT have to sum up to any
particular amount.
3/2/23, 8:49 PM Assignment 1: CSC148H1S 20231 (All Sections): Introduction to Computer Science
https://q.utoronto.ca/courses/292974/pages/assignment-1 12/16
Remember: you may need to define additional private attributes or private helper methods!
Something to think about!
What is the relationship between the Survey.score_students method and the Survey.score_grouping
method?
Task 10: Complete the grouper classes in grouper.py
The grouper classes represent different techniques for deciding how to split all the students in a
course into groups. You will be implementing three different groupers, each using a different
algorithm. The file Groupers.pdf (https://q.utoronto.ca/courses/292974/files/24915377?wrap=1)
(https://q.utoronto.ca/courses/292974/files/24915377/download?download_frd=1) walks through a
detailed example for each of the groupers. Make sure you understand the algorithms before you start
writing code.
Note that this task is intended to be the most algorithmically challenging part of the assignment. We
encourage you to make sure you have completed the other tasks before investing significant time in
this one.
The grouper classes are the classes in grouper.py that have “Grouper” in their name:
Grouper
AlphaGrouper
GreedyGrouper
SimulatedAnnealingGrouper
Unlike the criterion classes and question classes, the inheritance structure between the grouper
classes has been given to you. You should NOT change the inheritance structure between the
grouper classes.
What to do
1. Implement each of the methods in the grouper classes as described in the method docstrings,
using the algorithms in the Grouper Explanation.pdf file (which provides more detail than the
docstrings). Note that we have provided the abstract Grouper class for you, and that some of the
other grouper classes use the inherited initializer from the parent class. You need to write the
initializer only for SimulatedAnnealingGrouper , and you may find it helpful to add private attributes
and/or methods to that class.
You may find the function sort_students from the course.py file helpful. There are also several
helper functions defined in grouper.py for you to use. Read their docstrings carefully, but you are
not expected to understand all of the code in these helper functions.
You may assume that there are more students in a course than the group size, however the
3/2/23, 8:49 PM Assignment 1: CSC148H1S 20231 (All Sections): Introduction to Computer Science
https://q.utoronto.ca/courses/292974/pages/assignment-1 13/16
group size may not evenly divide the number of students. That is, you can assume that there will
be enough students to form at least two groups, and that you may end up with one group smaller
than the “ideal” group size.
2. Write at least one test in tests.py for each of the AlphaGrouper.make_grouping and
GreedyGrouper.make_grouping methods.
3. Optional but recommended: Write additional tests in tests.py for the AlphaGrouper.make_grouping
and GreedyGrouper.make_grouping methods. Note that it will be more challenging to write tests for
SimulatedAnnealing.make_grouping , since that method involves randomness.
4. Run the tests in example_tests.py and ensure that all tests in the TestAlphaGrouper ,
TestGreedyGrouper , and TestSimulatedAnnealingGrouper classes now pass.
Something to think about!
Now that you have written all the code, go back and look at the diagram in Task 1. This is just one
possible way to have designed this code. Think about:
How could we have structured the classes differently?
What other classes might we want to add to this code in the future?
Imagine we wanted to add a class that keeps track of all of the courses in a university? How easy
would it be to add this new class? Which existing classes (if any) would have to change?
Task 11: Test your code again!
Now that you have finished writing all the code, go back and run all the tests again. We strongly
recommend you do much more testing than we have required above to convince yourself that your
code is working correctly. The example_tests.py file might catch some bugs in your code but it will
certainly not catch them all.
Ideally you would write up thorough tests for every public method in the tasks above in pytest . We
have only required a small number of the tests that you should be running on your code, in order to
balance giving you some practice writing proper unit tests with letting you use other less formal
testing methods if you choose. We hope it is clear by now that we think testing is important!
Using example_usage.py
At this point, you can also run the example_usage.py file again. This file should now run without errors
(however this does not mean your code is bug-free).
The example_usage.py file will create a course and a survey and will use that survey to group the
students into groups using the three different grouper classes. It generates a visualization of the
results as a HTML file that you can open with your web browser.
To generate different groups, you can experiment with setting the values of the variables example and
group_size on the first two lines of the if __name__ == '__main__' block. You can also try changing the
number of iterations and initial temperature used to initialize the SimulatedAnnealingGrouper .
3/2/23, 8:49 PM Assignment 1: CSC148H1S 20231 (All Sections): Introduction to Computer Science
https://q.utoronto.ca/courses/292974/pages/assignment-1 14/16
The visualization HTML file contains a plot of the scores of the groups created by the different
algorithms, as well as some simple statistics about how well they do. This visualization is just for your
own exploration of the algorithms, you do not need to do anything with it.
Something to think about!
Do you think the different algorithms are better or worse at handling different kinds of criteria?
Final Task! Submit your work
You’ve almost finished and now it is time to hand in your work!
BUT BEFORE YOU SUBMIT:
Take some time to polish up your code This not only will improve your mark, but it also feels good to
make your code look its best! Here are some things you can do:
Pay attention to any violations of the Python style guidelines that PyCharm points out. Fix them!
In each file you will submit, run the provided python_ta.check_all(...) code to check for errors. Fix
them!
Make sure the tests.py file contains at least the required tests from the tasks above.
Check any docstrings that you have written to make sure they are precise and complete and that
they follow the conventions of the Function Design Recipe
(https://q.utoronto.ca/courses/292974/files/24917046?wrap=1)
(https://q.utoronto.ca/courses/292974/files/24917046/download?download_frd=1) and the Class
Design Recipe (https://q.utoronto.ca/courses/292974/files/24917049?wrap=1)
(https://q.utoronto.ca/courses/292974/files/24917049/download?download_frd=1) (but as noted
above, you do NOT need to write docstring examples on this assignment, as they would be
disruptively long).
Remove any code you added just for debugging, such as print function calls.
Remove any TODO comments where you have added the necessary code.
Take pride in your gorgeous code! This assignment is a significant piece of software, and you
should be proud of the work you’ve done!
Submission Guidelines:
1. Login to MarkUs and create a group for the assignment, or specify that you’re working alone.
2. DOUBLE CHECK AGAIN THAT YOUR CODE RUNS!!
3. Submit the following files only:
course.py
criterion.py
grouper.py
survey.py
tests.py
3/2/23, 8:49 PM Assignment 1: CSC148H1S 20231 (All Sections): Introduction to Computer Science
https://q.utoronto.ca/courses/292974/pages/assignment-1 15/16
4. Run the self-test provided on MarkUs. Are there any tests that fail? Are there any python-ta errors
that you should fix? Your code will be tested on MarkUs, so it must run in that environment!
5. Download the files you submitted and make sure you’re submitting the right version of your code!
6. If you make any changes to your code, make sure to submit the updated files to MarkUs before
the deadline – and run the self-test again!
Congratulations, you are finished with your first major assignment in CSC148! You should definitely
go and celebrate!
Appendix 1: An explanation of some pieces of the starter code
(OPTIONAL).
There are parts of the starter code that involve Python features that not been explained in class. It is
not absolutely necessary to understand them to complete this assignment but a brief explanation of
each will be provided below for those of you who are interested:
if TYPE_CHECKING: :
Pycharm does a lot of work in order to highlight problematic code and give us hints as to how to
improve the code we are writing as we are writing it. In order to do this, Pycharm constantly
analyzes your code by running it though a program called a type checker. The TYPE_CHECKING
variable is True only when a type checker is analyzing our code and False when we run our
code normally. This lets us define a block of code that we normally don’t want to run but is useful
for the type checker.
Extra Reading:
- https://docs.python.org/3/library/typing.html#typing.TYPE_CHECKING (https://docs.python.org/3/librar
y/typing.html#typing.TYPE_CHECKING)
- https://stackabuse.com/python-circular-imports/
@pytest.fixture
This is a part of the pytest library that lets us mark that a function should be treated as a “fixture”.
In testing, a fixture is an object that can be used in multiple tests. Before each test runs, a fixture
object is created if needed by running the fixture function and getting its return value. That fixture
object is then passed as a parameter to the test. A test can indicate which fixtures it needs by
including a parameter that has the same name as the fixture function.
For example, the TestCourse.test_enroll_students test has a parameter named empty_course so
before the test is run, the empty_course fixture function will run and pass its return value as an
argument to the test.
You do NOT need to use fixtures when writing your tests in the tests.py file.
Extra Reading:
3/2/23, 8:49 PM Assignment 1: CSC148H1S 20231 (All Sections): Introduction to Computer Science
https://q.utoronto.ca/courses/292974/pages/assignment-1 16/16
- https://docs.pytest.org/en/latest/fixture.html (https://docs.pytest.org/en/latest/fixture.html)
Classes in pytest:
You might have noticed that the tests in example_tests.py are organized into classes. This is
simply a way to keep your tests organized and make it clear which groups of tests logically go
together. You are not required to write your tests in tests.py in this way but you may if you wish.
Extra Reading:
- https://docs.pytest.org/en/latest/getting-started.html#group-multiple-tests-in-a-class (https://do
cs.pytest.org/en/latest/getting-started.html#group-multiple-tests-in-a-class)
essay、essay代写