LS215 Computational Thinking and Problem Solving

Réussis tes devoirs et examens dès maintenant avec Quizwiz!

Why is it important to create examples / test cases before we work through the algorithm or code?

- Creating test cases forces us to fully understand the problem requirements. If we can't build the test cases, then we don't fully understand the problem. - They also provide a more concrete version of the requirements, so after creating a test case, we may realize that the scenario it handles is not covered in our requirements. - Test cases also help us by giving us runnable code that we can use to verify that we have successfully solved the problem. - Test cases provide us with an explicit stopping point—once they all pass, we know that our solution is complete.

PEDAC: Understanding the Problem and Writing Example Test Cases

- Fully understand the Problem - Write out Examples

How do I come up with good test cases? Special Values

- If the input is a number, does it work with zero, negative numbers, fractional numbers (e.g., 0.567), or special values (e.g., NaN, Infinity)? - If the input is a string, array, or object, does it work with an empty string, array, or object (e.g., '', [], {})? - If the input is an array, does it work with a "sparse array" (e.g, [1, , 2]) or an array with an object property (e.g., [1, 2, a: "A"])?

How do I come up with good test cases? Try to avoid testing more than one requirement per test case.

- Isolating each specific requirement will make it easier to validate and debug our solution later on. - On the other hand, it is okay to test a single requirement using more than one test case—especially when testing more complex requirements, such as conditional requirements.

What is the purpose of the PEDAC process?

- Make implicit requirements explicit. - Provide a process for solving problems. - Understand all the requirements. - Come up with a plan of execution.

How do I come up with good test cases? Cover the requirements we captured in our requirement breakdown as completely as possible.

- Make sure to cover all the requirements, including both the generic cases and the edge cases. - Look for the word, "if", in the requirement breakdown. Conditional requirements need test cases that cover both sides of the condition to have full coverage. For example, the following two test cases cover both sides of the given conditional requirement:

Which of the following methods can be used to create an array based on the contents of a string?

- String.prototype.match - String.prototype.split - RegExp.prototype.exec

Why are test cases important?

- Test cases provide runnable code that you can use to verify your solution. - Test cases help you identify bugs in your solution. - Test cases help you understand the requirements. Test cases don't solve the problem for us. Rather, they let us determine which requirements the solution fails to satisfy—this is valuable feedback that helps us debug and fix errors. Therefore, test cases help us validate our understanding of the problem.

How do I come up with good test cases? Valid / Invalid inputs

- What should we consider as invalid inputs and what should we do with them? For example, if the input is supposed to be a "word", can we assume that it will be a string containing only letters and no other characters? Should we return a specific value—such as null or undefined—if the input isn't a valid word? Should we consider letter case? For example: 'a', 'dog', 'DOG', 'doG', ' dog', 'dog ', 'dog cat', 'dogCat', 'dog_cat', '@', 'dog4', '4dog', '42', 'dog\n'. - What should we do when an input has been omitted? For example, should we issue an error message, return a specific value, or set that input to a default value and execute the function normally?

Imperative Programming

A n imperative program consists of commands for the computer to perform. Imperative programming focuses on describing how a program operates.Focuses on the steps or mechanics of solving the problem. Each line of code has a purpose, but that purpose comes from understanding the developer's implementation.

Declarative Programming

A non-imperative style of programming in which programs describe their desired results without explicitly listing commands or steps that must be performed. The higher the level of abstraction that you work with, the more declarative your code is. Declarative programming frees programmers to think on a higher level that's more natural for humans. We focus on writing a good description of the problem to solve, and the computer takes care of the rest. In comparison, imperative programming often means that you must imagine yourself as the computer - "I am going to do this first, then if this condition is true I do x, otherwise I do y.", "I need to use this variable to hold this value, then increment it as I go through this array". Obviously, we are more productive and happier when we think like humans, and don't have to pretend to be computers.

What is a test/example case?

A test case is an example of how some code can be used. Test cases usually have a combination of the input values that the program accepts and the desired result (expected output) that we wish to determine with our code. There are two main types of test cases: generic cases and edge cases. Generic cases test for the typical input values that we expect will be given to our program. Edge cases test for less common input values that may require special handling. They can be invalid inputs that we want to handle gracefully or other specific scenarios that we must consider. We'll take a closer look at both of these types of test cases in the answer to the next question.

PEDAC: Abstractions

Avoid solving big problems! Always, ALWAYS break bigger problems into smaller problems.

How do I come up with good test cases? Input Types

Can the function take and handle different types of inputs, such as numbers, strings, booleans, and objects?

When trying to break a problem down, where should I even begin? I tend to think in terms of the solution instead of the problem.

Capture the inputs and outputs as the first step. Then focus on two aspects of the problem description: "Definitions" and "Rules". Are there key concepts that need to be more clearly defined? Are there implied rules that need to be made explicit?

Do I always need to consider every possible edge case?

Depending on the situation, it's not always necessary to test for every possible edge case. For example, if we are writing a function to be used as part of a bigger program, and we know that the input is guaranteed to always be a string, then we don't need to create test cases for other input types. However, any time that we are uncertain about some aspect of the input, we should cover the relevant edge cases. This is one reason why it's so important to ask questions in any type of situation in which we have been provided with incomplete information, such as a technical interview in which test cases have not been provided. The interviewer may tell us that we don't need to consider many of the edge cases, but we can't be certain unless we ask. Making assumptions about what the input will be—without confirming them with the interviewer—can be a costly mistake.

JavaScript reduce function

Each invocation of the callback affects later invocations. The reduce method takes a required first argument, which should be a Function: reduce invokes this callback Function once for each element in the Array. It passes four arguments to the callback Function on each call. - accumulator: The return value of the previous callback invocation (this is the initial value on the first iteration) - currentValue: The value of the current element in the Array - currentIndex: The index of the current element - array: The array being processed reduce passes the accumulator to the next callback invocation, and uses the return value of the final callback invocation as the overall return value of reduce. reduce accepts an optional second argument, the initialValue. It provides the value to use as the first argument in the first call to the callback. If the caller does not provide the initialValue, reduce uses the first element of the array; when this happens, reduce starts processing with the second element of the Array. reduce returns the value returned by the final callback invocation.

JavaScript filter function

Filtering is the process of creating a new Array that contains a subset of an existing Array, and can be done using the filter method in JavaScript. filter takes a single argument, which should be a Function object. This Function will be invoked once for each element in the Array and is called with three arguments: - The current element in the Array - The index of the current element - The Array being iterated over If the callback returns true, the element will be included in the final Array. If the callback returns false, it will be excluded. filter returns a new Array containing the elements for which the callback returned true.

Great email validation regex example.

Implement a function that checks whether an email address is valid. An email address has two parts: A "local part" and a "domain part." An @ sign separates the two parts: local-part@domain-part. The local part is the name of the mailbox; this is usually a username. The domain part is the domain name (e.g., gmail.com, yahoo.com.ph, or myCompanyName.com). The domain name contains a server name (sometimes called the mail server name) and a top-level domain (.com, .ph, etc.). For this practice problem, use the following criteria to determine whether an email address is valid: There must be one @ sign. The local part must contain one or more letters (A-Z, a-z) and/or digits (0-9). It may not contain any other characters. The domain part must contain two or more components with a single dot (.) between each component. Each component must contain one or more letters (A-Z, a-z) only.

JavaScript Interrogation functions

Interrogation lets you determine how many of an Array's elements satisfy some condition. There are two Array methods in this category: Array.prototype.some and Array.prototype.every. Array.prototype.some and Array.prototype.every each take a single argument, which should be a Function. Both methods invoke the callback function once for each element in the Array, passing three arguments to the function each time: - The value of the current element in the Array - The index of the current element - The Array being processed The every method iterates over all the elements in the array until the callback function returns a falsy value; every immediately returns false when this happens. If no elements produce a falsy result, then every returns true. The some method iterates over all the elements in the array until the callback function returns a truthy value; some immediately returns true when this happens. If no elements have a truthy result, then some returns false. Array.prototype.some returns true if the callback returns a truthy value for at least one of the elements in the original Array. Array.prototype.every returns true if the callback returns a truthy value for all of the elements in the original Array.

What about this code block? Does the following code block demonstrate the use of first-class functions?

It is not possible to be certain. If the return value of bar is a function expression or a property assigned to a function, then yes; otherwise, no.

Assuming that str contains a 10-character string, which of the following describes the operation that str.substr(2, 2) performs?

It returns a string that consists of the two characters starting at index position 2 of the string value referenced by str. Assuming that str is a 10-character string, and that n + m =< 10, and that n and m are both positive integers, then str.substr(n, m) returns an m character substring of str starting at index position n.

Functional Abstractions on Objects

JavaScript doesn't have a set of built-in higher-order functions for Objects as it does for Arrays. However, you can use Object.keys or Object.values to work with objects with higher level abstractions.

In JavaScript if you can call toString on a variable that contains a number, why can't you call it directly on a number?

JavaScript interprets the period immediately after a number as a decimal point, not a method separator. One way to avoid this is to use two periods instead of one. Replace 356.toString() with 356..toString(), and try running it again. This time, the program works and logs the String '356' to the console. Adding a second period acts as a method separator, which lets you call the method directly on a number. Some "linter" programs reject this usage, and instead suggest that you use parentheses around the number.

Which of the following statements describe an algorithm?

Pseudo-code describes an algorithm without going into a specific language's syntax.

JavaScript sort functions

Sort lets you rearrange the elements of an Array from lowest to highest or vice versa, based on any desired criteria; in JavaScript, we use the Array.prototype.sort method to do this. sort takes a callback function as an argument, and performs an in-place sort of the Array (that is, it mutates the Array). It also returns a reference to the sorted Array. sort uses the callback Function to compare elements. If you don't pass a callback function as an argument, Array.prototype.sort's default sort order is according to string Unicode code points. Note that sort only cares about the sign of the callback return value. You may sometimes see assertions that the comparison function should return 1, -1, or 0, but any value is appropriate provided the sign is correct. Our example uses 1, -1, and 0 merely as convenient values. sort mutates the original array and returns a reference to the mutated (sorted) array. Thus, you can use sort for either its return value or its side effect.

Which of the following methods can be used to match a string against a regular expression?

String.prototype.includes searches a string to determine if it contains a specified substring. It does not involve any regular expressions. The regular expression class in JavaScript is named RegExp, not Regexp, so Regexp.prototype.test is not a valid answer.

How much effort should I put into "Understanding the Problem"? Is it okay to skip this step for problems that seem very obvious?

The bulk of "Understanding the Problem" involves translating the problem description into a specific and explicit set of definitions and rules. Therefore, how much effort we expend here depends on the problem's complexity. We also need to consider whether the requirements are already given in explicit "technical terms" or whether they are merely demonstrated—such as when they are expressed in higher "problem domain" terms or when they contain implicit knowledge that we must capture. If you extrapolate this process to larger projects, it is similar to the phase where a business analyst translates "business needs" to "technical requirements" so that they can be implemented by technical teams.

JavaScript substr vs substring methods.

The difference is in the second argument. The second argument to substring is the index to stop at (but not include), but the second argument to substr is the maximum length to return.

JavaScript forEach function

The preferred way to iterate over a JavaScript Array is with the forEach method. forEach invokes this Function once for each element in the Array. It calls the function with three arguments: - The value of the current element in the Array - The index of the current element - The Array being processed forEach does not use the return value of the callback. forEach returns undefined. This means that forEach must have side effects to be useful. There is no way to stop or break a forEach() loop other than by throwing an exception. If you need such behavior, the forEach() method is the wrong tool.

JavaScript String Method: toUpperCase and toLowerCase

These methods let you change the letters in a string to uppercase or lowercase. Both methods leave other characters unchanged.

JavaScript String Method: replace

This method performs a substitution operation on the original string, and returns the result as a new string. By default, replace substitutes the first occurrence of the substring or regular expression pattern given by the first argument with the value specified by the second argument. replace does not modify the original string. Note that this only replaces the first s. To replace every instance s, we must use a regular expression instead of a String. Regular expressions can get complicated, but in many cases you can just replace the quote characters with forward slash characters (/) to convert the search string to a regular expression. If you then append a g to the regular expression, replace will replace every matching substring with the replacement value.

JavaScript String Method: lastIndexOf

This method returns the index of the last occurrence of a character or substring. Returns -1 if the search character or substring doesn't exist.

JavaScript String Method: indexOf

This method returns the numeric index of a character or substring of characters within a string. If the search character or substring doesn't exist, returns -1.

JavaScript String Method: split

This method splits the string into an array of strings based on a separator. If you supply a string, split parses the string by breaking it at each occurrence of the separator string. If the separator string is an empty string, it splits the string into an array of single character strings. As with the replace method, you can also use a regular expression to identify the separator. This is useful when you need something more complex than a simple constant substring. Note that the returned array does not include instances of the separator string or regular expression.

JavaScript map function

Transformation of an Array is the creation of a new Array that contains values calculated from the values in the original Array. JavaScript supplies the map method for transformation. map takes a single argument, a callback Function, and calls this function once for each element in the Array. It passes three arguments to the callback Function on each call: - The value of the current element in the Array - The index of the current element - The Array being processed The values returned by the callback Function become the elements in the new Array. map returns a new Array that contains one element for each element in the original Array. Each element in the returned Array contains the value returned by the callback Function for the corresponding element in the original Array.

JavaScript's List Processing Abstractions

We can perform many operations on lists of values, and we can group these operations into categories based on their use case. Each Array method that fits into the above categories takes a Function as an argument. This Function implements an abstraction of some sort, and the method invokes this Function for each element in the Array. The developer defines how to implement the chosen abstraction. Because the methods "call back" the Function, we often refer to this Function as a callback.

What practice to use if you need to exit a loop early?

Whenever your code needs an early return while processing a list, you should consider using a simple loop like a for or while loop. With the exception of some and every, all JavaScript list processing abstractions traverse the entire list. Sometimes, some and every will prove useful, but many problems are not amenable to an approach that uses these two methods.

Does the following code block demonstrate the use of first-class functions?

Yes, the value of the foo property is a function.

JavaScript String Method: substring

extracts and returns a portion of the original string that lies in the range specified by its two numeric arguments. The arguments provide the starting and ending indexes of the string you wish to extract from the original string. The extracted string starts with the character at the smaller index of the two arguments, and ends just before the character at the larger index of the two values.

Since Functions are ___ values in JavaScript, you can store them in ___ and pass them as ___ to other Functions.

first-class, variables, arguments


Ensembles d'études connexes

Series 7 - Questions answered wrong

View Set

Financial Measures - Definition and Formula

View Set

BA 370 Marketing Smartbook 5 + vocab

View Set

Wealth and power exam 1 quiz questions

View Set

Systems physiology final HW questions

View Set