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

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

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

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

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

א. משך הבחינה: שעתיים.
ב. מבנה השאלון ומפתח הערכה:
פרק ראשון (10*3) 30 נקודות
פרק שני (20*2) + (10*1) 50 נקודות
פרק שלישי (20*1) 20 נקודות
סך הכל 100 נקודות
ג. חומר עזר מותר בשימוש: כל חומר עזר, חוץ ממחשבון שיש בו אפשרות תכנות.

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

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

בהצלחה!

פרק ראשון (30 נקודות)

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

שאלה 1 · תפקיד Session

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

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

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

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

פתרון

תשובה

ג. אובייקט השומר מידע עבור משתמש מסויים.

מה נדרש – לבחור את ההגדרה הנכונה של Session.

רעיון – בשרת ASP.NET יש שני אובייקטים לשמירת מידע בין דפים ובין בקשות:

•Session – נוצר בנפרד לכל משתמש (לכל דפדפן שמתחבר). מה שנשמר ב־Session["..."] של משתמש אחד אינו נראה למשתמש אחר. לדוגמה: שם המשתמש שהתחבר, סל קניות.
•Application – אובייקט אחד משותף לכל האתר ולכל המשתמשים. לדוגמה: מונה מבקרים.

פתרון – נעבור על האפשרויות:

•א. "אובייקט השומר מידע עבור האתר עצמו" – זה תיאור של Application, לא של Session.
•ב. "העברת מידע מן הטופס לשרת בצורה גלויה" – זו שליחת טופס בשיטת GET (המידע מופיע בכתובת), לא Session.
•ג. "אובייקט השומר מידע עבור משתמש מסויים" – נכון, זה בדיוק Session.
•ד. "רכיב המאפשר למחשבים להתחבר לרשת" – רכיב תקשורת (כמו נתב / כרטיס רשת), לא קשור ל־Session.

תשובה: ג.

בדיקה – בשאלה 5 באותו שאלון שומרים ב־Session["name"], Session["age"] נתונים של המשתמש הנוכחי – בדיוק השימוש באפשרות ג.

טעות נפוצה: לבלבל בין Session (לכל משתמש) לבין Application (לכל האתר) ולבחור באפשרות א.

שאלה 2 · שאילתת SQL – טבלת משחקים

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

א. שם קבוצה (name).
ב. כמות משחקים (num).
ג. כמות נצחונות (win).
ד. כמות הפסדים (lost).
ה. כמות תוצאות תיקו (tie).
ו. ניקוד כולל (score).

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

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

פתרון

תשובה

SELECT name FROM Games WHERE win >= lost;

מה נדרש – שאילתה שמחזירה רק את עמודת שם הקבוצה, עבור השורות שבהן win ≥ lost.

רעיון – בוחרים (SELECT) רק את העמודה name, מהטבלה (FROM) Games, ומסננים שורות בתנאי (WHERE) שמשווה בין שתי עמודות באותה שורה: win >= lost.

פתרון

SQL
SELECT name
FROM Games
WHERE win >= lost;

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

namenumwinlosttiescore
מכבי1062220
הפועל1035211
בית"ר1044214
בני101725

התוצאה: מכבי (6 ≥ 2) ו־בית"ר (4 ≥ 4, שוויון נכלל). הפועל ובני לא הוחזרו כי אצלן win < lost.

טעות נפוצה: לכתוב > במקום >= – אז קבוצה עם מספר ניצחונות שווה למספר ההפסדים (כמו בית"ר) לא תוחזר, והשאלה דורשת "גדולה או שווה".

שאלה 3 · פלט של פונקציה בצד השרת (Response.Write)

לפניכם פונקציה בשם Func הכתובה בצד השרת. העתק למחברתך את מה שיוצג בדפדפן לאחר הרצת הפונקציה Func עם הפרמטר num = 21.

C#
public void Func (int num) {
    string str = "<table border = '1'>";
    int i = 2;
    while (i < num) {
        if (num % i ==0)
            str += "<tr><td>" + i + "</td></tr>";
        i++;
    }
    str += "</table>";
    Response.Write (str);
}

העתק למחברתך את מה שיוצג בדפדפן לאחר הרצת הפונקציה Func עם הפרמטר num = 21.

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

פתרון

תשובה

טבלה עם מסגרת, בעלת עמודה אחת ושתי שורות: בשורה הראשונה 3 ובשורה השנייה 7.
(ה־HTML שנשלח: <table border = '1'><tr><td>3</td></tr><tr><td>7</td></tr></table>)

מה נדרש – להבין איזה HTML הפונקציה בונה כש־num = 21, ואיך הדפדפן מציג אותו.

רעיון – הפונקציה בונה מחרוזת HTML של טבלה. הלולאה עוברת על כל i מ־2 עד num−1 (כלומר 2..20), ולכל i שמחלק את num ללא שארית (num % i == 0) מוסיפה שורה <tr> עם תא אחד <td> שבו הערך i. בסוף Response.Write שולח את המחרוזת לדפדפן. כלומר: הטבלה מציגה את המחלקים של num (בלי 1 ובלי num עצמו).

פתרון – מעקב (רק הערכים של i שבהם התנאי מתקיים משנים את str):

i21 % iמתחלק?מה נוסף ל־str
21לא–
30כן<tr><td>3</td></tr>
4, 5, 61, 1, 3לא–
70כן<tr><td>7</td></tr>
8 … 20≠ 0לא–
21–הלולאה נעצרת (i < num לא מתקיים)–

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

HTML
<table border = '1'><tr><td>3</td></tr><tr><td>7</td></tr></table>

מה יוצג בדפדפן – טבלה עם מסגרת (border = 1), עמודה אחת ושתי שורות:

3
7

בדיקה – הפונקציה כפי שהיא מודפסת בשאלון, עם num = 21, מפיקה בדיוק:
<table border = '1'><tr><td>3</td></tr><tr><td>7</td></tr></table>.
(לבדיקה נוספת: עם num = 12 מתקבלות השורות 2, 3, 4, 6, ועם num = 13 – מספר ראשוני – מתקבלת טבלה ריקה.)

טעות נפוצה: לכתוב גם את 1 ואת 21 – הלולאה מתחילה מ־2 ונעצרת לפני num. טעות נוספת: להעתיק את קוד ה־HTML במקום לתאר/לצייר את מה שמוצג בדפדפן – השאלה שואלת מה יוצג (טבלה עם המספרים 3 ו־7).

פרק שני (50 נקודות)

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

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

נועה, תלמידת מדעי המחשב, פיתחה אתר ובו מידע על ערי בירה באירופה. באתר תיקייה בשם Images ובה תמונה של דגל בשם flag.png

HTML
<!DOCTYPE html>
<html lang="he" >
  <meta charset="utf-8"/>
  <table style="width:150px" border=2px dir="rtl">
    <tr >
     <td colspan=2>אירופה</td>
    </tr>
    <tr>
     <td rowspan=3>ערי בירה</td>
     <td>פריז</td>
    </tr>
    <tr >
     <td >לונדון</td>
    </tr>
    <tr>
     <td>בריסל</td>
    </tr>
    <tr>
      <td colspan="2" align="center">
         <img src="Images/flag.png" />
      </td>
    </tr>
  </table>
</html>
א.

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

ב.

הוסיפו שורת קוד מתאימה ב html כך שלחיצה על תמונת הדגל תעביר לאתר:
https://en.wikipedia.org/wiki/Europe

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

סעיף א

תשובה

b

מה נדרש – לזהות איזה מארבעת הציורים מתאים לטבלה שבקוד.

רעיון – עוברים שורה־שורה (<tr>) ובודקים כמה תאים יש בכל שורה ומה המשמעות של colspan (תא שמתפרש על כמה עמודות) ושל rowspan (תא שמתפרש על כמה שורות). dir="rtl" אומר שהתא הראשון בשורה מופיע מימין.

פתרון

1.שורה 1: תא אחד colspan=2 – "אירופה" תופס את כל רוחב הטבלה (שתי עמודות).
2.שורה 2: התא "ערי בירה" עם rowspan=3 – תא אחד גבוה שתופס את שורות 2, 3, 4 בעמודה הימנית (הראשונה, בגלל rtl). לידו משמאל "פריז".
3.שורות 3 ו־4: בכל אחת תא אחד בלבד ("לונדון", "בריסל") – הם נכנסים לעמודה השמאלית, כי העמודה הימנית כבר תפוסה על ידי "ערי בירה".
4.שורה 5: תא colspan="2" עם align="center" – תמונת הדגל במרכז של תא ברוחב כל הטבלה.

נפסול את האפשרויות האחרות:

•a – כל תא בשורה נפרדת ברוחב מלא, "ערי בירה" לא מתפרש על 3 שורות – שגוי.
•c – "ערי בירה" מופיע 3 פעמים, כאילו אין rowspan – שגוי.
•d – הדגל בתא ברוחב עמודה אחת בלבד, כאילו אין colspan בשורה האחרונה – שגוי.
•b – תואם בדיוק את 4 הסעיפים שלמעלה.

תשובה: b.

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

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

סעיף ב

תשובה

עוטפים את התמונה בתגית קישור:
<a href="https://en.wikipedia.org/wiki/Europe"><img src="Images/flag.png" /></a>

מה נדרש – שלחיצה על תמונת הדגל תעביר לכתובת https://en.wikipedia.org/wiki/Europe.

רעיון – קישור ב־HTML נוצר בתגית <a href="...">. מה שנמצא בין <a> ל־</a> הוא האזור הלחיץ – אפשר לשים שם טקסט וגם תמונה. לכן עוטפים את תגית ה־<img> בתגית <a>.

פתרון – השורה שבתוך התא האחרון הופכת ל:

HTML
<a href="https://en.wikipedia.org/wiki/Europe"><img src="Images/flag.png" /></a>

הדף המלא אחרי השינוי:

HTML
<!DOCTYPE html>
<html lang="he" >
  <meta charset="utf-8"/>
  <table style="width:150px" border=2px dir="rtl">
    <tr >
     <td colspan=2>אירופה</td>
    </tr>
    <tr>
     <td rowspan=3>ערי בירה</td>
     <td>פריז</td>
    </tr>
    <tr >
     <td >לונדון</td>
    </tr>
    <tr>
     <td>בריסל</td>
    </tr>
    <tr>
      <td colspan="2" align="center">
         <a href="https://en.wikipedia.org/wiki/Europe">
            <img src="Images/flag.png" />
         </a>
      </td>
    </tr>
  </table>
</html>

בדיקה – בדף שהוצג בדפדפן, הדגל נשאר במקומו (שורה תחתונה, במרכז), ולחיצה עליו פותחת את הכתובת שב־href.

אפשרות נוספת (פחות מקובלת): להוסיף לתמונה אירוע JavaScript –
<img src="Images/flag.png" onclick="location.href='https://en.wikipedia.org/wiki/Europe'" />.

טעות נפוצה: לשים את הכתובת ב־src של התמונה (אז הדפדפן ינסה להציג את דף ויקיפדיה כתמונה), או לסגור את </a> לפני התמונה – אז הקישור ריק והתמונה אינה לחיצה.

שאלה 5 · הפניית משתמש לפי משתני Session

באתר בתי קולנוע "סרט לי" הוגדרו שלושה משתני Session:

•Session[“name”]: מחרוזת המייצגת את שם המשתמש.
•Session[“age”]: מספר שלם המייצג גיל המשתמש.
•Session[“genre”]: מחרוזת המייצגת את סוג הסרט המועדף (“action”, ”drama”, “comedy”).

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

א. משתמש מתחת לגיל 13 יועבר לעמוד kids.aspx
ב. משתמש מגיל 13 ומעלה הצופה בסרטי אקשן (action) או קומדיה (comedy) יועבר לעמוד action.aspx
ג. שאר המשתמשים יועברו לעמוד drama.aspx

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

פתרון

תשובה

if ((int)Session["age"] < 13) Response.Redirect("kids.aspx");
else if (genre == "action" || genre == "comedy") Response.Redirect("action.aspx");
else Response.Redirect("drama.aspx");

מה נדרש – קטע קוד בצד השרת (C#) שקורא את הגיל ואת סוג הסרט מה־Session ומעביר את המשתמש לאחד משלושה דפים.

רעיון

•ב־Session נשמרים ערכים מסוג object, לכן כשקוראים אותם צריך המרה (casting): (int)Session["age"] לגיל, (string)Session["genre"] (או .ToString()) לסוג הסרט.
•מעבר לדף אחר נעשה עם Response.Redirect("שם הדף").
•סדר הבדיקות חשוב: קודם בודקים גיל מתחת ל־13 (כלל א) – אז לא משנה מה סוג הסרט. רק אם הגיל 13 ומעלה (ה־else) בודקים אם הסוג action או comedy (כלל ב). כל השאר – drama.aspx (כלל ג).
•המשתנה Session["name"] לא נחוץ להחלטה.

פתרון

C#
int age = (int)Session["age"];
string genre = (string)Session["genre"];

if (age < 13)
{
    Response.Redirect("kids.aspx");
}
else if (genre == "action" || genre == "comedy")
{
    Response.Redirect("action.aspx");
}
else
{
    Response.Redirect("drama.aspx");
}

בדיקה – הקטע על כל המקרים:

agegenreהדף שהתקבל
5actionkids.aspx
12dramakids.aspx
12comedykids.aspx
13actionaction.aspx
13comedyaction.aspx
13dramadrama.aspx
40comedyaction.aspx
40dramadrama.aspx

הגבול: גיל 13 בדיוק כבר נחשב "מגיל 13 ומעלה" – לכן התנאי הוא age < 13 ולא age <= 13.

טעות נפוצה: להשוות Session["age"] < 13 בלי המרה ל־int (שגיאת הידור – אי אפשר להשוות object למספר), או לבדוק את סוג הסרט לפני הגיל – אז ילד בן 10 שאוהב קומדיה יועבר בטעות ל־action.aspx.

הקוד המלא
C#
int age = (int)Session["age"];
string genre = (string)Session["genre"];

if (age < 13)
{
    Response.Redirect("kids.aspx");
}
else if (genre == "action" || genre == "comedy")
{
    Response.Redirect("action.aspx");
}
else
{
    Response.Redirect("drama.aspx");
}

שאלה 6 · JavaScript – חילוץ סוג האתר מכתובת

כתובת אתר אינטרנט מורכבת מארבעה חלקים:
א. הכיתוב www (prefix)
ב. שם האתר (name)
ג. סוג האתר (type)– gov, co
ד. סיומת (suffix)– il, com

ארבעת החלקים מחוברים באמצעות התו נקודה (.) לדוגמה:

www.education.gov.il
www.ynet.co.il

כתבו בשפת JavaScript פונקציה בשם getType המקבלת מחרוזת המייצגת כתובת אתר אינטרנט תקין (domain) ומחזירה מחרוזת המכילה את סוג האתר (type). לדוגמה:

•עבור האתר www.education.gov.il תוחזר המחרוזת: gov
•עבור האתר www.ynet.co.il תוחזר המחרוזת: co
(20 נקודות)
◂ פתרון מלא לשאלה 6

פתרון

תשובה

function getType(domain) { var parts = domain.split("."); return parts[2]; }

מה נדרש – פונקציית JavaScript שמקבלת כתובת כמו www.education.gov.il ומחזירה את החלק השלישי – סוג האתר (gov).

רעיון – הכתובת תקינה ותמיד בנויה מ־4 חלקים המופרדים בנקודה: prefix.name.type.suffix. אם מפרקים את המחרוזת לפי התו "." מתקבל מערך של 4 מחרוזות, וסוג האתר הוא האיבר באינדקס 2 (האינדקסים מתחילים מ־0).

פתרון

JavaScript
function getType(domain) {
    var parts = domain.split(".");   // ["www", name, type, suffix]
    return parts[2];
}

עבור "www.education.gov.il" הפעולה split(".") מחזירה את המערך ["www", "education", "gov", "il"], והאיבר parts[2] הוא "gov".

פתרון חלופי בלי split – מוצאים את מקומות הנקודות עם indexOf ולוקחים את התת־מחרוזת שבין הנקודה השנייה לשלישית:

JavaScript
function getType(domain) {
    var first = domain.indexOf(".");              // the dot after www
    var second = domain.indexOf(".", first + 1);  // the dot after the site name
    var third = domain.indexOf(".", second + 1);  // the dot before the suffix
    return domain.substring(second + 1, third);
}

בדיקה – שתי הגרסאות:

•getType("www.education.gov.il") → gov
•getType("www.ynet.co.il") → co
•וגם www.abc.org.com → org, www.x.ac.il → ac.

טעות נפוצה: לקחת את parts[1] (שם האתר) במקום parts[2], או לחתוך לפי מיקומים קבועים (למשל תמיד מתו 4) – שם האתר באורך משתנה, ולכן חייבים להיעזר בנקודות. ב־substring(start, end) התו שבמקום end אינו נכלל, ולכן מעבירים בדיוק את מקום הנקודה השלישית.

שאלה 7 · SQL – שאילתה עם כמה תנאים (OR)

במסד נתונים של עיר מסוימת יש טבלה ששמה VehicleTable המכילה את נתוני כלי התחבורה בעיר.
העמודות בטבלה הן:

א. name (שם), מסוג טקסט.
ב. wheels (מספר גלגלים), מסוג מספר שלם.
ג. maxSpeed (מהירות בקמ"ש מקסימלית מותרת) מסוג מספר שלם.
ד. day (מספר כלי תחבורה בשעות היום), מסוג מספר שלם.
ה. evening (מספר כלי תחבורה בשעות הערב) מסוג מספר שלם.

דוגמה לטבלה ובה כמה מן פרטי כלי התחבורה בעיר:

namewheelsmaxSpeeddayevening
קורקינט2202030
אופניים2154510
אופניים חשמליים2359580
מכונית2100250100
אוטובוס4808720
משאית460405

כתבו שאילתה אחת בשפת SQL המבקשת להציג את שמות כלי התחבורה המקיימים אחד או יותר מהתנאים הבאים:

א. מספר כלי התחבורה בשעות היום נמוך ממספר כלי התחבורה בשעות הערב.
ב. מספר הרכבים הכולל ביממה (שעות היום וגם שעות הערב) גדול מ – 100.
ג. מהירות מקסימלית בין 30 קמ"ש ל- 75 קמ"ש (כולל).

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

פתרון

תשובה

SELECT name FROM VehicleTable WHERE day < evening OR day + evening > 100 OR maxSpeed BETWEEN 30 AND 75;
(על טבלת הדוגמה: קורקינט, אופניים חשמליים, מכונית, אוטובוס, משאית)

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

רעיון – "אחד או יותר מהתנאים" = חיבור התנאים ב־OR. כל תנאי מתורגם לביטוי על עמודות השורה:

•א: day < evening
•ב: סך היממה הוא day + evening (ב־SQL מותר לחשב ביטוי חשבוני בתנאי) – day + evening > 100
•ג: "בין 30 ל־75 כולל" – maxSpeed BETWEEN 30 AND 75 (BETWEEN כולל את שני הקצוות; שקול ל־maxSpeed >= 30 AND maxSpeed <= 75).

פתרון

SQL
SELECT name
FROM VehicleTable
WHERE day < evening
   OR day + evening > 100
   OR maxSpeed BETWEEN 30 AND 75;

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

nameא: day < eveningב: day + evening > 100ג: 30 ≤ maxSpeed ≤ 75מוצג?
קורקינט20 < 30 ✔50 ✘20 ✘כן
אופניים45 < 10 ✘55 ✘15 ✘לא
אופניים חשמליים✘175 ✔35 ✔כן
מכונית✘350 ✔100 ✘כן
אוטובוס✘107 ✔80 ✘כן
משאית✘45 ✘60 ✔כן

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

טעות נפוצה: לחבר את התנאים ב־AND (אז נדרשים כל התנאים יחד, ובטבלת הדוגמה לא יוחזר אף כלי), או לכתוב את תנאי ג כ־maxSpeed > 30 AND maxSpeed < 75 – בלי השוויון, למרות שכתוב "(כולל)". אם מערבבים AND בתוך OR – חובה לשים סוגריים: ... OR (maxSpeed >= 30 AND maxSpeed <= 75).

פרק שלישי (20 נקודות)

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

שאלה 8 · בדיקת שם משתמש וסיסמה מול מסד הנתונים

בטופס כניסה לאתר כלשהו נדרש המשתמש להכניס שם משתמש וסיסמה לשדות האלה :

HTML
<input type="text" name="id" id="id"/>

<input type="password" name="password" id="password" />

בבסיס הנתונים של האתר קיימת טבלה בשם users ובה שתי עמודות:

•name – משתנה מסוג טקסט
•password – משתנה מסוג טקסט
namepassword
MoshesomePassword
Danisecret

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

•אם שם המשתמש אינו קיים בבסיס הנתונים הפעולה תפנה לעמוד notExists.aspx
•אם שם המשתמש קיים אך הסיסמא שגויה הפעולה תפנה לעמוד wrongPassword.aspx
•אם שם המשתמש תקין וגם הסיסמא תקינה הפעולה תפנה לעמוד welcome.aspx
C#
protected void LoginFunc(string connectionString){
        SqlConnection  connection = new SqlConnection(connectionString);
        SqlCommand command  = new SqlCommand();
        DataSet ds = new DataSet();
        command.CommandText = string.Format("Select * From users Where name = '{0}'",
        Request.Form["id"]);
        command.Connection= connection;
        connection.Open();
        SqlDataAdapter adapter = new SqlDataAdapter(command);
        adapter.Fill(ds);
        connection.Close();
                    * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
                    * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
}

יש להשלים את הקוד החסר בסוף הפעולה (מסומן בכוכביות)

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

פתרון

תשובה

if (ds.Tables[0].Rows.Count == 0)
{
Response.Redirect("notExists.aspx");
}
else if (ds.Tables[0].Rows[0]["password"].ToString() == Request.Form["password"])
{
Response.Redirect("welcome.aspx");
}
else
{
Response.Redirect("wrongPassword.aspx");
}

מה נדרש – להשלים את סוף הפעולה: אחרי שהשאילתה רצה והתוצאות נמצאות ב־ds, להחליט לאיזה מבין שלושת הדפים להפנות.

רעיון

•השאילתה Select * From users Where name = '...' מחזירה רק את השורות שבהן השם שווה לשם שהוקלד בשדה id. התוצאה נמצאת בטבלה הראשונה של ה־DataSet: ds.Tables[0].
•אם בטבלה אין שורות (ds.Tables[0].Rows.Count == 0) – השם לא קיים → notExists.aspx.
•אחרת השם קיים, וצריך להשוות את הסיסמה השמורה בשורה שנמצאה, ds.Tables[0].Rows[0]["password"], לסיסמה שהמשתמש הקליד בטופס, Request.Form["password"] (השם password הוא ה־name של שדה הסיסמה בטופס).
•שוות → welcome.aspx; שונות → wrongPassword.aspx.
•הערך שבתא של DataRow הוא object, ולכן ממירים אותו ל־string עם ToString() לפני ההשוואה.

פתרון – הקוד שנכתב במקום הכוכביות:

C#
if (ds.Tables[0].Rows.Count == 0)
{
    Response.Redirect("notExists.aspx");
}
else if (ds.Tables[0].Rows[0]["password"].ToString() == Request.Form["password"])
{
    Response.Redirect("welcome.aspx");
}
else
{
    Response.Redirect("wrongPassword.aspx");
}

הפעולה המלאה:

C#
protected void LoginFunc(string connectionString){
    SqlConnection connection = new SqlConnection(connectionString);
    SqlCommand command = new SqlCommand();
    DataSet ds = new DataSet();
    command.CommandText = string.Format("Select * From users Where name = '{0}'",
    Request.Form["id"]);
    command.Connection= connection;
    connection.Open();
    SqlDataAdapter adapter = new SqlDataAdapter(command);
    adapter.Fill(ds);
    connection.Close();

    // ---- the missing code ----
    if (ds.Tables[0].Rows.Count == 0)
    {
        Response.Redirect("notExists.aspx");
    }
    else if (ds.Tables[0].Rows[0]["password"].ToString() == Request.Form["password"])
    {
        Response.Redirect("welcome.aspx");
    }
    else
    {
        Response.Redirect("wrongPassword.aspx");
    }
}

בדיקה – הפעולה המלאה על הטבלה users מהשאלה:

idpasswordהפניה
MoshesomePasswordwelcome.aspx
Danisecretwelcome.aspx
DanisomePasswordwrongPassword.aspx
Moshe(ריק)wrongPassword.aspx
YossisecretnotExists.aspx

טעות נפוצה: לגשת ל־Rows[0] בלי לבדוק קודם שיש שורות – כשהשם לא קיים זו שגיאת זמן ריצה. טעות נוספת: להשוות Rows[0]["password"] == Request.Form["password"] בלי ToString – זו השוואה בין object למחרוזת, שבודקת זהות של אובייקטים ולא את התוכן, ולכן תחזיר false גם כשהסיסמה נכונה.

הערה: בניית שאילתה משרשור הקלט של המשתמש (string.Format עם Request.Form) חשופה ל־SQL Injection; באתר אמיתי משתמשים בפרמטרים (@name). כאן הקוד הנתון כתוב כך, ואנו רק משלימים אותו.

הקוד המלא
C#
protected void LoginFunc(string connectionString){
    SqlConnection connection = new SqlConnection(connectionString);
    SqlCommand command = new SqlCommand();
    DataSet ds = new DataSet();
    command.CommandText = string.Format("Select * From users Where name = '{0}'",
    Request.Form["id"]);
    command.Connection= connection;
    connection.Open();
    SqlDataAdapter adapter = new SqlDataAdapter(command);
    adapter.Fill(ds);
    connection.Close();

    // ---- the missing code ----
    if (ds.Tables[0].Rows.Count == 0)
    {
        Response.Redirect("notExists.aspx");
    }
    else if (ds.Tables[0].Rows[0]["password"].ToString() == Request.Form["password"])
    {
        Response.Redirect("welcome.aspx");
    }
    else
    {
        Response.Redirect("wrongPassword.aspx");
    }
}

שאלה 9 · השלמת פעולה המציגה טבלה ממסד הנתונים

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

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

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

C#
protected void printTable(string connectionString)
{
   string resultStr = "";
   DataSet ds = new DataSet();
   SqlConnection connection = new SqlConnection(_____(1)______);
   SqlCommand cmd = new SqlCommand();
   cmd.CommandText = " _____(2)______ FROM [dbo].[VehicleTable] where ____(3)______";
   cmd.Connection = connection;
   connection.Open();
   SqlDataAdapter adapter = new SqlDataAdapter(____(4)___);
   adapter.____(5)___ (ds);
   connection.Close();
   resultStr += "<table dir=rtl><tr><th>name</th> <th>wheels</th>
   <th>maxSpeed</th>";
   resultStr += "<th>day</th><th> evening </th></tr>";

    foreach (_____(6)______)
    {
       resultStr += "<___(7)______>";
       resultStr += "<td>" + dr["name"] + "</td>";
       resultStr += "<td>" + dr[“wheels"] + "</td>";
       resultStr += "<td>" + dr["maxSpeed"] + "</td>";
       resultStr += "<td>" + dr["day"] + "</td>";
       resultStr += "<td>" + dr["evening"] + "</td>";
       resultStr += "</tr>";
     }
     resultStr += "</table>";
     _____(8)____ (resultStr);
}

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

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

פתרון

תשובה

(1) connectionString
(2) SELECT *
(3) wheels = 2 AND maxSpeed > 22
(4) cmd
(5) Fill
(6) DataRow dr in ds.Tables[0].Rows
(7) tr
(8) Response.Write

מה נדרש – להשלים 8 חורים בפעולה שמתחברת למסד, שולפת את כלי התחבורה הדו־גלגליים שמהירותם המקסימלית גדולה מ־22, ומציגה אותם בטבלת HTML.

רעיון – זה התבנית הקבועה של קריאה ממסד נתונים ב־ASP.NET:
חיבור (SqlConnection עם מחרוזת ההתחברות) → פקודה (SqlCommand עם טקסט השאילתה והחיבור) → פתיחת החיבור → SqlDataAdapter שמקבל את הפקודה וממלא (Fill) את ה־DataSet → סגירת החיבור → מעבר על השורות של ds.Tables[0] ובניית HTML → שליחה לדפדפן עם Response.Write.

פתרון

מספרהביטוי החסרהסבר
(1)connectionStringמחרוזת ההתחברות שהפעולה קיבלה כפרמטר
(2)SELECT *"את כל העמודות" – כוכבית
(3)wheels = 2 AND maxSpeed > 22שני התנאים יחד (AND); "לא כולל" ⇒ > ולא >=
(4)cmdה־adapter מריץ את הפקודה cmd
(5)Filladapter.Fill(ds) ממלא את ה־DataSet בתוצאות
(6)DataRow dr in ds.Tables[0].Rowsהמשתנה נקרא dr (כך הוא משמש בגוף הלולאה) ועובר על שורות הטבלה הראשונה
(7)trפתיחת שורה בטבלה; בסוף כל איטרציה נסגרת ב־</tr>
(8)Response.Writeשליחת מחרוזת ה־HTML לדפדפן

הפעולה המלאה אחרי ההשלמה:

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].[VehicleTable] where wheels = 2 AND maxSpeed > 22";
    cmd.Connection = connection;
    connection.Open();
    SqlDataAdapter adapter = new SqlDataAdapter(cmd);
    adapter.Fill(ds);
    connection.Close();
    resultStr += "<table dir=rtl><tr><th>name</th> <th>wheels</th> <th>maxSpeed</th>";
    resultStr += "<th>day</th><th> evening </th></tr>";

    foreach (DataRow dr in ds.Tables[0].Rows)
    {
        resultStr += "<tr>";
        resultStr += "<td>" + dr["name"] + "</td>";
        resultStr += "<td>" + dr["wheels"] + "</td>";
        resultStr += "<td>" + dr["maxSpeed"] + "</td>";
        resultStr += "<td>" + dr["day"] + "</td>";
        resultStr += "<td>" + dr["evening"] + "</td>";
        resultStr += "</tr>";
    }
    resultStr += "</table>";
    Response.Write(resultStr);
}

(בשאלון מחרוזת הכותרת "<table dir=rtl>...<th>maxSpeed</th>" נשברה לשתי שורות בהדפסה, ו־dr[“wheels"] מודפס עם מירכאה מעוצבת; בקוד אמיתי המחרוזת כתובה בשורה אחת והמירכאות רגילות, כמו למעלה.)

בדיקה – הפעולה המלאה על נתוני VehicleTable משאלה 7. מבין הכלים הדו־גלגליים: קורקינט (20) ואופניים (15) אינם עומדים בתנאי maxSpeed > 22; נשארים:

namewheelsmaxSpeeddayevening
אופניים חשמליים2359580
מכונית2100250100

(אוטובוס ומשאית נפסלים כי יש להם 4 גלגלים.) אותה תוצאה מתקבלת גם מהשאילתה SELECT * FROM VehicleTable WHERE wheels = 2 AND maxSpeed > 22.

טעות נפוצה: לכתוב ב־(3) OR במקום AND (אז יוצגו גם האוטובוס והמשאית), או maxSpeed >= 22 למרות ש"לא כולל". ב־(6) לשכוח את הטיפוס DataRow או לכתוב ds.Rows – ל־DataSet אין Rows, רק לטבלה שבתוכו (ds.Tables[0].Rows).

הקוד המלא
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].[VehicleTable] where wheels = 2 AND maxSpeed > 22";
    cmd.Connection = connection;
    connection.Open();
    SqlDataAdapter adapter = new SqlDataAdapter(cmd);
    adapter.Fill(ds);
    connection.Close();
    resultStr += "<table dir=rtl><tr><th>name</th> <th>wheels</th> <th>maxSpeed</th>";
    resultStr += "<th>day</th><th> evening </th></tr>";

    foreach (DataRow dr in ds.Tables[0].Rows)
    {
        resultStr += "<tr>";
        resultStr += "<td>" + dr["name"] + "</td>";
        resultStr += "<td>" + dr["wheels"] + "</td>";
        resultStr += "<td>" + dr["maxSpeed"] + "</td>";
        resultStr += "<td>" + dr["day"] + "</td>";
        resultStr += "<td>" + dr["evening"] + "</td>";
        resultStr += "</tr>";
    }
    resultStr += "</table>";
    Response.Write(resultStr);
}
טבלת התשובות
שאלהסעיףתשובה
1-

ג. אובייקט השומר מידע עבור משתמש מסויים.

2-

SELECT name FROM Games WHERE win >= lost;

3-

טבלה עם מסגרת, בעלת עמודה אחת ושתי שורות: בשורה הראשונה 3 ובשורה השנייה 7.
(ה־HTML שנשלח: <table border = '1'><tr><td>3</td></tr><tr><td>7</td></tr></table>)

4א

b

ב

עוטפים את התמונה בתגית קישור:
<a href="https://en.wikipedia.org/wiki/Europe"><img src="Images/flag.png" /></a>

5-

if ((int)Session["age"] < 13) Response.Redirect("kids.aspx");
else if (genre == "action" || genre == "comedy") Response.Redirect("action.aspx");
else Response.Redirect("drama.aspx");

6-

function getType(domain) { var parts = domain.split("."); return parts[2]; }

7-

SELECT name FROM VehicleTable WHERE day < evening OR day + evening > 100 OR maxSpeed BETWEEN 30 AND 75;
(על טבלת הדוגמה: קורקינט, אופניים חשמליים, מכונית, אוטובוס, משאית)

8-

if (ds.Tables[0].Rows.Count == 0)
{
Response.Redirect("notExists.aspx");
}
else if (ds.Tables[0].Rows[0]["password"].ToString() == Request.Form["password"])
{
Response.Redirect("welcome.aspx");
}
else
{
Response.Redirect("wrongPassword.aspx");
}

9-

(1) connectionString
(2) SELECT *
(3) wheels = 2 AND maxSpeed > 22
(4) cmd
(5) Fill
(6) DataRow dr in ds.Tables[0].Rows
(7) tr
(8) Response.Write

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

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

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