Skip to content

Commit

Permalink
Eighth commit
Browse files Browse the repository at this point in the history
  • Loading branch information
P4r1nc3 committed Aug 13, 2022
1 parent 6bfe4af commit c5cc239
Show file tree
Hide file tree
Showing 128 changed files with 226,938 additions and 0 deletions.
3 changes: 3 additions & 0 deletions part07/part07-09_how_old/.tmcproject.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
tests_timeout_ms: 10000
sandbox_image: eu.gcr.io/moocfi-public/tmc-sandbox-python
20 changes: 20 additions & 0 deletions part07/part07-09_how_old/src/how_old.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Write your solution here
from datetime import datetime

from datetime import datetime

def calculate_age(year: int, month: int, day: int):
birthday = datetime(year, month, day)
millenium = datetime(1999, 12, 31)
difference = millenium - birthday
return difference.days

day = int(input('Day: '))
month = int(input('Month: '))
year = int(input('Year: '))

age_by_millenium = calculate_age(year, month, day)
if age_by_millenium > 0:
print(f'You were {age_by_millenium} days old on the eve of the new millennium.')
else:
print(f"You weren't born yet on the eve of the new millennium.")
Empty file.
73 changes: 73 additions & 0 deletions part07/part07-09_how_old/test/test_how_old.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import unittest
from unittest.mock import patch

from tmc import points
from tmc.utils import load, load_module, reload_module, get_stdout
from functools import reduce
import os
import os.path
import textwrap
from random import choice, randint

exercise = 'src.how_old'

def x(t):
return "\n"+"\n".join(t)

@points('7.how_old')
class HowOldTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
with patch('builtins.input', side_effect=["30","12","1999"]):
cls.module = load_module(exercise, 'en')


def test1_uses_import_expression(self):
with open("src/how_old.py") as f:
cont = f.read()
self.assertTrue("import" in cont and "datetime" in cont,
f"Your program does not import datetime-library with the import expression.")

def test2_test_with_older_ones(self):
test_cases = {("1","1","1900"): "36523", ("10","9","1977"): "8147", ("30","12","1999"): 1, ("6","5","1995"): "1700"}
for test_case in test_cases:
with patch('builtins.input', side_effect=list(test_case)):
try:
reload_module(self.module)
except:
self.fail(f"Try to execute your program with the following inputs {x(test_case)}")

output = "\n".join([x.strip() for x in get_stdout().split("\n") if len(x.strip()) > 0])
lines = len(output.split("\n"))
correct = f"You were {test_cases[test_case]} days old on the eve of the new millennium."
msg = 'Note, that in this program no code must not be placed inside the if __name__ == "main" -block.'

self.assertTrue(lines > 0, f"Your program does not print out anything, {msg}")

self.assertTrue(lines == 1,
f"Your program is expected to print out 1 row, now it prints out {lines} rows: \n{output}\nwhen the input is {x(test_case)}")

self.assertTrue(correct in output,
f"Row {correct} is expected to be found out from your program, when the input is {x(test_case)}\nnow print out is \n{output}")

def test3_test_with_younger_ones(self):
test_cases = [("1","1","2100"), ("10","9","2019"), ("1","1","2000")]
for test_case in test_cases:
with patch('builtins.input', side_effect=list(test_case)):
try:
reload_module(self.module)
except:
self.fail(f"Try to execute your program with the following inputs {x(test_case)}")

output = "\n".join([x.strip() for x in get_stdout().split("\n") if len(x.strip()) > 0])
lines = len(output.split("\n"))
correct = "You weren't born yet on the eve of the new millennium."

self.assertTrue(lines == 1,
f"Your program is expected to print out 1 row, now it prints out {lines} rows: \n{output}\nwhen the input is {x(test_case)}")

self.assertTrue(correct in output,
f"Row {correct} is expected to be found out from your program, when the input is {x(test_case)}\nnow print out is \n{output}")

if __name__ == '__main__':
unittest.main()
2 changes: 2 additions & 0 deletions part07/part07-09_how_old/tmc/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .points import points
from .runner import TMCTestRunner
11 changes: 11 additions & 0 deletions part07/part07-09_how_old/tmc/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from unittest import TestProgram
from .runner import TMCTestRunner
import sys


if sys.argv.__len__() > 1 and sys.argv[1] == 'available_points':
TMCTestRunner().available_points()
sys.exit()

main = TestProgram
main(testRunner=TMCTestRunner, module=None, failfast=False, buffer=True)
50 changes: 50 additions & 0 deletions part07/part07-09_how_old/tmc/points.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from inspect import isclass, isfunction
from collections import defaultdict

point_register = {'suite': defaultdict(list), 'test': defaultdict(list)}


def qualifier(test):
return "%s.%s" % (test.__module__, test.__qualname__)


def save_points(o, points, dst):
q = qualifier(o)
dst[q] += filter(lambda point: point not in dst[q], points)


def points(*points):

def points_wrapper(o):
if isclass(o):
save_points(o, points, point_register['suite'])
elif isfunction(o):
save_points(o, points, point_register['test'])
else:
raise Exception("Expected decorator object '%s' type to be Class or Function but was %s." % (o, type(o)))
return o

if not points:
raise Exception("You need to define at least one point in the points decorator declaration")
for point in points:
if type(point) is not str:
msg = "Points decorator argument '%s' needs to be a string, but was %s." % (point, type(point).__name__)
raise Exception(msg)
return points_wrapper


def _parse_points(test):
name = _name_test(test)
testPoints = point_register['test']
points = testPoints[name]
key = name[:name.rfind('.')]
suitePoints = point_register['suite'][key]
points += suitePoints
return points


def _name_test(test):
module = test.__module__
classname = test.__class__.__name__
testName = test._testMethodName
return module + '.' + classname + '.' + testName
52 changes: 52 additions & 0 deletions part07/part07-09_how_old/tmc/result.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from unittest.runner import TextTestResult
from .points import _parse_points, _name_test
import atexit
import json
import traceback

results = []


class TMCResult(TextTestResult):

def __init__(self, stream, descriptions, verbosity):
super(TMCResult, self).__init__(stream, descriptions, verbosity)

def startTest(self, test):
super(TMCResult, self).startTest(test)

def addSuccess(self, test):
super(TMCResult, self).addSuccess(test)
self.addResult(test, 'passed')

def addFailure(self, test, err):
super(TMCResult, self).addFailure(test, err)
self.addResult(test, 'failed', err)

def addError(self, test, err):
super(TMCResult, self).addError(test, err)
self.addResult(test, 'errored', err)

def addResult(self, test, status, err=None):
points = _parse_points(test)
message = ""
backtrace = []
if err is not None:
message = str(err[1])
backtrace = traceback.format_tb(err[2])

details = {
'name': _name_test(test),
'status': status,
'message': message,
'passed': status == 'passed',
'points': points,
'backtrace': backtrace
}
results.append(details)

# TODO: Do not do this if not using TMCTestRunner
@atexit.register
def write_output():
with open('.tmc_test_results.json', 'w', encoding='utf8') as f:
json.dump(results, f, ensure_ascii=False)
36 changes: 36 additions & 0 deletions part07/part07-09_how_old/tmc/runner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from unittest import TextTestRunner, TestLoader
from .result import TMCResult
from .points import _parse_points, _name_test
from itertools import chain
import json


class TMCTestRunner(TextTestRunner):
"""A test runner for TMC exercises.
"""

resultclass = TMCResult

def __init__(self, *args, **kwargs):
super(TMCTestRunner, self).__init__(*args, **kwargs)

def run(self, test):
print('Running tests with some TMC magic...')
return super(TMCTestRunner, self).run(test)

def available_points(self):
testLoader = TestLoader()
tests = testLoader.discover('.', 'test*.py', None)
try:
tests = list(chain(*chain(*tests._tests)))
except Exception as error:
print("Received following Exception:", error)
tests.debug()

points = map(_parse_points, tests)
names = map(_name_test, tests)

result = dict(zip(names, points))

with open('.available_points.json', 'w') as f:
json.dump(result, f, ensure_ascii=False)
Loading

0 comments on commit c5cc239

Please sign in to comment.