diff --git a/README.md b/README.md index e69de29..0aa0bc4 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,125 @@ +# πŸ§™β€β™‚οΈ Workshop: Hogwarts School System - A Magical OOP Adventure + +## Welcome, Young Wizard! + +> *"The sorting hat has placed you in Gryffindor... No, wait! It placed you in the **Java Development** house!"* + +Welcome to the **Hogwarts School System** workshop! This magical journey will help you master the fundamentals of **Object-Oriented Programming (OOP)** through a fun, wizard-themed project. + +--- + +## 🎯 Workshop Objectives + +By completing this workshop, you will learn and practice: + +| Concept | How it's used in this project | +|---------|-------------------------------| +| **Encapsulation** | Private fields with public getters/setters | +| **Inheritance** | `Student` and `Teacher` extend `User` | +| **Polymorphism** | Different user types with same methods | +| **Abstraction** | Abstract `User` class with common behavior | +| **Lists & Collections** | Managing students, teachers, and courses with `ArrayList` | +| **Input Validation** | Validating usernames and passwords | +| **ID-based Selection** | Finding courses by unique ID instead of name | + +--- + +## 🏰 Storyline + +*Professor Dumbledore has asked you to help modernize Hogwarts! The old parchment-based course enrollment system is a disaster. Students keep signing up for the wrong classes, and Professor Snape is furious because his Potions class is full of first-year students who can't tell a bezoar from a newt's eye.* + +*Your mission: Build a digital School Management System that allows:* + +- *Students to view available courses and enroll using magical Course IDs* +- *Teachers to create new courses and manage their classes* +- *Everyone to log in securely (even Filch needs to check who's where)* + +--- + +## πŸ“š Class Hierarchy Diagram + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ User β”‚ + β”‚ (Abstract) β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ +β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β” +β”‚ Student β”‚ β”‚ Teacher β”‚ +β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ + β”‚ β”‚ +β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β” +β”‚enrolled β”‚ β”‚ myCourses β”‚ +β”‚ Courses β”‚ β”‚ (List) β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Course β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ - id (static) β”‚ +β”‚ - name β”‚ +β”‚ - teacher β”‚ +β”‚ - students β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β”‚ contains + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ SchoolSystem β”‚ +β”‚ (Service) β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + +--- + + + + + +--- + +## πŸ“‹ Complete TODO List + +### πŸ”§ Student.java (3 TODOs) + +| # | Method | Description | +|---|--------|-------------| +| 1 | `enrollInCourse(Course course)` | Register student in a course | +| 2 | `showMyCourses()` | Display all enrolled courses | +| 3 | `getEnrolledCourses()` | Return list of enrolled courses | + +### πŸ”§ SchoolSystem.java (5 TODOs) + +| # | Method | Description | +|---|--------|-------------| +| 4 | `registerStudent(String username, String password)` | Register new student | +| 5 | `loginStudent(String username, String password)` | Student login | +| 6 | `findStudent(String username)` | Find student by username (private) | +| 7 | `addCourseToSystem(String courseName)` | Add new course to system | +| 8 | `findCourseById(int id)` | Find course by ID | + +### πŸ”§ Main.java (4 TODOs) + +| # | Location | Description | +|---|----------|-------------| +| 9 | `registerMenu()` - case 1 | Student registration | +| 10 | `loginMenu()` - case 1 | Student login | +| 11 | `studentMenu()` - case 3 | Show my courses | +| 12 | `enrollInCourse(Student student)` | Enroll logic | + +### πŸ“Š Summary + +| File | TODO Count | +|------|------------| +| Student.java | 3 | +| SchoolSystem.java | 5 | +| Main.java | 4 | +| **Total** | **12** | + +--- + +## ℹ️ Note + +> This exercise is for practice only and has no bouns. +> Students can complete it in class with TA assistance. + +**Good luck, young wizard!** ✨ \ No newline at end of file diff --git a/pom.xml b/pom.xml index 88887c4..8fe5d97 100644 --- a/pom.xml +++ b/pom.xml @@ -7,4 +7,16 @@ org.example WS-04-oop-review 1.0-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + + 14 + 14 + + + + diff --git a/src/main/java/Main.java b/src/main/java/Main.java new file mode 100644 index 0000000..9916d83 --- /dev/null +++ b/src/main/java/Main.java @@ -0,0 +1,282 @@ +import models.*; +import services.*; +import java.util.Scanner; + +public class Main { + private static SchoolSystem school = new SchoolSystem(); + private static Scanner scanner = new Scanner(System.in); + + public static void main(String[] args) { + school.addCourseToSystem("Potions"); + school.addCourseToSystem("Defense Against Dark Arts"); + school.addCourseToSystem("Transfiguration"); + + runMainMenu(); + } + + private static void runMainMenu() { + while (true) { + System.out.println("\n HOGWARTS SCHOOL SYSTEM "); + System.out.println("1. Register (Sign Up)"); + System.out.println("2. Login"); + System.out.println("3. Exit"); + System.out.print("\nChoose: "); + + int choice = getIntInput(); + + switch (choice) { + case 1: + registerMenu(); + break; + case 2: + loginMenu(); + break; + case 3: + System.out.println(" Goodbye!"); + return; + default: + System.out.println(" Invalid choice!"); + } + } + } + + private static void registerMenu() { + System.out.println("\n══════════ REGISTER ══════════"); + System.out.println("1. Register as Student"); + System.out.println("2. Register as Teacher"); + System.out.println("3. Back"); + System.out.print("Choose: "); + + int choice = getIntInput(); + + System.out.print("Enter username: "); + String username = scanner.nextLine(); + + String usernameError = User.validateUsername(username); + if (usernameError != null) { + System.out.println(" " + usernameError); + return; + } + + System.out.print("Enter password: "); + String password = scanner.nextLine(); + + String passwordError = User.validatePassword(password); + if (passwordError != null) { + System.out.println(" " + passwordError); + return; + } + + boolean success; + switch (choice) { + case 1: + //TODO + break; + case 2: + success = school.registerTeacher(username, password); + if (success) { + System.out.println(" Teacher registered successfully!"); + } else { + System.out.println(" Username already exists!"); + } + break; + case 3: + return; + default: + System.out.println(" Invalid choice!"); + } + } + + private static void loginMenu() { + System.out.println("\n══════════ LOGIN ══════════"); + System.out.println("1. Login as Student"); + System.out.println("2. Login as Teacher"); + System.out.println("3. Back"); + System.out.print("Choose: "); + + int choice = getIntInput(); + + System.out.print("Username: "); + String username = scanner.nextLine(); + System.out.print("Password: "); + String password = scanner.nextLine(); + + switch (choice) { + case 1: + //TODO + break; + case 2: + Teacher teacher = school.loginTeacher(username, password); + if (teacher != null) { + teacherMenu(teacher); + } else { + System.out.println(" Invalid username or password!"); + } + break; + case 3: + return; + default: + System.out.println(" Invalid choice!"); + } + } + + // ==================== STUDENT MENU ==================== + private static void studentMenu(Student student) { + while (true) { + System.out.println("\n══════════ STUDENT DASHBOARD ══════════"); + System.out.println("Welcome, " + student.getUsername() + "!"); + System.out.println("1. View All Available Courses"); + System.out.println("2. Enroll in a Course"); + System.out.println("3. View My Courses"); + System.out.println("4. Logout"); + System.out.print("\nChoose: "); + + int choice = getIntInput(); + + switch (choice) { + case 1: + school.showAllCourses(); + break; + case 2: + enrollInCourse(student); + break; + case 3: + //student.showMyCourses(); + break; + case 4: + System.out.println(" Goodbye, " + student.getUsername() + "!"); + return; + default: + System.out.println(" Invalid choice!"); + } + } + } + + private static void enrollInCourse(Student student) { + //TODO + } + + // ==================== TEACHER MENU ==================== + private static void teacherMenu(Teacher teacher) { + while (true) { + System.out.println("\n══════════ TEACHER DASHBOARD ══════════"); + System.out.println("Welcome, Professor " + teacher.getUsername() + "!"); + System.out.println("1. View All Available Courses"); + System.out.println("2. Add New Course to System"); + System.out.println("3. View My Courses"); + System.out.println("4. Add Course to My List (by ID)"); + System.out.println("5. Remove Course from My List (by ID)"); + System.out.println("6. View Students in My Course (by ID)"); + System.out.println("7. Logout"); + System.out.print("\nChoose: "); + + int choice = getIntInput(); + + switch (choice) { + case 1: + school.showAllCourses(); + break; + case 2: + addNewCourseToSystem(teacher); + break; + case 3: + teacher.showMyCourses(); + break; + case 4: + addCourseToTeacher(teacher); + break; + case 5: + removeCourseFromTeacher(teacher); + break; + case 6: + showStudentsInTeacherCourse(teacher); + break; + case 7: + System.out.println(" Goodbye, Professor " + teacher.getUsername() + "!"); + return; + default: + System.out.println(" Invalid choice!"); + } + } + } + + private static void addNewCourseToSystem(Teacher teacher) { + System.out.print("Enter new course name: "); + String courseName = scanner.nextLine(); + + if (school.addCourseToSystem(courseName)) { + System.out.println(" Course '" + courseName + "' created successfully!"); + Course newCourse = school.findCourseByName(courseName); + if (newCourse != null) { + teacher.addCourse(newCourse); + } + } else { + System.out.println(" Course already exists!"); + } + } + + private static void addCourseToTeacher(Teacher teacher) { + school.showAllCourses(); + System.out.print("\nEnter Course ID to add to your list: "); + int courseId = getIntInput(); + + Course course = school.findCourseById(courseId); + if (course == null) { + System.out.println(" Course not found!"); + return; + } + + if (teacher.addCourse(course)) { + System.out.println(" Course '" + course.getName() + "' added to your list!"); + } else { + System.out.println(" You already teach this course!"); + } + } + + private static void removeCourseFromTeacher(Teacher teacher) { + teacher.showMyCourses(); + if (teacher.getMyCourses().isEmpty()) return; + + System.out.print("\nEnter Course ID to remove from your list: "); + int courseId = getIntInput(); + + Course course = school.findCourseById(courseId); + if (course == null) { + System.out.println(" Course not found!"); + return; + } + + if (teacher.removeCourse(course)) { + System.out.println(" Course '" + course.getName() + "' removed from your list!"); + } else { + System.out.println(" You don't teach this course!"); + } + } + + private static void showStudentsInTeacherCourse(Teacher teacher) { + teacher.showMyCourses(); + if (teacher.getMyCourses().isEmpty()) return; + + System.out.print("\nEnter Course ID to see students: "); + int courseId = getIntInput(); + + Course course = school.findCourseById(courseId); + if (course == null) { + System.out.println(" Course not found!"); + return; + } + + teacher.showStudentsInCourse(course); + } + + private static int getIntInput() { + try { + int value = scanner.nextInt(); + scanner.nextLine(); + return value; + } catch (Exception e) { + scanner.nextLine(); + return -1; + } + } +} \ No newline at end of file diff --git a/src/main/java/models/Course.java b/src/main/java/models/Course.java new file mode 100644 index 0000000..61c3f00 --- /dev/null +++ b/src/main/java/models/Course.java @@ -0,0 +1,67 @@ +package models; + +import java.util.ArrayList; +import java.util.List; + +public class Course { + private static int nextId = 1; + + private int id; + private String name; + private Teacher teacher; + private List students; + + public Course(String name) { + this.id = nextId++; + this.name = name; + this.students = new ArrayList<>(); + } + + public int getId() { return id; } + public String getName() { return name; } + public Teacher getTeacher() { return teacher; } + + public void setTeacher(Teacher teacher) { + this.teacher = teacher; + } + + public boolean addStudent(Student student) { + if (students.contains(student)) { + return false; + } + students.add(student); + return true; + } + + public List getStudents() { + return students; // Ψ³Ψ§Ψ―Ω‡ΨŒ Ψ¨Ψ―ΩˆΩ† unmodifiable + } + + public void showStudents() { + if (students.isEmpty()) { + System.out.println(" No students enrolled yet."); + } else { + System.out.println(" Students in " + name + ":"); + for (Student s : students) { + System.out.println(" - " + s.getUsername()); + } + } + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + Course course = (Course) obj; + return id == course.id; + } + + @Override + public String toString() { + if (teacher != null) { + return "[ID:" + id + "] " + name + " (Teacher: " + teacher.getUsername() + ")"; + } else { + return "[ID:" + id + "] " + name + " (No teacher assigned)"; + } + } +} \ No newline at end of file diff --git a/src/main/java/models/Student.java b/src/main/java/models/Student.java new file mode 100644 index 0000000..d3ce65c --- /dev/null +++ b/src/main/java/models/Student.java @@ -0,0 +1,15 @@ +package models; + +import java.util.ArrayList; +import java.util.List; + +public class Student extends User { + private List enrolledCourses; + + public Student(String username, String password) { + super(username, password); + this.enrolledCourses = new ArrayList<>(); + } + //TODO(complete the student class) + +} \ No newline at end of file diff --git a/src/main/java/models/Teacher.java b/src/main/java/models/Teacher.java new file mode 100644 index 0000000..9f900fc --- /dev/null +++ b/src/main/java/models/Teacher.java @@ -0,0 +1,53 @@ +package models; + +import java.util.ArrayList; +import java.util.List; + +public class Teacher extends User { + private List myCourses; + + public Teacher(String username, String password) { + super(username, password); + this.myCourses = new ArrayList<>(); + } + + public boolean addCourse(Course course) { + if (myCourses.contains(course)) { + return false; + } + myCourses.add(course); + course.setTeacher(this); + return true; + } + + public boolean removeCourse(Course course) { + if (myCourses.remove(course)) { + course.setTeacher(null); + return true; + } + return false; + } + + public List getMyCourses() { + return myCourses; + } + + public void showMyCourses() { + if (myCourses.isEmpty()) { + System.out.println(" You don't teach any course yet."); + } else { + System.out.println("\n My Courses:"); + for (int i = 0; i < myCourses.size(); i++) { + System.out.println(" " + (i+1) + ". " + myCourses.get(i)); + } + } + } + + public void showStudentsInCourse(Course course) { + if (!myCourses.contains(course)) { + System.out.println(" You don't teach this course!"); + return; + } + course.showStudents(); + } +} \ No newline at end of file diff --git a/src/main/java/models/User.java b/src/main/java/models/User.java new file mode 100644 index 0000000..eabe35e --- /dev/null +++ b/src/main/java/models/User.java @@ -0,0 +1,42 @@ +package models; + +public abstract class User { + protected String username; + protected String password; // Ψ³Ψ§Ψ―Ω‡ Ω†Ϊ―Ω‡ Ω…ΫŒβ€ŒΨ―Ψ§Ψ±ΫŒΩ… برای Ψ³Ψ·Ψ­ Ω…Ω‚Ψ―Ω…Ψ§Ψͺی + + public User(String username, String password) { + this.username = username; + this.password = password; + } + + public String getUsername() { return username; } + + public boolean checkPassword(String password) { + return this.password.equals(password); + } + + public static String validateUsername(String username) { + if (username == null || username.trim().isEmpty()) { + return "Username cannot be empty!"; + } + if (username.length() < 3) { + return "Username must be at least 3 characters!"; + } + return null; + } + + public static String validatePassword(String password) { + if (password == null || password.length() < 4) { + return "Password must be at least 4 characters!"; + } + return null; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + User user = (User) obj; + return username.equalsIgnoreCase(user.username); + } +} \ No newline at end of file diff --git a/src/main/java/org/example/Main.java b/src/main/java/org/example/Main.java deleted file mode 100644 index 0fcfac9..0000000 --- a/src/main/java/org/example/Main.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.example; - -public class Main { - public static void main(String[] args) { - System.out.println("Welcome to Movie App!"); - Movie movie = new Movie("Inception", "Christopher Nolan", 2010, 8.8); - System.out.println(movie.getTitle()); - } -} diff --git a/src/main/java/org/example/Movie.java b/src/main/java/org/example/Movie.java deleted file mode 100644 index 553e7b0..0000000 --- a/src/main/java/org/example/Movie.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.example; - -import java.util.ArrayList; -import java.util.List; - -public class Movie { - private String title; - private String director; - private int year; - private double rating; - private List images; // Ψ―Ψ±Ψ³Ψͺ Ψ΄Ψ―: Ψ§Ψ² Ψ’Ψ±Ψ§ΫŒΩ‡ Ψ¨Ω‡ Ω„ΫŒΨ³Ψͺ Ψͺغییر Ϊ©Ψ±Ψ― - - public Movie(String title, String director, int year, double rating) { - this.title = title; - this.director = director; - this.year = year; - this.rating = rating; - this.images = new ArrayList<>(); - } - - // Getters and Setters - public String getTitle() { return title; } - public void setTitle(String title) { this.title = title; } - public String getDirector() { return director; } - public void setDirector(String director) { this.director = director; } - public int getYear() { return year; } - public void setYear(int year) { this.year = year; } - public double getRating() { return rating; } - public void setRating(double rating) { this.rating = rating; } - public List getImages() { return images; } - public void setImages(List images) { this.images = images; } - - // Ω…ΨͺΨ―Ω‡Ψ§ΫŒ اآافی برای Ω…Ψ―ΫŒΨ±ΫŒΨͺ Ψͺءاویر - public void addImage(String imageUrl) { - this.images.add(imageUrl); - } - - public void removeImage(String imageUrl) { - this.images.remove(imageUrl); - } - - @Override - public String toString() { - return "Movie{title='" + title + "', director='" + director + - "', year=" + year + ", rating=" + rating + ", images=" + images + "}"; - } -} diff --git a/src/main/java/services/SchoolSystem.java b/src/main/java/services/SchoolSystem.java new file mode 100644 index 0000000..ec6f90e --- /dev/null +++ b/src/main/java/services/SchoolSystem.java @@ -0,0 +1,77 @@ +package services; + +import models.*; +import java.util.ArrayList; +import java.util.List; + +public class SchoolSystem { + private List students; + private List teachers; + private List allCourses; + + public SchoolSystem() { + this.students = new ArrayList<>(); + this.teachers = new ArrayList<>(); + this.allCourses = new ArrayList<>(); + } + + // ========== Student Management ========== + //TODO + + // ========== Teacher Management ========== + public boolean registerTeacher(String username, String password) { + if (findTeacher(username) != null) { + return false; + } + teachers.add(new Teacher(username, password)); + return true; + } + + public Teacher loginTeacher(String username, String password) { + Teacher teacher = findTeacher(username); + if (teacher != null && teacher.checkPassword(password)) { + return teacher; + } + return null; + } + + private Teacher findTeacher(String username) { + for (Teacher t : teachers) { + if (t.getUsername().equals(username)) return t; + } + return null; + } + + // ========== Course Management ========== + public boolean addCourseToSystem(String courseName) { + //TODO + return true; + } + + public Course findCourseById(int id) { + //TODO + return null; + } + + public Course findCourseByName(String name) { + for (Course c : allCourses) { + if (c.getName().equalsIgnoreCase(name)) return c; + } + return null; + } + + public void showAllCourses() { + if (allCourses.isEmpty()) { + System.out.println(" No courses available yet."); + } else { + System.out.println("\n All Available Courses:"); + for (int i = 0; i < allCourses.size(); i++) { + System.out.println(" " + (i+1) + ". " + allCourses.get(i)); + } + } + } + + public List getAllCourses() { + return allCourses; + } +} \ No newline at end of file