diff --git a/README.md b/README.md
index 9a0c952..0df43f9 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,82 @@
-# Library Management System
+#
Library Management System
+**A console-based Library Management System that demonstrates understanding of Kotlin's core concepts including OOP, functional programming, collections (HashMaps), recursion, and more.**
+
+
+
+## ❓How To Run
+Navigate to `app/src/main/kotlin/org/example/Main.kt`
+
+Run `fun main()`
+
+## ⭐️ Features
+## 🔶 Object-Oriented Programming ##
+✅ Abstraction
+
+An abstract LibraryItem class with core variables and abstract functions
+
+`app/src/main/kotlin/org/example/LibraryItem.kt`
+
+✅ Inheritance & Polymorphism
+
+Book, DVD and Magazine classes which inherit variables from LibraryItem and uniquely implement abstract functions
+
+`app/src/main/kotlin/org/example/Book.kt`
+`app/src/main/kotlin/org/example/DVD.kt`
+`app/src/main/kotlin/org/example/Magazine.kt`
+
+✅ Encapsulation
+
+A Member class which encapsulates all variables and functions required for Member objects
+
+`app/src/main/kotlin/org/example/Member.kt`
+
+## 🔶 Collections & HashMaps ##
+
+A Library class which uses HashMaps to hold collections of LibraryItems, Members and track Borrowed Items.
+
+`app/src/main/kotlin/org/example/Library.kt`
+
+## 🔶 Functional Programming ##
+
+✅ Higher-Order Functions & Lambdas
+
+findBookByAuthor(), findItemBy()
+
+to specify search by criteria
+
+getLibraryStatistics()
+
+to get formatted display of entire Library data
+
+processOverdueItems()
+
+to process overdue fees on items borrowed by members
+
+`app/src/main/kotlin/org/example/Library.kt`
+
+✅ Extension Functions
+
+Implemented in the Library class fuctions
+
+List.filterByAvailability()
+
+to filter a list of LibraryItems and filter by set Availability (true or false)
+
+String.isValidEmail()
+
+to varify if a certain string is a valid email
+
+LibraryItem.getFormattedInfo()
+
+to obtain a well formatted display of LibraryItem information
+
+`app/src/main/kotlin/org/example/Library.kt`
+
+## 🔶 Recursion ##
+
+calculateCompoundLateFee()
+
+a recursive function which calculates compounded late fees on item based on a base amount and number of days the item is late for return
+
+`app/src/main/kotlin/org/example/RecursiveFunctions.kt`
+
diff --git a/app/src/main/kotlin/org/example/App.kt b/app/src/main/kotlin/org/example/App.kt
deleted file mode 100644
index a1d413b..0000000
--- a/app/src/main/kotlin/org/example/App.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * This source file was generated by the Gradle 'init' task
- */
-package org.example
-
-class App {
- val greeting: String
- get() {
- return "Hello World!"
- }
-}
-
-fun main() {
- println(App().greeting)
-}
diff --git a/app/src/main/kotlin/org/example/Book.kt b/app/src/main/kotlin/org/example/Book.kt
new file mode 100644
index 0000000..ad9dda4
--- /dev/null
+++ b/app/src/main/kotlin/org/example/Book.kt
@@ -0,0 +1,14 @@
+package org.example
+
+class Book(
+ id: String,
+ title: String,
+ val author: String,
+ val isbn: String,
+ val pages: Int
+) : LibraryItem(id, title) {
+ override fun getItemType(): String = "Book"
+ override fun calculateLateFee(daysLate: Int): Double {
+ return daysLate * 0.5
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/example/DVD.kt b/app/src/main/kotlin/org/example/DVD.kt
new file mode 100644
index 0000000..b9a04df
--- /dev/null
+++ b/app/src/main/kotlin/org/example/DVD.kt
@@ -0,0 +1,14 @@
+package org.example
+
+class DVD(
+ id: String,
+ title: String,
+ val director: String,
+ val duration: Int,
+ val genre: String
+) : LibraryItem(id, title) {
+ override fun getItemType(): String = "DVD"
+ override fun calculateLateFee(daysLate: Int): Double {
+ return daysLate * 1.0
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/example/Library.kt b/app/src/main/kotlin/org/example/Library.kt
new file mode 100644
index 0000000..7f8628f
--- /dev/null
+++ b/app/src/main/kotlin/org/example/Library.kt
@@ -0,0 +1,148 @@
+package org.example
+
+import kotlin.math.PI
+import kotlin.math.pow
+
+class Library {
+ // Map of item id to LibraryItem
+ private val itemsById = HashMap()
+
+ // Map of category to list of LibraryItems in category
+ private val itemsByCategory = HashMap>()
+
+ // Map of memberId to Member
+ private val members = HashMap()
+
+ // Map of memberId to Member.borrowedItems
+ private val borrowedItems = HashMap>()
+
+ //library.addItem(Book("B001", "The Kotlin Guide", "John Doe", "978-1234567890", 300))
+ fun addItem(item: LibraryItem) {
+ itemsById[item.id] = item
+ itemsByCategory[item.getItemType()]?.add(item)
+ }
+ //library.registerMember(Member("M001", "Alice Johnson", "alice@email.com"))
+ fun registerMember(member: Member) {
+ members[member.getMemberId()] = member
+ }
+ //borrowItem("M001", "B001")
+ fun borrowItem(memberId: String, itemId: String) {
+
+ var member: Member? = null
+ if(members.contains(memberId)){
+ member = members[memberId]
+ }
+
+ var item: LibraryItem? = null
+ if(itemsById.contains(itemId)) {
+ item = itemsById[itemId]
+ }
+
+ if(member != null && item != null) {
+ member.borrowItem(item)
+ borrowedItems[memberId]?.add(itemId)
+ }
+ }
+
+ fun returningItem(memberId: String, itemId: String) {
+
+ var member: Member? = null
+ if(members.contains(memberId)){
+ member = members[memberId]
+ }
+
+ var item: LibraryItem? = null
+ if(itemsById.contains(itemId)) {
+ item = itemsById[itemId]
+ }
+
+ if(member != null && item != null) {
+ member.returnItem(item)
+ borrowedItems[memberId]?.remove(itemId)
+ }
+ }
+
+ //library.findBooksByAuthor("John Doe")
+ fun findBooksByAuthor(author: String): List {
+//
+ val booksInLibrary = itemsByCategory["Book"] as MutableList?
+
+ val booksByAuthor: MutableList = mutableListOf()
+
+ booksInLibrary?.forEach { book ->
+ if(book.author == author) {
+ booksByAuthor.add(book)
+ }
+ }
+
+ val result = booksByAuthor.toList()
+
+ return result
+ }
+
+
+// fun findItemsBy(
+// type: Class,
+// predicate: (T) -> Boolean
+// ) : List {
+// if((itemsByCategory).any(type))
+//
+// }
+
+ fun getLibraryStatistics(): Map {
+ val numberOfBooks = itemsByCategory["Book"]?.count()
+ val numberOfDVDs = itemsByCategory["DVD"]?.count()
+ val numberOfMagazines = itemsByCategory["Magazine"]?.count()
+
+ val result: Map
+
+ result = mapOf(
+ Pair("Number of Books in Library:",numberOfBooks),
+ Pair("Number of DVDs in Library:",numberOfDVDs),
+ Pair("Number of Magazines in Library:",numberOfMagazines)
+
+ ) as Map
+
+ return result
+ }
+
+ fun processOverdueItems(action: (LibraryItem, Member, Int) -> Unit) {
+
+ }
+
+ fun List.filterByAvailability(available: Boolean): List {
+ val items = itemsById.values
+
+ val resultList: MutableList = mutableListOf()
+
+ items.forEach { item ->
+ if(item.isAvailable == available) {
+ resultList.add(item)
+ }
+ }
+
+ return resultList.toList()
+ }
+
+ fun String.isValidEmail(): Boolean {
+ if(
+ String.toString().contains('@') &&
+ String.toString().contains(".")
+ ) {
+ return true
+ }
+ else {
+ return false
+ }
+ }
+
+// fun LibraryItem.getFormattedInfo(): String {
+// val item: LibraryItem
+// val info: String
+//
+// info = "Item ID: ${item.id}"
+// }
+
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/example/LibraryItem.kt b/app/src/main/kotlin/org/example/LibraryItem.kt
new file mode 100644
index 0000000..a0f790e
--- /dev/null
+++ b/app/src/main/kotlin/org/example/LibraryItem.kt
@@ -0,0 +1,16 @@
+package org.example
+
+abstract class LibraryItem(
+ val id: String,
+ val title: String,
+ var isAvailable: Boolean = true
+) {
+ abstract fun getItemType(): String
+ abstract fun calculateLateFee(daysLate: Int): Double
+
+ open fun displayInfo(): String {
+ return "ID: $id, Title: $title, Available: $isAvailable"
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/example/Magazine.kt b/app/src/main/kotlin/org/example/Magazine.kt
new file mode 100644
index 0000000..a273bbb
--- /dev/null
+++ b/app/src/main/kotlin/org/example/Magazine.kt
@@ -0,0 +1,13 @@
+package org.example
+
+class Magazine(
+ id: String,
+ title: String,
+ val issueNumber: Int,
+ val publisher: String
+) : LibraryItem(id, title) {
+ override fun getItemType(): String = "Magazine"
+ override fun calculateLateFee(daysLate: Int): Double {
+ return daysLate * 0.25
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/example/Main.kt b/app/src/main/kotlin/org/example/Main.kt
new file mode 100644
index 0000000..94fc8a5
--- /dev/null
+++ b/app/src/main/kotlin/org/example/Main.kt
@@ -0,0 +1,54 @@
+/*
+ * This source file was generated by the Gradle 'init' task
+ */
+package org.example
+
+fun main() {
+ val smith= Member("M1", "S", "s")
+ smith.setName("Smith")
+ smith.setEmail("smith.com")
+ smith.setEmail("smith@gmail.com")
+
+ val john = Member("M2", "John", "john@gmail.com")
+
+ val library = Library()
+// Add sample data
+ library.addItem(Book("B1", "The Kotlin Guide", "John Doe", "978-1234567890", 300))
+ library.addItem(Book("B2", "Harry Potter", "JK", "1111-222", 122))
+ library.addItem(DVD("D1", "Kotlin Tutorial", "Jane Smith", 120, "Educational"))
+ library.addItem(Magazine("Z1", "Times Magazine", 25, "NY-Times"))
+
+// Register member
+ library.registerMember(Member("M3", "Alice Johnson", "alice@email.com"))
+ library.registerMember(smith)
+ library.registerMember(john)
+
+ val libraryStats = library.getLibraryStatistics()
+ println("Library Stats: $libraryStats")
+
+// Demonstrate borrowing
+ library.borrowItem("M1", "B1")
+ library.borrowItem("M2", "B1")
+ library.borrowItem("M2", "B2")
+ library.borrowItem("M2", "D1")
+ library.borrowItem("M3", "Z1")
+
+//Demostrate returning
+ library.returningItem("M1", "B2")
+ library.returningItem("M1", "B1")
+
+ smith.totalLateFees(5)
+ john.totalLateFees(5)
+// Show functional programming
+ val availableBooks = library.findBooksByAuthor("John Doe")
+ .filter { it.isAvailable }
+// .map { it.getFormattedInfo() }
+ println("Available books by John Doe:")
+ availableBooks.forEach { book ->
+ println(book.title)
+ }
+//// Demonstrate recursion
+ val compoundFee = calculateCompoundLateFee(5.0, 7)
+ println("Compound late fee for 7 days: $$compoundFee")
+
+}
diff --git a/app/src/main/kotlin/org/example/Member.kt b/app/src/main/kotlin/org/example/Member.kt
new file mode 100644
index 0000000..cc3a22a
--- /dev/null
+++ b/app/src/main/kotlin/org/example/Member.kt
@@ -0,0 +1,64 @@
+package org.example
+
+class Member(
+ private val memberId: String,
+ private var name: String,
+ private var email: String
+) {
+ private val borrowedItems = mutableListOf()
+
+ fun getMemberId(): String = memberId
+ fun getName(): String = name
+ fun getEmail(): String = email
+
+ fun setName(memberName: String) {
+ name = memberName
+ println("Member Name set to $name")
+ }
+ fun setEmail(memberEmail: String) {
+ if(
+ memberEmail.contains('@')
+ &&
+ memberEmail.contains('.')
+ ) {
+ email = memberEmail
+ println("Member Email set to $email")
+ } else {
+ println("invalid email")
+ }
+ }
+
+ fun borrowItem(item: LibraryItem) {
+ if(item.isAvailable) {
+ borrowedItems.add(item)
+ item.isAvailable = false
+ println("Member $memberId $name borrowed item ${item.id} ${item.title}")
+ }
+ else {
+ println("item unavailable")
+ }
+ }
+
+ fun returnItem(item: LibraryItem) {
+ if(borrowedItems.contains(item)) {
+ borrowedItems.remove(item)
+ item.isAvailable = true
+ println("Member $memberId $name returned item ${item.id} ${item.title}")
+ } else {
+ println("Member $memberId $name did not borrow this item")
+ }
+ }
+
+ fun totalLateFees(daysLate: Int) {
+ if(borrowedItems.isEmpty()) {
+ println("$name borrowed no items")
+ }
+ else {
+ var total = 0.0
+ borrowedItems.forEach { item ->
+ total += item.calculateLateFee(daysLate)
+ }
+ println("$name Total Late Fees = $$total")
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/example/RecursiveFunctions.kt b/app/src/main/kotlin/org/example/RecursiveFunctions.kt
new file mode 100644
index 0000000..36f9f8b
--- /dev/null
+++ b/app/src/main/kotlin/org/example/RecursiveFunctions.kt
@@ -0,0 +1,15 @@
+package org.example
+
+fun calculateCompoundLateFee(baseFee: Double, days: Int): Double {
+ // Using Math
+// val fee: Double = baseFee * (1.05).pow(days)
+// return fee
+
+ // Recursive Function
+ var fee = baseFee
+ if(days != 0) {
+ fee = fee + baseFee * 1.05
+ calculateCompoundLateFee(baseFee = fee, days = days - 1 )
+ }
+ return fee
+}
\ No newline at end of file
diff --git a/app/src/main/resources/cmd.png b/app/src/main/resources/cmd.png
new file mode 100644
index 0000000..02d0548
Binary files /dev/null and b/app/src/main/resources/cmd.png differ
diff --git a/app/src/main/resources/kotlin.png b/app/src/main/resources/kotlin.png
new file mode 100644
index 0000000..9222d0e
Binary files /dev/null and b/app/src/main/resources/kotlin.png differ
diff --git a/app/src/main/resources/library.png b/app/src/main/resources/library.png
new file mode 100644
index 0000000..50a68b0
Binary files /dev/null and b/app/src/main/resources/library.png differ