2.10 פרויקטים פרויקט
פרויקטים - ג'אווהסקריפט בסיסי¶
שלושה פרויקטים שמשלבים את כל מה שלמדנו עד עכשיו: משתנים, תנאים, לולאות, פונקציות, מערכים, אובייקטים, מתודות מתקדמות, מחרוזות, דסטרקצ'רינג ו-spread.
כל הפרויקטים עובדים ב-console בלבד - בלי ממשק משתמש. ההתמקדות היא בלוגיקה.
פרויקט 1 - מחשבון - Calculator¶
תיאור¶
בנו מחשבון שעובד ב-console. המחשבון יתמוך בפעולות חשבון בסיסיות ובכמה פונקציות נוספות.
דרישות¶
- צרו פונקציות נפרדות לכל פעולה:
add(a, b)- חיבורsubtract(a, b)- חיסורmultiply(a, b)- כפלdivide(a, b)- חילוקpower(a, b)- חזקה-
modulo(a, b)- שארית -
צרו פונקציה ראשית
calculate(a, operator, b)שמקבלת שני מספרים ואופרטור כמחרוזת ומחזירה את התוצאה: - השתמשו ב-switch כדי לבחור את הפעולה
- תמכו באופרטורים:
"+","-","*","/","**","%" -
החזירו הודעת שגיאה לאופרטור לא חוקי
-
טיפול בשגיאות:
- חילוק באפס - החזירו
"Error: Division by zero" - קלט לא מספרי - החזירו
"Error: Invalid input" -
אופרטור לא חוקי - החזירו
"Error: Invalid operator" -
צרו פונקציה
calculateExpression(expression)שמקבלת מחרוזת כמו"5 + 3"ומפענחת אותה: - פצלו את המחרוזת לחלקים
- המירו את המספרים מטקסט למספרים
-
קראו ל-
calculateעם הערכים -
צרו מערך
historyשרושם את כל החישובים שנעשו בפורמט"5 + 3 = 8" -
צרו פונקציה
getHistory()שמחזירה את ההיסטוריה -
צרו פונקציה
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
}
דרישות¶
-
צרו אובייקט
shoppingListעם מאפייןitems(מערך ריק) ומאפייןnextIdשמתחיל מ-1 -
פונקציות CRUD:
addItem(name, quantity, category)- מוסיפה פריט חדש. ה-id נוצר אוטומטית, bought מתחיל כ-false, ו-addedAt הוא התאריך הנוכחי. מחזירה את הפריט שנוצר.removeItem(id)- מסירה פריט לפי id. מחזירה true אם נמחק, false אם לא נמצא.updateItem(id, updates)- מעדכנת מאפיינים של פריט (למשל שם, כמות). משתמשת ב-spread. מחזירה את הפריט המעודכן.markAsBought(id)- מסמנת פריט כ-"נקנה". מחזירה את הפריט המעודכן.-
markAsNotBought(id)- מבטלת סימון "נקנה". -
פונקציות שליפה:
getItems()- מחזירה את כל הפריטיםgetUnboughtItems()- מחזירה רק פריטים שלא נקנוgetBoughtItems()- מחזירה רק פריטים שנקנוgetItemsByCategory(category)- מחזירה פריטים לפי קטגוריה-
findItem(name)- מחפשת פריט לפי שם (חיפוש חלקי, case-insensitive) -
פונקציות סטטיסטיקה:
getTotalItems()- סך כל הפריטים (כמות, לא מספר שורות)getTotalBought()- כמה פריטים נקנוgetProgress()- אחוז ההשלמה (כמה פריטים נקנו מתוך הכל)-
getCategorySummary()- סיכום לפי קטגוריה: כמה פריטים, כמה נקנו -
פונקציות תצוגה:
printList()- מדפיסה את הרשימה בפורמט יפה-
printByCategory()- מדפיסה את הרשימה מקובצת לפי קטגוריות -
כללי:
- כל הפעולות צריכות להיות immutable - לא לשנות את המערך המקורי אלא ליצור חדש
- השתמשו ב-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 רגילות ככל הניתן.
getAverages(students)- מחזירה מערך של אובייקטים עם שם הסטודנט והציון הממוצע שלו:
getTopStudent(students)- מחזירה את שם הסטודנט עם הממוצע הגבוה ביותר:
getPassingStudents(students, minAverage)- מחזירה מערך של סטודנטים שהממוצע שלהם מעל minAverage:
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"]
// }
sortByAverage(students, ascending = true)- מחזירה מערך ממוין לפי ממוצע. הפרמטר ascending קובע אם מהנמוך לגבוה או להפך:
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
// }
getCourseSummary(students)- סיכום לפי קורס: כמה סטודנטים לומדים כל קורס:
getStudentsInCourse(students, course)- מחזירה שמות של סטודנטים שלומדים קורס מסוים:
getStudentsInCourse(students, "CS");
// ["Alice Cohen", "Charlie Ben-David", "Eve Shapiro", "Grace Avrahami"]
getHighestInEachCity(students)- מחזירה את הסטודנט המצטיין מכל עיר:
// {
// "Tel Aviv": "Charlie Ben-David",
// "Jerusalem": "Bob Levy",
// "Haifa": "Grace Avrahami",
// "Beer Sheva": "Henry Katz"
// }
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(...)