12au Final Exam Grading
From CSE154-Admin
Exam
Contents[hide] |
[edit] Question 1 (HTML/CSS Tracing)
[edit] Q1 Solution
[edit] Q1 Criteria
20 points total
Each of the following categories is atomic (all-or-nothing); if they make any mistake in that area, mark off all of the points for that area.
- 2 alignment: all text is left-aligned within the element (including 333 at far-left edge of page)
- 2 background color: the 22 div is colored (and nothing else)
- 2 block vs. inline: "1" is above 22; dashed border around 333, tight around content, not across page (no border around "1")
- 2 borders: solid borders around all divs
- 4 float: 4444 is floating left of 55555 properly (and no other content seems to be floating)
- -2 if 666666 does not clear below 4444
- -4 if 4444 is at far left edge of page, outside of parent div
- 2 margin: overall content area centered, no extraneous margins
- 2 padding: all divs have 1em padding on all sides, inside the border (if they don't have borders and therefore you can't tell, then -1; if 333 seems to have 1em padding, -1)
- 2 underline: 22 text is underlined (and no other text is underlined); underline is tight under content (doesn't stretch to edge of div)
- 2 width: 50% width for most divs
other deductions
- -1 point each for any other minor misc. stuff they do wrong that isn't listed above
[edit] Question 2 (CSS)
[edit] Q2 Solution
/* A */ body { text-align: center; font-family: monospace; } | 1 = div > span /* B */ #div { background-color: yellow; font-weight: bold; } | 22 = #div div > #div /* C */ div span { float: left; border: 2px solid black; } | 333 = span.div /* D */ .div, #span { float: right; width: 25%; border: 2px solid black; } | 4444 = div.div div > div.div /* E */ #span { clear: right; font-style: italic; } | 55555 = #span div > div#span /* F */ .span { clear: right; border-top: 2px dashed black; } | 666666 = .span div > div.span
[edit] Q2 Criteria
20 points total
- 2 alignment: text-align center on body or all divs (no margin auto or float center or other crap) (/* A */)
- 4 borders:
- 3: solid on 1, 333, 4444, 55555 (-1 for each missed) (/* C, D */)
- 1: dashed on top of 666666 (/* F */)
- 2 color: yellow background on "22" div (and not elsewhere; on "1" is okay) (-1 if exam didn't photocopy the bg color) (/* B */)
- 6 float:
- 2: "1" floats left (/* C */)
- 2: 333, 4444 float right (atomic) (/* D */)
- 2: 55555 clears and floats right (atomic) (or can use margin-left 75%, width 25%) (/* E */)
- 2: 666666 clears right (atomic) (doesn't need to clear if they use margin-left/width solution for 55555) (/* F */)
- 3 fonts
- 1: font-family monospace on body or all divs (/* A */)
- 1: "2 2" bold (/* B */)
- 1: "55555" italic (/* E */)
- 3 width
- 25% on 333, 4444, 55555 (-1 for each missed) (/* D */)
- special deductions
- -2 class/id confusion in their CSS syntax (# vs .)
- SHOW TO INSTRUCTOR / HEAD TA if they try to modify the provided HTML (add IDs, etc.)
[edit] Question 3 (PHP)
[edit] Q3 Solution
<?php if ($_SERVER["REQUEST_METHOD"] == "POST") { if (!isset($_POST["word"]) || !preg_match("/^[a-zA-Z]+$/", $_POST["word"])) { header("HTTP/1.1 400 Invalid Request"); die(); } $badword = strtolower($_POST["word"]); $lines = array(); foreach (file("text.txt", FILE_IGNORE_NEW_LINES) as $line) { $badline = FALSE; $words = explode(" ", $line); foreach ($words as $word) { if (strtolower($word) == strtolower($badword)) { $badline = TRUE; } } if (!$badline) { $lines[] = $line; } } file_put_contents("text.txt", implode("\n", $lines)); } ?> <form action="" method="post"> <div>Word to remove: <input type="text" name="word" /> <input type="submit" value="Submit" /> </div> </form> <p>Current file text:</p> <pre><?= file_get_contents("text.txt") ?></pre>
[edit] Q3 Criteria
20 points total
- 4 HTML form
- 2 <form action="filter.php" method="post"> (all must be perfect; MUST be post; action="" is OK)
- 1 submit button with proper text value
- 1 text box for word with proper name attribute ('id' is not helpful; ignore)
- -1 blanket deduction for W3C invalid but otherwise correct HTML
- 5 query params
- 1 $_POST params are read/used properly ($_REQUEST is okay; $_GET is not)
- 1 HTTP 400 error emitted when param not set (must use isset or array_key_exists, header, and die / no output)
- 3 detects when param is not a word (probably regex)
- (1/3 attempt if they use preg_match and regex is close but wrong)
- 11 text.txt file I/O
- 1 echoes file's current contents at end of page always in a pre block
- 1 lines attempt: breaks file into lines on POST (file(), explode, preg_split)
- 1 words attempt: breaks each line into words (explode or preg_split on space)
- 5 chooses lines to keep/filter perfectly; stores into array (or removes from file() array)
- (2/5 attempt if they perfectly detect the lines to keep but don't manage them in array properly)
- 1 case insensitivity (must convert both the line and the $_POST word to same case, or use case-insensitive regex)
- 2 saves data back into file properly (-1 if they forget \ns between lines)
- other deductions
- -1 for each misc. minor incorrect PHP syntax, if it is clear what they meant (e.g. str.length(), split(), OO syntax, document.getElementById, forgetting $ sign on variable, etc.)
[edit] Question 4 (JavaScript / Ajax / JSON)
[edit] Q4 Solution
- runnable solution as HTML/JS (view source to see code)
window.onload = function() { // "use strict"; is okay but not required fetchWord(); }; function fetchWord() { // jQuery, Prototype NOT okay var part = document.getElementById("part").value; var ajax = new XMLHttpRequest(); ajax.onload = wordHasArrived; ajax.open("GET", "word.php?part=" + part, true); // Formdata NOT okay; POST / false not okay ajax.send(); } function wordHasArrived() { // $, $$ okay (Prototype versions) var json = JSON.parse(this.responseText); document.getElementById("word").innerHTML = json.word + " (" + json.part + ")"; // json["word"], etc. is okay document.getElementById("choices").innerHTML = ""; for (var i = 0; i < json.choices.length; i++) { var button = document.createElement("button"); button.innerHTML = json.choices[i].definition; // textContent is okay button.className = json.choices[i].correct ? "correct" : "incorrect"; button.onclick = showResult; document.getElementById("choices").appendChild(button); } } function showResult() { alert("You are " + this.className); fetchWord(); } // okay to save correct answer into global var // and check if this.innerHTML == that var
[edit] Q4 Criteria
20 points total
- 1 window.onload proper syntax, attempts to set up an initial Ajax request
- 3 XMLHttpRequest
- 1 correct general syntax (open, send, "GET", async true, etc.)
- 2 attaches ajax.onload handler properly (onreadystatechange is okay)
- 6 JSON data processing
- 1 JSON.parse called/saved properly
- 2 inserts word and part of speech properly into $("word") (-1 if bad formatting around part-of-speech)
- 2 creates/adds buttons for each definition choice properly
- 1 onclick handlers on each button
- 10 button clicks (guesses)
- 2 message attempt: somehow remembers which answer is correct as a variable/property (or by saving JSON data)
- 4 message correct: always alerts the right "You are in/correct" message (-1 for text format problems)
- 4 fetches a new word, starts new game after alert (1 attempt, 3 correct)
- -2 if previous buttons are not cleared out (innerHTML = "" or removeChild)
- OK if they fetch/restart when part of speech is changed? -0?
- other deductions
- -1 for each small error such as OBOB
- -1 if they set ".foo" rather than ".style.foo" or vice versa
- -1 for misc. invalid JavaScript (e.g. explode, count, $_REQUEST, preg_split, etc.)
- -2 for using a framework such as jQuery, Prototype
[edit] Question 5 (SQL)
[edit] Q5 Solution
-- all actors who were in a Romantic Comedy with Woody Allen that came out in 1999 or later SELECT DISTINCT a2.first_name, a2.last_name, m.name FROM actors a1 JOIN roles r1 ON r1.actor_id = a1.id JOIN movies m ON m.id = r1.movie_id JOIN roles r2 ON r2.movie_id = m.id JOIN actors a2 ON a2.id = r2.actor_id JOIN movies_genres mg ON mg.movie_id = m.id JOIN movies_genres mg2 ON mg2.movie_id = m.id WHERE a1.first_name = "Woody" AND a1.last_name = "Allen" AND a1.id != a2.id AND mg.genre = "Romance" AND mg2.genre = "Comedy" AND m.year >= 1999 ORDER BY m.name, a2.last_name, a2.first_name;
[edit] Q5 Criteria
20 points total
- 2 SELECT actor-2's name, movie's name
- -1 if not DISTINCT actor name
- -2 for wrong actor's name (includes Woody Allen instead of actor-2)
- -1 for first/last rather than last/first order
- 10 JOINs
- 2 mechanics: joined on IDs properly at each link; doesn't skip any steps in a chain
- -2 if any table(s) are joined by something other than IDs (e.g. on first/last name, on genre)
- 3 two roles, one movie
- 2 second actor linked properly (movie -> role2 -> actor2)
- 3 two genres (movies_genres), one movie
- -2 if any extra tables added unnecessarily
- OK to have movie m2 as long as its not a coalesce
- OK to use "FROM table1, table2, ... WHERE a AND b AND c..." syntax if it's correct (give to question leader!)
- 2 mechanics: joined on IDs properly at each link; doesn't skip any steps in a chain
- 6 WHERE
- 1 ensures that actor-1 is Woody Allen
- 2 ensures that actor-2 != actor-1 (not Woody Allen)
- 2 ensures that two genres are "Romance" and "Comedy"
- 1 year >= 1999 (-1 for OBOB)
- -2 for each extra incorrect constraint if it screws up the query; -0 if it doesn't
- 2 ORDER BY movie, last_name, first_name
- OK to write ASC,ASCENDING; -2 for DESC,DESCENDING
- -1 for 'SORT BY' or just 'BY'
- other deductions
- -1 for surrounding their SQL with any PHP code
- -3 for each piece of advanced SQL syntax not taught in class (GROUP BY, HAVING, LEFT INNER JOIN, nested query, etc.) - give to question leader