Question
=== Module Description === This file contains classes that describe a survey as well as classes that described different types of questions that can be
=== Module Description ===
This file contains classes that describe a survey as well as classes that described different types of questions that can be asked in a given survey.
from __future__ import annotations from typing import TYPE_CHECKING, Union, Dict, List from criterion import HomogeneousCriterion, InvalidAnswerError if TYPE_CHECKING: from criterion import Criterion from grouper import Grouping from course import Student
class Question: """ An abstract class representing a question used in a survey
=== Public Attributes === id: the id of this question text: the text of this question
=== Representation Invariants === text is not the empty string """
id: int text: str
def __init__(self, id_: int, text: str) -> None: """ Initialize a question with the text
def __str__(self) -> str: """ Return a string representation of this question that contains both the text of this question and a description of all possible answers to this question.
You can choose the precise format of this string. """ raise NotImplementedError
def validate_answer(self, answer: Answer) -> bool: """ Return True iff
def get_similarity(self, answer1: Answer, answer2: Answer) -> float: """ Return a float between 0.0 and 1.0 indicating how similar two answers are.
=== Precondition ===
class MultipleChoiceQuestion: # TODO: make this a child class of another class defined in this file """ A question whose answers can be one of several options
=== Public Attributes === id: the id of this question text: the text of this question
=== Representation Invariants === text is not the empty string """
id: int text: str
def __init__(self, id_: int, text: str, options: List[str]) -> None: """ Initialize a question with the text
=== Precondition === No two elements in
def __str__(self) -> str: """ Return a string representation of this question including the text of the question and a description of the possible answers.
You can choose the precise format of this string. """ # TODO: complete the body of this method
def validate_answer(self, answer: Answer) -> bool: """ Return True iff
An answer is valid if its content is one of the possible answers to this question. """ # TODO: complete the body of this method
def get_similarity(self, answer1: Answer, answer2: Answer) -> float: """ Return 1.0 iff
=== Precondition ===
class NumericQuestion: # TODO: make this a child class of another class defined in this file """ A question whose answer can be an integer between some minimum and maximum value (inclusive).
=== Public Attributes === id: the id of this question text: the text of this question
=== Representation Invariants === text is not the empty string """
id: int text: str
def __init__(self, id_: int, text: str, min_: int, max_: int) -> None: """ Initialize a question with id
=== Precondition === min_ < max_ """ # TODO: complete the body of this method
def __str__(self) -> str: """ Return a string representation of this question including the text of the question and a description of the possible answers.
You can choose the precise format of this string. """ # TODO: complete the body of this method
def validate_answer(self, answer: Answer) -> bool: """ Return True iff the content of
def get_similarity(self, answer1: Answer, answer2: Answer) -> float: """ Return the similarity between
Similarity calculated by:
1. first find the absolute difference between
Hint: this is the same calculation from the worksheet in lecture!
For example: - Maximum similarity is 1.0 and occurs when
=== Precondition ===
class YesNoQuestion: # TODO: make this a child class of another class defined in this file """ A question whose answer is either yes (represented by True) or no (represented by False).
=== Public Attributes === id: the id of this question text: the text of this question
=== Representation Invariants === text is not the empty string """ id: int text: str
def __init__(self, id_: int, text: str) -> None: """ Initialize a question with the text
def __str__(self) -> str: """ Return a string representation of this question including the text of the question and a description of the possible answers.
You can choose the precise format of this string. """ # TODO: complete the body of this method
def validate_answer(self, answer: Answer) -> bool: """ Return True iff
def get_similarity(self, answer1: Answer, answer2: Answer) -> float: """ Return 1.0 iff
=== Precondition ===
class CheckboxQuestion: # TODO: make this a child class of another class defined in this file """ A question whose answers can be one or more of several options
=== Public Attributes === id: the id of this question text: the text of this question
=== Representation Invariants === text is not the empty string """
id: int text: str
def __init__(self, id_: int, text: str, options: List[str]) -> None: """ Initialize a question with the text
=== Precondition === No two elements in
def __str__(self) -> str: """ Return a string representation of this question including the text of the question and a description of the possible answers.
You can choose the precise format of this string. """ # TODO: complete the body of this method
def validate_answer(self, answer: Answer) -> bool: """ Return True iff
An answer is valid iff its content is a non-empty list containing unique possible answers to this question. """ # TODO: complete the body of this method
def get_similarity(self, answer1: Answer, answer2: Answer) -> float: """ Return the similarity between
Similarity is defined as the ratio between the number of strings that are common to both
For example, if
=== Precondition ===
class Answer: """ An answer to a question used in a survey
=== Public Attributes === content: an answer to a single question """ content: Union[str, bool, int, List[str]]
def __init__(self, content: Union[str, bool, int, List[Union[str]]]) -> None: """Initialize an answer with content
def is_valid(self, question: Question) -> bool: """Return True iff self.content is a valid answer to
class Survey: """ A survey containing questions as well as criteria and weights used to evaluate the quality of a group based on their answers to the survey questions.
=== Private Attributes === _questions: a dictionary mapping each question's id to the question itself _criteria: a dictionary mapping a question's id to its associated criterion _weights: a dictionary mapping a question's id to a weight; an integer representing the importance of this criteria. _default_criterion: a criterion to use to evaluate a question if the question does not have an associated criterion in _criteria _default_weight: a weight to use to evaluate a question if the question does not have an associated weight in _weights
=== Representation Invariants === No two questions on this survey have the same id Each key in _questions equals the id attribute of its value Each key in _criteria occurs as a key in _questions Each key in _weights occurs as a key in _questions Each value in _weights is greater than 0 _default_weight > 0 """
_questions: Dict[int, Question] _criteria: Dict[int, Criterion] _weights: Dict[int, int] _default_criterion: Criterion _default_weight: int
def __init__(self, questions: List[Question]) -> None: """ Initialize a new survey that contains every question in
def __len__(self) -> int: """ Return the number of questions in this survey """ # TODO: complete the body of this method
def __contains__(self, question: Question) -> bool: """ Return True iff there is a question in this survey with the same id as
def __str__(self) -> str: """ Return a string containing the string representation of all questions in this survey
You can choose the precise format of this string. """ # TODO: complete the body of this method
def get_questions(self) -> List[Question]: """ Return a list of all questions in this survey """ # TODO: complete the body of this method
def _get_criterion(self, question: Question) -> Criterion: """ Return the criterion associated with
Iff
=== Precondition ===
def _get_weight(self, question: Question) -> int: """ Return the weight associated with
Iff
=== Precondition ===
def set_weight(self, weight: int, question: Question) -> bool: """ Set the weight associated with
If
def set_criterion(self, criterion: Criterion, question: Question) -> bool: """ Set the criterion associated with
If
def score_students(self, students: List[Student]) -> float: """ Return a quality score for
This score is determined using the following algorithm:
1. For each question in
If an InvalidAnswerError would be raised by calling this method, or if there are no questions in
=== Precondition === All students in
def score_grouping(self, grouping: Grouping) -> float: """ Return a score for
If there are no groups in
1. For each group in
=== Precondition === All students in the groups in
if __name__ == '__main__': import python_ta python_ta.check_all(config={'extra-imports': ['typing', 'criterion', 'course', 'grouper']})
=== Module Description ===
This file contains classes that describe a university course and the students who are enrolled in these courses. """ from __future__ import annotations from typing import TYPE_CHECKING, List, Tuple, Optional if TYPE_CHECKING: from survey import Answer, Survey, Question
def sort_students(lst: List[Student], attribute: str) -> List[Student]: """ Return a shallow copy of
=== Precondition ===
>>> s1 = Student(1, 'Misha') >>> s2 = Student(2, 'Diane') >>> s3 = Student(3, 'Mario') >>> sort_students([s1, s3, s2], 'id') == [s1, s2, s3] True >>> sort_students([s1, s2, s3], 'name') == [s2, s3, s1] True """ return sorted(lst, key=lambda s: getattr(s, attribute))
class Student: """ A Student who can be enrolled in a university course.
=== Public Attributes === id: the id of the student name: the name of the student
=== Representation Invariants === name is not the empty string """
id: int name: str
def __init__(self, id_: int, name: str) -> None: """ Initialize a student with name
def __str__(self) -> str: """ Return the name of this student """ # TODO: complete the body of this method
def has_answer(self, question: Question) -> bool: """ Return True iff this student has an answer for a question with the same id as
def set_answer(self, question: Question, answer: Answer) -> None: """ Record this student's answer
def get_answer(self, question: Question) -> Optional[Answer]: """ Return this student's answer to the question
class Course: """ A University Course
=== Public Attributes === name: the name of the course students: a list of students enrolled in the course
=== Representation Invariants === - No two students in this course have the same id - name is not the empty string """
name: str students: List[Student]
def __init__(self, name: str) -> None: """ Initialize a course with the name of
def enroll_students(self, students: List[Student]) -> None: """ Enroll all students in
If adding any student would violate a representation invariant, do not add any of the students in
def all_answered(self, survey: Survey) -> bool: """ Return True iff all the students enrolled in this course have a valid answer for every question in
def get_students(self) -> Tuple[Student, ...]: """ Return a tuple of all students enrolled in this course.
The students in this tuple should be in order according to their id from lowest id to highest id.
Hint: the sort_students function might be useful """ # TODO: complete the body of this method
if __name__ == '__main__': import python_ta python_ta.check_all(config={'extra-imports': ['typing', 'survey']})
=== Module Description ===
This file contains classes that describe different types of criteria used to evaluate a group of answers to a survey question. """ from __future__ import annotations from typing import TYPE_CHECKING, List if TYPE_CHECKING: from survey import Question, Answer
class InvalidAnswerError(Exception): """ Error that should be raised when an answer is invalid for a given question. """
class Criterion: """ An abstract class representing a criterion used to evaluate the quality of a group based on the group members' answers for a given question. """
def score_answers(self, question: Question, answers: List[Answer]) -> float: """ Return score between 0.0 and 1.0 indicating the quality of the group of
Raise InvalidAnswerError if any answer in
Each implementation of this abstract class will measure quality differently. """ raise NotImplementedError
class HomogeneousCriterion: # TODO: make this a child class of another class defined in this file """ A criterion used to evaluate the quality of a group based on the group members' answers for a given question.
This criterion gives a higher score to answers that are more similar. """
def score_answers(self, question: Question, answers: List[Answer]) -> float: """ Return a score between 0.0 and 1.0 indicating how similar the answers in
This score is calculated by finding the similarity of every combination of two answers in
If there is only one answer in
Raise InvalidAnswerError if any answer in
=== Precondition === len(answers) > 0 """ # TODO: complete the body of this method
class HeterogeneousCriterion: # TODO: make this a child class of another class defined in this file """ A criterion used to evaluate the quality of a group based on the group members' answers for a given question.
This criterion gives a higher score to answers that are more different. """
def score_answers(self, question: Question, answers: List[Answer]) -> float: """ Return a score between 0.0 and 1.0 indicating how similar the answers in
This score is calculated by finding the similarity of every combination of two answers in
If there is only one answer in
Raise InvalidAnswerError if any answer in
=== Precondition === len(answers) > 0 """ # TODO: complete the body of this method
class LonelyMemberCriterion: # TODO: make this a child class of another class defined in this file """ A criterion used to measure the quality of a group of students according to the group members' answers to a question. This criterion assumes that a group is of high quality if no member of the group gives a unique answer to a question. """
def score_answers(self, question: Question, answers: List[Answer]) -> float: """ Return score between 0.0 and 1.0 indicating the quality of the group of
The score returned will be zero iff there are any unique answers in
An answer is not unique if there is at least one other answer in
Raise InvalidAnswerError if any answer in
=== Precondition === len(answers) > 0 """ # TODO: complete the body of this method
if __name__ == '__main__': import python_ta python_ta.check_all(config={'extra-imports': ['typing', 'survey']})
=== Module Description ===
This file contains classes that define different algorithms for grouping students according to chosen criteria and the group members' answers to survey questions. This file also contain a classe that describes a group of students as well as a grouping (a group of groups). """ from __future__ import annotations import random from typing import TYPE_CHECKING, List, Any from course import sort_students if TYPE_CHECKING: from survey import Survey from course import Course, Student
def slice_list(lst: List[Any], n: int) -> List[List[Any]]: """ Return a list containing slices of
The last slice may contain fewer than
=== Precondition === n <= len(lst)
>>> slice_list([3, 4, 6, 2, 3], 2) == [[3, 4], [6, 2], [3]] True >>> slice_list(['a', 1, 6.0, False], 3) == [['a', 1, 6.0], [False]] True """ # TODO: complete the body of this function
def windows(lst: List[Any], n: int) -> List[List[Any]]: """ Return a list containing windows of
=== Precondition === n <= len(lst)
>>> windows([3, 4, 6, 2, 3], 2) == [[3, 4], [4, 6], [6, 2], [2, 3]] True >>> windows(['a', 1, 6.0, False], 3) == [['a', 1, 6.0], [1, 6.0, False]] True """ # TODO: complete the body of this function
class Grouper: """ An abstract class representing a grouper used to create a grouping of students according to their answers to a survey.
=== Public Attributes === group_size: the ideal number of students that should be in each group
=== Representation Invariants === group_size > 1 """
group_size: int
def __init__(self, group_size: int) -> None: """ Initialize a grouper that creates groups of size
=== Precondition === group_size > 1 """ # TODO: complete the body of this method
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in
class AlphaGrouper(Grouper): """ A grouper that groups students in a given course according to the alphabetical order of their names.
=== Public Attributes === group_size: the ideal number of students that should be in each group
=== Representation Invariants === group_size > 1 """
group_size: int
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in
The first group should contain the students in
All groups in this grouping should have exactly self.group_size members except for the last group which may have fewer than self.group_size members if that is required to make sure all students in
Hint: the sort_students function might be useful """ # TODO: complete the body of this method
class RandomGrouper(Grouper): """ A grouper used to create a grouping of students by randomly assigning them to groups.
=== Public Attributes === group_size: the ideal number of students that should be in each group
=== Representation Invariants === group_size > 1 """
group_size: int
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in
Students should be assigned to groups randomly.
All groups in this grouping should have exactly self.group_size members except for one group which may have fewer than self.group_size members if that is required to make sure all students in
class GreedyGrouper(Grouper): """ A grouper used to create a grouping of students according to their answers to a survey. This grouper uses a greedy algorithm to create groups.
=== Public Attributes === group_size: the ideal number of students that should be in each group
=== Representation Invariants === group_size > 1 """
group_size: int
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in
Starting with a tuple of all students in
1. select the first student in the tuple that hasn't already been put into a group and put this student in a new group. 2. select the student in the tuple that hasn't already been put into a group that, if added to the new group, would increase the group's score the most (or reduce it the least), add that student to the new group. 3. repeat step 2 until there are N students in the new group where N is equal to self.group_size. 4. repeat steps 1-3 until all students have been placed in a group.
In step 2 above, use the
The final group created may have fewer than N members if that is required to make sure all students in
class WindowGrouper(Grouper): """ A grouper used to create a grouping of students according to their answers to a survey. This grouper uses a window search algorithm to create groups.
=== Public Attributes === group_size: the ideal number of students that should be in each group
=== Representation Invariants === group_size > 1 """
group_size: int
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in
Starting with a tuple of all students in
1. Get the windows of the list of students who have not already been put in a group. 2. For each window in order, calculate the current window's score as well as the score of the next window in the list. If the current window's score is greater than or equal to the next window's score, make a group out of the students in current window and start again at step 1. If the current window is the last window, compare it to the first window instead.
In step 2 above, use the
In step 1 and 2 above, use the windows function to get the windows of the list of students.
If there are any remaining students who have not been put in a group after repeating steps 1 and 2 above, put the remaining students into a new group. """ # TODO: complete the body of this method
class Group: """ A group of one or more students
=== Private Attributes === _members: a list of unique students in this group
=== Representation Invariants === No two students in _members have the same id """
_members: List[Student]
def __init__(self, members: List[Student]) -> None: """ Initialize a group with members
def __len__(self) -> int: """ Return the number of members in this group """ # TODO: complete the body of this method
def __contains__(self, member: Student) -> bool: """ Return True iff this group contains a member with the same id as
def __str__(self) -> str: """ Return a string containing the names of all members in this group on a single line.
You can choose the precise format of this string. """ # TODO: complete the body of this method
def get_members(self) -> List[Student]: """ Return a list of members in this group. This list should be a shallow copy of the self._members attribute. """ # TODO: complete the body of this method
class Grouping: """ A collection of groups
=== Private Attributes === _groups: a list of Groups
=== Representation Invariants === No group in _groups contains zero members No student appears in more than one group in _groups """
_groups: List[Group]
def __init__(self) -> None: """ Initialize a Grouping that contains zero groups """ # TODO: complete the body of this method
def __len__(self) -> int: """ Return the number of groups in this grouping """ # TODO: complete the body of this method
def __str__(self) -> str: """ Return a multi-line string that includes the names of all of the members of all of the groups in
You can choose the precise format of this string. """ # TODO: complete the body of this method
def add_group(self, group: Group) -> bool: """ Add
Iff adding
def get_groups(self) -> List[Group]: """ Return a list of all groups in this grouping. This list should be a shallow copy of the self._groups attribute. """ # TODO: complete the body of this method
if __name__ == '__main__': import python_ta python_ta.check_all(config={'extra-imports': ['typing', 'random', 'survey', 'course']})
plz use python and i paste on survey-course-criterion-grouper order and each one has one simple intro atbeginning thx
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started