CSE 211 midterm Quiz Questions
To avoid side-effects in programming, A. use a functional programming language B. in Java, use the keyword "final" when appropriate. (This will avoid side effects in that variable, but not others.) C. in C, use the keyword "constant" D. all of the above
D. all of the above
In Python the range(10, 16, 2) is equal to [10, 12, 14, 16] True False
False
Python uses static typing True False
False
There was a latent bug in dayOfYear. It didn't handle leap years at all. As part of fixing that, suppose we write a leap-year method. public static boolean leap(int y) { String tmp = String.valueOf(y); if (tmp.charAt(2) == '1' || tmp.charAt(2) == '3' || tmp.charAt(2) == 5 || tmp.charAt(2) == '7' || tmp.charAt(2) == '9') { if (tmp.charAt(3)=='2'||tmp.charAt(3)=='6') return true; /*R1*/ else return false; /*R2*/ }else{ if (tmp.charAt(2) == '0' && tmp.charAt(3) == '0') { return false; /*R3*/ } if (tmp.charAt(3)=='0'||tmp.charAt(3)=='4'||tmp.charAt(3)=='8')return true; /*R4*/ } return false; /*R5*/ } What happens when you call: leap(916) A. returns true on line R1 B. return false on line R2 C. return false on line R3 D. return true on line R4 E. return false on line R5 F. error before program starts G. error while program is running
G. error while program is running This code is making the assumption that the year has exactly 4 digits. When it has fewer than 4 digits, then tmp.charAt(3), which tries to look at the fourth digit in the string will fail with a dynamic error, in the same way that indexing beyond the end of a Python string would fail with an error.
A list in Python is a mutable sequence of 0 or more objects of any type. True False
True
An immutable object is one whose state cannot be modified after it is created. True False
True
In Python, all variables are references True False
True
After all the legal statements in the previous exercise's answers are executed, what is the resulting value of each variable? Write just the sequence of letters found in the variable's value, with no punctuation or spaces. For example: vowel0 = y char vowel0 = 'a'; final char vowel1 = vowel0; String vowel2 = vowel1 + "eiou"; final String vowel3 = vowel2; char[] vowel4 = new char[] { vowel0, 'e', 'i', 'o', 'u' }; final char[] vowel5 = vowel4; vowel2
uoiea vowel2 was reassigned to "uoiea" in the exercise answers.
After all the legal statements in the previous exercise's answers are executed, what is the resulting value of each variable? Write just the sequence of letters found in the variable's value, with no punctuation or spaces. For example: vowel0 = y char vowel0 = 'a'; final char vowel1 = vowel0; String vowel2 = vowel1 + "eiou"; final String vowel3 = vowel2; char[] vowel4 = new char[] { vowel0, 'e', 'i', 'o', 'u' }; final char[] vowel5 = vowel4; vowel4
zeiou vowel4 and vowel5 both refer to the same array object, which is initially has the five elements a, e, i, o, u. Mutating that object through either vowel4[0] or through vowel5[0] will affect what both variables see. The final mutation sets the 0th element to 'z'.
After all the legal statements in the previous exercise's answers are executed, what is the resulting value of each variable? Write just the sequence of letters found in the variable's value, with no punctuation or spaces. For example: vowel0 = y char vowel0 = 'a'; final char vowel1 = vowel0; String vowel2 = vowel1 + "eiou"; final String vowel3 = vowel2; char[] vowel4 = new char[] { vowel0, 'e', 'i', 'o', 'u' }; final char[] vowel5 = vowel4; vowel5
zeiou vowel4 and vowel5 both refer to the same array object, which is initially has the five elements a, e, i, o, u. Mutating that object through either vowel4[0] or through vowel5[0] will affect what both variables see. The final mutation sets the 0th element to 'z'. vowel4 and vowel5 refer to the same array object, so the answer for vowel5 is the same as for vowel4.
One reason why repeated code is bad is because a problem in the repeated code has to be fixed in many places, not just one. Suppose our calendar changed so that February really has 30 days instead of 28. How many numbers in this code have to be changed? public static int dayOfYear(int month, int dayOfMonth, int year) { if (month == 2) { dayOfMonth += 31; } else if (month == 3) { dayOfMonth += 59; } else if (month == 4) { dayOfMonth += 90; } else if (month == 5) { dayOfMonth += 31 + 28 + 31 + 30; } else if (month == 6) { dayOfMonth += 31 + 28 + 31 + 30 + 31; } else if (month == 7) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30; } else if (month == 8) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31; } else if (month == 9) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31; } else if (month == 10) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30; } else if (month == 11) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31; } else if (month == 12) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31; } return dayOfMonth; }
10 The eight explicit occurrences of 28 would have to change, and so would the two numbers 59 and 90, which implicitly depend on the assumption that February has 28 days: 59 = 31/*January*/ + 28/*February*/, and 90 = 31/*January*/ + 28/*February*/ + 31/*March*/. These two surprise numbers are magic numbers.
How many magic numbers are in this code? Count every occurrence if some appear more than once. public static boolean leap(int y) { String tmp = String.valueOf(y); if (tmp.charAt(2) == '1' || tmp.charAt(2) == '3' || tmp.charAt(2) == 5 || tmp.charAt(2) == '7' || tmp.charAt(2) == '9') { if (tmp.charAt(3)=='2'||tmp.charAt(3)=='6') return true; /*R1*/ else return false; /*R2*/ }else{ if (tmp.charAt(2) == '0' && tmp.charAt(3) == '0') { return false; /*R3*/ } if (tmp.charAt(3)=='0'||tmp.charAt(3)=='4'||tmp.charAt(3)=='8')return true; /*R4*/ } return false; /*R5*/ }
24 Every expression of the form tmp.charAt(k) == 'n' has two magic numbers in it, k and n. There are twelve such expressions.
Suppose we're editing the body of a function in Java, declaring and using local variables. int a = 5; // (1) if (a > 10) { // (2) int b = 2; // (3) } else { // (4) int b = 4; // (5) } // (6) b *= 3; // (7) Which line of Java code causes a compilation error? 1 2 3 4 5 6 7
7 This code declares two variables named b. One of them is in scope only for the if branch, and the other is in scope only for the else branch. When we reach line 7, the reference to b cannot be resolved.
public static int dayOfYear(int month, int dayOfMonth, int year) { if (month == 2) { dayOfMonth += 31; } else if (month == 3) { dayOfMonth += 59; } else if (month == 4) { dayOfMonth += 90; } else if (month == 5) { dayOfMonth += 31 + 28 + 31 + 30; } else if (month == 6) { dayOfMonth += 31 + 28 + 31 + 30 + 31; } else if (month == 7) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30; } else if (month == 8) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31; } else if (month == 9) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31; } else if (month == 10) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30; } else if (month == 11) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31; } else if (month == 12) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31; } return dayOfMonth; } Programmers often describe bad code as having a "bad smell" that needs to be removed. Some of the repetition in dayOfYear() is repeated values. How many times is the number of days in April written in dayOfYear()?
8 Each sum of the form 31 + 28 + 31 + 30 + ... is a sum of days in months: 31/*January*/ + 28/*February*/ + 31/*March*/ + 30/*April*/ + ... There are 8 occurrences of 30 that belong to April. By the way, the fact that this question couldn't be obviously answered from the code is an example of the problem of magic numbers, which we discussed in the class.
In Python, what is the output of the following code? >>> def cal (a, b, c): ... return a+b*c ... >>> cal ('apples', 'oranges, ', 3) A. 'applesoranges, oranges, oranges, ' B. 'applesoranges, applesoranges, applesoranges, ' C. 'oranges, oranges, oranges ' D.None of the above
A. 'applesoranges, oranges, oranges, '
Suppose you're reading some code that uses a turtle graphics library that you don't know well, and you see the code: turtle.rotate(3); Just from reading this line (not consulting the documentation), which of the following are likely assumptions you might make about the meaning of the number 3? A. 3 might mean 3 degrees clockwise B. 3 might mean 3 degrees counterclockwise C. 3 might mean 3 radians clockwise D. 3 might mean 3 full revolutions
A. 3 might mean 3 degrees clockwise B. 3 might mean 3 degrees counterclockwise C. 3 might mean 3 radians clockwise D. 3 might mean 3 full revolutions All of these are reasonable assumptions for a magic number 3.
Which comments are useful additions to the code? Consider each comment independently, as if the other comments weren't there. /** @param month month of the year, where January=1 and December=12 [C1] */ public static int dayOfYear(int month, int dayOfMonth, int year) { if (month == 2) { // we're in February [C2] dayOfMonth += 31; // add in the days of January that already passed [C3] } else if (month == 3) { dayOfMonth += 59; // month is 3 here [C4] } else if (month == 4) { dayOfMonth += 90; } ... } else if (month == 12) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31; } return dayOfMonth; // the answer [C5] } A. C1 B. C2 C. C3 D. C4 E. C5
A. C1 B. C2 C. C3 C1 is definitely a good addition because it clarifies what the month parameter means. In general, you should have a specification comment like this before every method. This specification isn't complete, but it's a start. C2 and C3 help clarify what the numbers 2 and 31 signify. The comments help here, however a better way to explain these lines is not with comments but with descriptive names, like month == FEBRUARY and dayOfMonth += MONTH_LENGTH[JANUARY]. C4 and C5 contribute nothing that a capable reader of Java wouldn't already know.
Select the smallest set of changes that will fix the bug: int a = 5; // (1) if (a > 10) { // (2) int b = 2; // (3) } else { // (4) int b = 4; // (5) } // (6) b *= 3; // (7) A. Declare int b; after line 1 B. Assign b = 0; before line 2 C. Assign b = 2; instead of line 3 D. Assign b = 4; instead of line 5 E. Declare and assign int b *= 3; instead of line 7
A. Declare int b; after line 1 C. Assign b = 2; instead of line 3 D. Assign b = 4; instead of line 5 We need to declare b outside the scope of the if-else. However, we do not need to assign it a value. The declarations on lines 3 and 5 must be changed to assignments, but the reassignment on line 7 is fine.
In working with a program that you wrote, you discover that you have passed two arguments to a function in the wrong order. You have just discovered A. Fault B. Failure C. Feature D. None of the above
A. Fault
If a compiler can catch errors when a program is compiled, this is an example of: A. Static checking B. Dynamic checking C. Immutability D. Mutability
A. Static checking
What is the output of the int ('5.7') command in Python? A. Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: invalid literal for int() with base 10: '5.7' B. 5 C. "5.7" D. 5.7
A. Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: invalid literal for int() with base 10: '5.7
Consider this (incomplete) function: /** * Solves quadratic equation ax^2 + bx + c = 0. * * @param a quadratic coefficient, requires a != 0 * @param b linear coefficient * @param c constant term * @return a list of the real roots of the equation */ public static List<Double> quadraticRoots(final int a, final int b, final int c) { List<Double> roots = new ArrayList<Double>(); // A ... // compute roots // B return roots; } What statements would be reasonable to write at position A? A. assert a != 0; B. assert b != 0; C. assert c != 0; D. assert roots.size() >= 0; E. assert roots.size() <= 2; F. for (double x : roots) { assert Math.abs(a*x*x + b*x + c) < 0.0001; }
A. assert a != 0; It's good to assert a!=0 at the start of the function, but not necessary to assert at the end of the function, since finalprevents it from being changed. It isn't correct to assert b!=0 or c!=0, since 0 is a legal value for those parameters. It isn't reasonable to assert the content of the roots list until it has actually been computed - i.e., not at the start of the function, but at the end of the function.
Encapsulation is: A. building walls around a module so that the module is responsible for its own internal behavior, and bugs in other parts of the system can't damage its integrity. B. dividing up a system into components, or modules, each of which can be designed, implemented, tested, reasoned about, and reused separately from the rest of the system. C. never using global variables. D. All of the above
A. building walls around a module so that the module is responsible for its own internal behavior, and bugs in other parts of the system can't damage its integrity.
Another kind of repetition in this code is dayOfMonth+=. Assume you have an array int[] monthLengths = new int[] { 31, 28, 31, 30, ..., 31}. Which of the following code skeletons could be used to DRY the code out enough so that dayOfMonth+= appears only once? public static int dayOfYear(int month, int dayOfMonth, int year) { if (month == 2) { dayOfMonth += 31; } else if (month == 3) { dayOfMonth += 59; } else if (month == 4) { dayOfMonth += 90; } else if (month == 5) { dayOfMonth += 31 + 28 + 31 + 30; } else if (month == 6) { dayOfMonth += 31 + 28 + 31 + 30 + 31; } else if (month == 7) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30; } else if (month == 8) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31; } else if (month == 9) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31; } else if (month == 10) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30; } else if (month == 11) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31; } else if (month == 12) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31; } return dayOfMonth; } A. for (int m = 1; m <= month; ++m) { ... } B. switch (month) { case 1: ...; break; case 2: ...; break; ... } C. while (m < month) { ...; m += 1; } D. if (month == 1) { ... } else { ... dayOfYear(month-1, dayOfMonth, year) ... }
A. for (int m = 1; m <= month; ++m) { ... } C. while (m < month) { ...; m += 1; } D. if (month == 1) { ... } else { ... dayOfYear(month-1, dayOfMonth, year) ... } Loop statements like for and while are both good approaches to condensing repetitive code. Both loops could work here. A switch statement is a more compact way to represent a series of if-else-if statements, like we see here, and it does help DRY the code out by eliminating the repetitive mentions of month==. But it wouldn't eliminate the repetitions of dayOfMonth+=. The fourth skeleton makes dayOfYear into a recursive function. It has a base case for January, and handles other months by recursively computing the dayOfYear from the previous month, then adding the current month to it. This approach also works for eliminating the dayOfMonth+= repetition. If you're not clear on these skeletons, try fleshing them out into actual code, and run it.
There was a latent bug in dayOfYear. It didn't handle leap years at all. As part of fixing that, suppose we write a leap-year method. public static boolean leap(int y) { String tmp = String.valueOf(y); if (tmp.charAt(2) == '1' || tmp.charAt(2) == '3' || tmp.charAt(2) == 5 || tmp.charAt(2) == '7' || tmp.charAt(2) == '9') { if (tmp.charAt(3)=='2'||tmp.charAt(3)=='6') return true; /*R1*/ else return false; /*R2*/ }else{ if (tmp.charAt(2) == '0' && tmp.charAt(3) == '0') { return false; /*R3*/ } if (tmp.charAt(3)=='0'||tmp.charAt(3)=='4'||tmp.charAt(3)=='8')return true; /*R4*/ } return false; /*R5*/ } What happens when you call: leap(2016) A. returns true on line R1 B. returns false on line R2 C. returns false on line R3 D. returns true on line R4 E. error before program starts F. error while program is running
A. returns true on line R1 Here is how the code executes: String.valueOf(2016) returns the string "2016" and stores it in tmp. tmp.charAt(2) is the character '1', so the code enters the first if statement. tmp.charAt(3) is the character '6', so the return statement marked R1 is executed. This is correct behavior. 2016 is in fact a leap year, so leap(2016) is behaving properly. Mental execution of code is a crucial part of reading and understanding code, and is often necessary in code review to help find bugs.
If the programmer's intent is to get 0.2, then: double probability = 1/5; A. static error B. dynamic error C. no error, wrong answer D. none of the above
A. static error If the programmer's intent was to get 0.2, this is using the wrong operation. / is overloaded for both integer division and floating point division. But because it's being called with integers, 1 and 5, Java chooses integer division, and it quietly truncates the fraction and produces the wrong answer: 0.
int n = 5; if (n) { n = n + 1; } A. static error B. dynamic error C. no error, wrong answer D. none of the above
A. static error This is a static type error, because the if statement requires an expression of boolean type, but n has int type.
Consider the following code, executed in order: char vowel0 = 'a'; final char vowel1 = vowel0; String vowel2 = vowel1 + "eiou"; final String vowel3 = vowel2; char[] vowel4 = new char[] { vowel0, 'e', 'i', 'o', 'u' }; final char[] vowel5 = vowel4; Which of the following statements are legal Java (i.e. produce no compiler error if placed after the code above)? A. vowel0 = 'y'; B. vowel1 = vowel0; C. vowel2 = "uoie" + vowel1; D. vowel3 = vowel2; E. vowel2[0] = 'x'; F. vowel3[0] = 'x'; G. vowel4 = vowel5; H. vowel5 = vowel4; I. vowel4[0] = 'x'; J. vowel5[0] = 'z';
A. vowel0 = 'y'; C. vowel2 = "uoie" + vowel1; G. vowel4 = vowel5; I. vowel4[0] = 'x'; J. vowel5[0] = 'z'; vowel1, vowel3, and vowel5 are final, so they cannot be reassigned. vowel2 and vowel3 are Strings, which don't provide the [] indexing operation like arrays do. You have to use the charAt() method instead. Even though vowel5 is final, it points at a mutable array, so vowel5[0] can be reassigned.
In the code: if (month == 2) { ... } what might a reasonable programmer plausibly assume about the meaning of the magic number 2? A. 2 might mean January B. 2 might mean February C. 2 might mean March D. 2 might mean the year 2 AD
B. 2 might mean February C. 2 might mean March For one-based indexing (January=1), 2 would mean February, but for zero-based indexing (January=0), it would mean March.
In the validation process we try to answer the question: A. Are we building the product right? B. Are we building the right product? C. All of the above D. None of the above
B. Are we building the right product
Which of the following is true about the use of assertions and exceptions? A. Exceptions test the internal state of a program; assertions handle issues that are external to the program. B. Assertions test the internal state of a program; exceptions handle issues that are external to the program. C. Exceptions and assertions are really the same thing. D. Exceptions and assertions are not identical, but are used for the same purpose.
B. Assertions test the internal state of a program; exceptions handle issues that are external to the program.
Java will catch array overflow errors at runtime, whereas C does not. This is an example of: A. Static checking B. Dynamic checking C. Immutability D. Mutability
B. Dynamic checking
Modularity is: A. building walls around a module so that the module is responsible for its own internal behavior, and bugs in other parts of the system can't damage its integrity. B. dividing up a system into components, or modules, each of which can be designed, implemented, tested, reasoned about, and reused separately from the rest of the system. C. never using global variables D. All of the above
B. dividing up a system into components, or modules, each of which can be designed, implemented, tested, reasoned about, and reused separately from the rest of the system.
int sum = 0; int n = 0; int average = sum/n; A. static error B. dynamic error C. no error, wrong answer D. none of the above
B. dynamic error Division by zero can't produce an integer, so it produces a dynamic error instead.
Suppose you are debugging the quadraticRoots function, which appears to be producing wrong answers sometimes. /** * Solves quadratic equation ax^2 + bx + c = 0. * * @param a quadratic coefficient, requires a != 0 * @param b linear coefficient * @param c constant term * @return a list of the real roots of the equation */ public static List<Double> quadraticRoots(final int a, final int b, final int c) { List<Double> roots = new ArrayList<Double>(); ... } Put the following items in the order that you should try them: 1, 2, 3, ... Say "wat" for items that are nonsense statements. A. Change your code from using ArrayList to using LinkedList. B. Put println() statements throughout your method to display the intermediate values of the calculation. C. Write a test case that causes the bug to happen. D. Switch from Java 8 back to Java 7.
C, B, A, D Having a failing test case makes it much easier to debug, and is always the best thing to start with. Inserting print statements to collect information takes more effort but the effort pays off. Changing from ArrayList to LinkedList, or Java 8 to Java 7, are good examples of the "swap components" technique, but these are trusted components that are supposed to behave alike, so they would be the last things to try.
In this course, the definition of what a good software means A. Easy to understand B. Safe from bugs C. All of the above D. Ready for change
C. All of the Above
What is considered to be "construction" depends to some degree on the life cycle model used. In general, software construction is mostly coding and debugging, but it also involves construction planning, detailed design, unit testing, integration testing, and other activities. If the linear model (e.g., waterfall) is used, the construction in this case is considered to be _________. A. Testing B. Debugging C. Coding D. Design
C. Coding
What is the process of analyzing and removing the causes of failures in software? A. Validation B. Testing C. Debugging D. Verification
C. Debugging
In the code, which of these are global variables? public static int LONG_WORD_LENGTH = 5; public static String longestWord; public static void countLongWords(List<String> words) { int n = 0; longestWord = ""; for (String word: words) { if (word.length() > LONG_WORD_LENGTH) ++n; if (word.length() > longestWord.length()) longestWord = word; } System.out.println(n); } A. countLongWords B. n C. LONG_WORD_LENGTH D. longestWord E. word F. words
C. LONG_WORD_LENGTH D. longestWord Recall that a global variable must be a variable, and it must be accessible from anywhere in the program. countLongWords is a method, not a variable. n, word, and words are local variables - their declarations are inside a method, which makes them accessible only within that method. LONG_WORD_LENGTH and longestWord are declared outside the method. They also have the modifier "public", but which means that even code outside this class can access and reassign those variables. Variables marked "public static" (but without final) are truly Java's global variables, and using them is a always a bad idea. Note that LONG_WORD_LENGTH is actually named in a misleading way. By Java convention, names that are all uppercase letters should be constants, but unfortunately the keyword "final" was omitted from LONG_WORD_LENGTH's declaration, which means it can be reassigned just like any other variable. It isn't actually a constant.
All of the following are examples of Mutable objects in Python: A. Int, Float, and String B. Set, List, and Range C. List, Set, and Dictionary D. Tuple, List, and String
C. List, Set, and Dictionary
In Python, the fact that a single method can include both of the following statements means what? x = 12.34 x = "Hello World" A. Python is statically typed B. Python variables do not have a type C. Python is dynamically typed D. These two statement would produce a syntax error in Python
C. Python is dynamically typed
Consider the following code (which is missing some variable declarations): 1 class Apartment { 2 Apartment(String newAddress) { 3 this.address = newAddress; 4 this.roommates = new HashSet<Person>(); 5 } 6 7 String getAddress() { 8 return address; 9 } 10 11 void addRoommate(Person newRoommate) { 12 roommates.add(newRoommate); 13 if (roommates.size() > MAXIMUM_OCCUPANCY) { 14 roommates.remove(newRoommate); 15 throw new TooManyPeopleException(); 15 } 16 } 17 18 void getMaximumOccupancy() { 19 return MAXIMUM_OCCUPANCY; 20 } 21 } Which of these lines are within the scope of the newRoommate variable? A. line 3 B. line 8 C. line 12 D. line 15 E. line 20
C. line 12 D. line 15 The scope of a parameter is its function body, so lines 11-16 are in scope.
int big = 200000; // 200,000 big = big * big; // big should be 4 billion now A. static error B. dynamic error C. no error, wrong answer D. none of the above
C. no error, wrong answer This is an integer overflow, because an int value can't represent a number bigger than 2^31 (about 2 billion). It isn't caught statically, but unfortunately in Java it isn't caught dynamically either. Integer overflows quietly produce the wrong answer.
Which of the following are ways of getting an immutable reference? A. Use const in C or C++ B. Use final in Java C. Use one of the immutable collection classes in Python D. All of the above
D. All of the above
The best defense against bugs is to make them impossible by design. Which of the following is part of this type of design? A. Static checking B. Dynamic checking C. Immutability D. All of the above
D. All of the above
There was a latent bug in dayOfYear. It didn't handle leap years at all. As part of fixing that, suppose we write a leap-year method. public static boolean leap(int y) { String tmp = String.valueOf(y); if (tmp.charAt(2) == '1' || tmp.charAt(2) == '3' || tmp.charAt(2) == 5 || tmp.charAt(2) == '7' || tmp.charAt(2) == '9') { if (tmp.charAt(3)=='2'||tmp.charAt(3)=='6') return true; /*R1*/ else return false; /*R2*/ }else{ if (tmp.charAt(2) == '0' && tmp.charAt(3) == '0') { return false; /*R3*/ } if (tmp.charAt(3)=='0'||tmp.charAt(3)=='4'||tmp.charAt(3)=='8')return true; /*R4*/ } return false; /*R5*/ } What happens when you call: leap(2050) A. returns true on line R1 B. returns false on line R2 C. returns false on line R3 D. returns true on line R4 E. returns false on line R5 F. error before program starts G. error while program is running
D. returns true on line R4 Note that leap() is returning the wrong answer in this case, because 2050 is not a leap year. The reason this happens is a subtle bug in the program: the expression tmp.charAt(2) == 5, which should be tmp.charAt(2) == '5'. Instead of testing the third character in 2050 against '5' and finding a match, it tests the character against the integer 5. Since the character's value is actually equivalent to the integer 53 (the Unicode value of the character '5'), the test fails, and the code goes on to a different part that produces the wrong answer. You might ask why Java even allows a character to be compared against an integer - why isn't it a static type error? Indeed, it should be. If you tried to compare a String with an integer, Java would indeed produce a type error. But for historical reasons, coming from its legacy in the C and C++ programming languages, characters in Java are numeric types, just like int and long, and automatically convert to integers when they need to. Static typing didn't save us here, because Java's type system is very weak in places, like this automatic numeric type conversion. We can also attribute this failure to the code's lack of DRYness. It contains twelve different character comparisons (charAt(k)=='c' for some k or c), and all that repetitive code means that each one is a potential place for a bug. Just because the code works for 2016 doesn't give us much confidence that it will work for 2050, because there are so many different paths through this function.
Which of the following are true about assertions? A. Assertions can be expensive. B. Although assertions are expensive, it is usually reasonable to pay this cost during debugging. C. In Java, assertions can be turned off after debugging is complete. D. The correctness of a program should never depend on whether assertions are executed. E. All of the above
E. All of the above
A type is A. a set of values B. a set of operations (or methods) that are appropriate for that set of operations C. not used in Python, but is important in Java D. all of the above E. both A and B
E. both A and B
After all the legal statements in the previous exercise's answers are executed, what is the resulting value of each variable? Write just the sequence of letters found in the variable's value, with no punctuation or spaces. For example: vowel0 = y char vowel0 = 'a'; final char vowel1 = vowel0; String vowel2 = vowel1 + "eiou"; final String vowel3 = vowel2; char[] vowel4 = new char[] { vowel0, 'e', 'i', 'o', 'u' }; final char[] vowel5 = vowel4; vowel1
a vowel0 was reassigned to 'y' in the exercise answers. vowel1 is final, so it must always be the value it was initialized with, 'a'.
After all the legal statements in the previous exercise's answers are executed, what is the resulting value of each variable? Write just the sequence of letters found in the variable's value, with no punctuation or spaces. For example: vowel0 = y char vowel0 = 'a'; final char vowel1 = vowel0; String vowel2 = vowel1 + "eiou"; final String vowel3 = vowel2; char[] vowel4 = new char[] { vowel0, 'e', 'i', 'o', 'u' }; final char[] vowel5 = vowel4; vowel3
aeiou vowel3 is final and refers to an immutable type (String), so it must always be the value it was initialized with, "aeiou".
Making a variable into a constant by adding the final keyword can eliminate the risk of global variables. In the following source code, what happens to each of these when the final keyword is added? public static int LONG_WORD_LENGTH = 5; public static String longestWord; public static void countLongWords(List<String> words) { int n = 0; longestWord = ""; for (String word: words) { if (word.length() > LONG_WORD_LENGTH) ++n; if (word.length() > longestWord.length()) longestWord = word; } System.out.println(n); } final LONG_WORD_LENGTH
becomes constant With final, LONG_WORD_LENGTH will become constant. It is assigned once, when it is first declared, and never changed again in this code. Now it truly deserves to be written in all uppercase letters, because it is truly constant.
Making a variable into a constant by adding the final keyword can eliminate the risk of global variables. In the following source code, what happens to each of these when the final keyword is added? public static int LONG_WORD_LENGTH = 5; public static String longestWord; public static void countLongWords(List<String> words) { int n = 0; longestWord = ""; for (String word: words) { if (word.length() > LONG_WORD_LENGTH) ++n; if (word.length() > longestWord.length()) longestWord = word; } System.out.println(n); } final word
becomes constant With final, the word variable now can't be reassigned within the body of the for loop. Each time around the for loop, however, it will get a fresh value.
Making a variable into a constant by adding the final keyword can eliminate the risk of global variables. In the following source code, what happens to each of these when the final keyword is added? public static int LONG_WORD_LENGTH = 5; public static String longestWord; public static void countLongWords(List<String> words) { int n = 0; longestWord = ""; for (String word: words) { if (word.length() > LONG_WORD_LENGTH) ++n; if (word.length() > longestWord.length()) longestWord = word; } System.out.println(n); } final words
doesn't become constant Adding final to the words variable means that the variable can't be reassigned - but the List object that it points to can still be mutated. This subtle difference can be a source of bugs.
Making a variable into a constant by adding the final keyword can eliminate the risk of global variables. In the following source code, what happens to each of these when the final keyword is added? public static int LONG_WORD_LENGTH = 5; public static String longestWord; public static void countLongWords(List<String> words) { int n = 0; longestWord = ""; for (String word: words) { if (word.length() > LONG_WORD_LENGTH) ++n; if (word.length() > longestWord.length()) longestWord = word; } System.out.println(n); } final longestWord
error before program starts With final, the compiler will notice that longestWord is reassigned in the body of the for loop, and it will signal a static error, just as it would for n. n and longestWord have to remain variables, but at least they aren't global.
Making a variable into a constant by adding the final keyword can eliminate the risk of global variables. In the following source code, what happens to each of these when the final keyword is added? public static int LONG_WORD_LENGTH = 5; public static String longestWord; public static void countLongWords(List<String> words) { int n = 0; longestWord = ""; for (String word: words) { if (word.length() > LONG_WORD_LENGTH) ++n; if (word.length() > longestWord.length()) longestWord = word; } System.out.println(n); } final n
error before program starts With final, the compiler will notice that the code is trying to increment n. "++n" is equivalent to "n += 1", which is equivalent to "n = n+1", which reassigns n. You'll get an error before the program starts.
Which of the following changes (considered separately) would make the code fail faster if it were called with arguments in the wrong order? public static int dayOfYear(int month, int dayOfMonth, int year) { if (month == 2) { dayOfMonth += 31; } else if (month == 3) { dayOfMonth += 59; } else if (month == 4) { dayOfMonth += 90; } else if (month == 5) { dayOfMonth += 31 + 28 + 31 + 30; } else if (month == 6) { dayOfMonth += 31 + 28 + 31 + 30 + 31; } else if (month == 7) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30; } else if (month == 8) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31; } else if (month == 9) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31; } else if (month == 10) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30; } else if (month == 11) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31; } else if (month == 12) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31; } return dayOfMonth; } public static int dayOfYear(int month, int dayOfMonth, int year) { if (month == 1) { ... } else if (month == 2) { ... } ... } else if (month == 12) { ... } else { throw new IllegalArgumentException("month out of range"); } }
fails faster - dynamic error This function also checks that the range of the month is in 1-12, and fails faster with a dynamic error if it isn't. It demonstrates a good defensive programming practice: end every multi-case if statement (or switch statement) with an else clause that says, effectively, "if it wasn't any of those cases, then there must be a bug, so fail NOW."
Which of the following changes (considered separately) would make the code fail faster if it were called with arguments in the wrong order? public static int dayOfYear(int month, int dayOfMonth, int year) { if (month == 2) { dayOfMonth += 31; } else if (month == 3) { dayOfMonth += 59; } else if (month == 4) { dayOfMonth += 90; } else if (month == 5) { dayOfMonth += 31 + 28 + 31 + 30; } else if (month == 6) { dayOfMonth += 31 + 28 + 31 + 30 + 31; } else if (month == 7) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30; } else if (month == 8) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31; } else if (month == 9) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31; } else if (month == 10) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30; } else if (month == 11) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31; } else if (month == 12) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31; } return dayOfMonth; } public static int dayOfYear(int month, int dayOfMonth, int year) { if (month < 1 || month > 12) { throw new IllegalArgumentException(); } ... }
fails faster - dynamic error This is a better approach to error checking. When you find a bug, complain about it immediately. This code does it by throwing an exception, which will talk about more in a future. Unless the exception is intentionally caught by the program, it will cause a dynamic error, stopping the program. So we're failing faster than if we allowed a wrong answer to propagate.
Which of the following changes (considered separately) would make the code fail faster if it were called with arguments in the wrong order? public static int dayOfYear(int month, int dayOfMonth, int year) { if (month == 2) { dayOfMonth += 31; } else if (month == 3) { dayOfMonth += 59; } else if (month == 4) { dayOfMonth += 90; } else if (month == 5) { dayOfMonth += 31 + 28 + 31 + 30; } else if (month == 6) { dayOfMonth += 31 + 28 + 31 + 30 + 31; } else if (month == 7) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30; } else if (month == 8) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31; } else if (month == 9) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31; } else if (month == 10) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30; } else if (month == 11) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31; } else if (month == 12) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31; } return dayOfMonth; } public static int dayOfYear(String month, int dayOfMonth, int year) { ... }
fails faster - static error Requiring the month to be a String causes a static error for the plausible mistakes where the day or year are passed first instead, since they are both integers. So it fails faster in those cases, rather than quietly producing wrong answers.
Which of the following changes (considered separately) would make the code fail faster if it were called with arguments in the wrong order? public static int dayOfYear(int month, int dayOfMonth, int year) { if (month == 2) { dayOfMonth += 31; } else if (month == 3) { dayOfMonth += 59; } else if (month == 4) { dayOfMonth += 90; } else if (month == 5) { dayOfMonth += 31 + 28 + 31 + 30; } else if (month == 6) { dayOfMonth += 31 + 28 + 31 + 30 + 31; } else if (month == 7) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30; } else if (month == 8) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31; } else if (month == 9) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31; } else if (month == 10) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30; } else if (month == 11) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31; } else if (month == 12) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31; } return dayOfMonth; } public enum Month { JANUARY, FEBRUARY, MARCH, ..., DECEMBER }; public static int dayOfYear(Month month, int dayOfMonth, int year) { ... }
fails faster - static error This is similar to requiring the month to be a String, because it causes a static error for the plausible mistakes where the day or year are passed first instead. But it's even better than using a String because the only values that a caller can pass are one of the twelve months. Any other values would be rejected by the compiler, statically. By contrast, using a String, the caller could pass a misspelled month name like "Aprile", or a different language like "Ñнварь", or an abbreviation like "Jan" that the code wasn't ready for, and the best this method could do would be a dynamic error. Using a fixed 12-value enumeration would catch more errors at compile time.
public static int dayOfYear(int month, int dayOfMonth, int year) { if (month == 2) { dayOfMonth += 31; } else if (month == 3) { dayOfMonth += 59; } else if (month == 4) { dayOfMonth += 90; } else if (month == 5) { dayOfMonth += 31 + 28 + 31 + 30; } else if (month == 6) { dayOfMonth += 31 + 28 + 31 + 30 + 31; } else if (month == 7) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30; } else if (month == 8) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31; } else if (month == 9) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31; } else if (month == 10) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30; } else if (month == 11) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31; } else if (month == 12) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31; } return dayOfMonth; } Suppose the date is February 9, 2019. The correct dayOfYear() result for this date is 40, since it's the fortieth day of the year. Which of the following are plausible ways that a programmer might (mistakenly) call dayOfYear()? And for each one, does it lead to a static error, dynamic error, or wrong answer? dayOfYear(2, 2019, 9)
implausible mistake This is implausible because no convention for writing dates puts the year in the middle. It's unlikely to happen by accident.
Which of the following changes (considered separately) would make the code fail faster if it were called with arguments in the wrong order? public static int dayOfYear(int month, int dayOfMonth, int year) { if (month == 2) { dayOfMonth += 31; } else if (month == 3) { dayOfMonth += 59; } else if (month == 4) { dayOfMonth += 90; } else if (month == 5) { dayOfMonth += 31 + 28 + 31 + 30; } else if (month == 6) { dayOfMonth += 31 + 28 + 31 + 30 + 31; } else if (month == 7) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30; } else if (month == 8) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31; } else if (month == 9) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31; } else if (month == 10) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30; } else if (month == 11) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31; } else if (month == 12) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31; } return dayOfMonth; } public static int dayOfYear(int month, int dayOfMonth, int year) { if (month < 1 || month > 12) { return -1; } ... }
no change This code checks whether the month is in the desired range, which is smart, but then it does something dumb in response - it quietly returns a wrong answer, which can continue to propagate through subsequent code. Granted, it's a strange-looking wrong answer, since -1 is not in the usual range 1-366 that dayOfYear() would normally return, but it won't fail fast, and that strangeness may even be masked by subsequent code (for example, if the caller adds 7 to the result to find a week later).
public static int dayOfYear(int month, int dayOfMonth, int year) { if (month == 2) { dayOfMonth += 31; } else if (month == 3) { dayOfMonth += 59; } else if (month == 4) { dayOfMonth += 90; } else if (month == 5) { dayOfMonth += 31 + 28 + 31 + 30; } else if (month == 6) { dayOfMonth += 31 + 28 + 31 + 30 + 31; } else if (month == 7) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30; } else if (month == 8) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31; } else if (month == 9) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31; } else if (month == 10) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30; } else if (month == 11) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31; } else if (month == 12) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31; } return dayOfMonth; } Suppose the date is February 9, 2019. The correct dayOfYear() result for this date is 40, since it's the fortieth day of the year. Which of the following are plausible ways that a programmer might (mistakenly) call dayOfYear()? And for each one, does it lead to a static error, dynamic error, or wrong answer? dayOfYear(2, 9, 2019)
not a mistake - right answer dayOfYear() expects its arguments in month/day/year order, with the month as a number from 1 to 12, so this is the right way to call it, and it will produce the right answer, 40.
public static int dayOfYear(int month, int dayOfMonth, int year) { if (month == 2) { dayOfMonth += 31; } else if (month == 3) { dayOfMonth += 59; } else if (month == 4) { dayOfMonth += 90; } else if (month == 5) { dayOfMonth += 31 + 28 + 31 + 30; } else if (month == 6) { dayOfMonth += 31 + 28 + 31 + 30 + 31; } else if (month == 7) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30; } else if (month == 8) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31; } else if (month == 9) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31; } else if (month == 10) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30; } else if (month == 11) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31; } else if (month == 12) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31; } return dayOfMonth; } Suppose the date is February 9, 2019. The correct dayOfYear() result for this date is 40, since it's the fortieth day of the year. Which of the following are plausible ways that a programmer might (mistakenly) call dayOfYear()? And for each one, does it lead to a static error, dynamic error, or wrong answer? dayOfYear("February", 9, 2019)
plausible mistake - static error This is plausible if the programmer is assuming the month is passed by a string name (in English). Static type checking forbids passing a String to an int argument, however, so the mistake is caught fast, before the program even starts.
public static int dayOfYear(int month, int dayOfMonth, int year) { if (month == 2) { dayOfMonth += 31; } else if (month == 3) { dayOfMonth += 59; } else if (month == 4) { dayOfMonth += 90; } else if (month == 5) { dayOfMonth += 31 + 28 + 31 + 30; } else if (month == 6) { dayOfMonth += 31 + 28 + 31 + 30 + 31; } else if (month == 7) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30; } else if (month == 8) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31; } else if (month == 9) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31; } else if (month == 10) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30; } else if (month == 11) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31; } else if (month == 12) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31; } return dayOfMonth; } Suppose the date is February 9, 2019. The correct dayOfYear() result for this date is 40, since it's the fortieth day of the year. Which of the following are plausible ways that a programmer might (mistakenly) call dayOfYear()? And for each one, does it lead to a static error, dynamic error, or wrong answer? dayOfYear(9, 2, 2019)
plausible mistake - wrong answer This is plausible if the programmer is assuming the arguments are in day/month/year order, which is the standard almost everywhere in the world except the United States. It quietly produces the wrong answer because dayOfYear() interprets those arguments as September 2.
public static int dayOfYear(int month, int dayOfMonth, int year) { if (month == 2) { dayOfMonth += 31; } else if (month == 3) { dayOfMonth += 59; } else if (month == 4) { dayOfMonth += 90; } else if (month == 5) { dayOfMonth += 31 + 28 + 31 + 30; } else if (month == 6) { dayOfMonth += 31 + 28 + 31 + 30 + 31; } else if (month == 7) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30; } else if (month == 8) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31; } else if (month == 9) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31; } else if (month == 10) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30; } else if (month == 11) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31; } else if (month == 12) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31; } return dayOfMonth; } Suppose the date is February 9, 2019. The correct dayOfYear() result for this date is 40, since it's the fortieth day of the year. Which of the following are plausible ways that a programmer might (mistakenly) call dayOfYear()? And for each one, does it lead to a static error, dynamic error, or wrong answer? dayOfYear(2019, 2, 9)
plausible mistake - wrong answer This is plausible if the programmer is assuming the arguments are in year/month/day order, which is a common international standard (ISO 8601, in fact). It quietly produces the wrong answer because none of the if statements match the huge month number, so it ends up treating it the same as January 2.
public static int dayOfYear(int month, int dayOfMonth, int year) { if (month == 2) { dayOfMonth += 31; } else if (month == 3) { dayOfMonth += 59; } else if (month == 4) { dayOfMonth += 90; } else if (month == 5) { dayOfMonth += 31 + 28 + 31 + 30; } else if (month == 6) { dayOfMonth += 31 + 28 + 31 + 30 + 31; } else if (month == 7) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30; } else if (month == 8) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31; } else if (month == 9) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31; } else if (month == 10) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30; } else if (month == 11) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31; } else if (month == 12) { dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31; } return dayOfMonth; } Suppose the date is February 9, 2019. The correct dayOfYear() result for this date is 40, since it's the fortieth day of the year. Which of the following are plausible ways that a programmer might (mistakenly) call dayOfYear()? And for each one, does it lead to a static error, dynamic error, or wrong answer? dayOfYear(1, 9, 2019)
plausible mistake - wrong answer This is plausible if the programmer is assuming zero-based indexing for months, i.e. the month is a number from 0 to 11, so February is 1. Zero-based indexing is far more common in programming than one-based indexing, so this is a very plausible mistake, but it quietly produces the wrong answer.