diff --git a/students/aaron/lesson08/assignment/pylint.log b/students/aaron/lesson08/assignment/pylint.log new file mode 100644 index 0000000..34a550f --- /dev/null +++ b/students/aaron/lesson08/assignment/pylint.log @@ -0,0 +1,74 @@ + + +Report +====== +20 statements analysed. + +Statistics by type +------------------ + ++---------+-------+-----------+-----------+------------+---------+ +|type |number |old number |difference |%documented |%badname | ++=========+=======+===========+===========+============+=========+ +|module |1 |1 |= |100.00 |0.00 | ++---------+-------+-----------+-----------+------------+---------+ +|class |0 |0 |= |0 |0 | ++---------+-------+-----------+-----------+------------+---------+ +|method |0 |0 |= |0 |0 | ++---------+-------+-----------+-----------+------------+---------+ +|function |3 |3 |= |100.00 |0.00 | ++---------+-------+-----------+-----------+------------+---------+ + + + +Raw metrics +----------- + ++----------+-------+------+---------+-----------+ +|type |number |% |previous |difference | ++==========+=======+======+=========+===========+ +|code |28 |75.68 |28 |= | ++----------+-------+------+---------+-----------+ +|docstring |3 |8.11 |3 |= | ++----------+-------+------+---------+-----------+ +|comment |2 |5.41 |2 |= | ++----------+-------+------+---------+-----------+ +|empty |4 |10.81 |4 |= | ++----------+-------+------+---------+-----------+ + + + +Duplication +----------- + ++-------------------------+------+---------+-----------+ +| |now |previous |difference | ++=========================+======+=========+===========+ +|nb duplicated lines |0 |0 |= | ++-------------------------+------+---------+-----------+ +|percent duplicated lines |0.000 |0.000 |= | ++-------------------------+------+---------+-----------+ + + + +Messages by category +-------------------- + ++-----------+-------+---------+-----------+ +|type |number |previous |difference | ++===========+=======+=========+===========+ +|convention |0 |0 |= | ++-----------+-------+---------+-----------+ +|refactor |0 |0 |= | ++-----------+-------+---------+-----------+ +|warning |0 |0 |= | ++-----------+-------+---------+-----------+ +|error |0 |0 |= | ++-----------+-------+---------+-----------+ + + + + +-------------------------------------------------------------------- +Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00) + diff --git a/students/aaron/lesson08/assignment/pylintrc b/students/aaron/lesson08/assignment/pylintrc new file mode 100644 index 0000000..c8e5fee --- /dev/null +++ b/students/aaron/lesson08/assignment/pylintrc @@ -0,0 +1,236 @@ +[MASTER] + +# Specify a configuration file. +#rcfile= + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +#init-hook= + +# Profiled execution. +profile=no + +# Add to the black list. It should be a base name, not a +# path. You may set this option multiple times. +ignore=CVS + +# Pickle collected data for later comparisons. +persistent=yes + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + + +[MESSAGES CONTROL] + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time. +#enable= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifier separated by comma (,) or put this option +# multiple time. +disable= too-few-public-methods, too-many-arguments + + +[REPORTS] + +# Set the output format. Available formats are text, parseable, colorized, msvs +# (visual studio) and html +output-format=text + +# Include message's id in output +include-ids=no + +# Put messages in a separate file for each module / package specified on the +# command line instead of printing them on stdout. Reports (if any) will be +# written in a file name "pylint_global.[txt|html]". +files-output=no + +# Tells whether to display a full report or only the messages +reports=yes + +# Python expression which should return a note less than 10 (10 is the highest +# note). You have access to the variables errors warning, statement which +# respectively contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (R0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Add a comment according to your evaluation note. This is used by the global +# evaluation report (R0004). +comment=no + + +[VARIABLES] + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# A regular expression matching names used for dummy variables (i.e. not used). +dummy-variables-rgx=_|dummy + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid to define new builtins when possible. +additional-builtins= + + +[BASIC] + +# Required attributes for module, separated by a comma +required-attributes= + +# List of builtins function names that should not be used, separated by a comma +bad-functions=map,filter,apply,input + +# Regular expression which should only match correct module names +module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ + +# Regular expression which should only match correct module level names +const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ + +# Regular expression which should only match correct class names +class-rgx=[A-Z_][a-zA-Z0-9]+$ + +# Regular expression which should only match correct function names +function-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct method names +method-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct instance attribute names +attr-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct argument names +argument-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct variable names +variable-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct list comprehension / +# generator expression variable names +inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ + +# Good variable names which should always be accepted, separated by a comma +good-names=i,j,k,ex,Run,_ + +# Bad variable names which should always be refused, separated by a comma +bad-names=foo,bar,baz,toto,tutu,tata + +# Regular expression which should only match functions or classes name which do +# not require a docstring +no-docstring-rgx=__.*__ + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME,XXX,TODO + + +[FORMAT] + +# Maximum number of characters on a single line. +max-line-length=100 + +# Maximum number of lines in a module +max-module-lines=1000 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + + +[SIMILARITIES] + +# Minimum lines number of a similarity. +min-similarity-lines=4 + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + + +[TYPECHECK] + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# List of classes names for which member attributes should not be checked +# (useful for classes with attributes dynamically set). +ignored-classes=SQLObject + +# When zope mode is activated, add a predefined set of Zope acquired attributes +# to generated-members. +zope=no + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E0201 when accessed. +generated-members=REQUEST,acl_users,aq_parent + + +[DESIGN] + +# Maximum number of arguments for function / method +max-args=5 + +# Argument names that match this expression will be ignored. Default to name +# with leading underscore +ignored-argument-names=_.* + +# Maximum number of locals for function / method body +max-locals=15 + +# Maximum number of return / yield for function / method body +max-returns=6 + +# Maximum number of branch for function / method body +max-branchs=12 + +# Maximum number of statements in function / method body +max-statements=50 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + + +[IMPORTS] + +# Deprecated modules which should not be used, separated by a comma +deprecated-modules=regsub,string,TERMIOS,Bastion,rexec + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report RP0402 must not be disabled) +import-graph= + +# Create a graph of external dependencies in the given file (report RP0402 must +# not be disabled) +ext-import-graph= + +# Create a graph of internal dependencies in the given file (report RP0402 must +# not be disabled) +int-import-graph= + + +[CLASSES] + +# List of interface methods to ignore, separated by a comma. This is used for +# instance to not check methods defines in Zope's Interface base class. +ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__,__new__,setUp diff --git a/students/aaron/lesson08/assignment/pytest.log b/students/aaron/lesson08/assignment/pytest.log new file mode 100644 index 0000000..025c203 --- /dev/null +++ b/students/aaron/lesson08/assignment/pytest.log @@ -0,0 +1,10 @@ +============================= test session starts ============================== +platform darwin -- Python 3.7.2, pytest-4.3.0, py-1.7.0, pluggy-0.8.1 -- /usr/local/opt/python/bin/python3.7 +cachedir: .pytest_cache +rootdir: /Users/adevey/class/Python220A_2019/students/aaron/lesson08/assignment, inifile: +collecting ... collected 2 items + +tests/test_inventory.py::test_add_furniture_new_file PASSED [ 50%] +tests/test_inventory.py::test_single_customer PASSED [100%] + +=========================== 2 passed in 0.01 seconds =========================== diff --git a/students/aaron/lesson08/assignment/src/inventory.py b/students/aaron/lesson08/assignment/src/inventory.py new file mode 100755 index 0000000..173e972 --- /dev/null +++ b/students/aaron/lesson08/assignment/src/inventory.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +''' Create and read inventory csv files. Lesson08 homework. ''' + +import os +from functools import partial + +def add_furniture(invoice_file, customer_name, item_code, + item_description, item_monthly_price): + ''' The function which actually adds data to a file ''' + write_header = not os.path.isfile(invoice_file) + fil = open(invoice_file, 'a+') + if write_header: + fil.write("customer_name,item_code,item_description,item_monthly_price\n") + fil.write("%s,%s,%s,%s\n" % (customer_name, item_code, item_description, item_monthly_price)) + fil.close() + +def single_customer(customer_name, invoice_file): + ''' Generator returns a function that adds a list of items ''' + customer_add_furniture = partial(add_furniture, invoice_file=invoice_file, + customer_name=customer_name) + def add_items_for_customer(rental_items): + for item in rental_items: + customer_add_furniture(**item) + return add_items_for_customer + +# simple test mode if run from the cli +if __name__ == "__main__": + print("Adding furniture.") + ADDER = single_customer("Bob Barker", "inventory.csv") + ITEMS = [ + {'item_code': 'DSK01', 'item_description': 'Office Desk', 'item_monthly_price': 10.01}, + {'item_code': 'LMP52', 'item_description': 'Desk Lamp', 'item_monthly_price': 1.61}, + {'item_code': 'CHR19', 'item_description': 'Office Chair', 'item_monthly_price': 5.22} + ] + ADDER(ITEMS) diff --git a/students/aaron/lesson08/assignment/tests/test_inventory.py b/students/aaron/lesson08/assignment/tests/test_inventory.py new file mode 100755 index 0000000..fa6ab54 --- /dev/null +++ b/students/aaron/lesson08/assignment/tests/test_inventory.py @@ -0,0 +1,49 @@ +""" + Autograde Lesson 8 assignment + +""" + +import pytest +import os + +import src.inventory as i + + +FILENAME = 'test_data_file.csv' + +@pytest.fixture +def _complete_furniture_file(): + return "customer_name,item_code,item_description,item_monthly_price\nStan Lee,DSK01,Office Desk,10.01\nStan Lee,LMP52,Desk Lamp,1.61\nStan Lee,CHR19,Office Chair,5.22\n" + +@pytest.fixture +def _short_furniture_file(): + return "customer_name,item_code,item_description,item_monthly_price\nAbe Lincoln,LOG24,Fireplace Log,1.11\n" + +@pytest.fixture(autouse=True) +def cleanup_after_test(): + ''' cleans up the file after every test ''' + yield + os.remove(FILENAME) + +def test_add_furniture_new_file(_short_furniture_file): + ''' Tests output file after an add_furniture call ''' + assert os.path.isfile(FILENAME) == False + i.add_furniture(FILENAME, 'Abe Lincoln', 'LOG24', 'Fireplace Log', 1.11) + f = open(FILENAME, 'r') + contents = f.read() + f.close() + assert contents == _short_furniture_file + +def test_single_customer(_complete_furniture_file): + ''' Tests output file after an add_furniture call ''' + items = [ + {'item_code': 'DSK01', 'item_description': 'Office Desk', 'item_monthly_price': 10.01}, + {'item_code': 'LMP52', 'item_description': 'Desk Lamp', 'item_monthly_price': 1.61}, + {'item_code': 'CHR19', 'item_description': 'Office Chair', 'item_monthly_price': 5.22} + ] + adder = i.single_customer('Stan Lee', FILENAME) + adder(items) + f = open(FILENAME, 'r') + contents = f.read() + f.close() + assert contents == _complete_furniture_file