First commit with 2 exercises.
This commit is contained in:
commit
14152b9a30
136
.gitignore
vendored
Normal file
136
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
# ---> Python
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# VSCode project settings
|
||||
.vscode
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# Project specific
|
||||
test-folder
|
||||
1
README.md
Normal file
1
README.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Here are my solutions and all the tinkering going around [Python Morsels](https://www.pythonmorsels.com/)' exercises.
|
||||
6
add/add.py
Normal file
6
add/add.py
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
def add(*matrices):
|
||||
get_shape = lambda matrix: [len(vector) for vector in matrix]
|
||||
shape = get_shape(matrices[0])
|
||||
if any(get_shape(matrix) != shape for matrix in matrices):
|
||||
raise ValueError("Given matrices are not the same size.")
|
||||
return [[sum(elt) for elt in zip(*vectors)] for vectors in zip(*matrices)]
|
||||
7
add/add_v1.py
Normal file
7
add/add_v1.py
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
def add(*matrices):
|
||||
m_sizes = [len(matrix) for matrix in matrices]
|
||||
v_sizes = [len(vectors) for matrix in matrices for vectors in matrix]
|
||||
same_values = lambda l: all(e == l[0] for e in l[1:])
|
||||
if not same_values(m_sizes) or not same_values(v_sizes):
|
||||
raise ValueError("Given matrices are not the same size.")
|
||||
return [[sum(elt) for elt in zip(*vectors)] for vectors in zip(*matrices)]
|
||||
63
add/test_add.py
Normal file
63
add/test_add.py
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
from copy import deepcopy
|
||||
import unittest
|
||||
|
||||
from add import add
|
||||
|
||||
|
||||
class AddTests(unittest.TestCase):
|
||||
|
||||
"""Tests for add."""
|
||||
|
||||
def test_single_items(self):
|
||||
self.assertEqual(add([[5]], [[-2]]), [[3]])
|
||||
|
||||
def test_two_by_two_matrixes(self):
|
||||
m1 = [[6, 6], [3, 1]]
|
||||
m2 = [[1, 2], [3, 4]]
|
||||
m3 = [[7, 8], [6, 5]]
|
||||
self.assertEqual(add(m1, m2), m3)
|
||||
|
||||
def test_two_by_three_matrixes(self):
|
||||
m1 = [[1, 2, 3], [4, 5, 6]]
|
||||
m2 = [[-1, -2, -3], [-4, -5, -6]]
|
||||
m3 = [[0, 0, 0], [0, 0, 0]]
|
||||
self.assertEqual(add(m1, m2), m3)
|
||||
|
||||
def test_input_unchanged(self):
|
||||
m1 = [[6, 6], [3, 1]]
|
||||
m2 = [[1, 2], [3, 4]]
|
||||
m1_original = deepcopy(m1)
|
||||
m2_original = deepcopy(m2)
|
||||
add(m1, m2)
|
||||
self.assertEqual(m1, m1_original)
|
||||
self.assertEqual(m2, m2_original)
|
||||
|
||||
# To test the Bonus part of this exercise, comment out the following line
|
||||
# @unittest.expectedFailure
|
||||
def test_any_number_of_matrixes(self):
|
||||
m1 = [[6, 6], [3, 1]]
|
||||
m2 = [[1, 2], [3, 4]]
|
||||
m3 = [[2, 1], [3, 4]]
|
||||
m4 = [[9, 9], [9, 9]]
|
||||
m5 = [[31, 32], [27, 24]]
|
||||
self.assertEqual(add(m1, m2, m3), m4)
|
||||
self.assertEqual(add(m2, m3, m1, m1, m2, m4, m1), m5)
|
||||
|
||||
# To test the Bonus part of this exercise, comment out the following line
|
||||
# @unittest.expectedFailure
|
||||
def test_different_matrix_size(self):
|
||||
m1 = [[6, 6], [3, 1]]
|
||||
m2 = [[1, 2], [3, 4], [5, 6]]
|
||||
m3 = [[6, 6], [3, 1, 2]]
|
||||
with self.assertRaises(ValueError):
|
||||
add(m1, m2)
|
||||
with self.assertRaises(ValueError):
|
||||
add(m1, m3)
|
||||
with self.assertRaises(ValueError):
|
||||
add(m1, m1, m1, m3, m1, m1)
|
||||
with self.assertRaises(ValueError):
|
||||
add(m1, m1, m1, m2, m1, m1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main(verbosity=2)
|
||||
37
circle/circle.py
Normal file
37
circle/circle.py
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
from math import pi
|
||||
|
||||
|
||||
class Circle:
|
||||
def __init__(self, radius=1):
|
||||
self.radius = radius
|
||||
|
||||
def __repr__(self):
|
||||
return f"Circle({self.radius})"
|
||||
|
||||
@property
|
||||
def radius(self):
|
||||
return self._radius
|
||||
|
||||
@radius.setter
|
||||
def radius(self, radius):
|
||||
if radius < 0:
|
||||
raise ValueError("Radius cannot be negative")
|
||||
self._radius = radius
|
||||
|
||||
@property
|
||||
def diameter(self):
|
||||
return 2 * self._radius
|
||||
|
||||
@diameter.setter
|
||||
def diameter(self, diameter):
|
||||
if diameter < 0:
|
||||
raise ValueError("Diameter cannot be negative")
|
||||
self._radius = diameter / 2
|
||||
|
||||
@property
|
||||
def area(self):
|
||||
return pi * self._radius ** 2
|
||||
|
||||
@area.setter
|
||||
def area(self, area):
|
||||
raise AttributeError("Can't set attribute")
|
||||
72
circle/test_circle.py
Normal file
72
circle/test_circle.py
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import math
|
||||
import unittest
|
||||
|
||||
from circle import Circle
|
||||
|
||||
|
||||
class CircleTests(unittest.TestCase):
|
||||
|
||||
"""Tests for Circle."""
|
||||
|
||||
def test_radius(self):
|
||||
circle = Circle(5)
|
||||
self.assertEqual(circle.radius, 5)
|
||||
|
||||
def test_default_radius(self):
|
||||
circle = Circle()
|
||||
self.assertEqual(circle.radius, 1)
|
||||
|
||||
def test_diameter(self):
|
||||
circle = Circle(2)
|
||||
self.assertEqual(circle.diameter, 4)
|
||||
|
||||
def test_area(self):
|
||||
circle = Circle(2)
|
||||
self.assertEqual(circle.area, math.pi * 4)
|
||||
circle = Circle(1)
|
||||
self.assertEqual(circle.area, math.pi)
|
||||
|
||||
def test_string_representation(self):
|
||||
circle = Circle(2)
|
||||
self.assertEqual(str(circle), "Circle(2)")
|
||||
self.assertEqual(repr(circle), "Circle(2)")
|
||||
circle.radius = 1
|
||||
self.assertEqual(repr(circle), "Circle(1)")
|
||||
|
||||
# To test the Bonus part of this exercise, comment out the following line
|
||||
# @unittest.expectedFailure
|
||||
def test_diameter_and_area_change_based_on_radius(self):
|
||||
circle = Circle(2)
|
||||
self.assertEqual(circle.diameter, 4)
|
||||
circle.radius = 3
|
||||
self.assertEqual(circle.diameter, 6)
|
||||
self.assertEqual(circle.area, math.pi * 9)
|
||||
|
||||
# To test the Bonus part of this exercise, comment out the following line
|
||||
# @unittest.expectedFailure
|
||||
def test_diameter_changeable_but_area_not(self):
|
||||
circle = Circle(2)
|
||||
self.assertEqual(circle.diameter, 4)
|
||||
self.assertEqual(circle.area, math.pi * 4)
|
||||
circle.diameter = 3
|
||||
self.assertEqual(circle.radius, 1.5)
|
||||
with self.assertRaises(AttributeError):
|
||||
circle.area = 3
|
||||
|
||||
# To test the Bonus part of this exercise, comment out the following line
|
||||
# @unittest.expectedFailure
|
||||
def test_no_negative_radius(self):
|
||||
with self.assertRaises(ValueError) as context:
|
||||
circle = Circle(-2)
|
||||
self.assertEqual(str(context.exception).lower(), "radius cannot be negative")
|
||||
circle = Circle(2)
|
||||
with self.assertRaises(ValueError) as context:
|
||||
circle.radius = -10
|
||||
self.assertEqual(str(context.exception).lower(), "radius cannot be negative")
|
||||
with self.assertRaises(ValueError):
|
||||
circle.diameter = -20
|
||||
self.assertEqual(circle.radius, 2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main(verbosity=2)
|
||||
Loading…
Reference in a new issue