Merge remote-tracking branch 'origin/main' into main

This commit is contained in:
MstrPikachu
2022-01-30 22:14:15 -05:00
+200
View File
@@ -0,0 +1,200 @@
"""CSC111 Winter 2022 Prep 4: Programming Exercises
Instructions (READ THIS FIRST!)
===============================
Your task in this prep is to implement each of the unimplemented Tree methods in this file.
Use the recursive Tree method code template---decide whether to include the "size-one" base case
by determining whether it would be redundant.
We have marked each place you need to write code with the word "TODO".
As you complete your work in this file, delete each TODO comment.
You may add additional doctests, but they will not be graded. You should test your work
carefully before submitting it!
Copyright and Usage Information
===============================
This file is provided solely for the personal and private use of students
taking CSC111 at the University of Toronto St. George campus. All forms of
distribution of this code, whether as given or with any changes, are
expressly prohibited. For more information on copyright for CSC111 materials,
please consult our Course Syllabus.
This file is Copyright (c) 2022 Mario Badr, David Liu, and Diane Horton.
"""
from __future__ import annotations
from typing import Any, Optional
class Tree:
"""A recursive tree data structure.
Note the relationship between this class and RecursiveList; the only major
difference is that _rest has been replaced by _subtrees to handle multiple
recursive sub-parts.
Representation Invariants:
- self._root is not None or self._subtrees == []
- all(not subtree.is_empty() for subtree in self._subtrees)
"""
# Private Instance Attributes:
# - _root:
# The item stored at this tree's root, or None if the tree is empty.
# - _subtrees:
# The list of subtrees of this tree. This attribute is empty when
# self._root is None (representing an empty tree). However, this attribute
# may be empty when self._root is not None, which represents a tree consisting
# of just one item.
_root: Optional[Any]
_subtrees: list[Tree]
def __init__(self, root: Optional[Any], subtrees: list[Tree]) -> None:
"""Initialize a new Tree with the given root value and subtrees.
If root is None, the tree is empty.
Preconditions:
- root is not none or subtrees == []
"""
self._root = root
self._subtrees = subtrees
def is_empty(self) -> bool:
"""Return whether this tree is empty.
>>> t1 = Tree(None, [])
>>> t1.is_empty()
True
>>> t2 = Tree(3, [])
>>> t2.is_empty()
False
"""
return self._root is None
def __len__(self) -> int:
"""Return the number of items contained in this tree.
>>> t1 = Tree(None, [])
>>> len(t1)
0
>>> t2 = Tree(3, [Tree(4, []), Tree(1, [])])
>>> len(t2)
3
"""
if self.is_empty():
return 0
else:
size = 1 # count the root
for subtree in self._subtrees:
size += subtree.__len__() # could also write len(subtree)
return size
############################################################################
# Prep exercises start here
############################################################################
def num_negatives(self) -> int:
"""Return the number of negative integers in this tree.
Preconditions:
- all items in this tree are integers
Remember, 0 is *not* negative.
>>> t1 = Tree(17, [])
>>> t1.num_negatives()
0
>>> t1 = Tree(-17, [])
>>> t1.num_negatives()
1
>>> t1 = Tree(-17, [Tree(-1, [Tree(-20, [])]), Tree(-15, []), Tree(0, []), Tree(2, [Tree(-20, [])])])
>>> t1.num_negatives()
5
"""
if self.is_empty():
return 0
elif not self._subtrees:
return int(self._root < 0)
else:
return int(self._root < 0) + sum(s.num_negatives() for s in self._subtrees)
def maximum(self: Tree) -> int:
"""Return the maximum value stored in this tree.
Return 0 if this tree is empty.
Preconditions:
- all values in this tree are positive integers.
>>> t1 = Tree(17, [])
>>> t1.maximum()
17
>>> t1 = Tree(17, [Tree(18, []), Tree(2, [Tree(19, [])])])
>>> t1.maximum()
19
"""
if self.is_empty():
return 0
elif not self._subtrees:
return int(self._root)
else:
return max(s.maximum() for s in self._subtrees)
def height(self: Tree) -> int:
"""Return the height of this tree.
Please refer to the prep readings for the definition of tree height.
>>> t1 = Tree(17, [])
>>> t1.height()
1
>>> t1 = Tree(17, [Tree(18, []), Tree(2, [Tree(19, [])])])
>>> t1.height()
3
"""
if self.is_empty():
return 1
elif not self._subtrees:
return 1
else:
return 1 + max(s.height() for s in self._subtrees)
def __contains__(self, item: Any) -> bool:
"""Return whether this tree contains <item>.
>>> t = Tree(1, [])
>>> t.__contains__(-30) # Could also write -30 in t
False
>>> t.__contains__(1)
True
>>> t = Tree(17, [Tree(18, []), Tree(2, [Tree(19, [Tree('A', [])])])])
>>> 19 in t
True
>>> 2 in t
True
>>> 3 in t
False
>>> 'A' in t
True
"""
if self.is_empty():
return False
elif not self._subtrees:
return self._root == item
else:
return self._root == item or any(item in s for s in self._subtrees)
if __name__ == '__main__':
import python_ta.contracts
python_ta.contracts.check_all_contracts()
import doctest
doctest.testmod()
import python_ta
python_ta.check_all(config={
'max-line-length': 100,
'disable': ['E1136']
})