לדלג לתוכן

2.10 פרויקטים פרויקט

פרויקטים - ג'אווהסקריפט בסיסי

שלושה פרויקטים שמשלבים את כל מה שלמדנו עד עכשיו: משתנים, תנאים, לולאות, פונקציות, מערכים, אובייקטים, מתודות מתקדמות, מחרוזות, דסטרקצ'רינג ו-spread.

כל הפרויקטים עובדים ב-console בלבד - בלי ממשק משתמש. ההתמקדות היא בלוגיקה.


פרויקט 1 - מחשבון - Calculator

תיאור

בנו מחשבון שעובד ב-console. המחשבון יתמוך בפעולות חשבון בסיסיות ובכמה פונקציות נוספות.

דרישות

  1. צרו פונקציות נפרדות לכל פעולה:
  2. add(a, b) - חיבור
  3. subtract(a, b) - חיסור
  4. multiply(a, b) - כפל
  5. divide(a, b) - חילוק
  6. power(a, b) - חזקה
  7. modulo(a, b) - שארית

  8. צרו פונקציה ראשית calculate(a, operator, b) שמקבלת שני מספרים ואופרטור כמחרוזת ומחזירה את התוצאה:

  9. השתמשו ב-switch כדי לבחור את הפעולה
  10. תמכו באופרטורים: "+", "-", "*", "/", "**", "%"
  11. החזירו הודעת שגיאה לאופרטור לא חוקי

  12. טיפול בשגיאות:

  13. חילוק באפס - החזירו "Error: Division by zero"
  14. קלט לא מספרי - החזירו "Error: Invalid input"
  15. אופרטור לא חוקי - החזירו "Error: Invalid operator"

  16. צרו פונקציה calculateExpression(expression) שמקבלת מחרוזת כמו "5 + 3" ומפענחת אותה:

  17. פצלו את המחרוזת לחלקים
  18. המירו את המספרים מטקסט למספרים
  19. קראו ל-calculate עם הערכים

  20. צרו מערך history שרושם את כל החישובים שנעשו בפורמט "5 + 3 = 8"

  21. צרו פונקציה getHistory() שמחזירה את ההיסטוריה

  22. צרו פונקציה clearHistory() שמנקה את ההיסטוריה

דוגמת שימוש

console.log(calculate(10, "+", 5));   // 15
console.log(calculate(10, "/", 0));   // "Error: Division by zero"
console.log(calculate(10, "^", 5));   // "Error: Invalid operator"

console.log(calculateExpression("10 + 5"));  // 15
console.log(calculateExpression("100 / 4")); // 25

console.log(getHistory());
// ["10 + 5 = 15", "100 / 4 = 25"]

clearHistory();
console.log(getHistory()); // []

פרויקט 2 - מנהל רשימת קניות - Shopping List Manager

תיאור

בנו מערכת לניהול רשימת קניות. המערכת מאפשרת להוסיף, למחוק, לעדכן ולסנן פריטים.

מבנה הנתונים

כל פריט ברשימה הוא אובייקט עם המבנה:

{
  id: 1,                  // unique identifier (auto-generated)
  name: "Milk",           // product name
  quantity: 2,            // how many to buy
  category: "dairy",      // product category
  bought: false,          // was it bought?
  addedAt: "2024-01-15"   // when it was added
}

דרישות

  1. צרו אובייקט shoppingList עם מאפיין items (מערך ריק) ומאפיין nextId שמתחיל מ-1

  2. פונקציות CRUD:

  3. addItem(name, quantity, category) - מוסיפה פריט חדש. ה-id נוצר אוטומטית, bought מתחיל כ-false, ו-addedAt הוא התאריך הנוכחי. מחזירה את הפריט שנוצר.
  4. removeItem(id) - מסירה פריט לפי id. מחזירה true אם נמחק, false אם לא נמצא.
  5. updateItem(id, updates) - מעדכנת מאפיינים של פריט (למשל שם, כמות). משתמשת ב-spread. מחזירה את הפריט המעודכן.
  6. markAsBought(id) - מסמנת פריט כ-"נקנה". מחזירה את הפריט המעודכן.
  7. markAsNotBought(id) - מבטלת סימון "נקנה".

  8. פונקציות שליפה:

  9. getItems() - מחזירה את כל הפריטים
  10. getUnboughtItems() - מחזירה רק פריטים שלא נקנו
  11. getBoughtItems() - מחזירה רק פריטים שנקנו
  12. getItemsByCategory(category) - מחזירה פריטים לפי קטגוריה
  13. findItem(name) - מחפשת פריט לפי שם (חיפוש חלקי, case-insensitive)

  14. פונקציות סטטיסטיקה:

  15. getTotalItems() - סך כל הפריטים (כמות, לא מספר שורות)
  16. getTotalBought() - כמה פריטים נקנו
  17. getProgress() - אחוז ההשלמה (כמה פריטים נקנו מתוך הכל)
  18. getCategorySummary() - סיכום לפי קטגוריה: כמה פריטים, כמה נקנו

  19. פונקציות תצוגה:

  20. printList() - מדפיסה את הרשימה בפורמט יפה
  21. printByCategory() - מדפיסה את הרשימה מקובצת לפי קטגוריות

  22. כללי:

  23. כל הפעולות צריכות להיות immutable - לא לשנות את המערך המקורי אלא ליצור חדש
  24. השתמשו ב-map, filter, find, reduce, spread, destructuring

דוגמת שימוש

addItem("Milk", 2, "dairy");
addItem("Bread", 1, "bakery");
addItem("Eggs", 12, "dairy");
addItem("Tomatoes", 6, "vegetables");
addItem("Cheese", 1, "dairy");
addItem("Cucumber", 3, "vegetables");

markAsBought(1); // milk
markAsBought(4); // tomatoes

printList();
// === Shopping List ===
// [x] Milk (x2) - dairy
// [ ] Bread (x1) - bakery
// [x] Tomatoes (x6) - vegetables
// [ ] Eggs (x12) - dairy
// [ ] Cheese (x1) - dairy
// [ ] Cucumber (x3) - vegetables
// ====================
// Progress: 2/6 items (33.33%)

console.log(getUnboughtItems());
// [Bread, Eggs, Cheese, Cucumber]

console.log(getCategorySummary());
// {
//   dairy: { total: 3, bought: 1 },
//   bakery: { total: 1, bought: 0 },
//   vegetables: { total: 2, bought: 1 }
// }

updateItem(3, { quantity: 24 }); // update eggs to 24
removeItem(5); // remove cheese

printByCategory();
// === dairy ===
// [x] Milk (x2)
// [ ] Eggs (x24)
//
// === bakery ===
// [ ] Bread (x1)
//
// === vegetables ===
// [x] Tomatoes (x6)
// [ ] Cucumber (x3)

פרויקט 3 - מעבד נתוני תלמידים - Student Data Processor

תיאור

בנו מערכת לעיבוד וניתוח נתונים של תלמידים. המערכת מקבלת מערך JSON של תלמידים ומבצעת עליו פעולות שונות.

נתוני קלט

const students = [
  {
    name: "Alice Cohen",
    age: 22,
    city: "Tel Aviv",
    grades: [92, 88, 95, 79, 86],
    courses: ["Math", "Physics", "CS"]
  },
  {
    name: "Bob Levy",
    age: 24,
    city: "Jerusalem",
    grades: [78, 82, 75, 90, 85],
    courses: ["Math", "Chemistry", "Biology"]
  },
  {
    name: "Charlie Ben-David",
    age: 21,
    city: "Tel Aviv",
    grades: [95, 98, 92, 97, 94],
    courses: ["CS", "Math", "Physics"]
  },
  {
    name: "Diana Mizrahi",
    age: 23,
    city: "Haifa",
    grades: [65, 72, 68, 70, 75],
    courses: ["Biology", "Chemistry", "Math"]
  },
  {
    name: "Eve Shapiro",
    age: 22,
    city: "Tel Aviv",
    grades: [88, 91, 85, 93, 87],
    courses: ["CS", "Physics", "Math"]
  },
  {
    name: "Frank Goldstein",
    age: 25,
    city: "Jerusalem",
    grades: [55, 62, 58, 70, 65],
    courses: ["Biology", "Chemistry"]
  },
  {
    name: "Grace Avrahami",
    age: 21,
    city: "Haifa",
    grades: [90, 85, 92, 88, 91],
    courses: ["Math", "CS", "Physics"]
  },
  {
    name: "Henry Katz",
    age: 23,
    city: "Beer Sheva",
    grades: [73, 78, 80, 75, 82],
    courses: ["Math", "Biology"]
  }
];

דרישות

כתבו פונקציות לכל אחת מהמשימות הבאות. השתמשו במתודות מערכים (map, filter, reduce, sort, find וכו'), דסטרקצ'רינג, ו-spread. הימנעו מלולאות for רגילות ככל הניתן.

  1. getAverages(students) - מחזירה מערך של אובייקטים עם שם הסטודנט והציון הממוצע שלו:
// [
//   { name: "Alice Cohen", average: 88 },
//   { name: "Bob Levy", average: 82 },
//   ...
// ]
  1. getTopStudent(students) - מחזירה את שם הסטודנט עם הממוצע הגבוה ביותר:
// "Charlie Ben-David"
  1. getPassingStudents(students, minAverage) - מחזירה מערך של סטודנטים שהממוצע שלהם מעל minAverage:
getPassingStudents(students, 85);
// [Alice, Charlie, Eve, Grace]
  1. groupByCity(students) - מחזירה אובייקט שמקבץ סטודנטים לפי עיר:
// {
//   "Tel Aviv": ["Alice Cohen", "Charlie Ben-David", "Eve Shapiro"],
//   "Jerusalem": ["Bob Levy", "Frank Goldstein"],
//   "Haifa": ["Diana Mizrahi", "Grace Avrahami"],
//   "Beer Sheva": ["Henry Katz"]
// }
  1. sortByAverage(students, ascending = true) - מחזירה מערך ממוין לפי ממוצע. הפרמטר ascending קובע אם מהנמוך לגבוה או להפך:
sortByAverage(students, false);
// [Charlie(95.2), Eve(88.8), Grace(89.2), Alice(88), ...]
  1. getGradeDistribution(students) - מחזירה חלוקת ציונים:
// {
//   "A (90-100)": 4,     // number of students
//   "B (80-89)": 2,
//   "C (70-79)": 1,
//   "D (60-69)": 1,
//   "F (below 60)": 0
// }
  1. getCourseSummary(students) - סיכום לפי קורס: כמה סטודנטים לומדים כל קורס:
// {
//   Math: 7,
//   Physics: 4,
//   CS: 4,
//   Chemistry: 3,
//   Biology: 4
// }
  1. getStudentsInCourse(students, course) - מחזירה שמות של סטודנטים שלומדים קורס מסוים:
getStudentsInCourse(students, "CS");
// ["Alice Cohen", "Charlie Ben-David", "Eve Shapiro", "Grace Avrahami"]
  1. getHighestInEachCity(students) - מחזירה את הסטודנט המצטיין מכל עיר:
// {
//   "Tel Aviv": "Charlie Ben-David",
//   "Jerusalem": "Bob Levy",
//   "Haifa": "Grace Avrahami",
//   "Beer Sheva": "Henry Katz"
// }
  1. generateReport(students) - מחזירה דוח סיכום מלא:
// {
//   totalStudents: 8,
//   overallAverage: 81.15,
//   topStudent: "Charlie Ben-David",
//   bottomStudent: "Frank Goldstein",
//   passingRate: "87.5%",
//   cities: ["Tel Aviv", "Jerusalem", "Haifa", "Beer Sheva"],
//   courses: ["Math", "Physics", "CS", "Chemistry", "Biology"],
//   gradeDistribution: { ... },
//   cityBreakdown: { ... }
// }

דוגמת שימוש מלאה

// calculate averages
const averages = getAverages(students);
averages.forEach(({ name, average }) => {
  console.log(`${name}: ${average.toFixed(1)}`);
});

// find top student
console.log("Top student:", getTopStudent(students));

// filter by minimum average
const honor = getPassingStudents(students, 85);
console.log("Honor roll:", honor.map(({ name }) => name));

// group by city
const byCities = groupByCity(students);
Object.entries(byCities).forEach(([city, names]) => {
  console.log(`${city}: ${names.join(", ")}`);
});

// sort by average (highest first)
const ranked = sortByAverage(students, false);
ranked.forEach(({ name, average }, index) => {
  console.log(`${index + 1}. ${name} - ${average.toFixed(1)}`);
});

// full report
const report = generateReport(students);
console.log("=== Student Report ===");
console.log(`Total students: ${report.totalStudents}`);
console.log(`Overall average: ${report.overallAverage.toFixed(1)}`);
console.log(`Top student: ${report.topStudent}`);
console.log(`Passing rate: ${report.passingRate}`);

טיפים

  • צרו פונקציית עזר calcAverage(grades) שמחשבת ממוצע ושתשמש אותכם בכל הפונקציות
  • השתמשו ב-toFixed(2) לעיגול מספרים
  • השתמשו בדסטרקצ'רינג בתוך ה-callbacks כמו ({ name, grades }) =>
  • כל הפונקציות צריכות להיות "טהורות" - לא לשנות את המערך המקורי
  • שלבו מתודות עם שרשור: students.filter(...).map(...).sort(...)