דילוג לתוכן המרכזי

בגרות במדעי המחשב תכנות באינטרנט 899372 - קיץ 2025

נבחנים אקסטרניים · שאלון 899372 · 9 שאלות · 2 שעות · פתרון מלא לכל סעיף

בחינת הבגרות במדעי המחשב, תכנות באינטרנט, קיץ 2025, כל 9 השאלות כמו בשאלון. לכל סעיף יש תשובה ופתרון מלא: הרעיון, הקוד או המעקב, ובדיקה קצרה. כל קוד מופיע ב-Java וב-C#. נסו לפתור לבד, ואז פתחו את הפתרון.

הוראות הבחינה (כמו בשאלון)

א. משך הבחינה: שעתיים.

ב. מבנה השאלון ומפתח הערכה: בשאלון זה שלושה פרקים.

פרק ראשון — (10x3) — 30 נקודות
פרק שני — (20x2)+(10x1) — 50 נקודות
פרק שלישי — (20x1) — 20 נקודות
סך הכול — 100 נקודות

ג. חומר עזר מותר בשימוש: כל חומר עזר, חוץ ממחשבון שיש בו אפשרות תכנות.

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

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

בהצלחה!

פרק ראשון

ענו על שלוש השאלות 3-1 (לכל שאלה – 10 נקודות).

שאלה 1 · תפקיד האובייקט Response

מהו תפקידו של אובייקט Response בתקשורת בין השרת לדפדפן?
העתיקו למחברת הבחינה את התשובה הנכונה מבין האפשרויות א–ד שלפניכם.

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

העתיקו למחברת הבחינה את התשובה הנכונה מבין האפשרויות א–ד.

(10 נקודות)
◂ פתרון מלא לשאלה 1

פתרון

תשובה

ג. האובייקט מכיל את התגובה מהשרת לדפדפן

מה נדרש: לבחור את התיאור הנכון של האובייקט Response.

רעיון: בתקשורת שרת-לקוח יש שני כיוונים:

•בקשה (Request) – מהדפדפן לשרת. בצד השרת היא נקראת דרך האובייקט Request (למשל Request.Form, Request.QueryString).
•תגובה (Response) – מהשרת חזרה לדפדפן. בצד השרת בונים אותה דרך האובייקט Response: Response.Write(...) כותב HTML לדף שיישלח, Response.Redirect(...) שולח לדפדפן הוראה לעבור לדף אחר.

פתרון: התשובה הנכונה היא ג – האובייקט מכיל את התגובה מהשרת לדפדפן.

בדיקה – למה האחרות שגויות:

•א – שליחת בקשות מהדפדפן לשרת היא הבקשה (Request), לא התגובה.
•ב – עבודה מול מסד הנתונים נעשית בעזרת אובייקטים של חיבור למסד (למשל SqlConnection, SqlCommand), לא Response.
•ד – אימות משתמש הוא לוגיקה שהמתכנת כותב (בדיקה מול טבלת משתמשים), לא תפקידו של Response.

שאלה 2 · שאילתה על טבלת חדרי בריחה

במסד נתונים של חדרי בריחה מוגדרת טבלה בשם EscapeRoom ובה מאפייני החדרים. בטבלה יש ארבע עמודות:

•שם החדר (name)
•נושא החדר (subject)
•מספר מינימלי של שחקנים (minUser)
•מספר מקסימלי של שחקנים (maxUser)

כתבו שאילתה בשפת SQL המאחזרת את שמות ונושאי החדרים, בהם 5 שחקנים יכולים לשחק.

כתבו שאילתה בשפת SQL המאחזרת את שמות ונושאי החדרים, בהם 5 שחקנים יכולים לשחק.

(10 נקודות)
◂ פתרון מלא לשאלה 2

פתרון

תשובה

SELECT name, subject FROM EscapeRoom WHERE minUser <= 5 AND maxUser >= 5;

מה נדרש: שמות ונושאים של החדרים שקבוצה של 5 שחקנים יכולה לשחק בהם.

רעיון: 5 שחקנים יכולים לשחק בחדר אם 5 נמצא בטווח המותר של החדר: המינימום לכל היותר 5 וגם המקסימום לפחות 5. בוחרים (SELECT) רק את שתי העמודות name ו-subject ומסננים (WHERE) בשני תנאים המחוברים ב-AND.

פתרון:

SQL
SELECT name, subject
FROM EscapeRoom
WHERE minUser <= 5 AND maxUser >= 5;

(אפשר גם לכתוב WHERE 5 BETWEEN minUser AND maxUser – BETWEEN כולל את שני הקצוות.)

בדיקה: השאילתה על טבלה לדוגמה:

namesubjectminUsermaxUserמתאים ל-5?
הכספת הנסתרתשוד26כן
המעבדהמדע45כן (5 הוא המקסימום)
הצוללתים58כן (5 הוא המינימום)
בית הקברותאימה24לא (מקסימום 4)
החלליתחלל610לא (מינימום 6)

התקבלו שלוש השורות הראשונות בלבד, כמצופה.

טעות נפוצה: לכתוב minUser = 5 או maxUser = 5 – כך מפספסים חדרים שבהם 5 נמצא בתוך הטווח. טעות נוספת: minUser >= 5 (הכיוון הפוך).

שאלה 3 · פלט של Response.Write עם רשימה

לפניכם הפונקציה Func, הכתובה בצד שרת.

C#
public void Func (int num) {
      string str = "<ul>";
      for (int i = 1; i <= num; i++) {
         if (i % 2 == 0)
            str += "<li>Even number: " + i + "</li>";
         else
            str += "<li>Odd number: " + i + "</li>";
      }
      str += "</ul>";
      Response.Write(str);
}

כתבו במחברת הבחינה את הפלט שיוצג בדפדפן לאחר זימון הפונקציה Func(10).

כתבו במחברת הבחינה את הפלט שיוצג בדפדפן לאחר זימון הפונקציה Func(10).

(10 נקודות)
◂ פתרון מלא לשאלה 3

פתרון

תשובה

רשימת תבליטים של 10 שורות: Odd number: 1, Even number: 2, Odd number: 3, ..., Odd number: 9, Even number: 10 (כל שורה עם תבליט • בתחילתה).

מה נדרש: מה יראה המשתמש בדפדפן (לא את מחרוזת ה-HTML, אלא את התצוגה שלה).

רעיון: הפונקציה בונה מחרוזת HTML: <ul> פותח רשימה לא ממוספרת (רשימת תבליטים), כל <li>...</li> הוא פריט ברשימה, ובסוף </ul> סוגר אותה. הלולאה רצה על i מ-1 עד 10: עבור i זוגי (i % 2 == 0) נוסף פריט "Even number: i", ועבור i אי-זוגי – "Odd number: i". Response.Write שולח את המחרוזת לדפדפן, והדפדפן מציג אותה כרשימה.

פתרון – מעקב:

ii % 2הפריט שנוסף
11<li>Odd number: 1</li>
20<li>Even number: 2</li>
31<li>Odd number: 3</li>
………
91<li>Odd number: 9</li>
100<li>Even number: 10</li>

המחרוזת שנשלחת לדפדפן:

HTML
<ul><li>Odd number: 1</li><li>Even number: 2</li><li>Odd number: 3</li><li>Even number: 4</li><li>Odd number: 5</li><li>Even number: 6</li><li>Odd number: 7</li><li>Even number: 8</li><li>Odd number: 9</li><li>Even number: 10</li></ul>

הפלט שיוצג בדפדפן – רשימת תבליטים (נקודה • לפני כל שורה), כל פריט בשורה נפרדת:

•Odd number: 1
•Even number: 2
•Odd number: 3
•Even number: 4
•Odd number: 5
•Even number: 6
•Odd number: 7
•Even number: 8
•Odd number: 9
•Even number: 10

בדיקה: 10 פריטים – 5 אי-זוגיים (1, 3, 5, 7, 9) ו-5 זוגיים (2, 4, 6, 8, 10), לסירוגין, מתחילים ב-Odd כי 1 אי-זוגי.

טעות נפוצה: לכתוב את התגיות <li> כחלק מהפלט, או לרשום מספרים 1–10 בתחילת השורות – <ul> מציגה תבליטים ולא מספור (מספור היה מתקבל עם <ol>).

פרק שני

ענו על שלוש שאלות: על שאלה 4 (חובה – 10 נקודות) ועל שתיים מן השאלות 7-5 (לכל שאלה – 20 נקודות).

שאלה 4 · טבלת HTML עם colspan/rowspan וקישור (10 נקודות)

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

HTML
<!DOCTYPE html>
<html lang="he" >
  <meta charset="utf-8"/>
  <table style="width:150px" border=2px dir="ltr">
    <tr >
     <td colspan=2 align="center">Animals</td>
    </tr>
    <tr>
     <td rowspan=2>Dog</td>
     <td>Bonnie</td>
    </tr>
    <tr >
     <td >Lilo</td>
    </tr>
    <tr>
     <td>Turtle</td>
     <td>Alfi</td>
    </tr>
    <tr >
     <td colspan=2 align="center">Lunch time</td>
    </tr>
  </table>
</html>
א.

כיצד יוצג הדף? כתבו במחברת הבחינה את מספר התשובה הנכונה מבין האפשרויות (a-d).

ב.

כתבו שורת קוד מתאימה ב- html כך שלחיצה על המילה Animals תעביר לאתר:
https://he.wikipedia.org/wiki/Animal

◂ פתרון מלא לשאלה 4

סעיף א

תשובה

b

מה נדרש: לזהות איך הדפדפן מסדר את תאי הטבלה.

רעיון: עוברים שורה-שורה (<tr>) ומניחים כל תא (<td>) במקום הפנוי הבא בשורה. colspan=2 – התא תופס שתי עמודות; rowspan=2 – התא תופס גם את המקום שלו בשורה הבאה. dir="ltr" – התא הראשון בכל שורה נמצא משמאל.

פתרון – בניית הטבלה:

שורהמה כתוב בקודהתוצאה
1Animals עם colspan=2, ממורכזAnimals על פני שתי העמודות
2Dog עם rowspan=2, ואחריו BonnieDog בעמודה השמאלית (תופס גם את שורה 3), Bonnie מימין
3רק Liloהעמודה השמאלית תפוסה ע"י Dog, ולכן Lilo נכנס לעמודה הימנית – מתחת ל-Bonnie
4Turtle, AlfiTurtle משמאל, Alfi מימין
5Lunch time עם colspan=2, ממורכזLunch time על פני שתי העמודות

מתקבלת הטבלה של אפשרות b.

בדיקה: הצגנו את הקוד בדפדפן וקיבלנו בדיוק את סידור התאים של b. האפשרויות האחרות נפסלות:

•a – בשורה האחרונה יש תא ריק ו-Lunch time בתא אחד, כאילו אין colspan=2.
•c – Animals ו-Lunch time תופסים עמודה אחת בלבד, ו-Lilo מופיע לפני Bonnie.
•d – Lilo לפני Bonnie, Alfi ו-Turtle בסדר הפוך, ו-Lunch time בעמודה אחת.

סעיף ב

תשובה

<td colspan=2 align="center"><a href="https://he.wikipedia.org/wiki/Animal">Animals</a></td>

מה נדרש: להפוך את המילה Animals לקישור.

רעיון: קישור נכתב בתגית <a> עם התכונה href שמכילה את כתובת היעד. הטקסט שבין <a ...> ל-</a> הוא מה שלוחצים עליו. עוטפים את המילה Animals בתוך התא הקיים (התא נשאר עם colspan=2 ו-align="center").

פתרון: מחליפים את שורת התא הראשון בשורה:

HTML
<td colspan=2 align="center"><a href="https://he.wikipedia.org/wiki/Animal">Animals</a></td>

בדיקה: בהצגת הדף המילה Animals מופיעה כקישור (כחול עם קו תחתון) במרכז השורה העליונה, ולחיצה עליה מעבירה ל-https://he.wikipedia.org/wiki/Animal. מבנה הטבלה לא השתנה.

טעות נפוצה: לשים את <a> מחוץ ל-<td> (בין <tr> ל-<td>) – זה HTML לא תקין. טעות נוספת: לשכוח את המירכאות או את https:// בכתובת.

שאלה 5 · ניתוב בין דפים לפי משתני Session

באתר חדר בריחה "הכספת הנסתרת", על השחקן לפתוח כספת גדולה בחדר הראשון. על מנת להשיג זאת, האתר משתמש במספר משתני Session:

•Session["time_room1"]: מספר שלם המייצג את זמן השהייה של השחקן בחדר הראשון.
•Session["solved_colors"]: משתנה בוליאני המציין האם השחקן סיים את חידת הצבעים: כן (true) או לא (false).
•Session["keys_found"]: מספר שלם המייצג את מספר המפתחות הקטנים שנאספו.

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

– אם time_room1 קטן מ-25 וגם solved_colors הוא true וגם keys_found שווה ל-5 ומעלה, השחקן מועבר לדף פתיחת הכספת openSafe.aspx.
– אם keys_found גדול או שווה ל- 3 וגם לפחות אחד משני התנאים הבאים מתקיים:
time_room1 קטן מ- 30 או solved_colors הוא true,
השחקן מועבר לדף רמזים cluePage.aspx.
– שאר השחקנים מועברים חזרה לדף הפתיחה openPage.aspx.

כתבו קוד המתאים לדרישות.

כתבו קוד המתאים לדרישות.

(20 נקודות)
◂ פתרון מלא לשאלה 5

פתרון

תשובה

קוראים את שלושת משתני ה-Session עם המרה (int)/(bool), ואז: if (time < 25 && solved && keys >= 5) Response.Redirect("openSafe.aspx"); else if (keys >= 3 && (time < 30 || solved)) Response.Redirect("cluePage.aspx"); else Response.Redirect("openPage.aspx");

מה נדרש: קוד צד שרת (C#) שמעביר את השחקן לאחד משלושה דפים לפי ערכי שלושה משתני Session.

רעיון:

1.ב-Session נשמרים ערכים מטיפוס object, ולכן קוראים כל משתנה עם המרה לטיפוס שלו: (int) למספרים ו-(bool) לבוליאני.
2.בודקים את הכללים לפי הסדר בשרשרת if / else if / else: קודם הכלל המחמיר (פתיחת הכספת), אחריו דף הרמזים, ובסוף כל השאר.
3.בכלל השני יש "וגם" בין keys_found ≥ 3 לבין "לפחות אחד" משני תנאים – לכן ה-"או" (||) חייב להיות בתוך סוגריים.
4.מעבר לדף אחר נעשה ב-Response.Redirect("שם הדף").

פתרון (בקובץ ה-code behind של הדף):

C#
protected void Page_Load(object sender, EventArgs e)
{
    int time = (int)Session["time_room1"];
    bool solved = (bool)Session["solved_colors"];
    int keys = (int)Session["keys_found"];

    if (time < 25 && solved && keys >= 5)
        Response.Redirect("openSafe.aspx");
    else if (keys >= 3 && (time < 30 || solved))
        Response.Redirect("cluePage.aspx");
    else
        Response.Redirect("openPage.aspx");
}

בדיקה: בכל הצירופים של הערכים הקוד מפנה לדף הנכון. כמה דוגמאות:

time_room1solved_colorskeys_foundהדף
20true5openSafe.aspx
20false5cluePage.aspx (אין חידת צבעים, אבל 3 מפתחות ומעלה וזמן < 30)
40true3cluePage.aspx (הזמן גדול, אבל solved_colors = true)
28false4cluePage.aspx
40false6openPage.aspx (אף אחד משני התנאים הפנימיים לא מתקיים)
10true2openPage.aspx (פחות מ-3 מפתחות)

טעות נפוצה:

•לכתוב keys >= 3 && time < 30 || solved בלי סוגריים – בגלל ש-&& קודם ל-||, שחקן עם 0 מפתחות שפתר את חידת הצבעים היה מועבר לדף הרמזים.
•להשתמש ב-Session["keys_found"] ישירות בהשוואה בלי המרה ל-int – לא יעבור הידור.
•לכתוב שלושה if נפרדים במקום else if – אז שחקן שעומד בתנאי הראשון "ממשיך" לבדיקות הבאות.
הקוד המלא
C#
protected void Page_Load(object sender, EventArgs e)
{
    int time = (int)Session["time_room1"];
    bool solved = (bool)Session["solved_colors"];
    int keys = (int)Session["keys_found"];

    if (time < 25 && solved && keys >= 5)
        Response.Redirect("openSafe.aspx");
    else if (keys >= 3 && (time < 30 || solved))
        Response.Redirect("cluePage.aspx");
    else
        Response.Redirect("openPage.aspx");
}

שאלה 6 · זוג "ראש זנב"

זוג "ראש זנב" הוא זוג של מספרים חיוביים ושלמים שבו הספרה הראשונה באחד מן המספרים זהה לספרה האחרונה במספר האחר. אם יש רק ספרה אחת במספר, מספר זה נחשב כספרה ראשונה או כספרה אחרונה.
הערה: אין חשיבות לסדר המספרים בזוג המספרים.

דוגמאות לזוגות מספרים שהם "ראש זנב":

מספר 1מספר 2
12338
9159
45254

כתבו פונקציה בשם IsHeadTail בצד שרת, המקבלת שני מספרים שלמים ומחזירה אמת אם הם זוג "ראש זנב". אחרת, הפונקציה מחזירה שקר.
הערה: ניתן להשתמש בפעולות עזר.

כתבו פונקציה בשם IsHeadTail בצד שרת, המקבלת שני מספרים שלמים ומחזירה אמת אם הם זוג "ראש זנב". אחרת, הפונקציה מחזירה שקר.

(20 נקודות)
◂ פתרון מלא לשאלה 6

פתרון

תשובה

return FirstDigit(num1) == num2 % 10 || FirstDigit(num2) == num1 % 10; (FirstDigit מחלקת ב-10 כל עוד המספר ≥ 10)

מה נדרש: פונקציה בוליאנית שבודקת אם הספרה הראשונה של אחד המספרים שווה לספרה האחרונה של המספר האחר.

רעיון:

•ספרה אחרונה (ספרת האחדות) של מספר חיובי: num % 10.
•ספרה ראשונה (השמאלית): מחלקים ב-10 (חילוק שלמים) כל עוד המספר דו-ספרתי לפחות (≥ 10). מה שנשאר הוא הספרה הראשונה. נכתוב לכך פעולת עזר FirstDigit.
•"אין חשיבות לסדר" – לכן בודקים את שני הכיוונים: ראשונה של num1 מול אחרונה של num2, או ראשונה של num2 מול אחרונה של num1.
•במספר חד-ספרתי הלולאה לא מתבצעת ו-num % 10 הוא המספר עצמו – כלומר הספרה היחידה נחשבת גם ראשונה וגם אחרונה, כנדרש.

פתרון:

C#
// פעולת עזר: מחזירה את הספרה הראשונה (השמאלית) של מספר חיובי
public int FirstDigit(int num)
{
    while (num >= 10)
        num = num / 10;
    return num;
}

public bool IsHeadTail(int num1, int num2)
{
    // הספרה הראשונה של אחד שווה לספרה האחרונה של האחר (בכל אחד משני הכיוונים)
    return FirstDigit(num1) == num2 % 10 || FirstDigit(num2) == num1 % 10;
}

בדיקה:

num1num2חישובתוצאה
12338ראשונה של 38 היא 3, אחרונה של 123 היא 3True
9159ראשונה של 9 היא 9, אחרונה של 159 היא 9True
45254ראשונה של 45 היא 4, אחרונה של 254 היא 4True
12341≠4 וגם 3≠2False
1021ראשונה של 10 היא 1, אחרונה של 21 היא 1True
100231≠3 וגם 2≠0False

טעות נפוצה: לבדוק רק כיוון אחד (ראשונה של num1 מול אחרונה של num2) – אז הזוג (9, 159) מהדוגמה כן עובד, אבל (123, 38) נכשל. טעות נוספת: לולאה while (num > 0) num = num / 10; – היא מגיעה ל-0 ומאבדת את הספרה.

הקוד המלא
C#
// פעולת עזר: מחזירה את הספרה הראשונה (השמאלית) של מספר חיובי
public int FirstDigit(int num)
{
    while (num >= 10)
        num = num / 10;
    return num;
}

public bool IsHeadTail(int num1, int num2)
{
    // הספרה הראשונה של אחד שווה לספרה האחרונה של האחר (בכל אחד משני הכיוונים)
    return FirstDigit(num1) == num2 % 10 || FirstDigit(num2) == num1 % 10;
}

שאלה 7 · שאילתות SQL על טבלת פעילויות (20 נקודות)

במסד נתונים של קבוצת הצופים בעיר מסוימת יש טבלה ששמה GroupActivities המכילה את נתוני פעילויות הקבוצה. העמודות בטבלה הן:

•activityName (שם הפעילות) - מסוג טקסט
•count (מספר משתתפים מקסימלי לפעילות) - מסוג מספר שלם
•duration (משך הפעילות בדקות) - מסוג מספר שלם
•dayNum (מספר המשתתפים בשעות היום) - מסוג מספר שלם
•eveningNum (מספר המשתתפים בשעות הערב) - מסוג מספר שלם

דוגמה לטבלה:

activityNamecountdurationdayNumeveningNum
"טיול אופניים"402402530
"סדנת יצירה"35603035
"הפנינג קיץ"801807040
"פיסול"1550107

יש לבחור 2 מתוך 4 הסעיפים הבאים:

א.

כתבו שאילתה בשפת SQL שמחזירה את כמות הפעילויות בהם מספר המשתתפים המקסימלי גדול מ-20. דוגמה: בטבלה הנוכחית יוחזר הערך 3 (עבור סדנת יצירה, טיול אופניים והפנינג קיץ)

ב.

כתבו שאילתה בשפת SQL המחזירה את מספר המשתתפים הגדול ביותר שהיה בפעילות בשעות היום (הניחו שיש פעילות אחת כזו). דוגמה: בטבלה הנוכחית יוחזר הערך 70 ("הפנינג קיץ").

ג.

כתבו שאילתה בשפת SQL שמחזירה את שמות הפעילויות ואת משך הפעילות שלהם (בדקות), בפעילויות בהם מספר המשתתפים בערב גדול ממספר המשתתפים ביום.

ד.

כתבו שאילתה בשפת SQL שמחזירה את סך כל המשתתפים, בכל סוגי פעילויות, שהיו בפעילות יום. דוגמה: בטבלה הנוכחית יוחזר הערך 135 (25+30+70+10).

◂ פתרון מלא לשאלה 7

סעיף א

תשובה

SELECT COUNT(*) AS numActivities FROM GroupActivities WHERE [count] > 20;

מה נדרש: מספר הפעילויות (כמה שורות) שבהן count גדול מ-20.

רעיון: מסננים ב-WHERE את השורות עם count > 20, וסופרים אותן בפונקציית הצבירה COUNT(*). שם העמודה count זהה לשם הפונקציה COUNT, ולכן כדאי לעטוף אותו בסוגריים מרובעים [count] כדי שיובן כשם עמודה.

פתרון:

SQL
SELECT COUNT(*) AS numActivities
FROM GroupActivities
WHERE [count] > 20;

בדיקה: על טבלת הדוגמה: השורות המתאימות הן טיול אופניים (40), סדנת יצירה (35), הפנינג קיץ (80); פיסול (15) לא. התקבל 3, כמו בדוגמה.

טעות נפוצה: להחזיר את השמות (SELECT activityName) במקום את הכמות, או לכתוב >= 20 במקום > 20.

סעיף ב

תשובה

SELECT MAX(dayNum) AS maxDay FROM GroupActivities;

מה נדרש: הערך הגדול ביותר בעמודה dayNum.

רעיון: פונקציית הצבירה MAX מחזירה את הערך המקסימלי בעמודה. אין צורך ב-WHERE – בודקים את כל הפעילויות.

פתרון:

SQL
SELECT MAX(dayNum) AS maxDay
FROM GroupActivities;

בדיקה: הערכים בעמודה dayNum הם 25, 30, 70, 10. התקבל 70, כמו בדוגמה.

טעות נפוצה: לחפש את המקסימום בעמודה count (המספר המקסימלי המותר) – אבל השאלה שואלת על מספר המשתתפים בפועל בשעות היום, כלומר dayNum.

סעיף ג

תשובה

SELECT activityName, duration FROM GroupActivities WHERE eveningNum > dayNum;

מה נדרש: שם ומשך של כל פעילות שבה eveningNum > dayNum.

רעיון: בוחרים את העמודות activityName ו-duration, ובתנאי WHERE משווים בין שתי עמודות באותה שורה – SQL מאפשר להשוות עמודה לעמודה, לא רק לקבוע.

פתרון:

SQL
SELECT activityName, duration
FROM GroupActivities
WHERE eveningNum > dayNum;

בדיקה: על טבלת הדוגמה:

activityNameduration
טיול אופניים240
סדנת יצירה60

(30 > 25 ו-35 > 30; בהפנינג קיץ 40 < 70 ובפיסול 7 < 10.)

סעיף ד

תשובה

SELECT SUM(dayNum) AS totalDay FROM GroupActivities;

מה נדרש: סכום העמודה dayNum על כל השורות.

רעיון: פונקציית הצבירה SUM מחברת את כל הערכים בעמודה.

פתרון:

SQL
SELECT SUM(dayNum) AS totalDay
FROM GroupActivities;

בדיקה: 25 + 30 + 70 + 10 = 135 – התוצאה 135, כמו בדוגמה.

טעות נפוצה: להשתמש ב-COUNT(dayNum) – זה סופר שורות (4) ולא מחבר ערכים.

פרק שלישי

ענו על שאלה אחת מן השאלות 9-8.

שאלה 8 · ספירת כניסות עם Session ו-Application (20 נקודות)

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

C#
protected void Page_Load (object sender, EventArgs e)
{
     if (Session["log"] == null) // איתחול
           __________(1)___________;
     if (_________(2)________) // LOGIN מותר מקסימום 3 נסיונות
           Response.Write("חרגת ממספר הנסיונות האפשריים");
    else
    {
       // המשתנים UserName, PassWord מכילים את שם המשתמש והסיסמא שהמשתמש הכניס בטופס
       bool ok = Login(UserName, PassWord);
       if (ok)
       {
           Application.Lock();
           if (Application["myCount"] == null)
               Application["myCount"] = 0;
           Application["myCount"] = (int) (_________(3)________;
           Application(_________(4)________ ();
       }// End if
      else
      {
         Session["log"] = ________(5)_________;
      }// End else
   }// End else
} // End Page_load
א.

השלימו את הקוד: כיתבו ליד כל מספר 5-1, את הביטוי החסר.

ב.

הסבירו מה התפקיד של Application["myCount"] בקטע הקוד .

ג.

הסבירו מה התפקיד של Session["log"] בקטע הקוד.

◂ פתרון מלא לשאלה 8

סעיף א

תשובה

(1) Session["log"] = 0 (2) (int)Session["log"] >= 3 (3) Application["myCount"]) + 1 (4) UnLock (5) (int)Session["log"] + 1

מה נדרש: להשלים חמישה ביטויים בקוד שסופר כניסות תקינות ומגביל כל משתמש ל-3 ניסיונות.

רעיון:

•Session["log"] – מונה אישי (לכל משתמש) של ניסיונות כניסה שנכשלו. בפעם הראשונה הוא null ולכן מאתחלים אותו ל-0.
•אם המונה הגיע ל-3 – חוסמים ומציגים הודעה. אחרת בודקים את הפרטים: כניסה תקינה מגדילה את המונה המשותף Application["myCount"]; כניסה שגויה מגדילה את המונה האישי.
•ב-Session וב-Application נשמר object, לכן לפני השוואה או חישוב ממירים ל-int.
•עדכון של Application נעשה בין Application.Lock() ל-Application.UnLock(), כדי ששני משתמשים לא יעדכנו את המונה בו-זמנית.

פתרון:

מספרהביטוי החסרהסבר
(1)Session["log"] = 0אתחול מונה הניסיונות הכושלים של המשתמש
(2)(int)Session["log"] >= 3המשתמש כבר נכשל 3 פעמים – אין לו עוד ניסיונות
(3)Application["myCount"]) + 1השורה המלאה: Application["myCount"] = (int) (Application["myCount"]) + 1; – המרה ל-int והוספת 1
(4)UnLockשחרור הנעילה: Application.UnLock();
(5)(int)Session["log"] + 1ניסיון כושל – מגדילים את המונה האישי ב-1

הקוד המלא:

C#
protected void Page_Load (object sender, EventArgs e)
{
    if (Session["log"] == null) // איתחול
        Session["log"] = 0;
    if ((int)Session["log"] >= 3) // LOGIN מותר מקסימום 3 נסיונות
        Response.Write("חרגת ממספר הנסיונות האפשריים");
    else
    {
        // המשתנים UserName, PassWord מכילים את שם המשתמש והסיסמא שהמשתמש הכניס בטופס
        bool ok = Login(UserName, PassWord);
        if (ok)
        {
            Application.Lock();
            if (Application["myCount"] == null)
                Application["myCount"] = 0;
            Application["myCount"] = (int) (Application["myCount"]) + 1;
            Application.UnLock();
        }// End if
        else
        {
            Session["log"] = (int)Session["log"] + 1;
        }// End else
    }// End else
} // End Page_load

הערה: בשורה (4) מודפס בשאלון Application( – כנראה טעות דפוס במקום Application.; הפקודה הנדרשת היא Application.UnLock();.

בדיקה: Session נפרד לכל משתמש ו-Application משותף (סיסמה נכונה בדוגמה: 1234):

פעולהlog של המשתמשmyCount
דנה – סיסמה שגויה1null
דנה – סיסמה נכונה11
אבי – 3 סיסמאות שגויות1, 2, 31
אבי – סיסמה נכונה3 – מוצגת ההודעה "חרגת ממספר הנסיונות האפשריים"1
דנה – סיסמה נכונה12

טעות נפוצה: להשוות Session["log"] >= 3 בלי המרה – object אי אפשר להשוות למספר, והקוד לא עובר הידור. טעות נוספת: לשכוח את UnLock – אז הנעילה נשארת עד שהשרת מסיים לטפל בבקשה, ובינתיים בקשות של משתמשים אחרים שצריכות את Application ממתינות. משחררים את הנעילה מיד אחרי העדכון.

הקוד המלא
C#
protected void Page_Load (object sender, EventArgs e)
{
    if (Session["log"] == null) // איתחול
        Session["log"] = 0;
    if ((int)Session["log"] >= 3) // LOGIN מותר מקסימום 3 נסיונות
        Response.Write("חרגת ממספר הנסיונות האפשריים");
    else
    {
        // המשתנים UserName, PassWord מכילים את שם המשתמש והסיסמא שהמשתמש הכניס בטופס
        bool ok = Login(UserName, PassWord);
        if (ok)
        {
            Application.Lock();
            if (Application["myCount"] == null)
                Application["myCount"] = 0;
            Application["myCount"] = (int) (Application["myCount"]) + 1;
            Application.UnLock();
        }// End if
        else
        {
            Session["log"] = (int)Session["log"] + 1;
        }// End else
    }// End else
} // End Page_load

סעיף ב

תשובה

מונה משותף לכל משתמשי האתר, שסופר את מספר הכניסות התקינות לאתר (מכל המשתמשים יחד).

מה נדרש: להסביר מה מייצג המשתנה Application["myCount"].

רעיון: משתנה Application נשמר בשרת אחד לכל האתר ומשותף לכל המשתמשים, ונשאר קיים כל זמן שהאתר פועל (לא נמחק כשמשתמש עוזב).

פתרון: Application["myCount"] הוא מונה הכניסות התקינות לאתר – של כל המשתמשים יחד. בכל פעם שמשתמש כלשהו מתחבר בהצלחה (Login מחזירה true), המונה גדל ב-1. בפעם הראשונה הוא null ולכן מאותחל ל-0. מאחר שכמה משתמשים עשויים להתחבר באותו רגע, העדכון נעשה בין Application.Lock() ל-Application.UnLock(), כדי שלא יאבדו ספירות.

בדיקה: אחרי שתי כניסות תקינות של דנה (ומשתמש נוסף שנחסם) הערך הוא 2 – אותו ערך נראה מכל ה-Session-ים.

סעיף ג

תשובה

מונה אישי לכל משתמש של ניסיונות הכניסה שנכשלו; כשהוא מגיע ל-3 המשתמש נחסם.

מה נדרש: להסביר מה מייצג המשתנה Session["log"].

רעיון: משתנה Session נשמר בשרת בנפרד לכל משתמש (לכל דפדפן/גלישה), ולכן מתאים לשמירת מידע אישי בין טעינות של הדף.

פתרון: Session["log"] הוא מונה ניסיונות הכניסה הכושלים של המשתמש הנוכחי. בטעינה הראשונה הוא מאותחל ל-0; בכל ניסיון כושל (Login מחזירה false) הוא גדל ב-1; לפני כל ניסיון בודקים אותו, וכשהגיע ל-3 – המשתמש לא יכול לנסות שוב ומוצגת לו ההודעה "חרגת ממספר הנסיונות האפשריים". כך כל משתמש מוגבל ל-3 ניסיונות, בלי להשפיע על משתמשים אחרים.

בדיקה: אבי נחסם אחרי 3 כישלונות (log = 3) ואילו אצל דנה, באותו זמן, log = 1 והיא ממשיכה להתחבר.

שאלה 9 · הצגת טבלה ממסד נתונים ב-ASP.NET

שאלה זו מתייחסת לטבלת הנתונים GroupActivities המוצגת בשאלה 7.

ראש צוות הצופים מעוניין להפיק טבלה ובה נתוני כל הפעילויות אשר נמשכות לפחות 90 דקות ומתאימות לקבוצה של לפחות 15 אנשים. הפונקציה מקבלת מחרוזת התחברות למסד הנתונים connectionString ומציגה בטבלה את כל העמודות של הפעילויות המתאימות.

בפונקציה חסרים שמונה ביטויים מסומנים במספרים בין סוגריים עגולים. כתבו במחברת הבחינה את מספרי הביטויים החסרים (8-1), וכתבו ליד כל מספר את הביטוי החסר שהוא מייצג.

C#
protected void printTable(string connectionString){
   string resultStr = ______(1)_______;
   DataSet ds = new DataSet();
   SqlConnection connection = new SqlConnection(____(2)________);
   SqlCommand cmd = new SqlCommand();
  cmd.CommandText = "SELECT * FROM [dbo].[ GroupActivities ] WHERE ___(3)___ >= 90
  ____(4)____ count >= 15";
  cmd.Connection = connection;
  connection.___(5)____();
  SqlDataAdapter adapter = new ____(6)______(cmd);
  adapter.Fill(ds);
  connection.Close();
  resultStr += "<table dir=rtl><tr><th>activityName</th><th>duration</th>
  <th>count</th><th>dayNum</th><th>eveningNum</th></tr>";
 foreach (DataRow dr in ds.Tables[0].Rows) {
      resultStr += "<___(7)_____>";
      resultStr += "<td>" + dr["activityName"] + "</td>";
      resultStr += "<td>" + dr["duration"] + "</td>";
      resultStr += "<td>" + dr["count"] + "</td>";
      resultStr += "<td>" + dr["dayNum"] + "</td>";
      resultStr += "<td>" + dr["eveningNum"] + "</td>";
      resultStr += "</tr>";
   }
   resultStr += "</table>";
   Response.___(8)_____(resultStr);
}

כתבו במחברת הבחינה את מספרי הביטויים החסרים (8-1), וכתבו ליד כל מספר את הביטוי החסר שהוא מייצג.

(20 נקודות)
◂ פתרון מלא לשאלה 9

פתרון

תשובה

(1) "" (2) connectionString (3) duration (4) AND (5) Open (6) SqlDataAdapter (7) tr (8) Write

מה נדרש: להשלים שמונה ביטויים בפונקציה ששולפת ממסד הנתונים את הפעילויות המתאימות ומציגה אותן בטבלת HTML.

רעיון – שלבי העבודה עם מסד נתונים:

1.יוצרים חיבור (SqlConnection) בעזרת מחרוזת ההתחברות.
2.יוצרים פקודה (SqlCommand) עם טקסט השאילתה ומקשרים אותה לחיבור.
3.פותחים את החיבור, ממלאים DataSet בעזרת SqlDataAdapter, וסוגרים את החיבור.
4.עוברים על השורות של ds.Tables[0] ובונים מחרוזת HTML: שורת <tr> לכל פעילות, ובה תא <td> לכל עמודה.
5.שולחים את המחרוזת לדפדפן ב-Response.Write.

התנאי בשאלה: "נמשכות לפחות 90 דקות" ← duration >= 90, "ומתאימות לקבוצה של לפחות 15" ← count >= 15 – שני התנאים יחד, כלומר AND.

פתרון:

מספרהביטוי החסרהסבר
(1)""מחרוזת ריקה – מוסיפים לה בהמשך ב-+=
(2)connectionStringמחרוזת ההתחברות שהפונקציה קיבלה כפרמטר
(3)durationעמודת משך הפעילות בדקות (≥ 90)
(4)ANDשני התנאים צריכים להתקיים יחד
(5)Openconnection.Open(); – פתיחת החיבור לפני השליפה
(6)SqlDataAdapternew SqlDataAdapter(cmd) – המתאם שממלא את ה-DataSet
(7)trפתיחת שורה בטבלה, <tr> (נסגרת בהמשך ב-</tr>)
(8)WriteResponse.Write(resultStr); – שליחת הטבלה לדפדפן

הפונקציה המלאה:

C#
protected void printTable(string connectionString){
   string resultStr = "";
   DataSet ds = new DataSet();
   SqlConnection connection = new SqlConnection(connectionString);
   SqlCommand cmd = new SqlCommand();
   cmd.CommandText = "SELECT * FROM [dbo].[GroupActivities] WHERE duration >= 90 AND count >= 15";
   cmd.Connection = connection;
   connection.Open();
   SqlDataAdapter adapter = new SqlDataAdapter(cmd);
   adapter.Fill(ds);
   connection.Close();
   resultStr += "<table dir=rtl><tr><th>activityName</th><th>duration</th><th>count</th><th>dayNum</th><th>eveningNum</th></tr>";
   foreach (DataRow dr in ds.Tables[0].Rows) {
      resultStr += "<tr>";
      resultStr += "<td>" + dr["activityName"] + "</td>";
      resultStr += "<td>" + dr["duration"] + "</td>";
      resultStr += "<td>" + dr["count"] + "</td>";
      resultStr += "<td>" + dr["dayNum"] + "</td>";
      resultStr += "<td>" + dr["eveningNum"] + "</td>";
      resultStr += "</tr>";
   }
   resultStr += "</table>";
   Response.Write(resultStr);
}

הערה: בשאלון השאילתה ושורת הכותרות של הטבלה מודפסות על פני שתי שורות, ובסוגריים המרובעים מופיעים רווחים ([ GroupActivities ]). בקוד C# אמיתי מחרוזת רגילה חייבת להיות בשורה אחת ושם הטבלה בלי רווחים, ולכן בפתרון הן כתובות כך.

בדיקה: הפונקציה על טבלת הדוגמה משאלה 7. השאילתה מחזירה את טיול אופניים (240 דקות, 40) ואת הפנינג קיץ (180 דקות, 80); סדנת יצירה (60 דקות) ופיסול (50 דקות) נפסלות בגלל משך הפעילות. המחרוזת שנשלחה לדפדפן:

HTML
<table dir=rtl><tr><th>activityName</th><th>duration</th><th>count</th><th>dayNum</th><th>eveningNum</th></tr><tr><td>טיול אופניים</td><td>240</td><td>40</td><td>25</td><td>30</td></tr><tr><td>הפנינג קיץ</td><td>180</td><td>80</td><td>70</td><td>40</td></tr></table>

טעות נפוצה: להשלים ב-(4) OR – אז תוצג גם פעילות קצרה שמתאימה ל-15 אנשים (למשל סדנת יצירה). טעות נוספת: ב-(1) לכתוב null – זה עובד ב-C# אבל לא נכון רעיונית; מאתחלים מחרוזת שמוסיפים לה כמחרוזת ריקה.

הקוד המלא
C#
protected void printTable(string connectionString){
   string resultStr = "";
   DataSet ds = new DataSet();
   SqlConnection connection = new SqlConnection(connectionString);
   SqlCommand cmd = new SqlCommand();
   cmd.CommandText = "SELECT * FROM [dbo].[GroupActivities] WHERE duration >= 90 AND count >= 15";
   cmd.Connection = connection;
   connection.Open();
   SqlDataAdapter adapter = new SqlDataAdapter(cmd);
   adapter.Fill(ds);
   connection.Close();
   resultStr += "<table dir=rtl><tr><th>activityName</th><th>duration</th><th>count</th><th>dayNum</th><th>eveningNum</th></tr>";
   foreach (DataRow dr in ds.Tables[0].Rows) {
      resultStr += "<tr>";
      resultStr += "<td>" + dr["activityName"] + "</td>";
      resultStr += "<td>" + dr["duration"] + "</td>";
      resultStr += "<td>" + dr["count"] + "</td>";
      resultStr += "<td>" + dr["dayNum"] + "</td>";
      resultStr += "<td>" + dr["eveningNum"] + "</td>";
      resultStr += "</tr>";
   }
   resultStr += "</table>";
   Response.Write(resultStr);
}
טבלת התשובות
שאלהסעיףתשובה
1-

ג. האובייקט מכיל את התגובה מהשרת לדפדפן

2-

SELECT name, subject FROM EscapeRoom WHERE minUser <= 5 AND maxUser >= 5;

3-

רשימת תבליטים של 10 שורות: Odd number: 1, Even number: 2, Odd number: 3, ..., Odd number: 9, Even number: 10 (כל שורה עם תבליט • בתחילתה).

4א

b

ב

<td colspan=2 align="center"><a href="https://he.wikipedia.org/wiki/Animal">Animals</a></td>

5-

קוראים את שלושת משתני ה-Session עם המרה (int)/(bool), ואז: if (time < 25 && solved && keys >= 5) Response.Redirect("openSafe.aspx"); else if (keys >= 3 && (time < 30 || solved)) Response.Redirect("cluePage.aspx"); else Response.Redirect("openPage.aspx");

6-

return FirstDigit(num1) == num2 % 10 || FirstDigit(num2) == num1 % 10; (FirstDigit מחלקת ב-10 כל עוד המספר ≥ 10)

7א

SELECT COUNT(*) AS numActivities FROM GroupActivities WHERE [count] > 20;

ב

SELECT MAX(dayNum) AS maxDay FROM GroupActivities;

ג

SELECT activityName, duration FROM GroupActivities WHERE eveningNum > dayNum;

ד

SELECT SUM(dayNum) AS totalDay FROM GroupActivities;

8א

(1) Session["log"] = 0 (2) (int)Session["log"] >= 3 (3) Application["myCount"]) + 1 (4) UnLock (5) (int)Session["log"] + 1

ב

מונה משותף לכל משתמשי האתר, שסופר את מספר הכניסות התקינות לאתר (מכל המשתמשים יחד).

ג

מונה אישי לכל משתמש של ניסיונות הכניסה שנכשלו; כשהוא מגיע ל-3 המשתמש נחסם.

9-

(1) "" (2) connectionString (3) duration (4) AND (5) Open (6) SqlDataAdapter (7) tr (8) Write

כל האתר במבט אחד

קיצורי דרך לכל הכלים, הבגרויות והקורסים

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