diff --git a/Layout.puml b/Layout.puml new file mode 100644 index 0000000..24dc0b9 --- /dev/null +++ b/Layout.puml @@ -0,0 +1,52 @@ +@startuml + +class Book { + - id : int + - title : String + - author : String + - isAvailable : boolean + + Book(id : int, title : String, author : String) + + getId() : int + + setId(id : int) : void + + getTitle() : String + + setTitle(title : String) : void + + getAuthor() : String + + setAuthor(author : String) : void + + isAvailable() : boolean + + setAvailable(available : boolean) : void + + toString() : String +} + +class Library { + - books : ArrayList + - nextBookId : int + + Library() + + addBook(title : String, author : String) : void + + displayAllBooks() : void + + displayAvailableBooks() : void + + displayBorrowedBooks() : void + + borrowBookById(id : int) : void + + returnBookById(id : int) : void + + searchBookById(id : int) : void + + searchBookByTitle(title : String) : void + - findBookById(id : int) : Book +} + +class Main { + + main(args : String[]) : void + + startApplication(scanner : Scanner, library : Library) : void + + printMenu() : void + + getValidatedMenuChoice(scanner : Scanner) : int + + addStarterBooks(library : Library) : void + + addBook(scanner : Scanner, library : Library) : void + + borrowBook(scanner : Scanner, library : Library) : void + + returnBook(scanner : Scanner, library : Library) : void + + searchBook(scanner : Scanner, library : Library) : void + + getValidatedSearchChoice(scanner : Scanner) : int + + getValidatedPositiveNumber(scanner : Scanner) : int +} + +Library "1" --> "*" Book : manages +Main --> Library : uses + +@enduml \ No newline at end of file diff --git a/M&WREADME.md b/M&WREADME.md new file mode 100644 index 0000000..d1c1073 --- /dev/null +++ b/M&WREADME.md @@ -0,0 +1,246 @@ +# Library Book Tracker +## The Mission + +This project is an application that simulates a small library management system. + +The goal of the project is to demonstrate our ability to: + +* Design a real-world software system + +* Structure a Java program using multiple classes + +* Collaborate with a partner using Git and GitHub + +* Explain the technical decisions behind our code + +The application allows users to add books, view books, borrow books, return books, and search for books. + +# Theme: Everyday Application + +This project represents a real-world system that libraries use to track books and their availability. + +The program helps users manage a collection of books by assigning each book a unique ID, making it easier to borrow and return books without typing the full title. + +# Team Structure + +This project was completed in pairs. + +Using concepts from Scrum, we organized development into three sprint phases. + +Each sprint represents a stage of the development process: + +* Planning + +* Building + +* Reflecting + +# Sprint Documentation +## Sprint 1 — The Plan +### Problem + +Libraries need a simple way to track which books are available and which are borrowed. +This application provides a command line system that allows users to manage books in a small library. + +### Planned Features + +* Add books + +* View all books + +* Borrow books + +* Return books + +* Search for books + +* Exit the program + +### Planned Classes + +* Book – represents individual books + +* Library – manages the collection of books + +* Main – handles the user interface and program flow + +### Work Division + +### William + +* Designed the Book class + +* Created the UML diagram + +* Helped design the system structure + +### Mesheik +* Built the CLI menu system + +* Implemented input validation + +* Managed user interaction + +## Both of us + +* Built and tested the Library class + +* Implemented borrowing and returning logic + +* Tested the full application + +# Sprint 2 — The Build +## What We Implemented + +The finished program allows users to: + +* Add books to the system + +* View all books + +* View available books + +* View borrowed books + +* Borrow books using a Book ID + +* Return books using a Book ID + +* Search books by ID or title + +### Changes From the Original Plan + +During development we improved the system by: + +* Adding a unique ID system for books + +* Implementing input validation to prevent crashes + +* Organizing the code into smaller helper methods for readability + +### Challenges + +Some challenges we faced included: + +* Designing a system to generate unique book IDs + +* Validating user input from the command line + +* Organizing responsibilities between classes + +### Solutions + +We solved these challenges by: + +* Using a nextBookId counter in the Library class + +* Creating reusable input validation methods + +* Separating logic between Book, Library, and Main + +## Sprint 3 — The Reflection +### What Works Well + +The program is organized and demonstrates strong use of object-oriented programming. + +The Book ID system improves usability because users can borrow and return books without typing the exact title. + +### Future Improvements + +If we had more time, we would add: + +* Removing books from the system + +* Saving book data to files + +* Book categories or genres + +* Sorting and filtering options + +### Java Concepts Used + +This project demonstrates several key Java concepts: + +* Classes and Objects + +* Constructors + +* Methods + +* Encapsulation + +* Loops + +* Conditional statements + +* Collections (ArrayList) + +* User input using Scanner + +### What We Learned + +Through this project we learned how to: + +* Design a Java application from scratch + +* Organize code into multiple classes + +* Collaborate using Git and GitHub + +* Apply Java fundamentals to a real-world problem + +## Code Explanation Requirement + +Our code includes comments explaining technical decisions, such as: + +* Why certain classes were created + +* Why ArrayList was used to store books + +* Why loops are used to iterate through book collections + +* Why input validation methods were implemented + + +## Technical Expectations + +This project demonstrates the following Java skills: + +* Classes and Objects + +* Constructors + +* Methods + +* Encapsulation (getters/setters) + +* Loops + +* Conditional statements + +* Collections (ArrayList) + +* User input using Scanner + +* Clean program organization + + +Final Goal + +This project demonstrates that we can: + +* Design software without step-by-step instructions + +* Apply Java concepts to solve a real problem + +* Work collaboratively using Git and GitHub + +* Explain our code and technical decisions + +The project reinforces the Java concepts learned throughout the course and prepares us for the final Java assessment. + +## Contributors + +* Mesheik Brown + +* William Blue \ No newline at end of file diff --git a/src/main/java/LibraryBookTracker/Book.java b/src/main/java/LibraryBookTracker/Book.java new file mode 100644 index 0000000..b536adb --- /dev/null +++ b/src/main/java/LibraryBookTracker/Book.java @@ -0,0 +1,71 @@ +package LibraryBookTracker; + +public class Book { + + + // Private fields + private String title; + private String author; + private boolean isAvailable; + private int id; + + // Constructor + public Book(int id, String title, String author) { + this.title = title; + this.author = author; + this.isAvailable = true; // default value + this.id = id; + } + + + // Getter for title + public int getId() { + return id; + } + + public String getTitle() { + return title; + } + + // Setter for title + public void setTitle(String title) { + this.title = title; + } + + // Getter for author + public String getAuthor() { + return author; + } + + // Setter for author + public void setAuthor(String author) { + this.author = author; + } + + // Check availability + public boolean isAvailable() { + return isAvailable; + } + + // Set availability + public void setAvailable(boolean available) { + this.isAvailable = available; + } + + // toString method + + @Override + public String toString() { + String status; + + if (isAvailable) { + status = "Available"; + } else { + status = "Borrowed"; + } + + return "ID: " + id + " | Title: " + title + " | Author: " + author + " | Status: " + status; + + } + } + diff --git a/src/main/java/LibraryBookTracker/Library.java b/src/main/java/LibraryBookTracker/Library.java new file mode 100644 index 0000000..863c03c --- /dev/null +++ b/src/main/java/LibraryBookTracker/Library.java @@ -0,0 +1,156 @@ +package LibraryBookTracker; + +import java.util.ArrayList; + +public class Library { + + // Using ArrayList because the number of books can grow as users add more + private ArrayList books; + + // This keeps track of the next ID to assign to a new book + private int nextBookId; + + // Constructor creates the book list and starts IDs at 1 + public Library() { + books = new ArrayList<>(); + nextBookId = 1; + } + + // Creates and adds a new book using the next available ID + public void addBook(String title, String author) { + Book newBook = new Book(nextBookId, title, author); + books.add(newBook); + nextBookId++; + + System.out.println("Book added successfully."); + System.out.println(newBook); + } + + // Displays every book in the system + public void displayAllBooks() { + if (books.isEmpty()) { + System.out.println("No books in the library."); + return; + } + + System.out.println("\n--- All Books ---"); + for (Book book : books) { + System.out.println(book); + } + } + + // Displays only books that are currently available + public void displayAvailableBooks() { + boolean foundAvailable = false; + + System.out.println("\n--- Available Books ---"); + for (Book book : books) { + if (book.isAvailable()) { + System.out.println(book); + foundAvailable = true; + } + } + + if (!foundAvailable) { + System.out.println("No available books right now."); + } + } + + // Displays only books that are currently borrowed + public void displayBorrowedBooks() { + boolean foundBorrowed = false; + + System.out.println("\n--- Borrowed Books ---"); + for (Book book : books) { + if (!book.isAvailable()) { + System.out.println(book); + foundBorrowed = true; + } + } + + if (!foundBorrowed) { + System.out.println("No borrowed books right now."); + } + } + + // Lets the user borrow a book using its unique ID + public void borrowBookById(int id) { + Book book = findBookById(id); + + if (book == null) { + System.out.println("Book not found."); + return; + } + + if (!book.isAvailable()) { + System.out.println("That book is already borrowed."); + return; + } + + book.setAvailable(false); + System.out.println("You borrowed: " + book.getTitle()); + } + + // Lets the user return a book using its unique ID + public void returnBookById(int id) { + Book book = findBookById(id); + + if (book == null) { + System.out.println("Book not found."); + return; + } + + if (book.isAvailable()) { + System.out.println("That book is already available."); + return; + } + + book.setAvailable(true); + System.out.println("You returned: " + book.getTitle()); + } + + // Searches for a book by ID + public void searchBookById(int id) { + Book book = findBookById(id); + + if (book == null) { + System.out.println("Book not found."); + } else { + System.out.println("Book found:"); + System.out.println(book); + } + } + + // Searches for books by title + // Using contains() makes searching more flexible than exact matching + public void searchBookByTitle(String title) { + boolean found = false; + + //This code loops through a list of books and checks if each book’s title contains the user’s search term. + // It converts both strings to lowercase to make the search case-insensitive, + // prints any matching books, and shows a message if no matches are found. + + System.out.println("\n--- Search Results ---"); + for (Book book : books) { + if (book.getTitle().toLowerCase().contains(title.toLowerCase())) { + System.out.println(book); + found = true; + } + } + + if (!found) { + System.out.println("No books matched that title."); + } + } + + // Helper method used to find one book by its unique ID + // Keeping this logic in one place avoids repeated code + private Book findBookById(int id) { + for (Book book : books) { + if (book.getId() == id) { + return book; + } + } + return null; + } +} \ No newline at end of file diff --git a/src/main/java/LibraryBookTracker/Main.java b/src/main/java/LibraryBookTracker/Main.java new file mode 100644 index 0000000..4b59e69 --- /dev/null +++ b/src/main/java/LibraryBookTracker/Main.java @@ -0,0 +1,195 @@ +package LibraryBookTracker; + +import java.util.Scanner; + +public class Main { + + public static void main(String[] args) { + + // Scanner reads user input from the keyboard + Scanner scanner = new Scanner(System.in); + + // One Library object manages the whole system + Library library = new Library(); + + // Add starter books so the app has data at launch + addStarterBooks(library); + + // Start the menu loop + startApplication(scanner, library); + + // Close scanner at the end of the program + scanner.close(); + } + + // Controls the main loop of the application + public static void startApplication(Scanner scanner, Library library) { + boolean running = true; + + while (running) { + printMenu(); + int choice = getValidatedMenuChoice(scanner); + + switch (choice) { + case 1: + addBook(scanner, library); + break; + case 2: + library.displayAllBooks(); + break; + case 3: + library.displayAvailableBooks(); + break; + case 4: + library.displayBorrowedBooks(); + break; + case 5: + borrowBook(scanner, library); + break; + case 6: + returnBook(scanner, library); + break; + case 7: + searchBook(scanner, library); + break; + case 8: + System.out.println("Thank you for visiting M&W Library !"); + running = false; + break; + } + } + } + + // Prints the main menu for the user + public static void printMenu() { + System.out.println("\n===== M&W Library Book Tracker ====="); + System.out.println("1. Add a book"); + System.out.println("2. View all books"); + System.out.println("3. View available books"); + System.out.println("4. View borrowed books"); + System.out.println("5. Borrow a book by ID"); + System.out.println("6. Return a book by ID"); + System.out.println("7. Search for a book"); + System.out.println("8. Exit"); + System.out.print("Choose an option (1-8): "); + } + + // Validates menu input so the program does not crash on bad input + public static int getValidatedMenuChoice(Scanner scanner) { + while (true) { + if (!scanner.hasNextInt()) { + System.out.println("Invalid input. Please enter a number."); + scanner.next(); + continue; + } + + int choice = scanner.nextInt(); + scanner.nextLine(); + + if (choice >= 1 && choice <= 8) { + return choice; + } + + System.out.println("Invalid menu option. Please choose 1-8."); + } + } + + // Adds starter books to make the program easier to test + public static void addStarterBooks(Library library) { + library.addBook("The Hobbit", "J.R.R. Tolkien"); + library.addBook("Maze Runner", "James Dashner"); + library.addBook("To Kill a Mockingbird", "Harper Lee"); + library.addBook("The Godfather", "Mario Puzo"); + library.addBook("Harry Potter", "J. K. Rowling"); + //"Charlie and the Chocolate Factory" by Roald Dahl + } + + // Collects input for a new book and sends it to the Library + public static void addBook(Scanner scanner, Library library) { + System.out.print("Enter book title: "); + String title = scanner.nextLine(); + + System.out.print("Enter author name: "); + String author = scanner.nextLine(); + + library.addBook(title, author); + } + + // Lets the user borrow a book by entering the book's ID + public static void borrowBook(Scanner scanner, Library library) { + System.out.print("Enter the ID of the book to borrow: "); + int id = getValidatedPositiveNumber(scanner); + library.borrowBookById(id); + } + + // Lets the user return a book by entering the book's ID + public static void returnBook(Scanner scanner, Library library) { + System.out.print("Enter the ID of the book to return: "); + int id = getValidatedPositiveNumber(scanner); + library.returnBookById(id); + } + + // Gives the user two search options: by ID or by title + public static void searchBook(Scanner scanner, Library library) { + System.out.println("Search by:"); + System.out.println("1. ID"); + System.out.println("2. Title"); + System.out.print("Choose an option: "); + + //This method acts like a menu for searching books. + // It asks the user whether they want to search by ID or title, validates the input, + // Also then sends that value to the appropriate search method in the Library class. + + int searchChoice = getValidatedSearchChoice(scanner); + + if (searchChoice == 1) { + System.out.print("Enter book ID: "); + int id = getValidatedPositiveNumber(scanner); + library.searchBookById(id); + } else { + System.out.print("Enter book title: "); + String title = scanner.nextLine(); + library.searchBookByTitle(title); + } + } + + // Validates search menu options + public static int getValidatedSearchChoice(Scanner scanner) { + while (true) { + if (!scanner.hasNextInt()) { + System.out.println("Invalid input. Please enter a number."); + scanner.next(); + continue; + } + + int choice = scanner.nextInt(); + scanner.nextLine(); + + if (choice == 1 || choice == 2) { + return choice; + } + + System.out.println("Please choose 1 or 2."); + } + } + + // Validates positive number input for book IDs + public static int getValidatedPositiveNumber(Scanner scanner) { + while (true) { + if (!scanner.hasNextInt()) { + System.out.println("Invalid input. Please enter a number."); + scanner.next(); + continue; + } + + int number = scanner.nextInt(); + scanner.nextLine(); + + if (number > 0) { + return number; + } + + System.out.println("Please enter a number greater than 0."); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/codedifferently/maxxblue/Book.java b/src/main/java/org/codedifferently/maxxblue/Book.java new file mode 100644 index 0000000..52551c6 --- /dev/null +++ b/src/main/java/org/codedifferently/maxxblue/Book.java @@ -0,0 +1,56 @@ +package org.codedifferently.maxxblue; + +public class Book { + + + // Private fields + private String title; + private String author; + private boolean isAvailable; + + // Constructor + public Book(String title, String author) { + this.title = title; + this.author = author; + this.isAvailable = true; // default value + } + + // Getter for title + public String getTitle() { + return title; + } + + // Setter for title + public void setTitle(String title) { + this.title = title; + } + + // Getter for author + public String getAuthor() { + return author; + } + + // Setter for author + public void setAuthor(String author) { + this.author = author; + } + + // Check availability + public boolean isAvailable() { + return isAvailable; + } + + // Set availability + public void setAvailable(boolean available) { + this.isAvailable = available; + } + + // toString method + @Override + public String toString() { + return "Book Title: " + title + + ", Author: " + author + + ", Available: " + isAvailable; + } + } +