08 October 2010

Beware late changes in mind! 7 October quiz scored incorrectly (1484)

The question for the 7 October quiz was: Which of the following blocks, when executed, satisfy these two requirements:
1. It will display the string "50" (without the double quotes).
2. Every statement in the block is required for the block to compile successfully.
My main objective with this lesson was to remind everyone that you do not need to (and should not) declare a variable for the iterator in a FOR loop. That is done implicitly for us by Oracle. And the way I decided to get the point across was to add that second requirement "Every statement in the block is required for the block to compile successfully." That is, the choice in which that "extra" variable was declared was scored as incorrect:
DECLARE
  l_iterator   PLS_INTEGER;
BEGIN
  FOR l_iterator IN 1 .. 100
  LOOP
     IF l_iterator = 50
     THEN
        DBMS_OUTPUT.put_line (l_iterator);
     END IF;
  END LOOP;
END;
/
So why is there a problem with this quiz? Because another choice was as follows:
DECLARE
  l_counter   PLS_INTEGER := 0;
BEGIN
  FOR l_iterator IN 1 .. 100
  LOOP
     l_counter := l_counter + 1;
  END LOOP;

  DBMS_OUTPUT.put_line (l_counter / 2);
END;
/
This block of code avoids declaring l_iterator, and displays "50." Originally (up until more or less the "last minute"), I scored this as correct. Then, as I did my just-before-quiz-starts review of the quiz, I said to myself: "Wait a minute, I could remove that DBMS_OUTPUT.PUT_LINE call and the block would still compile successfully! So this is incorrect." So I changed the way I scored that choice. I think that this change would have made sense if the question did not say "when executed", but that clause clearly indicates that both requirements need to be made at the time the block executes. The lesson I learned (and re-learn, sadly)? Do not change your mind late in the process, certainly not without discussing the change, and motivation for it, with someone else. To conclude: this choice was scored improperly. I will change it from "incorrect" to "correct," and I will also change the explanation to explain clearly why this should be considered correct. And then I will update scores and re-rank. Congratulations to Oliver Dimalanta, one of over a dozen players who reported this mistake. Oliver receives his choice of an O'Reilly Media ebook.

13 comments:

  1. Oh, the evils of a last minute change! I think every true developer has learnt that mistake at least once in their career ;-)

    My heart goes out to those who like me, while concentrating on which code would execute correctly, forgot the "is *required*" for the block to compile successfully, as opposed to "yeah, it will work"

    ReplyDelete
  2. Thanks!

    I was going to mention this one, because I got it wrong too - was a bit annoyed because it felt like a "trick question".

    You may want to change the notes for the answer because they still say "this choice is not correct".

    Also, perhaps the question needs to be reworded as well, e.g. "every line is required to compile successfully, while still displaying "50"."

    ReplyDelete
  3. It only goes to show how difficult it is to create unambiguous questions that do not already give away the answer. And it also goes to show how important it is to read and reread the requirements because I totally overlooked the "every statement is required" part in the second requirement and read something along the lines of "every statement compiles". I never realised that this would not make sense, because either a block compiles or it doesn't. So I marked the first choice as correct while being aware that the declaration is not required.

    Cheers
    Holger

    ReplyDelete
  4. Hi Steven,
    I have taught enough to know that it is sometimes impossible to see all possible interpretations of a text and (hidden) ambiguities within. Especially in one's own work. However, when the challenge runs into such a problem I think that it should be solved generously to the players i.e. grant both answers as correct. The quiz still had 5 more unambiguous parts...

    My own interpretation of the question is that execution and compilation of a block are two serially performed things. Never ever to happen at the same time and therefore it doesn't make sense to apply "when executed" to both conditions. It's simply not applicable to "compile" and the answer should be scored as "incorrect" since it violates second condition. Your reasoning IMO compares apples and oranges.

    Best regards
    MP

    ReplyDelete
  5. I know how you feel Steven...when answering this question I lost track of the original question and forgot the 'required' word. I perfectly know that you should not declare the loop variable, but if you do, Oracle will not complain and it compiles fine. But it is not required and that is what I forgot about the question, so one wrong answer made. And to make things worse, all the almost look-alike answers made my head go mad and I answered another obvious incorrect answer as correct because I read l_countrer instead of l_iterator as the variable displayed outside the loop (wrong offcourse). It did not help that I was sitting in the train and the tickets were being checked just at that time. Few lessions I learned as well: do not answer to quickly, review my answers once more before submitting and prevent myself from the risk I get distracted.

    A great question that I hate to have answered so wrong.

    Have an nice weekend everyone, the Q3 final is coming up!

    Toine

    ReplyDelete
  6. Steven,

    your lessons learned is valid also for development projects. Who did not experience how last-minute corrections did more harm than they repaired ..
    One more remark: you corrected the scoring, but not the explanation. The text still says this choice is incorrect ...

    Greetings from Germany
    Ralf

    ReplyDelete
  7. The first choice though compiles successfully and does not throw any error. So, why is the choice incorrect?

    ReplyDelete
  8. Hi Steven,

    i still don't see why this choice is correct. The dbms_output line is not required to compile the block, only to show "50". The question does'nt say "every line is required to compile successfully, while still displaying "50"", is it?

    Greetings from Germany Anja

    ReplyDelete
  9. Hello,

    In the first choice, Steven claims that declaring l_iterator is unnecessary - and his description is roght.

    But I would argue against that this is an unnecessary _statement_.

    Declaration part states that we have some variables - from this point, this is a statement. But, AFAIK, this is not the concept 'statement' usually used wrt. procedural programming languages. Oracle Database 10gR2 book "PL/SQL User's Guide and Reference" (B14261-01) on Fig. 1-2 refers only to the block body (i.e. between BEGIN and END) as the part actually holding statements.

    From this point of view, the first choice, though is of bad programming style, does not violate the 2nd criterion of this quiz. As such, it should be classified as correct.

    Greetings,
    Jozsef

    ReplyDelete
  10. But i still feel choice one below also should be correct :

    DECLARE
    l_iterator PLS_INTEGER;
    BEGIN
    FOR l_iterator IN 1 .. 100
    LOOP
    IF l_iterator = 50
    THEN
    DBMS_OUTPUT.put_line (l_iterator);
    END IF;
    END LOOP;
    END;
    /

    OR to match your answer, the question should have been like below

    Which of the following blocks, when executed should display the string 50, and meet the below statement :
    1. Every statement in the block is required to accomplish above

    OR

    Which of the following blocks, when executed, satisfy these two requirements:

    1. It will display the string "50" (without the double quotes).

    2. Every statement in the block is required to meet above requirement 1.

    ReplyDelete
  11. @Nagaraju - that block doesn't meet the second criterion, because the explicit declaration of the L_INTERATOR variable is not required. Try it.

    ReplyDelete
  12. Hi Steven,

    I am thoroughly confused when I try to understand why the choice is correct.

    Question says:
    /*
    2. Every statement in the block is required for the block to compile successfully.
    */

    The explanation says:

    /*
    The call to DBMS_OUTPUT.PUT_LINE could be removed from the block and it would still compile, but then you would not see "50". So this choice is correct.
    */

    If you say the dbms_output.put_line could be removed, it violates assumption#2 of the quiz - right?

    Is the argument that - compilation and execution are to be treated as two different actions? But event then, when you try to 'execute' anonymous block 'compilation' is done automatically.. so it still violates assumption#2 hence the choice is incorrect (IMO)

    ReplyDelete
  13. Thanks for all your comments. First, regarding Jozsef's argument that a declaration is not a statement:

    I checked with a secret Oracle contact who is in a position to know about such things and was told:

    "The PL/SQL Language Reference doesn't have a single occurrence of the phrase 'declaration statement'. Normally we simply say 'a declaration'. However, it has a semicolon as its last character. And that's what's true for all statements -- simple and compound."

    So I feel that it is acceptable to describe generally any line of code in a PL/SQL block that is terminated with a ";" as a "statement".

    As for many of the other comments, it comes back to the use of the phrase "when executed" in the question. You can't remove the DBMS_OUTPUT.PUT_LINE statement and still get the "50" to appear, so that is a necessary statement for satisfying the first requirement, and therefore the overall question.

    ReplyDelete