diff --git a/students/template_student/lesson00/oo_class.py b/students/Justin_Jameson/lesson00/oo_class.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson00/oo_class.py
rename to students/Justin_Jameson/lesson00/oo_class.py
diff --git a/students/template_student/lesson00/oo_inherit.py b/students/Justin_Jameson/lesson00/oo_inherit.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson00/oo_inherit.py
rename to students/Justin_Jameson/lesson00/oo_inherit.py
diff --git a/students/Justin_Jameson/lesson01/activity/.idea/activity.iml b/students/Justin_Jameson/lesson01/activity/.idea/activity.iml
new file mode 100644
index 0000000..f3d7bc9
--- /dev/null
+++ b/students/Justin_Jameson/lesson01/activity/.idea/activity.iml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson01/activity/.idea/encodings.xml b/students/Justin_Jameson/lesson01/activity/.idea/encodings.xml
new file mode 100644
index 0000000..15a15b2
--- /dev/null
+++ b/students/Justin_Jameson/lesson01/activity/.idea/encodings.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson01/activity/.idea/misc.xml b/students/Justin_Jameson/lesson01/activity/.idea/misc.xml
new file mode 100644
index 0000000..a2e120d
--- /dev/null
+++ b/students/Justin_Jameson/lesson01/activity/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson01/activity/.idea/modules.xml b/students/Justin_Jameson/lesson01/activity/.idea/modules.xml
new file mode 100644
index 0000000..2b39da0
--- /dev/null
+++ b/students/Justin_Jameson/lesson01/activity/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson01/activity/.idea/vcs.xml b/students/Justin_Jameson/lesson01/activity/.idea/vcs.xml
new file mode 100644
index 0000000..4fce1d8
--- /dev/null
+++ b/students/Justin_Jameson/lesson01/activity/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson01/activity/.idea/workspace.xml b/students/Justin_Jameson/lesson01/activity/.idea/workspace.xml
new file mode 100644
index 0000000..2fed593
--- /dev/null
+++ b/students/Justin_Jameson/lesson01/activity/.idea/workspace.xml
@@ -0,0 +1,568 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ divider
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1554349476508
+
+
+ 1554349476508
+
+
+ 1554934285313
+
+
+
+ 1554934285313
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/students/template_student/lesson01/activity/README.md b/students/Justin_Jameson/lesson01/activity/README.md
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson01/activity/README.md
rename to students/Justin_Jameson/lesson01/activity/README.md
diff --git a/students/template_student/lesson01/activity/calculator/__init__.py b/students/Justin_Jameson/lesson01/activity/calculator/__init__.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson01/activity/calculator/__init__.py
rename to students/Justin_Jameson/lesson01/activity/calculator/__init__.py
diff --git a/students/template_student/lesson01/activity/calculator/adder.py b/students/Justin_Jameson/lesson01/activity/calculator/adder.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson01/activity/calculator/adder.py
rename to students/Justin_Jameson/lesson01/activity/calculator/adder.py
diff --git a/students/template_student/lesson01/activity/calculator/calculator.py b/students/Justin_Jameson/lesson01/activity/calculator/calculator.py
old mode 100755
new mode 100644
similarity index 92%
rename from students/template_student/lesson01/activity/calculator/calculator.py
rename to students/Justin_Jameson/lesson01/activity/calculator/calculator.py
index 1434d8a..203bd21
--- a/students/template_student/lesson01/activity/calculator/calculator.py
+++ b/students/Justin_Jameson/lesson01/activity/calculator/calculator.py
@@ -1,5 +1,6 @@
from .exceptions import InsufficientOperands
+
class Calculator(object):
def __init__(self, adder, subtracter, multiplier, divider):
@@ -11,7 +12,7 @@ def __init__(self, adder, subtracter, multiplier, divider):
self.stack = []
def enter_number(self, number):
- self.stack.insert(0, number)
+ self.stack.insert(1, number)
def _do_calc(self, operator):
try:
@@ -31,5 +32,5 @@ def subtract(self):
def multiply(self):
return self._do_calc(self.multiplier)
- def divide(self):
+ def divider(self):
return self._do_calc(self.divider)
diff --git a/students/template_student/lesson01/activity/calculator/divider.py b/students/Justin_Jameson/lesson01/activity/calculator/divider.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson01/activity/calculator/divider.py
rename to students/Justin_Jameson/lesson01/activity/calculator/divider.py
diff --git a/students/template_student/lesson01/activity/calculator/exceptions.py b/students/Justin_Jameson/lesson01/activity/calculator/exceptions.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson01/activity/calculator/exceptions.py
rename to students/Justin_Jameson/lesson01/activity/calculator/exceptions.py
diff --git a/students/template_student/lesson01/activity/calculator/multiplier.py b/students/Justin_Jameson/lesson01/activity/calculator/multiplier.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson01/activity/calculator/multiplier.py
rename to students/Justin_Jameson/lesson01/activity/calculator/multiplier.py
diff --git a/students/template_student/lesson01/activity/calculator/subtracter.py b/students/Justin_Jameson/lesson01/activity/calculator/subtracter.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson01/activity/calculator/subtracter.py
rename to students/Justin_Jameson/lesson01/activity/calculator/subtracter.py
diff --git a/students/template_student/lesson01/activity/squarer/squarer.py b/students/Justin_Jameson/lesson01/activity/squarer/squarer.py
similarity index 100%
rename from students/template_student/lesson01/activity/squarer/squarer.py
rename to students/Justin_Jameson/lesson01/activity/squarer/squarer.py
diff --git a/students/template_student/lesson01/activity/squarer/test.py b/students/Justin_Jameson/lesson01/activity/squarer/test.py
similarity index 100%
rename from students/template_student/lesson01/activity/squarer/test.py
rename to students/Justin_Jameson/lesson01/activity/squarer/test.py
diff --git a/students/template_student/lesson01/activity/squarer/test2.py b/students/Justin_Jameson/lesson01/activity/squarer/test2.py
similarity index 100%
rename from students/template_student/lesson01/activity/squarer/test2.py
rename to students/Justin_Jameson/lesson01/activity/squarer/test2.py
diff --git a/students/template_student/lesson01/activity/test_integration.py b/students/Justin_Jameson/lesson01/activity/test_integration.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson01/activity/test_integration.py
rename to students/Justin_Jameson/lesson01/activity/test_integration.py
diff --git a/students/template_student/lesson01/activity/test_unit.py b/students/Justin_Jameson/lesson01/activity/test_unit.py
old mode 100755
new mode 100644
similarity index 64%
rename from students/template_student/lesson01/activity/test_unit.py
rename to students/Justin_Jameson/lesson01/activity/test_unit.py
index 059f66e..72e2df5
--- a/students/template_student/lesson01/activity/test_unit.py
+++ b/students/Justin_Jameson/lesson01/activity/test_unit.py
@@ -8,6 +8,7 @@
from calculator.calculator import Calculator
from calculator.exceptions import InsufficientOperands
+
class AdderTests(TestCase):
def test_adding(self):
@@ -28,6 +29,26 @@ def test_subtracting(self):
self.assertEqual(i - j, subtracter.calc(i, j))
+class MultiplierTests(TestCase):
+
+ def test_multiplying(self):
+ multiplier = Multiplier()
+
+ for i in range(-10, 10):
+ for j in range(-10, 10):
+ self.assertEqual(i * j, multiplier.calc(i, j))
+
+
+class DividerTests(TestCase):
+
+ def test_dividing(self):
+ divider = Divider()
+
+ for i in range(-10, 10):
+ for j in range(1, 21):
+ self.assertEqual(i / j, divider.calc(i, j))
+
+
class CalculatorTests(TestCase):
def setUp(self):
@@ -62,4 +83,20 @@ def test_subtracter_call(self):
self.subtracter.calc.assert_called_with(1, 2)
+ def test_multiplier_call(self):
+ self.multiplier.calc = MagicMock(return_value=0)
+
+ self.calculator.enter_number(1)
+ self.calculator.enter_number(2)
+ self.calculator.multiply()
+
+ self.multiplier.calc.assert_called_with(1, 2)
+
+ def test_divider_call(self):
+ self.divider.calc = MagicMock(return_value=0)
+
+ self.calculator.enter_number(1)
+ self.calculator.enter_number(2)
+ self.calculator.divider()
+ self.divider.calc.assert_called_with(1, 2)
diff --git a/students/Justin_Jameson/lesson01/assignment/Justin Jameson inventory_management.zip b/students/Justin_Jameson/lesson01/assignment/Justin Jameson inventory_management.zip
new file mode 100644
index 0000000..8ba0532
Binary files /dev/null and b/students/Justin_Jameson/lesson01/assignment/Justin Jameson inventory_management.zip differ
diff --git a/students/template_student/lesson01/assignment/README.md b/students/Justin_Jameson/lesson01/assignment/README.md
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson01/assignment/README.md
rename to students/Justin_Jameson/lesson01/assignment/README.md
diff --git a/students/Justin_Jameson/lesson01/assignment/inventory_management/.idea/encodings.xml b/students/Justin_Jameson/lesson01/assignment/inventory_management/.idea/encodings.xml
new file mode 100644
index 0000000..15a15b2
--- /dev/null
+++ b/students/Justin_Jameson/lesson01/assignment/inventory_management/.idea/encodings.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson01/assignment/inventory_management/.idea/inventory_management.iml b/students/Justin_Jameson/lesson01/assignment/inventory_management/.idea/inventory_management.iml
new file mode 100644
index 0000000..f3d7bc9
--- /dev/null
+++ b/students/Justin_Jameson/lesson01/assignment/inventory_management/.idea/inventory_management.iml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson01/assignment/inventory_management/.idea/misc.xml b/students/Justin_Jameson/lesson01/assignment/inventory_management/.idea/misc.xml
new file mode 100644
index 0000000..a2e120d
--- /dev/null
+++ b/students/Justin_Jameson/lesson01/assignment/inventory_management/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson01/assignment/inventory_management/.idea/modules.xml b/students/Justin_Jameson/lesson01/assignment/inventory_management/.idea/modules.xml
new file mode 100644
index 0000000..2b9380c
--- /dev/null
+++ b/students/Justin_Jameson/lesson01/assignment/inventory_management/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson01/assignment/inventory_management/.idea/vcs.xml b/students/Justin_Jameson/lesson01/assignment/inventory_management/.idea/vcs.xml
new file mode 100644
index 0000000..bc59970
--- /dev/null
+++ b/students/Justin_Jameson/lesson01/assignment/inventory_management/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson01/assignment/inventory_management/.idea/workspace.xml b/students/Justin_Jameson/lesson01/assignment/inventory_management/.idea/workspace.xml
new file mode 100644
index 0000000..07b6794
--- /dev/null
+++ b/students/Justin_Jameson/lesson01/assignment/inventory_management/.idea/workspace.xml
@@ -0,0 +1,441 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ productCode
+ marketPrice
+ rentalPrice
+ inventory
+ furniture
+ FurnitureClass
+ itemCode
+ isFurniture
+ isElectricAppliance
+ itemVoltage
+ itemInfo
+ printDict
+ returnAsDictionary
+ V
+ variable name
+ FULL
+ FULL_INVENTORY
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1554956370486
+
+
+ 1554956370486
+
+
+ 1554962824626
+
+
+
+ 1554962824626
+
+
+ 1555028299073
+
+
+
+ 1555028299073
+
+
+ 1555033481936
+
+
+
+ 1555033481936
+
+
+ 1555037422763
+
+
+
+ 1555037422763
+
+
+ 1555044378345
+
+
+
+ 1555044378345
+
+
+ 1555433176564
+
+
+
+ 1555433176564
+
+
+ 1555437331844
+
+
+
+ 1555437331844
+
+
+ 1555437485614
+
+
+
+ 1555437485614
+
+
+ 1555460569576
+
+
+
+ 1555460569576
+
+
+ 1555525315497
+
+
+
+ 1555525315497
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson01/assignment/inventory_management/electric_appliances_class.py b/students/Justin_Jameson/lesson01/assignment/inventory_management/electric_appliances_class.py
new file mode 100644
index 0000000..e3b35cd
--- /dev/null
+++ b/students/Justin_Jameson/lesson01/assignment/inventory_management/electric_appliances_class.py
@@ -0,0 +1,47 @@
+# -------------------------------------------------#
+# # Title: electric appliances class module for Inventory Management
+# # Dev: unknown
+# # Date: 4/16/2019
+# # ChangeLog: (Who, , What)
+# Justin Jameson
+# added content to doc strings
+# -------------------------------------------------#
+"""
+This files is a class for Electric appliances
+"""
+from inventory_class import Inventory
+
+
+class ElectricAppliances(Inventory):
+ """
+ This class is for appliances.
+ """
+ def __init__(self,
+ product_code,
+ description,
+ market_price,
+ rental_price,
+ brand,
+ voltage):
+
+ """Creates common instance variables from the parent class"""
+ super().__init__(product_code,
+ description,
+ market_price,
+ rental_price)
+
+ self.brand = brand
+ self.voltage = voltage
+ self.output_dict = {}
+
+ def returnasdictionary(self):
+ """"fixing docstring"""
+ # output_dict = {}
+ self.output_dict['product_code'] = self.product_code
+ self.output_dict['description'] = self.description
+ self.output_dict['market_price'] = self.market_price
+ self.output_dict['rental_price'] = self.rental_price
+ self.output_dict['brand'] = self.brand
+ self.output_dict['voltage'] = self.voltage
+
+ return self.output_dict
diff --git a/students/Justin_Jameson/lesson01/assignment/inventory_management/furniture_class.py b/students/Justin_Jameson/lesson01/assignment/inventory_management/furniture_class.py
new file mode 100644
index 0000000..e3224c8
--- /dev/null
+++ b/students/Justin_Jameson/lesson01/assignment/inventory_management/furniture_class.py
@@ -0,0 +1,43 @@
+# -------------------------------------------------#
+# # Title:inventory class module for Inventory Management
+# # Dev: unknown
+# # Date: 4/16/2019
+# # ChangeLog: (Who, What)
+# Justin Jameson
+# added content to doc strings
+# added super(). to get rid of duplicate code.
+# -------------------------------------------------#
+""" Fixing docstring """
+from inventory_class import Inventory
+
+
+class Furniture(Inventory):
+ """ creating a child class of Inventory"""
+ def __init__(self,
+ product_code,
+ description,
+ market_price,
+ rental_price,
+ material,
+ size):
+ """Creates common instance variables from the parent class"""
+ super().__init__(product_code,
+ description,
+ market_price,
+ rental_price)
+
+ self.material = material
+ self.size = size
+ self.output_dict = {}
+
+ def return_as_dictionary(self):
+ """"can I get rid of the replicated ones from the original class?"""
+ # output_dict = {}
+ self.output_dict['product_code'] = self.product_code
+ self.output_dict['description'] = self.description
+ self.output_dict['market_price'] = self.market_price
+ self.output_dict['rental_price'] = self.rental_price
+ self.output_dict['material'] = self.material
+ self.output_dict['size'] = self.size
+
+ return self.output_dict
diff --git a/students/Justin_Jameson/lesson01/assignment/inventory_management/inventory_class.py b/students/Justin_Jameson/lesson01/assignment/inventory_management/inventory_class.py
new file mode 100644
index 0000000..e9f6b65
--- /dev/null
+++ b/students/Justin_Jameson/lesson01/assignment/inventory_management/inventory_class.py
@@ -0,0 +1,36 @@
+# -------------------------------------------------#
+# # Title:inventory class module for Inventory Management
+# # Dev: unknown
+# # Date: 4/16/2019
+# # ChangeLog: (Who, What)
+# Justin Jameson
+# added content to doc strings
+# -------------------------------------------------#
+
+""" Super class for Inventory Management program """
+
+
+class Inventory:
+ """ Inventory class defining attributes, content
+ is fed to this class from main.py and converted
+ to a dictionary. """
+ def __init__(self,
+ product_code,
+ description,
+ market_price,
+ rental_price):
+ """ prepping input from main to place in dictionary"""
+ self.product_code = product_code
+ self.description = description
+ self.market_price = market_price
+ self.rental_price = rental_price
+
+ def return_as_dictionary(self):
+ """ Fixing doc string """
+ output_dict = {}
+ output_dict['product_code'] = self.product_code
+ output_dict['description'] = self.description
+ output_dict['market_price'] = self.market_price
+ output_dict['rental_price'] = self.rental_price
+
+ return output_dict
diff --git a/students/Justin_Jameson/lesson01/assignment/inventory_management/main.py b/students/Justin_Jameson/lesson01/assignment/inventory_management/main.py
new file mode 100644
index 0000000..fd41ea8
--- /dev/null
+++ b/students/Justin_Jameson/lesson01/assignment/inventory_management/main.py
@@ -0,0 +1,112 @@
+# -------------------------------------------------#
+# # Title: Main module for inventory Management
+# # Dev: unknown
+# # Date: 4/16/2019
+# # ChangeLog: (Who, What)
+# Justin Jameson
+# Added doc strings
+# shortened lines to conform to PEP 8
+# method 'add_new_item' removed global FULL_INVENTORY;
+# added doc strings.
+# #-------------------------------------------------#
+""" Launches the user interface for the Inventory management system"""
+
+import sys
+import market_prices
+import inventory_class
+import furniture_class
+import electric_appliances_class
+
+
+def main_menu(user_prompt=None):
+ """"This method is the menu for the program. The intent is to
+ offer (3) choices, add an item, retrieve information from an existing
+ item, and exit the program."""
+ valid_prompts = {"1": add_new_item,
+ "2": item_info,
+ "q": exit_program}
+ options = list(valid_prompts.keys())
+
+ while user_prompt not in valid_prompts:
+ options_str = ("{}" + ", {}" * (len(options)-1)).format(*options)
+ # look at the format string with the use of f and options at the end.
+ print(f"Please choose from the following options ({options_str}):")
+ print("1. Add a new item to the Inventory")
+ print("2. Get item information")
+ print("q. Quit")
+ user_prompt = input(">")
+ return valid_prompts.get(user_prompt)
+
+
+def get_price(item_code):
+ """This method is incomplete, I suspect it will
+ be incorporated in the future with code from below
+ item_price = market_prices.get_latest_price(item_code)"""
+ # print("Get price")
+ item_price = market_prices.get_latest_price(item_code)
+
+
+def add_new_item():
+ """Adding items to inventory. This method will add user
+ input into a dictionary"""
+ item_code = input("Enter item code: ")
+ item_description = input("Enter item description: ")
+ item_rental_price = input("Enter item rental price: ")
+
+ # Get price from the market prices module
+ item_price = market_prices.get_latest_price(item_code)
+
+ is_furniture = input("Is this item a piece of Furniture? (Y/N): ")
+ if is_furniture.lower() == "y":
+ item_material = input("Enter item material: ")
+ item_size = input("Enter item size (S,M,L,XL): ")
+ new_item = furniture_class.Furniture(item_code,
+ item_description,
+ item_price,
+ item_rental_price,
+ item_material,
+ item_size)
+ else:
+ is_electric_appliance = input("Is this item an electric appliance?"
+ " (Y/N): ")
+ if is_electric_appliance.lower() == "y":
+ item_brand = input("Enter item brand: ")
+ item_voltage = input("Enter item voltage: ")
+ new_item = \
+ electric_appliances_class.ElectricAppliances(item_code,
+ item_description,
+ item_price,
+ item_rental_price,
+ item_brand,
+ item_voltage)
+ else:
+ new_item = inventory_class.Inventory(item_code,
+ item_description,
+ item_price,
+ item_rental_price)
+ FULL_INVENTORY[item_code] = new_item.return_as_dictionary()
+ print("New Inventory item added")
+
+
+def item_info():
+ """ This method prints the dictionary"""
+ item_code = input("Enter item code: ")
+ if item_code in FULL_INVENTORY:
+ print_dict = FULL_INVENTORY[item_code]
+ for k, value in print_dict.items():
+ print("{}:{}".format(k, value))
+ else:
+ print("Item not found in Inventory")
+
+
+def exit_program():
+ """This method exits the program"""
+ sys.exit()
+
+
+if __name__ == '__main__':
+ FULL_INVENTORY = {}
+ while True:
+ print(FULL_INVENTORY)
+ main_menu()()
+ input("Press Enter to continue...........")
diff --git a/students/Justin_Jameson/lesson01/assignment/inventory_management/market_prices.py b/students/Justin_Jameson/lesson01/assignment/inventory_management/market_prices.py
new file mode 100644
index 0000000..8021a99
--- /dev/null
+++ b/students/Justin_Jameson/lesson01/assignment/inventory_management/market_prices.py
@@ -0,0 +1,8 @@
+""" Market Prices """
+
+
+def get_latest_price(item_code):
+ """ I think this should be the magic mock?
+ Not sure exactly what is happening here"""
+ return 24
+ # Raise an exception to force the user to Mock its output
diff --git a/students/template_student/lesson01/assignment/pylintrc b/students/Justin_Jameson/lesson01/assignment/pylintrc
similarity index 100%
rename from students/template_student/lesson01/assignment/pylintrc
rename to students/Justin_Jameson/lesson01/assignment/pylintrc
diff --git a/students/Justin_Jameson/lesson01/assignment/test_unit.py b/students/Justin_Jameson/lesson01/assignment/test_unit.py
new file mode 100644
index 0000000..a084b5b
--- /dev/null
+++ b/students/Justin_Jameson/lesson01/assignment/test_unit.py
@@ -0,0 +1,49 @@
+from unittest import TestCase
+from unittest.mock import MagicMock
+from unittest.mock import patch
+from inventory_management import main
+from inventory_class import Inventory
+from furniture_class import Furniture
+from electric_appliances_class import ElectricAppliances
+
+
+class MainTest(unittest.TestCase):
+ """Tests for main.py:
+ 1. does each prompt work in 'main_menu'.
+ 2. when adding content to 'add_new_item', item is added to the dictionary.
+ 3. 'item_info' either prints the dictionary or 'Item not found in Inventory' """
+
+ def test_main(self):
+
+
+class InventoryTest(unittest.TestCase):
+ """Tests for inventory_class
+ Not a test, but would like to think about, if any of the codes have a specific
+ format, such as numbers only.
+ 1. can take 4 input items and create a dictionary"""
+
+ def test_dic_values(self):
+ test_dic = {'0u812': {'product_code': '0u812', 'description': 'new', 'market_price': 24, 'rental_price': '70'}}
+ product_code = '0u812'
+ description = 'new'
+ market_price = 24
+ rental_price = 70
+ self.assertEqual(test_dic, output_dict)
+
+
+class FurnitureTest(unittest.TestCase):
+ """Tests for furniture_class
+ 1. can take 6 input items and create a dictionary"""
+ pass
+
+
+class ElectricAppliancesTest(unittest.TestCase):
+ """Tests for electric_appliances_class
+ 1. can take 6 input items and create a dictionary"""
+ pass
+
+
+class MarketPriceTest(unittest.TestCase):
+ """Test for market_prices
+ 1. can return a value for latest price """
+ pass
diff --git a/students/template_student/lesson01/assignment/tests/README.md b/students/Justin_Jameson/lesson01/assignment/tests/README.md
similarity index 100%
rename from students/template_student/lesson01/assignment/tests/README.md
rename to students/Justin_Jameson/lesson01/assignment/tests/README.md
diff --git a/students/Justin_Jameson/lesson01/assignment/tests/test_unit.py b/students/Justin_Jameson/lesson01/assignment/tests/test_unit.py
new file mode 100644
index 0000000..6a8a286
--- /dev/null
+++ b/students/Justin_Jameson/lesson01/assignment/tests/test_unit.py
@@ -0,0 +1,23 @@
+from unittest import TestCase
+from unittest.mock import MagicMock
+import main.py
+
+"""Tests for Main.py:
+1. does each prompt work in 'main_menu'.
+2. when adding content to 'add_new_item', item is added to the dictionary.
+3. 'item_info' either prints the dictionary or 'Item not found in Inventory'
+
+Tests for inventory_class
+Not a test, but would like to think about, if any of the codes have a specific
+format, such as numbers only.
+1. can take 4 input items and create a dictionary
+
+Tests for furniture_class
+1. can take 6 input items and create a dictionary
+
+Tests for electric_appliances_class
+1. can take 6 input items and create a dictionary
+
+Test for market_prices
+1. can return a value for latest price?
+"""
\ No newline at end of file
diff --git a/students/template_student/lesson02/activity/recursive.py b/students/Justin_Jameson/lesson02/activity/recursive.py
similarity index 100%
rename from students/template_student/lesson02/activity/recursive.py
rename to students/Justin_Jameson/lesson02/activity/recursive.py
diff --git a/students/Justin_Jameson/lesson02/assignment/Justin Jameson src.zip b/students/Justin_Jameson/lesson02/assignment/Justin Jameson src.zip
new file mode 100644
index 0000000..4de3e77
Binary files /dev/null and b/students/Justin_Jameson/lesson02/assignment/Justin Jameson src.zip differ
diff --git a/students/template_student/lesson02/assignment/README.md b/students/Justin_Jameson/lesson02/assignment/README.md
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson02/assignment/README.md
rename to students/Justin_Jameson/lesson02/assignment/README.md
diff --git a/students/template_student/lesson02/assignment/extras-optional/PhyRe.py b/students/Justin_Jameson/lesson02/assignment/extras-optional/PhyRe.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson02/assignment/extras-optional/PhyRe.py
rename to students/Justin_Jameson/lesson02/assignment/extras-optional/PhyRe.py
diff --git a/students/template_student/lesson02/assignment/extras-optional/README.md b/students/Justin_Jameson/lesson02/assignment/extras-optional/README.md
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson02/assignment/extras-optional/README.md
rename to students/Justin_Jameson/lesson02/assignment/extras-optional/README.md
diff --git a/students/template_student/lesson02/assignment/pylintrc b/students/Justin_Jameson/lesson02/assignment/pylintrc
similarity index 100%
rename from students/template_student/lesson02/assignment/pylintrc
rename to students/Justin_Jameson/lesson02/assignment/pylintrc
diff --git a/students/Justin_Jameson/lesson02/assignment/src/charges_calc.py b/students/Justin_Jameson/lesson02/assignment/src/charges_calc.py
new file mode 100644
index 0000000..fb98e23
--- /dev/null
+++ b/students/Justin_Jameson/lesson02/assignment/src/charges_calc.py
@@ -0,0 +1,88 @@
+# -------------------------------------------------#
+# # Title: charges calculator for Inventory management.
+# # Dev: unknown
+# # Date: 4/17/2019
+# # ChangeLog: (Who, What)
+# Justin Jameson
+# correct ouput to output line 20 'ouptu JSON file'
+# in source.json removed extra comma on line 5884 from
+# 'units_rented': 7,,
+# imported logger
+# #-------------------------------------------------#
+
+""" Returns total price paid for individual rentals """
+
+import argparse
+import json
+import datetime
+import math
+import logging
+logging.basicConfig(filename='charges_calc.log', level=logging.DEBUG)
+log_format = "%(asctime)s %(filename)s:%(lineno)-3d %(levelname)s %(message)s"
+formatter = logging.Formatter(log_format)
+file_handler = logging.FileHandler('charges_calc.log')
+file_handler.setFormatter(formatter)
+logger = logging.getLogger()
+logger.addHandler(file_handler)
+
+
+
+def parse_cmd_arguments():
+ logging.debug('called parse_cmd')
+ parser = argparse.ArgumentParser(description='Process some integers.')
+ parser.add_argument('-i', '--input', help='input JSON file', required=True)
+ parser.add_argument('-o', '--output', help='output JSON file', required=True)
+ logging.debug('about to return parser.parse_arg')
+ return parser.parse_args()
+
+
+def load_rentals_file(filename):
+ with open(filename) as file:
+ try:
+ logging.debug('you made it to the try except block')
+ data = json.load(file)
+ except:
+ logging.warning('load_rentals_files threw an exception')
+ exit(0)
+ logging.debug('made it through try except about to "return data"')
+ return data
+
+
+def calculate_additional_fields(data):
+ for value in data.values():
+ logging.debug('trying to print values in data', value)
+ try:
+ logging.debug('cycling through calculate_add.. try block')
+ rental_start = datetime.datetime.strptime(value['rental_start'], '%m/%d/%y')
+ logging.debug('made it through rental_start')
+ rental_end = datetime.datetime.strptime(value['rental_end'], '%m/%d/%y')
+ logging.debug('made it through rental_end')
+ value['total_days'] = (rental_end - rental_start).days
+ logging.debug('made it through value total_days')
+ value['total_price'] = value['total_days'] * value['price_per_day']
+ logging.debug('made it through total_price')
+ # value['sqrt_total_price'] = math.sqrt(value['total_price'])
+ # logging.debug('made it through sqrt_total_price')
+ value['unit_cost'] = value['total_price'] / value['units_rented']
+ logging.debug('made it through calculate_add... try block', value)
+ except:
+ logging.warning('except block of calculate_add... this will exit the program without')
+ exit(0)
+ logging.debug('about to return data from calculate_add...')
+ return data
+
+
+def save_to_json(filename, data):
+ logging.debug('made it to "save_to_json')
+ with open(filename, 'w') as file:
+ json.dump(data, file)
+
+
+if __name__ == "__main__":
+ args = parse_cmd_arguments()
+ logging.debug('stepping into data')
+ data = load_rentals_file(args.input)
+ logging.debug('returning data, now redefining data to calculate_add...')
+ data = calculate_additional_fields(data)
+ logging.debug('returned data from calculate_add..., now stepping into save_to_json')
+ save_to_json(args.output, data)
diff --git a/students/template_student/lesson02/assignment/src/source.json b/students/Justin_Jameson/lesson02/assignment/src/source.json
old mode 100755
new mode 100644
similarity index 99%
rename from students/template_student/lesson02/assignment/src/source.json
rename to students/Justin_Jameson/lesson02/assignment/src/source.json
index e33b77c..a092f9b
--- a/students/template_student/lesson02/assignment/src/source.json
+++ b/students/Justin_Jameson/lesson02/assignment/src/source.json
@@ -5881,7 +5881,7 @@
},
"RNT841": {
"product_code": "PRD33",
- "units_rented": 7,,
+ "units_rented": 7,
"price_per_day": 19,
"rental_start": "5/11/16",
"rental_end": "7/27/17"
diff --git a/students/Justin_Jameson/lesson02/assignment/src/testing logger.py b/students/Justin_Jameson/lesson02/assignment/src/testing logger.py
new file mode 100644
index 0000000..4179a2c
--- /dev/null
+++ b/students/Justin_Jameson/lesson02/assignment/src/testing logger.py
@@ -0,0 +1,5 @@
+import logging
+logging.basicConfig(filename='example.log',level=logging.DEBUG)
+logging.debug('This message should go to the log file')
+logging.info('So should this')
+logging.warning('And this, too')
\ No newline at end of file
diff --git a/students/template_student/lesson03/activity/DatabaseDiagram.jpeg b/students/Justin_Jameson/lesson03/activity/DatabaseDiagram.jpeg
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson03/activity/DatabaseDiagram.jpeg
rename to students/Justin_Jameson/lesson03/activity/DatabaseDiagram.jpeg
diff --git a/students/template_student/lesson03/activity/create_personjob.py b/students/Justin_Jameson/lesson03/activity/create_personjob.py
similarity index 100%
rename from students/template_student/lesson03/activity/create_personjob.py
rename to students/Justin_Jameson/lesson03/activity/create_personjob.py
diff --git a/students/template_student/lesson03/activity/personjob.db b/students/Justin_Jameson/lesson03/activity/personjob.db
similarity index 100%
rename from students/template_student/lesson03/activity/personjob.db
rename to students/Justin_Jameson/lesson03/activity/personjob.db
diff --git a/students/template_student/lesson03/activity/personjob_learning_v1_p1.py b/students/Justin_Jameson/lesson03/activity/personjob_learning_v1_p1.py
similarity index 100%
rename from students/template_student/lesson03/activity/personjob_learning_v1_p1.py
rename to students/Justin_Jameson/lesson03/activity/personjob_learning_v1_p1.py
diff --git a/students/template_student/lesson03/activity/personjob_learning_v1_p2.csv b/students/Justin_Jameson/lesson03/activity/personjob_learning_v1_p2.csv
similarity index 100%
rename from students/template_student/lesson03/activity/personjob_learning_v1_p2.csv
rename to students/Justin_Jameson/lesson03/activity/personjob_learning_v1_p2.csv
diff --git a/students/template_student/lesson03/activity/personjob_learning_v1_p3.txt b/students/Justin_Jameson/lesson03/activity/personjob_learning_v1_p3.txt
similarity index 100%
rename from students/template_student/lesson03/activity/personjob_learning_v1_p3.txt
rename to students/Justin_Jameson/lesson03/activity/personjob_learning_v1_p3.txt
diff --git a/students/template_student/lesson03/activity/personjob_learning_v3_p1.py b/students/Justin_Jameson/lesson03/activity/personjob_learning_v3_p1.py
similarity index 100%
rename from students/template_student/lesson03/activity/personjob_learning_v3_p1.py
rename to students/Justin_Jameson/lesson03/activity/personjob_learning_v3_p1.py
diff --git a/students/template_student/lesson03/activity/personjob_learning_v3_p2.py b/students/Justin_Jameson/lesson03/activity/personjob_learning_v3_p2.py
similarity index 100%
rename from students/template_student/lesson03/activity/personjob_learning_v3_p2.py
rename to students/Justin_Jameson/lesson03/activity/personjob_learning_v3_p2.py
diff --git a/students/template_student/lesson03/activity/personjob_learning_v3_p3.py b/students/Justin_Jameson/lesson03/activity/personjob_learning_v3_p3.py
similarity index 100%
rename from students/template_student/lesson03/activity/personjob_learning_v3_p3.py
rename to students/Justin_Jameson/lesson03/activity/personjob_learning_v3_p3.py
diff --git a/students/template_student/lesson03/activity/personjob_learning_v5_p1.py b/students/Justin_Jameson/lesson03/activity/personjob_learning_v5_p1.py
similarity index 100%
rename from students/template_student/lesson03/activity/personjob_learning_v5_p1.py
rename to students/Justin_Jameson/lesson03/activity/personjob_learning_v5_p1.py
diff --git a/students/template_student/lesson03/activity/personjob_learning_v5_p2.py b/students/Justin_Jameson/lesson03/activity/personjob_learning_v5_p2.py
similarity index 100%
rename from students/template_student/lesson03/activity/personjob_learning_v5_p2.py
rename to students/Justin_Jameson/lesson03/activity/personjob_learning_v5_p2.py
diff --git a/students/template_student/lesson03/activity/personjob_learning_v5_p3.py b/students/Justin_Jameson/lesson03/activity/personjob_learning_v5_p3.py
similarity index 100%
rename from students/template_student/lesson03/activity/personjob_learning_v5_p3.py
rename to students/Justin_Jameson/lesson03/activity/personjob_learning_v5_p3.py
diff --git a/students/template_student/lesson03/activity/personjob_learning_v5_p4.py b/students/Justin_Jameson/lesson03/activity/personjob_learning_v5_p4.py
similarity index 100%
rename from students/template_student/lesson03/activity/personjob_learning_v5_p4.py
rename to students/Justin_Jameson/lesson03/activity/personjob_learning_v5_p4.py
diff --git a/students/template_student/lesson03/activity/personjob_learning_v5_p5.py b/students/Justin_Jameson/lesson03/activity/personjob_learning_v5_p5.py
similarity index 100%
rename from students/template_student/lesson03/activity/personjob_learning_v5_p5.py
rename to students/Justin_Jameson/lesson03/activity/personjob_learning_v5_p5.py
diff --git a/students/template_student/lesson03/activity/personjob_learning_v5_p6.py b/students/Justin_Jameson/lesson03/activity/personjob_learning_v5_p6.py
similarity index 100%
rename from students/template_student/lesson03/activity/personjob_learning_v5_p6.py
rename to students/Justin_Jameson/lesson03/activity/personjob_learning_v5_p6.py
diff --git a/students/template_student/lesson03/activity/personjob_learning_v5_p7.py b/students/Justin_Jameson/lesson03/activity/personjob_learning_v5_p7.py
similarity index 100%
rename from students/template_student/lesson03/activity/personjob_learning_v5_p7.py
rename to students/Justin_Jameson/lesson03/activity/personjob_learning_v5_p7.py
diff --git a/students/template_student/lesson03/activity/personjob_model.py b/students/Justin_Jameson/lesson03/activity/personjob_model.py
similarity index 100%
rename from students/template_student/lesson03/activity/personjob_model.py
rename to students/Justin_Jameson/lesson03/activity/personjob_model.py
diff --git a/students/template_student/lesson03/activity/personjob_modeli.py b/students/Justin_Jameson/lesson03/activity/personjob_modeli.py
similarity index 100%
rename from students/template_student/lesson03/activity/personjob_modeli.py
rename to students/Justin_Jameson/lesson03/activity/personjob_modeli.py
diff --git a/students/template_student/lesson03/activity/utilities.py b/students/Justin_Jameson/lesson03/activity/utilities.py
similarity index 100%
rename from students/template_student/lesson03/activity/utilities.py
rename to students/Justin_Jameson/lesson03/activity/utilities.py
diff --git a/students/Justin_Jameson/lesson03/assignment/.idea/assignment.iml b/students/Justin_Jameson/lesson03/assignment/.idea/assignment.iml
new file mode 100644
index 0000000..738176b
--- /dev/null
+++ b/students/Justin_Jameson/lesson03/assignment/.idea/assignment.iml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson03/assignment/.idea/dictionaries/jjame.xml b/students/Justin_Jameson/lesson03/assignment/.idea/dictionaries/jjame.xml
new file mode 100644
index 0000000..6b3b38d
--- /dev/null
+++ b/students/Justin_Jameson/lesson03/assignment/.idea/dictionaries/jjame.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson03/assignment/.idea/encodings.xml b/students/Justin_Jameson/lesson03/assignment/.idea/encodings.xml
new file mode 100644
index 0000000..15a15b2
--- /dev/null
+++ b/students/Justin_Jameson/lesson03/assignment/.idea/encodings.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson03/assignment/.idea/misc.xml b/students/Justin_Jameson/lesson03/assignment/.idea/misc.xml
new file mode 100644
index 0000000..a2e120d
--- /dev/null
+++ b/students/Justin_Jameson/lesson03/assignment/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson03/assignment/.idea/modules.xml b/students/Justin_Jameson/lesson03/assignment/.idea/modules.xml
new file mode 100644
index 0000000..25466ae
--- /dev/null
+++ b/students/Justin_Jameson/lesson03/assignment/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson03/assignment/.idea/terminal.xml b/students/Justin_Jameson/lesson03/assignment/.idea/terminal.xml
new file mode 100644
index 0000000..63657c7
--- /dev/null
+++ b/students/Justin_Jameson/lesson03/assignment/.idea/terminal.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson03/assignment/.idea/vcs.xml b/students/Justin_Jameson/lesson03/assignment/.idea/vcs.xml
new file mode 100644
index 0000000..4fce1d8
--- /dev/null
+++ b/students/Justin_Jameson/lesson03/assignment/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson03/assignment/.idea/workspace.xml b/students/Justin_Jameson/lesson03/assignment/.idea/workspace.xml
new file mode 100644
index 0000000..34460b3
--- /dev/null
+++ b/students/Justin_Jameson/lesson03/assignment/.idea/workspace.xml
@@ -0,0 +1,599 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Meta
+ \\
+ primary_key = True,
+ m
+ output_dict
+ customer_class
+ customer_info_model
+ model_to_dict
+ query_dict
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1555782273196
+
+
+ 1555782273196
+
+
+ 1555782412790
+
+
+
+ 1555782412790
+
+
+ 1555796326395
+
+
+
+ 1555796326395
+
+
+ 1556086646514
+
+
+
+ 1556086646514
+
+
+ 1556842384205
+
+
+
+ 1556842384205
+
+
+ 1556852773290
+
+
+
+ 1556852773290
+
+
+ 1556852783036
+
+
+
+ 1556852783036
+
+
+ 1556853408569
+
+
+
+ 1556853408569
+
+
+ 1556856112774
+
+
+
+ 1556856112774
+
+
+ 1556856134280
+
+
+
+ 1556856134280
+
+
+ 1557361963869
+
+
+
+ 1557361963869
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson03/assignment/Justin_Jameson_Lesson 3 src.zip b/students/Justin_Jameson/lesson03/assignment/Justin_Jameson_Lesson 3 src.zip
new file mode 100644
index 0000000..05e8ab7
Binary files /dev/null and b/students/Justin_Jameson/lesson03/assignment/Justin_Jameson_Lesson 3 src.zip differ
diff --git a/students/template_student/lesson03/assignment/data/customer.csv b/students/Justin_Jameson/lesson03/assignment/data/customer.csv
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson03/assignment/data/customer.csv
rename to students/Justin_Jameson/lesson03/assignment/data/customer.csv
diff --git a/students/template_student/lesson03/assignment/pylintrc b/students/Justin_Jameson/lesson03/assignment/pylintrc
similarity index 100%
rename from students/template_student/lesson03/assignment/pylintrc
rename to students/Justin_Jameson/lesson03/assignment/pylintrc
diff --git a/students/Justin_Jameson/lesson03/assignment/src/basic_operations.py b/students/Justin_Jameson/lesson03/assignment/src/basic_operations.py
new file mode 100644
index 0000000..414344b
--- /dev/null
+++ b/students/Justin_Jameson/lesson03/assignment/src/basic_operations.py
@@ -0,0 +1,210 @@
+# -------------------------------------------------#
+# # Title: Lesson 03 basic_operations
+# # Dev: Justin Jameson
+# # Date: 4/20/2019
+# # ChangeLog: (Who, when, What)
+# -------------------------------------------------#
+""" This file will perform interactions with the database and gather user input.
+Defining the database information and applying logging messages"""
+
+import sys
+import logging # Refactored by importing only Customer from customer_class, which was importing *
+import peewee
+import time
+from customer_class import CustomerInformationClass
+from customer_info_model import Customer, database # refactored to only import Customer class
+from playhouse.shortcuts import model_to_dict
+
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+
+def main_menu(user_prompt=None):
+ """
+ This method creates the menu for the program.
+ """
+ valid_prompts = {"1": create_new_customer,
+ "2": search_customer,
+ "3": delete_customer,
+ "4": update_customer_credit,
+ "5": list_active_customers,
+ "q": exit_program,
+ "t": method_to_call_testing}
+ options = list(valid_prompts.keys())
+
+ while user_prompt not in valid_prompts:
+ options_str = ("{}" + ", {}" * (len(options)-1)).format(*options)
+ print(f"Please choose from the following options ({options_str}):")
+ print("1. Add a new Customer to the DataBase")
+ print("2. Search the DataBase for a Customer")
+ print("3. Delete a Customer from the DataBase")
+ print("4. Update the Customer's credit line")
+ print("5. List all active Customers")
+ print("q. Quit")
+ user_prompt = input(">")
+ return valid_prompts.get(user_prompt)
+
+
+def create_new_customer():
+ """
+ This method calls the Customer class to populate attribute information
+ for a new customer as a dictionary.
+ :return: returns dictionary to the class?
+ """
+ new_customer = CustomerInformationClass(
+ customer_id=input("Enter Customer ID: "),
+ first_name=input("Enter Customers first name: "),
+ last_name=input("Enter Customers last name: "),
+ home_address=input("Enter the Customers Home Address: "),
+ phone_number=input("Enter the Customers Phone Number: "),
+ email_address=input("Enter the Customers Email: "),
+ customer_status=input("Enter the Customers Status (Active/Inactive):"),
+ credit_limit=input("Enter the Customers Credit Limit: "))
+ logger.info('create_new _customer parameters entered.')
+ customer_info = new_customer.return_as_dictionary()
+ add_customer(customer_info)
+
+
+def add_customer(customer_dict):
+ """
+ This method will add a customer to the database using the dictionary
+ created in the create_new_customer method.
+ :param customer_dict:
+ :return: returns to the main menu
+ """
+ try:
+ new_customer = Customer.create(
+ customer_id=customer_dict['customer_id'],
+ first_name=customer_dict['first_name'],
+ last_name=customer_dict['last_name'],
+ home_address=customer_dict['home_address'],
+ phone_number=customer_dict['phone_number'],
+ email_address=customer_dict['email_address'],
+ customer_status=customer_dict['customer_status'],
+ credit_limit=customer_dict['credit_limit']) # Record created
+ new_customer.save() # Record saved
+ logger.info('Database add successful')
+ logger.info(customer_dict)
+
+ except Exception as e:
+ logger.info(f'Error creating = {customer_dict}')
+ logger.info(e)
+ logger.info('See how the database protects our data')
+
+ # main_menu()()
+
+
+def search_customer(customer_id=None):
+ """
+ This function will return a dictionary object with name, last name,
+ email address and phone number of a customer or an empty dictionary object
+ if no customer was found.
+ :param customer_id:
+ :return: query dictionary
+ """
+ logger.info("starting try block")
+ try:
+ if customer_id is not None:
+ raise TypeError
+ customer_id = input("Enter Customer ID: ")
+
+ except TypeError:
+ customer_id = customer_id
+
+ query_dict = {}
+ try:
+ query = (
+ Customer
+ .select()
+ .where(Customer.customer_id == customer_id).get())
+ query_dict = model_to_dict(query)
+ except peewee.DoesNotExist:
+ logger.info("Can't find customer with id: %s.", customer_id)
+ logger.info("Returning empty dict.")
+ print(query_dict)
+ return query_dict # where does this return go to?
+
+
+def delete_customer(customer_id=None):
+ """
+ This function will delete a customer from the sqlite3 database.
+ :param customer_id:
+ :return: None
+ """
+ dbase = Customer
+ try:
+ if customer_id is not None:
+ raise TypeError
+ customer_id = input("Enter Customer ID: ")
+
+ except TypeError:
+ customer_id = customer_id
+ try:
+ remove_customer = dbase.get(dbase.customer_id == customer_id)
+ remove_customer.delete_instance()
+ logger.info('Database delete successful')
+
+ except Exception as e:
+ logger.info(f'Error finding = {customer_id}')
+ logger.info(e)
+
+
+def update_customer_credit(new_credit=None, customer_id=None):
+ """
+ This function will search an existing customer by customer_id
+ and update their credit limit or raise a ValueError exception
+ if the customer does not exist.
+ :param customer_id:
+ :param new_credit:
+ :return:
+ """
+ try:
+ if customer_id is not None and new_credit is not None:
+ raise TypeError
+ customer_id = input("Enter Customer ID: ")
+ new_credit = input("Enter new credit limit: ")
+
+ except TypeError:
+ customer_id = customer_id
+ new_credit = new_credit
+
+ with database.transaction():
+ update = (
+ Customer
+ .update(credit_limit=new_credit)
+ .where(Customer.customer_id == customer_id)
+ .execute()
+ )
+ # if update == 0:
+ # logger.info("No customer was found for id %s", customer_id)
+ # raise ValueError("NoCustomer")
+ return update
+
+
+def list_active_customers():
+ """This function will return an integer with the number of customers
+ whose status is currently active."""
+ try:
+ active_customers = (
+ Customer
+ .select()
+ .where(Customer.customer_status == "A").count())
+ except peewee.DoesNotExist:
+ logger.info("No active customers found in DB")
+ return active_customers
+
+
+def exit_program():
+ """This method exits the program"""
+ logger.info('called exit_program')
+ sys.exit()
+
+
+if __name__ == '__main__':
+
+ while True:
+ beginning_time = time.time()
+ main_menu()()
+ elapsed_time = time.time() - beginning_time
+ logger.info(elapsed_time)
+ input("Press Enter to continue...........")
diff --git a/students/Justin_Jameson/lesson03/assignment/src/customer_class.py b/students/Justin_Jameson/lesson03/assignment/src/customer_class.py
new file mode 100644
index 0000000..f9050af
--- /dev/null
+++ b/students/Justin_Jameson/lesson03/assignment/src/customer_class.py
@@ -0,0 +1,62 @@
+# -------------------------------------------------#
+# # Title: Lesson 03 customer_class
+# # Dev: Justin Jameson
+# # Date: 4/20/2019
+# # ChangeLog: (Who, when, What)
+# -------------------------------------------------#
+
+""" Establishing a class to collect Customer Information"""
+
+
+class CustomerInformationClass:
+ """
+ This class creates attributes for collecting Customer information. The attributes will be
+ used for database integration.
+ """
+
+ def __init__(self, customer_id, first_name, last_name, home_address, phone_number,
+ email_address, customer_status, credit_limit):
+ self.customer_id = customer_id
+ self.first_name = first_name
+ self.last_name = last_name
+ self.home_address = home_address
+ self.phone_number = phone_number
+ self.email_address = email_address
+ self.customer_status = customer_status
+ self.credit_limit = credit_limit
+
+ def return_as_dictionary(self):
+ """
+ Returns Class Representation as a Dictionary
+ :return: Dictionary Representation of the customer information
+ class
+ """
+ customer_dict = {}
+ customer_dict['customer_id'] = self.customer_id
+ customer_dict['first_name'] = self.first_name
+ customer_dict['last_name'] = self.last_name
+ customer_dict['home_address'] = self.home_address
+ customer_dict['phone_number'] = self.phone_number
+ customer_dict['email_address'] = self.email_address
+ customer_dict['customer_status'] = self.customer_status
+ customer_dict['credit_limit'] = self.credit_limit
+
+ return customer_dict
+
+ def return_as_list(self):
+ """
+ Returns Class Representation as a list
+ :return: list Representation of the customer information
+ class
+ """
+ customer_list = [(self.customer_id,
+ self.first_name,
+ self.last_name,
+ self.home_address,
+ self.phone_number,
+ self.email_address,
+ self.customer_status,
+ self.credit_limit), ]
+
+ return customer_list
+
diff --git a/students/Justin_Jameson/lesson03/assignment/src/customer_info.db b/students/Justin_Jameson/lesson03/assignment/src/customer_info.db
new file mode 100644
index 0000000..ce78013
Binary files /dev/null and b/students/Justin_Jameson/lesson03/assignment/src/customer_info.db differ
diff --git a/students/Justin_Jameson/lesson03/assignment/src/customer_info_model.py b/students/Justin_Jameson/lesson03/assignment/src/customer_info_model.py
new file mode 100644
index 0000000..caf1f95
--- /dev/null
+++ b/students/Justin_Jameson/lesson03/assignment/src/customer_info_model.py
@@ -0,0 +1,49 @@
+# -------------------------------------------------#
+# # Title: Lesson 03 customer_class
+# # Dev: Justin Jameson
+# # Date: 4/20/2019
+# # ChangeLog: (Who, when, What)
+# -------------------------------------------------#
+"""Defining the database information and applying logging messages"""
+
+import logging
+from peewee import *
+
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+database = SqliteDatabase('customer_info.db')
+database.connect()
+database.execute_sql('PRAGMA foreign_keys = ON;') # needed for sqlite only
+
+
+class BaseModel(Model):
+ class Meta:
+ database = database
+
+
+class Customer(BaseModel):
+ """
+ This class defines the Customer attribute information for the table 'Customer'.
+ """
+ customer_id = CharField(primary_key=True, max_length=10)
+ first_name = CharField(max_length=30)
+ last_name = CharField(max_length=30)
+ home_address = CharField(max_length=30)
+ phone_number = CharField(max_length=15, null=True)
+ email_address = CharField(max_length=30)
+ customer_status = CharField(max_length=30)
+ credit_limit = DecimalField(max_digits=7, decimal_places=2)
+
+ class Meta:
+ database = database # using 'customer_info.db'
+
+
+def create_table():
+ database.create_tables([Customer])
+
+
+def delete_customer(customer_id):
+ customer_id.deleteinstance()
+
+# create_table()
diff --git a/students/Justin_Jameson/lesson03/assignment/src/test.py b/students/Justin_Jameson/lesson03/assignment/src/test.py
new file mode 100644
index 0000000..87b5445
--- /dev/null
+++ b/students/Justin_Jameson/lesson03/assignment/src/test.py
@@ -0,0 +1,13 @@
+
+def catch(id = None):
+ try:
+ if id is None:
+ raise TypeError
+ print('dick')
+ except TypeError:
+ print('except worked')
+ print(2+2+1)
+ return 'shit'
+
+
+print(catch(6))
diff --git a/students/Justin_Jameson/lesson03/assignment/src/test_basic_operations.py b/students/Justin_Jameson/lesson03/assignment/src/test_basic_operations.py
new file mode 100644
index 0000000..46046be
--- /dev/null
+++ b/students/Justin_Jameson/lesson03/assignment/src/test_basic_operations.py
@@ -0,0 +1,108 @@
+# -------------------------------------------------#
+# # Title: Lesson 03 Test Harness
+# # Dev: Justin Jameson
+# # Date: 4/20/2019
+# # ChangeLog: (Who, when, What)
+# -------------------------------------------------#
+"""
+Following guidlines set forth in: Testing Python APPLYING UNIT TESTING, TDD, BDD, AND ACCEPTANCE TESTING
+- Unit tests should be placed under a test/unit directory at the top level of your project folder.
+- All folders within the application's code should be mirrored by test folders under test/unit,
+which will have the unit tests for each file in them.
+For example, app/data should have a mirrored folder of test/unit/app/data.
+- All unit test files should mirror the name of the file they are testing, with _testas the suffix.
+For example, app/data/data_interface.py should have a test file of test/unit/app/data/data_interface_test.py.
+"""
+
+import pytest
+import basic_operations as b_ops
+
+
+@pytest.fixture
+def _add_customers():
+ """
+ possible refactor could be defining the dict as a constant then calling each key in the specific method.
+ see chapter 2 from above book:
+ """
+
+ customer_dict = {'customer_id': '6', 'first_name': 'Katee', 'last_name': 'Jane',
+ 'home_address': 'Pac NW', 'phone_number': '764 206 3800',
+ 'email_address': 'none', 'customer_status': 'A',
+ 'credit_limit': '231'}
+ return customer_dict
+
+
+@pytest.fixture
+def _search_customers():
+ customer_id = 6
+ return customer_id
+
+
+@pytest.fixture
+def _delete_customers():
+ customer_id = 6
+ return customer_id
+
+
+@pytest.fixture
+def _update_customer_credit():
+ new_credit = 369
+ customer_id = 6
+ return new_credit, customer_id
+
+
+@pytest.fixture
+def _list_active_customers():
+ return []
+
+
+def test_list_active_customers(_list_active_customers):
+ """ actives """
+
+ actives = b_ops.list_active_customers()
+ assert actives != 2
+
+
+def test_add_customer(_add_customers):
+ """ additions
+ """
+ # b_ops.main_menu("q")
+ b_ops.add_customer(_add_customers)
+ added = b_ops.search_customer(6)
+ assert added["first_name"] == 'Katee'
+ assert added["last_name"] == 'Jane'
+ assert added["email_address"] == 'none'
+ assert added["phone_number"] == '764 206 3800'
+ # b_ops.delete_customer(6)
+
+
+def test_search_customer(_search_customers):
+ """ search """
+ # result = b_ops.search_customer(_search_customers)
+ # assert result == {}, {'customer_id': '6', 'first_name': 'Katee', 'last_name': 'Jane',
+ # 'home_address': 'Pac NW', 'phone_number': '764 206 3800',
+ # 'email_address': 'none', 'customer_status': 'A',
+ # 'credit_limit': '231'}
+
+ result = b_ops.search_customer(_search_customers)
+ assert result['first_name'] == 'Katee'
+ assert result["last_name"] == 'Jane'
+
+
+def test_update_customer_credit(_update_customer_credit):
+ """ update """
+ new_credit = 369
+ customer_id = 6
+ b_ops.update_customer_credit(new_credit, customer_id)
+ result = b_ops.search_customer(6)
+ assert result['credit_limit'] == 369
+
+
+def test_delete_customer(_delete_customers):
+ """ delete """
+
+ response = b_ops.delete_customer(_delete_customers)
+ assert response is None
+
+ deleted = b_ops.search_customer(_delete_customers)
+ assert deleted == {}
diff --git a/students/Justin_Jameson/lesson03/assignment/tests/test_basic_operations.py b/students/Justin_Jameson/lesson03/assignment/tests/test_basic_operations.py
new file mode 100644
index 0000000..2b746d7
--- /dev/null
+++ b/students/Justin_Jameson/lesson03/assignment/tests/test_basic_operations.py
@@ -0,0 +1,132 @@
+# -------------------------------------------------#
+# # Title: Lesson 03 Test Harness
+# # Dev: Justin Jameson
+# # Date: 4/20/2019
+# # ChangeLog: (Who, when, What)
+# -------------------------------------------------#
+"""
+Following guidlines set forth in: Testing Python APPLYING UNIT TESTING, TDD, BDD, AND ACCEPTANCE TESTING
+- Unit tests should be placed under a test/unit directory at the top level of your project folder.
+- All folders within the application's code should be mirrored by test folders under test/unit,
+which will have the unit tests for each file in them.
+For example, app/data should have a mirrored folder of test/unit/app/data.
+- All unit test files should mirror the name of the file they are testing, with _testas the suffix.
+For example, app/data/data_interface.py should have a test file of test/unit/app/data/data_interface_test.py.
+"""
+
+import pytest
+from ..assignment.src import basic_operations as b_ops
+
+
+@pytest.fixture
+def _add_customers():
+ """
+ possible refactor could be defining the dict as a constant then calling each key in the specific method.
+ see chapter 2 from above book:
+Without Setup
+class TestCalculate(unittest.TestCase):
+ def test_add_method_returns_correct_result(self):
+ calc = Calculate()
+ self.assertEqual(4, calc.add(2,2))
+
+ def test_add_method_raises_typeerror_if_not_ints(self):
+ calc = Calculate()
+ self.assertRaises(TypeError, calc.add, "Hello", "World")
+
+if __name__ == '__main__':
+ unittest.main()
+With Setup
+class TestCalculate(unittest.TestCase):
+
+ def setUp(self):
+ self.calc = Calculate()
+
+ def test_add_method_returns_correct_result(self):
+ self.assertEqual(4, self.calc.add(2,2))
+
+ def test_add_method_raises_typeerror_if_not_ints(self):
+ self.assertRaises(TypeError, self.calc.add, "Hello", "World")
+ :return:
+ """
+ customer_dict = {'customer_id': '6', 'first_name': 'Katee', 'last_name': 'Jane',
+ 'home_address': 'lkasdjf', 'phone_number': '9876',
+ 'email_address': 'none', 'customer_status': 'A',
+ 'credit_limit': '231'}
+ return customer_dict
+
+
+@pytest.fixture
+def _search_customers():
+ customer_id = 6
+ return customer_id
+
+
+@pytest.fixture
+def _delete_customers():
+ customer_id = 6
+ return customer_id
+
+
+@pytest.fixture
+def _update_customer_credit():
+ customer_id = 6
+ new_credit = 369
+ return customer_id, new_credit
+
+
+@pytest.fixture
+def _list_active_customers():
+ return []
+
+
+def test_list_active_customers(_list_active_customers):
+ """ actives """
+
+ actives = b_ops.list_active_customers()
+
+ assert actives == 2
+
+
+def test_add_customer(_add_customers):
+ """ additions
+ """
+
+ b_ops.add_customer(_add_customers)
+ added = b_ops.search_customer(6)
+ assert added["first_name"] == 'Katee'
+ assert added["last_name"] == 'Jane'
+ assert added["email_address"] == 'none'
+ assert added["phone_number"] == 9876
+ b_ops.delete_customer(6)
+
+
+def test_search_customer(_search_customers):
+ """ search """
+ result = b_ops.search_customer(_search_customers)
+ assert result == {'customer_id': '6', 'first_name': 'Katee', 'last_name': 'Jane',
+ 'home_address': 'lkasdjf', 'phone_number': '9876',
+ 'email_address': 'none', 'customer_status': 'A',
+ 'credit_limit': '231'}
+
+ result = b_ops.search_customer(_search_customers)
+ assert result["name"] == 'Katee'
+ assert result["lastname"] == 'Jane'
+
+
+def test_update_customer_credit(_update_customer_credit):
+ """ update """
+ b_ops.update_customer_credit(_update_customer_credit)
+ with pytest.raises(ValueError) as excinfo:
+ b_ops.update_customer_credit("00100", 1000) # error
+ assert 'NoCustomer' in str(excinfo.value)
+
+
+def test_delete_customer(_delete_customers):
+ """ delete """
+
+ response = b_ops.delete_customer(_delete_customers)
+ assert response is True
+
+ deleted = b_ops.search_customer(_delete_customers)
+ assert deleted == {}
+
diff --git a/students/template_student/lesson03/assignment/tests/test_gradel03.py b/students/Justin_Jameson/lesson03/assignment/tests/test_gradel03.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson03/assignment/tests/test_gradel03.py
rename to students/Justin_Jameson/lesson03/assignment/tests/test_gradel03.py
diff --git a/students/template_student/lesson04/activity/README.md b/students/Justin_Jameson/lesson04/activity/README.md
similarity index 100%
rename from students/template_student/lesson04/activity/README.md
rename to students/Justin_Jameson/lesson04/activity/README.md
diff --git a/students/Justin_Jameson/lesson04/assignment/Justin_Jameson_Lesson_04 src.zip b/students/Justin_Jameson/lesson04/assignment/Justin_Jameson_Lesson_04 src.zip
new file mode 100644
index 0000000..70095e0
Binary files /dev/null and b/students/Justin_Jameson/lesson04/assignment/Justin_Jameson_Lesson_04 src.zip differ
diff --git a/students/template_student/lesson04/assignment/data/customer.csv b/students/Justin_Jameson/lesson04/assignment/data/customer.csv
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson04/assignment/data/customer.csv
rename to students/Justin_Jameson/lesson04/assignment/data/customer.csv
diff --git a/students/template_student/lesson04/assignment/pylintrc b/students/Justin_Jameson/lesson04/assignment/pylintrc
similarity index 100%
rename from students/template_student/lesson04/assignment/pylintrc
rename to students/Justin_Jameson/lesson04/assignment/pylintrc
diff --git a/students/Justin_Jameson/lesson04/assignment/src/basic_operations.py b/students/Justin_Jameson/lesson04/assignment/src/basic_operations.py
new file mode 100644
index 0000000..414344b
--- /dev/null
+++ b/students/Justin_Jameson/lesson04/assignment/src/basic_operations.py
@@ -0,0 +1,210 @@
+# -------------------------------------------------#
+# # Title: Lesson 03 basic_operations
+# # Dev: Justin Jameson
+# # Date: 4/20/2019
+# # ChangeLog: (Who, when, What)
+# -------------------------------------------------#
+""" This file will perform interactions with the database and gather user input.
+Defining the database information and applying logging messages"""
+
+import sys
+import logging # Refactored by importing only Customer from customer_class, which was importing *
+import peewee
+import time
+from customer_class import CustomerInformationClass
+from customer_info_model import Customer, database # refactored to only import Customer class
+from playhouse.shortcuts import model_to_dict
+
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+
+def main_menu(user_prompt=None):
+ """
+ This method creates the menu for the program.
+ """
+ valid_prompts = {"1": create_new_customer,
+ "2": search_customer,
+ "3": delete_customer,
+ "4": update_customer_credit,
+ "5": list_active_customers,
+ "q": exit_program,
+ "t": method_to_call_testing}
+ options = list(valid_prompts.keys())
+
+ while user_prompt not in valid_prompts:
+ options_str = ("{}" + ", {}" * (len(options)-1)).format(*options)
+ print(f"Please choose from the following options ({options_str}):")
+ print("1. Add a new Customer to the DataBase")
+ print("2. Search the DataBase for a Customer")
+ print("3. Delete a Customer from the DataBase")
+ print("4. Update the Customer's credit line")
+ print("5. List all active Customers")
+ print("q. Quit")
+ user_prompt = input(">")
+ return valid_prompts.get(user_prompt)
+
+
+def create_new_customer():
+ """
+ This method calls the Customer class to populate attribute information
+ for a new customer as a dictionary.
+ :return: returns dictionary to the class?
+ """
+ new_customer = CustomerInformationClass(
+ customer_id=input("Enter Customer ID: "),
+ first_name=input("Enter Customers first name: "),
+ last_name=input("Enter Customers last name: "),
+ home_address=input("Enter the Customers Home Address: "),
+ phone_number=input("Enter the Customers Phone Number: "),
+ email_address=input("Enter the Customers Email: "),
+ customer_status=input("Enter the Customers Status (Active/Inactive):"),
+ credit_limit=input("Enter the Customers Credit Limit: "))
+ logger.info('create_new _customer parameters entered.')
+ customer_info = new_customer.return_as_dictionary()
+ add_customer(customer_info)
+
+
+def add_customer(customer_dict):
+ """
+ This method will add a customer to the database using the dictionary
+ created in the create_new_customer method.
+ :param customer_dict:
+ :return: returns to the main menu
+ """
+ try:
+ new_customer = Customer.create(
+ customer_id=customer_dict['customer_id'],
+ first_name=customer_dict['first_name'],
+ last_name=customer_dict['last_name'],
+ home_address=customer_dict['home_address'],
+ phone_number=customer_dict['phone_number'],
+ email_address=customer_dict['email_address'],
+ customer_status=customer_dict['customer_status'],
+ credit_limit=customer_dict['credit_limit']) # Record created
+ new_customer.save() # Record saved
+ logger.info('Database add successful')
+ logger.info(customer_dict)
+
+ except Exception as e:
+ logger.info(f'Error creating = {customer_dict}')
+ logger.info(e)
+ logger.info('See how the database protects our data')
+
+ # main_menu()()
+
+
+def search_customer(customer_id=None):
+ """
+ This function will return a dictionary object with name, last name,
+ email address and phone number of a customer or an empty dictionary object
+ if no customer was found.
+ :param customer_id:
+ :return: query dictionary
+ """
+ logger.info("starting try block")
+ try:
+ if customer_id is not None:
+ raise TypeError
+ customer_id = input("Enter Customer ID: ")
+
+ except TypeError:
+ customer_id = customer_id
+
+ query_dict = {}
+ try:
+ query = (
+ Customer
+ .select()
+ .where(Customer.customer_id == customer_id).get())
+ query_dict = model_to_dict(query)
+ except peewee.DoesNotExist:
+ logger.info("Can't find customer with id: %s.", customer_id)
+ logger.info("Returning empty dict.")
+ print(query_dict)
+ return query_dict # where does this return go to?
+
+
+def delete_customer(customer_id=None):
+ """
+ This function will delete a customer from the sqlite3 database.
+ :param customer_id:
+ :return: None
+ """
+ dbase = Customer
+ try:
+ if customer_id is not None:
+ raise TypeError
+ customer_id = input("Enter Customer ID: ")
+
+ except TypeError:
+ customer_id = customer_id
+ try:
+ remove_customer = dbase.get(dbase.customer_id == customer_id)
+ remove_customer.delete_instance()
+ logger.info('Database delete successful')
+
+ except Exception as e:
+ logger.info(f'Error finding = {customer_id}')
+ logger.info(e)
+
+
+def update_customer_credit(new_credit=None, customer_id=None):
+ """
+ This function will search an existing customer by customer_id
+ and update their credit limit or raise a ValueError exception
+ if the customer does not exist.
+ :param customer_id:
+ :param new_credit:
+ :return:
+ """
+ try:
+ if customer_id is not None and new_credit is not None:
+ raise TypeError
+ customer_id = input("Enter Customer ID: ")
+ new_credit = input("Enter new credit limit: ")
+
+ except TypeError:
+ customer_id = customer_id
+ new_credit = new_credit
+
+ with database.transaction():
+ update = (
+ Customer
+ .update(credit_limit=new_credit)
+ .where(Customer.customer_id == customer_id)
+ .execute()
+ )
+ # if update == 0:
+ # logger.info("No customer was found for id %s", customer_id)
+ # raise ValueError("NoCustomer")
+ return update
+
+
+def list_active_customers():
+ """This function will return an integer with the number of customers
+ whose status is currently active."""
+ try:
+ active_customers = (
+ Customer
+ .select()
+ .where(Customer.customer_status == "A").count())
+ except peewee.DoesNotExist:
+ logger.info("No active customers found in DB")
+ return active_customers
+
+
+def exit_program():
+ """This method exits the program"""
+ logger.info('called exit_program')
+ sys.exit()
+
+
+if __name__ == '__main__':
+
+ while True:
+ beginning_time = time.time()
+ main_menu()()
+ elapsed_time = time.time() - beginning_time
+ logger.info(elapsed_time)
+ input("Press Enter to continue...........")
diff --git a/students/Justin_Jameson/lesson04/assignment/src/customer_class.py b/students/Justin_Jameson/lesson04/assignment/src/customer_class.py
new file mode 100644
index 0000000..f9050af
--- /dev/null
+++ b/students/Justin_Jameson/lesson04/assignment/src/customer_class.py
@@ -0,0 +1,62 @@
+# -------------------------------------------------#
+# # Title: Lesson 03 customer_class
+# # Dev: Justin Jameson
+# # Date: 4/20/2019
+# # ChangeLog: (Who, when, What)
+# -------------------------------------------------#
+
+""" Establishing a class to collect Customer Information"""
+
+
+class CustomerInformationClass:
+ """
+ This class creates attributes for collecting Customer information. The attributes will be
+ used for database integration.
+ """
+
+ def __init__(self, customer_id, first_name, last_name, home_address, phone_number,
+ email_address, customer_status, credit_limit):
+ self.customer_id = customer_id
+ self.first_name = first_name
+ self.last_name = last_name
+ self.home_address = home_address
+ self.phone_number = phone_number
+ self.email_address = email_address
+ self.customer_status = customer_status
+ self.credit_limit = credit_limit
+
+ def return_as_dictionary(self):
+ """
+ Returns Class Representation as a Dictionary
+ :return: Dictionary Representation of the customer information
+ class
+ """
+ customer_dict = {}
+ customer_dict['customer_id'] = self.customer_id
+ customer_dict['first_name'] = self.first_name
+ customer_dict['last_name'] = self.last_name
+ customer_dict['home_address'] = self.home_address
+ customer_dict['phone_number'] = self.phone_number
+ customer_dict['email_address'] = self.email_address
+ customer_dict['customer_status'] = self.customer_status
+ customer_dict['credit_limit'] = self.credit_limit
+
+ return customer_dict
+
+ def return_as_list(self):
+ """
+ Returns Class Representation as a list
+ :return: list Representation of the customer information
+ class
+ """
+ customer_list = [(self.customer_id,
+ self.first_name,
+ self.last_name,
+ self.home_address,
+ self.phone_number,
+ self.email_address,
+ self.customer_status,
+ self.credit_limit), ]
+
+ return customer_list
+
diff --git a/students/Justin_Jameson/lesson04/assignment/src/customer_info.db b/students/Justin_Jameson/lesson04/assignment/src/customer_info.db
new file mode 100644
index 0000000..ce78013
Binary files /dev/null and b/students/Justin_Jameson/lesson04/assignment/src/customer_info.db differ
diff --git a/students/Justin_Jameson/lesson04/assignment/src/customer_info_model.py b/students/Justin_Jameson/lesson04/assignment/src/customer_info_model.py
new file mode 100644
index 0000000..caf1f95
--- /dev/null
+++ b/students/Justin_Jameson/lesson04/assignment/src/customer_info_model.py
@@ -0,0 +1,49 @@
+# -------------------------------------------------#
+# # Title: Lesson 03 customer_class
+# # Dev: Justin Jameson
+# # Date: 4/20/2019
+# # ChangeLog: (Who, when, What)
+# -------------------------------------------------#
+"""Defining the database information and applying logging messages"""
+
+import logging
+from peewee import *
+
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+database = SqliteDatabase('customer_info.db')
+database.connect()
+database.execute_sql('PRAGMA foreign_keys = ON;') # needed for sqlite only
+
+
+class BaseModel(Model):
+ class Meta:
+ database = database
+
+
+class Customer(BaseModel):
+ """
+ This class defines the Customer attribute information for the table 'Customer'.
+ """
+ customer_id = CharField(primary_key=True, max_length=10)
+ first_name = CharField(max_length=30)
+ last_name = CharField(max_length=30)
+ home_address = CharField(max_length=30)
+ phone_number = CharField(max_length=15, null=True)
+ email_address = CharField(max_length=30)
+ customer_status = CharField(max_length=30)
+ credit_limit = DecimalField(max_digits=7, decimal_places=2)
+
+ class Meta:
+ database = database # using 'customer_info.db'
+
+
+def create_table():
+ database.create_tables([Customer])
+
+
+def delete_customer(customer_id):
+ customer_id.deleteinstance()
+
+# create_table()
diff --git a/students/Justin_Jameson/lesson04/assignment/src/test.py b/students/Justin_Jameson/lesson04/assignment/src/test.py
new file mode 100644
index 0000000..87b5445
--- /dev/null
+++ b/students/Justin_Jameson/lesson04/assignment/src/test.py
@@ -0,0 +1,13 @@
+
+def catch(id = None):
+ try:
+ if id is None:
+ raise TypeError
+ print('dick')
+ except TypeError:
+ print('except worked')
+ print(2+2+1)
+ return 'shit'
+
+
+print(catch(6))
diff --git a/students/Justin_Jameson/lesson04/assignment/src/test_basic_operations.py b/students/Justin_Jameson/lesson04/assignment/src/test_basic_operations.py
new file mode 100644
index 0000000..46046be
--- /dev/null
+++ b/students/Justin_Jameson/lesson04/assignment/src/test_basic_operations.py
@@ -0,0 +1,108 @@
+# -------------------------------------------------#
+# # Title: Lesson 03 Test Harness
+# # Dev: Justin Jameson
+# # Date: 4/20/2019
+# # ChangeLog: (Who, when, What)
+# -------------------------------------------------#
+"""
+Following guidlines set forth in: Testing Python APPLYING UNIT TESTING, TDD, BDD, AND ACCEPTANCE TESTING
+- Unit tests should be placed under a test/unit directory at the top level of your project folder.
+- All folders within the application's code should be mirrored by test folders under test/unit,
+which will have the unit tests for each file in them.
+For example, app/data should have a mirrored folder of test/unit/app/data.
+- All unit test files should mirror the name of the file they are testing, with _testas the suffix.
+For example, app/data/data_interface.py should have a test file of test/unit/app/data/data_interface_test.py.
+"""
+
+import pytest
+import basic_operations as b_ops
+
+
+@pytest.fixture
+def _add_customers():
+ """
+ possible refactor could be defining the dict as a constant then calling each key in the specific method.
+ see chapter 2 from above book:
+ """
+
+ customer_dict = {'customer_id': '6', 'first_name': 'Katee', 'last_name': 'Jane',
+ 'home_address': 'Pac NW', 'phone_number': '764 206 3800',
+ 'email_address': 'none', 'customer_status': 'A',
+ 'credit_limit': '231'}
+ return customer_dict
+
+
+@pytest.fixture
+def _search_customers():
+ customer_id = 6
+ return customer_id
+
+
+@pytest.fixture
+def _delete_customers():
+ customer_id = 6
+ return customer_id
+
+
+@pytest.fixture
+def _update_customer_credit():
+ new_credit = 369
+ customer_id = 6
+ return new_credit, customer_id
+
+
+@pytest.fixture
+def _list_active_customers():
+ return []
+
+
+def test_list_active_customers(_list_active_customers):
+ """ actives """
+
+ actives = b_ops.list_active_customers()
+ assert actives != 2
+
+
+def test_add_customer(_add_customers):
+ """ additions
+ """
+ # b_ops.main_menu("q")
+ b_ops.add_customer(_add_customers)
+ added = b_ops.search_customer(6)
+ assert added["first_name"] == 'Katee'
+ assert added["last_name"] == 'Jane'
+ assert added["email_address"] == 'none'
+ assert added["phone_number"] == '764 206 3800'
+ # b_ops.delete_customer(6)
+
+
+def test_search_customer(_search_customers):
+ """ search """
+ # result = b_ops.search_customer(_search_customers)
+ # assert result == {}, {'customer_id': '6', 'first_name': 'Katee', 'last_name': 'Jane',
+ # 'home_address': 'Pac NW', 'phone_number': '764 206 3800',
+ # 'email_address': 'none', 'customer_status': 'A',
+ # 'credit_limit': '231'}
+
+ result = b_ops.search_customer(_search_customers)
+ assert result['first_name'] == 'Katee'
+ assert result["last_name"] == 'Jane'
+
+
+def test_update_customer_credit(_update_customer_credit):
+ """ update """
+ new_credit = 369
+ customer_id = 6
+ b_ops.update_customer_credit(new_credit, customer_id)
+ result = b_ops.search_customer(6)
+ assert result['credit_limit'] == 369
+
+
+def test_delete_customer(_delete_customers):
+ """ delete """
+
+ response = b_ops.delete_customer(_delete_customers)
+ assert response is None
+
+ deleted = b_ops.search_customer(_delete_customers)
+ assert deleted == {}
diff --git a/students/template_student/lesson04/assignment/tests/test_gradel04.py b/students/Justin_Jameson/lesson04/assignment/tests/test_gradel04.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson04/assignment/tests/test_gradel04.py
rename to students/Justin_Jameson/lesson04/assignment/tests/test_gradel04.py
diff --git a/students/Justin_Jameson/lesson05/.idea/encodings.xml b/students/Justin_Jameson/lesson05/.idea/encodings.xml
new file mode 100644
index 0000000..15a15b2
--- /dev/null
+++ b/students/Justin_Jameson/lesson05/.idea/encodings.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson05/.idea/lesson05.iml b/students/Justin_Jameson/lesson05/.idea/lesson05.iml
new file mode 100644
index 0000000..f3d7bc9
--- /dev/null
+++ b/students/Justin_Jameson/lesson05/.idea/lesson05.iml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson05/.idea/misc.xml b/students/Justin_Jameson/lesson05/.idea/misc.xml
new file mode 100644
index 0000000..a2e120d
--- /dev/null
+++ b/students/Justin_Jameson/lesson05/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson05/.idea/modules.xml b/students/Justin_Jameson/lesson05/.idea/modules.xml
new file mode 100644
index 0000000..47a7029
--- /dev/null
+++ b/students/Justin_Jameson/lesson05/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson05/.idea/vcs.xml b/students/Justin_Jameson/lesson05/.idea/vcs.xml
new file mode 100644
index 0000000..c2365ab
--- /dev/null
+++ b/students/Justin_Jameson/lesson05/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson05/.idea/workspace.xml b/students/Justin_Jameson/lesson05/.idea/workspace.xml
new file mode 100644
index 0000000..ae80d9f
--- /dev/null
+++ b/students/Justin_Jameson/lesson05/.idea/workspace.xml
@@ -0,0 +1,414 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ result
+ drop_data
+ valid_prompts
+ ReadCsvFiles
+ return_db_info
+ user_prompt
+ print_mdb_collection
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1557689396152
+
+
+ 1557689396152
+
+
+ 1557689465299
+
+
+
+ 1557689465299
+
+
+ 1557899214975
+
+
+
+ 1557899214976
+
+
+ 1557921286895
+
+
+
+ 1557921286895
+
+
+ 1558212503659
+
+
+
+ 1558212503660
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson05/MongoWorkModified.py b/students/Justin_Jameson/lesson05/MongoWorkModified.py
new file mode 100644
index 0000000..1ae5f30
--- /dev/null
+++ b/students/Justin_Jameson/lesson05/MongoWorkModified.py
@@ -0,0 +1,103 @@
+from pymongo import MongoClient
+
+
+class MongoDBConnection():
+ """MongoDB Connection"""
+
+ def __init__(self, host='127.0.0.1', port=27017):
+ """ be sure to use the ip address not name for local windows"""
+ self.host = host
+ self.port = port
+ self.connection = None
+
+ def __enter__(self):
+ self.connection = MongoClient(self.host, self.port)
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self.connection.close()
+
+
+def print_mdb_collection(collection_name):
+ for doc in collection_name.find():
+ print(doc)
+
+
+def main():
+ mongo = MongoDBConnection()
+
+ with mongo: # Context manager.
+ # mongodb database; it all starts here
+ db = mongo.connection.media #We are connecting to a database named "media".
+
+ # collection in database
+ cd = db["cd"] #Please do not confuse "cd" (corresponding to CompactDisk) with similarly named OS command (change directory)
+
+ # notice how easy these are to create and that they are "schemaless"
+ # that is, the Python module defines the data structure in a dict,
+ # rather than the database which just stores what it is told
+
+ cd_ip = {"artist": "The Who", "Title": "By Numbers"}
+ result = cd.insert_one(cd_ip) #Inserting precisely one record
+
+ cd_ip = [{
+ "artist": "Deep Purple",
+ "Title": "Made In Japan",
+ "name": "Andy"
+ },
+ {
+ "artist": "Led Zeppelin",
+ "Title": "House of the Holy",
+ "name": "Andy"
+ }, {
+ "artist": "Pink Floyd",
+ "Title": "DSOM",
+ "name": "Andy"
+ },
+ {
+ "artist": "Albert Hammond",
+ "Title": "Free Electric Band",
+ "name": "Sam"
+ }, {
+ "artist": "Nilsson",
+ "Title": "Without You",
+ "name": "Sam"
+ }] #List of dictionaries corresponding to records to be inserted
+
+ result = cd.insert_many(cd_ip) #Inserts records specified in the list above
+
+ print_mdb_collection(cd) #Prints all records from a specified table
+
+ # another collection, i.e., table
+ ThePersonWhoCollects = db["ThePersonWhoCollects"] #Should table names be the same or different?
+ #I changed name from collector to ThePersonWhoCollects so that it would not be confused with "collection".
+ ThePersonWhoCollects_ip = [{
+ "name": "Andy",
+ "preference": "Rock"
+ }, {
+ "name": "Sam",
+ "preference": "Pop"
+ }]
+ result = ThePersonWhoCollects.insert_many(ThePersonWhoCollects_ip) #The database appears after we insert many
+
+ print_mdb_collection(ThePersonWhoCollects)
+
+ # related data
+ for CurrentRecord in ThePersonWhoCollects.find(): #Here CurrentRecord is a variable pointing to each found record in a table
+ #CurrentRecord is a dictionary (EACH record is a dictionary). We can refer an element of the dictionary
+ #by its key; one of the keys is called "name"
+ print(f'List for {CurrentRecord["name"]}')
+ query = {"name": CurrentRecord["name"]}
+ for a_cd in cd.find(query): #Find all the records from table "cd" where attribute name is equal to a specified value (which happens to be a
+ #a name of a current record). In general, keys from records need satisfy properties specified in query
+ print(f'{CurrentRecord["name"]} has collected {a_cd}')
+
+ # start afresh next time?
+ yorn = input("Drop data?")
+ if yorn.upper() == 'Y':
+ cd.drop()
+ ThePersonWhoCollects.drop() #Deletes the table and the data
+
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/students/template_student/lesson05/activity/mongdb_ex.py b/students/Justin_Jameson/lesson05/activity/mongdb_ex.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/activity/mongdb_ex.py
rename to students/Justin_Jameson/lesson05/activity/mongdb_ex.py
diff --git a/students/template_student/lesson05/activity/mongodb.py b/students/Justin_Jameson/lesson05/activity/mongodb.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/activity/mongodb.py
rename to students/Justin_Jameson/lesson05/activity/mongodb.py
diff --git a/students/template_student/lesson05/activity/mongodb_script.py.amend b/students/Justin_Jameson/lesson05/activity/mongodb_script.py.amend
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/activity/mongodb_script.py.amend
rename to students/Justin_Jameson/lesson05/activity/mongodb_script.py.amend
diff --git a/students/template_student/lesson05/activity/neo4j.py b/students/Justin_Jameson/lesson05/activity/neo4j.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/activity/neo4j.py
rename to students/Justin_Jameson/lesson05/activity/neo4j.py
diff --git a/students/template_student/lesson05/activity/nosql-other/.config/config.ini.sample b/students/Justin_Jameson/lesson05/activity/nosql-other/.config/config.ini.sample
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/activity/nosql-other/.config/config.ini.sample
rename to students/Justin_Jameson/lesson05/activity/nosql-other/.config/config.ini.sample
diff --git a/students/template_student/lesson05/activity/nosql-other/data/data.pkl b/students/Justin_Jameson/lesson05/activity/nosql-other/data/data.pkl
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/activity/nosql-other/data/data.pkl
rename to students/Justin_Jameson/lesson05/activity/nosql-other/data/data.pkl
diff --git a/students/template_student/lesson05/activity/nosql-other/data/rockstars.csv b/students/Justin_Jameson/lesson05/activity/nosql-other/data/rockstars.csv
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/activity/nosql-other/data/rockstars.csv
rename to students/Justin_Jameson/lesson05/activity/nosql-other/data/rockstars.csv
diff --git a/students/template_student/lesson05/activity/nosql-other/data/shelve.dat.db b/students/Justin_Jameson/lesson05/activity/nosql-other/data/shelve.dat.db
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/activity/nosql-other/data/shelve.dat.db
rename to students/Justin_Jameson/lesson05/activity/nosql-other/data/shelve.dat.db
diff --git a/students/template_student/lesson05/activity/nosql-other/data/shelve.db b/students/Justin_Jameson/lesson05/activity/nosql-other/data/shelve.db
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/activity/nosql-other/data/shelve.db
rename to students/Justin_Jameson/lesson05/activity/nosql-other/data/shelve.db
diff --git a/students/template_student/lesson05/activity/nosql-other/src/__init__.py b/students/Justin_Jameson/lesson05/activity/nosql-other/src/__init__.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/activity/nosql-other/src/__init__.py
rename to students/Justin_Jameson/lesson05/activity/nosql-other/src/__init__.py
diff --git a/students/template_student/lesson05/activity/nosql-other/src/learn_data.py b/students/Justin_Jameson/lesson05/activity/nosql-other/src/learn_data.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/activity/nosql-other/src/learn_data.py
rename to students/Justin_Jameson/lesson05/activity/nosql-other/src/learn_data.py
diff --git a/students/template_student/lesson05/activity/nosql-other/src/learnnosql.py b/students/Justin_Jameson/lesson05/activity/nosql-other/src/learnnosql.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/activity/nosql-other/src/learnnosql.py
rename to students/Justin_Jameson/lesson05/activity/nosql-other/src/learnnosql.py
diff --git a/students/template_student/lesson05/activity/nosql-other/src/login_database.py b/students/Justin_Jameson/lesson05/activity/nosql-other/src/login_database.py
old mode 100755
new mode 100644
similarity index 88%
rename from students/template_student/lesson05/activity/nosql-other/src/login_database.py
rename to students/Justin_Jameson/lesson05/activity/nosql-other/src/login_database.py
index 4a9e6fd..aa7d8cd
--- a/students/template_student/lesson05/activity/nosql-other/src/login_database.py
+++ b/students/Justin_Jameson/lesson05/activity/nosql-other/src/login_database.py
@@ -21,16 +21,16 @@ def login_mongodb_cloud():
"""
log.info('Here is where we use the connect to mongodb.')
- log.info('Note use of f string to embed the user & password (from the tuple).')
+ log.info('Note use of customer string to embed the user & password (from the tuple).')
try:
config.read(config_file)
user = config["mongodb_cloud"]["user"]
pw = config["mongodb_cloud"]["pw"]
except Exception as e:
- print(f'error: {e}')
+ print(customer'error: {e}')
- client = pymongo.MongoClient(f'mongodb://{user}:{pw}'
+ client = pymongo.MongoClient(customer'mongodb://{user}:{pw}'
'@cluster0-shard-00-00-wphqo.mongodb.net:27017,'
'cluster0-shard-00-01-wphqo.mongodb.net:27017,'
'cluster0-shard-00-02-wphqo.mongodb.net:27017/test'
@@ -51,7 +51,7 @@ def login_redis_cloud():
except Exception as e:
- print(f'error: {e}')
+ print(customer'error: {e}')
log.info('Here is where we use the connect to redis.')
@@ -59,7 +59,7 @@ def login_redis_cloud():
r = redis.StrictRedis(host=host, port=port, password=pw, decode_responses=True)
except Exception as e:
- print(f'error: {e}')
+ print(customer'error: {e}')
return r
diff --git a/students/template_student/lesson05/activity/nosql-other/src/mongodb_script.py b/students/Justin_Jameson/lesson05/activity/nosql-other/src/mongodb_script.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/activity/nosql-other/src/mongodb_script.py
rename to students/Justin_Jameson/lesson05/activity/nosql-other/src/mongodb_script.py
diff --git a/students/template_student/lesson05/activity/nosql-other/src/neo4j_script.py b/students/Justin_Jameson/lesson05/activity/nosql-other/src/neo4j_script.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/activity/nosql-other/src/neo4j_script.py
rename to students/Justin_Jameson/lesson05/activity/nosql-other/src/neo4j_script.py
diff --git a/students/template_student/lesson05/activity/nosql-other/src/redis_script.py b/students/Justin_Jameson/lesson05/activity/nosql-other/src/redis_script.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/activity/nosql-other/src/redis_script.py
rename to students/Justin_Jameson/lesson05/activity/nosql-other/src/redis_script.py
diff --git a/students/template_student/lesson05/activity/nosql-other/src/simple_script.py b/students/Justin_Jameson/lesson05/activity/nosql-other/src/simple_script.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/activity/nosql-other/src/simple_script.py
rename to students/Justin_Jameson/lesson05/activity/nosql-other/src/simple_script.py
diff --git a/students/template_student/lesson05/activity/nosql-other/src/utilities.py b/students/Justin_Jameson/lesson05/activity/nosql-other/src/utilities.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/activity/nosql-other/src/utilities.py
rename to students/Justin_Jameson/lesson05/activity/nosql-other/src/utilities.py
diff --git a/students/template_student/lesson05/activity/peeweeapi.py b/students/Justin_Jameson/lesson05/activity/peeweeapi.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/activity/peeweeapi.py
rename to students/Justin_Jameson/lesson05/activity/peeweeapi.py
diff --git a/students/template_student/lesson05/activity/rdbms_api.py b/students/Justin_Jameson/lesson05/activity/rdbms_api.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/activity/rdbms_api.py
rename to students/Justin_Jameson/lesson05/activity/rdbms_api.py
diff --git a/students/template_student/lesson05/activity/redis.py b/students/Justin_Jameson/lesson05/activity/redis.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/activity/redis.py
rename to students/Justin_Jameson/lesson05/activity/redis.py
diff --git a/students/Justin_Jameson/lesson05/assignment/data/csv testing.py b/students/Justin_Jameson/lesson05/assignment/data/csv testing.py
new file mode 100644
index 0000000..bf58fcb
--- /dev/null
+++ b/students/Justin_Jameson/lesson05/assignment/data/csv testing.py
@@ -0,0 +1,26 @@
+import csv
+list_of_customers = []
+list_of_products = []
+list_of_rentals = []
+with open('customers.csv', 'r') as customer:
+ reader = csv.reader(customer)
+ for row in reader:
+ c_dict = {'User ID': row[0], 'Name': row[1], 'Address': row[2],
+ 'zip code': row[3], 'phone number': row[4], 'email': row[5]}
+ list_of_customers.append(c_dict)
+ list_of_customers.pop(0)
+with open('product.csv', 'r') as product:
+ reader = csv.reader(product)
+ for row in reader:
+ p_dict = {'Product ID': row[0], 'Description': row[1], 'Product Type': row[2], 'Quantity available': row[3]}
+ list_of_products.append(p_dict)
+ list_of_products.pop(0)
+with open('rental.csv', 'r') as rentals:
+ reader = csv.reader(rentals)
+ for row in reader:
+ r_dict = {'Product ID': row[0], 'User ID': row[1]}
+ list_of_rentals.append(r_dict)
+ list_of_rentals.pop(0)
+print(list_of_customers)
+print(list_of_products)
+print(list_of_rentals)
diff --git a/students/template_student/lesson05/assignment/data/customers.csv b/students/Justin_Jameson/lesson05/assignment/data/customers.csv
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/assignment/data/customers.csv
rename to students/Justin_Jameson/lesson05/assignment/data/customers.csv
diff --git a/students/template_student/lesson05/assignment/data/product.csv b/students/Justin_Jameson/lesson05/assignment/data/product.csv
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/assignment/data/product.csv
rename to students/Justin_Jameson/lesson05/assignment/data/product.csv
diff --git a/students/template_student/lesson05/assignment/data/rental.csv b/students/Justin_Jameson/lesson05/assignment/data/rental.csv
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/assignment/data/rental.csv
rename to students/Justin_Jameson/lesson05/assignment/data/rental.csv
diff --git a/students/template_student/lesson05/assignment/pylintrc b/students/Justin_Jameson/lesson05/assignment/pylintrc
similarity index 100%
rename from students/template_student/lesson05/assignment/pylintrc
rename to students/Justin_Jameson/lesson05/assignment/pylintrc
diff --git a/students/Justin_Jameson/lesson05/assignment/src/Test open in other dir.py b/students/Justin_Jameson/lesson05/assignment/src/Test open in other dir.py
new file mode 100644
index 0000000..a377b6f
--- /dev/null
+++ b/students/Justin_Jameson/lesson05/assignment/src/Test open in other dir.py
@@ -0,0 +1,94 @@
+from pymongo import MongoClient
+import csv
+
+
+class MongoDBConnection:
+ """MongoDB Connection"""
+
+ def __init__(self, host='127.0.0.1', port=27017):
+ """ be sure to use the ip address not name for local windows"""
+ self.host = host
+ self.port = port
+ self.connection = None
+
+ def __enter__(self):
+ self.connection = MongoClient(self.host, self.port)
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self.connection.close()
+
+
+def print_mdb_collection(collection_name):
+ for doc in collection_name.find():
+ print(doc)
+
+
+def read_csv_files():
+ list_of_customers = []
+ list_of_products = []
+ list_of_rentals = []
+ with open('..\\.\\data\\customers.csv', 'r') as customer:
+ reader = csv.reader(customer)
+ for row in reader:
+ c_dict = {'User ID': row[0], 'Name': row[1], 'Address': row[2],
+ 'zip code': row[3], 'phone number': row[4], 'email': row[5]}
+ list_of_customers.append(c_dict)
+ list_of_customers.pop(0)
+ with open('..\\.\\data\\product.csv', 'r') as product:
+ reader = csv.reader(product)
+ for row in reader:
+ p_dict = {'Product ID': row[0], 'Description': row[1], 'Product Type': row[2], 'Quantity available': row[3]}
+ list_of_products.append(p_dict)
+ list_of_products.pop(0)
+ with open('..\\.\\data\\rental.csv', 'r') as rentals:
+ reader = csv.reader(rentals)
+ for row in reader:
+ r_dict = {'Product ID': row[0], 'User ID': row[1]}
+ list_of_rentals.append(r_dict)
+ list_of_rentals.pop(0)
+ main(list_of_customers, list_of_products, list_of_rentals)
+
+
+def main(list_of_customers, list_of_products, list_of_rentals):
+ mongo = MongoDBConnection()
+
+ with mongo: # Context manager.
+ # mongodb database; create rentaldatabase
+ db = mongo.connection.rentaldatabase
+
+ # collection (table) in database, (3) customers, products and rental status (rental)
+ customers = db["customers"] # todo: if the db is failing, review original code from instructor for syntax
+ # todo: create method to define the list of dictionaries for customers, pass in as an argument
+ products = db["products"]
+ rental = db["rental"]
+ result_customer = customers.insert_many(list_of_customers) # Inserts records specified in the list above
+ result_products = products.insert_many(list_of_products)
+ result_rentals = rental.insert_many(list_of_rentals)
+ print_mdb_collection(customers) # Prints all records from a specified table
+ print_mdb_collection(products)
+ print_mdb_collection(rental)
+
+ """ # related data
+ for CurrentRecord in ThePersonWhoCollects.find(): # Here CurrentRecord is a variable
+ pointing to each found record in a table
+ # CurrentRecord is a dictionary (EACH record is a dictionary). We can refer an element of the dictionary
+ # by its key; one of the keys is called "name"
+ print(customer'List for {CurrentRecord["name"]}')
+ query = {"name": CurrentRecord["name"]}
+ for a_cd in cd.find(
+ query): # Find all the records from table "cd" where attribute name
+ is equal to a specified value (which happens to be a
+ # a name of a current record). In general, keys from records need satisfy properties specified in query
+ print(customer'{CurrentRecord["name"]} has collected {a_cd}')
+ """
+ # start afresh next time?
+ yorn = input("Drop data?")
+ if yorn.upper() == 'Y':
+ customers.drop()
+ products.drop()
+ rental.drop() # Deletes the table and the data
+
+
+if __name__ == "__main__":
+ read_csv_files()
diff --git a/students/Justin_Jameson/lesson05/assignment/src/database.py b/students/Justin_Jameson/lesson05/assignment/src/database.py
new file mode 100644
index 0000000..f954912
--- /dev/null
+++ b/students/Justin_Jameson/lesson05/assignment/src/database.py
@@ -0,0 +1,233 @@
+# -------------------------------------------------#
+# # Title: Lesson 05 database.py
+# # Dev: Justin Jameson
+# # Date: 5/18/2019
+# # ChangeLog: (Who, when, What)
+# -------------------------------------------------#
+from pymongo import MongoClient
+import sys
+import csv
+import logging
+
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+# ************************************** Defining variables *************************************
+directory_name = '..\\.\\data\\'
+product_data = 'product.csv'
+customer_data = 'customers.csv'
+rentals_data = 'rental.csv'
+logger.info('defined directory name and the following .csv files: product_data, customer_data, and rental_data')
+
+
+# ******************************************** Defining Classes *********************************
+class MongoDBConnection:
+ """
+ MongoDB Connection
+ """
+
+ def __init__(self, host='127.0.0.1', port=27017):
+ """ be sure to use the ip address not name for local windows"""
+ self.host = host
+ self.port = port
+ self.connection = None
+ logger.info('created connection to host {} and port {}'.format(self.host, self.port))
+
+ def __enter__(self):
+ self.connection = MongoClient(self.host, self.port)
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self.connection.close()
+
+
+class ReadCsvFiles:
+ """
+ This class calls 'import_data' method to access the csv files.
+ Then reads the csv files, and turns them into a list of dictionaries.
+ Then sends the list to the 'main' method for incorporation into MongoDB.
+ This class also uses the self items for calls in other methods.
+
+ :return:
+ """
+ def __init__(self, list_of_customers=[], list_of_products=[], list_of_rentals=[]):
+ self.list_of_customers = list_of_customers
+ self.list_of_products = list_of_products
+ self.list_of_rentals = list_of_rentals
+
+ logger.info('created empty lists')
+ imported_data = import_data(directory_name, product_data, customer_data, rentals_data)
+ customers_file = imported_data[0]
+ products_file = imported_data[1]
+ rentals_file = imported_data[2]
+
+ with open(customers_file, 'r') as customer:
+ reader = csv.reader(customer)
+ for row in reader:
+ c_dict = {'User ID': row[0], 'Name': row[1], 'Address': row[2],
+ 'zip code': row[3], 'phone number': row[4], 'email': row[5]}
+ list_of_customers.append(c_dict)
+ list_of_customers.pop(0)
+ with open(products_file, 'r') as product:
+ reader = csv.reader(product)
+ for row in reader:
+ p_dict = {'Product ID': row[0], 'Description': row[1], 'Product Type': row[2], 'Quantity available': row[3]}
+ list_of_products.append(p_dict)
+ list_of_products.pop(0)
+ with open(rentals_file, 'r') as rentals:
+ reader = csv.reader(rentals)
+ for row in reader:
+ r_dict = {'Product ID': row[0], 'User ID': row[1]}
+ list_of_rentals.append(r_dict)
+ list_of_rentals.pop(0)
+ logger.info('appended all lists with content from csv files')
+ return
+
+
+# ************************************* user interface *************************************
+def main_menu(user_prompt=None):
+ """
+ This method creates the menu for the program.
+ """
+ valid_prompts = {"1": ReadCsvFiles,
+ "2": show_available_products,
+ "3": show_rentals,
+ "4": reset_db,
+ "q": exit_program}
+ options = list(valid_prompts.keys())
+
+ while user_prompt not in valid_prompts:
+ options_str = ("{}" + ", {}" * (len(options) - 1)).format(*options)
+ print(f"Please choose from the following options ({options_str}):")
+ print("1. Load csv files to database.")
+ print("2. Show Customer products available for rent")
+ print("3. Show Sales Person the list of customers")
+ print("4. Reset the DataBase")
+ print("q. Quit")
+ user_prompt = input(">")
+ return valid_prompts.get(user_prompt)
+
+
+# ************************************* Processing *****************************************
+def db_info():
+ """
+ This method returns the use of the class 'ReadCsvFiles'.
+ :return:
+ """
+ return ReadCsvFiles()
+
+
+def import_data(directory_location, product_file, customer_file, rental_file):
+ """
+ This function takes a directory name and three csv files as input,
+ then creates a directory and file name for use in 'ReadCsvFiles' method.
+ 1. product data = product.csv
+ 2. customer data = customers.csv
+ 3. rentals data = rental.csv
+ :param directory_location:
+ :param product_file:
+ :param customer_file:
+ :param rental_file:
+ :return:import_customer, import_product, import_rentals
+ """
+ import_customer = directory_location + customer_file
+ import_product = directory_location + product_file
+ import_rentals = directory_location + rental_file
+ logger.info('returning tuple for use in method "ReadCsvFiles"')
+ return import_customer, import_product, import_rentals
+
+
+def main(list_of_customers, list_of_products, list_of_rentals):
+ """
+ Return: 2 tuples:
+ 1. a record count of the number of products, customers and rentals
+ added (in that order)
+ 2. a count of any errors that occurred, in the same order.
+ :param list_of_customers:
+ :param list_of_products:
+ :param list_of_rentals:
+ :return:
+ """
+ mongo = MongoDBConnection()
+
+ with mongo: # Context manager.
+ # mongodb database; create rentaldatabase
+ db = mongo.connection.rentaldatabase
+
+ # collection (table) in database, (3) customers, products and rental status (rental)
+ customers = db["customers"]
+ products = db["products"]
+ rental = db["rental"]
+ result_customer = customers.insert_many(list_of_customers) # Inserts records specified in the list above
+ result_products = products.insert_many(list_of_products)
+ result_rentals = rental.insert_many(list_of_rentals)
+ # print_mdb_collection(customers) # Prints all records from a specified table
+ # print_mdb_collection(products)
+ # print_mdb_collection(rental)
+ return result_customer, result_products, result_rentals
+
+
+def reset_db():
+ """
+ deletes db
+ :return:
+ """
+ mongo = MongoDBConnection()
+
+ with mongo: # Context manager.
+ db = mongo.connection.rentaldatabase
+ # start afresh next time?
+ drop_data = input("Drop data?")
+ if drop_data.upper() == 'Y':
+ db['customers'].drop()
+ db["products"].drop()
+ db["rental"].drop()
+ logger.info('dropped data from DB')
+
+
+# ****************************************** output to the user *************************************
+def show_available_products():
+ """
+ As a HP Norton customer I want to see a list of all products available for rent so that I can make a rental choice.
+ You can have a specific field to indicate if a product is available, however,
+ a quantity_available of 0 is understood as “not available”.
+ Returns a Python dictionary of products listed as available with the following fields:
+ product_id.
+ description.
+ product_type.
+ quantity_available.
+ :return:
+ """
+
+ for dlop in return_db_info.list_of_products:
+ if dlop['Quantity available'] != '0':
+ print(dlop)
+
+
+def show_rentals():
+ """
+ Returns a Python dictionary with the following user information from users that have rented products
+ matching product_id:
+ user_id.
+ name.
+ address.
+ phone_number.
+ email.
+ """
+ for doc in return_db_info.list_of_customers:
+ logger.info('producing a list of products, customers, and rentals.')
+ print(doc)
+
+
+# ***************************************** execution ***********************************************
+def exit_program():
+ """This method exits the program"""
+ logger.info('called exit_program')
+ sys.exit()
+
+
+if __name__ == "__main__":
+ return_db_info = db_info()
+ while True:
+ main_menu()()
+ input("Press Enter to continue...........")
diff --git a/students/template_student/lesson03/assignment/src/basic_operations.py b/students/Justin_Jameson/lesson05/assignment/src/testcode.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson03/assignment/src/basic_operations.py
rename to students/Justin_Jameson/lesson05/assignment/src/testcode.py
diff --git a/students/Justin_Jameson/lesson05/assignment/src/testcode2.py b/students/Justin_Jameson/lesson05/assignment/src/testcode2.py
new file mode 100644
index 0000000..325864a
--- /dev/null
+++ b/students/Justin_Jameson/lesson05/assignment/src/testcode2.py
@@ -0,0 +1,231 @@
+# -------------------------------------------------#
+# # Title: Lesson 05 database.py
+# # Dev: Justin Jameson
+# # Date: 5/18/2019
+# # ChangeLog: (Who, when, What)
+# -------------------------------------------------#
+from pymongo import MongoClient
+import sys
+import csv
+import logging
+
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+# ************************************** Defining variables *************************************
+directory_name = '..\\.\\data\\'
+product_data = 'product.csv'
+customer_data = 'customers.csv'
+rentals_data = 'rental.csv'
+logger.info('defined directory name and the following .csv files: product_data, customer_data, and rental_data')
+
+
+# ******************************************** Defining Classes *********************************
+class MongoDBConnection:
+ """
+ MongoDB Connection
+ """
+
+ def __init__(self, host='127.0.0.1', port=27017):
+ """ be sure to use the ip address not name for local windows"""
+ self.host = host
+ self.port = port
+ self.connection = None
+ logger.info('created connection to host {} and port {}'.format(self.host, self.port))
+
+ def __enter__(self):
+ self.connection = MongoClient(self.host, self.port)
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self.connection.close()
+
+
+class ReadCsvFiles:
+ """
+ This class calls 'import_data' method to access the csv files.
+ Then reads the csv files, and turns them into a list of dictionaries.
+ Then sends the list to the 'main' method for incorporation into MongoDB.
+ This class also uses the self items for calls in other methods.
+
+ :return:
+ """
+ def __init__(self, list_of_customers=[], list_of_products=[], list_of_rentals=[]):
+ self.list_of_customers = list_of_customers
+ self.list_of_products = list_of_products
+ self.list_of_rentals = list_of_rentals
+
+ logger.info('created empty lists')
+ imported_data = import_data(directory_name, product_data, customer_data, rentals_data)
+ customers_file = imported_data[0]
+ products_file = imported_data[1]
+ rentals_file = imported_data[2]
+
+ with open(customers_file, 'r') as customer:
+ reader = csv.reader(customer)
+ for row in reader:
+ c_dict = {'User ID': row[0], 'Name': row[1], 'Address': row[2],
+ 'zip code': row[3], 'phone number': row[4], 'email': row[5]}
+ list_of_customers.append(c_dict)
+ list_of_customers.pop(0)
+ with open(products_file, 'r') as product:
+ reader = csv.reader(product)
+ for row in reader:
+ p_dict = {'Product ID': row[0], 'Description': row[1], 'Product Type': row[2], 'Quantity available': row[3]}
+ list_of_products.append(p_dict)
+ list_of_products.pop(0)
+ with open(rentals_file, 'r') as rentals:
+ reader = csv.reader(rentals)
+ for row in reader:
+ r_dict = {'Product ID': row[0], 'User ID': row[1]}
+ list_of_rentals.append(r_dict)
+ list_of_rentals.pop(0)
+ logger.info('appended all lists with content from csv files')
+ main_menu()()
+
+
+# ************************************* user interface *************************************
+def main_menu(user_prompt=None):
+ """
+ This method creates the menu for the program.
+ """
+ valid_prompts = {"1": ReadCsvFiles,
+ "2": show_available_products,
+ "3": show_rentals,
+ "4": reset_db,
+ "q": exit_program}
+ options = list(valid_prompts.keys())
+
+ while user_prompt not in valid_prompts:
+ options_str = ("{}" + ", {}" * (len(options) - 1)).format(*options)
+ print(f"Please choose from the following options ({options_str}):")
+ print("1. Load csv files to database.")
+ print("2. Show Customer products available for rent")
+ print("3. Show Sales Person the list of customers")
+ print("4. Reset the DataBase")
+ print("q. Quit")
+ user_prompt = input(">")
+ return valid_prompts.get(user_prompt)
+
+
+# ************************************* Processing *****************************************
+def db_info():
+ """
+ This method returns the use of the class 'ReadCsvFiles'.
+ :return:
+ """
+ return ReadCsvFiles()
+
+
+def import_data(directory_location, product_file, customer_file, rental_file):
+ """
+ This function takes a directory name and three csv files as input,
+ then creates a directory and file name for use in 'ReadCsvFiles' method.
+ 1. product data = product.csv
+ 2. customer data = customers.csv
+ 3. rentals data = rental.csv
+ :param directory_location:
+ :param product_file:
+ :param customer_file:
+ :param rental_file:
+ :return:import_customer, import_product, import_rentals
+ """
+ import_customer = directory_location + customer_file
+ import_product = directory_location + product_file
+ import_rentals = directory_location + rental_file
+ logger.info('returning tuple for use in method "ReadCsvFiles"')
+ return import_customer, import_product, import_rentals
+
+
+def main(list_of_customers, list_of_products, list_of_rentals):
+ """
+ Return: 2 tuples:
+ 1. a record count of the number of products, customers and rentals
+ added (in that order)
+ 2. a count of any errors that occurred, in the same order.
+ :param list_of_customers:
+ :param list_of_products:
+ :param list_of_rentals:
+ :return:
+ """
+ mongo = MongoDBConnection()
+
+ with mongo: # Context manager.
+ # mongodb database; create rentaldatabase
+ db = mongo.connection.rentaldatabase
+
+ # collection (table) in database, (3) customers, products and rental status (rental)
+ customers = db["customers"]
+ products = db["products"]
+ rental = db["rental"]
+ result_customer = customers.insert_many(list_of_customers) # Inserts records specified in the list above
+ result_products = products.insert_many(list_of_products)
+ result_rentals = rental.insert_many(list_of_rentals)
+ # print_mdb_collection(customers) # Prints all records from a specified table
+ # print_mdb_collection(products)
+ # print_mdb_collection(rental)
+ return result_customer, result_products, result_rentals
+
+
+def reset_db():
+ """
+ deletes db
+ :return:
+ """
+ mongo = MongoDBConnection()
+
+ with mongo: # Context manager.
+ db = mongo.connection.rentaldatabase
+ # start afresh next time?
+ drop_data = input("Drop data?")
+ if drop_data.upper() == 'Y':
+ db['customers'].drop()
+ db["products"].drop()
+ db["rental"].drop()
+ logger.info('dropped data from DB')
+
+
+# ****************************************** output to the user *************************************
+def show_available_products():
+ """
+ As a HP Norton customer I want to see a list of all products available for rent so that I can make a rental choice.
+ You can have a specific field to indicate if a product is available, however,
+ a quantity_available of 0 is understood as “not available”.
+ Returns a Python dictionary of products listed as available with the following fields:
+ product_id.
+ description.
+ product_type.
+ quantity_available.
+ :return:
+ """
+
+ for dlop in return_db_info.list_of_products:
+ if dlop['Quantity available'] != '0':
+ print(dlop)
+
+
+def show_rentals():
+ """
+ Returns a Python dictionary with the following user information from users that have rented products
+ matching product_id:
+ user_id.
+ name.
+ address.
+ phone_number.
+ email.
+ """
+ return_db_info = db_info()
+ for doc in return_db_info.list_of_customers:
+ logger.info('producing a list of products, customers, and rentals.')
+ print(doc)
+
+
+# ***************************************** execution ***********************************************
+def exit_program():
+ """This method exits the program"""
+ logger.info('called exit_program')
+ sys.exit()
+
+
+if __name__ == "__main__":
+ main_menu()()
diff --git a/students/template_student/lesson05/assignment/tests/test_database.py b/students/Justin_Jameson/lesson05/assignment/tests/test_database.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson05/assignment/tests/test_database.py
rename to students/Justin_Jameson/lesson05/assignment/tests/test_database.py
diff --git a/students/Justin_Jameson/lesson05/chat from zoom lesson 5.txt b/students/Justin_Jameson/lesson05/chat from zoom lesson 5.txt
new file mode 100644
index 0000000..5247b6b
--- /dev/null
+++ b/students/Justin_Jameson/lesson05/chat from zoom lesson 5.txt
@@ -0,0 +1,110 @@
+From Kyle Creek to Everyone: 06:02 PM
+I am ready whenever
+From danielcastro to Everyone: 06:02 PM
+yes ready
+From PYTHON Host to Everyone: 06:04 PM
+Any volunteer to answer the question :)
+From Sam Chang to Everyone: 06:18 PM
+not yet
+From Me to Everyone: 06:18 PM
+yes
+From Kyle Creek to Everyone: 06:18 PM
+I tried to install the software. Not sure if it works
+From Aaron Devey to Everyone: 06:19 PM
+haven't tried yet
+From Kyle Creek to Everyone: 06:20 PM
+I had to go to the mongo website to install Mongo
+From danielcastro to Everyone: 06:20 PM
+theres a test file you can run to make sure everything was installed
+From Aaron Devey to Everyone: 06:20 PM
+brew is for mac
+https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/ <--- windows instructions
+From Kyle Creek to Everyone: 06:21 PM
+I have a question about Mongo, or maybe API's in general. From what I"ve gathered Mongo is an API. I always had the understand that you query APIs for data and they return it. IN the samples provided it seems like you build the data and store it in a MongoDB?
+From Me to Everyone: 06:21 PM
+Thanks Aaron!
+From Kyle Creek to Everyone: 06:25 PM
+Yeah that makes sense
+From PYTHON Host to Everyone: 06:26 PM
+Does anyone have a Windows computer?
+From Kyle Creek to Everyone: 06:26 PM
+I have a windows computer
+From PYTHON Host to Everyone: 06:27 PM
+My understanding is that you were able to install Mongo, Kyle…
+From Kyle Creek to Everyone: 06:27 PM
+I believe so
+From PYTHON Host to Everyone: 06:27 PM
+:)
+From Kyle Creek to Everyone: 06:27 PM
+I ran the file given in the "activity" foler and it worked
+From danielcastro to Everyone: 06:29 PM
+You can run this script to test it
+https://canvas.uw.edu/courses/1260484/files/56075781?module_item_id=9450736
+Yes we can see it
+From Kyle Creek to Everyone: 06:32 PM
+what is the significance of host and port? is that like an IP addres?
+From Kyle Creek to Everyone: 06:42 PM
+Its gets confusing
+From PYTHON Host to Everyone: 06:42 PM
+Yes.
+And what else?
+From danielcastro to Everyone: 06:42 PM
+The length of all of them might not match?
+From Kyle Creek to Everyone: 06:42 PM
+Uses a lot of memory?
+From Lola Guerrero to Everyone: 06:42 PM
+it might never finish
+From Aaron Devey to Everyone: 06:42 PM
+big O gets really out of hand
+From PYTHON Host to Everyone: 06:43 PM
+Or at least not within reasonable time...
+Say we need to browse through 1,000,000 records in one for loop, 1,000 in the second, 1,000 in the thitd,
+From Aaron Devey to Everyone: 06:43 PM
+exponential loops
+From PYTHON Host to Everyone: 06:45 PM
+And 1,000 in the fourth for loop.
+The number of records retrieved does grow exponentially with number of fors.
+Indexes
+From Kyle Creek to Everyone: 06:47 PM
+is there similiar documentation for mongo
+like there is for the database stuff we used last week?
+From Aaron Devey to Everyone: 06:50 PM
+there should be some docs for pymongo
+http://api.mongodb.com/python/current/tutorial.html
+From Kyle Creek to Everyone: 06:51 PM
+I think I might have misunderstood the structure. So if you would be so kind please correct me if I'm wrong. MongoDB is just the location that houses the data. The code that is written utilizes the Pymongo module to obtain and manipulate that housed data
+From Aaron Devey to Everyone: 06:52 PM
+MongoDB is actually a server or daemon
+From PYTHON Host to Everyone: 06:52 PM
+I think you are both right.
+From Kyle Creek to Everyone: 06:53 PM
+what is a daemon
+I don't have much of a CS background so I'm trying to wrap my head around some of these conceptfs
+From Aaron Devey to Everyone: 06:53 PM
+there are other kinds of servers or daemons that you might already be familiar with, such as web servers
+From PYTHON Host to Everyone: 06:53 PM
+The point is: in real World, you would not connect to a local application, you would connect to a server, with a specified IP address. Through Python, you’d be able to insert and manipulate (query, delete, update) data.
+From Aaron Devey to Everyone: 06:54 PM
+when you go to a website for example, you're connecting to a web server
+daemon is just another word for a server
+From PYTHON Host to Everyone: 06:54 PM
+The beauty of data base approach: while you are connecting to it, it I can also connect, and this is precisely when you are on FB. When you type a status, it goes to a FB database, when I am commenting on your status, it goes there, too, but from my client (browser).
+From Kyle Creek to Everyone: 06:54 PM
+got it. Thank you.
+From PYTHON Host to Everyone: 06:57 PM
+Deamon is an application running on a server; server is typically a machine, deamon is a software.
+Do you see my screen with (pdb) prompt?
+From Kyle Creek to Everyone: 07:00 PM
+yes
+where do you define the initial databse media
+or does calling it initialize it
+From Kyle Creek to Everyone: 07:22 PM
+why do you have to assign the insert function to the "result" variable
+From Kyle Creek to Everyone: 07:41 PM
+I'm ready whenever
+From rlarge to Everyone: 07:41 PM
+ready
+From Lola Guerrero to Everyone: 07:41 PM
+mee too
+From Sam Chang to Everyone: 07:41 PM
+ready to go
diff --git a/students/template_student/lesson06/activity/README.md b/students/Justin_Jameson/lesson06/activity/README.md
similarity index 100%
rename from students/template_student/lesson06/activity/README.md
rename to students/Justin_Jameson/lesson06/activity/README.md
diff --git a/students/template_student/lesson06/assignment/data/exercise.csv b/students/Justin_Jameson/lesson06/assignment/data/exercise.csv
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson06/assignment/data/exercise.csv
rename to students/Justin_Jameson/lesson06/assignment/data/exercise.csv
diff --git a/students/template_student/lesson06/assignment/pylintrc b/students/Justin_Jameson/lesson06/assignment/pylintrc
similarity index 100%
rename from students/template_student/lesson06/assignment/pylintrc
rename to students/Justin_Jameson/lesson06/assignment/pylintrc
diff --git a/students/template_student/lesson06/assignment/src/good_perf.py b/students/Justin_Jameson/lesson06/assignment/src/good_perf.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson06/assignment/src/good_perf.py
rename to students/Justin_Jameson/lesson06/assignment/src/good_perf.py
diff --git a/students/template_student/lesson06/assignment/src/poor_perf.py b/students/Justin_Jameson/lesson06/assignment/src/poor_perf.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson06/assignment/src/poor_perf.py
rename to students/Justin_Jameson/lesson06/assignment/src/poor_perf.py
diff --git a/students/template_student/lesson06/assignment/tests/test_good_perf.py b/students/Justin_Jameson/lesson06/assignment/tests/test_good_perf.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson06/assignment/tests/test_good_perf.py
rename to students/Justin_Jameson/lesson06/assignment/tests/test_good_perf.py
diff --git a/students/template_student/lesson06/assignment/tests/test_perf.py b/students/Justin_Jameson/lesson06/assignment/tests/test_perf.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson06/assignment/tests/test_perf.py
rename to students/Justin_Jameson/lesson06/assignment/tests/test_perf.py
diff --git a/students/template_student/lesson07/activity/README.md b/students/Justin_Jameson/lesson07/activity/README.md
similarity index 100%
rename from students/template_student/lesson07/activity/README.md
rename to students/Justin_Jameson/lesson07/activity/README.md
diff --git a/students/template_student/lesson07/assignment/data/customer.csv b/students/Justin_Jameson/lesson07/assignment/data/customer.csv
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson07/assignment/data/customer.csv
rename to students/Justin_Jameson/lesson07/assignment/data/customer.csv
diff --git a/students/template_student/lesson07/assignment/data/product.csv b/students/Justin_Jameson/lesson07/assignment/data/product.csv
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson07/assignment/data/product.csv
rename to students/Justin_Jameson/lesson07/assignment/data/product.csv
diff --git a/students/template_student/lesson07/assignment/data/rental.csv b/students/Justin_Jameson/lesson07/assignment/data/rental.csv
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson07/assignment/data/rental.csv
rename to students/Justin_Jameson/lesson07/assignment/data/rental.csv
diff --git a/students/template_student/lesson07/assignment/pylintrc b/students/Justin_Jameson/lesson07/assignment/pylintrc
similarity index 100%
rename from students/template_student/lesson07/assignment/pylintrc
rename to students/Justin_Jameson/lesson07/assignment/pylintrc
diff --git a/students/template_student/lesson07/assignment/tests/test_gradel07.py b/students/Justin_Jameson/lesson07/assignment/tests/test_gradel07.py
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson07/assignment/tests/test_gradel07.py
rename to students/Justin_Jameson/lesson07/assignment/tests/test_gradel07.py
diff --git a/students/Justin_Jameson/lesson08/Justin_Jameson_lesson08.zip b/students/Justin_Jameson/lesson08/Justin_Jameson_lesson08.zip
new file mode 100644
index 0000000..3d46296
Binary files /dev/null and b/students/Justin_Jameson/lesson08/Justin_Jameson_lesson08.zip differ
diff --git a/students/template_student/lesson10/activity/README.md b/students/Justin_Jameson/lesson08/activity/README.md
similarity index 92%
rename from students/template_student/lesson10/activity/README.md
rename to students/Justin_Jameson/lesson08/activity/README.md
index 48cdce8..5e05e74 100644
--- a/students/template_student/lesson10/activity/README.md
+++ b/students/Justin_Jameson/lesson08/activity/README.md
@@ -1 +1 @@
-placeholder
+placeholder
diff --git a/students/Justin_Jameson/lesson08/assignment/data/rented_items.csv b/students/Justin_Jameson/lesson08/assignment/data/rented_items.csv
new file mode 100644
index 0000000..9f588d2
--- /dev/null
+++ b/students/Justin_Jameson/lesson08/assignment/data/rented_items.csv
@@ -0,0 +1,11 @@
+
+Elisa Miles,LR04,Leather Sofa,25
+Edward Data,KT78,Kitchen Table,10
+Alex Gonzales,QM83,Queen Mattress,17
+Elisa Miles,LR04,Leather Sofa,25
+Edward Data,KT78,Kitchen Table,10
+Alex Gonzales,QM83,Queen Mattress,17
+Susan Wong,LR01,Small lamp,7.5
+Susan Wong,LR02,Television,28
+Susan Wong,BR07,LED lamp,5.5
+Susan Wong,KT08,Basic refrigerator,40
diff --git a/students/Justin_Jameson/lesson08/assignment/data/test_invoice_file - Copy.csv b/students/Justin_Jameson/lesson08/assignment/data/test_invoice_file - Copy.csv
new file mode 100644
index 0000000..f2ddaa6
--- /dev/null
+++ b/students/Justin_Jameson/lesson08/assignment/data/test_invoice_file - Copy.csv
@@ -0,0 +1,6 @@
+customer_name,item_code,item_description,item_monthly_price
+Elisa Miles,LR04,Leather Sofa,25
+Edward Data,KT78,Kitchen Table,10
+Gonzales,BR02,Queen Mattress,17
+Edward Data,KT78,Kitchen Table,10
+Gonzales,BR02,Queen Mattress,17
diff --git a/students/Justin_Jameson/lesson08/assignment/data/test_invoice_file.csv b/students/Justin_Jameson/lesson08/assignment/data/test_invoice_file.csv
new file mode 100644
index 0000000..d45675c
--- /dev/null
+++ b/students/Justin_Jameson/lesson08/assignment/data/test_invoice_file.csv
@@ -0,0 +1,10 @@
+customer_name,item_code,item_description,item_monthly_price
+Elisa Miles,LR04,Leather Sofa,25
+Edward Data,KT78,Kitchen Table,10
+Gonzales,BR02,Queen Mattress,17
+Edward Data,KT78,Kitchen Table,10
+Gonzales,BR02,Queen Mattress,17
+Susan,LR01,Small lamp,7.5
+Susan,LR02,Television,28
+Susan,BR07,LED lamp,5.5
+Susan,KT08,Basic refrigerator,40
diff --git a/students/Justin_Jameson/lesson08/assignment/data/test_items - Copy.csv b/students/Justin_Jameson/lesson08/assignment/data/test_items - Copy.csv
new file mode 100644
index 0000000..f0ac872
--- /dev/null
+++ b/students/Justin_Jameson/lesson08/assignment/data/test_items - Copy.csv
@@ -0,0 +1,4 @@
+LR01,Small lamp,7.5
+LR02,Television,28
+BR07,LED lamp,5.5
+KT08,Basic refrigerator,40
diff --git a/students/Justin_Jameson/lesson08/assignment/data/test_items.csv b/students/Justin_Jameson/lesson08/assignment/data/test_items.csv
new file mode 100644
index 0000000..f0ac872
--- /dev/null
+++ b/students/Justin_Jameson/lesson08/assignment/data/test_items.csv
@@ -0,0 +1,4 @@
+LR01,Small lamp,7.5
+LR02,Television,28
+BR07,LED lamp,5.5
+KT08,Basic refrigerator,40
diff --git a/students/template_student/lesson09/assignment/pylintrc b/students/Justin_Jameson/lesson08/assignment/pylintrc
similarity index 96%
rename from students/template_student/lesson09/assignment/pylintrc
rename to students/Justin_Jameson/lesson08/assignment/pylintrc
index 0d96a23..c6cccdb 100644
--- a/students/template_student/lesson09/assignment/pylintrc
+++ b/students/Justin_Jameson/lesson08/assignment/pylintrc
@@ -1,236 +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=80
-
-# 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
+[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=80
+
+# 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/Justin_Jameson/lesson08/assignment/src/Justin_Jameson_with_Partial_inventory.zip b/students/Justin_Jameson/lesson08/assignment/src/Justin_Jameson_with_Partial_inventory.zip
new file mode 100644
index 0000000..d0c4cb7
Binary files /dev/null and b/students/Justin_Jameson/lesson08/assignment/src/Justin_Jameson_with_Partial_inventory.zip differ
diff --git a/students/Justin_Jameson/lesson08/assignment/src/Testing.py b/students/Justin_Jameson/lesson08/assignment/src/Testing.py
new file mode 100644
index 0000000..a455e99
--- /dev/null
+++ b/students/Justin_Jameson/lesson08/assignment/src/Testing.py
@@ -0,0 +1,19 @@
+import csv
+
+
+def single_customer(customer_name, invoice_file):
+ # open csv file and read lines.
+ with open(invoice_file, 'r', newline='') as rcsvfile:
+ reader = csv.reader(rcsvfile, delimiter=',', quotechar='"')
+ for row in reader:
+ # write to the invoice to file.
+ def simple_intro(item_code, item_description, item_monthly_price):
+ with open('../data/test_invoice_file.csv', 'a', newline='') as wcsvfile:
+ writer = csv.writer(wcsvfile, delimiter=',', quotechar='"')
+ new_row = [customer_name, item_code, item_description, item_monthly_price]
+ writer.writerow(new_row)
+ return print(new_row)
+ simple_intro(row[0], row[1], row[2])
+
+
+single_customer('Susan', '../data/test_items.csv')
diff --git a/students/Justin_Jameson/lesson08/assignment/src/inventory.py b/students/Justin_Jameson/lesson08/assignment/src/inventory.py
new file mode 100644
index 0000000..47733f1
--- /dev/null
+++ b/students/Justin_Jameson/lesson08/assignment/src/inventory.py
@@ -0,0 +1,76 @@
+# **************************
+# Title: inventory.py
+# Desc:
+# 1. Create a python module called inventory.py, to replace the existing spreadsheet.
+# 2. Create a function called add_furniture that takes the following input parameters:
+# invoice_file
+# customer_name
+# item_code
+# item_description
+# item_monthly_price
+# This function will create invoice_file (to replace the spreadsheet’s data)
+# if it doesnt exist, or append a new line to it if it does exist.
+#
+# 3. Create a function called single_customer:
+# Input parameters: customer_name, invoice_file.
+# Output: Returns a function that takes one parameter, rental_items.
+# single_customer needs to use functools.partial and closures, in order to return a function
+# that will iterate through rental_items and add each item to invoice_file.
+#
+# should write a try catch block to identify if items are not included such as if item no has more than len(4) error.
+#
+# Change Log: (Who, When, What)
+# Justin Jameson, 20190525, created file
+#
+# **************************
+
+import csv
+from functools import partial
+
+
+existing_invoice_file = '../data/rented_items.csv'
+
+
+def add_furniture(invoice_file=existing_invoice_file, customer_name='Name',
+ item_code='Item', item_description='Description', item_monthly_price='Price'):
+ """
+ This function creates invoice_file if it does not exist, or appends a new line to it if it does exist.
+ :param invoice_file: The name of the csv file(s) that will be added to the master (single_customer) invoice.
+ :param customer_name: The name of the Customer who rented the furniture.
+ :param item_code: The coding identifier for the rented furniture.
+ :param item_description: A short description of the furniture.
+ :param item_monthly_price: The amount rental amount for the furniture.
+ :return:
+ """
+ with open(invoice_file, 'a', newline='') as csvfile:
+ writer = csv.writer(csvfile, delimiter=',', quotechar='"')
+ new_row = [customer_name, item_code, item_description, item_monthly_price]
+ writer.writerow(new_row)
+
+
+def single_customer(customer_name, invoice_file):
+ """
+ This function imports a csv file, reads the rows, then writes the row to the invoice csv file.
+ :param customer_name: A single customer with multiple rentals.
+ :param invoice_file: File that the invoice will write to (database).
+ :return:
+ """
+ with open(invoice_file, 'r', newline='') as rcsvfile:
+ reader = csv.reader(rcsvfile, delimiter=',', quotechar='"')
+ for row in reader:
+ mult_entry_single_customer = partial(add_furniture, existing_invoice_file, customer_name)
+ mult_entry_single_customer(row[0], row[1], row[2])
+
+
+if __name__ == "__main__":
+ add_furniture("../data/rented_items.csv", "Elisa Miles", "LR04", "Leather Sofa", 25)
+ add_furniture("../data/rented_items.csv", "Edward Data", "KT78", "Kitchen Table", 10)
+ add_furniture("../data/rented_items.csv", "Alex Gonzales", "QM83", "Queen Mattress", 17)
+ single_customer("Susan Wong", "../data/test_items.csv")
+
+
+
+
+ # my_single_customer("XYAJ", "TABLE", 22)
+
+# https://www.learnpython.org/en/Partial_functions
diff --git a/students/Justin_Jameson/lesson08/assignment/src/moreTesting.py b/students/Justin_Jameson/lesson08/assignment/src/moreTesting.py
new file mode 100644
index 0000000..62c7599
--- /dev/null
+++ b/students/Justin_Jameson/lesson08/assignment/src/moreTesting.py
@@ -0,0 +1,46 @@
+from functools import partial
+import csv
+
+existing_invoice_file = '../data/rented_items.csv'
+
+def add_furniture(invoice_file='existing_invoice_file', customer_name='Name',
+ item_code='Item', item_description='Description', item_monthly_price='Price'):
+ print(invoice_file, customer_name, item_code,item_description, item_monthly_price)
+
+
+def single_customer(customer_name, invoice_file):
+ with open(invoice_file, 'r', newline='') as rcsvfile:
+ reader = csv.reader(rcsvfile, delimiter=',', quotechar='"')
+ for row in reader:
+ mult_entry_single_customer = partial(add_furniture, existing_invoice_file, customer_name)
+ # mult_entry_single_customer('lro4', 'leather sofa', 25)
+ mult_entry_single_customer(row[0], row[1], row[2])
+
+
+add_furniture("../data/rented_items.csv", "Elisa Miles", "LR04", "Leather Sofa", 25)
+add_furniture("../data/rented_items.csv", "Edward Data", "KT78", "Kitchen Table", 10)
+add_furniture("../data/rented_items.csv", "Alex Gonzales", "QM83", "Queen Mattress", 17)
+single_customer("Susan Wong", "../data/test_items.csv")
+
+# mult_entry_single_customer = single_customer("Susan Wong", "../data/test_items.csv")
+# mult_entry_single_customer('lro4', 'leather sofa', 25)
+
+
+# ***************************************************************
+# # mult_entry_single_customer = partial(add_furniture, customer_name, invoice_file)
+# # open csv file and read lines.
+# with open(invoice_file, 'r', newline='') as rcsvfile:
+# reader = csv.reader(rcsvfile, delimiter=',', quotechar='"')
+# for row in reader:
+# mult_entry_single_customer = partial(add_furniture, customer_name, existing_invoice_file)
+# mult_entry_single_customer(row[0], row[1], row[2])
+# print(row)
+# print(mult_entry_single_customer(row[0], row[1], row[2]))
+# # write to the invoice to file.
+# # def invoice_file(item_code, item_description, item_monthly_price):
+# # with open(existing_invoice_file, 'a', newline='') as wcsvfile:
+# # writer = csv.writer(wcsvfile, delimiter=',', quotechar='"')
+# # new_row = [customer_name, item_code, item_description, item_monthly_price]
+# # writer.writerow(new_row)
+# # return print(new_row)
+# # invoice_file(row[0], row[1], row[2])
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson08/assignment/src/tester.py b/students/Justin_Jameson/lesson08/assignment/src/tester.py
new file mode 100644
index 0000000..9919e3a
--- /dev/null
+++ b/students/Justin_Jameson/lesson08/assignment/src/tester.py
@@ -0,0 +1,6 @@
+from .inventory import add_furniture, single_customer
+add_furniture("rented_items.csv", "Elisa Miles", "LR04", "Leather Sofa", 25)
+add_furniture("rented_items.csv", "Edward Data", "KT78", "Kitchen Table", 10)
+add_furniture("rented_items.csv", "Alex Gonzales", "Queen Mattress", 17)
+# create_invoice = single_customer("Susan Wong", "rented_items.csv")
+# create_invoice("test_items.csv")
diff --git a/students/template_student/lesson08/assignment/tests/test_inventory.py b/students/Justin_Jameson/lesson08/assignment/tests/test_inventory.py
old mode 100755
new mode 100644
similarity index 93%
rename from students/template_student/lesson08/assignment/tests/test_inventory.py
rename to students/Justin_Jameson/lesson08/assignment/tests/test_inventory.py
index cb1d05e..2bd3a0d
--- a/students/template_student/lesson08/assignment/tests/test_inventory.py
+++ b/students/Justin_Jameson/lesson08/assignment/tests/test_inventory.py
@@ -1,19 +1,19 @@
-"""
- Autograde Lesson 8 assignment
-
-"""
-
-import pytest
-
-import inventory as l
-
-
-
-def test_add_furniture(invoice_file, customer_name, item_code, item_description, item_monthly_price):
-
-
-
-def single_customer(customer_name, invoice_file):
-
-
+"""
+ Autograde Lesson 8 assignment
+
+"""
+
+import pytest
+
+import inventory as l
+
+
+
+def test_add_furniture(invoice_file, customer_name, item_code, item_description, item_monthly_price):
+
+
+
+def single_customer(customer_name, invoice_file):
+
+
\ No newline at end of file
diff --git a/students/template_student/lesson09/activity/locke_manager.py b/students/Justin_Jameson/lesson09/activity/locke_manager.py
similarity index 93%
rename from students/template_student/lesson09/activity/locke_manager.py
rename to students/Justin_Jameson/lesson09/activity/locke_manager.py
index ce8b925..7f844a0 100644
--- a/students/template_student/lesson09/activity/locke_manager.py
+++ b/students/Justin_Jameson/lesson09/activity/locke_manager.py
@@ -1,3 +1,3 @@
-class Locke:
-
-if __name__ == '__main__':
+class Locke:
+
+if __name__ == '__main__':
diff --git a/students/template_student/lesson09/assignment/data/furniture/chair/couch/sofa_400_clr_10056.png b/students/Justin_Jameson/lesson09/assignment/data/furniture/chair/couch/sofa_400_clr_10056.png
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson09/assignment/data/furniture/chair/couch/sofa_400_clr_10056.png
rename to students/Justin_Jameson/lesson09/assignment/data/furniture/chair/couch/sofa_400_clr_10056.png
diff --git a/students/template_student/lesson09/assignment/data/furniture/chair/metal_chair_back_isometric_400_clr_17527.png b/students/Justin_Jameson/lesson09/assignment/data/furniture/chair/metal_chair_back_isometric_400_clr_17527.png
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson09/assignment/data/furniture/chair/metal_chair_back_isometric_400_clr_17527.png
rename to students/Justin_Jameson/lesson09/assignment/data/furniture/chair/metal_chair_back_isometric_400_clr_17527.png
diff --git a/students/template_student/lesson09/assignment/data/furniture/table/basic_desk_main_400_clr_17523.png b/students/Justin_Jameson/lesson09/assignment/data/furniture/table/basic_desk_main_400_clr_17523.png
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson09/assignment/data/furniture/table/basic_desk_main_400_clr_17523.png
rename to students/Justin_Jameson/lesson09/assignment/data/furniture/table/basic_desk_main_400_clr_17523.png
diff --git a/students/template_student/lesson09/assignment/data/furniture/table/desk_isometric_back_400_clr_17524.png b/students/Justin_Jameson/lesson09/assignment/data/furniture/table/desk_isometric_back_400_clr_17524.png
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson09/assignment/data/furniture/table/desk_isometric_back_400_clr_17524.png
rename to students/Justin_Jameson/lesson09/assignment/data/furniture/table/desk_isometric_back_400_clr_17524.png
diff --git a/students/template_student/lesson09/assignment/data/furniture/table/table_with_cloth_400_clr_10664.png b/students/Justin_Jameson/lesson09/assignment/data/furniture/table/table_with_cloth_400_clr_10664.png
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson09/assignment/data/furniture/table/table_with_cloth_400_clr_10664.png
rename to students/Justin_Jameson/lesson09/assignment/data/furniture/table/table_with_cloth_400_clr_10664.png
diff --git a/students/Justin_Jameson/lesson09/assignment/data/list_of_files.bat b/students/Justin_Jameson/lesson09/assignment/data/list_of_files.bat
new file mode 100644
index 0000000..068a3f4
--- /dev/null
+++ b/students/Justin_Jameson/lesson09/assignment/data/list_of_files.bat
@@ -0,0 +1 @@
+dir /b /s > List_of_jpg.txt
diff --git a/students/template_student/lesson09/assignment/data/new/chairs_balancing_stacked_400_clr_11525.png b/students/Justin_Jameson/lesson09/assignment/data/new/chairs_balancing_stacked_400_clr_11525.png
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson09/assignment/data/new/chairs_balancing_stacked_400_clr_11525.png
rename to students/Justin_Jameson/lesson09/assignment/data/new/chairs_balancing_stacked_400_clr_11525.png
diff --git a/students/template_student/lesson09/assignment/data/new/hotel_room_400_clr_12721.png b/students/Justin_Jameson/lesson09/assignment/data/new/hotel_room_400_clr_12721.png
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson09/assignment/data/new/hotel_room_400_clr_12721.png
rename to students/Justin_Jameson/lesson09/assignment/data/new/hotel_room_400_clr_12721.png
diff --git a/students/template_student/lesson09/assignment/data/old/couple_on_swing_bench_400_clr_12844.png b/students/Justin_Jameson/lesson09/assignment/data/old/couple_on_swing_bench_400_clr_12844.png
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson09/assignment/data/old/couple_on_swing_bench_400_clr_12844.png
rename to students/Justin_Jameson/lesson09/assignment/data/old/couple_on_swing_bench_400_clr_12844.png
diff --git a/students/template_student/lesson09/assignment/data/old/sitting_in_chair_relaxing_400_clr_6028.png b/students/Justin_Jameson/lesson09/assignment/data/old/sitting_in_chair_relaxing_400_clr_6028.png
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson09/assignment/data/old/sitting_in_chair_relaxing_400_clr_6028.png
rename to students/Justin_Jameson/lesson09/assignment/data/old/sitting_in_chair_relaxing_400_clr_6028.png
diff --git a/students/template_student/lesson10/assignment/pylintrc b/students/Justin_Jameson/lesson09/assignment/pylintrc
similarity index 96%
rename from students/template_student/lesson10/assignment/pylintrc
rename to students/Justin_Jameson/lesson09/assignment/pylintrc
index 0d96a23..c6cccdb 100644
--- a/students/template_student/lesson10/assignment/pylintrc
+++ b/students/Justin_Jameson/lesson09/assignment/pylintrc
@@ -1,236 +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=80
-
-# 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
+[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=80
+
+# 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/Justin_Jameson/lesson09/assignment/src/charges_calc.log b/students/Justin_Jameson/lesson09/assignment/src/charges_calc.log
new file mode 100644
index 0000000..dc69b21
--- /dev/null
+++ b/students/Justin_Jameson/lesson09/assignment/src/charges_calc.log
@@ -0,0 +1,13 @@
+DEBUG:root:called parse_cmd
+2019-06-02 22:26:57,016 charges_calc.py:32 DEBUG called parse_cmd
+DEBUG:root:about to return parser.parse_arg
+2019-06-02 22:26:57,017 charges_calc.py:36 DEBUG about to return parser.parse_arg
+2019-06-02 23:44:54,409 charges_calc.py:41 DEBUG Calling parse_cmd_arguments()
+2019-06-02 23:47:18,404 charges_calc.py:41 DEBUG Calling parse_cmd_arguments()
+2019-06-02 23:47:18,406 charges_calc.py:43 INFO 'parse_cmd_arguments' returned Namespace(input=None, output=None)
+2019-06-02 23:47:18,406 charges_calc.py:41 DEBUG Calling load_rentals_file(None)
+2019-06-03 12:53:00,170 charges_calc.py:41 DEBUG Calling parse_cmd_arguments()
+2019-06-03 12:53:00,173 charges_calc.py:43 INFO 'parse_cmd_arguments' returned Namespace(input=None, output=None)
+2019-06-03 12:53:00,174 charges_calc.py:41 DEBUG Calling load_rentals_file(None)
+2019-06-03 12:53:25,520 charges_calc.py:41 DEBUG Calling parse_cmd_arguments()
+2019-06-05 19:50:00,530 charges_calc.py:41 DEBUG Calling parse_cmd_arguments()
diff --git a/students/Justin_Jameson/lesson09/assignment/src/charges_calc.py b/students/Justin_Jameson/lesson09/assignment/src/charges_calc.py
new file mode 100644
index 0000000..fcd95e7
--- /dev/null
+++ b/students/Justin_Jameson/lesson09/assignment/src/charges_calc.py
@@ -0,0 +1,100 @@
+# -------------------------------------------------#
+# # Title: charges calculator for Inventory management.
+# # Dev: unknown
+# # Date: 4/17/2019
+# # ChangeLog: (Who, What)
+# Justin Jameson
+# correct ouput to output line 20 'ouptu JSON file'
+# in source.json removed extra comma on line 5884 from
+# 'units_rented': 7,,
+# imported logger
+# 20190602 updating file to use decorators to induce logging.
+# #-------------------------------------------------#
+
+""" Returns total price paid for individual rentals """
+
+import argparse
+import json
+import datetime
+import math
+import logging
+import functools
+
+logging.basicConfig(filename='charges_calc_updated.log', level=logging.DEBUG)
+log_format = "%(asctime)s %(filename)s:%(lineno)-3d %(levelname)s %(message)s"
+formatter = logging.Formatter(log_format)
+file_handler = logging.FileHandler('charges_calc.log')
+file_handler.setFormatter(formatter)
+logger = logging.getLogger()
+logger.addHandler(file_handler)
+do_debug = input('Debug? Y/N: ')
+
+
+def debug(func):
+ """Print the function signature and return value"""
+ if do_debug.lower() == 'y':
+ @functools.wraps(func)
+ def wrapper_debug(*args, **kwargs):
+ args_repr = [repr(a) for a in args]
+ kwargs_repr = [f"{k}={v!r}" for k, v in kwargs.items()]
+ signature = ", ".join(args_repr + kwargs_repr)
+ logging.debug(f"Calling {func.__name__}({signature})")
+ value = func(*args, **kwargs)
+ logging.info(f"{func.__name__!r} returned {value!r}")
+ return value
+ return wrapper_debug
+ else:
+ @functools.wraps(func)
+ def debug_disabled(*args, **kwargs):
+ # print("Debug has been disabled")
+ returned_value = func(*args, **kwargs)
+ return returned_value
+ return debug_disabled
+
+
+@debug
+def parse_cmd_arguments():
+ parser = argparse.ArgumentParser(description='Process some integers.')
+ parser.add_argument('-i', '--input', help='input JSON file', required=True)
+ parser.add_argument('-o', '--output', help='output JSON file', required=True)
+ return parser.parse_args()
+
+
+@debug
+def load_rentals_file(filename):
+ with open(filename) as file:
+ try:
+ data = json.load(file)
+ except:
+ logging.warning('load_rentals_files threw an exception')
+ exit(0)
+ return data
+
+
+@debug
+def calculate_additional_fields(data):
+ for value in data.values():
+ try:
+ rental_start = datetime.datetime.strptime(value['rental_start'], '%m/%d/%y')
+ rental_end = datetime.datetime.strptime(value['rental_end'], '%m/%d/%y')
+ value['total_days'] = (rental_end - rental_start).days
+ value['total_price'] = value['total_days'] * value['price_per_day']
+ value['sqrt_total_price'] = math.sqrt(value['total_price'])
+ value['unit_cost'] = value['total_price'] / value['units_rented']
+ except:
+ logging.warning('except block of calculate_add... this will exit the program without')
+ exit(0)
+ return data
+
+
+@debug
+def save_to_json(filename, data):
+ with open(filename, 'w') as file:
+ json.dump(data, file)
+
+
+if __name__ == "__main__":
+ args = parse_cmd_arguments()
+ data = load_rentals_file(args.input)
+ data = calculate_additional_fields(data)
+ save_to_json(args.output, data)
diff --git a/students/Justin_Jameson/lesson09/assignment/src/charges_calc_updated.log b/students/Justin_Jameson/lesson09/assignment/src/charges_calc_updated.log
new file mode 100644
index 0000000..231c4c6
--- /dev/null
+++ b/students/Justin_Jameson/lesson09/assignment/src/charges_calc_updated.log
@@ -0,0 +1,9 @@
+DEBUG:root:Calling parse_cmd_arguments()
+DEBUG:root:Calling parse_cmd_arguments()
+INFO:root:'parse_cmd_arguments' returned Namespace(input=None, output=None)
+DEBUG:root:Calling load_rentals_file(None)
+DEBUG:root:Calling parse_cmd_arguments()
+INFO:root:'parse_cmd_arguments' returned Namespace(input=None, output=None)
+DEBUG:root:Calling load_rentals_file(None)
+DEBUG:root:Calling parse_cmd_arguments()
+DEBUG:root:Calling parse_cmd_arguments()
diff --git a/students/Justin_Jameson/lesson09/assignment/src/database.py b/students/Justin_Jameson/lesson09/assignment/src/database.py
new file mode 100644
index 0000000..61a80bb
--- /dev/null
+++ b/students/Justin_Jameson/lesson09/assignment/src/database.py
@@ -0,0 +1,235 @@
+# -------------------------------------------------#
+# # Title: Lesson 09 database.py
+# # Dev: Justin Jameson
+# # Date: 5/18/2019
+# # ChangeLog: (Who, when, What)
+# # adding ideas for mongo context manager.
+# -------------------------------------------------#
+from pymongo import MongoClient
+import sys
+import csv
+import logging
+
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+# ************************************** Defining variables *************************************
+directory_name = '..\\.\\data\\'
+product_data = 'product.csv'
+customer_data = 'customers.csv'
+rentals_data = 'rental.csv'
+logger.info('defined directory name and the following .csv files: product_data, customer_data, and rental_data')
+
+
+# ******************************************** Defining Classes *********************************
+class MongoDBConnection:
+ """
+ MongoDB Connection
+ """
+
+ def __init__(self, host='127.0.0.1', port=27017):
+ """ be sure to use the ip address not name for local windows"""
+ self.host = host
+ self.port = port
+ self.connection = None
+ logger.info('created connection to host {} and port {}'.format(self.host, self.port))
+ # maybe add an option to offer client log in?
+
+ def __enter__(self):
+ self.connection = MongoClient(self.host, self.port)
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self.connection.close()
+
+
+class ReadCsvFiles:
+ """
+ This class calls 'import_data' method to access the csv files.
+ Then reads the csv files, and turns them into a list of dictionaries.
+ Then sends the list to the 'main' method for incorporation into MongoDB.
+ This class also uses the self items for calls in other methods.
+
+ :return:
+ """
+ def __init__(self, list_of_customers=[], list_of_products=[], list_of_rentals=[]):
+ self.list_of_customers = list_of_customers
+ self.list_of_products = list_of_products
+ self.list_of_rentals = list_of_rentals
+
+ logger.info('created empty lists')
+ imported_data = import_data(directory_name, product_data, customer_data, rentals_data)
+ customers_file = imported_data[0]
+ products_file = imported_data[1]
+ rentals_file = imported_data[2]
+
+ with open(customers_file, 'r') as customer:
+ reader = csv.reader(customer)
+ for row in reader:
+ c_dict = {'User ID': row[0], 'Name': row[1], 'Address': row[2],
+ 'zip code': row[3], 'phone number': row[4], 'email': row[5]}
+ list_of_customers.append(c_dict)
+ list_of_customers.pop(0)
+ with open(products_file, 'r') as product:
+ reader = csv.reader(product)
+ for row in reader:
+ p_dict = {'Product ID': row[0], 'Description': row[1], 'Product Type': row[2], 'Quantity available': row[3]}
+ list_of_products.append(p_dict)
+ list_of_products.pop(0)
+ with open(rentals_file, 'r') as rentals:
+ reader = csv.reader(rentals)
+ for row in reader:
+ r_dict = {'Product ID': row[0], 'User ID': row[1]}
+ list_of_rentals.append(r_dict)
+ list_of_rentals.pop(0)
+ logger.info('appended all lists with content from csv files')
+ return
+
+
+# ************************************* user interface *************************************
+def main_menu(user_prompt=None):
+ """
+ This method creates the menu for the program.
+ """
+ valid_prompts = {"1": ReadCsvFiles,
+ "2": show_available_products,
+ "3": show_rentals,
+ "4": reset_db,
+ "q": exit_program}
+ options = list(valid_prompts.keys())
+
+ while user_prompt not in valid_prompts:
+ options_str = ("{}" + ", {}" * (len(options) - 1)).format(*options)
+ print(f"Please choose from the following options ({options_str}):")
+ print("1. Load csv files to database.")
+ print("2. Show Customer products available for rent")
+ print("3. Show Sales Person the list of customers")
+ print("4. Reset the DataBase")
+ print("q. Quit")
+ user_prompt = input(">")
+ return valid_prompts.get(user_prompt)
+
+
+# ************************************* Processing *****************************************
+def db_info():
+ """
+ This method returns the use of the class 'ReadCsvFiles'.
+ :return:
+ """
+ return ReadCsvFiles()
+
+
+def import_data(directory_location, product_file, customer_file, rental_file):
+ """
+ This function takes a directory name and three csv files as input,
+ then creates a directory and file name for use in 'ReadCsvFiles' method.
+ 1. product data = product.csv
+ 2. customer data = customers.csv
+ 3. rentals data = rental.csv
+ :param directory_location:
+ :param product_file:
+ :param customer_file:
+ :param rental_file:
+ :return:import_customer, import_product, import_rentals
+ """
+ import_customer = directory_location + customer_file
+ import_product = directory_location + product_file
+ import_rentals = directory_location + rental_file
+ logger.info('returning tuple for use in method "ReadCsvFiles"')
+ return import_customer, import_product, import_rentals
+
+
+def main(list_of_customers, list_of_products, list_of_rentals):
+ """
+ Return: 2 tuples:
+ 1. a record count of the number of products, customers and rentals
+ added (in that order)
+ 2. a count of any errors that occurred, in the same order.
+ :param list_of_customers:
+ :param list_of_products:
+ :param list_of_rentals:
+ :return:
+ """
+ mongo = MongoDBConnection()
+
+ with mongo: # Context manager.
+ # mongodb database; create rentaldatabase
+ db = mongo.connection.rentaldatabase
+
+ # collection (table) in database, (3) customers, products and rental status (rental)
+ customers = db["customers"]
+ products = db["products"]
+ rental = db["rental"]
+ result_customer = customers.insert_many(list_of_customers) # Inserts records specified in the list above
+ result_products = products.insert_many(list_of_products)
+ result_rentals = rental.insert_many(list_of_rentals)
+ # print_mdb_collection(customers) # Prints all records from a specified table
+ # print_mdb_collection(products)
+ # print_mdb_collection(rental)
+ return result_customer, result_products, result_rentals
+
+
+def reset_db():
+ """
+ deletes db
+ :return:
+ """
+ mongo = MongoDBConnection()
+
+ with mongo: # Context manager.
+ db = mongo.connection.rentaldatabase
+ # start afresh next time?
+ drop_data = input("Drop data?")
+ if drop_data.upper() == 'Y':
+ db['customers'].drop()
+ db["products"].drop()
+ db["rental"].drop()
+ logger.info('dropped data from DB')
+
+
+# ****************************************** output to the user *************************************
+def show_available_products():
+ """
+ As a HP Norton customer I want to see a list of all products available for rent so that I can make a rental choice.
+ You can have a specific field to indicate if a product is available, however,
+ a quantity_available of 0 is understood as “not available”.
+ Returns a Python dictionary of products listed as available with the following fields:
+ product_id.
+ description.
+ product_type.
+ quantity_available.
+ :return:
+ """
+
+ for dlop in return_db_info.list_of_products:
+ if dlop['Quantity available'] != '0':
+ print(dlop)
+
+
+def show_rentals():
+ """
+ Returns a Python dictionary with the following user information from users that have rented products
+ matching product_id:
+ user_id.
+ name.
+ address.
+ phone_number.
+ email.
+ """
+ for doc in return_db_info.list_of_customers:
+ logger.info('producing a list of products, customers, and rentals.')
+ print(doc)
+
+
+# ***************************************** execution ***********************************************
+def exit_program():
+ """This method exits the program"""
+ logger.info('called exit_program')
+ sys.exit()
+
+
+if __name__ == "__main__":
+ return_db_info = db_info()
+ while True:
+ main_menu()()
+ input("Press Enter to continue...........")
diff --git a/students/Justin_Jameson/lesson09/assignment/src/example.log b/students/Justin_Jameson/lesson09/assignment/src/example.log
new file mode 100644
index 0000000..3a92009
--- /dev/null
+++ b/students/Justin_Jameson/lesson09/assignment/src/example.log
@@ -0,0 +1,8 @@
+DEBUG:root:This message should go to the log file
+INFO:root:So should this
+WARNING:root:And this, too
+DEBUG:root:This message should go to the log file
+INFO:root:So should this
+WARNING:root:And this, too
+DEBUG:root:Calling some_function()
+INFO:root:'some_function' returned 'Just a funciton'
diff --git a/students/Justin_Jameson/lesson09/assignment/src/jpgdiscover.py b/students/Justin_Jameson/lesson09/assignment/src/jpgdiscover.py
new file mode 100644
index 0000000..f96ef55
--- /dev/null
+++ b/students/Justin_Jameson/lesson09/assignment/src/jpgdiscover.py
@@ -0,0 +1,42 @@
+# **************************
+# Title: jpgdiscover.py
+# Desc:
+# 1. Discovers all directories on the server?
+# 2. Searches the Parent directory and all subdirectories for jpg files.
+# 3. Works from a parent directory called images provided on the command line.
+# a. The program will take the parent directory as input.
+# b. As output, it will return a list of lists structured like this:
+# [“full/working_directory/to/files”, [“file1.jpg”, “file2.jpg”,…], “another/working_directory”,[], etc]
+#
+# Change Log: (Who, When, What)
+# Justin Jameson, 20190602, created file
+# Justin Jameson,
+# **************************#
+
+
+import os
+
+# collect current directory and move back one folder.
+working_directory = os.path.dirname('../')
+
+
+def list_jpg_files(path):
+ """
+ utilizing os.walk to recurse through the directory and find jpg files. However, only png files have been provided.
+ :param path: defines directory to start the search.
+ :return: a list of directories and file names.
+ """
+ files = []
+ # r=root, d=directories, f = files
+ for r, d, f in os.walk(path):
+ for file in f:
+ # direction sate find jpg files. However, no jpg files exist so I found png files instead.
+ if '.png' in file:
+ entry = []
+ entry.append(os.path.join(r, file))
+ files.append(entry)
+ return files
+
+
+print(list_jpg_files(working_directory))
+
diff --git a/students/Justin_Jameson/lesson09/assignment/src/source.json b/students/Justin_Jameson/lesson09/assignment/src/source.json
new file mode 100644
index 0000000..c4e90b1
--- /dev/null
+++ b/students/Justin_Jameson/lesson09/assignment/src/source.json
@@ -0,0 +1,6995 @@
+{
+ "RNT001": {
+ "product_code": "PRD80",
+ "units_rented": 8,
+ "price_per_day": 31,
+ "rental_start": "6/12/17",
+ "rental_end": "3/22/17"
+ },
+ "RNT002": {
+ "product_code": "PRD11",
+ "units_rented": 1,
+ "price_per_day": 16,
+ "rental_start": "7/20/16",
+ "rental_end": "9/30/18"
+ },
+ "RNT003": {
+ "product_code": "PRD22",
+ "units_rented": 4,
+ "price_per_day": 40,
+ "rental_start": "2/1/16",
+ "rental_end": "6/4/17"
+ },
+ "RNT004": {
+ "product_code": "PRD86",
+ "units_rented": 6,
+ "price_per_day": 40,
+ "rental_start": "8/14/16",
+ "rental_end": "12/7/17"
+ },
+ "RNT005": {
+ "product_code": "PRD70",
+ "units_rented": 8,
+ "price_per_day": 7,
+ "rental_start": "7/12/17",
+ "rental_end": "11/23/18"
+ },
+ "RNT006": {
+ "product_code": "PRD51",
+ "units_rented": 8,
+ "price_per_day": 20,
+ "rental_start": "8/26/18",
+ "rental_end": "7/29/18"
+ },
+ "RNT007": {
+ "product_code": "PRD42",
+ "units_rented": 1,
+ "price_per_day": 16,
+ "rental_start": "7/10/17",
+ "rental_end": "5/31/17"
+ },
+ "RNT008": {
+ "product_code": "PRD32",
+ "units_rented": 3,
+ "price_per_day": 12,
+ "rental_start": "10/25/18",
+ "rental_end": "7/4/18"
+ },
+ "RNT009": {
+ "product_code": "PRD13",
+ "units_rented": 9,
+ "price_per_day": 6,
+ "rental_start": "11/3/18",
+ "rental_end": "7/28/16"
+ },
+ "RNT010": {
+ "product_code": "PRD22",
+ "units_rented": 6,
+ "price_per_day": 27,
+ "rental_start": "3/15/18",
+ "rental_end": "8/27/17"
+ },
+ "RNT011": {
+ "product_code": "PRD17",
+ "units_rented": 7,
+ "price_per_day": 26,
+ "rental_start": "9/29/17",
+ "rental_end": "4/29/16"
+ },
+ "RNT012": {
+ "product_code": "PRD55",
+ "units_rented": 4,
+ "price_per_day": 18,
+ "rental_start": "10/24/17",
+ "rental_end": "1/15/16"
+ },
+ "RNT013": {
+ "product_code": "PRD81",
+ "units_rented": 10,
+ "price_per_day": 10,
+ "rental_start": "2/3/17",
+ "rental_end": "8/31/17"
+ },
+ "RNT014": {
+ "product_code": "PRD0",
+ "units_rented": 7,
+ "price_per_day": 37,
+ "rental_start": "1/30/17",
+ "rental_end": "7/30/16"
+ },
+ "RNT015": {
+ "product_code": "PRD82",
+ "units_rented": 10,
+ "price_per_day": 29,
+ "rental_start": "5/2/17",
+ "rental_end": "6/22/18"
+ },
+ "RNT016": {
+ "product_code": "PRD52",
+ "units_rented": 10,
+ "price_per_day": 11,
+ "rental_start": "6/18/18",
+ "rental_end": "2/5/16"
+ },
+ "RNT017": {
+ "product_code": "PRD5",
+ "units_rented": 10,
+ "price_per_day": 36,
+ "rental_start": "4/28/18",
+ "rental_end": "4/11/18"
+ },
+ "RNT018": {
+ "product_code": "PRD59",
+ "units_rented": 9,
+ "price_per_day": 40,
+ "rental_start": "8/16/16",
+ "rental_end": "1/13/16"
+ },
+ "RNT019": {
+ "product_code": "PRD6",
+ "units_rented": 8,
+ "price_per_day": 39,
+ "rental_start": "12/16/17",
+ "rental_end": "5/10/16"
+ },
+ "RNT020": {
+ "product_code": "PRD2",
+ "units_rented": 9,
+ "price_per_day": 33,
+ "rental_start": "6/20/18",
+ "rental_end": "1/12/16"
+ },
+ "RNT021": {
+ "product_code": "PRD97",
+ "units_rented": 3,
+ "price_per_day": 33,
+ "rental_start": "8/31/17",
+ "rental_end": "2/9/16"
+ },
+ "RNT022": {
+ "product_code": "PRD66",
+ "units_rented": 9,
+ "price_per_day": 14,
+ "rental_start": "10/3/16",
+ "rental_end": "11/1/17"
+ },
+ "RNT023": {
+ "product_code": "PRD14",
+ "units_rented": 9,
+ "price_per_day": 20,
+ "rental_start": "9/13/16",
+ "rental_end": "11/16/18"
+ },
+ "RNT024": {
+ "product_code": "PRD78",
+ "units_rented": 3,
+ "price_per_day": 20,
+ "rental_start": "7/14/17",
+ "rental_end": "11/25/18"
+ },
+ "RNT025": {
+ "product_code": "PRD28",
+ "units_rented": 5,
+ "price_per_day": 26,
+ "rental_start": "3/2/18",
+ "rental_end": "5/28/16"
+ },
+ "RNT026": {
+ "product_code": "PRD40",
+ "units_rented": 6,
+ "price_per_day": 24,
+ "rental_start": "3/27/18",
+ "rental_end": "4/21/16"
+ },
+ "RNT027": {
+ "product_code": "PRD11",
+ "units_rented": 2,
+ "price_per_day": 27,
+ "rental_start": "3/28/16",
+ "rental_end": "8/3/16"
+ },
+ "RNT028": {
+ "product_code": "PRD63",
+ "units_rented": 10,
+ "price_per_day": 17,
+ "rental_start": "7/6/18",
+ "rental_end": "5/6/17"
+ },
+ "RNT029": {
+ "product_code": "PRD77",
+ "units_rented": 5,
+ "price_per_day": 10,
+ "rental_start": "9/5/16",
+ "rental_end": "5/3/18"
+ },
+ "RNT030": {
+ "product_code": "PRD43",
+ "units_rented": 4,
+ "price_per_day": 31,
+ "rental_start": "7/1/17",
+ "rental_end": "4/18/17"
+ },
+ "RNT031": {
+ "product_code": "PRD51",
+ "units_rented": 10,
+ "price_per_day": 27,
+ "rental_start": "4/18/18",
+ "rental_end": "4/13/17"
+ },
+ "RNT032": {
+ "product_code": "PRD97",
+ "units_rented": 9,
+ "price_per_day": 34,
+ "rental_start": "7/2/16",
+ "rental_end": "7/18/16"
+ },
+ "RNT033": {
+ "product_code": "PRD0",
+ "units_rented": 6,
+ "price_per_day": 8,
+ "rental_start": "2/5/17",
+ "rental_end": "3/28/17"
+ },
+ "RNT034": {
+ "product_code": "PRD72",
+ "units_rented": 9,
+ "price_per_day": 36,
+ "rental_start": "10/11/17",
+ "rental_end": "4/3/16"
+ },
+ "RNT035": {
+ "product_code": "PRD19",
+ "units_rented": 7,
+ "price_per_day": 20,
+ "rental_start": "9/15/16",
+ "rental_end": "11/4/17"
+ },
+ "RNT036": {
+ "product_code": "PRD94",
+ "units_rented": 2,
+ "price_per_day": 14,
+ "rental_start": "10/16/17",
+ "rental_end": "1/9/18"
+ },
+ "RNT037": {
+ "product_code": "PRD6",
+ "units_rented": 8,
+ "price_per_day": 7,
+ "rental_start": "3/20/18",
+ "rental_end": "9/13/18"
+ },
+ "RNT038": {
+ "product_code": "PRD5",
+ "units_rented": 4,
+ "price_per_day": 18,
+ "rental_start": "2/16/17",
+ "rental_end": "6/24/17"
+ },
+ "RNT039": {
+ "product_code": "PRD61",
+ "units_rented": 1,
+ "price_per_day": 17,
+ "rental_start": "7/24/16",
+ "rental_end": "7/24/16"
+ },
+ "RNT040": {
+ "product_code": "PRD51",
+ "units_rented": 1,
+ "price_per_day": 23,
+ "rental_start": "12/1/17",
+ "rental_end": "12/30/16"
+ },
+ "RNT041": {
+ "product_code": "PRD59",
+ "units_rented": 4,
+ "price_per_day": 14,
+ "rental_start": "2/19/18",
+ "rental_end": "3/30/17"
+ },
+ "RNT042": {
+ "product_code": "PRD18",
+ "units_rented": 10,
+ "price_per_day": 11,
+ "rental_start": "7/27/17",
+ "rental_end": "10/19/17"
+ },
+ "RNT043": {
+ "product_code": "PRD68",
+ "units_rented": 2,
+ "price_per_day": 27,
+ "rental_start": "4/9/17",
+ "rental_end": "7/5/18"
+ },
+ "RNT044": {
+ "product_code": "PRD43",
+ "units_rented": 1,
+ "price_per_day": 15,
+ "rental_start": "9/4/18",
+ "rental_end": "12/19/16"
+ },
+ "RNT045": {
+ "product_code": "PRD62",
+ "units_rented": 3,
+ "price_per_day": 33,
+ "rental_start": "12/19/18",
+ "rental_end": "11/12/18"
+ },
+ "RNT046": {
+ "product_code": "PRD46",
+ "units_rented": 5,
+ "price_per_day": 34,
+ "rental_start": "10/15/18",
+ "rental_end": "1/8/18"
+ },
+ "RNT047": {
+ "product_code": "PRD52",
+ "units_rented": 2,
+ "price_per_day": 12,
+ "rental_start": "8/3/18",
+ "rental_end": "6/24/16"
+ },
+ "RNT048": {
+ "product_code": "PRD32",
+ "units_rented": 5,
+ "price_per_day": 36,
+ "rental_start": "9/5/17",
+ "rental_end": "10/28/16"
+ },
+ "RNT049": {
+ "product_code": "PRD77",
+ "units_rented": 4,
+ "price_per_day": 14,
+ "rental_start": "1/9/18",
+ "rental_end": "3/14/18"
+ },
+ "RNT050": {
+ "product_code": "PRD6",
+ "units_rented": 8,
+ "price_per_day": 34,
+ "rental_start": "12/6/18",
+ "rental_end": "6/30/17"
+ },
+ "RNT051": {
+ "product_code": "PRD45",
+ "units_rented": 6,
+ "price_per_day": 33,
+ "rental_start": "2/18/16",
+ "rental_end": "7/19/17"
+ },
+ "RNT052": {
+ "product_code": "PRD53",
+ "units_rented": 7,
+ "price_per_day": 9,
+ "rental_start": "10/30/16",
+ "rental_end": "3/13/17"
+ },
+ "RNT053": {
+ "product_code": "PRD17",
+ "units_rented": 7,
+ "price_per_day": 10,
+ "rental_start": "12/12/16",
+ "rental_end": "9/20/17"
+ },
+ "RNT054": {
+ "product_code": "PRD62",
+ "units_rented": 1,
+ "price_per_day": 6,
+ "rental_start": "12/31/16",
+ "rental_end": "12/21/17"
+ },
+ "RNT055": {
+ "product_code": "PRD16",
+ "units_rented": 6,
+ "price_per_day": 33,
+ "rental_start": "2/4/18",
+ "rental_end": "9/14/18"
+ },
+ "RNT056": {
+ "product_code": "PRD43",
+ "units_rented": 9,
+ "price_per_day": 40,
+ "rental_start": "4/12/18",
+ "rental_end": "2/27/16"
+ },
+ "RNT057": {
+ "product_code": "PRD58",
+ "units_rented": 4,
+ "price_per_day": 23,
+ "rental_start": "9/23/17",
+ "rental_end": "9/17/18"
+ },
+ "RNT058": {
+ "product_code": "PRD35",
+ "units_rented": 8,
+ "price_per_day": 28,
+ "rental_start": "7/14/17",
+ "rental_end": "1/25/17"
+ },
+ "RNT059": {
+ "product_code": "PRD9",
+ "units_rented": 8,
+ "price_per_day": 7,
+ "rental_start": "3/26/16",
+ "rental_end": "10/11/16"
+ },
+ "RNT060": {
+ "product_code": "PRD84",
+ "units_rented": 8,
+ "price_per_day": 29,
+ "rental_start": "2/15/16",
+ "rental_end": "1/18/16"
+ },
+ "RNT061": {
+ "product_code": "PRD35",
+ "units_rented": 8,
+ "price_per_day": 24,
+ "rental_start": "2/12/18",
+ "rental_end": "2/28/17"
+ },
+ "RNT062": {
+ "product_code": "PRD29",
+ "units_rented": 3,
+ "price_per_day": 12,
+ "rental_start": "8/25/18",
+ "rental_end": "6/3/18"
+ },
+ "RNT063": {
+ "product_code": "PRD47",
+ "units_rented": 4,
+ "price_per_day": 35,
+ "rental_start": "1/11/17",
+ "rental_end": "5/18/18"
+ },
+ "RNT064": {
+ "product_code": "PRD83",
+ "units_rented": 3,
+ "price_per_day": 23,
+ "rental_start": "2/24/17",
+ "rental_end": "6/28/17"
+ },
+ "RNT065": {
+ "product_code": "PRD61",
+ "units_rented": 1,
+ "price_per_day": 11,
+ "rental_start": "10/11/18",
+ "rental_end": "12/12/16"
+ },
+ "RNT066": {
+ "product_code": "PRD74",
+ "units_rented": 10,
+ "price_per_day": 39,
+ "rental_start": "2/28/16",
+ "rental_end": "11/12/17"
+ },
+ "RNT067": {
+ "product_code": "PRD29",
+ "units_rented": 5,
+ "price_per_day": 31,
+ "rental_start": "1/18/18",
+ "rental_end": "10/18/17"
+ },
+ "RNT068": {
+ "product_code": "PRD71",
+ "units_rented": 5,
+ "price_per_day": 38,
+ "rental_start": "3/28/16",
+ "rental_end": "5/20/16"
+ },
+ "RNT069": {
+ "product_code": "PRD38",
+ "units_rented": 9,
+ "price_per_day": 27,
+ "rental_start": "10/21/16",
+ "rental_end": "2/17/17"
+ },
+ "RNT070": {
+ "product_code": "PRD82",
+ "units_rented": 3,
+ "price_per_day": 13,
+ "rental_start": "10/24/17",
+ "rental_end": "10/21/18"
+ },
+ "RNT071": {
+ "product_code": "PRD38",
+ "units_rented": 9,
+ "price_per_day": 6,
+ "rental_start": "10/5/16",
+ "rental_end": "5/25/16"
+ },
+ "RNT072": {
+ "product_code": "PRD53",
+ "units_rented": 8,
+ "price_per_day": 32,
+ "rental_start": "10/6/16",
+ "rental_end": "6/19/18"
+ },
+ "RNT073": {
+ "product_code": "PRD37",
+ "units_rented": 3,
+ "price_per_day": 23,
+ "rental_start": "4/3/18",
+ "rental_end": "9/8/18"
+ },
+ "RNT074": {
+ "product_code": "PRD33",
+ "units_rented": 9,
+ "price_per_day": 22,
+ "rental_start": "9/9/17",
+ "rental_end": "7/14/17"
+ },
+ "RNT075": {
+ "product_code": "PRD2",
+ "units_rented": 8,
+ "price_per_day": 25,
+ "rental_start": "4/25/16",
+ "rental_end": "11/13/18"
+ },
+ "RNT076": {
+ "product_code": "PRD64",
+ "units_rented": 4,
+ "price_per_day": 20,
+ "rental_start": "6/6/18",
+ "rental_end": "5/12/16"
+ },
+ "RNT077": {
+ "product_code": "PRD6",
+ "units_rented": 8,
+ "price_per_day": 14,
+ "rental_start": "8/15/18",
+ "rental_end": "11/19/16"
+ },
+ "RNT078": {
+ "product_code": "PRD72",
+ "units_rented": 9,
+ "price_per_day": 14,
+ "rental_start": "1/6/17",
+ "rental_end": "11/1/17"
+ },
+ "RNT079": {
+ "product_code": "PRD85",
+ "units_rented": 1,
+ "price_per_day": 21,
+ "rental_start": "11/27/18",
+ "rental_end": "1/27/18"
+ },
+ "RNT080": {
+ "product_code": "PRD8",
+ "units_rented": 10,
+ "price_per_day": 21,
+ "rental_start": "6/27/17",
+ "rental_end": "4/18/18"
+ },
+ "RNT081": {
+ "product_code": "PRD52",
+ "units_rented": 7,
+ "price_per_day": 17,
+ "rental_start": "2/8/18",
+ "rental_end": "12/9/18"
+ },
+ "RNT082": {
+ "product_code": "PRD2",
+ "units_rented": 2,
+ "price_per_day": 24,
+ "rental_start": "10/3/16",
+ "rental_end": "11/16/17"
+ },
+ "RNT083": {
+ "product_code": "PRD70",
+ "units_rented": 1,
+ "price_per_day": 17,
+ "rental_start": "9/9/17",
+ "rental_end": "2/6/18"
+ },
+ "RNT084": {
+ "product_code": "PRD75",
+ "units_rented": 6,
+ "price_per_day": 16,
+ "rental_start": "5/13/17",
+ "rental_end": "4/29/16"
+ },
+ "RNT085": {
+ "product_code": "PRD16",
+ "units_rented": 6,
+ "price_per_day": 21,
+ "rental_start": "2/21/18",
+ "rental_end": "3/20/18"
+ },
+ "RNT086": {
+ "product_code": "PRD87",
+ "units_rented": 6,
+ "price_per_day": 40,
+ "rental_start": "12/3/18",
+ "rental_end": "3/20/18"
+ },
+ "RNT087": {
+ "product_code": "PRD0",
+ "units_rented": 2,
+ "price_per_day": 37,
+ "rental_start": "8/10/16",
+ "rental_end": "6/18/16"
+ },
+ "RNT088": {
+ "product_code": "PRD84",
+ "units_rented": 9,
+ "price_per_day": 20,
+ "rental_start": "6/9/16",
+ "rental_end": "2/25/17"
+ },
+ "RNT089": {
+ "product_code": "PRD58",
+ "units_rented": 5,
+ "price_per_day": 20,
+ "rental_start": "11/5/18",
+ "rental_end": "8/15/18"
+ },
+ "RNT090": {
+ "product_code": "PRD18",
+ "units_rented": 10,
+ "price_per_day": 10,
+ "rental_start": "1/14/17",
+ "rental_end": "8/19/18"
+ },
+ "RNT091": {
+ "product_code": "PRD46",
+ "units_rented": 7,
+ "price_per_day": 5,
+ "rental_start": "6/27/17",
+ "rental_end": "10/25/17"
+ },
+ "RNT092": {
+ "product_code": "PRD6",
+ "units_rented": 10,
+ "price_per_day": 18,
+ "rental_start": "3/10/17",
+ "rental_end": "5/23/16"
+ },
+ "RNT093": {
+ "product_code": "PRD64",
+ "units_rented": 2,
+ "price_per_day": 33,
+ "rental_start": "4/2/16",
+ "rental_end": "11/19/18"
+ },
+ "RNT094": {
+ "product_code": "PRD28",
+ "units_rented": 3,
+ "price_per_day": 19,
+ "rental_start": "8/22/16",
+ "rental_end": "8/24/16"
+ },
+ "RNT095": {
+ "product_code": "PRD83",
+ "units_rented": 6,
+ "price_per_day": 6,
+ "rental_start": "8/5/18",
+ "rental_end": "7/23/17"
+ },
+ "RNT096": {
+ "product_code": "PRD97",
+ "units_rented": 1,
+ "price_per_day": 12,
+ "rental_start": "2/6/16",
+ "rental_end": "7/9/16"
+ },
+ "RNT097": {
+ "product_code": "PRD36",
+ "units_rented": 7,
+ "price_per_day": 29,
+ "rental_start": "1/11/17",
+ "rental_end": "8/29/16"
+ },
+ "RNT098": {
+ "product_code": "PRD5",
+ "units_rented": 7,
+ "price_per_day": 19,
+ "rental_start": "1/28/17",
+ "rental_end": "2/11/18"
+ },
+ "RNT099": {
+ "product_code": "PRD42",
+ "units_rented": 1,
+ "price_per_day": 18,
+ "rental_start": "11/23/18",
+ "rental_end": "10/21/16"
+ },
+ "RNT100": {
+ "product_code": "PRD66",
+ "units_rented": 6,
+ "price_per_day": 10,
+ "rental_start": "6/16/18",
+ "rental_end": "5/21/16"
+ },
+ "RNT101": {
+ "product_code": "PRD42",
+ "units_rented": 9,
+ "price_per_day": 9,
+ "rental_start": "12/3/18",
+ "rental_end": "9/20/17"
+ },
+ "RNT102": {
+ "product_code": "PRD68",
+ "units_rented": 7,
+ "price_per_day": 34,
+ "rental_start": "7/17/17",
+ "rental_end": "12/8/16"
+ },
+ "RNT103": {
+ "product_code": "PRD76",
+ "units_rented": 6,
+ "price_per_day": 20,
+ "rental_start": "1/24/17",
+ "rental_end": "2/18/16"
+ },
+ "RNT104": {
+ "product_code": "PRD98",
+ "units_rented": 1,
+ "price_per_day": 31,
+ "rental_start": "12/20/17",
+ "rental_end": "8/30/16"
+ },
+ "RNT105": {
+ "product_code": "PRD3",
+ "units_rented": 4,
+ "price_per_day": 32,
+ "rental_start": "12/29/17",
+ "rental_end": "2/20/16"
+ },
+ "RNT106": {
+ "product_code": "PRD80",
+ "units_rented": 7,
+ "price_per_day": 35,
+ "rental_start": "3/14/18",
+ "rental_end": "1/1/18"
+ },
+ "RNT107": {
+ "product_code": "PRD84",
+ "units_rented": 3,
+ "price_per_day": 11,
+ "rental_start": "5/30/17",
+ "rental_end": "6/4/16"
+ },
+ "RNT108": {
+ "product_code": "PRD44",
+ "units_rented": 1,
+ "price_per_day": 26,
+ "rental_start": "6/5/16",
+ "rental_end": "3/15/17"
+ },
+ "RNT109": {
+ "product_code": "PRD88",
+ "units_rented": 2,
+ "price_per_day": 30,
+ "rental_start": "6/26/18",
+ "rental_end": "1/9/17"
+ },
+ "RNT110": {
+ "product_code": "PRD42",
+ "units_rented": 2,
+ "price_per_day": 33,
+ "rental_start": "10/25/16",
+ "rental_end": "7/14/18"
+ },
+ "RNT111": {
+ "product_code": "PRD10",
+ "units_rented": 7,
+ "price_per_day": 5,
+ "rental_start": "9/4/16",
+ "rental_end": "11/10/17"
+ },
+ "RNT112": {
+ "product_code": "PRD99",
+ "units_rented": 10,
+ "price_per_day": 20,
+ "rental_start": "7/11/16",
+ "rental_end": "9/1/16"
+ },
+ "RNT113": {
+ "product_code": "PRD65",
+ "units_rented": 2,
+ "price_per_day": 6,
+ "rental_start": "10/19/18",
+ "rental_end": "11/6/18"
+ },
+ "RNT114": {
+ "product_code": "PRD89",
+ "units_rented": 10,
+ "price_per_day": 14,
+ "rental_start": "6/6/17",
+ "rental_end": "1/9/16"
+ },
+ "RNT115": {
+ "product_code": "PRD22",
+ "units_rented": 2,
+ "price_per_day": 8,
+ "rental_start": "5/11/18",
+ "rental_end": "2/3/16"
+ },
+ "RNT116": {
+ "product_code": "PRD74",
+ "units_rented": 1,
+ "price_per_day": 8,
+ "rental_start": "4/14/17",
+ "rental_end": "8/4/16"
+ },
+ "RNT117": {
+ "product_code": "PRD11",
+ "units_rented": 9,
+ "price_per_day": 29,
+ "rental_start": "6/12/18",
+ "rental_end": "12/23/18"
+ },
+ "RNT118": {
+ "product_code": "PRD11",
+ "units_rented": 10,
+ "price_per_day": 23,
+ "rental_start": "7/23/18",
+ "rental_end": "6/4/17"
+ },
+ "RNT119": {
+ "product_code": "PRD58",
+ "units_rented": 10,
+ "price_per_day": 28,
+ "rental_start": "7/19/18",
+ "rental_end": "12/18/17"
+ },
+ "RNT120": {
+ "product_code": "PRD83",
+ "units_rented": 8,
+ "price_per_day": 6,
+ "rental_start": "1/3/17",
+ "rental_end": "8/1/16"
+ },
+ "RNT121": {
+ "product_code": "PRD39",
+ "units_rented": 2,
+ "price_per_day": 11,
+ "rental_start": "11/30/18",
+ "rental_end": "2/25/17"
+ },
+ "RNT122": {
+ "product_code": "PRD9",
+ "units_rented": 5,
+ "price_per_day": 16,
+ "rental_start": "12/4/18",
+ "rental_end": "4/5/17"
+ },
+ "RNT123": {
+ "product_code": "PRD83",
+ "units_rented": 7,
+ "price_per_day": 13,
+ "rental_start": "3/2/18",
+ "rental_end": "7/25/17"
+ },
+ "RNT124": {
+ "product_code": "PRD42",
+ "units_rented": 2,
+ "price_per_day": 11,
+ "rental_start": "11/3/16",
+ "rental_end": "3/10/17"
+ },
+ "RNT125": {
+ "product_code": "PRD76",
+ "units_rented": 10,
+ "price_per_day": 27,
+ "rental_start": "12/15/18",
+ "rental_end": "7/30/18"
+ },
+ "RNT126": {
+ "product_code": "PRD8",
+ "units_rented": 7,
+ "price_per_day": 10,
+ "rental_start": "1/10/16",
+ "rental_end": "7/7/17"
+ },
+ "RNT127": {
+ "product_code": "PRD95",
+ "units_rented": 10,
+ "price_per_day": 39,
+ "rental_start": "4/8/16",
+ "rental_end": "8/25/18"
+ },
+ "RNT128": {
+ "product_code": "PRD59",
+ "units_rented": 10,
+ "price_per_day": 29,
+ "rental_start": "4/8/17",
+ "rental_end": "12/7/17"
+ },
+ "RNT129": {
+ "product_code": "PRD75",
+ "units_rented": 10,
+ "price_per_day": 6,
+ "rental_start": "3/23/18",
+ "rental_end": "5/23/17"
+ },
+ "RNT130": {
+ "product_code": "PRD23",
+ "units_rented": 8,
+ "price_per_day": 5,
+ "rental_start": "12/17/18",
+ "rental_end": "6/21/17"
+ },
+ "RNT131": {
+ "product_code": "PRD74",
+ "units_rented": 3,
+ "price_per_day": 18,
+ "rental_start": "1/15/16",
+ "rental_end": "5/31/16"
+ },
+ "RNT132": {
+ "product_code": "PRD23",
+ "units_rented": 6,
+ "price_per_day": 32,
+ "rental_start": "3/17/16",
+ "rental_end": "2/20/17"
+ },
+ "RNT133": {
+ "product_code": "PRD0",
+ "units_rented": 8,
+ "price_per_day": 19,
+ "rental_start": "2/14/17",
+ "rental_end": "9/24/18"
+ },
+ "RNT134": {
+ "product_code": "PRD64",
+ "units_rented": 1,
+ "price_per_day": 37,
+ "rental_start": "1/23/18",
+ "rental_end": "9/7/18"
+ },
+ "RNT135": {
+ "product_code": "PRD79",
+ "units_rented": 3,
+ "price_per_day": 11,
+ "rental_start": "10/13/16",
+ "rental_end": "8/11/16"
+ },
+ "RNT136": {
+ "product_code": "PRD79",
+ "units_rented": 1,
+ "price_per_day": 5,
+ "rental_start": "6/10/17",
+ "rental_end": "10/15/17"
+ },
+ "RNT137": {
+ "product_code": "PRD74",
+ "units_rented": 1,
+ "price_per_day": 5,
+ "rental_start": "11/6/16",
+ "rental_end": "9/11/17"
+ },
+ "RNT138": {
+ "product_code": "PRD23",
+ "units_rented": 10,
+ "price_per_day": 22,
+ "rental_start": "1/4/18",
+ "rental_end": "12/22/18"
+ },
+ "RNT139": {
+ "product_code": "PRD13",
+ "units_rented": 2,
+ "price_per_day": 23,
+ "rental_start": "9/13/17",
+ "rental_end": "5/1/17"
+ },
+ "RNT140": {
+ "product_code": "PRD70",
+ "units_rented": 7,
+ "price_per_day": 7,
+ "rental_start": "12/14/16",
+ "rental_end": "2/26/17"
+ },
+ "RNT141": {
+ "product_code": "PRD63",
+ "units_rented": 3,
+ "price_per_day": 21,
+ "rental_start": "1/20/18",
+ "rental_end": "3/22/17"
+ },
+ "RNT142": {
+ "product_code": "PRD66",
+ "units_rented": 9,
+ "price_per_day": 16,
+ "rental_start": "11/15/16",
+ "rental_end": "5/2/16"
+ },
+ "RNT143": {
+ "product_code": "PRD38",
+ "units_rented": 8,
+ "price_per_day": 39,
+ "rental_start": "11/20/18",
+ "rental_end": "1/3/16"
+ },
+ "RNT144": {
+ "product_code": "PRD51",
+ "units_rented": 7,
+ "price_per_day": 35,
+ "rental_start": "5/18/16",
+ "rental_end": "5/29/18"
+ },
+ "RNT145": {
+ "product_code": "PRD31",
+ "units_rented": 7,
+ "price_per_day": 31,
+ "rental_start": "7/28/18",
+ "rental_end": "7/15/16"
+ },
+ "RNT146": {
+ "product_code": "PRD56",
+ "units_rented": 8,
+ "price_per_day": 38,
+ "rental_start": "5/8/16",
+ "rental_end": "9/17/17"
+ },
+ "RNT147": {
+ "product_code": "PRD94",
+ "units_rented": 3,
+ "price_per_day": 11,
+ "rental_start": "4/8/17",
+ "rental_end": "10/10/17"
+ },
+ "RNT148": {
+ "product_code": "PRD33",
+ "units_rented": 6,
+ "price_per_day": 13,
+ "rental_start": "10/20/18",
+ "rental_end": "9/17/18"
+ },
+ "RNT149": {
+ "product_code": "PRD34",
+ "units_rented": 8,
+ "price_per_day": 20,
+ "rental_start": "9/29/18",
+ "rental_end": "11/3/16"
+ },
+ "RNT150": {
+ "product_code": "PRD88",
+ "units_rented": 6,
+ "price_per_day": 8,
+ "rental_start": "2/3/16",
+ "rental_end": "7/14/17"
+ },
+ "RNT151": {
+ "product_code": "PRD93",
+ "units_rented": 7,
+ "price_per_day": 25,
+ "rental_start": "8/11/18",
+ "rental_end": "8/16/16"
+ },
+ "RNT152": {
+ "product_code": "PRD89",
+ "units_rented": 4,
+ "price_per_day": 36,
+ "rental_start": "12/24/17",
+ "rental_end": "12/24/17"
+ },
+ "RNT153": {
+ "product_code": "PRD12",
+ "units_rented": 9,
+ "price_per_day": 15,
+ "rental_start": "3/31/16",
+ "rental_end": "8/19/16"
+ },
+ "RNT154": {
+ "product_code": "PRD35",
+ "units_rented": 3,
+ "price_per_day": 16,
+ "rental_start": "5/24/17",
+ "rental_end": "3/30/16"
+ },
+ "RNT155": {
+ "product_code": "PRD30",
+ "units_rented": 9,
+ "price_per_day": 22,
+ "rental_start": "1/7/18",
+ "rental_end": "7/19/17"
+ },
+ "RNT156": {
+ "product_code": "PRD2",
+ "units_rented": 1,
+ "price_per_day": 5,
+ "rental_start": "5/8/16",
+ "rental_end": "5/12/17"
+ },
+ "RNT157": {
+ "product_code": "PRD72",
+ "units_rented": 7,
+ "price_per_day": 32,
+ "rental_start": "12/23/18",
+ "rental_end": "5/19/17"
+ },
+ "RNT158": {
+ "product_code": "PRD3",
+ "units_rented": 4,
+ "price_per_day": 12,
+ "rental_start": "7/10/18",
+ "rental_end": "3/6/16"
+ },
+ "RNT159": {
+ "product_code": "PRD51",
+ "units_rented": 10,
+ "price_per_day": 40,
+ "rental_start": "4/14/16",
+ "rental_end": "9/14/17"
+ },
+ "RNT160": {
+ "product_code": "PRD61",
+ "units_rented": 6,
+ "price_per_day": 12,
+ "rental_start": "5/18/18",
+ "rental_end": "3/14/18"
+ },
+ "RNT161": {
+ "product_code": "PRD13",
+ "units_rented": 5,
+ "price_per_day": 9,
+ "rental_start": "2/23/16",
+ "rental_end": "3/7/17"
+ },
+ "RNT162": {
+ "product_code": "PRD52",
+ "units_rented": 9,
+ "price_per_day": 37,
+ "rental_start": "2/27/16",
+ "rental_end": "11/17/16"
+ },
+ "RNT163": {
+ "product_code": "PRD43",
+ "units_rented": 8,
+ "price_per_day": 24,
+ "rental_start": "12/16/16",
+ "rental_end": "9/10/16"
+ },
+ "RNT164": {
+ "product_code": "PRD71",
+ "units_rented": 4,
+ "price_per_day": 21,
+ "rental_start": "4/24/18",
+ "rental_end": "8/7/17"
+ },
+ "RNT165": {
+ "product_code": "PRD33",
+ "units_rented": 7,
+ "price_per_day": 12,
+ "rental_start": "5/29/16",
+ "rental_end": "9/9/17"
+ },
+ "RNT166": {
+ "product_code": "PRD60",
+ "units_rented": 3,
+ "price_per_day": 37,
+ "rental_start": "4/14/18",
+ "rental_end": "2/15/16"
+ },
+ "RNT167": {
+ "product_code": "PRD34",
+ "units_rented": 4,
+ "price_per_day": 27,
+ "rental_start": "2/3/17",
+ "rental_end": "12/11/16"
+ },
+ "RNT168": {
+ "product_code": "PRD44",
+ "units_rented": 4,
+ "price_per_day": 39,
+ "rental_start": "10/15/16",
+ "rental_end": "5/25/16"
+ },
+ "RNT169": {
+ "product_code": "PRD0",
+ "units_rented": 4,
+ "price_per_day": 28,
+ "rental_start": "3/18/18",
+ "rental_end": "9/25/16"
+ },
+ "RNT170": {
+ "product_code": "PRD54",
+ "units_rented": 9,
+ "price_per_day": 15,
+ "rental_start": "9/16/18",
+ "rental_end": "1/11/17"
+ },
+ "RNT171": {
+ "product_code": "PRD89",
+ "units_rented": 3,
+ "price_per_day": 36,
+ "rental_start": "10/3/16",
+ "rental_end": "8/17/17"
+ },
+ "RNT172": {
+ "product_code": "PRD21",
+ "units_rented": 5,
+ "price_per_day": 15,
+ "rental_start": "3/29/18",
+ "rental_end": "4/24/18"
+ },
+ "RNT173": {
+ "product_code": "PRD31",
+ "units_rented": 2,
+ "price_per_day": 24,
+ "rental_start": "10/12/17",
+ "rental_end": "6/8/18"
+ },
+ "RNT174": {
+ "product_code": "PRD40",
+ "units_rented": 3,
+ "price_per_day": 22,
+ "rental_start": "2/5/16",
+ "rental_end": "2/15/17"
+ },
+ "RNT175": {
+ "product_code": "PRD48",
+ "units_rented": 9,
+ "price_per_day": 39,
+ "rental_start": "5/16/18",
+ "rental_end": "3/15/18"
+ },
+ "RNT176": {
+ "product_code": "PRD10",
+ "units_rented": 10,
+ "price_per_day": 12,
+ "rental_start": "2/25/17",
+ "rental_end": "5/18/17"
+ },
+ "RNT177": {
+ "product_code": "PRD27",
+ "units_rented": 5,
+ "price_per_day": 32,
+ "rental_start": "6/6/16",
+ "rental_end": "9/15/17"
+ },
+ "RNT178": {
+ "product_code": "PRD35",
+ "units_rented": 5,
+ "price_per_day": 40,
+ "rental_start": "8/1/18",
+ "rental_end": "4/7/18"
+ },
+ "RNT179": {
+ "product_code": "PRD16",
+ "units_rented": 8,
+ "price_per_day": 6,
+ "rental_start": "8/24/18",
+ "rental_end": "8/14/18"
+ },
+ "RNT180": {
+ "product_code": "PRD12",
+ "units_rented": 3,
+ "price_per_day": 27,
+ "rental_start": "12/29/18",
+ "rental_end": "9/8/16"
+ },
+ "RNT181": {
+ "product_code": "PRD90",
+ "units_rented": 10,
+ "price_per_day": 40,
+ "rental_start": "9/13/16",
+ "rental_end": "12/22/16"
+ },
+ "RNT182": {
+ "product_code": "PRD7",
+ "units_rented": 6,
+ "price_per_day": 23,
+ "rental_start": "2/8/18",
+ "rental_end": "9/21/18"
+ },
+ "RNT183": {
+ "product_code": "PRD10",
+ "units_rented": 5,
+ "price_per_day": 24,
+ "rental_start": "5/31/18",
+ "rental_end": "4/8/18"
+ },
+ "RNT184": {
+ "product_code": "PRD66",
+ "units_rented": 3,
+ "price_per_day": 5,
+ "rental_start": "3/12/18",
+ "rental_end": "9/28/16"
+ },
+ "RNT185": {
+ "product_code": "PRD39",
+ "units_rented": 4,
+ "price_per_day": 35,
+ "rental_start": "12/11/16",
+ "rental_end": "1/12/18"
+ },
+ "RNT186": {
+ "product_code": "PRD48",
+ "units_rented": 9,
+ "price_per_day": 39,
+ "rental_start": "12/23/17",
+ "rental_end": "2/20/18"
+ },
+ "RNT187": {
+ "product_code": "PRD12",
+ "units_rented": 10,
+ "price_per_day": 10,
+ "rental_start": "10/5/17",
+ "rental_end": "1/11/16"
+ },
+ "RNT188": {
+ "product_code": "PRD76",
+ "units_rented": 7,
+ "price_per_day": 14,
+ "rental_start": "3/20/17",
+ "rental_end": "10/1/18"
+ },
+ "RNT189": {
+ "product_code": "PRD54",
+ "units_rented": 8,
+ "price_per_day": 18,
+ "rental_start": "11/20/16",
+ "rental_end": "8/17/16"
+ },
+ "RNT190": {
+ "product_code": "PRD45",
+ "units_rented": 6,
+ "price_per_day": 5,
+ "rental_start": "1/29/17",
+ "rental_end": "10/11/17"
+ },
+ "RNT191": {
+ "product_code": "PRD69",
+ "units_rented": 7,
+ "price_per_day": 34,
+ "rental_start": "6/1/16",
+ "rental_end": "11/6/18"
+ },
+ "RNT192": {
+ "product_code": "PRD59",
+ "units_rented": 10,
+ "price_per_day": 31,
+ "rental_start": "5/10/17",
+ "rental_end": "4/30/17"
+ },
+ "RNT193": {
+ "product_code": "PRD50",
+ "units_rented": 6,
+ "price_per_day": 36,
+ "rental_start": "10/19/16",
+ "rental_end": "2/17/17"
+ },
+ "RNT194": {
+ "product_code": "PRD49",
+ "units_rented": 1,
+ "price_per_day": 35,
+ "rental_start": "8/14/17",
+ "rental_end": "2/22/18"
+ },
+ "RNT195": {
+ "product_code": "PRD93",
+ "units_rented": 2,
+ "price_per_day": 17,
+ "rental_start": "5/4/18",
+ "rental_end": "1/6/16"
+ },
+ "RNT196": {
+ "product_code": "PRD92",
+ "units_rented": 8,
+ "price_per_day": 19,
+ "rental_start": "10/28/18",
+ "rental_end": "5/4/16"
+ },
+ "RNT197": {
+ "product_code": "PRD69",
+ "units_rented": 4,
+ "price_per_day": 33,
+ "rental_start": "3/2/18",
+ "rental_end": "11/14/17"
+ },
+ "RNT198": {
+ "product_code": "PRD45",
+ "units_rented": 10,
+ "price_per_day": 20,
+ "rental_start": "6/1/16",
+ "rental_end": "12/6/17"
+ },
+ "RNT199": {
+ "product_code": "PRD95",
+ "units_rented": 7,
+ "price_per_day": 23,
+ "rental_start": "2/22/18",
+ "rental_end": "5/26/18"
+ },
+ "RNT200": {
+ "product_code": "PRD9",
+ "units_rented": 9,
+ "price_per_day": 39,
+ "rental_start": "8/6/18",
+ "rental_end": "8/30/18"
+ },
+ "RNT201": {
+ "product_code": "PRD14",
+ "units_rented": 1,
+ "price_per_day": 17,
+ "rental_start": "10/12/17",
+ "rental_end": "9/17/16"
+ },
+ "RNT202": {
+ "product_code": "PRD93",
+ "units_rented": 2,
+ "price_per_day": 34,
+ "rental_start": "11/4/18",
+ "rental_end": "2/7/16"
+ },
+ "RNT203": {
+ "product_code": "PRD85",
+ "units_rented": 4,
+ "price_per_day": 25,
+ "rental_start": "8/21/17",
+ "rental_end": "8/27/18"
+ },
+ "RNT204": {
+ "product_code": "PRD70",
+ "units_rented": 10,
+ "price_per_day": 26,
+ "rental_start": "4/15/17",
+ "rental_end": "4/3/18"
+ },
+ "RNT205": {
+ "product_code": "PRD46",
+ "units_rented": 1,
+ "price_per_day": 25,
+ "rental_start": "12/4/16",
+ "rental_end": "3/28/18"
+ },
+ "RNT206": {
+ "product_code": "PRD59",
+ "units_rented": 9,
+ "price_per_day": 12,
+ "rental_start": "2/16/18",
+ "rental_end": "2/19/18"
+ },
+ "RNT207": {
+ "product_code": "PRD21",
+ "units_rented": 7,
+ "price_per_day": 21,
+ "rental_start": "3/15/18",
+ "rental_end": "6/3/16"
+ },
+ "RNT208": {
+ "product_code": "PRD86",
+ "units_rented": 1,
+ "price_per_day": 16,
+ "rental_start": "2/24/16",
+ "rental_end": "2/18/16"
+ },
+ "RNT209": {
+ "product_code": "PRD95",
+ "units_rented": 4,
+ "price_per_day": 14,
+ "rental_start": "9/12/16",
+ "rental_end": "12/15/17"
+ },
+ "RNT210": {
+ "product_code": "PRD2",
+ "units_rented": 2,
+ "price_per_day": 6,
+ "rental_start": "7/5/17",
+ "rental_end": "1/2/17"
+ },
+ "RNT211": {
+ "product_code": "PRD89",
+ "units_rented": 7,
+ "price_per_day": 17,
+ "rental_start": "6/15/18",
+ "rental_end": "7/23/18"
+ },
+ "RNT212": {
+ "product_code": "PRD16",
+ "units_rented": 3,
+ "price_per_day": 27,
+ "rental_start": "9/3/16",
+ "rental_end": "9/26/16"
+ },
+ "RNT213": {
+ "product_code": "PRD44",
+ "units_rented": 10,
+ "price_per_day": 28,
+ "rental_start": "4/9/16",
+ "rental_end": "9/4/18"
+ },
+ "RNT214": {
+ "product_code": "PRD6",
+ "units_rented": 6,
+ "price_per_day": 26,
+ "rental_start": "12/4/16",
+ "rental_end": "6/29/16"
+ },
+ "RNT215": {
+ "product_code": "PRD36",
+ "units_rented": 9,
+ "price_per_day": 19,
+ "rental_start": "4/25/16",
+ "rental_end": "8/3/17"
+ },
+ "RNT216": {
+ "product_code": "PRD6",
+ "units_rented": 2,
+ "price_per_day": 16,
+ "rental_start": "4/20/16",
+ "rental_end": "2/10/16"
+ },
+ "RNT217": {
+ "product_code": "PRD11",
+ "units_rented": 3,
+ "price_per_day": 5,
+ "rental_start": "8/18/18",
+ "rental_end": "8/4/16"
+ },
+ "RNT218": {
+ "product_code": "PRD20",
+ "units_rented": 8,
+ "price_per_day": 40,
+ "rental_start": "12/11/17",
+ "rental_end": "12/23/16"
+ },
+ "RNT219": {
+ "product_code": "PRD79",
+ "units_rented": 8,
+ "price_per_day": 30,
+ "rental_start": "1/24/17",
+ "rental_end": "12/16/17"
+ },
+ "RNT220": {
+ "product_code": "PRD69",
+ "units_rented": 9,
+ "price_per_day": 11,
+ "rental_start": "1/1/16",
+ "rental_end": "2/14/17"
+ },
+ "RNT221": {
+ "product_code": "PRD12",
+ "units_rented": 6,
+ "price_per_day": 40,
+ "rental_start": "10/26/18",
+ "rental_end": "7/28/16"
+ },
+ "RNT222": {
+ "product_code": "PRD97",
+ "units_rented": 1,
+ "price_per_day": 23,
+ "rental_start": "5/5/16",
+ "rental_end": "2/27/17"
+ },
+ "RNT223": {
+ "product_code": "PRD51",
+ "units_rented": 7,
+ "price_per_day": 27,
+ "rental_start": "2/3/18",
+ "rental_end": "4/28/16"
+ },
+ "RNT224": {
+ "product_code": "PRD10",
+ "units_rented": 10,
+ "price_per_day": 34,
+ "rental_start": "11/5/17",
+ "rental_end": "10/7/16"
+ },
+ "RNT225": {
+ "product_code": "PRD51",
+ "units_rented": 7,
+ "price_per_day": 25,
+ "rental_start": "5/15/17",
+ "rental_end": "12/24/16"
+ },
+ "RNT226": {
+ "product_code": "PRD90",
+ "units_rented": 3,
+ "price_per_day": 5,
+ "rental_start": "10/19/17",
+ "rental_end": "12/3/17"
+ },
+ "RNT227": {
+ "product_code": "PRD32",
+ "units_rented": 9,
+ "price_per_day": 17,
+ "rental_start": "5/11/18",
+ "rental_end": "2/4/16"
+ },
+ "RNT228": {
+ "product_code": "PRD61",
+ "units_rented": 7,
+ "price_per_day": 34,
+ "rental_start": "1/28/18",
+ "rental_end": "12/9/18"
+ },
+ "RNT229": {
+ "product_code": "PRD75",
+ "units_rented": 3,
+ "price_per_day": 10,
+ "rental_start": "2/23/17",
+ "rental_end": "11/3/16"
+ },
+ "RNT230": {
+ "product_code": "PRD99",
+ "units_rented": 3,
+ "price_per_day": 21,
+ "rental_start": "10/27/17",
+ "rental_end": "1/4/18"
+ },
+ "RNT231": {
+ "product_code": "PRD20",
+ "units_rented": 2,
+ "price_per_day": 35,
+ "rental_start": "5/25/16",
+ "rental_end": "12/28/18"
+ },
+ "RNT232": {
+ "product_code": "PRD26",
+ "units_rented": 10,
+ "price_per_day": 26,
+ "rental_start": "9/30/16",
+ "rental_end": "10/6/17"
+ },
+ "RNT233": {
+ "product_code": "PRD35",
+ "units_rented": 7,
+ "price_per_day": 9,
+ "rental_start": "4/27/18",
+ "rental_end": "7/25/16"
+ },
+ "RNT234": {
+ "product_code": "PRD2",
+ "units_rented": 10,
+ "price_per_day": 13,
+ "rental_start": "4/25/18",
+ "rental_end": "1/20/18"
+ },
+ "RNT235": {
+ "product_code": "PRD34",
+ "units_rented": 6,
+ "price_per_day": 24,
+ "rental_start": "10/11/18",
+ "rental_end": "10/17/18"
+ },
+ "RNT236": {
+ "product_code": "PRD16",
+ "units_rented": 10,
+ "price_per_day": 10,
+ "rental_start": "12/17/18",
+ "rental_end": "3/25/16"
+ },
+ "RNT237": {
+ "product_code": "PRD9",
+ "units_rented": 10,
+ "price_per_day": 12,
+ "rental_start": "3/25/16",
+ "rental_end": "12/4/17"
+ },
+ "RNT238": {
+ "product_code": "PRD43",
+ "units_rented": 7,
+ "price_per_day": 5,
+ "rental_start": "1/1/18",
+ "rental_end": "8/7/17"
+ },
+ "RNT239": {
+ "product_code": "PRD79",
+ "units_rented": 8,
+ "price_per_day": 20,
+ "rental_start": "3/26/16",
+ "rental_end": "4/23/16"
+ },
+ "RNT240": {
+ "product_code": "PRD20",
+ "units_rented": 1,
+ "price_per_day": 14,
+ "rental_start": "6/17/16",
+ "rental_end": "12/5/16"
+ },
+ "RNT241": {
+ "product_code": "PRD97",
+ "units_rented": 9,
+ "price_per_day": 28,
+ "rental_start": "7/2/18",
+ "rental_end": "12/7/17"
+ },
+ "RNT242": {
+ "product_code": "PRD14",
+ "units_rented": 7,
+ "price_per_day": 9,
+ "rental_start": "1/31/17",
+ "rental_end": "2/18/16"
+ },
+ "RNT243": {
+ "product_code": "PRD0",
+ "units_rented": 4,
+ "price_per_day": 13,
+ "rental_start": "12/8/17",
+ "rental_end": "10/13/16"
+ },
+ "RNT244": {
+ "product_code": "PRD23",
+ "units_rented": 2,
+ "price_per_day": 12,
+ "rental_start": "6/25/18",
+ "rental_end": "9/16/16"
+ },
+ "RNT245": {
+ "product_code": "PRD0",
+ "units_rented": 9,
+ "price_per_day": 39,
+ "rental_start": "6/11/16",
+ "rental_end": "9/10/18"
+ },
+ "RNT246": {
+ "product_code": "PRD85",
+ "units_rented": 3,
+ "price_per_day": 21,
+ "rental_start": "2/2/18",
+ "rental_end": "8/28/17"
+ },
+ "RNT247": {
+ "product_code": "PRD33",
+ "units_rented": 6,
+ "price_per_day": 9,
+ "rental_start": "7/10/17",
+ "rental_end": "6/10/17"
+ },
+ "RNT248": {
+ "product_code": "PRD79",
+ "units_rented": 9,
+ "price_per_day": 33,
+ "rental_start": "6/23/16",
+ "rental_end": "7/29/17"
+ },
+ "RNT249": {
+ "product_code": "PRD6",
+ "units_rented": 6,
+ "price_per_day": 6,
+ "rental_start": "10/28/16",
+ "rental_end": "2/16/17"
+ },
+ "RNT250": {
+ "product_code": "PRD83",
+ "units_rented": 8,
+ "price_per_day": 24,
+ "rental_start": "3/23/18",
+ "rental_end": "4/28/18"
+ },
+ "RNT251": {
+ "product_code": "PRD58",
+ "units_rented": 1,
+ "price_per_day": 27,
+ "rental_start": "1/12/18",
+ "rental_end": "10/6/18"
+ },
+ "RNT252": {
+ "product_code": "PRD5",
+ "units_rented": 5,
+ "price_per_day": 21,
+ "rental_start": "12/30/16",
+ "rental_end": "8/27/17"
+ },
+ "RNT253": {
+ "product_code": "PRD10",
+ "units_rented": 6,
+ "price_per_day": 28,
+ "rental_start": "1/11/17",
+ "rental_end": "12/17/18"
+ },
+ "RNT254": {
+ "product_code": "PRD13",
+ "units_rented": 7,
+ "price_per_day": 8,
+ "rental_start": "10/31/16",
+ "rental_end": "4/17/16"
+ },
+ "RNT255": {
+ "product_code": "PRD10",
+ "units_rented": 10,
+ "price_per_day": 17,
+ "rental_start": "4/1/17",
+ "rental_end": "9/2/18"
+ },
+ "RNT256": {
+ "product_code": "PRD60",
+ "units_rented": 6,
+ "price_per_day": 26,
+ "rental_start": "9/5/17",
+ "rental_end": "11/23/17"
+ },
+ "RNT257": {
+ "product_code": "PRD0",
+ "units_rented": 5,
+ "price_per_day": 20,
+ "rental_start": "4/4/16",
+ "rental_end": "12/15/18"
+ },
+ "RNT258": {
+ "product_code": "PRD70",
+ "units_rented": 2,
+ "price_per_day": 18,
+ "rental_start": "10/21/17",
+ "rental_end": "4/10/17"
+ },
+ "RNT259": {
+ "product_code": "PRD86",
+ "units_rented": 4,
+ "price_per_day": 34,
+ "rental_start": "2/14/18",
+ "rental_end": "8/16/16"
+ },
+ "RNT260": {
+ "product_code": "PRD17",
+ "units_rented": 10,
+ "price_per_day": 16,
+ "rental_start": "1/28/18",
+ "rental_end": "1/19/17"
+ },
+ "RNT261": {
+ "product_code": "PRD82",
+ "units_rented": 4,
+ "price_per_day": 15,
+ "rental_start": "3/14/18",
+ "rental_end": "11/10/17"
+ },
+ "RNT262": {
+ "product_code": "PRD59",
+ "units_rented": 7,
+ "price_per_day": 11,
+ "rental_start": "11/24/16",
+ "rental_end": "3/13/17"
+ },
+ "RNT263": {
+ "product_code": "PRD90",
+ "units_rented": 1,
+ "price_per_day": 33,
+ "rental_start": "3/3/18",
+ "rental_end": "12/5/18"
+ },
+ "RNT264": {
+ "product_code": "PRD50",
+ "units_rented": 1,
+ "price_per_day": 15,
+ "rental_start": "9/25/18",
+ "rental_end": "9/26/16"
+ },
+ "RNT265": {
+ "product_code": "PRD15",
+ "units_rented": 5,
+ "price_per_day": 16,
+ "rental_start": "10/8/17",
+ "rental_end": "10/7/17"
+ },
+ "RNT266": {
+ "product_code": "PRD35",
+ "units_rented": 7,
+ "price_per_day": 39,
+ "rental_start": "1/7/18",
+ "rental_end": "1/20/18"
+ },
+ "RNT267": {
+ "product_code": "PRD44",
+ "units_rented": 3,
+ "price_per_day": 26,
+ "rental_start": "4/12/16",
+ "rental_end": "8/5/17"
+ },
+ "RNT268": {
+ "product_code": "PRD27",
+ "units_rented": 2,
+ "price_per_day": 15,
+ "rental_start": "6/10/16",
+ "rental_end": "7/16/16"
+ },
+ "RNT269": {
+ "product_code": "PRD5",
+ "units_rented": 6,
+ "price_per_day": 39,
+ "rental_start": "6/17/17",
+ "rental_end": "11/20/18"
+ },
+ "RNT270": {
+ "product_code": "PRD19",
+ "units_rented": 4,
+ "price_per_day": 19,
+ "rental_start": "8/30/16",
+ "rental_end": "7/24/16"
+ },
+ "RNT271": {
+ "product_code": "PRD33",
+ "units_rented": 1,
+ "price_per_day": 11,
+ "rental_start": "11/27/18",
+ "rental_end": "8/7/16"
+ },
+ "RNT272": {
+ "product_code": "PRD57",
+ "units_rented": 2,
+ "price_per_day": 24,
+ "rental_start": "7/31/17",
+ "rental_end": "5/19/17"
+ },
+ "RNT273": {
+ "product_code": "PRD96",
+ "units_rented": 9,
+ "price_per_day": 12,
+ "rental_start": "10/27/17",
+ "rental_end": "6/30/18"
+ },
+ "RNT274": {
+ "product_code": "PRD3",
+ "units_rented": 2,
+ "price_per_day": 38,
+ "rental_start": "12/15/18",
+ "rental_end": "2/12/17"
+ },
+ "RNT275": {
+ "product_code": "PRD17",
+ "units_rented": 8,
+ "price_per_day": 22,
+ "rental_start": "11/14/16",
+ "rental_end": "12/30/16"
+ },
+ "RNT276": {
+ "product_code": "PRD84",
+ "units_rented": 2,
+ "price_per_day": 27,
+ "rental_start": "7/2/16",
+ "rental_end": "4/2/18"
+ },
+ "RNT277": {
+ "product_code": "PRD28",
+ "units_rented": 2,
+ "price_per_day": 5,
+ "rental_start": "8/7/18",
+ "rental_end": "10/21/16"
+ },
+ "RNT278": {
+ "product_code": "PRD64",
+ "units_rented": 3,
+ "price_per_day": 36,
+ "rental_start": "7/25/16",
+ "rental_end": "12/23/18"
+ },
+ "RNT279": {
+ "product_code": "PRD14",
+ "units_rented": 8,
+ "price_per_day": 34,
+ "rental_start": "5/23/16",
+ "rental_end": "4/25/18"
+ },
+ "RNT280": {
+ "product_code": "PRD14",
+ "units_rented": 10,
+ "price_per_day": 9,
+ "rental_start": "7/25/16",
+ "rental_end": "8/1/18"
+ },
+ "RNT281": {
+ "product_code": "PRD29",
+ "units_rented": 1,
+ "price_per_day": 6,
+ "rental_start": "7/18/17",
+ "rental_end": "5/25/18"
+ },
+ "RNT282": {
+ "product_code": "PRD28",
+ "units_rented": 8,
+ "price_per_day": 20,
+ "rental_start": "2/3/18",
+ "rental_end": "9/4/17"
+ },
+ "RNT283": {
+ "product_code": "PRD85",
+ "units_rented": 7,
+ "price_per_day": 12,
+ "rental_start": "7/18/18",
+ "rental_end": "6/30/18"
+ },
+ "RNT284": {
+ "product_code": "PRD40",
+ "units_rented": 6,
+ "price_per_day": 36,
+ "rental_start": "1/17/16",
+ "rental_end": "12/19/16"
+ },
+ "RNT285": {
+ "product_code": "PRD19",
+ "units_rented": 6,
+ "price_per_day": 33,
+ "rental_start": "3/31/17",
+ "rental_end": "5/5/17"
+ },
+ "RNT286": {
+ "product_code": "PRD1",
+ "units_rented": 6,
+ "price_per_day": 5,
+ "rental_start": "4/26/16",
+ "rental_end": "3/27/17"
+ },
+ "RNT287": {
+ "product_code": "PRD28",
+ "units_rented": 5,
+ "price_per_day": 38,
+ "rental_start": "6/9/16",
+ "rental_end": "1/1/17"
+ },
+ "RNT288": {
+ "product_code": "PRD74",
+ "units_rented": 8,
+ "price_per_day": 37,
+ "rental_start": "12/31/18",
+ "rental_end": "9/13/18"
+ },
+ "RNT289": {
+ "product_code": "PRD75",
+ "units_rented": 10,
+ "price_per_day": 27,
+ "rental_start": "6/11/18",
+ "rental_end": "7/1/18"
+ },
+ "RNT290": {
+ "product_code": "PRD90",
+ "units_rented": 2,
+ "price_per_day": 26,
+ "rental_start": "5/17/16",
+ "rental_end": "5/12/16"
+ },
+ "RNT291": {
+ "product_code": "PRD19",
+ "units_rented": 1,
+ "price_per_day": 14,
+ "rental_start": "7/26/16",
+ "rental_end": "10/10/18"
+ },
+ "RNT292": {
+ "product_code": "PRD14",
+ "units_rented": 1,
+ "price_per_day": 29,
+ "rental_start": "1/13/17",
+ "rental_end": "3/31/17"
+ },
+ "RNT293": {
+ "product_code": "PRD75",
+ "units_rented": 6,
+ "price_per_day": 8,
+ "rental_start": "4/6/18",
+ "rental_end": "12/3/18"
+ },
+ "RNT294": {
+ "product_code": "PRD40",
+ "units_rented": 6,
+ "price_per_day": 16,
+ "rental_start": "1/14/16",
+ "rental_end": "11/16/18"
+ },
+ "RNT295": {
+ "product_code": "PRD71",
+ "units_rented": 3,
+ "price_per_day": 35,
+ "rental_start": "11/10/16",
+ "rental_end": "4/25/16"
+ },
+ "RNT296": {
+ "product_code": "PRD84",
+ "units_rented": 5,
+ "price_per_day": 24,
+ "rental_start": "12/8/17",
+ "rental_end": "5/13/16"
+ },
+ "RNT297": {
+ "product_code": "PRD61",
+ "units_rented": 1,
+ "price_per_day": 5,
+ "rental_start": "12/29/17",
+ "rental_end": "9/4/18"
+ },
+ "RNT298": {
+ "product_code": "PRD29",
+ "units_rented": 3,
+ "price_per_day": 20,
+ "rental_start": "12/11/18",
+ "rental_end": "7/8/18"
+ },
+ "RNT299": {
+ "product_code": "PRD69",
+ "units_rented": 6,
+ "price_per_day": 39,
+ "rental_start": "10/13/16",
+ "rental_end": "10/8/16"
+ },
+ "RNT300": {
+ "product_code": "PRD18",
+ "units_rented": 1,
+ "price_per_day": 27,
+ "rental_start": "1/27/17",
+ "rental_end": "6/30/16"
+ },
+ "RNT301": {
+ "product_code": "PRD89",
+ "units_rented": 8,
+ "price_per_day": 15,
+ "rental_start": "8/10/17",
+ "rental_end": "1/29/16"
+ },
+ "RNT302": {
+ "product_code": "PRD37",
+ "units_rented": 3,
+ "price_per_day": 6,
+ "rental_start": "12/2/16",
+ "rental_end": "2/22/16"
+ },
+ "RNT303": {
+ "product_code": "PRD13",
+ "units_rented": 8,
+ "price_per_day": 30,
+ "rental_start": "7/2/18",
+ "rental_end": "5/23/17"
+ },
+ "RNT304": {
+ "product_code": "PRD11",
+ "units_rented": 8,
+ "price_per_day": 20,
+ "rental_start": "6/29/18",
+ "rental_end": "12/31/17"
+ },
+ "RNT305": {
+ "product_code": "PRD12",
+ "units_rented": 7,
+ "price_per_day": 19,
+ "rental_start": "1/10/18",
+ "rental_end": "4/20/16"
+ },
+ "RNT306": {
+ "product_code": "PRD18",
+ "units_rented": 1,
+ "price_per_day": 40,
+ "rental_start": "8/6/18",
+ "rental_end": "1/21/17"
+ },
+ "RNT307": {
+ "product_code": "PRD90",
+ "units_rented": 9,
+ "price_per_day": 10,
+ "rental_start": "11/4/17",
+ "rental_end": "6/18/18"
+ },
+ "RNT308": {
+ "product_code": "PRD23",
+ "units_rented": 6,
+ "price_per_day": 5,
+ "rental_start": "7/25/16",
+ "rental_end": "4/28/16"
+ },
+ "RNT309": {
+ "product_code": "PRD14",
+ "units_rented": 5,
+ "price_per_day": 35,
+ "rental_start": "12/3/17",
+ "rental_end": "10/26/17"
+ },
+ "RNT310": {
+ "product_code": "PRD29",
+ "units_rented": 10,
+ "price_per_day": 13,
+ "rental_start": "11/28/18",
+ "rental_end": "7/5/16"
+ },
+ "RNT311": {
+ "product_code": "PRD45",
+ "units_rented": 8,
+ "price_per_day": 31,
+ "rental_start": "12/24/18",
+ "rental_end": "5/19/17"
+ },
+ "RNT312": {
+ "product_code": "PRD98",
+ "units_rented": 1,
+ "price_per_day": 34,
+ "rental_start": "6/17/17",
+ "rental_end": "3/26/17"
+ },
+ "RNT313": {
+ "product_code": "PRD75",
+ "units_rented": 8,
+ "price_per_day": 13,
+ "rental_start": "1/23/18",
+ "rental_end": "2/17/17"
+ },
+ "RNT314": {
+ "product_code": "PRD71",
+ "units_rented": 8,
+ "price_per_day": 39,
+ "rental_start": "7/25/18",
+ "rental_end": "3/6/17"
+ },
+ "RNT315": {
+ "product_code": "PRD86",
+ "units_rented": 3,
+ "price_per_day": 35,
+ "rental_start": "9/19/17",
+ "rental_end": "12/21/16"
+ },
+ "RNT316": {
+ "product_code": "PRD92",
+ "units_rented": 6,
+ "price_per_day": 16,
+ "rental_start": "1/9/17",
+ "rental_end": "4/14/16"
+ },
+ "RNT317": {
+ "product_code": "PRD41",
+ "units_rented": 3,
+ "price_per_day": 14,
+ "rental_start": "9/12/16",
+ "rental_end": "9/15/18"
+ },
+ "RNT318": {
+ "product_code": "PRD95",
+ "units_rented": 3,
+ "price_per_day": 37,
+ "rental_start": "12/29/16",
+ "rental_end": "11/5/17"
+ },
+ "RNT319": {
+ "product_code": "PRD96",
+ "units_rented": 6,
+ "price_per_day": 38,
+ "rental_start": "2/7/16",
+ "rental_end": "12/24/18"
+ },
+ "RNT320": {
+ "product_code": "PRD90",
+ "units_rented": 5,
+ "price_per_day": 14,
+ "rental_start": "10/16/18",
+ "rental_end": "8/25/17"
+ },
+ "RNT321": {
+ "product_code": "PRD65",
+ "units_rented": 9,
+ "price_per_day": 17,
+ "rental_start": "4/18/18",
+ "rental_end": "6/9/17"
+ },
+ "RNT322": {
+ "product_code": "PRD29",
+ "units_rented": 4,
+ "price_per_day": 37,
+ "rental_start": "1/27/17",
+ "rental_end": "6/6/17"
+ },
+ "RNT323": {
+ "product_code": "PRD82",
+ "units_rented": 4,
+ "price_per_day": 21,
+ "rental_start": "8/15/16",
+ "rental_end": "2/2/17"
+ },
+ "RNT324": {
+ "product_code": "PRD18",
+ "units_rented": 5,
+ "price_per_day": 18,
+ "rental_start": "12/29/18",
+ "rental_end": "2/3/16"
+ },
+ "RNT325": {
+ "product_code": "PRD42",
+ "units_rented": 1,
+ "price_per_day": 34,
+ "rental_start": "5/18/18",
+ "rental_end": "6/10/16"
+ },
+ "RNT326": {
+ "product_code": "PRD28",
+ "units_rented": 4,
+ "price_per_day": 27,
+ "rental_start": "1/5/16",
+ "rental_end": "7/18/17"
+ },
+ "RNT327": {
+ "product_code": "PRD10",
+ "units_rented": 7,
+ "price_per_day": 31,
+ "rental_start": "4/19/16",
+ "rental_end": "1/10/18"
+ },
+ "RNT328": {
+ "product_code": "PRD26",
+ "units_rented": 6,
+ "price_per_day": 5,
+ "rental_start": "8/25/17",
+ "rental_end": "12/5/17"
+ },
+ "RNT329": {
+ "product_code": "PRD85",
+ "units_rented": 9,
+ "price_per_day": 40,
+ "rental_start": "7/16/16",
+ "rental_end": "8/6/17"
+ },
+ "RNT330": {
+ "product_code": "PRD18",
+ "units_rented": 3,
+ "price_per_day": 25,
+ "rental_start": "1/20/17",
+ "rental_end": "5/5/17"
+ },
+ "RNT331": {
+ "product_code": "PRD68",
+ "units_rented": 2,
+ "price_per_day": 38,
+ "rental_start": "7/8/17",
+ "rental_end": "7/6/17"
+ },
+ "RNT332": {
+ "product_code": "PRD30",
+ "units_rented": 5,
+ "price_per_day": 13,
+ "rental_start": "8/8/16",
+ "rental_end": "1/8/18"
+ },
+ "RNT333": {
+ "product_code": "PRD24",
+ "units_rented": 2,
+ "price_per_day": 6,
+ "rental_start": "2/25/16",
+ "rental_end": "9/30/18"
+ },
+ "RNT334": {
+ "product_code": "PRD82",
+ "units_rented": 5,
+ "price_per_day": 33,
+ "rental_start": "2/21/17",
+ "rental_end": "4/27/17"
+ },
+ "RNT335": {
+ "product_code": "PRD37",
+ "units_rented": 3,
+ "price_per_day": 10,
+ "rental_start": "12/19/17",
+ "rental_end": "12/4/17"
+ },
+ "RNT336": {
+ "product_code": "PRD95",
+ "units_rented": 7,
+ "price_per_day": 17,
+ "rental_start": "9/3/17",
+ "rental_end": "12/13/16"
+ },
+ "RNT337": {
+ "product_code": "PRD31",
+ "units_rented": 9,
+ "price_per_day": 25,
+ "rental_start": "12/16/17",
+ "rental_end": "3/25/17"
+ },
+ "RNT338": {
+ "product_code": "PRD29",
+ "units_rented": 3,
+ "price_per_day": 29,
+ "rental_start": "1/23/17",
+ "rental_end": "11/23/17"
+ },
+ "RNT339": {
+ "product_code": "PRD43",
+ "units_rented": 5,
+ "price_per_day": 38,
+ "rental_start": "7/12/17",
+ "rental_end": "3/1/16"
+ },
+ "RNT340": {
+ "product_code": "PRD81",
+ "units_rented": 9,
+ "price_per_day": 14,
+ "rental_start": "1/23/16",
+ "rental_end": "12/9/17"
+ },
+ "RNT341": {
+ "product_code": "PRD11",
+ "units_rented": 3,
+ "price_per_day": 31,
+ "rental_start": "9/23/16",
+ "rental_end": "8/30/17"
+ },
+ "RNT342": {
+ "product_code": "PRD91",
+ "units_rented": 5,
+ "price_per_day": 15,
+ "rental_start": "12/23/16",
+ "rental_end": "6/21/18"
+ },
+ "RNT343": {
+ "product_code": "PRD73",
+ "units_rented": 3,
+ "price_per_day": 32,
+ "rental_start": "2/15/17",
+ "rental_end": "1/17/17"
+ },
+ "RNT344": {
+ "product_code": "PRD61",
+ "units_rented": 1,
+ "price_per_day": 26,
+ "rental_start": "8/3/18",
+ "rental_end": "8/27/18"
+ },
+ "RNT345": {
+ "product_code": "PRD44",
+ "units_rented": 5,
+ "price_per_day": 38,
+ "rental_start": "5/15/17",
+ "rental_end": "10/22/16"
+ },
+ "RNT346": {
+ "product_code": "PRD59",
+ "units_rented": 7,
+ "price_per_day": 27,
+ "rental_start": "9/17/18",
+ "rental_end": "3/21/17"
+ },
+ "RNT347": {
+ "product_code": "PRD32",
+ "units_rented": 6,
+ "price_per_day": 18,
+ "rental_start": "4/17/18",
+ "rental_end": "9/21/17"
+ },
+ "RNT348": {
+ "product_code": "PRD37",
+ "units_rented": 4,
+ "price_per_day": 34,
+ "rental_start": "2/19/16",
+ "rental_end": "5/28/16"
+ },
+ "RNT349": {
+ "product_code": "PRD0",
+ "units_rented": 6,
+ "price_per_day": 15,
+ "rental_start": "10/11/16",
+ "rental_end": "4/5/18"
+ },
+ "RNT350": {
+ "product_code": "PRD22",
+ "units_rented": 1,
+ "price_per_day": 28,
+ "rental_start": "11/12/16",
+ "rental_end": "3/14/17"
+ },
+ "RNT351": {
+ "product_code": "PRD66",
+ "units_rented": 2,
+ "price_per_day": 34,
+ "rental_start": "1/7/16",
+ "rental_end": "6/3/17"
+ },
+ "RNT352": {
+ "product_code": "PRD92",
+ "units_rented": 8,
+ "price_per_day": 33,
+ "rental_start": "7/16/18",
+ "rental_end": "1/15/17"
+ },
+ "RNT353": {
+ "product_code": "PRD38",
+ "units_rented": 4,
+ "price_per_day": 38,
+ "rental_start": "10/4/17",
+ "rental_end": "12/13/16"
+ },
+ "RNT354": {
+ "product_code": "PRD36",
+ "units_rented": 10,
+ "price_per_day": 12,
+ "rental_start": "9/17/16",
+ "rental_end": "10/17/17"
+ },
+ "RNT355": {
+ "product_code": "PRD29",
+ "units_rented": 3,
+ "price_per_day": 12,
+ "rental_start": "9/13/18",
+ "rental_end": "7/30/18"
+ },
+ "RNT356": {
+ "product_code": "PRD59",
+ "units_rented": 9,
+ "price_per_day": 7,
+ "rental_start": "1/16/18",
+ "rental_end": "8/21/17"
+ },
+ "RNT357": {
+ "product_code": "PRD28",
+ "units_rented": 10,
+ "price_per_day": 33,
+ "rental_start": "3/16/18",
+ "rental_end": "8/29/18"
+ },
+ "RNT358": {
+ "product_code": "PRD46",
+ "units_rented": 9,
+ "price_per_day": 7,
+ "rental_start": "9/15/16",
+ "rental_end": "9/19/17"
+ },
+ "RNT359": {
+ "product_code": "PRD30",
+ "units_rented": 5,
+ "price_per_day": 32,
+ "rental_start": "8/20/16",
+ "rental_end": "8/13/17"
+ },
+ "RNT360": {
+ "product_code": "PRD96",
+ "units_rented": 4,
+ "price_per_day": 27,
+ "rental_start": "1/29/16",
+ "rental_end": "3/3/17"
+ },
+ "RNT361": {
+ "product_code": "PRD31",
+ "units_rented": 3,
+ "price_per_day": 21,
+ "rental_start": "1/29/18",
+ "rental_end": "3/5/16"
+ },
+ "RNT362": {
+ "product_code": "PRD99",
+ "units_rented": 2,
+ "price_per_day": 19,
+ "rental_start": "3/18/17",
+ "rental_end": "10/3/18"
+ },
+ "RNT363": {
+ "product_code": "PRD40",
+ "units_rented": 3,
+ "price_per_day": 19,
+ "rental_start": "6/12/18",
+ "rental_end": "5/21/18"
+ },
+ "RNT364": {
+ "product_code": "PRD51",
+ "units_rented": 5,
+ "price_per_day": 38,
+ "rental_start": "6/24/18",
+ "rental_end": "5/14/18"
+ },
+ "RNT365": {
+ "product_code": "PRD76",
+ "units_rented": 2,
+ "price_per_day": 34,
+ "rental_start": "9/29/16",
+ "rental_end": "11/18/17"
+ },
+ "RNT366": {
+ "product_code": "PRD73",
+ "units_rented": 1,
+ "price_per_day": 34,
+ "rental_start": "7/24/18",
+ "rental_end": "10/8/17"
+ },
+ "RNT367": {
+ "product_code": "PRD71",
+ "units_rented": 6,
+ "price_per_day": 37,
+ "rental_start": "8/12/17",
+ "rental_end": "11/26/17"
+ },
+ "RNT368": {
+ "product_code": "PRD31",
+ "units_rented": 9,
+ "price_per_day": 27,
+ "rental_start": "3/9/17",
+ "rental_end": "6/18/17"
+ },
+ "RNT369": {
+ "product_code": "PRD2",
+ "units_rented": 2,
+ "price_per_day": 20,
+ "rental_start": "6/1/18",
+ "rental_end": "9/11/18"
+ },
+ "RNT370": {
+ "product_code": "PRD3",
+ "units_rented": 10,
+ "price_per_day": 28,
+ "rental_start": "7/23/16",
+ "rental_end": "2/23/18"
+ },
+ "RNT371": {
+ "product_code": "PRD2",
+ "units_rented": 2,
+ "price_per_day": 30,
+ "rental_start": "11/20/18",
+ "rental_end": "6/10/17"
+ },
+ "RNT372": {
+ "product_code": "PRD40",
+ "units_rented": 6,
+ "price_per_day": 26,
+ "rental_start": "9/14/17",
+ "rental_end": "9/17/16"
+ },
+ "RNT373": {
+ "product_code": "PRD30",
+ "units_rented": 2,
+ "price_per_day": 21,
+ "rental_start": "9/17/17",
+ "rental_end": "12/24/17"
+ },
+ "RNT374": {
+ "product_code": "PRD85",
+ "units_rented": 6,
+ "price_per_day": 9,
+ "rental_start": "6/28/18",
+ "rental_end": "1/15/18"
+ },
+ "RNT375": {
+ "product_code": "PRD1",
+ "units_rented": 5,
+ "price_per_day": 8,
+ "rental_start": "5/18/17",
+ "rental_end": "7/17/17"
+ },
+ "RNT376": {
+ "product_code": "PRD75",
+ "units_rented": 10,
+ "price_per_day": 23,
+ "rental_start": "11/20/17",
+ "rental_end": "4/20/17"
+ },
+ "RNT377": {
+ "product_code": "PRD76",
+ "units_rented": 1,
+ "price_per_day": 21,
+ "rental_start": "4/9/16",
+ "rental_end": "3/10/18"
+ },
+ "RNT378": {
+ "product_code": "PRD68",
+ "units_rented": 5,
+ "price_per_day": 28,
+ "rental_start": "6/24/16",
+ "rental_end": "12/19/17"
+ },
+ "RNT379": {
+ "product_code": "PRD44",
+ "units_rented": 10,
+ "price_per_day": 17,
+ "rental_start": "9/11/18",
+ "rental_end": "11/21/16"
+ },
+ "RNT380": {
+ "product_code": "PRD12",
+ "units_rented": 10,
+ "price_per_day": 24,
+ "rental_start": "3/6/16",
+ "rental_end": "5/23/17"
+ },
+ "RNT381": {
+ "product_code": "PRD30",
+ "units_rented": 3,
+ "price_per_day": 19,
+ "rental_start": "5/28/18",
+ "rental_end": "12/26/16"
+ },
+ "RNT382": {
+ "product_code": "PRD95",
+ "units_rented": 3,
+ "price_per_day": 21,
+ "rental_start": "5/19/17",
+ "rental_end": "12/8/18"
+ },
+ "RNT383": {
+ "product_code": "PRD58",
+ "units_rented": 9,
+ "price_per_day": 9,
+ "rental_start": "5/28/17",
+ "rental_end": "5/6/17"
+ },
+ "RNT384": {
+ "product_code": "PRD73",
+ "units_rented": 1,
+ "price_per_day": 34,
+ "rental_start": "11/28/17",
+ "rental_end": "5/29/17"
+ },
+ "RNT385": {
+ "product_code": "PRD29",
+ "units_rented": 9,
+ "price_per_day": 18,
+ "rental_start": "12/17/16",
+ "rental_end": "8/30/18"
+ },
+ "RNT386": {
+ "product_code": "PRD99",
+ "units_rented": 4,
+ "price_per_day": 38,
+ "rental_start": "1/5/17",
+ "rental_end": "6/9/16"
+ },
+ "RNT387": {
+ "product_code": "PRD38",
+ "units_rented": 3,
+ "price_per_day": 40,
+ "rental_start": "12/28/18",
+ "rental_end": "7/18/16"
+ },
+ "RNT388": {
+ "product_code": "PRD38",
+ "units_rented": 9,
+ "price_per_day": 5,
+ "rental_start": "7/21/18",
+ "rental_end": "12/11/16"
+ },
+ "RNT389": {
+ "product_code": "PRD71",
+ "units_rented": 10,
+ "price_per_day": 27,
+ "rental_start": "4/6/17",
+ "rental_end": "8/25/18"
+ },
+ "RNT390": {
+ "product_code": "PRD81",
+ "units_rented": 7,
+ "price_per_day": 5,
+ "rental_start": "12/16/16",
+ "rental_end": "10/19/17"
+ },
+ "RNT391": {
+ "product_code": "PRD2",
+ "units_rented": 1,
+ "price_per_day": 27,
+ "rental_start": "8/18/17",
+ "rental_end": "8/6/17"
+ },
+ "RNT392": {
+ "product_code": "PRD64",
+ "units_rented": 9,
+ "price_per_day": 21,
+ "rental_start": "7/17/18",
+ "rental_end": "4/4/18"
+ },
+ "RNT393": {
+ "product_code": "PRD49",
+ "units_rented": 8,
+ "price_per_day": 15,
+ "rental_start": "3/10/16",
+ "rental_end": "4/6/17"
+ },
+ "RNT394": {
+ "product_code": "PRD11",
+ "units_rented": 3,
+ "price_per_day": 27,
+ "rental_start": "2/15/18",
+ "rental_end": "1/10/17"
+ },
+ "RNT395": {
+ "product_code": "PRD22",
+ "units_rented": 5,
+ "price_per_day": 6,
+ "rental_start": "3/31/18",
+ "rental_end": "12/29/17"
+ },
+ "RNT396": {
+ "product_code": "PRD10",
+ "units_rented": 8,
+ "price_per_day": 5,
+ "rental_start": "8/9/16",
+ "rental_end": "5/16/18"
+ },
+ "RNT397": {
+ "product_code": "PRD81",
+ "units_rented": 4,
+ "price_per_day": 18,
+ "rental_start": "6/22/17",
+ "rental_end": "5/11/16"
+ },
+ "RNT398": {
+ "product_code": "PRD46",
+ "units_rented": 9,
+ "price_per_day": 16,
+ "rental_start": "5/27/18",
+ "rental_end": "6/5/18"
+ },
+ "RNT399": {
+ "product_code": "PRD10",
+ "units_rented": 5,
+ "price_per_day": 35,
+ "rental_start": "1/21/16",
+ "rental_end": "10/11/17"
+ },
+ "RNT400": {
+ "product_code": "PRD59",
+ "units_rented": 5,
+ "price_per_day": 27,
+ "rental_start": "10/12/18",
+ "rental_end": "3/6/17"
+ },
+ "RNT401": {
+ "product_code": "PRD86",
+ "units_rented": 1,
+ "price_per_day": 36,
+ "rental_start": "1/1/18",
+ "rental_end": "5/10/18"
+ },
+ "RNT402": {
+ "product_code": "PRD69",
+ "units_rented": 9,
+ "price_per_day": 24,
+ "rental_start": "3/8/17",
+ "rental_end": "12/3/17"
+ },
+ "RNT403": {
+ "product_code": "PRD59",
+ "units_rented": 2,
+ "price_per_day": 6,
+ "rental_start": "8/16/16",
+ "rental_end": "10/7/17"
+ },
+ "RNT404": {
+ "product_code": "PRD95",
+ "units_rented": 7,
+ "price_per_day": 40,
+ "rental_start": "9/1/16",
+ "rental_end": "11/23/17"
+ },
+ "RNT405": {
+ "product_code": "PRD48",
+ "units_rented": 3,
+ "price_per_day": 18,
+ "rental_start": "10/9/18",
+ "rental_end": "4/17/17"
+ },
+ "RNT406": {
+ "product_code": "PRD49",
+ "units_rented": 5,
+ "price_per_day": 13,
+ "rental_start": "3/2/17",
+ "rental_end": "1/5/18"
+ },
+ "RNT407": {
+ "product_code": "PRD75",
+ "units_rented": 8,
+ "price_per_day": 37,
+ "rental_start": "8/7/16",
+ "rental_end": "3/18/17"
+ },
+ "RNT408": {
+ "product_code": "PRD42",
+ "units_rented": 2,
+ "price_per_day": 37,
+ "rental_start": "2/1/17",
+ "rental_end": "1/2/17"
+ },
+ "RNT409": {
+ "product_code": "PRD12",
+ "units_rented": 10,
+ "price_per_day": 24,
+ "rental_start": "8/16/17",
+ "rental_end": "11/18/16"
+ },
+ "RNT410": {
+ "product_code": "PRD56",
+ "units_rented": 10,
+ "price_per_day": 14,
+ "rental_start": "8/8/18",
+ "rental_end": "9/7/18"
+ },
+ "RNT411": {
+ "product_code": "PRD99",
+ "units_rented": 3,
+ "price_per_day": 16,
+ "rental_start": "10/7/16",
+ "rental_end": "6/2/18"
+ },
+ "RNT412": {
+ "product_code": "PRD58",
+ "units_rented": 3,
+ "price_per_day": 33,
+ "rental_start": "6/30/18",
+ "rental_end": "9/16/17"
+ },
+ "RNT413": {
+ "product_code": "PRD6",
+ "units_rented": 2,
+ "price_per_day": 5,
+ "rental_start": "9/22/18",
+ "rental_end": "10/1/17"
+ },
+ "RNT414": {
+ "product_code": "PRD65",
+ "units_rented": 8,
+ "price_per_day": 38,
+ "rental_start": "8/5/17",
+ "rental_end": "11/4/16"
+ },
+ "RNT415": {
+ "product_code": "PRD26",
+ "units_rented": 1,
+ "price_per_day": 9,
+ "rental_start": "4/12/16",
+ "rental_end": "9/13/17"
+ },
+ "RNT416": {
+ "product_code": "PRD71",
+ "units_rented": 4,
+ "price_per_day": 27,
+ "rental_start": "10/26/17",
+ "rental_end": "2/18/17"
+ },
+ "RNT417": {
+ "product_code": "PRD14",
+ "units_rented": 10,
+ "price_per_day": 37,
+ "rental_start": "5/4/16",
+ "rental_end": "9/22/16"
+ },
+ "RNT418": {
+ "product_code": "PRD31",
+ "units_rented": 6,
+ "price_per_day": 22,
+ "rental_start": "9/29/16",
+ "rental_end": "6/30/17"
+ },
+ "RNT419": {
+ "product_code": "PRD12",
+ "units_rented": 9,
+ "price_per_day": 10,
+ "rental_start": "2/3/16",
+ "rental_end": "9/2/18"
+ },
+ "RNT420": {
+ "product_code": "PRD49",
+ "units_rented": 7,
+ "price_per_day": 20,
+ "rental_start": "8/22/16",
+ "rental_end": "11/27/18"
+ },
+ "RNT421": {
+ "product_code": "PRD92",
+ "units_rented": 9,
+ "price_per_day": 9,
+ "rental_start": "12/6/17",
+ "rental_end": "4/14/16"
+ },
+ "RNT422": {
+ "product_code": "PRD14",
+ "units_rented": 4,
+ "price_per_day": 21,
+ "rental_start": "12/24/16",
+ "rental_end": "7/18/16"
+ },
+ "RNT423": {
+ "product_code": "PRD45",
+ "units_rented": 6,
+ "price_per_day": 35,
+ "rental_start": "10/17/16",
+ "rental_end": "1/25/16"
+ },
+ "RNT424": {
+ "product_code": "PRD5",
+ "units_rented": 8,
+ "price_per_day": 22,
+ "rental_start": "9/27/18",
+ "rental_end": "4/27/16"
+ },
+ "RNT425": {
+ "product_code": "PRD26",
+ "units_rented": 5,
+ "price_per_day": 35,
+ "rental_start": "1/30/17",
+ "rental_end": "6/23/18"
+ },
+ "RNT426": {
+ "product_code": "PRD33",
+ "units_rented": 7,
+ "price_per_day": 23,
+ "rental_start": "3/6/16",
+ "rental_end": "4/26/17"
+ },
+ "RNT427": {
+ "product_code": "PRD59",
+ "units_rented": 9,
+ "price_per_day": 11,
+ "rental_start": "5/5/18",
+ "rental_end": "1/9/17"
+ },
+ "RNT428": {
+ "product_code": "PRD86",
+ "units_rented": 7,
+ "price_per_day": 15,
+ "rental_start": "11/11/16",
+ "rental_end": "6/11/16"
+ },
+ "RNT429": {
+ "product_code": "PRD9",
+ "units_rented": 10,
+ "price_per_day": 30,
+ "rental_start": "2/13/16",
+ "rental_end": "9/4/16"
+ },
+ "RNT430": {
+ "product_code": "PRD57",
+ "units_rented": 2,
+ "price_per_day": 15,
+ "rental_start": "5/3/18",
+ "rental_end": "4/11/18"
+ },
+ "RNT431": {
+ "product_code": "PRD90",
+ "units_rented": 6,
+ "price_per_day": 9,
+ "rental_start": "3/30/16",
+ "rental_end": "7/23/18"
+ },
+ "RNT432": {
+ "product_code": "PRD12",
+ "units_rented": 3,
+ "price_per_day": 19,
+ "rental_start": "12/24/17",
+ "rental_end": "12/27/18"
+ },
+ "RNT433": {
+ "product_code": "PRD31",
+ "units_rented": 8,
+ "price_per_day": 25,
+ "rental_start": "1/31/16",
+ "rental_end": "11/6/18"
+ },
+ "RNT434": {
+ "product_code": "PRD18",
+ "units_rented": 10,
+ "price_per_day": 29,
+ "rental_start": "8/18/17",
+ "rental_end": "11/3/18"
+ },
+ "RNT435": {
+ "product_code": "PRD70",
+ "units_rented": 1,
+ "price_per_day": 32,
+ "rental_start": "11/22/16",
+ "rental_end": "1/24/16"
+ },
+ "RNT436": {
+ "product_code": "PRD37",
+ "units_rented": 4,
+ "price_per_day": 10,
+ "rental_start": "4/17/18",
+ "rental_end": "5/7/17"
+ },
+ "RNT437": {
+ "product_code": "PRD39",
+ "units_rented": 5,
+ "price_per_day": 32,
+ "rental_start": "8/31/16",
+ "rental_end": "9/17/17"
+ },
+ "RNT438": {
+ "product_code": "PRD10",
+ "units_rented": 10,
+ "price_per_day": 8,
+ "rental_start": "4/24/16",
+ "rental_end": "6/29/16"
+ },
+ "RNT439": {
+ "product_code": "PRD76",
+ "units_rented": 5,
+ "price_per_day": 38,
+ "rental_start": "4/30/18",
+ "rental_end": "7/24/18"
+ },
+ "RNT440": {
+ "product_code": "PRD43",
+ "units_rented": 1,
+ "price_per_day": 36,
+ "rental_start": "11/24/18",
+ "rental_end": "12/3/16"
+ },
+ "RNT441": {
+ "product_code": "PRD33",
+ "units_rented": 4,
+ "price_per_day": 12,
+ "rental_start": "6/1/16",
+ "rental_end": "5/1/18"
+ },
+ "RNT442": {
+ "product_code": "PRD68",
+ "units_rented": 8,
+ "price_per_day": 13,
+ "rental_start": "2/6/17",
+ "rental_end": "8/21/18"
+ },
+ "RNT443": {
+ "product_code": "PRD82",
+ "units_rented": 9,
+ "price_per_day": 27,
+ "rental_start": "8/7/18",
+ "rental_end": "2/18/16"
+ },
+ "RNT444": {
+ "product_code": "PRD0",
+ "units_rented": 1,
+ "price_per_day": 40,
+ "rental_start": "6/16/17",
+ "rental_end": "12/8/17"
+ },
+ "RNT445": {
+ "product_code": "PRD87",
+ "units_rented": 6,
+ "price_per_day": 16,
+ "rental_start": "2/22/18",
+ "rental_end": "10/24/17"
+ },
+ "RNT446": {
+ "product_code": "PRD55",
+ "units_rented": 4,
+ "price_per_day": 18,
+ "rental_start": "6/30/18",
+ "rental_end": "6/26/16"
+ },
+ "RNT447": {
+ "product_code": "PRD67",
+ "units_rented": 3,
+ "price_per_day": 21,
+ "rental_start": "11/14/17",
+ "rental_end": "7/7/17"
+ },
+ "RNT448": {
+ "product_code": "PRD33",
+ "units_rented": 7,
+ "price_per_day": 29,
+ "rental_start": "6/20/17",
+ "rental_end": "12/25/17"
+ },
+ "RNT449": {
+ "product_code": "PRD89",
+ "units_rented": 6,
+ "price_per_day": 37,
+ "rental_start": "10/17/18",
+ "rental_end": "7/30/17"
+ },
+ "RNT450": {
+ "product_code": "PRD40",
+ "units_rented": 8,
+ "price_per_day": 22,
+ "rental_start": "12/31/16",
+ "rental_end": "12/25/17"
+ },
+ "RNT451": {
+ "product_code": "PRD3",
+ "units_rented": 2,
+ "price_per_day": 6,
+ "rental_start": "3/23/17",
+ "rental_end": "10/16/16"
+ },
+ "RNT452": {
+ "product_code": "PRD57",
+ "units_rented": 7,
+ "price_per_day": 18,
+ "rental_start": "2/6/17",
+ "rental_end": "11/17/18"
+ },
+ "RNT453": {
+ "product_code": "PRD52",
+ "units_rented": 1,
+ "price_per_day": 34,
+ "rental_start": "10/10/18",
+ "rental_end": "7/23/16"
+ },
+ "RNT454": {
+ "product_code": "PRD46",
+ "units_rented": 2,
+ "price_per_day": 5,
+ "rental_start": "9/28/18",
+ "rental_end": "8/25/18"
+ },
+ "RNT455": {
+ "product_code": "PRD73",
+ "units_rented": 7,
+ "price_per_day": 7,
+ "rental_start": "11/16/16",
+ "rental_end": "5/3/17"
+ },
+ "RNT456": {
+ "product_code": "PRD24",
+ "units_rented": 6,
+ "price_per_day": 19,
+ "rental_start": "2/16/16",
+ "rental_end": "4/23/16"
+ },
+ "RNT457": {
+ "product_code": "PRD56",
+ "units_rented": 5,
+ "price_per_day": 31,
+ "rental_start": "8/6/18",
+ "rental_end": "11/25/16"
+ },
+ "RNT458": {
+ "product_code": "PRD70",
+ "units_rented": 3,
+ "price_per_day": 7,
+ "rental_start": "9/24/17",
+ "rental_end": "2/26/18"
+ },
+ "RNT459": {
+ "product_code": "PRD92",
+ "units_rented": 8,
+ "price_per_day": 35,
+ "rental_start": "5/23/16",
+ "rental_end": "2/25/17"
+ },
+ "RNT460": {
+ "product_code": "PRD23",
+ "units_rented": 5,
+ "price_per_day": 29,
+ "rental_start": "11/17/16",
+ "rental_end": "3/15/18"
+ },
+ "RNT461": {
+ "product_code": "PRD80",
+ "units_rented": 2,
+ "price_per_day": 11,
+ "rental_start": "7/21/18",
+ "rental_end": "6/6/16"
+ },
+ "RNT462": {
+ "product_code": "PRD82",
+ "units_rented": 7,
+ "price_per_day": 17,
+ "rental_start": "6/9/18",
+ "rental_end": "5/2/18"
+ },
+ "RNT463": {
+ "product_code": "PRD6",
+ "units_rented": 5,
+ "price_per_day": 39,
+ "rental_start": "11/18/18",
+ "rental_end": "3/14/18"
+ },
+ "RNT464": {
+ "product_code": "PRD80",
+ "units_rented": 2,
+ "price_per_day": 6,
+ "rental_start": "3/31/18",
+ "rental_end": "7/23/18"
+ },
+ "RNT465": {
+ "product_code": "PRD81",
+ "units_rented": 3,
+ "price_per_day": 37,
+ "rental_start": "4/28/18",
+ "rental_end": "3/7/17"
+ },
+ "RNT466": {
+ "product_code": "PRD93",
+ "units_rented": 3,
+ "price_per_day": 7,
+ "rental_start": "1/14/17",
+ "rental_end": "8/20/18"
+ },
+ "RNT467": {
+ "product_code": "PRD65",
+ "units_rented": 8,
+ "price_per_day": 28,
+ "rental_start": "5/18/18",
+ "rental_end": "5/23/16"
+ },
+ "RNT468": {
+ "product_code": "PRD90",
+ "units_rented": 5,
+ "price_per_day": 6,
+ "rental_start": "5/12/16",
+ "rental_end": "7/19/16"
+ },
+ "RNT469": {
+ "product_code": "PRD49",
+ "units_rented": 5,
+ "price_per_day": 10,
+ "rental_start": "12/27/16",
+ "rental_end": "11/21/18"
+ },
+ "RNT470": {
+ "product_code": "PRD74",
+ "units_rented": 2,
+ "price_per_day": 23,
+ "rental_start": "3/4/18",
+ "rental_end": "7/1/18"
+ },
+ "RNT471": {
+ "product_code": "PRD52",
+ "units_rented": 5,
+ "price_per_day": 7,
+ "rental_start": "11/25/16",
+ "rental_end": "11/22/18"
+ },
+ "RNT472": {
+ "product_code": "PRD44",
+ "units_rented": 9,
+ "price_per_day": 36,
+ "rental_start": "4/25/17",
+ "rental_end": "3/5/17"
+ },
+ "RNT473": {
+ "product_code": "PRD22",
+ "units_rented": 8,
+ "price_per_day": 30,
+ "rental_start": "1/25/17",
+ "rental_end": "12/3/18"
+ },
+ "RNT474": {
+ "product_code": "PRD81",
+ "units_rented": 5,
+ "price_per_day": 35,
+ "rental_start": "5/23/17",
+ "rental_end": "6/4/17"
+ },
+ "RNT475": {
+ "product_code": "PRD31",
+ "units_rented": 10,
+ "price_per_day": 6,
+ "rental_start": "8/15/17",
+ "rental_end": "7/29/18"
+ },
+ "RNT476": {
+ "product_code": "PRD40",
+ "units_rented": 4,
+ "price_per_day": 36,
+ "rental_start": "7/28/18",
+ "rental_end": "11/26/16"
+ },
+ "RNT477": {
+ "product_code": "PRD15",
+ "units_rented": 9,
+ "price_per_day": 5,
+ "rental_start": "8/24/16",
+ "rental_end": "1/23/18"
+ },
+ "RNT478": {
+ "product_code": "PRD39",
+ "units_rented": 3,
+ "price_per_day": 36,
+ "rental_start": "1/12/16",
+ "rental_end": "3/29/16"
+ },
+ "RNT479": {
+ "product_code": "PRD59",
+ "units_rented": 10,
+ "price_per_day": 22,
+ "rental_start": "9/13/16",
+ "rental_end": "9/28/16"
+ },
+ "RNT480": {
+ "product_code": "PRD42",
+ "units_rented": 3,
+ "price_per_day": 8,
+ "rental_start": "8/2/18",
+ "rental_end": "4/8/17"
+ },
+ "RNT481": {
+ "product_code": "PRD76",
+ "units_rented": 8,
+ "price_per_day": 21,
+ "rental_start": "5/16/17",
+ "rental_end": "9/4/17"
+ },
+ "RNT482": {
+ "product_code": "PRD96",
+ "units_rented": 7,
+ "price_per_day": 13,
+ "rental_start": "1/25/16",
+ "rental_end": "1/24/17"
+ },
+ "RNT483": {
+ "product_code": "PRD63",
+ "units_rented": 3,
+ "price_per_day": 23,
+ "rental_start": "1/13/17",
+ "rental_end": "3/19/18"
+ },
+ "RNT484": {
+ "product_code": "PRD40",
+ "units_rented": 6,
+ "price_per_day": 14,
+ "rental_start": "6/23/16",
+ "rental_end": "9/7/17"
+ },
+ "RNT485": {
+ "product_code": "PRD56",
+ "units_rented": 7,
+ "price_per_day": 38,
+ "rental_start": "3/26/18",
+ "rental_end": "1/29/17"
+ },
+ "RNT486": {
+ "product_code": "PRD20",
+ "units_rented": 1,
+ "price_per_day": 6,
+ "rental_start": "10/26/17",
+ "rental_end": "10/9/18"
+ },
+ "RNT487": {
+ "product_code": "PRD93",
+ "units_rented": 5,
+ "price_per_day": 36,
+ "rental_start": "3/12/17",
+ "rental_end": "4/28/16"
+ },
+ "RNT488": {
+ "product_code": "PRD66",
+ "units_rented": 3,
+ "price_per_day": 23,
+ "rental_start": "3/8/16",
+ "rental_end": "2/15/18"
+ },
+ "RNT489": {
+ "product_code": "PRD69",
+ "units_rented": 6,
+ "price_per_day": 19,
+ "rental_start": "8/21/18",
+ "rental_end": "5/9/18"
+ },
+ "RNT490": {
+ "product_code": "PRD58",
+ "units_rented": 5,
+ "price_per_day": 19,
+ "rental_start": "9/23/17",
+ "rental_end": "8/17/17"
+ },
+ "RNT491": {
+ "product_code": "PRD14",
+ "units_rented": 10,
+ "price_per_day": 15,
+ "rental_start": "6/2/18",
+ "rental_end": "2/3/17"
+ },
+ "RNT492": {
+ "product_code": "PRD26",
+ "units_rented": 6,
+ "price_per_day": 11,
+ "rental_start": "1/22/17",
+ "rental_end": "10/10/17"
+ },
+ "RNT493": {
+ "product_code": "PRD95",
+ "units_rented": 6,
+ "price_per_day": 12,
+ "rental_start": "8/23/18",
+ "rental_end": "10/10/16"
+ },
+ "RNT494": {
+ "product_code": "PRD88",
+ "units_rented": 7,
+ "price_per_day": 23,
+ "rental_start": "7/31/16",
+ "rental_end": "12/29/16"
+ },
+ "RNT495": {
+ "product_code": "PRD23",
+ "units_rented": 10,
+ "price_per_day": 7,
+ "rental_start": "6/22/17",
+ "rental_end": "7/31/16"
+ },
+ "RNT496": {
+ "product_code": "PRD8",
+ "units_rented": 7,
+ "price_per_day": 26,
+ "rental_start": "11/28/17",
+ "rental_end": "12/5/16"
+ },
+ "RNT497": {
+ "product_code": "PRD12",
+ "units_rented": 4,
+ "price_per_day": 17,
+ "rental_start": "6/17/18",
+ "rental_end": "4/20/17"
+ },
+ "RNT498": {
+ "product_code": "PRD95",
+ "units_rented": 6,
+ "price_per_day": 14,
+ "rental_start": "5/1/16",
+ "rental_end": "4/30/17"
+ },
+ "RNT499": {
+ "product_code": "PRD64",
+ "units_rented": 10,
+ "price_per_day": 23,
+ "rental_start": "8/18/17",
+ "rental_end": "4/20/18"
+ },
+ "RNT500": {
+ "product_code": "PRD88",
+ "units_rented": 5,
+ "price_per_day": 27,
+ "rental_start": "3/16/16",
+ "rental_end": "6/5/16"
+ },
+ "RNT501": {
+ "product_code": "PRD51",
+ "units_rented": 2,
+ "price_per_day": 27,
+ "rental_start": "10/30/16",
+ "rental_end": "7/4/16"
+ },
+ "RNT502": {
+ "product_code": "PRD97",
+ "units_rented": 9,
+ "price_per_day": 15,
+ "rental_start": "2/26/17",
+ "rental_end": "7/2/18"
+ },
+ "RNT503": {
+ "product_code": "PRD37",
+ "units_rented": 3,
+ "price_per_day": 39,
+ "rental_start": "3/15/17",
+ "rental_end": "11/22/16"
+ },
+ "RNT504": {
+ "product_code": "PRD88",
+ "units_rented": 2,
+ "price_per_day": 22,
+ "rental_start": "12/22/16",
+ "rental_end": "3/7/18"
+ },
+ "RNT505": {
+ "product_code": "PRD28",
+ "units_rented": 6,
+ "price_per_day": 20,
+ "rental_start": "5/18/16",
+ "rental_end": "10/4/16"
+ },
+ "RNT506": {
+ "product_code": "PRD97",
+ "units_rented": 10,
+ "price_per_day": 36,
+ "rental_start": "1/25/18",
+ "rental_end": "11/19/18"
+ },
+ "RNT507": {
+ "product_code": "PRD1",
+ "units_rented": 4,
+ "price_per_day": 6,
+ "rental_start": "6/20/18",
+ "rental_end": "6/1/17"
+ },
+ "RNT508": {
+ "product_code": "PRD53",
+ "units_rented": 8,
+ "price_per_day": 31,
+ "rental_start": "5/31/17",
+ "rental_end": "3/21/16"
+ },
+ "RNT509": {
+ "product_code": "PRD78",
+ "units_rented": 6,
+ "price_per_day": 12,
+ "rental_start": "12/18/18",
+ "rental_end": "3/17/18"
+ },
+ "RNT510": {
+ "product_code": "PRD74",
+ "units_rented": 5,
+ "price_per_day": 17,
+ "rental_start": "7/14/16",
+ "rental_end": "7/29/16"
+ },
+ "RNT511": {
+ "product_code": "PRD23",
+ "units_rented": 5,
+ "price_per_day": 23,
+ "rental_start": "3/27/18",
+ "rental_end": "12/27/18"
+ },
+ "RNT512": {
+ "product_code": "PRD29",
+ "units_rented": 4,
+ "price_per_day": 8,
+ "rental_start": "11/15/17",
+ "rental_end": "11/3/17"
+ },
+ "RNT513": {
+ "product_code": "PRD2",
+ "units_rented": 6,
+ "price_per_day": 25,
+ "rental_start": "12/22/18",
+ "rental_end": "7/6/18"
+ },
+ "RNT514": {
+ "product_code": "PRD23",
+ "units_rented": 9,
+ "price_per_day": 34,
+ "rental_start": "8/18/18",
+ "rental_end": "9/25/17"
+ },
+ "RNT515": {
+ "product_code": "PRD24",
+ "units_rented": 8,
+ "price_per_day": 18,
+ "rental_start": "4/22/18",
+ "rental_end": "9/18/17"
+ },
+ "RNT516": {
+ "product_code": "PRD91",
+ "units_rented": 3,
+ "price_per_day": 28,
+ "rental_start": "3/15/18",
+ "rental_end": "4/15/17"
+ },
+ "RNT517": {
+ "product_code": "PRD74",
+ "units_rented": 5,
+ "price_per_day": 14,
+ "rental_start": "8/17/18",
+ "rental_end": "12/20/16"
+ },
+ "RNT518": {
+ "product_code": "PRD41",
+ "units_rented": 2,
+ "price_per_day": 25,
+ "rental_start": "6/10/18",
+ "rental_end": "9/29/16"
+ },
+ "RNT519": {
+ "product_code": "PRD10",
+ "units_rented": 5,
+ "price_per_day": 7,
+ "rental_start": "8/27/17",
+ "rental_end": "8/28/17"
+ },
+ "RNT520": {
+ "product_code": "PRD96",
+ "units_rented": 6,
+ "price_per_day": 18,
+ "rental_start": "8/15/17",
+ "rental_end": "4/10/17"
+ },
+ "RNT521": {
+ "product_code": "PRD98",
+ "units_rented": 8,
+ "price_per_day": 23,
+ "rental_start": "2/5/17",
+ "rental_end": "9/27/17"
+ },
+ "RNT522": {
+ "product_code": "PRD85",
+ "units_rented": 8,
+ "price_per_day": 15,
+ "rental_start": "5/10/18",
+ "rental_end": "11/22/17"
+ },
+ "RNT523": {
+ "product_code": "PRD53",
+ "units_rented": 9,
+ "price_per_day": 14,
+ "rental_start": "1/23/16",
+ "rental_end": "4/2/16"
+ },
+ "RNT524": {
+ "product_code": "PRD63",
+ "units_rented": 1,
+ "price_per_day": 37,
+ "rental_start": "7/29/18",
+ "rental_end": "3/22/18"
+ },
+ "RNT525": {
+ "product_code": "PRD86",
+ "units_rented": 7,
+ "price_per_day": 34,
+ "rental_start": "2/18/18",
+ "rental_end": "10/26/17"
+ },
+ "RNT526": {
+ "product_code": "PRD2",
+ "units_rented": 3,
+ "price_per_day": 37,
+ "rental_start": "4/24/16",
+ "rental_end": "2/4/18"
+ },
+ "RNT527": {
+ "product_code": "PRD99",
+ "units_rented": 1,
+ "price_per_day": 10,
+ "rental_start": "4/28/16",
+ "rental_end": "1/12/18"
+ },
+ "RNT528": {
+ "product_code": "PRD59",
+ "units_rented": 4,
+ "price_per_day": 28,
+ "rental_start": "5/30/18",
+ "rental_end": "2/6/16"
+ },
+ "RNT529": {
+ "product_code": "PRD96",
+ "units_rented": 9,
+ "price_per_day": 40,
+ "rental_start": "9/12/16",
+ "rental_end": "12/3/16"
+ },
+ "RNT530": {
+ "product_code": "PRD10",
+ "units_rented": 6,
+ "price_per_day": 38,
+ "rental_start": "3/11/16",
+ "rental_end": "7/13/17"
+ },
+ "RNT531": {
+ "product_code": "PRD5",
+ "units_rented": 4,
+ "price_per_day": 19,
+ "rental_start": "10/5/17",
+ "rental_end": "11/26/18"
+ },
+ "RNT532": {
+ "product_code": "PRD81",
+ "units_rented": 10,
+ "price_per_day": 34,
+ "rental_start": "12/7/18",
+ "rental_end": "10/30/17"
+ },
+ "RNT533": {
+ "product_code": "PRD66",
+ "units_rented": 1,
+ "price_per_day": 14,
+ "rental_start": "3/29/18",
+ "rental_end": "12/28/16"
+ },
+ "RNT534": {
+ "product_code": "PRD30",
+ "units_rented": 5,
+ "price_per_day": 11,
+ "rental_start": "6/9/16",
+ "rental_end": "6/24/17"
+ },
+ "RNT535": {
+ "product_code": "PRD79",
+ "units_rented": 7,
+ "price_per_day": 26,
+ "rental_start": "6/5/18",
+ "rental_end": "11/22/16"
+ },
+ "RNT536": {
+ "product_code": "PRD94",
+ "units_rented": 6,
+ "price_per_day": 39,
+ "rental_start": "12/29/18",
+ "rental_end": "7/3/18"
+ },
+ "RNT537": {
+ "product_code": "PRD71",
+ "units_rented": 1,
+ "price_per_day": 36,
+ "rental_start": "6/30/17",
+ "rental_end": "8/29/16"
+ },
+ "RNT538": {
+ "product_code": "PRD5",
+ "units_rented": 10,
+ "price_per_day": 34,
+ "rental_start": "11/24/16",
+ "rental_end": "2/22/16"
+ },
+ "RNT539": {
+ "product_code": "PRD74",
+ "units_rented": 8,
+ "price_per_day": 23,
+ "rental_start": "7/28/17",
+ "rental_end": "7/3/16"
+ },
+ "RNT540": {
+ "product_code": "PRD84",
+ "units_rented": 7,
+ "price_per_day": 34,
+ "rental_start": "11/20/17",
+ "rental_end": "1/11/18"
+ },
+ "RNT541": {
+ "product_code": "PRD54",
+ "units_rented": 7,
+ "price_per_day": 20,
+ "rental_start": "8/12/18",
+ "rental_end": "5/5/16"
+ },
+ "RNT542": {
+ "product_code": "PRD44",
+ "units_rented": 7,
+ "price_per_day": 31,
+ "rental_start": "12/20/17",
+ "rental_end": "11/19/18"
+ },
+ "RNT543": {
+ "product_code": "PRD26",
+ "units_rented": 5,
+ "price_per_day": 14,
+ "rental_start": "2/27/17",
+ "rental_end": "3/4/17"
+ },
+ "RNT544": {
+ "product_code": "PRD53",
+ "units_rented": 2,
+ "price_per_day": 14,
+ "rental_start": "1/9/18",
+ "rental_end": "6/19/17"
+ },
+ "RNT545": {
+ "product_code": "PRD66",
+ "units_rented": 4,
+ "price_per_day": 27,
+ "rental_start": "11/8/18",
+ "rental_end": "9/27/17"
+ },
+ "RNT546": {
+ "product_code": "PRD81",
+ "units_rented": 9,
+ "price_per_day": 37,
+ "rental_start": "11/10/16",
+ "rental_end": "6/16/16"
+ },
+ "RNT547": {
+ "product_code": "PRD28",
+ "units_rented": 3,
+ "price_per_day": 15,
+ "rental_start": "5/28/16",
+ "rental_end": "12/2/17"
+ },
+ "RNT548": {
+ "product_code": "PRD58",
+ "units_rented": 2,
+ "price_per_day": 39,
+ "rental_start": "10/27/18",
+ "rental_end": "10/20/17"
+ },
+ "RNT549": {
+ "product_code": "PRD0",
+ "units_rented": 6,
+ "price_per_day": 28,
+ "rental_start": "7/20/17",
+ "rental_end": "10/14/17"
+ },
+ "RNT550": {
+ "product_code": "PRD40",
+ "units_rented": 7,
+ "price_per_day": 39,
+ "rental_start": "9/5/17",
+ "rental_end": "5/30/16"
+ },
+ "RNT551": {
+ "product_code": "PRD34",
+ "units_rented": 9,
+ "price_per_day": 10,
+ "rental_start": "6/24/18",
+ "rental_end": "8/8/17"
+ },
+ "RNT552": {
+ "product_code": "PRD16",
+ "units_rented": 7,
+ "price_per_day": 27,
+ "rental_start": "1/11/16",
+ "rental_end": "1/6/18"
+ },
+ "RNT553": {
+ "product_code": "PRD75",
+ "units_rented": 4,
+ "price_per_day": 24,
+ "rental_start": "12/17/16",
+ "rental_end": "7/31/17"
+ },
+ "RNT554": {
+ "product_code": "PRD70",
+ "units_rented": 4,
+ "price_per_day": 6,
+ "rental_start": "5/7/16",
+ "rental_end": "3/10/18"
+ },
+ "RNT555": {
+ "product_code": "PRD42",
+ "units_rented": 10,
+ "price_per_day": 40,
+ "rental_start": "6/15/17",
+ "rental_end": "4/15/17"
+ },
+ "RNT556": {
+ "product_code": "PRD81",
+ "units_rented": 1,
+ "price_per_day": 36,
+ "rental_start": "11/23/17",
+ "rental_end": "11/9/18"
+ },
+ "RNT557": {
+ "product_code": "PRD99",
+ "units_rented": 3,
+ "price_per_day": 39,
+ "rental_start": "3/18/16",
+ "rental_end": "7/16/17"
+ },
+ "RNT558": {
+ "product_code": "PRD45",
+ "units_rented": 8,
+ "price_per_day": 28,
+ "rental_start": "9/24/18",
+ "rental_end": "6/10/18"
+ },
+ "RNT559": {
+ "product_code": "PRD82",
+ "units_rented": 7,
+ "price_per_day": 10,
+ "rental_start": "11/25/17",
+ "rental_end": "7/28/18"
+ },
+ "RNT560": {
+ "product_code": "PRD0",
+ "units_rented": 2,
+ "price_per_day": 15,
+ "rental_start": "6/20/16",
+ "rental_end": "1/18/17"
+ },
+ "RNT561": {
+ "product_code": "PRD35",
+ "units_rented": 1,
+ "price_per_day": 30,
+ "rental_start": "7/14/18",
+ "rental_end": "5/15/16"
+ },
+ "RNT562": {
+ "product_code": "PRD9",
+ "units_rented": 7,
+ "price_per_day": 32,
+ "rental_start": "11/18/18",
+ "rental_end": "8/14/18"
+ },
+ "RNT563": {
+ "product_code": "PRD49",
+ "units_rented": 3,
+ "price_per_day": 24,
+ "rental_start": "7/19/17",
+ "rental_end": "6/11/18"
+ },
+ "RNT564": {
+ "product_code": "PRD72",
+ "units_rented": 8,
+ "price_per_day": 17,
+ "rental_start": "7/26/17",
+ "rental_end": "4/11/18"
+ },
+ "RNT565": {
+ "product_code": "PRD37",
+ "units_rented": 6,
+ "price_per_day": 36,
+ "rental_start": "6/4/17",
+ "rental_end": "8/20/17"
+ },
+ "RNT566": {
+ "product_code": "PRD3",
+ "units_rented": 3,
+ "price_per_day": 33,
+ "rental_start": "11/25/18",
+ "rental_end": "2/27/16"
+ },
+ "RNT567": {
+ "product_code": "PRD49",
+ "units_rented": 1,
+ "price_per_day": 28,
+ "rental_start": "11/7/16",
+ "rental_end": "12/2/17"
+ },
+ "RNT568": {
+ "product_code": "PRD85",
+ "units_rented": 1,
+ "price_per_day": 26,
+ "rental_start": "4/17/17",
+ "rental_end": "9/17/18"
+ },
+ "RNT569": {
+ "product_code": "PRD43",
+ "units_rented": 8,
+ "price_per_day": 37,
+ "rental_start": "10/1/18",
+ "rental_end": "5/30/18"
+ },
+ "RNT570": {
+ "product_code": "PRD7",
+ "units_rented": 4,
+ "price_per_day": 38,
+ "rental_start": "11/21/17",
+ "rental_end": "7/13/17"
+ },
+ "RNT571": {
+ "product_code": "PRD40",
+ "units_rented": 5,
+ "price_per_day": 12,
+ "rental_start": "7/3/16",
+ "rental_end": "7/10/16"
+ },
+ "RNT572": {
+ "product_code": "PRD38",
+ "units_rented": 9,
+ "price_per_day": 10,
+ "rental_start": "10/13/18",
+ "rental_end": "8/7/16"
+ },
+ "RNT573": {
+ "product_code": "PRD62",
+ "units_rented": 4,
+ "price_per_day": 23,
+ "rental_start": "2/20/18",
+ "rental_end": "3/12/18"
+ },
+ "RNT574": {
+ "product_code": "PRD13",
+ "units_rented": 2,
+ "price_per_day": 9,
+ "rental_start": "5/18/16",
+ "rental_end": "8/19/18"
+ },
+ "RNT575": {
+ "product_code": "PRD91",
+ "units_rented": 9,
+ "price_per_day": 12,
+ "rental_start": "8/1/17",
+ "rental_end": "1/22/17"
+ },
+ "RNT576": {
+ "product_code": "PRD95",
+ "units_rented": 3,
+ "price_per_day": 39,
+ "rental_start": "10/7/16",
+ "rental_end": "6/9/18"
+ },
+ "RNT577": {
+ "product_code": "PRD89",
+ "units_rented": 8,
+ "price_per_day": 26,
+ "rental_start": "1/6/17",
+ "rental_end": "4/23/18"
+ },
+ "RNT578": {
+ "product_code": "PRD79",
+ "units_rented": 2,
+ "price_per_day": 40,
+ "rental_start": "1/5/16",
+ "rental_end": "3/9/16"
+ },
+ "RNT579": {
+ "product_code": "PRD31",
+ "units_rented": 10,
+ "price_per_day": 26,
+ "rental_start": "7/14/17",
+ "rental_end": "9/5/17"
+ },
+ "RNT580": {
+ "product_code": "PRD81",
+ "units_rented": 9,
+ "price_per_day": 25,
+ "rental_start": "7/2/18",
+ "rental_end": "4/24/17"
+ },
+ "RNT581": {
+ "product_code": "PRD33",
+ "units_rented": 3,
+ "price_per_day": 24,
+ "rental_start": "8/3/16",
+ "rental_end": "5/9/18"
+ },
+ "RNT582": {
+ "product_code": "PRD10",
+ "units_rented": 4,
+ "price_per_day": 35,
+ "rental_start": "5/2/17",
+ "rental_end": "4/28/17"
+ },
+ "RNT583": {
+ "product_code": "PRD3",
+ "units_rented": 1,
+ "price_per_day": 39,
+ "rental_start": "6/15/17",
+ "rental_end": "5/19/18"
+ },
+ "RNT584": {
+ "product_code": "PRD37",
+ "units_rented": 10,
+ "price_per_day": 18,
+ "rental_start": "4/16/16",
+ "rental_end": "10/6/18"
+ },
+ "RNT585": {
+ "product_code": "PRD75",
+ "units_rented": 1,
+ "price_per_day": 16,
+ "rental_start": "2/9/18",
+ "rental_end": "1/15/16"
+ },
+ "RNT586": {
+ "product_code": "PRD73",
+ "units_rented": 4,
+ "price_per_day": 27,
+ "rental_start": "1/27/17",
+ "rental_end": "7/5/16"
+ },
+ "RNT587": {
+ "product_code": "PRD63",
+ "units_rented": 3,
+ "price_per_day": 27,
+ "rental_start": "5/1/18",
+ "rental_end": "3/20/17"
+ },
+ "RNT588": {
+ "product_code": "PRD70",
+ "units_rented": 5,
+ "price_per_day": 6,
+ "rental_start": "5/13/16",
+ "rental_end": "9/23/17"
+ },
+ "RNT589": {
+ "product_code": "PRD60",
+ "units_rented": 10,
+ "price_per_day": 16,
+ "rental_start": "4/3/16",
+ "rental_end": "6/1/16"
+ },
+ "RNT590": {
+ "product_code": "PRD67",
+ "units_rented": 7,
+ "price_per_day": 40,
+ "rental_start": "12/23/18",
+ "rental_end": "6/26/17"
+ },
+ "RNT591": {
+ "product_code": "PRD73",
+ "units_rented": 4,
+ "price_per_day": 22,
+ "rental_start": "6/2/18",
+ "rental_end": "3/21/18"
+ },
+ "RNT592": {
+ "product_code": "PRD1",
+ "units_rented": 4,
+ "price_per_day": 21,
+ "rental_start": "8/26/16",
+ "rental_end": "5/4/16"
+ },
+ "RNT593": {
+ "product_code": "PRD69",
+ "units_rented": 1,
+ "price_per_day": 37,
+ "rental_start": "11/26/16",
+ "rental_end": "9/23/16"
+ },
+ "RNT594": {
+ "product_code": "PRD51",
+ "units_rented": 7,
+ "price_per_day": 30,
+ "rental_start": "5/6/16",
+ "rental_end": "8/21/17"
+ },
+ "RNT595": {
+ "product_code": "PRD24",
+ "units_rented": 5,
+ "price_per_day": 32,
+ "rental_start": "2/23/17",
+ "rental_end": "1/2/16"
+ },
+ "RNT596": {
+ "product_code": "PRD72",
+ "units_rented": 3,
+ "price_per_day": 5,
+ "rental_start": "3/9/17",
+ "rental_end": "10/2/17"
+ },
+ "RNT597": {
+ "product_code": "PRD45",
+ "units_rented": 7,
+ "price_per_day": 37,
+ "rental_start": "10/29/18",
+ "rental_end": "2/21/17"
+ },
+ "RNT598": {
+ "product_code": "PRD48",
+ "units_rented": 7,
+ "price_per_day": 9,
+ "rental_start": "3/2/18",
+ "rental_end": "8/29/16"
+ },
+ "RNT599": {
+ "product_code": "PRD87",
+ "units_rented": 8,
+ "price_per_day": 21,
+ "rental_start": "6/17/18",
+ "rental_end": "2/12/16"
+ },
+ "RNT600": {
+ "product_code": "PRD99",
+ "units_rented": 10,
+ "price_per_day": 25,
+ "rental_start": "10/8/16",
+ "rental_end": "8/20/17"
+ },
+ "RNT601": {
+ "product_code": "PRD71",
+ "units_rented": 5,
+ "price_per_day": 32,
+ "rental_start": "6/12/17",
+ "rental_end": "1/12/17"
+ },
+ "RNT602": {
+ "product_code": "PRD24",
+ "units_rented": 8,
+ "price_per_day": 31,
+ "rental_start": "10/10/16",
+ "rental_end": "4/12/16"
+ },
+ "RNT603": {
+ "product_code": "PRD65",
+ "units_rented": 1,
+ "price_per_day": 9,
+ "rental_start": "9/17/17",
+ "rental_end": "2/7/16"
+ },
+ "RNT604": {
+ "product_code": "PRD72",
+ "units_rented": 6,
+ "price_per_day": 6,
+ "rental_start": "7/14/17",
+ "rental_end": "7/6/16"
+ },
+ "RNT605": {
+ "product_code": "PRD48",
+ "units_rented": 7,
+ "price_per_day": 33,
+ "rental_start": "11/4/17",
+ "rental_end": "9/6/16"
+ },
+ "RNT606": {
+ "product_code": "PRD61",
+ "units_rented": 10,
+ "price_per_day": 39,
+ "rental_start": "10/21/18",
+ "rental_end": "5/31/16"
+ },
+ "RNT607": {
+ "product_code": "PRD83",
+ "units_rented": 2,
+ "price_per_day": 35,
+ "rental_start": "4/12/17",
+ "rental_end": "10/16/18"
+ },
+ "RNT608": {
+ "product_code": "PRD38",
+ "units_rented": 2,
+ "price_per_day": 21,
+ "rental_start": "7/12/16",
+ "rental_end": "7/31/16"
+ },
+ "RNT609": {
+ "product_code": "PRD96",
+ "units_rented": 5,
+ "price_per_day": 18,
+ "rental_start": "1/16/16",
+ "rental_end": "7/24/18"
+ },
+ "RNT610": {
+ "product_code": "PRD94",
+ "units_rented": 9,
+ "price_per_day": 24,
+ "rental_start": "1/23/18",
+ "rental_end": "11/4/18"
+ },
+ "RNT611": {
+ "product_code": "PRD97",
+ "units_rented": 4,
+ "price_per_day": 33,
+ "rental_start": "3/5/18",
+ "rental_end": "1/30/18"
+ },
+ "RNT612": {
+ "product_code": "PRD90",
+ "units_rented": 2,
+ "price_per_day": 32,
+ "rental_start": "12/12/16",
+ "rental_end": "8/29/17"
+ },
+ "RNT613": {
+ "product_code": "PRD99",
+ "units_rented": 10,
+ "price_per_day": 10,
+ "rental_start": "10/4/18",
+ "rental_end": "1/17/18"
+ },
+ "RNT614": {
+ "product_code": "PRD56",
+ "units_rented": 1,
+ "price_per_day": 16,
+ "rental_start": "3/6/18",
+ "rental_end": "12/7/18"
+ },
+ "RNT615": {
+ "product_code": "PRD29",
+ "units_rented": 4,
+ "price_per_day": 40,
+ "rental_start": "9/30/17",
+ "rental_end": "6/29/17"
+ },
+ "RNT616": {
+ "product_code": "PRD99",
+ "units_rented": 2,
+ "price_per_day": 35,
+ "rental_start": "8/24/16",
+ "rental_end": "4/27/17"
+ },
+ "RNT617": {
+ "product_code": "PRD87",
+ "units_rented": 10,
+ "price_per_day": 20,
+ "rental_start": "5/28/17",
+ "rental_end": "4/15/18"
+ },
+ "RNT618": {
+ "product_code": "PRD96",
+ "units_rented": 9,
+ "price_per_day": 38,
+ "rental_start": "7/25/17",
+ "rental_end": "1/3/18"
+ },
+ "RNT619": {
+ "product_code": "PRD30",
+ "units_rented": 6,
+ "price_per_day": 13,
+ "rental_start": "7/24/17",
+ "rental_end": "8/21/17"
+ },
+ "RNT620": {
+ "product_code": "PRD81",
+ "units_rented": 2,
+ "price_per_day": 16,
+ "rental_start": "8/13/16",
+ "rental_end": "1/19/18"
+ },
+ "RNT621": {
+ "product_code": "PRD40",
+ "units_rented": 3,
+ "price_per_day": 39,
+ "rental_start": "4/26/16",
+ "rental_end": "3/15/18"
+ },
+ "RNT622": {
+ "product_code": "PRD40",
+ "units_rented": 3,
+ "price_per_day": 32,
+ "rental_start": "8/22/16",
+ "rental_end": "4/18/16"
+ },
+ "RNT623": {
+ "product_code": "PRD44",
+ "units_rented": 5,
+ "price_per_day": 39,
+ "rental_start": "4/18/16",
+ "rental_end": "6/30/16"
+ },
+ "RNT624": {
+ "product_code": "PRD15",
+ "units_rented": 8,
+ "price_per_day": 34,
+ "rental_start": "1/20/17",
+ "rental_end": "4/2/17"
+ },
+ "RNT625": {
+ "product_code": "PRD7",
+ "units_rented": 10,
+ "price_per_day": 10,
+ "rental_start": "4/15/16",
+ "rental_end": "5/1/16"
+ },
+ "RNT626": {
+ "product_code": "PRD11",
+ "units_rented": 9,
+ "price_per_day": 32,
+ "rental_start": "7/22/18",
+ "rental_end": "8/1/17"
+ },
+ "RNT627": {
+ "product_code": "PRD91",
+ "units_rented": 6,
+ "price_per_day": 21,
+ "rental_start": "8/23/16",
+ "rental_end": "12/31/18"
+ },
+ "RNT628": {
+ "product_code": "PRD81",
+ "units_rented": 3,
+ "price_per_day": 7,
+ "rental_start": "9/1/17",
+ "rental_end": "12/7/18"
+ },
+ "RNT629": {
+ "product_code": "PRD81",
+ "units_rented": 5,
+ "price_per_day": 19,
+ "rental_start": "1/2/17",
+ "rental_end": "8/31/17"
+ },
+ "RNT630": {
+ "product_code": "PRD68",
+ "units_rented": 6,
+ "price_per_day": 37,
+ "rental_start": "11/27/16",
+ "rental_end": "9/15/16"
+ },
+ "RNT631": {
+ "product_code": "PRD68",
+ "units_rented": 8,
+ "price_per_day": 25,
+ "rental_start": "2/8/16",
+ "rental_end": "10/5/18"
+ },
+ "RNT632": {
+ "product_code": "PRD45",
+ "units_rented": 7,
+ "price_per_day": 18,
+ "rental_start": "1/13/16",
+ "rental_end": "1/7/16"
+ },
+ "RNT633": {
+ "product_code": "PRD54",
+ "units_rented": 9,
+ "price_per_day": 6,
+ "rental_start": "7/9/18",
+ "rental_end": "2/1/18"
+ },
+ "RNT634": {
+ "product_code": "PRD99",
+ "units_rented": 9,
+ "price_per_day": 14,
+ "rental_start": "9/16/18",
+ "rental_end": "8/7/18"
+ },
+ "RNT635": {
+ "product_code": "PRD81",
+ "units_rented": 2,
+ "price_per_day": 11,
+ "rental_start": "3/2/16",
+ "rental_end": "1/22/17"
+ },
+ "RNT636": {
+ "product_code": "PRD81",
+ "units_rented": 7,
+ "price_per_day": 38,
+ "rental_start": "11/2/18",
+ "rental_end": "9/15/17"
+ },
+ "RNT637": {
+ "product_code": "PRD85",
+ "units_rented": 1,
+ "price_per_day": 17,
+ "rental_start": "4/24/16",
+ "rental_end": "11/28/17"
+ },
+ "RNT638": {
+ "product_code": "PRD15",
+ "units_rented": 9,
+ "price_per_day": 17,
+ "rental_start": "2/24/17",
+ "rental_end": "3/20/16"
+ },
+ "RNT639": {
+ "product_code": "PRD47",
+ "units_rented": 5,
+ "price_per_day": 23,
+ "rental_start": "12/9/18",
+ "rental_end": "9/10/17"
+ },
+ "RNT640": {
+ "product_code": "PRD35",
+ "units_rented": 6,
+ "price_per_day": 5,
+ "rental_start": "9/9/17",
+ "rental_end": "4/29/16"
+ },
+ "RNT641": {
+ "product_code": "PRD94",
+ "units_rented": 8,
+ "price_per_day": 7,
+ "rental_start": "8/30/16",
+ "rental_end": "5/10/18"
+ },
+ "RNT642": {
+ "product_code": "PRD14",
+ "units_rented": 8,
+ "price_per_day": 28,
+ "rental_start": "7/25/16",
+ "rental_end": "7/3/16"
+ },
+ "RNT643": {
+ "product_code": "PRD59",
+ "units_rented": 7,
+ "price_per_day": 32,
+ "rental_start": "10/20/18",
+ "rental_end": "2/13/16"
+ },
+ "RNT644": {
+ "product_code": "PRD45",
+ "units_rented": 6,
+ "price_per_day": 11,
+ "rental_start": "1/22/18",
+ "rental_end": "2/27/18"
+ },
+ "RNT645": {
+ "product_code": "PRD65",
+ "units_rented": 4,
+ "price_per_day": 29,
+ "rental_start": "12/29/16",
+ "rental_end": "4/12/17"
+ },
+ "RNT646": {
+ "product_code": "PRD8",
+ "units_rented": 5,
+ "price_per_day": 39,
+ "rental_start": "4/13/16",
+ "rental_end": "9/17/18"
+ },
+ "RNT647": {
+ "product_code": "PRD8",
+ "units_rented": 2,
+ "price_per_day": 7,
+ "rental_start": "4/5/17",
+ "rental_end": "9/8/16"
+ },
+ "RNT648": {
+ "product_code": "PRD53",
+ "units_rented": 4,
+ "price_per_day": 11,
+ "rental_start": "7/19/18",
+ "rental_end": "6/26/17"
+ },
+ "RNT649": {
+ "product_code": "PRD64",
+ "units_rented": 9,
+ "price_per_day": 37,
+ "rental_start": "7/17/18",
+ "rental_end": "11/16/17"
+ },
+ "RNT650": {
+ "product_code": "PRD47",
+ "units_rented": 10,
+ "price_per_day": 11,
+ "rental_start": "1/26/16",
+ "rental_end": "6/10/17"
+ },
+ "RNT651": {
+ "product_code": "PRD94",
+ "units_rented": 6,
+ "price_per_day": 5,
+ "rental_start": "9/13/18",
+ "rental_end": "1/27/16"
+ },
+ "RNT652": {
+ "product_code": "PRD46",
+ "units_rented": 3,
+ "price_per_day": 26,
+ "rental_start": "3/13/16",
+ "rental_end": "1/2/17"
+ },
+ "RNT653": {
+ "product_code": "PRD54",
+ "units_rented": 10,
+ "price_per_day": 12,
+ "rental_start": "8/22/17",
+ "rental_end": "3/25/17"
+ },
+ "RNT654": {
+ "product_code": "PRD95",
+ "units_rented": 6,
+ "price_per_day": 10,
+ "rental_start": "5/2/18",
+ "rental_end": "12/31/18"
+ },
+ "RNT655": {
+ "product_code": "PRD3",
+ "units_rented": 1,
+ "price_per_day": 32,
+ "rental_start": "10/20/18",
+ "rental_end": "11/3/18"
+ },
+ "RNT656": {
+ "product_code": "PRD34",
+ "units_rented": 7,
+ "price_per_day": 10,
+ "rental_start": "10/5/18",
+ "rental_end": "7/4/16"
+ },
+ "RNT657": {
+ "product_code": "PRD81",
+ "units_rented": 8,
+ "price_per_day": 26,
+ "rental_start": "8/5/16",
+ "rental_end": "11/15/18"
+ },
+ "RNT658": {
+ "product_code": "PRD96",
+ "units_rented": 5,
+ "price_per_day": 29,
+ "rental_start": "8/9/16",
+ "rental_end": "11/27/18"
+ },
+ "RNT659": {
+ "product_code": "PRD9",
+ "units_rented": 10,
+ "price_per_day": 23,
+ "rental_start": "9/14/18",
+ "rental_end": "9/6/17"
+ },
+ "RNT660": {
+ "product_code": "PRD89",
+ "units_rented": 1,
+ "price_per_day": 37,
+ "rental_start": "2/15/16",
+ "rental_end": "12/18/16"
+ },
+ "RNT661": {
+ "product_code": "PRD56",
+ "units_rented": 7,
+ "price_per_day": 37,
+ "rental_start": "2/5/18",
+ "rental_end": "7/18/18"
+ },
+ "RNT662": {
+ "product_code": "PRD12",
+ "units_rented": 5,
+ "price_per_day": 30,
+ "rental_start": "4/27/18",
+ "rental_end": "2/13/18"
+ },
+ "RNT663": {
+ "product_code": "PRD85",
+ "units_rented": 8,
+ "price_per_day": 34,
+ "rental_start": "1/3/18",
+ "rental_end": "1/20/17"
+ },
+ "RNT664": {
+ "product_code": "PRD4",
+ "units_rented": 3,
+ "price_per_day": 11,
+ "rental_start": "7/2/18",
+ "rental_end": "8/20/16"
+ },
+ "RNT665": {
+ "product_code": "PRD78",
+ "units_rented": 5,
+ "price_per_day": 21,
+ "rental_start": "9/8/17",
+ "rental_end": "2/4/17"
+ },
+ "RNT666": {
+ "product_code": "PRD75",
+ "units_rented": 6,
+ "price_per_day": 22,
+ "rental_start": "11/21/16",
+ "rental_end": "9/1/17"
+ },
+ "RNT667": {
+ "product_code": "PRD30",
+ "units_rented": 2,
+ "price_per_day": 25,
+ "rental_start": "1/4/18",
+ "rental_end": "3/31/16"
+ },
+ "RNT668": {
+ "product_code": "PRD85",
+ "units_rented": 6,
+ "price_per_day": 17,
+ "rental_start": "2/17/16",
+ "rental_end": "1/1/16"
+ },
+ "RNT669": {
+ "product_code": "PRD43",
+ "units_rented": 3,
+ "price_per_day": 38,
+ "rental_start": "7/28/18",
+ "rental_end": "12/16/18"
+ },
+ "RNT670": {
+ "product_code": "PRD65",
+ "units_rented": 5,
+ "price_per_day": 20,
+ "rental_start": "11/27/16",
+ "rental_end": "1/30/16"
+ },
+ "RNT671": {
+ "product_code": "PRD51",
+ "units_rented": 6,
+ "price_per_day": 21,
+ "rental_start": "3/5/18",
+ "rental_end": "6/16/17"
+ },
+ "RNT672": {
+ "product_code": "PRD64",
+ "units_rented": 10,
+ "price_per_day": 14,
+ "rental_start": "6/16/16",
+ "rental_end": "4/9/18"
+ },
+ "RNT673": {
+ "product_code": "PRD88",
+ "units_rented": 3,
+ "price_per_day": 9,
+ "rental_start": "1/31/16",
+ "rental_end": "10/4/16"
+ },
+ "RNT674": {
+ "product_code": "PRD56",
+ "units_rented": 8,
+ "price_per_day": 25,
+ "rental_start": "7/24/18",
+ "rental_end": "4/24/17"
+ },
+ "RNT675": {
+ "product_code": "PRD48",
+ "units_rented": 5,
+ "price_per_day": 18,
+ "rental_start": "2/19/18",
+ "rental_end": "2/22/18"
+ },
+ "RNT676": {
+ "product_code": "PRD46",
+ "units_rented": 3,
+ "price_per_day": 20,
+ "rental_start": "10/13/17",
+ "rental_end": "11/7/18"
+ },
+ "RNT677": {
+ "product_code": "PRD69",
+ "units_rented": 10,
+ "price_per_day": 40,
+ "rental_start": "9/3/17",
+ "rental_end": "8/17/17"
+ },
+ "RNT678": {
+ "product_code": "PRD44",
+ "units_rented": 8,
+ "price_per_day": 25,
+ "rental_start": "11/27/16",
+ "rental_end": "11/13/16"
+ },
+ "RNT679": {
+ "product_code": "PRD26",
+ "units_rented": 5,
+ "price_per_day": 29,
+ "rental_start": "11/21/17",
+ "rental_end": "2/3/16"
+ },
+ "RNT680": {
+ "product_code": "PRD21",
+ "units_rented": 4,
+ "price_per_day": 33,
+ "rental_start": "12/28/16",
+ "rental_end": "12/3/18"
+ },
+ "RNT681": {
+ "product_code": "PRD70",
+ "units_rented": 1,
+ "price_per_day": 40,
+ "rental_start": "4/29/16",
+ "rental_end": "9/19/18"
+ },
+ "RNT682": {
+ "product_code": "PRD68",
+ "units_rented": 10,
+ "price_per_day": 29,
+ "rental_start": "12/31/18",
+ "rental_end": "10/19/18"
+ },
+ "RNT683": {
+ "product_code": "PRD17",
+ "units_rented": 4,
+ "price_per_day": 17,
+ "rental_start": "1/10/17",
+ "rental_end": "4/12/18"
+ },
+ "RNT684": {
+ "product_code": "PRD74",
+ "units_rented": 3,
+ "price_per_day": 25,
+ "rental_start": "6/26/17",
+ "rental_end": "4/3/16"
+ },
+ "RNT685": {
+ "product_code": "PRD17",
+ "units_rented": 6,
+ "price_per_day": 25,
+ "rental_start": "2/24/17",
+ "rental_end": "3/3/17"
+ },
+ "RNT686": {
+ "product_code": "PRD81",
+ "units_rented": 9,
+ "price_per_day": 34,
+ "rental_start": "12/21/16",
+ "rental_end": "10/28/18"
+ },
+ "RNT687": {
+ "product_code": "PRD37",
+ "units_rented": 8,
+ "price_per_day": 33,
+ "rental_start": "5/8/18",
+ "rental_end": "5/30/18"
+ },
+ "RNT688": {
+ "product_code": "PRD74",
+ "units_rented": 6,
+ "price_per_day": 7,
+ "rental_start": "7/6/18",
+ "rental_end": "6/2/18"
+ },
+ "RNT689": {
+ "product_code": "PRD1",
+ "units_rented": 4,
+ "price_per_day": 19,
+ "rental_start": "10/19/16",
+ "rental_end": "12/20/16"
+ },
+ "RNT690": {
+ "product_code": "PRD30",
+ "units_rented": 1,
+ "price_per_day": 37,
+ "rental_start": "12/20/17",
+ "rental_end": "6/15/18"
+ },
+ "RNT691": {
+ "product_code": "PRD84",
+ "units_rented": 5,
+ "price_per_day": 36,
+ "rental_start": "9/19/18",
+ "rental_end": "9/10/16"
+ },
+ "RNT692": {
+ "product_code": "PRD50",
+ "units_rented": 10,
+ "price_per_day": 18,
+ "rental_start": "8/27/17",
+ "rental_end": "7/29/17"
+ },
+ "RNT693": {
+ "product_code": "PRD80",
+ "units_rented": 3,
+ "price_per_day": 5,
+ "rental_start": "5/16/16",
+ "rental_end": "4/12/18"
+ },
+ "RNT694": {
+ "product_code": "PRD12",
+ "units_rented": 9,
+ "price_per_day": 26,
+ "rental_start": "12/9/18",
+ "rental_end": "9/15/17"
+ },
+ "RNT695": {
+ "product_code": "PRD47",
+ "units_rented": 5,
+ "price_per_day": 25,
+ "rental_start": "7/14/16",
+ "rental_end": "3/5/16"
+ },
+ "RNT696": {
+ "product_code": "PRD12",
+ "units_rented": 2,
+ "price_per_day": 39,
+ "rental_start": "11/17/17",
+ "rental_end": "5/18/18"
+ },
+ "RNT697": {
+ "product_code": "PRD24",
+ "units_rented": 4,
+ "price_per_day": 32,
+ "rental_start": "11/28/17",
+ "rental_end": "8/21/18"
+ },
+ "RNT698": {
+ "product_code": "PRD69",
+ "units_rented": 1,
+ "price_per_day": 38,
+ "rental_start": "4/2/18",
+ "rental_end": "11/22/16"
+ },
+ "RNT699": {
+ "product_code": "PRD66",
+ "units_rented": 4,
+ "price_per_day": 6,
+ "rental_start": "6/7/18",
+ "rental_end": "7/24/18"
+ },
+ "RNT700": {
+ "product_code": "PRD44",
+ "units_rented": 4,
+ "price_per_day": 28,
+ "rental_start": "6/1/16",
+ "rental_end": "10/27/18"
+ },
+ "RNT701": {
+ "product_code": "PRD42",
+ "units_rented": 5,
+ "price_per_day": 22,
+ "rental_start": "10/24/17",
+ "rental_end": "10/11/18"
+ },
+ "RNT702": {
+ "product_code": "PRD88",
+ "units_rented": 6,
+ "price_per_day": 15,
+ "rental_start": "9/26/17",
+ "rental_end": "12/8/16"
+ },
+ "RNT703": {
+ "product_code": "PRD41",
+ "units_rented": 6,
+ "price_per_day": 9,
+ "rental_start": "6/15/18",
+ "rental_end": "3/1/18"
+ },
+ "RNT704": {
+ "product_code": "PRD6",
+ "units_rented": 4,
+ "price_per_day": 19,
+ "rental_start": "12/23/17",
+ "rental_end": "4/2/16"
+ },
+ "RNT705": {
+ "product_code": "PRD74",
+ "units_rented": 5,
+ "price_per_day": 12,
+ "rental_start": "2/25/17",
+ "rental_end": "6/23/17"
+ },
+ "RNT706": {
+ "product_code": "PRD59",
+ "units_rented": 5,
+ "price_per_day": 20,
+ "rental_start": "9/8/17",
+ "rental_end": "5/17/17"
+ },
+ "RNT707": {
+ "product_code": "PRD13",
+ "units_rented": 9,
+ "price_per_day": 24,
+ "rental_start": "4/10/16",
+ "rental_end": "10/13/18"
+ },
+ "RNT708": {
+ "product_code": "PRD28",
+ "units_rented": 7,
+ "price_per_day": 16,
+ "rental_start": "7/29/16",
+ "rental_end": "1/15/17"
+ },
+ "RNT709": {
+ "product_code": "PRD26",
+ "units_rented": 9,
+ "price_per_day": 12,
+ "rental_start": "5/18/17",
+ "rental_end": "1/15/17"
+ },
+ "RNT710": {
+ "product_code": "PRD58",
+ "units_rented": 3,
+ "price_per_day": 21,
+ "rental_start": "11/17/16",
+ "rental_end": "12/29/18"
+ },
+ "RNT711": {
+ "product_code": "PRD41",
+ "units_rented": 1,
+ "price_per_day": 9,
+ "rental_start": "4/25/18",
+ "rental_end": "4/25/17"
+ },
+ "RNT712": {
+ "product_code": "PRD74",
+ "units_rented": 3,
+ "price_per_day": 10,
+ "rental_start": "10/9/17",
+ "rental_end": "8/8/16"
+ },
+ "RNT713": {
+ "product_code": "PRD11",
+ "units_rented": 2,
+ "price_per_day": 14,
+ "rental_start": "9/3/18",
+ "rental_end": "11/27/18"
+ },
+ "RNT714": {
+ "product_code": "PRD18",
+ "units_rented": 4,
+ "price_per_day": 27,
+ "rental_start": "4/9/16",
+ "rental_end": "10/18/17"
+ },
+ "RNT715": {
+ "product_code": "PRD78",
+ "units_rented": 3,
+ "price_per_day": 27,
+ "rental_start": "8/23/17",
+ "rental_end": "6/23/16"
+ },
+ "RNT716": {
+ "product_code": "PRD12",
+ "units_rented": 6,
+ "price_per_day": 22,
+ "rental_start": "9/16/16",
+ "rental_end": "11/27/16"
+ },
+ "RNT717": {
+ "product_code": "PRD90",
+ "units_rented": 3,
+ "price_per_day": 31,
+ "rental_start": "9/25/18",
+ "rental_end": "1/12/16"
+ },
+ "RNT718": {
+ "product_code": "PRD87",
+ "units_rented": 5,
+ "price_per_day": 19,
+ "rental_start": "3/25/18",
+ "rental_end": "4/26/18"
+ },
+ "RNT719": {
+ "product_code": "PRD18",
+ "units_rented": 6,
+ "price_per_day": 24,
+ "rental_start": "9/22/16",
+ "rental_end": "4/5/16"
+ },
+ "RNT720": {
+ "product_code": "PRD58",
+ "units_rented": 6,
+ "price_per_day": 36,
+ "rental_start": "1/29/16",
+ "rental_end": "4/18/18"
+ },
+ "RNT721": {
+ "product_code": "PRD58",
+ "units_rented": 2,
+ "price_per_day": 28,
+ "rental_start": "9/2/18",
+ "rental_end": "2/13/18"
+ },
+ "RNT722": {
+ "product_code": "PRD24",
+ "units_rented": 8,
+ "price_per_day": 22,
+ "rental_start": "10/6/17",
+ "rental_end": "3/8/16"
+ },
+ "RNT723": {
+ "product_code": "PRD46",
+ "units_rented": 8,
+ "price_per_day": 28,
+ "rental_start": "2/13/16",
+ "rental_end": "3/8/17"
+ },
+ "RNT724": {
+ "product_code": "PRD82",
+ "units_rented": 9,
+ "price_per_day": 11,
+ "rental_start": "1/3/16",
+ "rental_end": "10/29/18"
+ },
+ "RNT725": {
+ "product_code": "PRD71",
+ "units_rented": 7,
+ "price_per_day": 32,
+ "rental_start": "2/19/17",
+ "rental_end": "11/17/16"
+ },
+ "RNT726": {
+ "product_code": "PRD22",
+ "units_rented": 2,
+ "price_per_day": 39,
+ "rental_start": "11/24/17",
+ "rental_end": "5/6/16"
+ },
+ "RNT727": {
+ "product_code": "PRD69",
+ "units_rented": 9,
+ "price_per_day": 24,
+ "rental_start": "1/18/17",
+ "rental_end": "7/15/18"
+ },
+ "RNT728": {
+ "product_code": "PRD48",
+ "units_rented": 7,
+ "price_per_day": 20,
+ "rental_start": "7/27/17",
+ "rental_end": "7/23/18"
+ },
+ "RNT729": {
+ "product_code": "PRD16",
+ "units_rented": 3,
+ "price_per_day": 39,
+ "rental_start": "8/18/17",
+ "rental_end": "4/23/17"
+ },
+ "RNT730": {
+ "product_code": "PRD18",
+ "units_rented": 4,
+ "price_per_day": 16,
+ "rental_start": "12/20/16",
+ "rental_end": "8/23/18"
+ },
+ "RNT731": {
+ "product_code": "PRD30",
+ "units_rented": 1,
+ "price_per_day": 10,
+ "rental_start": "11/17/17",
+ "rental_end": "9/2/17"
+ },
+ "RNT732": {
+ "product_code": "PRD96",
+ "units_rented": 5,
+ "price_per_day": 35,
+ "rental_start": "8/18/17",
+ "rental_end": "11/24/16"
+ },
+ "RNT733": {
+ "product_code": "PRD40",
+ "units_rented": 1,
+ "price_per_day": 32,
+ "rental_start": "5/26/17",
+ "rental_end": "11/5/16"
+ },
+ "RNT734": {
+ "product_code": "PRD4",
+ "units_rented": 9,
+ "price_per_day": 27,
+ "rental_start": "4/3/16",
+ "rental_end": "10/25/17"
+ },
+ "RNT735": {
+ "product_code": "PRD22",
+ "units_rented": 8,
+ "price_per_day": 37,
+ "rental_start": "1/15/18",
+ "rental_end": "11/3/18"
+ },
+ "RNT736": {
+ "product_code": "PRD31",
+ "units_rented": 10,
+ "price_per_day": 37,
+ "rental_start": "4/13/16",
+ "rental_end": "6/9/17"
+ },
+ "RNT737": {
+ "product_code": "PRD92",
+ "units_rented": 1,
+ "price_per_day": 20,
+ "rental_start": "1/4/16",
+ "rental_end": "12/6/16"
+ },
+ "RNT738": {
+ "product_code": "PRD59",
+ "units_rented": 4,
+ "price_per_day": 11,
+ "rental_start": "11/3/16",
+ "rental_end": "7/1/17"
+ },
+ "RNT739": {
+ "product_code": "PRD73",
+ "units_rented": 5,
+ "price_per_day": 37,
+ "rental_start": "9/18/17",
+ "rental_end": "6/2/18"
+ },
+ "RNT740": {
+ "product_code": "PRD81",
+ "units_rented": 7,
+ "price_per_day": 32,
+ "rental_start": "2/16/18",
+ "rental_end": "10/13/17"
+ },
+ "RNT741": {
+ "product_code": "PRD1",
+ "units_rented": 3,
+ "price_per_day": 6,
+ "rental_start": "4/21/16",
+ "rental_end": "2/7/18"
+ },
+ "RNT742": {
+ "product_code": "PRD9",
+ "units_rented": 4,
+ "price_per_day": 26,
+ "rental_start": "4/24/16",
+ "rental_end": "8/21/17"
+ },
+ "RNT743": {
+ "product_code": "PRD44",
+ "units_rented": 10,
+ "price_per_day": 32,
+ "rental_start": "6/28/16",
+ "rental_end": "12/22/18"
+ },
+ "RNT744": {
+ "product_code": "PRD39",
+ "units_rented": 1,
+ "price_per_day": 15,
+ "rental_start": "4/28/16",
+ "rental_end": "8/27/17"
+ },
+ "RNT745": {
+ "product_code": "PRD36",
+ "units_rented": 6,
+ "price_per_day": 21,
+ "rental_start": "9/2/18",
+ "rental_end": "10/18/17"
+ },
+ "RNT746": {
+ "product_code": "PRD40",
+ "units_rented": 5,
+ "price_per_day": 28,
+ "rental_start": "10/16/17",
+ "rental_end": "8/8/17"
+ },
+ "RNT747": {
+ "product_code": "PRD65",
+ "units_rented": 3,
+ "price_per_day": 22,
+ "rental_start": "7/1/16",
+ "rental_end": "4/11/18"
+ },
+ "RNT748": {
+ "product_code": "PRD91",
+ "units_rented": 3,
+ "price_per_day": 7,
+ "rental_start": "9/14/17",
+ "rental_end": "3/30/17"
+ },
+ "RNT749": {
+ "product_code": "PRD70",
+ "units_rented": 4,
+ "price_per_day": 36,
+ "rental_start": "7/6/17",
+ "rental_end": "1/11/18"
+ },
+ "RNT750": {
+ "product_code": "PRD67",
+ "units_rented": 1,
+ "price_per_day": 40,
+ "rental_start": "1/6/17",
+ "rental_end": "8/22/16"
+ },
+ "RNT751": {
+ "product_code": "PRD2",
+ "units_rented": 4,
+ "price_per_day": 33,
+ "rental_start": "12/9/17",
+ "rental_end": "5/20/17"
+ },
+ "RNT752": {
+ "product_code": "PRD1",
+ "units_rented": 6,
+ "price_per_day": 34,
+ "rental_start": "5/21/17",
+ "rental_end": "10/29/18"
+ },
+ "RNT753": {
+ "product_code": "PRD81",
+ "units_rented": 10,
+ "price_per_day": 25,
+ "rental_start": "9/19/18",
+ "rental_end": "7/10/18"
+ },
+ "RNT754": {
+ "product_code": "PRD80",
+ "units_rented": 10,
+ "price_per_day": 22,
+ "rental_start": "3/28/17",
+ "rental_end": "9/18/18"
+ },
+ "RNT755": {
+ "product_code": "PRD28",
+ "units_rented": 7,
+ "price_per_day": 8,
+ "rental_start": "2/4/16",
+ "rental_end": "3/30/17"
+ },
+ "RNT756": {
+ "product_code": "PRD44",
+ "units_rented": 6,
+ "price_per_day": 14,
+ "rental_start": "12/3/17",
+ "rental_end": "7/14/17"
+ },
+ "RNT757": {
+ "product_code": "PRD52",
+ "units_rented": 1,
+ "price_per_day": 14,
+ "rental_start": "12/13/18",
+ "rental_end": "7/6/18"
+ },
+ "RNT758": {
+ "product_code": "PRD34",
+ "units_rented": 1,
+ "price_per_day": 19,
+ "rental_start": "11/21/16",
+ "rental_end": "8/31/17"
+ },
+ "RNT759": {
+ "product_code": "PRD53",
+ "units_rented": 5,
+ "price_per_day": 11,
+ "rental_start": "2/10/18",
+ "rental_end": "1/5/16"
+ },
+ "RNT760": {
+ "product_code": "PRD11",
+ "units_rented": 7,
+ "price_per_day": 14,
+ "rental_start": "11/23/16",
+ "rental_end": "5/9/18"
+ },
+ "RNT761": {
+ "product_code": "PRD2",
+ "units_rented": 5,
+ "price_per_day": 40,
+ "rental_start": "3/21/16",
+ "rental_end": "11/27/17"
+ },
+ "RNT762": {
+ "product_code": "PRD78",
+ "units_rented": 8,
+ "price_per_day": 26,
+ "rental_start": "8/1/16",
+ "rental_end": "3/2/17"
+ },
+ "RNT763": {
+ "product_code": "PRD43",
+ "units_rented": 7,
+ "price_per_day": 31,
+ "rental_start": "1/10/18",
+ "rental_end": "5/21/18"
+ },
+ "RNT764": {
+ "product_code": "PRD26",
+ "units_rented": 5,
+ "price_per_day": 13,
+ "rental_start": "9/13/16",
+ "rental_end": "2/2/18"
+ },
+ "RNT765": {
+ "product_code": "PRD25",
+ "units_rented": 6,
+ "price_per_day": 10,
+ "rental_start": "9/13/16",
+ "rental_end": "4/28/17"
+ },
+ "RNT766": {
+ "product_code": "PRD86",
+ "units_rented": 4,
+ "price_per_day": 25,
+ "rental_start": "3/15/18",
+ "rental_end": "7/28/17"
+ },
+ "RNT767": {
+ "product_code": "PRD29",
+ "units_rented": 10,
+ "price_per_day": 23,
+ "rental_start": "9/25/16",
+ "rental_end": "3/2/18"
+ },
+ "RNT768": {
+ "product_code": "PRD68",
+ "units_rented": 1,
+ "price_per_day": 10,
+ "rental_start": "3/8/17",
+ "rental_end": "9/5/18"
+ },
+ "RNT769": {
+ "product_code": "PRD51",
+ "units_rented": 4,
+ "price_per_day": 28,
+ "rental_start": "11/12/17",
+ "rental_end": "11/18/18"
+ },
+ "RNT770": {
+ "product_code": "PRD83",
+ "units_rented": 7,
+ "price_per_day": 36,
+ "rental_start": "12/2/18",
+ "rental_end": "1/6/16"
+ },
+ "RNT771": {
+ "product_code": "PRD65",
+ "units_rented": 9,
+ "price_per_day": 17,
+ "rental_start": "5/4/16",
+ "rental_end": "6/12/16"
+ },
+ "RNT772": {
+ "product_code": "PRD71",
+ "units_rented": 7,
+ "price_per_day": 20,
+ "rental_start": "6/18/18",
+ "rental_end": "2/21/18"
+ },
+ "RNT773": {
+ "product_code": "PRD14",
+ "units_rented": 4,
+ "price_per_day": 24,
+ "rental_start": "10/23/16",
+ "rental_end": "10/13/16"
+ },
+ "RNT774": {
+ "product_code": "PRD30",
+ "units_rented": 1,
+ "price_per_day": 36,
+ "rental_start": "7/13/18",
+ "rental_end": "12/28/16"
+ },
+ "RNT775": {
+ "product_code": "PRD2",
+ "units_rented": 3,
+ "price_per_day": 36,
+ "rental_start": "4/20/17",
+ "rental_end": "10/10/18"
+ },
+ "RNT776": {
+ "product_code": "PRD70",
+ "units_rented": 1,
+ "price_per_day": 14,
+ "rental_start": "6/19/16",
+ "rental_end": ""
+ },
+ "RNT777": {
+ "product_code": "PRD15",
+ "units_rented": 9,
+ "price_per_day": 39,
+ "rental_start": "8/11/17",
+ "rental_end": "10/7/18"
+ },
+ "RNT778": {
+ "product_code": "PRD65",
+ "units_rented": 5,
+ "price_per_day": 39,
+ "rental_start": "1/13/18",
+ "rental_end": "1/3/17"
+ },
+ "RNT779": {
+ "product_code": "PRD37",
+ "units_rented": 5,
+ "price_per_day": 23,
+ "rental_start": "1/31/17",
+ "rental_end": "8/21/16"
+ },
+ "RNT780": {
+ "product_code": "PRD67",
+ "units_rented": 7,
+ "price_per_day": 21,
+ "rental_start": "8/21/18",
+ "rental_end": "10/5/18"
+ },
+ "RNT781": {
+ "product_code": "PRD61",
+ "units_rented": 9,
+ "price_per_day": 26,
+ "rental_start": "1/31/16",
+ "rental_end": "7/19/17"
+ },
+ "RNT782": {
+ "product_code": "PRD14",
+ "units_rented": 10,
+ "price_per_day": 22,
+ "rental_start": "1/25/18",
+ "rental_end": "4/16/17"
+ },
+ "RNT783": {
+ "product_code": "PRD98",
+ "units_rented": 10,
+ "price_per_day": 13,
+ "rental_start": "11/27/18",
+ "rental_end": "3/22/17"
+ },
+ "RNT784": {
+ "product_code": "PRD53",
+ "units_rented": 5,
+ "price_per_day": 31,
+ "rental_start": "12/31/17",
+ "rental_end": "7/7/18"
+ },
+ "RNT785": {
+ "product_code": "PRD15",
+ "units_rented": 5,
+ "price_per_day": 28,
+ "rental_start": "7/31/18",
+ "rental_end": "12/20/18"
+ },
+ "RNT786": {
+ "product_code": "PRD79",
+ "units_rented": 7,
+ "price_per_day": 14,
+ "rental_start": "12/1/16",
+ "rental_end": "2/25/18"
+ },
+ "RNT787": {
+ "product_code": "PRD31",
+ "units_rented": 10,
+ "price_per_day": 6,
+ "rental_start": "10/14/17",
+ "rental_end": "2/15/18"
+ },
+ "RNT788": {
+ "product_code": "PRD10",
+ "units_rented": 4,
+ "price_per_day": 27,
+ "rental_start": "2/24/16",
+ "rental_end": "7/31/16"
+ },
+ "RNT789": {
+ "product_code": "PRD7",
+ "units_rented": 7,
+ "price_per_day": 26,
+ "rental_start": "4/10/18",
+ "rental_end": "6/4/18"
+ },
+ "RNT790": {
+ "product_code": "PRD55",
+ "units_rented": 7,
+ "price_per_day": 11,
+ "rental_start": "3/30/17",
+ "rental_end": "2/24/16"
+ },
+ "RNT791": {
+ "product_code": "PRD92",
+ "units_rented": 9,
+ "price_per_day": 27,
+ "rental_start": "3/18/18",
+ "rental_end": "6/3/17"
+ },
+ "RNT792": {
+ "product_code": "PRD82",
+ "units_rented": 1,
+ "price_per_day": 13,
+ "rental_start": "12/24/17",
+ "rental_end": "12/8/18"
+ },
+ "RNT793": {
+ "product_code": "PRD55",
+ "units_rented": 1,
+ "price_per_day": 22,
+ "rental_start": "1/16/16",
+ "rental_end": "2/7/16"
+ },
+ "RNT794": {
+ "product_code": "PRD54",
+ "units_rented": 5,
+ "price_per_day": 39,
+ "rental_start": "12/30/18",
+ "rental_end": "4/30/16"
+ },
+ "RNT795": {
+ "product_code": "PRD83",
+ "units_rented": 8,
+ "price_per_day": 19,
+ "rental_start": "1/25/18",
+ "rental_end": "9/15/17"
+ },
+ "RNT796": {
+ "product_code": "PRD90",
+ "units_rented": 10,
+ "price_per_day": 32,
+ "rental_start": "1/13/18",
+ "rental_end": "6/8/17"
+ },
+ "RNT797": {
+ "product_code": "PRD56",
+ "units_rented": 5,
+ "price_per_day": 13,
+ "rental_start": "2/2/16",
+ "rental_end": "2/6/17"
+ },
+ "RNT798": {
+ "product_code": "PRD58",
+ "units_rented": 7,
+ "price_per_day": 36,
+ "rental_start": "10/9/16",
+ "rental_end": "9/5/18"
+ },
+ "RNT799": {
+ "product_code": "PRD23",
+ "units_rented": 2,
+ "price_per_day": 33,
+ "rental_start": "3/12/17",
+ "rental_end": "4/22/18"
+ },
+ "RNT800": {
+ "product_code": "PRD66",
+ "units_rented": 3,
+ "price_per_day": 25,
+ "rental_start": "5/15/16",
+ "rental_end": "3/13/18"
+ },
+ "RNT801": {
+ "product_code": "PRD54",
+ "units_rented": 8,
+ "price_per_day": 34,
+ "rental_start": "6/25/17",
+ "rental_end": "5/19/18"
+ },
+ "RNT802": {
+ "product_code": "PRD37",
+ "units_rented": 10,
+ "price_per_day": 9,
+ "rental_start": "4/17/17",
+ "rental_end": "12/13/17"
+ },
+ "RNT803": {
+ "product_code": "PRD32",
+ "units_rented": 10,
+ "price_per_day": 5,
+ "rental_start": "10/17/16",
+ "rental_end": "2/10/16"
+ },
+ "RNT804": {
+ "product_code": "PRD19",
+ "units_rented": 2,
+ "price_per_day": 38,
+ "rental_start": "9/30/16",
+ "rental_end": "4/8/17"
+ },
+ "RNT805": {
+ "product_code": "PRD41",
+ "units_rented": 9,
+ "price_per_day": 8,
+ "rental_start": "3/8/18",
+ "rental_end": "4/24/18"
+ },
+ "RNT806": {
+ "product_code": "PRD9",
+ "units_rented": 3,
+ "price_per_day": 32,
+ "rental_start": "10/24/16",
+ "rental_end": "11/2/16"
+ },
+ "RNT807": {
+ "product_code": "PRD12",
+ "units_rented": 7,
+ "price_per_day": 26,
+ "rental_start": "4/3/18",
+ "rental_end": "7/19/17"
+ },
+ "RNT808": {
+ "product_code": "PRD67",
+ "units_rented": 9,
+ "price_per_day": 10,
+ "rental_start": "7/25/17",
+ "rental_end": "12/15/16"
+ },
+ "RNT809": {
+ "product_code": "PRD18",
+ "units_rented": 3,
+ "price_per_day": 17,
+ "rental_start": "12/4/17",
+ "rental_end": "4/7/17"
+ },
+ "RNT810": {
+ "product_code": "PRD47",
+ "units_rented": 7,
+ "price_per_day": 29,
+ "rental_start": "9/3/16",
+ "rental_end": "10/26/18"
+ },
+ "RNT811": {
+ "product_code": "PRD92",
+ "units_rented": 2,
+ "price_per_day": 14,
+ "rental_start": "1/23/16",
+ "rental_end": "10/25/16"
+ },
+ "RNT812": {
+ "product_code": "PRD23",
+ "units_rented": 8,
+ "price_per_day": 26,
+ "rental_start": "10/25/16",
+ "rental_end": "8/18/16"
+ },
+ "RNT813": {
+ "product_code": "PRD11",
+ "units_rented": 9,
+ "price_per_day": 8,
+ "rental_start": "6/6/16",
+ "rental_end": "12/14/18"
+ },
+ "RNT814": {
+ "product_code": "PRD32",
+ "units_rented": 5,
+ "price_per_day": 38,
+ "rental_start": "5/16/18",
+ "rental_end": "5/3/17"
+ },
+ "RNT815": {
+ "product_code": "PRD58",
+ "units_rented": 7,
+ "price_per_day": 39,
+ "rental_start": "11/29/17",
+ "rental_end": "3/26/17"
+ },
+ "RNT816": {
+ "product_code": "PRD72",
+ "units_rented": 8,
+ "price_per_day": 8,
+ "rental_start": "12/20/17",
+ "rental_end": "7/6/17"
+ },
+ "RNT817": {
+ "product_code": "PRD66",
+ "units_rented": 7,
+ "price_per_day": 36,
+ "rental_start": "11/27/18",
+ "rental_end": "2/11/16"
+ },
+ "RNT818": {
+ "product_code": "PRD36",
+ "units_rented": 10,
+ "price_per_day": 40,
+ "rental_start": "11/13/17",
+ "rental_end": "5/13/16"
+ },
+ "RNT819": {
+ "product_code": "PRD84",
+ "units_rented": 7,
+ "price_per_day": 20,
+ "rental_start": "12/7/17",
+ "rental_end": "9/25/17"
+ },
+ "RNT820": {
+ "product_code": "PRD97",
+ "units_rented": 2,
+ "price_per_day": 10,
+ "rental_start": "5/3/16",
+ "rental_end": "4/25/16"
+ },
+ "RNT821": {
+ "product_code": "PRD79",
+ "units_rented": 8,
+ "price_per_day": 9,
+ "rental_start": "3/29/17",
+ "rental_end": "10/12/18"
+ },
+ "RNT822": {
+ "product_code": "PRD26",
+ "units_rented": 9,
+ "price_per_day": 22,
+ "rental_start": "12/15/17",
+ "rental_end": "8/11/17"
+ },
+ "RNT823": {
+ "product_code": "PRD98",
+ "units_rented": 7,
+ "price_per_day": 5,
+ "rental_start": "1/12/17",
+ "rental_end": "9/15/17"
+ },
+ "RNT824": {
+ "product_code": "PRD86",
+ "units_rented": 6,
+ "price_per_day": 27,
+ "rental_start": "2/5/16",
+ "rental_end": "10/23/17"
+ },
+ "RNT825": {
+ "product_code": "PRD67",
+ "units_rented": 7,
+ "price_per_day": 19,
+ "rental_start": "3/18/18",
+ "rental_end": "11/25/17"
+ },
+ "RNT826": {
+ "product_code": "PRD61",
+ "units_rented": 6,
+ "price_per_day": 11,
+ "rental_start": "3/6/17",
+ "rental_end": "4/2/18"
+ },
+ "RNT827": {
+ "product_code": "PRD64",
+ "units_rented": 10,
+ "price_per_day": 9,
+ "rental_start": "6/25/16",
+ "rental_end": "12/17/16"
+ },
+ "RNT828": {
+ "product_code": "PRD7",
+ "units_rented": 4,
+ "price_per_day": 30,
+ "rental_start": "7/24/16",
+ "rental_end": "6/29/18"
+ },
+ "RNT829": {
+ "product_code": "PRD3",
+ "units_rented": 3,
+ "price_per_day": 25,
+ "rental_start": "6/5/16",
+ "rental_end": "8/28/17"
+ },
+ "RNT830": {
+ "product_code": "PRD53",
+ "units_rented": 10,
+ "price_per_day": 20,
+ "rental_start": "8/18/16",
+ "rental_end": "11/8/16"
+ },
+ "RNT831": {
+ "product_code": "PRD10",
+ "units_rented": 3,
+ "price_per_day": 5,
+ "rental_start": "2/28/17",
+ "rental_end": "2/25/17"
+ },
+ "RNT832": {
+ "product_code": "PRD42",
+ "units_rented": 9,
+ "price_per_day": 13,
+ "rental_start": "4/7/16",
+ "rental_end": "12/11/18"
+ },
+ "RNT833": {
+ "product_code": "PRD47",
+ "units_rented": 8,
+ "price_per_day": 26,
+ "rental_start": "5/16/16",
+ "rental_end": "6/23/18"
+ },
+ "RNT834": {
+ "product_code": "PRD51",
+ "units_rented": 5,
+ "price_per_day": 39,
+ "rental_start": "10/28/16",
+ "rental_end": "10/5/18"
+ },
+ "RNT835": {
+ "product_code": "PRD2",
+ "units_rented": 6,
+ "price_per_day": 22,
+ "rental_start": "8/24/17",
+ "rental_end": "1/8/16"
+ },
+ "RNT836": {
+ "product_code": "PRD32",
+ "units_rented": 4,
+ "price_per_day": 20,
+ "rental_start": "7/14/16",
+ "rental_end": "7/9/16"
+ },
+ "RNT837": {
+ "product_code": "PRD82",
+ "units_rented": 4,
+ "price_per_day": 8,
+ "rental_start": "7/28/17",
+ "rental_end": "10/28/17"
+ },
+ "RNT838": {
+ "product_code": "PRD74",
+ "units_rented": 8,
+ "price_per_day": 7,
+ "rental_start": "9/18/16",
+ "rental_end": "10/12/18"
+ },
+ "RNT839": {
+ "product_code": "PRD67",
+ "units_rented": 1,
+ "price_per_day": 9,
+ "rental_start": "12/21/18",
+ "rental_end": "6/25/18"
+ },
+ "RNT840": {
+ "product_code": "PRD63",
+ "units_rented": 10,
+ "price_per_day": 19,
+ "rental_start": "11/1/18",
+ "rental_end": "2/4/17"
+ },
+ "RNT841": {
+ "product_code": "PRD33",
+ "units_rented": 7,
+ "price_per_day": 19,
+ "rental_start": "5/11/16",
+ "rental_end": "7/27/17"
+ },
+ "RNT842": {
+ "product_code": "PRD91",
+ "units_rented": 7,
+ "price_per_day": 17,
+ "rental_start": "10/16/17",
+ "rental_end": "4/16/16"
+ },
+ "RNT843": {
+ "product_code": "PRD79",
+ "units_rented": 0,
+ "price_per_day": 34,
+ "rental_start": "11/7/17",
+ "rental_end": "6/26/16"
+ },
+ "RNT844": {
+ "product_code": "PRD26",
+ "units_rented": 8,
+ "price_per_day": 37,
+ "rental_start": "4/14/18",
+ "rental_end": "9/9/17"
+ },
+ "RNT845": {
+ "product_code": "PRD81",
+ "units_rented": 10,
+ "price_per_day": 32,
+ "rental_start": "4/6/16",
+ "rental_end": "7/15/17"
+ },
+ "RNT846": {
+ "product_code": "PRD89",
+ "units_rented": 2,
+ "price_per_day": 27,
+ "rental_start": "9/8/17",
+ "rental_end": "6/29/16"
+ },
+ "RNT847": {
+ "product_code": "PRD88",
+ "units_rented": 9,
+ "price_per_day": 14,
+ "rental_start": "10/19/18",
+ "rental_end": "3/7/18"
+ },
+ "RNT848": {
+ "product_code": "PRD72",
+ "units_rented": 7,
+ "price_per_day": 28,
+ "rental_start": "8/23/17",
+ "rental_end": "11/4/17"
+ },
+ "RNT849": {
+ "product_code": "PRD58",
+ "units_rented": 7,
+ "price_per_day": 6,
+ "rental_start": "7/19/18",
+ "rental_end": "8/18/16"
+ },
+ "RNT850": {
+ "product_code": "PRD95",
+ "units_rented": 8,
+ "price_per_day": 38,
+ "rental_start": "3/9/16",
+ "rental_end": "9/11/16"
+ },
+ "RNT851": {
+ "product_code": "PRD8",
+ "units_rented": 5,
+ "price_per_day": 23,
+ "rental_start": "3/18/17",
+ "rental_end": "5/7/18"
+ },
+ "RNT852": {
+ "product_code": "PRD50",
+ "units_rented": 8,
+ "price_per_day": 35,
+ "rental_start": "7/31/16",
+ "rental_end": "9/20/17"
+ },
+ "RNT853": {
+ "product_code": "PRD88",
+ "units_rented": 4,
+ "price_per_day": 15,
+ "rental_start": "5/14/18",
+ "rental_end": "2/9/16"
+ },
+ "RNT854": {
+ "product_code": "PRD84",
+ "units_rented": 8,
+ "price_per_day": 39,
+ "rental_start": "8/11/16",
+ "rental_end": "12/2/18"
+ },
+ "RNT855": {
+ "product_code": "PRD28",
+ "units_rented": 2,
+ "price_per_day": 23,
+ "rental_start": "10/6/18",
+ "rental_end": "6/16/18"
+ },
+ "RNT856": {
+ "product_code": "PRD81",
+ "units_rented": 5,
+ "price_per_day": 23,
+ "rental_start": "3/6/17",
+ "rental_end": "10/14/17"
+ },
+ "RNT857": {
+ "product_code": "PRD20",
+ "units_rented": 5,
+ "price_per_day": 38,
+ "rental_start": "6/17/17",
+ "rental_end": "7/27/17"
+ },
+ "RNT858": {
+ "product_code": "PRD61",
+ "units_rented": 6,
+ "price_per_day": 25,
+ "rental_start": "8/15/18",
+ "rental_end": "6/7/18"
+ },
+ "RNT859": {
+ "product_code": "PRD48",
+ "units_rented": 1,
+ "price_per_day": 12,
+ "rental_start": "6/1/16",
+ "rental_end": "10/5/16"
+ },
+ "RNT860": {
+ "product_code": "PRD22",
+ "units_rented": 5,
+ "price_per_day": 10,
+ "rental_start": "5/5/18",
+ "rental_end": "12/16/18"
+ },
+ "RNT861": {
+ "product_code": "PRD52",
+ "units_rented": 5,
+ "price_per_day": 24,
+ "rental_start": "1/30/18",
+ "rental_end": "9/12/16"
+ },
+ "RNT862": {
+ "product_code": "PRD94",
+ "units_rented": 2,
+ "price_per_day": 24,
+ "rental_start": "5/4/16",
+ "rental_end": "5/28/16"
+ },
+ "RNT863": {
+ "product_code": "PRD42",
+ "units_rented": 2,
+ "price_per_day": 24,
+ "rental_start": "11/5/16",
+ "rental_end": "3/31/16"
+ },
+ "RNT864": {
+ "product_code": "PRD53",
+ "units_rented": 6,
+ "price_per_day": 12,
+ "rental_start": "1/20/18",
+ "rental_end": "1/12/18"
+ },
+ "RNT865": {
+ "product_code": "PRD84",
+ "units_rented": 3,
+ "price_per_day": 24,
+ "rental_start": "1/16/18",
+ "rental_end": "4/14/18"
+ },
+ "RNT866": {
+ "product_code": "PRD57",
+ "units_rented": 9,
+ "price_per_day": 38,
+ "rental_start": "1/1/18",
+ "rental_end": "5/7/17"
+ },
+ "RNT867": {
+ "product_code": "PRD60",
+ "units_rented": 7,
+ "price_per_day": 19,
+ "rental_start": "6/14/17",
+ "rental_end": "1/19/17"
+ },
+ "RNT868": {
+ "product_code": "PRD14",
+ "units_rented": 5,
+ "price_per_day": 37,
+ "rental_start": "12/10/16",
+ "rental_end": "5/26/17"
+ },
+ "RNT869": {
+ "product_code": "PRD74",
+ "units_rented": 10,
+ "price_per_day": 26,
+ "rental_start": "9/27/17",
+ "rental_end": "12/2/16"
+ },
+ "RNT870": {
+ "product_code": "PRD9",
+ "units_rented": 7,
+ "price_per_day": 7,
+ "rental_start": "9/13/16",
+ "rental_end": "11/26/18"
+ },
+ "RNT871": {
+ "product_code": "PRD25",
+ "units_rented": 7,
+ "price_per_day": 29,
+ "rental_start": "4/30/17",
+ "rental_end": "2/20/17"
+ },
+ "RNT872": {
+ "product_code": "PRD26",
+ "units_rented": 8,
+ "price_per_day": 26,
+ "rental_start": "1/13/16",
+ "rental_end": "5/7/17"
+ },
+ "RNT873": {
+ "product_code": "PRD16",
+ "units_rented": 3,
+ "price_per_day": 5,
+ "rental_start": "2/8/18",
+ "rental_end": "11/24/17"
+ },
+ "RNT874": {
+ "product_code": "PRD83",
+ "units_rented": 9,
+ "price_per_day": 38,
+ "rental_start": "8/11/18",
+ "rental_end": "8/8/18"
+ },
+ "RNT875": {
+ "product_code": "PRD96",
+ "units_rented": 8,
+ "price_per_day": 15,
+ "rental_start": "6/4/16",
+ "rental_end": "7/24/16"
+ },
+ "RNT876": {
+ "product_code": "PRD60",
+ "units_rented": 4,
+ "price_per_day": 26,
+ "rental_start": "4/30/17",
+ "rental_end": "9/20/16"
+ },
+ "RNT877": {
+ "product_code": "PRD43",
+ "units_rented": 3,
+ "price_per_day": 14,
+ "rental_start": "12/27/16",
+ "rental_end": "8/1/18"
+ },
+ "RNT878": {
+ "product_code": "PRD72",
+ "units_rented": 3,
+ "price_per_day": 8,
+ "rental_start": "8/15/18",
+ "rental_end": "8/25/18"
+ },
+ "RNT879": {
+ "product_code": "PRD44",
+ "units_rented": 5,
+ "price_per_day": 24,
+ "rental_start": "5/5/18",
+ "rental_end": "6/11/16"
+ },
+ "RNT880": {
+ "product_code": "PRD60",
+ "units_rented": 7,
+ "price_per_day": 29,
+ "rental_start": "7/10/17",
+ "rental_end": "8/30/17"
+ },
+ "RNT881": {
+ "product_code": "PRD97",
+ "units_rented": 7,
+ "price_per_day": 8,
+ "rental_start": "3/16/17",
+ "rental_end": "3/30/18"
+ },
+ "RNT882": {
+ "product_code": "PRD3",
+ "units_rented": 6,
+ "price_per_day": 28,
+ "rental_start": "1/27/18",
+ "rental_end": "4/13/16"
+ },
+ "RNT883": {
+ "product_code": "PRD28",
+ "units_rented": 6,
+ "price_per_day": 19,
+ "rental_start": "6/14/18",
+ "rental_end": "11/20/17"
+ },
+ "RNT884": {
+ "product_code": "PRD1",
+ "units_rented": 4,
+ "price_per_day": 11,
+ "rental_start": "12/3/16",
+ "rental_end": "5/1/16"
+ },
+ "RNT885": {
+ "product_code": "PRD3",
+ "units_rented": 1,
+ "price_per_day": 15,
+ "rental_start": "1/28/17",
+ "rental_end": "2/10/18"
+ },
+ "RNT886": {
+ "product_code": "PRD33",
+ "units_rented": 2,
+ "price_per_day": 24,
+ "rental_start": "1/24/17",
+ "rental_end": "10/23/16"
+ },
+ "RNT887": {
+ "product_code": "PRD81",
+ "units_rented": 3,
+ "price_per_day": 32,
+ "rental_start": "4/14/17",
+ "rental_end": "7/4/18"
+ },
+ "RNT888": {
+ "product_code": "PRD56",
+ "units_rented": 9,
+ "price_per_day": 13,
+ "rental_start": "12/11/17",
+ "rental_end": "6/16/18"
+ },
+ "RNT889": {
+ "product_code": "PRD73",
+ "units_rented": 10,
+ "price_per_day": 21,
+ "rental_start": "2/2/18",
+ "rental_end": "11/30/18"
+ },
+ "RNT890": {
+ "product_code": "PRD91",
+ "units_rented": 6,
+ "price_per_day": 8,
+ "rental_start": "6/12/18",
+ "rental_end": "3/21/16"
+ },
+ "RNT891": {
+ "product_code": "PRD79",
+ "units_rented": 1,
+ "price_per_day": 28,
+ "rental_start": "12/10/16",
+ "rental_end": "6/24/18"
+ },
+ "RNT892": {
+ "product_code": "PRD6",
+ "units_rented": 3,
+ "price_per_day": 8,
+ "rental_start": "3/29/17",
+ "rental_end": "11/20/16"
+ },
+ "RNT893": {
+ "product_code": "PRD20",
+ "units_rented": 2,
+ "price_per_day": 26,
+ "rental_start": "8/4/17",
+ "rental_end": "10/27/16"
+ },
+ "RNT894": {
+ "product_code": "PRD29",
+ "units_rented": 5,
+ "price_per_day": 13,
+ "rental_start": "3/6/17",
+ "rental_end": "12/7/16"
+ },
+ "RNT895": {
+ "product_code": "PRD9",
+ "units_rented": 6,
+ "price_per_day": 40,
+ "rental_start": "7/6/18",
+ "rental_end": "1/4/16"
+ },
+ "RNT896": {
+ "product_code": "PRD74",
+ "units_rented": 4,
+ "price_per_day": 30,
+ "rental_start": "10/9/17",
+ "rental_end": "7/7/17"
+ },
+ "RNT897": {
+ "product_code": "PRD48",
+ "units_rented": 5,
+ "price_per_day": 26,
+ "rental_start": "1/28/16",
+ "rental_end": "7/7/16"
+ },
+ "RNT898": {
+ "product_code": "PRD7",
+ "units_rented": 2,
+ "price_per_day": 31,
+ "rental_start": "8/30/17",
+ "rental_end": "11/18/16"
+ },
+ "RNT899": {
+ "product_code": "PRD67",
+ "units_rented": 9,
+ "price_per_day": 6,
+ "rental_start": "2/24/16",
+ "rental_end": "7/15/16"
+ },
+ "RNT900": {
+ "product_code": "PRD45",
+ "units_rented": 9,
+ "price_per_day": 21,
+ "rental_start": "5/10/17",
+ "rental_end": "6/28/18"
+ },
+ "RNT901": {
+ "product_code": "PRD69",
+ "units_rented": 9,
+ "price_per_day": 14,
+ "rental_start": "4/8/17",
+ "rental_end": "11/19/16"
+ },
+ "RNT902": {
+ "product_code": "PRD98",
+ "units_rented": 9,
+ "price_per_day": 21,
+ "rental_start": "1/10/17",
+ "rental_end": "4/3/17"
+ },
+ "RNT903": {
+ "product_code": "PRD55",
+ "units_rented": 8,
+ "price_per_day": 14,
+ "rental_start": "4/22/18",
+ "rental_end": "12/26/17"
+ },
+ "RNT904": {
+ "product_code": "PRD67",
+ "units_rented": 8,
+ "price_per_day": 9,
+ "rental_start": "2/18/17",
+ "rental_end": "3/15/17"
+ },
+ "RNT905": {
+ "product_code": "PRD77",
+ "units_rented": 7,
+ "price_per_day": 27,
+ "rental_start": "9/6/17",
+ "rental_end": "8/21/17"
+ },
+ "RNT906": {
+ "product_code": "PRD67",
+ "units_rented": 7,
+ "price_per_day": 16,
+ "rental_start": "2/9/16",
+ "rental_end": "5/13/16"
+ },
+ "RNT907": {
+ "product_code": "PRD44",
+ "units_rented": 10,
+ "price_per_day": 5,
+ "rental_start": "3/5/17",
+ "rental_end": "9/9/17"
+ },
+ "RNT908": {
+ "product_code": "PRD55",
+ "units_rented": 2,
+ "price_per_day": 27,
+ "rental_start": "3/6/16",
+ "rental_end": "5/25/17"
+ },
+ "RNT909": {
+ "product_code": "PRD52",
+ "units_rented": 3,
+ "price_per_day": 15,
+ "rental_start": "5/23/18",
+ "rental_end": "5/17/16"
+ },
+ "RNT910": {
+ "product_code": "PRD78",
+ "units_rented": 6,
+ "price_per_day": 5,
+ "rental_start": "6/7/17",
+ "rental_end": "6/23/17"
+ },
+ "RNT911": {
+ "product_code": "PRD55",
+ "units_rented": 6,
+ "price_per_day": 20,
+ "rental_start": "10/14/16",
+ "rental_end": "1/17/16"
+ },
+ "RNT912": {
+ "product_code": "PRD54",
+ "units_rented": 6,
+ "price_per_day": 22,
+ "rental_start": "11/20/18",
+ "rental_end": "9/5/16"
+ },
+ "RNT913": {
+ "product_code": "PRD33",
+ "units_rented": 9,
+ "price_per_day": 7,
+ "rental_start": "1/30/16",
+ "rental_end": "5/26/17"
+ },
+ "RNT914": {
+ "product_code": "PRD56",
+ "units_rented": 3,
+ "price_per_day": 38,
+ "rental_start": "7/4/18",
+ "rental_end": "7/3/16"
+ },
+ "RNT915": {
+ "product_code": "PRD35",
+ "units_rented": 1,
+ "price_per_day": 16,
+ "rental_start": "8/9/18",
+ "rental_end": "12/19/17"
+ },
+ "RNT916": {
+ "product_code": "PRD81",
+ "units_rented": 2,
+ "price_per_day": 25,
+ "rental_start": "3/6/16",
+ "rental_end": "12/8/18"
+ },
+ "RNT917": {
+ "product_code": "PRD75",
+ "units_rented": 5,
+ "price_per_day": 33,
+ "rental_start": "2/17/17",
+ "rental_end": "5/30/16"
+ },
+ "RNT918": {
+ "product_code": "PRD0",
+ "units_rented": 2,
+ "price_per_day": 39,
+ "rental_start": "8/10/18",
+ "rental_end": "7/20/18"
+ },
+ "RNT919": {
+ "product_code": "PRD2",
+ "units_rented": 7,
+ "price_per_day": 17,
+ "rental_start": "4/17/18",
+ "rental_end": "2/25/17"
+ },
+ "RNT920": {
+ "product_code": "PRD9",
+ "units_rented": 7,
+ "price_per_day": 34,
+ "rental_start": "2/17/16",
+ "rental_end": "12/25/18"
+ },
+ "RNT921": {
+ "product_code": "PRD81",
+ "units_rented": 4,
+ "price_per_day": 30,
+ "rental_start": "3/11/17",
+ "rental_end": "7/11/18"
+ },
+ "RNT922": {
+ "product_code": "PRD3",
+ "units_rented": 6,
+ "price_per_day": 5,
+ "rental_start": "1/20/18",
+ "rental_end": "6/13/17"
+ },
+ "RNT923": {
+ "product_code": "PRD47",
+ "units_rented": 10,
+ "price_per_day": 23,
+ "rental_start": "11/15/16",
+ "rental_end": "9/10/17"
+ },
+ "RNT924": {
+ "product_code": "PRD79",
+ "units_rented": 9,
+ "price_per_day": 31,
+ "rental_start": "5/12/18",
+ "rental_end": "4/3/16"
+ },
+ "RNT925": {
+ "product_code": "PRD72",
+ "units_rented": 10,
+ "price_per_day": 31,
+ "rental_start": "1/15/17",
+ "rental_end": "6/26/18"
+ },
+ "RNT926": {
+ "product_code": "PRD44",
+ "units_rented": 8,
+ "price_per_day": 37,
+ "rental_start": "9/8/17",
+ "rental_end": "4/12/17"
+ },
+ "RNT927": {
+ "product_code": "PRD61",
+ "units_rented": 3,
+ "price_per_day": 19,
+ "rental_start": "8/17/17",
+ "rental_end": "7/18/17"
+ },
+ "RNT928": {
+ "product_code": "PRD66",
+ "units_rented": 3,
+ "price_per_day": 11,
+ "rental_start": "10/10/17",
+ "rental_end": "4/1/16"
+ },
+ "RNT929": {
+ "product_code": "PRD40",
+ "units_rented": 10,
+ "price_per_day": 8,
+ "rental_start": "12/6/16",
+ "rental_end": "12/2/17"
+ },
+ "RNT930": {
+ "product_code": "PRD50",
+ "units_rented": 4,
+ "price_per_day": 32,
+ "rental_start": "1/11/17",
+ "rental_end": "8/4/16"
+ },
+ "RNT931": {
+ "product_code": "PRD94",
+ "units_rented": 5,
+ "price_per_day": 38,
+ "rental_start": "3/17/18",
+ "rental_end": "11/24/16"
+ },
+ "RNT932": {
+ "product_code": "PRD63",
+ "units_rented": 3,
+ "price_per_day": 40,
+ "rental_start": "5/15/18",
+ "rental_end": "4/30/16"
+ },
+ "RNT933": {
+ "product_code": "PRD57",
+ "units_rented": 8,
+ "price_per_day": 7,
+ "rental_start": "4/4/16",
+ "rental_end": "7/31/16"
+ },
+ "RNT934": {
+ "product_code": "PRD6",
+ "units_rented": 10,
+ "price_per_day": 36,
+ "rental_start": "10/21/16",
+ "rental_end": "12/15/18"
+ },
+ "RNT935": {
+ "product_code": "PRD97",
+ "units_rented": 5,
+ "price_per_day": 20,
+ "rental_start": "3/2/18",
+ "rental_end": "2/21/18"
+ },
+ "RNT936": {
+ "product_code": "PRD82",
+ "units_rented": 5,
+ "price_per_day": 29,
+ "rental_start": "9/30/16",
+ "rental_end": "3/11/17"
+ },
+ "RNT937": {
+ "product_code": "PRD57",
+ "units_rented": 10,
+ "price_per_day": 19,
+ "rental_start": "3/27/17",
+ "rental_end": "3/14/17"
+ },
+ "RNT938": {
+ "product_code": "PRD6",
+ "units_rented": 5,
+ "price_per_day": 36,
+ "rental_start": "6/30/17",
+ "rental_end": "8/7/16"
+ },
+ "RNT939": {
+ "product_code": "PRD94",
+ "units_rented": 1,
+ "price_per_day": 33,
+ "rental_start": "12/10/17",
+ "rental_end": "3/23/16"
+ },
+ "RNT940": {
+ "product_code": "PRD2",
+ "units_rented": 6,
+ "price_per_day": 13,
+ "rental_start": "10/23/16",
+ "rental_end": "10/15/16"
+ },
+ "RNT941": {
+ "product_code": "PRD85",
+ "units_rented": 8,
+ "price_per_day": 40,
+ "rental_start": "8/25/16",
+ "rental_end": "3/27/17"
+ },
+ "RNT942": {
+ "product_code": "PRD29",
+ "units_rented": 3,
+ "price_per_day": 35,
+ "rental_start": "4/7/17",
+ "rental_end": "2/21/17"
+ },
+ "RNT943": {
+ "product_code": "PRD78",
+ "units_rented": 1,
+ "price_per_day": 35,
+ "rental_start": "7/19/17",
+ "rental_end": "2/10/16"
+ },
+ "RNT944": {
+ "product_code": "PRD26",
+ "units_rented": 9,
+ "price_per_day": 18,
+ "rental_start": "7/19/18",
+ "rental_end": "7/22/17"
+ },
+ "RNT945": {
+ "product_code": "PRD94",
+ "units_rented": 5,
+ "price_per_day": 28,
+ "rental_start": "9/30/16",
+ "rental_end": "11/10/16"
+ },
+ "RNT946": {
+ "product_code": "PRD81",
+ "units_rented": 4,
+ "price_per_day": 39,
+ "rental_start": "11/12/17",
+ "rental_end": "8/19/17"
+ },
+ "RNT947": {
+ "product_code": "PRD72",
+ "units_rented": 4,
+ "price_per_day": 8,
+ "rental_start": "11/26/16",
+ "rental_end": "9/11/16"
+ },
+ "RNT948": {
+ "product_code": "PRD90",
+ "units_rented": 8,
+ "price_per_day": 7,
+ "rental_start": "11/30/18",
+ "rental_end": "5/9/17"
+ },
+ "RNT949": {
+ "product_code": "PRD50",
+ "units_rented": 4,
+ "price_per_day": 21,
+ "rental_start": "8/30/16",
+ "rental_end": "1/19/16"
+ },
+ "RNT950": {
+ "product_code": "PRD64",
+ "units_rented": 3,
+ "price_per_day": 11,
+ "rental_start": "7/25/17",
+ "rental_end": "10/6/18"
+ },
+ "RNT951": {
+ "product_code": "PRD99",
+ "units_rented": 2,
+ "price_per_day": 5,
+ "rental_start": "8/27/18",
+ "rental_end": "12/16/16"
+ },
+ "RNT952": {
+ "product_code": "PRD70",
+ "units_rented": 7,
+ "price_per_day": 28,
+ "rental_start": "8/21/17",
+ "rental_end": "9/21/17"
+ },
+ "RNT953": {
+ "product_code": "PRD41",
+ "units_rented": 5,
+ "price_per_day": 38,
+ "rental_start": "3/17/16",
+ "rental_end": "11/16/18"
+ },
+ "RNT954": {
+ "product_code": "PRD27",
+ "units_rented": 3,
+ "price_per_day": 21,
+ "rental_start": "4/10/16",
+ "rental_end": "10/21/16"
+ },
+ "RNT955": {
+ "product_code": "PRD74",
+ "units_rented": 7,
+ "price_per_day": 35,
+ "rental_start": "10/15/17",
+ "rental_end": "7/9/17"
+ },
+ "RNT956": {
+ "product_code": "PRD43",
+ "units_rented": 6,
+ "price_per_day": 16,
+ "rental_start": "5/17/16",
+ "rental_end": "2/29/16"
+ },
+ "RNT957": {
+ "product_code": "PRD28",
+ "units_rented": 9,
+ "price_per_day": 30,
+ "rental_start": "6/14/18",
+ "rental_end": "11/1/17"
+ },
+ "RNT958": {
+ "product_code": "PRD82",
+ "units_rented": 10,
+ "price_per_day": 24,
+ "rental_start": "6/21/17",
+ "rental_end": "11/13/16"
+ },
+ "RNT959": {
+ "product_code": "PRD92",
+ "units_rented": 1,
+ "price_per_day": 19,
+ "rental_start": "2/8/17",
+ "rental_end": "7/21/16"
+ },
+ "RNT960": {
+ "product_code": "PRD30",
+ "units_rented": 6,
+ "price_per_day": 22,
+ "rental_start": "3/1/18",
+ "rental_end": "10/22/16"
+ },
+ "RNT961": {
+ "product_code": "PRD67",
+ "units_rented": 2,
+ "price_per_day": 14,
+ "rental_start": "5/14/18",
+ "rental_end": "3/19/18"
+ },
+ "RNT962": {
+ "product_code": "PRD27",
+ "units_rented": 7,
+ "price_per_day": 19,
+ "rental_start": "8/20/17",
+ "rental_end": "6/25/17"
+ },
+ "RNT963": {
+ "product_code": "PRD20",
+ "units_rented": 7,
+ "price_per_day": 16,
+ "rental_start": "1/16/17",
+ "rental_end": "12/13/16"
+ },
+ "RNT964": {
+ "product_code": "PRD97",
+ "units_rented": 2,
+ "price_per_day": 11,
+ "rental_start": "1/25/16",
+ "rental_end": "3/26/16"
+ },
+ "RNT965": {
+ "product_code": "PRD19",
+ "units_rented": 10,
+ "price_per_day": 30,
+ "rental_start": "12/15/17",
+ "rental_end": "10/13/17"
+ },
+ "RNT966": {
+ "product_code": "PRD60",
+ "units_rented": 9,
+ "price_per_day": 22,
+ "rental_start": "5/17/17",
+ "rental_end": "6/25/18"
+ },
+ "RNT967": {
+ "product_code": "PRD14",
+ "units_rented": 5,
+ "price_per_day": 26,
+ "rental_start": "10/18/18",
+ "rental_end": "4/6/17"
+ },
+ "RNT968": {
+ "product_code": "PRD82",
+ "units_rented": 7,
+ "price_per_day": 35,
+ "rental_start": "6/11/16",
+ "rental_end": "1/17/17"
+ },
+ "RNT969": {
+ "product_code": "PRD77",
+ "units_rented": 1,
+ "price_per_day": 36,
+ "rental_start": "6/28/18",
+ "rental_end": "5/27/16"
+ },
+ "RNT970": {
+ "product_code": "PRD61",
+ "units_rented": 1,
+ "price_per_day": 22,
+ "rental_start": "2/26/18",
+ "rental_end": "4/19/16"
+ },
+ "RNT971": {
+ "product_code": "PRD78",
+ "units_rented": 5,
+ "price_per_day": 20,
+ "rental_start": "11/20/17",
+ "rental_end": "1/13/17"
+ },
+ "RNT972": {
+ "product_code": "PRD6",
+ "units_rented": 3,
+ "price_per_day": 40,
+ "rental_start": "4/2/17",
+ "rental_end": "8/24/18"
+ },
+ "RNT973": {
+ "product_code": "PRD11",
+ "units_rented": 9,
+ "price_per_day": 14,
+ "rental_start": "9/13/17",
+ "rental_end": "4/28/18"
+ },
+ "RNT974": {
+ "product_code": "PRD66",
+ "units_rented": 6,
+ "price_per_day": 30,
+ "rental_start": "10/23/18",
+ "rental_end": "2/28/18"
+ },
+ "RNT975": {
+ "product_code": "PRD77",
+ "units_rented": 7,
+ "price_per_day": 39,
+ "rental_start": "5/9/16",
+ "rental_end": "5/26/16"
+ },
+ "RNT976": {
+ "product_code": "PRD42",
+ "units_rented": 5,
+ "price_per_day": 32,
+ "rental_start": "1/27/16",
+ "rental_end": "8/5/16"
+ },
+ "RNT977": {
+ "product_code": "PRD23",
+ "units_rented": 8,
+ "price_per_day": 37,
+ "rental_start": "4/5/17",
+ "rental_end": "10/10/16"
+ },
+ "RNT978": {
+ "product_code": "PRD57",
+ "units_rented": 3,
+ "price_per_day": 39,
+ "rental_start": "1/4/16",
+ "rental_end": "11/15/16"
+ },
+ "RNT979": {
+ "product_code": "PRD48",
+ "units_rented": 4,
+ "price_per_day": 5,
+ "rental_start": "9/23/17",
+ "rental_end": "4/16/16"
+ },
+ "RNT980": {
+ "product_code": "PRD66",
+ "units_rented": 5,
+ "price_per_day": 40,
+ "rental_start": "11/16/17",
+ "rental_end": "12/7/17"
+ },
+ "RNT981": {
+ "product_code": "PRD76",
+ "units_rented": 10,
+ "price_per_day": 18,
+ "rental_start": "2/28/17",
+ "rental_end": "2/2/18"
+ },
+ "RNT982": {
+ "product_code": "PRD39",
+ "units_rented": 10,
+ "price_per_day": 7,
+ "rental_start": "11/3/16",
+ "rental_end": "3/16/16"
+ },
+ "RNT983": {
+ "product_code": "PRD46",
+ "units_rented": 2,
+ "price_per_day": 29,
+ "rental_start": "11/11/16",
+ "rental_end": "1/16/16"
+ },
+ "RNT984": {
+ "product_code": "PRD48",
+ "units_rented": 7,
+ "price_per_day": 17,
+ "rental_start": "10/8/17",
+ "rental_end": "11/26/18"
+ },
+ "RNT985": {
+ "product_code": "PRD63",
+ "units_rented": 1,
+ "price_per_day": 14,
+ "rental_start": "11/8/16",
+ "rental_end": "6/30/16"
+ },
+ "RNT986": {
+ "product_code": "PRD40",
+ "units_rented": 2,
+ "price_per_day": 31,
+ "rental_start": "11/20/18",
+ "rental_end": "3/11/16"
+ },
+ "RNT987": {
+ "product_code": "PRD23",
+ "units_rented": 7,
+ "price_per_day": 34,
+ "rental_start": "9/10/17",
+ "rental_end": "2/28/16"
+ },
+ "RNT988": {
+ "product_code": "PRD66",
+ "units_rented": 10,
+ "price_per_day": 33,
+ "rental_start": "3/8/18",
+ "rental_end": "8/22/18"
+ },
+ "RNT989": {
+ "product_code": "PRD19",
+ "units_rented": 10,
+ "price_per_day": 30,
+ "rental_start": "10/25/18",
+ "rental_end": "4/7/16"
+ },
+ "RNT990": {
+ "product_code": "PRD9",
+ "units_rented": 9,
+ "price_per_day": 7,
+ "rental_start": "5/7/16",
+ "rental_end": "4/24/18"
+ },
+ "RNT991": {
+ "product_code": "PRD71",
+ "units_rented": 9,
+ "price_per_day": 38,
+ "rental_start": "6/17/16",
+ "rental_end": "11/18/16"
+ },
+ "RNT992": {
+ "product_code": "PRD68",
+ "units_rented": 5,
+ "price_per_day": 37,
+ "rental_start": "3/10/18",
+ "rental_end": "9/8/18"
+ },
+ "RNT993": {
+ "product_code": "PRD87",
+ "units_rented": 8,
+ "price_per_day": 24,
+ "rental_start": "5/26/16",
+ "rental_end": "12/10/17"
+ },
+ "RNT994": {
+ "product_code": "PRD42",
+ "units_rented": 5,
+ "price_per_day": 30,
+ "rental_start": "6/4/17",
+ "rental_end": "1/2/17"
+ },
+ "RNT995": {
+ "product_code": "PRD0",
+ "units_rented": 10,
+ "price_per_day": 10,
+ "rental_start": "9/7/16",
+ "rental_end": "1/28/18"
+ },
+ "RNT996": {
+ "product_code": "PRD4",
+ "units_rented": 6,
+ "price_per_day": 40,
+ "rental_start": "7/5/16",
+ "rental_end": "1/25/18"
+ },
+ "RNT997": {
+ "product_code": "PRD30",
+ "units_rented": 1,
+ "price_per_day": 11,
+ "rental_start": "4/25/16",
+ "rental_end": "1/29/18"
+ },
+ "RNT998": {
+ "product_code": "PRD73",
+ "units_rented": 7,
+ "price_per_day": 30,
+ "rental_start": "9/2/18",
+ "rental_end": "4/14/16"
+ },
+ "RNT999": {
+ "product_code": "PRD69",
+ "units_rented": 8,
+ "price_per_day": 36,
+ "rental_start": "10/12/18",
+ "rental_end": "10/2/16"
+ }
+}
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson09/assignment/src/testing deco.py b/students/Justin_Jameson/lesson09/assignment/src/testing deco.py
new file mode 100644
index 0000000..52da4e4
--- /dev/null
+++ b/students/Justin_Jameson/lesson09/assignment/src/testing deco.py
@@ -0,0 +1,35 @@
+import logging
+import functools
+
+logging.basicConfig(filename='example.log', level=logging.DEBUG)
+
+do_debug = input('Debug? Y/N: ')
+
+def debug(func):
+ """Print the function signature and return value"""
+ if do_debug.lower() == 'y':
+ @functools.wraps(func)
+ def wrapper_debug(*args, **kwargs):
+ args_repr = [repr(a) for a in args]
+ kwargs_repr = [f"{k}={v!r}" for k, v in kwargs.items()]
+ signature = ", ".join(args_repr + kwargs_repr)
+ logging.debug(f"Calling {func.__name__}({signature})")
+ value = func(*args, **kwargs)
+ logging.info(f"{func.__name__!r} returned {value!r}")
+ return value
+ return wrapper_debug
+ else:
+ @functools.wraps(func)
+ def debug_disabled(*args, **kwargs):
+ # print("Debug has been disabled")
+ returned_value = func(*args, **kwargs)
+ return returned_value
+
+ return debug_disabled
+
+
+@debug
+def some_function():
+ return"Just a funciton"
+
+print(some_function())
\ No newline at end of file
diff --git a/students/Justin_Jameson/lesson09/assignment/src/testing for time.py b/students/Justin_Jameson/lesson09/assignment/src/testing for time.py
new file mode 100644
index 0000000..28fc84b
--- /dev/null
+++ b/students/Justin_Jameson/lesson09/assignment/src/testing for time.py
@@ -0,0 +1 @@
+import datetime
\ No newline at end of file
diff --git a/students/template_student/lesson09/assignment/tests/test_database.py b/students/Justin_Jameson/lesson09/assignment/tests/test_database.py
old mode 100755
new mode 100644
similarity index 97%
rename from students/template_student/lesson09/assignment/tests/test_database.py
rename to students/Justin_Jameson/lesson09/assignment/tests/test_database.py
index 3ecf267..5b2cfd7
--- a/students/template_student/lesson09/assignment/tests/test_database.py
+++ b/students/Justin_Jameson/lesson09/assignment/tests/test_database.py
@@ -1,39 +1,39 @@
-import pytest
-import os
-
-import database as l
-
-@pytest.fixture
-def _show_available_products():
- return {
- 'P000001':{'description':'Chair Red leather','product_type':'livingroom','quantity_available':'21'},
- 'P000002':{'description':'Table Oak','product_type':'livingroom','quantity_available':'4'},
- 'P000003':{'description':'Couch Green cloth','product_type':'livingroom','quantity_available':'10'},
- 'P000004':{'description':'Dining table Plastic','product_type':'Kitchen','quantity_available':'23'},
- 'P000005':{'description':'Stool Black ash','product_type':'Kitchen','quantity_available':'12'}
- }
-
-@pytest.fixture
-def _show_rentals():
- return {
- 'C000001':{'name':'Shea Boehm','address':'3343 Sallie Gateway','phone_number':'508.104.0644','email':'Alexander.Weber@monroe.com'},
- 'C000003':{'name':'Elfrieda Skiles','address':'3180 Mose Row','phone_number':'839)825-0058','email':'Mylene_Smitham@hannah.co.uk'}
- }
-
-def test_import_data():
- dir = os.path.dirname(os.path.abspath(__file__))
- added, errors = l.import_data(dir, "products.csv", "customers.csv", "rentals.csv")
- for add in added:
- assert isinstance(add, int)
- for error in errors:
- assert isinstance(error, int)
- assert added == (5,11,9)
- assert errors == (0,0,0)
-
-def test_show_available_products(_show_available_products):
- students_response = l.show_available_products()
- assert students_response == _show_available_products
-
-def test_show_rentals(_show_rentals):
- students_response = l.show_rentals("P000003")
- assert students_response == _show_rentals
+import pytest
+import os
+
+import database as l
+
+@pytest.fixture
+def _show_available_products():
+ return {
+ 'P000001':{'description':'Chair Red leather','product_type':'livingroom','quantity_available':'21'},
+ 'P000002':{'description':'Table Oak','product_type':'livingroom','quantity_available':'4'},
+ 'P000003':{'description':'Couch Green cloth','product_type':'livingroom','quantity_available':'10'},
+ 'P000004':{'description':'Dining table Plastic','product_type':'Kitchen','quantity_available':'23'},
+ 'P000005':{'description':'Stool Black ash','product_type':'Kitchen','quantity_available':'12'}
+ }
+
+@pytest.fixture
+def _show_rentals():
+ return {
+ 'C000001':{'name':'Shea Boehm','address':'3343 Sallie Gateway','phone_number':'508.104.0644','email':'Alexander.Weber@monroe.com'},
+ 'C000003':{'name':'Elfrieda Skiles','address':'3180 Mose Row','phone_number':'839)825-0058','email':'Mylene_Smitham@hannah.co.uk'}
+ }
+
+def test_import_data():
+ dir = os.path.dirname(os.path.abspath(__file__))
+ added, errors = l.import_data(dir, "products.csv", "customers.csv", "rentals.csv")
+ for add in added:
+ assert isinstance(add, int)
+ for error in errors:
+ assert isinstance(error, int)
+ assert added == (5,11,9)
+ assert errors == (0,0,0)
+
+def test_show_available_products(_show_available_products):
+ students_response = l.show_available_products()
+ assert students_response == _show_available_products
+
+def test_show_rentals(_show_rentals):
+ students_response = l.show_rentals("P000003")
+ assert students_response == _show_rentals
diff --git a/students/template_student/lesson09/assignment/tests/test_jpgdiscover.py b/students/Justin_Jameson/lesson09/assignment/tests/test_jpgdiscover.py
old mode 100755
new mode 100644
similarity index 96%
rename from students/template_student/lesson09/assignment/tests/test_jpgdiscover.py
rename to students/Justin_Jameson/lesson09/assignment/tests/test_jpgdiscover.py
index 826f4fc..20d7a10
--- a/students/template_student/lesson09/assignment/tests/test_jpgdiscover.py
+++ b/students/Justin_Jameson/lesson09/assignment/tests/test_jpgdiscover.py
@@ -1,21 +1,21 @@
-"""
-grade l9 part 3
-"""
-import pytest
-
-import jpgdiscover as sut
-
-@pytest.fixture
-def _test_list_jpg_files():
- """ structure from test """
- return [
- "tests/lesson09/data/furniture/chair", ["metal_chair_back_isometric_400_clr_17527.png"],
- "tests/lesson09/data/furniture/chair/couch", ["sofa_400_clr_10056.png"],
- "tests/lesson09/data/furniture/table", ["basic_desk_main_400_clr_17523.png", "desk_isometric_back_400_clr_17524.png", "table_with_cloth_400_clr_10664.png"],
- "tests/lesson09/data/new", ["chairs_balancing_stacked_400_clr_11525.png", "hotel_room_400_clr_12721.png"],
- "tests/lesson09/data/old", ["couple_on_swing_bench_400_clr_12844.png", "sitting_in_chair_relaxing_400_clr_6028.png"]]
-
-def test_list_jpg_files(_test_list_jpg_files):
- """ student geneartes """
- jpgs = sut.list_jpg_files("tests/lesson09/data/")
- assert jpgs == _test_list_jpg_files
+"""
+grade l9 part 3
+"""
+import pytest
+
+import jpgdiscover as sut
+
+@pytest.fixture
+def _test_list_jpg_files():
+ """ structure from test """
+ return [
+ "tests/lesson09/data/furniture/chair", ["metal_chair_back_isometric_400_clr_17527.png"],
+ "tests/lesson09/data/furniture/chair/couch", ["sofa_400_clr_10056.png"],
+ "tests/lesson09/data/furniture/table", ["basic_desk_main_400_clr_17523.png", "desk_isometric_back_400_clr_17524.png", "table_with_cloth_400_clr_10664.png"],
+ "tests/lesson09/data/new", ["chairs_balancing_stacked_400_clr_11525.png", "hotel_room_400_clr_12721.png"],
+ "tests/lesson09/data/old", ["couple_on_swing_bench_400_clr_12844.png", "sitting_in_chair_relaxing_400_clr_6028.png"]]
+
+def test_list_jpg_files(_test_list_jpg_files):
+ """ student geneartes """
+ jpgs = sut.list_jpg_files("tests/lesson09/data/")
+ assert jpgs == _test_list_jpg_files
diff --git a/students/template_student/lesson08/activity/README.md b/students/Justin_Jameson/lesson10/activity/README.md
similarity index 100%
rename from students/template_student/lesson08/activity/README.md
rename to students/Justin_Jameson/lesson10/activity/README.md
diff --git a/students/template_student/lesson10/assignment/README.md b/students/Justin_Jameson/lesson10/assignment/README.md
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson10/assignment/README.md
rename to students/Justin_Jameson/lesson10/assignment/README.md
diff --git a/students/template_student/lesson10/assignment/data/customer.csv b/students/Justin_Jameson/lesson10/assignment/data/customer.csv
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson10/assignment/data/customer.csv
rename to students/Justin_Jameson/lesson10/assignment/data/customer.csv
diff --git a/students/template_student/lesson10/assignment/data/product.csv b/students/Justin_Jameson/lesson10/assignment/data/product.csv
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson10/assignment/data/product.csv
rename to students/Justin_Jameson/lesson10/assignment/data/product.csv
diff --git a/students/template_student/lesson10/assignment/data/rental.csv b/students/Justin_Jameson/lesson10/assignment/data/rental.csv
old mode 100755
new mode 100644
similarity index 100%
rename from students/template_student/lesson10/assignment/data/rental.csv
rename to students/Justin_Jameson/lesson10/assignment/data/rental.csv
diff --git a/students/template_student/lesson08/assignment/pylintrc b/students/Justin_Jameson/lesson10/assignment/pylintrc
similarity index 100%
rename from students/template_student/lesson08/assignment/pylintrc
rename to students/Justin_Jameson/lesson10/assignment/pylintrc
diff --git a/students/Justin_Jameson/lesson10/assignment/src/Justin Jameson lesson 10.zip b/students/Justin_Jameson/lesson10/assignment/src/Justin Jameson lesson 10.zip
new file mode 100644
index 0000000..e4c0ed4
Binary files /dev/null and b/students/Justin_Jameson/lesson10/assignment/src/Justin Jameson lesson 10.zip differ
diff --git a/students/template_student/lesson10/assignment/src/databse.py b/students/Justin_Jameson/lesson10/assignment/src/databse.py
similarity index 100%
rename from students/template_student/lesson10/assignment/src/databse.py
rename to students/Justin_Jameson/lesson10/assignment/src/databse.py
diff --git a/students/template_student/lesson01/assignment/inventory_management/electricAppliancesClass.py b/students/template_student/lesson01/assignment/inventory_management/electricAppliancesClass.py
deleted file mode 100755
index 291f199..0000000
--- a/students/template_student/lesson01/assignment/inventory_management/electricAppliancesClass.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Electric appliances class
-from inventoryClass import inventory
-
-class electricAppliances(inventory):
-
- def __init__(self, productCode, description, marketPrice, rentalPrice, brand, voltage):
- inventory.__init__(self,productCode,description,marketPrice,rentalPrice) # Creates common instance variables from the parent class
-
-
- self.brand = brand
- self.voltage = voltage
-
- def returnAsDictionary(self):
- outputDict = {}
- outputDict['productCode'] = self.productCode
- outputDict['description'] = self.description
- outputDict['marketPrice'] = self.marketPrice
- outputDict['rentalPrice'] = self.rentalPrice
- outputDict['brand'] = self.brand
- outputDict['voltage'] = self.voltage
-
- return outputDict
\ No newline at end of file
diff --git a/students/template_student/lesson01/assignment/inventory_management/furnitureClass.py b/students/template_student/lesson01/assignment/inventory_management/furnitureClass.py
deleted file mode 100755
index 9a98aa7..0000000
--- a/students/template_student/lesson01/assignment/inventory_management/furnitureClass.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Furniture class
-from inventoryClass import inventory
-
-class furniture(inventory):
-
- def __init__(self, productCode, description, marketPrice, rentalPrice, material, size):
- inventory.__init__(self,productCode,description,marketPrice,rentalPrice) # Creates common instance variables from the parent class
-
- self.material = material
- self.size = size
-
- def returnAsDictionary(self):
- outputDict = {}
- outputDict['productCode'] = self.productCode
- outputDict['description'] = self.description
- outputDict['marketPrice'] = self.marketPrice
- outputDict['rentalPrice'] = self.rentalPrice
- outputDict['material'] = self.material
- outputDict['size'] = self.size
-
- return outputDict
\ No newline at end of file
diff --git a/students/template_student/lesson01/assignment/inventory_management/inventoryClass.py b/students/template_student/lesson01/assignment/inventory_management/inventoryClass.py
deleted file mode 100755
index 40c7fd3..0000000
--- a/students/template_student/lesson01/assignment/inventory_management/inventoryClass.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Inventory class
-class inventory:
-
- def __init__(self, productCode, description, marketPrice, rentalPrice):
- self.productCode = productCode
- self.description = description
- self.marketPrice = marketPrice
- self.rentalPrice = rentalPrice
-
- def returnAsDictionary(self):
- outputDict = {}
- outputDict['productCode'] = self.productCode
- outputDict['description'] = self.description
- outputDict['marketPrice'] = self.marketPrice
- outputDict['rentalPrice'] = self.rentalPrice
-
- return outputDict
\ No newline at end of file
diff --git a/students/template_student/lesson01/assignment/inventory_management/main.py b/students/template_student/lesson01/assignment/inventory_management/main.py
deleted file mode 100755
index 4b82694..0000000
--- a/students/template_student/lesson01/assignment/inventory_management/main.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# Launches the user interface for the inventory management system
-import sys
-import market_prices
-import inventoryClass
-import furnitureClass
-import electricAppliancesClass
-
-def mainMenu(user_prompt=None):
- valid_prompts = {"1": addNewItem,
- "2": itemInfo,
- "q": exitProgram}
- options = list(valid_prompts.keys())
-
- while user_prompt not in valid_prompts:
- options_str = ("{}" + (", {}") * (len(options)-1)).format(*options)
- print("Please choose from the following options ({options_str}):")
- print("1. Add a new item to the inventory")
- print("2. Get item information")
- print("q. Quit")
- user_prompt = input(">")
- return valid_prompts.get(user_prompt)
-
-def getPrice(itemCode):
- print("Get price")
-
-def addNewItem():
- global fullInventory
- itemCode = input("Enter item code: ")
- itemDescription = input("Enter item description: ")
- itemRentalPrice = input("Enter item rental price: ")
-
- # Get price from the market prices module
- itemPrice = market_prices.get_latest_price(itemCode)
-
- isFurniture = input("Is this item a piece of furniture? (Y/N): ")
- if isFurniture.lower() == "y":
- itemMaterial = input("Enter item material: ")
- itemSize = input("Enter item size (S,M,L,XL): ")
- newItem = furnitureClass.furniture(itemCode,itemDescription,itemPrice,itemRentalPrice,itemMaterial,itemSize)
- else:
- isElectricAppliance = input("Is this item an electric appliance? (Y/N): ")
- if isElectricAppliance.lower() == "y":
- itemBrand = input("Enter item brand: ")
- itemVoltage = input("Enter item voltage: ")
- newItem = electricAppliancesClass.electricAppliances(itemCode,itemDescription,itemPrice,itemRentalPrice,itemBrand,itemVoltage)
- else:
- newItem = inventoryClass.inventory(itemCode,itemDescription,itemPrice,itemRentalPrice)
- fullInventory[itemCode] = newItem.returnAsDictionary()
- print("New inventory item added")
-
-
-def itemInfo():
- itemCode = input("Enter item code: ")
- if itemCode in fullInventory:
- printDict = fullInventory[itemCode]
- for k,v in printDict.items():
- print("{}:{}".format(k,v))
- else:
- print("Item not found in inventory")
-
-def exitProgram():
- sys.exit()
-
-if __name__ == '__main__':
- fullInventory = {}
- while True:
- print(fullInventory)
- mainMenu()()
- input("Press Enter to continue...........")
diff --git a/students/template_student/lesson01/assignment/inventory_management/market_prices.py b/students/template_student/lesson01/assignment/inventory_management/market_prices.py
deleted file mode 100755
index a486cc8..0000000
--- a/students/template_student/lesson01/assignment/inventory_management/market_prices.py
+++ /dev/null
@@ -1,3 +0,0 @@
-def get_latest_price(item_code):
- return 24
- # Raise an exception to force the user to Mock its output
\ No newline at end of file
diff --git a/students/template_student/lesson02/assignment/src/charges_calc.py b/students/template_student/lesson02/assignment/src/charges_calc.py
deleted file mode 100755
index 2a4496a..0000000
--- a/students/template_student/lesson02/assignment/src/charges_calc.py
+++ /dev/null
@@ -1,47 +0,0 @@
-'''
-Returns total price paid for individual rentals
-'''
-import argparse
-import json
-import datetime
-import math
-
-def parse_cmd_arguments():
- parser = argparse.ArgumentParser(description='Process some integers.')
- parser.add_argument('-i', '--input', help='input JSON file', required=True)
- parser.add_argument('-o', '--output', help='ouput JSON file', required=True)
-
- return parser.parse_args()
-
-
-def load_rentals_file(filename):
- with open(filename) as file:
- try:
- data = json.load(file)
- except:
- exit(0)
- return data
-
-def calculate_additional_fields(data):
- for value in data.values():
- try:
- rental_start = datetime.datetime.strptime(value['rental_start'], '%m/%d/%y')
- rental_end = datetime.datetime.strptime(value['rental_end'], '%m/%d/%y')
- value['total_days'] = (rental_end - rental_start).days
- value['total_price'] = value['total_days'] * value['price_per_day']
- value['sqrt_total_price'] = math.sqrt(value['total_price'])
- value['unit_cost'] = value['total_price'] / value['units_rented']
- except:
- exit(0)
-
- return data
-
-def save_to_json(filename, data):
- with open(filename, 'w') as file:
- json.dump(data, file)
-
-if __name__ == "__main__":
- args = parse_cmd_arguments()
- data = load_rentals_file(args.input)
- data = calculate_additional_fields(data)
- save_to_json(args.output, data)
diff --git a/students/template_student/lesson04/assignment/src/basic_operations.py b/students/template_student/lesson04/assignment/src/basic_operations.py
deleted file mode 100755
index e69de29..0000000
diff --git a/students/template_student/lesson05/assignment/src/database.py b/students/template_student/lesson05/assignment/src/database.py
deleted file mode 100755
index e69de29..0000000
diff --git a/students/template_student/lesson08/assignment/data/test_items.csv b/students/template_student/lesson08/assignment/data/test_items.csv
deleted file mode 100755
index ce43d9b..0000000
--- a/students/template_student/lesson08/assignment/data/test_items.csv
+++ /dev/null
@@ -1,4 +0,0 @@
-LR01,Small lamp,7.50
-LR02,Television,28.00
-BR07,LED lamp,5.50
-KT08,Basic refrigerator,40.00
\ No newline at end of file
diff --git a/students/template_student/lesson08/assignment/src/inventory.py b/students/template_student/lesson08/assignment/src/inventory.py
deleted file mode 100755
index e69de29..0000000
diff --git a/students/template_student/lesson09/assignment/src/database.py b/students/template_student/lesson09/assignment/src/database.py
deleted file mode 100755
index e69de29..0000000
diff --git a/students/template_student/lesson09/assignment/src/jpgdiscover.py b/students/template_student/lesson09/assignment/src/jpgdiscover.py
deleted file mode 100755
index e69de29..0000000