Skip to content

Commit

Permalink
Converts module to class. (#1)
Browse files Browse the repository at this point in the history
* Adds instructions.md for module conversion assignment.

* Renames list_ops to listops and begins class conversion.

* ListOps class formatted and converted to class.

* Adds test.sh bash script for running pytest.

* Updates test_check_inputs for new class API.

* Updates all tests with new API.

* Updates to docstring in listops and documentation re-built.
  • Loading branch information
rvshi committed Feb 21, 2018
1 parent 0480515 commit dc58e5e
Show file tree
Hide file tree
Showing 16 changed files with 189 additions and 158 deletions.
3 changes: 1 addition & 2 deletions docs/index.rst
Expand Up @@ -10,13 +10,12 @@ Welcome to 59ers Unit Testing and Documentation Project's documentation!
:maxdepth: 2
:caption: Contents:

.. automodule:: list_ops
.. automodule:: listops
.. automodule:: test_sum
.. automodule:: test_min_max
.. automodule:: test_max_diff
.. automodule:: test_check_inputs
.. automodule:: test_import
.. automodule:: logging_config

Indices and tables
==================
Expand Down
7 changes: 0 additions & 7 deletions docs/list_ops.rst

This file was deleted.

7 changes: 7 additions & 0 deletions docs/listops.rst
@@ -0,0 +1,7 @@
listops module
==============

.. automodule:: listops
:members:
:undoc-members:
:show-inheritance:
7 changes: 7 additions & 0 deletions docs/logging_config.rst
@@ -0,0 +1,7 @@
logging\_config module
======================

.. automodule:: logging_config
:members:
:undoc-members:
:show-inheritance:
9 changes: 6 additions & 3 deletions docs/modules.rst
@@ -1,10 +1,13 @@
59ers_testing
=============
59ers_fork
==========

.. toctree::
:maxdepth: 4

list_ops
listops
logging_config
test_check_inputs
test_import
test_max_diff
test_min_max
test_sum
7 changes: 7 additions & 0 deletions docs/test_check_inputs.rst
@@ -0,0 +1,7 @@
test\_check\_inputs module
==========================

.. automodule:: test_check_inputs
:members:
:undoc-members:
:show-inheritance:
7 changes: 7 additions & 0 deletions docs/test_import.rst
@@ -0,0 +1,7 @@
test\_import module
===================

.. automodule:: test_import
:members:
:undoc-members:
:show-inheritance:
17 changes: 17 additions & 0 deletions instructions.md
@@ -0,0 +1,17 @@
# Converting Module to Class

You will work on this assignment **individually** (not with your team).

* Fork your team repository from `v2.0.0` of your testing assignment repository
into your individual user account.
* Convert your module to a class, keeping the following in mind:
+ Your module functions should become class methods.
+ Your class should have a initializer (`def __init__():`) to pass input
values into the instantiated class.
+ Your initializer should also create "placeholder" attributes that will be
assigned values when your methods are executed. These placeholders should
be set to `None` in the initializer.
* Your unit tests will need to be updated to accommodate the transition to a class.
* Maintain your docstrings and ability to build your Sphinx documentation.
* Make sure to keep using good software development practices (e.g., git feature branch workflow).
* Create an annotated tag (`v3.0.0`) when your assignment is complete.
131 changes: 0 additions & 131 deletions list_ops.py

This file was deleted.

118 changes: 118 additions & 0 deletions listops.py
@@ -0,0 +1,118 @@
import logging
from logging_config import config


class BadNumbersException(Exception):
pass


class ListOps:
"""Class to perform several basic operations on lists of integers.
"""

def __init__(self, l):
"""Inits the list object for internal storage.
:param l: list of integers to perform operations on
"""
# init logging config
logging.basicConfig(**config)
self.logger = logging.getLogger(__name__)

self.__list = None
self.list = l
self.np = self.import_modules() # import numpy

@property
def list(self):
"""List object for class
"""

return self.__list

@list.setter
def list(self, list):
"""Updates the value of self.__list while checking inputs.
See self.check_inputs(l) for exceptions raised
:param list: list object to input
"""
self.check_inputs(list)
self.__list = list

def get_sum(self):
""" Returns the sum of a list
:returns: sum of all the n integers in the list
"""
self.logger.info('Calculating sum of the list')
self.logger.debug('Input list: %s', str(self.list))
self.logger.debug('Output: %s', sum(self.list))
return sum(self.list)

def get_min_max(self):
""" Returns min and max in a list
:returns: min and max of list in a tuple
"""
min_max = (self.np.amin(self.list),
self.np.amax(self.list))

self.logger.info('Obtaining min and max of list')
self.logger.debug('Input list: %s', str(self.list))
self.logger.debug('Output: %s', str(min_max))
return min_max

def get_max_diff(self):
""" Returns maximum difference between consecutive elements in input list
:returns: maximum difference d defined by d = self.list[i+1] - self.list[i] for i = 0 to n-1
"""
diff_arr = self.np.diff(self.list)
max_diff = self.np.max(diff_arr)

self.logger.info('Calculating maximum difference in the list')
self.logger.debug('Input list: %s', str(self.list))
self.logger.debug('Output: %s', str(max_diff))
return max_diff

def import_modules(self):
""" Imports required module (Numpy)
:returns: the module Numpy
"""
try:
import numpy as np
except (ModuleNotFoundError, ImportError) as error:
raise ImportError(
'''Could not import numpy. Please make sure to have the package installed''')
self.logger.info('Imported numpy module')
return np

def check_inputs(self, l):
""" Checks if input list fits desired format
:param l: list of n integers between -9,000 and 9,000
:raises TypeError: Input must be lists
:raises TypeError: Input elements must be integers
:raises ValueError: All input elements must be between -9,000 and 9,000 (inclusive)
:raises BadNumbersException: Numbers 123 and 321 cannot be in same list
"""
if(not type(l) is list):
raise TypeError('Input must be a list')

if(not all([type(num) is int for num in l])):
self.logger.error("TypeError in setting list: must be list of integers")
raise TypeError('All inputs in list must be integers.')

if(any([abs(num) > 9000 for num in l])):
self.logger.error(
"ValueError in setting list: integers must be between -9,000 and 9,000")
raise ValueError('All inputs must be between -9,000 and 9,000 (inclusive)')
elif (any([abs(num) > 8500 for num in l])):
self.logger.warning('Some of your inputs are very close to 9000. Be careful to not exceed 9000!')
elif (any([abs(num) > 7000 for num in l])):
self.logger.warning('Some of your inputs are somewhat close to 9000. Be careful to not exceed 9000!')

if(123 in l and 321 in l):
raise BadNumbersException('List cannot contain both 123 and 321')
3 changes: 3 additions & 0 deletions test.sh
@@ -0,0 +1,3 @@
#!/bin/bash

pytest -v --pep8 --ignore=docs
9 changes: 4 additions & 5 deletions test_check_inputs.py
@@ -1,5 +1,4 @@
import pytest
from list_ops import BadNumbersException
import logging
from logging_config import config

Expand All @@ -10,7 +9,7 @@

def test_check_inputs():
logger.debug('Begin testing check inputs function')
import list_ops as lops
from listops import BadNumbersException, ListOps
error_input_list = (12,
[1, 2, 3.32],
[4, 'GTHC', 2, 333],
Expand All @@ -25,9 +24,9 @@ def test_check_inputs():
# loop over exception triggers and module functions
for i, nums in enumerate(error_input_list):
with pytest.raises(error_output_list[i]):
lops.get_sum(nums)
ListOps(nums)
with pytest.raises(error_output_list[i]):
lops.get_min_max(nums)
ListOps(nums)
with pytest.raises(error_output_list[i]):
lops.get_max_diff(nums)
ListOps(nums)
logger.debug('Complete testing check inputs function')
4 changes: 2 additions & 2 deletions test_import.py
Expand Up @@ -13,8 +13,8 @@ def test_import():
logger.debug('Begin testing import')
# remove the numpy library
with mock.patch.dict('sys.modules', {'numpy': None}):
from list_ops import import_modules
from listops import ListOps

with pytest.raises(ImportError):
import_modules()
ListOps([])
logger.debug('Complete testing import')
5 changes: 3 additions & 2 deletions test_max_diff.py
Expand Up @@ -8,9 +8,10 @@

def test_max_diff():
logger.debug('Begin testing max difference function')
from list_ops import get_max_diff
from listops import ListOps
input_list = ([1, 1, 3], [-1, 3, -16], [5, 5, 5, 5, 5])
output_results = (2, 4, 0)
for i, nums in enumerate(input_list):
assert get_max_diff(nums) == output_results[i]
l = ListOps(nums)
assert l.get_max_diff() == output_results[i]
logger.debug('Complete testing max difference function')

0 comments on commit dc58e5e

Please sign in to comment.