python version of exercise

This commit is contained in:
Emily Bache
2019-08-07 08:47:07 +02:00
parent 358dab1c5b
commit cd583380f5
9 changed files with 190 additions and 0 deletions

76
python/.gitignore vendored Normal file
View File

@@ -0,0 +1,76 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# 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/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/
.pytest_cache
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask instance folder
instance/
# Sphinx documentation
docs/_build/
# MkDocs documentation
/site/
# PyBuilder
target/
# IPython Notebook
.ipynb_checkpoints
# pyenv
.python-version
venv
.idea

3
python/requirements.txt Normal file
View File

@@ -0,0 +1,3 @@
pytest
approvaltests
pytest-approvaltests

41
python/statement.py Normal file
View File

@@ -0,0 +1,41 @@
import math
def statement(invoice, plays):
total_amount = 0
volume_credits = 0
result = f'Statement for {invoice["customer"]}\n'
def format_as_dollars(amount):
return f"${amount:0,.2f}"
for perf in invoice['performances']:
play = plays[perf['playID']]
if play['type'] == "tragedy":
this_amount = 40000
if perf['audience'] > 30:
this_amount += 1000 * (perf['audience'] - 30)
elif play['type'] == "comedy":
this_amount = 30000
if perf['audience'] > 20:
this_amount += 10000 + 500 * (perf['audience'] - 20)
this_amount += 300 * perf['audience']
else:
raise ValueError(f'unknown type: {play["type"]}')
# add volume credits
volume_credits += max(perf['audience'] - 30, 0)
# add extra credit for every ten comedy attendees
if "comedy" == play["type"]:
volume_credits += math.floor(perf['audience'] / 5)
# print line for this order
result += f' {play["name"]}: {format_as_dollars(this_amount/100)} ({perf["audience"]} seats)\n'
total_amount += this_amount
result += f'Amount owed is {format_as_dollars(total_amount/100)}\n'
result += f'You earned {volume_credits} credits\n'
return result

17
python/tests/invoice.json Normal file
View File

@@ -0,0 +1,17 @@
{
"customer": "BigCo",
"performances": [
{
"playID": "hamlet",
"audience": 55
},
{
"playID": "as-like",
"audience": 35
},
{
"playID": "othello",
"audience": 40
}
]
}

View File

@@ -0,0 +1,13 @@
{
"customer": "BigCoII",
"performances": [
{
"playID": "henry-v",
"audience": 53
},
{
"playID": "as-like",
"audience": 55
}
]
}

View File

@@ -0,0 +1,4 @@
{
"henry-v": {"name": "Henry V", "type": "history"},
"as-like": {"name": "As You Like It", "type": "pastoral"}
}

5
python/tests/plays.json Normal file
View File

@@ -0,0 +1,5 @@
{
"hamlet": {"name": "Hamlet", "type": "tragedy"},
"as-like": {"name": "As You Like It", "type": "comedy"},
"othello": {"name": "Othello", "type": "tragedy"}
}

View File

@@ -0,0 +1,25 @@
import json
import pytest
from approvaltests import verify
from approvaltests.utils import get_adjacent_file
from statement import statement
def test_example_statement():
with open(get_adjacent_file("invoice.json")) as f:
invoice = json.loads(f.read())
with open(get_adjacent_file("plays.json")) as f:
plays = json.loads(f.read())
verify(statement(invoice, plays))
def test_statement_with_new_play_types():
with open(get_adjacent_file("invoice_new_plays.json")) as f:
invoice = json.loads(f.read())
with open(get_adjacent_file("new_plays.json")) as f:
plays = json.loads(f.read())
with pytest.raises(ValueError) as exception_info:
statement(invoice, plays)
assert "unknown type" in str(exception_info.value)

View File

@@ -0,0 +1,6 @@
Statement for BigCo
Hamlet: $650.00 (55 seats)
As You Like It: $580.00 (35 seats)
Othello: $500.00 (40 seats)
Amount owed is $1,730.00
You earned 47 credits