Skip to content

Commit

Permalink
Merge 17e4f8c into 737dad7
Browse files Browse the repository at this point in the history
  • Loading branch information
Kirill Korniakov committed Oct 20, 2020
2 parents 737dad7 + 17e4f8c commit b95972a
Show file tree
Hide file tree
Showing 19 changed files with 128 additions and 98 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@

# macOS
.DS_Store

# Python
env
*.pyc
18 changes: 10 additions & 8 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
language: python

python:
- "2.7"
#- "3.5"
# TravisCI uses Python 3.6.7 as of 2020-10-19
# python:
# - "2.7"
# - "3.5"

# install dependencies
install: "pip install -r requirements.txt"
# Install dependencies
install:
- pip install -r requirements.txt

# run tests
# Run checks
script:
- nosetests code/* --with-coverage
- nosetests -x --with-coverage code/*
- flake8 --max-line-length=110 code

# submit coverage report
# Submit coverage report
after_success:
- coveralls
38 changes: 3 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Спецкурс Agile Development, Python Edition
# Спецкурс Agile Development (Python Edition)

[![Join the chat][gitter-badge]][gitter-chat]
[![Build Status][travis-badge]][travis]
Expand Down Expand Up @@ -35,39 +35,7 @@
[book-agile]: http://www.books.ru/books/printsipy-patterny-i-metodiki-gibkoi-razrabotki-na-yazyke-c-fail-pdf-864714/?show=1
[book-refactoring]: http://www.books.ru/books/refaktoring-uluchshenie-sushchestvuyushchego-koda-fail-pdf-552092/?show=1

[lab-guide]: https://github.com/UNN-VMK-Software/agile-course-practice-python/tree/master/docs
[quiz]: https://github.com/UNN-VMK-Software/agile-course-theory/blob/master/slides/control-questions.md
[lab-guide]: https://github.com/UNN-ITMM-Software/agile-course-practice-python/tree/master/docs
[quiz]: https://github.com/UNN-ITMM-Software/agile-course-theory/blob/master/slides/control-questions.md
[cheatsheet]: https://docs.google.com/document/d/1QhdJOnSw-Gn_-WM9RWLzmxZMrWTB4EbyTkaNBWMGA3Y/edit
[exam-questions]: https://docs.google.com/spreadsheets/d/1Pt9i-UGUiFG8_tjnUjxmCqVjP9VHG9GJc1LNZQeGU_4/edit#gid=827430395

<!-- NOTES
TODO
- code
- migrate to newer version of Python
- remove log files in the end of the test
- overall code cleaning
- implement one more topic as an excersize
- infrastructure
- update lab guides for Python
- whether and how to use Python virtualenv
- change license to MIT or something like that
- also enable macOS testing on Travis CI
NOTES
- on macOS used default Python2.7
- without pip installed nose using $sudo easy_install nose, all tests have passed
69 easy_install pip
70 sudo easy_install pip
95 pip install -r requirements.txt
80 python -m pip install flake8
87 pip install zipp==0.5.0
88 pip install contextlib2 pathlib2
89 pip install configparser==3.5
99 PATH="/Users/kirill-personal/Library/Python/2.7/bin:$PATH"
-->
3 changes: 2 additions & 1 deletion code/color_space/src/model/color.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import numpy as np
from color_space import ColorSpace

from .color_space import ColorSpace


class InvalidColorError(Exception):
Expand Down
9 changes: 5 additions & 4 deletions code/color_space/src/model/color_space_converter.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import numpy as np
from numpy.linalg import inv
import math
from color import Color
from color_space import ColorSpace
import utility

from .color import Color
from .color_space import ColorSpace
from . import utility


class InvalidConversion(Exception):
Expand Down Expand Up @@ -106,7 +107,7 @@ def lab2rgb(self, color):
z = y - (b - 128.) / 200.

xyz = np.multiply(
map(utility.xyz2lab_nonlinear_transform_inv, [x, y, z]),
list(map(utility.xyz2lab_nonlinear_transform_inv, [x, y, z])),
ColorSpaceConverter.WHITE_POINT)

# Convert XYZ to RGB.
Expand Down
7 changes: 4 additions & 3 deletions code/color_space/src/model/test_color_space.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import unittest
import numpy as np
from color_space import ColorSpace, InvalidColorSpace
from color import Color, InvalidColorError
from color_space_converter import ColorSpaceConverter, InvalidConversion

from .color_space import ColorSpace, InvalidColorSpace
from .color import Color, InvalidColorError
from .color_space_converter import ColorSpaceConverter, InvalidConversion


class TestColorSpaceClass(unittest.TestCase):
Expand Down
2 changes: 1 addition & 1 deletion code/color_space/src/my_logger/mockup_logger.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from ilogger import ILogger
from .ilogger import ILogger


class MockUpLogger(ILogger):
Expand Down
2 changes: 1 addition & 1 deletion code/color_space/src/my_logger/real_logger.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from ilogger import ILogger
from .ilogger import ILogger


class Logger(ILogger):
Expand Down
5 changes: 3 additions & 2 deletions code/color_space/src/my_logger/test_logger.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import unittest
from real_logger import Logger
from ilogger import ILogger

from .real_logger import Logger
from .ilogger import ILogger


class TestILogger(unittest.TestCase):
Expand Down
8 changes: 7 additions & 1 deletion code/color_space/src/viewmodel/test_view_model.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import unittest
from view_model import ViewModel

from .view_model import ViewModel
from my_logger.real_logger import Logger
from my_logger.mockup_logger import MockUpLogger

Expand Down Expand Up @@ -73,10 +74,15 @@ def test_complains_on_incorrect_color_in_not_in_range(self):
self.assertEqual("Input values should be in range 0-255.", self.viewmodel.get_error_message())

def test_when_convert_def_rgb_to_rgb_display_it(self):
# Arrange
self.viewmodel.set_color_space_in("RGB")
self.viewmodel.set_color_space_out("RGB")
self.viewmodel.set_color_in(['0', '0', '0'])

# Act
self.viewmodel.convert()

# Assert
self.assertEqual(['0', '0', '0'], self.viewmodel.get_color_out())

def test_when_convert_rgb_to_hsv_display_it(self):
Expand Down
7 changes: 4 additions & 3 deletions code/color_space/src/viewmodel/view_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
class ViewModel:
@staticmethod
def is_correct(color):
return map(operator.methodcaller("isdigit"), color) == [True] * 3
return list(map(operator.methodcaller("isdigit"), color)) == [True] * 3

@staticmethod
def is_in_range(color, lower, upper):
Expand Down Expand Up @@ -78,9 +78,10 @@ def get_color_in(self):
return self.color_in

def convert(self):
color = Color(ColorSpace(self.color_space_in), np.array(map(int, self.color_in)))
a = np.array(list(map(int, self.color_in)))
color = Color(ColorSpace(self.color_space_in), a)
converted_color = self.converter.convert(color, ColorSpace(self.color_space_out))
self.color_out = map(str, converted_color.value.tolist())
self.color_out = list(map(str, converted_color.value.tolist()))
self.logger.log("Input color: " + str(color) + " --> " + "Output color: " + str(converted_color))

def get_error_message(self):
Expand Down
32 changes: 15 additions & 17 deletions code/fraction/src/cliview/cli_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,24 @@ def left_text(self, string):

def print_main_window(self):
os.system('cls')
print self.center_text('')
print self.center_text('Welcome to fractions calculator')
print self.left_text('First fraction: %s ' % self.first_fraction)
print self.left_text('Operation: %s ' % self.operation)
print(self.center_text(''))
print(self.center_text('Welcome to fractions calculator'))
print(self.left_text('First fraction: %s ' % self.first_fraction))
print(self.left_text('Operation: %s ' % self.operation))
if self.is_second_fraction_enabled:
print self.left_text('Second fraction: %s ' %
self.second_fraction)
print(self.left_text('Second fraction: %s ' % self.second_fraction))
if self.result:
print self.center_text('Calculation result: %s' % self.result)
print self.center_text('Possible commands:')
print self.left_text('"SetFirst,x", where x is '
'fraction value, to set first fraction')
print(self.center_text('Calculation result: %s' % self.result))
print(self.center_text('Possible commands:'))
print(self.left_text('"SetFirst,x", where x is fraction value, to set first fraction'))
if self.is_second_fraction_enabled:
print self.left_text('"SetSecond,x", where x is fraction '
'value, to set second fraction')
print self.left_text('"SetOp,x", where x is '
'one of +-*/ or "Convert to continuous"')
print(self.left_text('"SetSecond,x", where x is fraction '
'value, to set second fraction'))
print(self.left_text('"SetOp,x", where x is '
'one of +-*/ or "Convert to continuous"'))
if self.is_calc_enabled:
print self.left_text('"Calc" to get a result')
print self.left_text('"Exit" to exit')
print(self.left_text('"Calc" to get a result'))
print(self.left_text('"Exit" to exit'))

def mvvm_bind(self):
self.view_model.set_first_fraction(self.first_fraction)
Expand Down Expand Up @@ -84,7 +82,7 @@ def operation_changed(self):
def mainloop(self):
while True:
self.print_main_window()
raw_command = raw_input('Enter your choice: ')
raw_command = input('Enter your choice: ')
if ',' not in raw_command:
command = raw_command
value = None
Expand Down
2 changes: 1 addition & 1 deletion code/fraction/src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ def parse_args():
elif args.gui:
gui_view.GUIView().mainloop()
else:
print 'Option is required'
print('Option is required')
27 changes: 15 additions & 12 deletions code/fraction/src/model/fraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,36 @@ class Fraction:
FRACTION_REGEXP = '^([-]?\d+)(?:[/](\d+))?$'

@staticmethod
def from_decimal(decimal_number):
decimal_number = float(decimal_number)
def from_decimal(decimal):
decimal_str = str(decimal)
try:
n_digits_after_point = len(decimal_str) - decimal_str.index('.') - 1
except ValueError:
n_digits_after_point = 0
q = pow(10, n_digits_after_point)

# TODO: simplify logic, make it less fragile
decimal_number = float(decimal_str)
int_part = int(decimal_number)
frac_part = decimal_number - int_part
str_frac_part = str(frac_part)
n_digits_after_point = len(str_frac_part) - \
str_frac_part.index('.') - 1

q = pow(10, n_digits_after_point)
p = int(round(frac_part * q)) + int_part * q
p = int_part * q + int(round(frac_part * q))

return Fraction(p, q)

def __init__(self, p=0, q=1):
if q == 0:
raise InvalidFractionError('q cannot be equal to zero')
common_divisor = rational_math.gcd(p, q)
self.p = p / common_divisor
self.q = q / common_divisor
self.p = int(p / common_divisor)
self.q = int(q / common_divisor)

def __str__(self):
return '{p}/{q}'.format(p=self.p, q=self.q)

def __mul__(self, other):
return Fraction(self.p * other.p, self.q * other.q)

def __div__(self, other):
def __truediv__(self, other):
return Fraction(self.p * other.q, self.q * other.p)

def __rmul__(self, other):
Expand All @@ -60,7 +63,7 @@ def __sub__(self, other):
return self.__add__(-1.0 * other)

def get_integer_part(self):
return self.p / self.q
return int(self.p / self.q)

def to_decimal(self):
return self.p / float(self.q)
Expand Down
2 changes: 1 addition & 1 deletion code/fraction/src/model/rational_math.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
def euclidean_algorithm(a, b):
while b != 0:
remainder = a % b
quotient = a / b
quotient = int(a / b)
a, b = b, remainder
yield quotient, remainder

Expand Down
6 changes: 3 additions & 3 deletions code/fraction/src/model/test_fraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def test_auto_reduce_fraction(self):

def test_can_print_fraction(self):
frac = Fraction(5, 7)
self.assertEqual(str(frac), '5/7')
self.assertEqual('5/7', str(frac))

def test_can_get_int_part(self):
frac = Fraction(7, 3)
Expand Down Expand Up @@ -123,8 +123,8 @@ def test_can_convert_from_decimal_0_333333333333(self):
def test_can_convert_to_continuous_1071_462(self):
frac = Fraction(1071, 462)
expected_coefficients = [2, 3, 7]
for actual, expected in zip(frac.to_continuous(),
expected_coefficients):

for actual, expected in zip(frac.to_continuous(), expected_coefficients):
self.assertEqual(actual, expected)

def test_can_convert_to_continuous_9_4(self):
Expand Down
2 changes: 1 addition & 1 deletion code/fraction/src/viewmodel/test_viewmodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from logger.fakelogger import FakeLogger
from logger.reallogger import RealLogger
from viewmodel import ViewModel
from viewmodel.viewmodel import ViewModel


class TestFractionCalculatorViewModel(unittest.TestCase):
Expand Down
43 changes: 43 additions & 0 deletions docs/developer-notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# TODO

## Next step

- Fix issues with `flake8 --max-line-length=110 code`

## Code

* test GUI
- optional
- fix flake8 warning (newer version of flake8 and/or pycodestyle=2.4+)
- remove log files in the end of the test (or create them in folder)
- implement one more topic as an excersize
- overall code cleaning

## Infrastructure

* update lab guides for Python language
- decide whether to use Python virtualenv
- change license to MIT or something like that
- enable macOS testing on Travis CI

# NOTES

- Python virtual environment
$ python3 -m venv tutorial-env
$ source tutorial-env/bin/activate
$ deactivate # if needed


- Dependencies installation
69 easy_install pip
70 sudo easy_install pip
95 pip install -r requirements.txt

80 python -m pip install flake8
87 pip install zipp==0.5.0
88 pip install contextlib2 pathlib2
89 pip install configparser==3.5
99 PATH="/Users/kirill-personal/Library/Python/2.7/bin:$PATH"

- list available versions of the package
$ pip3 install flake8==

0 comments on commit b95972a

Please sign in to comment.