Final Exam Grading 12sp
From CSE190M-Admin
Contents |
[edit] Exam
[edit] Question 1 (HTML/CSS Tracing)
[edit] Q1 Solution
[edit] Q1 Criteria
25 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.
- 3 alignment: one/two text is close to right edge of enclosing div (and other text is not right-aligned)
- 2 background color: both of one/two divs are colored (and nothing else is colored)
- 4 borders: -2 for each of the categories below that is not perfect:
- dashed border around four/three/one+two areas;
- dashed around one/two inner divs;
- solid border around paragraphs;
- solid border around last line of 'four'
- (and no borders around anything else on the page)
- 1 br and inline content: line break between each line of two/three/four; otherwise N copies on Nth line
- 4 float: one/two/three/four divs are floated properly
- -2 for wrong order (all floated to right but in reverse order)
- -2 if p tag does not clear
- 3 margin: 1em margin on all sides of one/two divs, outside the border, AND no margin between four/three/one-two areas, bottom paragraph
- 2 padding: all divs have 1em padding on all sides, inside the border (if they don't have borders so you can't tell, then -2)
- 3 underline: two/two text is underlined (and no other text is underlined)
- 3 width: each div is just wide enough to fit its content; width of paragraphs extends across entire page. (Do not take off if effed up for non floating)
other deductions
- -1 point each for any other minor misc. stuff they do wrong that isn't listed above
[edit] Question 2 (PHP)
[edit] Q2 Solution
<!-- order.php --> <form action="order-submit.php" method="post"> <div> Food item: <select name="food"> <?php foreach (glob("*.jpg") as $image) { ?> <option> <?= str_replace(".jpg", "", $image) ?> </option> <?php } ?> </select> </div> <div> Quantity: <input type="text" name="quantity" size="2" /> </div> <div> <input type="submit" value="Order" /> </div> </form>
<?php # order-submit.php if (!isset($_POST["food"]) || !isset($_POST["quantity"])) { header("HTTP/1.1 400 Invalid Request"); die(); } $food = $_POST["food"]; $quantity = $_POST["quantity"]; $found = FALSE; foreach (file("inventory.txt") as $line) { list($item, $number, $price) = explode("\t", $line); # list() is optional if ($item == $food && $number >= $quantity) { $total = $quantity * $price; ?> <p>Order successful! $<?= $total ?> is your total price. Here is what you ordered: <?php for ($i = 0; $i < $quantity; $i++) { ?> <img src="<?= $food ?>.jpg" alt="food" /> <?php } ?> $found = TRUE; break; # optional } } if (!$found) { ?> <p>Sorry, we don't have <?= $quantity ?> of '<?= $food ?>' in stock.</p> <?php } ?>
[edit] Q2 Criteria
25 points total
- 8 order.php HTML form
- 2 <form action="order-submit.php" method="post"> (all must be perfect)
- 1 submit button and quantity text box
- -1 if they forget size="2" (maxlength=2 is okay)
- 4 select / options / glob
- -2 if they don't properly remove '.jpg' from each image's name (basename() does not work)
- -3 blanket deduction if form controls don't have 'name' attribute (having 'id' is fine, but still must have 'name')
- 1 appearance, otherwise correct, etc.
- <br/> instead of divs is okay
- stuff that would fail the W3C validator but works is okay
- 3 order-submit.php query params
- 1 $_POST params are read/used properly ($_REQUEST is okay; $_GET is not)
- 2 HTTP 400 error when params are not set (must use isset, header, and die / no output)
- 5 order-submit.php file I/O
- 2 attempt: evidence of line-based and token-based approach (explode or preg_split)
- 3 correct: finds the food item, matches against query parameter, and uses/stores its info
- 5 order-submit.php successful case, HTML output
- 2 computes/outputs total cost properly
- 3 outputs the right image,
$quantity
times- -1 for any minor output formatting issue like forgetting 'quotes' or $ around number, punctuation, etc.
- 4 order-submit.php not enough inventory case
- 3 correctly determines whether to print the success or failure output
(properly checks quantity available in file; falls through to error case at end properly, etc.) - 1 prints special "don't have it in stock" message
- -1 for any minor output formatting issue like forgetting 'quotes' or $ around number, punctuation, '.jpg', etc.
- 3 correctly determines whether to print the success or failure output
- other deductions
- -1 if they use print/echo
- -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 3 (JS/DOM)
[edit] Q3 Solution
// "use strict"; is fine but not required window.onload = function() { // document.observe(... is okay $("find").onclick = findClick; // .observe("click"... is okay }; function findClick() { $("palindromes").innerHTML = ""; var words = $("phrase").value.split(" "); // $F("phrase").split(" "); var count = 0; for (var i = 0; i < words.length; i++) { if (lengthOkay(words[i]) && isPalindrome(words[i])) { var li = document.createElement("li"); li.innerHTML = words[i]; // textContent is okay if (count % 2 == 0) { li.style.backgroundColor = "#cccccc"; } $("palindromes").appendChild(li); count++; } } $("count").innerHTML = count + " total palindrome(s)."; // count == $$("#palindromes li").length } function isPalindrome(s) { s = s.toLowerCase(); for (var i = 0; i < s.length / 2; i++) { // loop up to length-1 is okay (slower but not wrong) if (s[i] != s[s.length - 1 - i]) { return false; } // charAt is okay } return true; // return s == s.split("").reverse().join(""); } function lengthOkay(s) { return (!$("min").value || s.length >= $("min").value) && // parseInt okay but not needed (!$("max").value || s.length <= $("max").value); }
[edit] Q3 Criteria
25 points total
- 2 window onload: attaches click handler perfectly (*.observe is okay)
- 2 splits phrase into words and loops over them properly
- 2 attempt, 2 correct; -1 for small error such as OBOB
- it is possible to split the words using indexOf(" ") and substring, but it's hard and they probably will mess it up
- 8 finding palindromes: correct test/function to see whether a word is a palindrome
- 2 attempt (good approaches: looping from both ends; trying to reverse string; using a stack/array)
- 3 correct (ignoring case sensitivity issues)
- -4 if they pretend that strings have a 'reverse' method (they don't)
- -1 for each small error such as OBOB
- 3 case insensitivity handled perfectly
(must lower/uppercase before palindrome test, AND must still use original word case when inserting li)
- 4 counting palindromes
- 2 keeps correct count of palindromes; injects into $('count') div
- 2 colors even-numbered palindromes with #CCCCCC or #CC0000 background-color (setting bg to "gray" is okay)
- -2 if they set the odd-numbered ones rather than the even ones
- -2 if they set ".foo" rather than ".style.foo"
- 5 min/max
- 2 respects min/max properly when present
- 3 ignores min/max properly when absent (tests for truthy/falsey value)
- 4 DOM: li for each palindrome
- 2 creates li DOM and puts text into it; puts onto page in proper DOM place ($('palindromes').appendChild)
- 2 works for multiple clicks; clears previous text properly (sets output.innerHTML = "" or removes children)
- other deductions
- -1 for misc. invalid JavaScript (e.g. explode, count, $_REQUEST, preg_split, etc.)
[edit] Question 4 (SQL)
[edit] Q4 Solution
-- all directors who have made >= 2 movies across >= 2 genres -- SELECT DISTINCT d.id, d.first_name, d.last_name FROM directors d JOIN movies_directors md1 ON md1.director_id = d.id JOIN movies_genres mg1 ON mg1.movie_id = md1.movie_id JOIN movies_directors md2 ON md2.director_id = d.id JOIN movies_genres mg2 ON mg2.movie_id = md2.movie_id WHERE mg1.genre <> mg2.genre AND mg1.movie_id <> mg2.movie_id ORDER BY d.last_name, d.first_name;
-- all directors who have made >= 2 movies across >= 2 genres (includes movies table unnecessarily) -- SELECT DISTINCT dir.id, dir.last_name, dir.first_name FROM directors dir JOIN movies_directors md1 ON md1.director_id = dir.id JOIN movies m1 ON m1.id = md1.movie_id JOIN movies_genres mg1 ON mg1.movie_id = m1.id JOIN movies_directors md2 ON md2.director_id = dir.id JOIN movies m2 ON m2.id = md2.movie_id JOIN movies_genres mg2 ON mg2.movie_id = m2.id WHERE m1.id <> m2.id AND mg1.genre <> mg2.genre ORDER BY dir.last_name, dir.first_name;
[edit] Q4 Criteria
25 points total
- 3 SELECT director id, last/first name
- -3 if not DISTINCT id
- -1 for first/last rather than last/first
- 3 JOIN mechanics: joined on IDs properly at each link; doesn't skip any steps in a chain
- -3 if any table(s) are joined by something other than IDs (e.g. on first/last name, on genre)
- 8 JOIN choice of tables to join together
- -8 if they don't have two movies_directors tables and two movies_genres tables
- -2 for each extra table added unnecessarily, other than movies
- joining to movies table is okay (doesn't break the query) but is not necessary
- OK to use "FROM table1, table2, ... WHERE a AND b AND c..." syntax if it's right
- 8 WHERE
- -4 if they forget to demand two distinct movies (forgot to compare md1.movie_id with md2.movie_id)
- -4 if they forget to demand two distinct genres (forgot to compare mg1.genre with mg2.genre)
- -3 if they compare using < or > for both tests (need to use <> or !=)
- -2 for each extra incorrect constraint if it screws up the query; -0 if it doesn't
- 3 ORDER BY last name, first name
- OK to write ASC; -3 for DESC or DESCENDING; -1 for ASCENDING
- -2 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.)