First commit with 2 exercises.

This commit is contained in:
Cacahuete 2020-11-30 23:58:29 +01:00
commit 14152b9a30
7 changed files with 322 additions and 0 deletions

136
.gitignore vendored Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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)