Final Code
MOCK FINAL EXAM – SET 1
Theme: Library System (Books & Borrowing)
Task 1 – Abstract Class LibraryItem
Create an abstract class LibraryItem with:
Non-public attributes:
_title,_year_publishedGetters/setters with validation:
title– cannot be empty stringyear_published– must be between 1450 and current year (use2026as current)
Raise
ValueErrorfor invalid valuesAbstract method:
get_info()
Task 2 – Class Book inherits from LibraryItem
Add non-public attributes:
_isbn(string)_borrow_history(list of integers representing days borrowed per transaction)
Implement:
Getters for ISBN and borrow history
get_info()returns formatted stringaverage_borrow_duration()– average days per borrowingOverride
__iadd__– adds a valid borrow duration (integer > 0) to historyOverride
__len__– returns number of borrow transactions
Task 3 – CSV Processing
CSV file (library_borrows.csv):
text
isbn;title;year;days_borrowed
978-3-16-148410-0;Python Basics;2020;14
978-0-13-468599-1;Data Structures;2019;21
978-3-16-148410-0;Python Basics;2020;7
978-0-596-52068-7;Learning Java;2018;30
978-0-13-468599-1;Data Structures;2019;10
978-3-16-148410-0;Python Basics;2020;28Read CSV, group by ISBN, create Book objects, accumulate borrow histories.
Task 4 – JSON Processing
Same data as JSON (library_borrows.json):
json
[
{"isbn": "978-3-16-148410-0", "title": "Python Basics", "year": 2020, "days_borrowed": 14},
{"isbn": "978-0-13-468599-1", "title": "Data Structures", "year": 2019, "days_borrowed": 21},
{"isbn": "978-3-16-148410-0", "title": "Python Basics", "year": 2020, "days_borrowed": 7},
{"isbn": "978-0-596-52068-7", "title": "Learning Java", "year": 2018, "days_borrowed": 30},
{"isbn": "978-0-13-468599-1", "title": "Data Structures", "year": 2019, "days_borrowed": 10},
{"isbn": "978-3-16-148410-0", "title": "Python Basics", "year": 2020, "days_borrowed": 28}
]Repeat grouping process from Task 3.
Task 5 – Output
Print each book:
text
Title: Python Basics, borrows: 3, average days: 16.33
Title: Data Structures, borrows: 2, average days: 15.50
Title: Learning Java, borrows: 1, average days: 30.00Task 6 – Unit Tests
Write unittest tests for:
LibraryItem–year_publishedsetter:Valid: 2000
Invalid: 1400 (too old), 2030 (future)
Book.__iadd__:Valid:
book + 15Invalid:
book + -5(negative days)Invalid:
book + "ten"(wrong type)
final.py:
#mock final exam set 1 - Library system
from abc import ABC, abstractmethod
import csv
import json
#task 1
class LibraryItem(ABC):
def __init__(self, title, year_published):
self._title = title
self._year_published = year_published
def get_title(self):
return self._title
def get_year_published(self):
return self._year_published
"""
INCORRECT
def set_title(self, title):
try:
if title == "":
print("Title cannot be empty")
else:
self._title = title
raise ValueError("Title cannot be empty")
"""
#CORRECT
def set_title(self, title):
if not title:
raise ValueError("Title cannot be empty")
self._title = title
"""
INCORRECT
def set_year_published(self, year_published):
try:
if 1450<= year_published <=2026:
self._year_published = year_published
else:
print("Year published is out of range")
raise ValueError("Year published is out of range")
"""
def set_year_published(self, year_published):
if not 1450<=year_published<=2026:
raise ValueError("Year published cannot be empty")
self._year_published = year_published
@abstractmethod
def get_info(self):
pass
#task 2
class Book(LibraryItem):
def __init__(self, title, year_published, isbn):
super().__init__(title, year_published)
self._isbn = isbn
self._borrow_history = []
def get_isbn(self):
return self._isbn
def get_borrow_history(self):
return self._borrow_history
def get_info(self):
return f"{self._title} is published on {self._year_published}, was borrowed on {self._borrow_history}"
def average_borrow_duration(self):
return sum(self._borrow_history) / len(self._borrow_history)
"""
INCORRECT
def __iadd__(self, other):
try:
if self._borrow_history is int and self._borrow_history > 0:
return self._borrow_history.append(other)
else:
self._borrow_history = other._borrow_history
raise ValueError("Must be more than 0")
"""
def __iadd__(self, other):
if not isinstance(other, int) or other <=0:
raise ValueError("Must be more than 0")
self._borrow_history.append(other)
return self
def __len__(self):
return len(self._borrow_history)
#task 3
def ex1():
books = {}
with open("library_borrows.csv") as file:
reader = csv.reader(file, delimiter=';')
next(reader)
for row in reader:
isbn = row[0]
title = row[1]
year_published = int(row[2])
borrow_history = int(row[3])
if isbn not in books:
books[isbn] = Book(title, year_published) #create the Book
books[isbn] += borrow_history
return books
"""
isbn_group = list(filter(_isbn)) #don't know/remember how to group by isbn
book1= "978-0-13-468599-4;Data Analysis;2021;10" #i guess this is how we create Book objects
#accumulate borrow histories - don't even know how to attempt
"""
#task 4 - json processing - to be frank, i don't know anything in python about how to wrok with json, especially
#how to pivot from csv to json, please show me full code, functionalities
def ex1():
books = {}
with open("library_borrows.json") as file:
reader = json.load(file)
for row in reader:
isbn = row["isbn"]
title = row["title"]
year_published = int(row["year_published"])
borrow_history = int(row["borrow_history"])
if isbn not in books:
books[isbn] = Book(title, year_published, isbn)
books[isbn] += borrow_history
return books
#task 5 - output
for book in books.values():
print(f"Title: {book._title}, borrows: {book._borrow_history}, "
f"average days: {book.average_borrow_duration}")
test_final.py
import unittest
from final2 import Book
#task 6 - unit tests
class MyTestCase(unittest.TestCase):
def setUp(self):
self.book = Book("Python Basics", 2020, "978-3-16-148410-0")
#again - i don't remember syntax for unit tests, don't even know how to start and logic for writing it
#updated
def test_year_validation(self):
self.book.set_year_published(2000)
self.assertEqual(self.book.get_year_published(), 2000)
def test_year_failure(self):
with self.assertRaises(ValueError):
self.book.set_year_published(1400)
with self.assertRaises(ValueError):
self.book.set_year_published(2030)
def test_iadd_valid(self):
self.book +=15
self.assertEqual(len(self.book), 1)
self.assertEqual(self.book.get_borrow_history(), [15])
def test_iadd_failure(self):
with self.assertRaises(ValueError):
self.book += -5
with self.assertRaises(ValueError):
self.book += "ten"
if __name__ == '__main__':
unittest.main()
MOCK FINAL EXAM – SET 2
Theme: E-commerce (Products & Reviews)
Task 1 – Abstract Class Product
Create abstract class Product with:
Non-public attributes:
_name,_priceGetters/setters with validation:
name– non-empty, at least 3 charactersprice– must be > 0 (float or int)
Raise
ValueErrorfor violationsAbstract method:
get_details()
Task 2 – Class ReviewedProduct inherits from Product
Add non-public attributes:
_sku(string, stock keeping unit)_ratings(list of integers 1–5)
Implement:
Getters for SKU and ratings
get_details()returns product infoaverage_rating()– mean of ratingsOverride
__iadd__– adds valid rating (1–5 integer only)Override
__len__– number of ratings
Task 3 – CSV Processing
CSV file (product_reviews.csv):
text
sku;name;price;rating
SKU100;Wireless Mouse;25.99;5
SKU200;Mechanical Keyboard;89.50;4
SKU100;Wireless Mouse;25.99;3
SKU300;USB Cable;12.99;5
SKU200;Mechanical Keyboard;89.50;5
SKU100;Wireless Mouse;25.99;4
SKU200;Mechanical Keyboard;89.50;2Read CSV, group by SKU, create ReviewedProduct objects, accumulate ratings.
Task 4 – JSON Processing
Same data as JSON (product_reviews.json):
json
[
{"sku": "SKU100", "name": "Wireless Mouse", "price": 25.99, "rating": 5},
{"sku": "SKU200", "name": "Mechanical Keyboard", "price": 89.50, "rating": 4},
{"sku": "SKU100", "name": "Wireless Mouse", "price": 25.99, "rating": 3},
{"sku": "SKU300", "name": "USB Cable", "price": 12.99, "rating": 5},
{"sku": "SKU200", "name": "Mechanical Keyboard", "price": 89.50, "rating": 5},
{"sku": "SKU100", "name": "Wireless Mouse", "price": 25.99, "rating": 4},
{"sku": "SKU200", "name": "Mechanical Keyboard", "price": 89.50, "rating": 2}
]Repeat grouping.
Task 5 – Output
Print each product:
text
Name: Wireless Mouse, ratings: 3, average: 4.00
Name: Mechanical Keyboard, ratings: 3, average: 3.67
Name: USB Cable, ratings: 1, average: 5.00Task 6 – Unit Tests
Test:
Product–pricesetter:Valid: 29.99
Invalid: 0, -10
ReviewedProduct.__iadd__:Valid:
product + 5Invalid:
product + 6(too high),product + 0(too low)
final3.py:
#MOCK FINAL EXAM – SET 2 Theme: E-commerce (Products & Reviews)
import csv
from abc import ABC, abstractmethod
import json
#task1
class Product(ABC):
def __init__(self, name, price):
self._name = name
self._price = price
def get_name(self):
return self._name
def get_price(self):
return self._price
def set_name(self, name):
if not name or len(name)<3:
raise ValueError("Invalid name")
self._name = name
def set_price(self, price):
if not isinstance(price, int) or not isinstance(price, float):
raise ValueError('Price must be a positive integer')
self._price = price
@abstractmethod
def get_details(self):
pass
#task 2
class ReviewedProduct(Product):
def __init__(self, name, price, sku):
super().__init__(name, price)
self._sku = sku
self._ratings = []
def get_sku(self):
return self._sku
def get_ratings(self):
return self._ratings
def get_details(self):
return f"{self._name} costs {self._price}. There's {len(self._ratings)} ratings and {len(self._sku)} units in stock"
def average_rating(self):
return sum(self._ratings)/len(self._ratings)
def __iadd__(self, other):
if self.other <=1 or self.other >=5:
raise ValueError("The other must be greater than or equal to 5")
elif not isinstance(other, int):
raise ValueError('The other must be an integer')
else:
self._ratings.append(other)
return self
def __len__(self):
return len(self._ratings)
#task 3
def ex1():
reviewed = {}
with open('product_reviews.csv') as file:
next(file)
reader = csv.reader(file, delimiter = ';')
for row in reader:
name = row[1]
price = float(row[2])
sku = row[0]
ratings = int(row[3])
if sku not in reviewed:
reviewed[sku] = ReviewedProduct(name, price, sku)
reviewed[sku] += ratings
return reviewed
#task 4
def ex2():
reviewed = {}
with open('product_reviews.json') as file:
reader = json.load(file)
for row in reader:
name = row["name"]
price = float(row["price"])
sku = row["sku"]
rating = int(row["ratings"])
if sku not in reviewed:
reviewed[sku] = ReviewedProduct(name, price, sku)
reviewed[sku] += rating
return reviewed
#task 5
def print_products(reviewed):
for review in reviewed.values():
print(f"Name:{review.get_name}, rating: {len(review)}, average: {review.average_rating()}")
test_final3.py:
import unittest
from final3 import *
#task 6
class MyTestCase(unittest.TestCase):
def setUp(self):
self.product = ReviewedProduct("Wireless Kitten",25.99, "SKU100")
def test_get_price_success(self):
self.product.set_price(29.98)
self.assertEqual(self.product.get_price(), 29.99)
def test_get_price_zero(self):
with self.assertRaises(ValueError):
self.product.set_price(0)
def test_get_price_negative(self):
with self.assertRaises(ValueError):
self.product.set_price(-1)
def test_iadd_reviewed_product_success(self):
self.product +=5
self.assertEqual(len(self.product), 1)
self.assertEqual(self.product.get_ratings(), [5])
def test_iadd_reviewed_product_failure(self):
with self.assertRaises(ValueError):
self.product +=6
def test_iadd_reviewed_product_zero(self):
with self.assertRaises(ValueError):
self.product +=0
if __name__ == '__main__':
unittest.main()