Skip to content

Commit e1d6f20

Browse files
committed
add pseudo directions
1 parent e14ffcc commit e1d6f20

File tree

3 files changed

+297
-0
lines changed

3 files changed

+297
-0
lines changed

Diff for: Pseudocode.md

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Pseudocode
2+
3+
## What is pseudocode?
4+
Pseudocode is fake code. This includes a combination of words and fundamental codelogic written out to complete an algorithm without any worry of the syntax.
5+
Pseudocode is language agnostic, which means anyone, regardless of their language, can read and understand what is going on before converting it into their language of choice.
6+
7+
There is not an 'official' syntax of pseudocode, just standard guidelines. Pseudocode is designed to stay lightweight and flexible allowing for many dialects to be used.
8+
9+
10+
| Symbol | Meaning |
11+
| ------------- |:-------------:|
12+
| Not Equal | ≠ |
13+
| Equal | = |
14+
| Greater than or equal to | ≥ |
15+
| Less than or equal to | ≤ |
16+
| Greater than | > |
17+
| Less than | < |
18+
19+
#### Pseudocode does not have
20+
- colons (:)
21+
- semicolons (;)
22+
- curly braces for code blocks ({})
23+
- parenthesis (other than method signature declarations)
24+
25+
#### Pseudocode does have
26+
- backwards arrows to set a value (←)
27+
- indentation to specify scope
28+
- equal sign for comparison (=)
29+
- keyword "DECLARE" when creating a variable in memory (no need to define type)
30+
- keyword "OUTPUT" when writing out to the console
31+
- keyword "RETURN" when returning a value out of a method
32+
33+
### Example 1
34+
35+
```
36+
ALGORITHM FizzBuzz(n)
37+
//INPUT ← a non-negative integer n
38+
//OUTPUT ← no return, output string
39+
for i ← 0 to n do
40+
if i mod 3 AND i mod 5
41+
OUTPUT ← "FizzBuzz"
42+
else if i mod 3
43+
OUTPUT ← "Fizz"
44+
else if i mod 5
45+
OUTPUT ← "Buzz"
46+
else
47+
OUTPUT ← i
48+
```
49+
50+
### Example 2
51+
52+
```
53+
ALGORITHM Factorial(n)
54+
// INPUT ← non-negative integer
55+
// OUTPUT ← product of factorials
56+
if n ≤ 0
57+
RETURN 1
58+
DECLARE number ← n * Factorial(n-1)
59+
RETURN number
60+
```
61+
62+
63+
### Example 3
64+
65+
```
66+
ALGORITHM BubbleSort(A[0…n-1])
67+
// INPUT ← An unsorted array of orderable elements
68+
// OUTPUT ← array sorted in nondecreasing order
69+
for i ← 0 to n-2 do
70+
for j ← 0 to n-2-i do
71+
if A[j+1] < A[j] SWAP A[j] and A[j+1]
72+
73+
```
74+
75+
### Example 4
76+
77+
```
78+
ALGORITHM SumOfLLValues(l)
79+
// INPUT ← Singly linkedlist with at lesat 1 node
80+
// OUTPUT ← non-negative integer
81+
DECLARE current ← l.Head
82+
DECLARE sum ← 0
83+
84+
while current.Next ≠ null do
85+
sum ← sum current.Value
86+
current ← current.Next
87+
88+
RETURN sum
89+
```
90+
91+
### Example 5
92+
93+
```
94+
ALGORITHM Countdown(n)
95+
//INPUT ← non-negative number
96+
//OUTPUT ← none
97+
for i ← n down to 0 do
98+
OUTPUT ← i
99+
```

Diff for: Testing_Workflow.md

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Writing Unit Tests
2+
3+
## Questions Unit Test Should Answer
4+
1. What are you testing?
5+
1. What should it do?
6+
1. What is the actual output?
7+
1. What is the expected output?
8+
9+
## Shoulds of Unit Testing
10+
1. Should test a single aspect of a component
11+
- Usually this means test should contain only a single assert
12+
1. Tests should not rely on running in any particular order
13+
1. Should be able to run repeatedly with same results given same input
14+
1. Should be fast
15+
1. Should be run often
16+
- Many tools allow tests to run on file save, or even after every keystroke!
17+
1. Prefer simple assert statements
18+
- Frameworks often contain advanced, and sometimes very handy, assertions.
19+
- E.g. `assertRendersTemplate('home.html')`
20+
- These are awesome, but use sparingly. Simple asserts are usually more readable.
21+
22+
23+
## Example Tests
24+
25+
### Given a function like...
26+
```
27+
def sum(a,b):
28+
""" sum two numeric arguments """
29+
30+
if isinstance(a, (int, float)) and isinstance(b, (int, float)):
31+
return a + b
32+
33+
raise TypeError('argument must be int or float')
34+
```
35+
36+
### Test the 'Happy Path' cases
37+
```
38+
def test_should_sum_two_integers():
39+
expected = 3
40+
actual = sum(1,2)
41+
assert expected is actual, "sum of 1 and 2 should be 3"
42+
```
43+
44+
```
45+
def test_should_sum_two_larger_integers():
46+
expected = 1333332
47+
actual = sum(1234567,98765)
48+
assert expected is actual, "sum of 1234567 and 98765 should be 1333332"
49+
```
50+
51+
### Test with less obvious values. E.g. zero and negative numbers
52+
53+
```
54+
def test_should_sum_negative_numbers():
55+
expected = 3
56+
actual = sum(5,-2)
57+
assert expected is actual, "sum of 5 and -2 should be 3"
58+
```
59+
60+
### Test default argument values as needed
61+
62+
```
63+
def test_should_handle_single_argument():
64+
expected = 2
65+
actual = sum(2)
66+
assert expected is actual, "sum of 2 and nothing should be 2 because 2nd argument defaults to 0"
67+
```
68+
69+
### Test acceptable argument types
70+
71+
**Note:** Different languages handle floating point precision differently. Adjust your assertion as needed.
72+
```
73+
def test_should_sum_floats():
74+
expected = 5.0
75+
actual = sum(3.5,1.5)
76+
assert expected == actual, "sum of 3.5 and 1.5 should be 5.0"
77+
```
78+
79+
```
80+
def test_should_sum_integer_and_float():
81+
expected = 5.5
82+
actual = sum(3.5,2)
83+
assert expected == actual, "sum of 3.5 and 2 should be 5.5"
84+
```
85+
86+
### Test unsupported argument types
87+
88+
```
89+
def test_should_accept_only_numbers():
90+
# consult docs for how your test framework handles testing exceptions
91+
with pytest.raises(TypeError):
92+
sum('1',3)
93+
```
94+
## References
95+
96+
- [What Exactly is a Unit in Unit Testing?](https://www.blinkingcaret.com/2016/04/27/what-exactly-is-a-unit-in-unit-testing/){:target="_blank"}
97+
- [10 Tips](https://dzone.com/articles/10-tips-to-writing-good-unit-tests){:target="_blank"}
98+
- [5 Questions Every Unit Test Must Answer](https://medium.com/javascript-scene/what-every-unit-test-needs-f6cd34d9836d){:target="_blank"}
99+

Diff for: Whiteboard_Workflow.md

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Whiteboard Challenge Workflow
2+
3+
This file contains details on what is expected when completing a whiteboard challenge. Please refer to the visual as a guideline to what content is required for each whiteboarding challenge.
4+
5+
![Example Whiteboard Image](assets/DataStructuresWhiteboard.PNG)
6+
7+
## Overall Guidance on Whiteboard Workflow
8+
9+
The steps in this document are meant to show you one solid workflow. It's a structure that works for most people to help them solve whiteboarding problems effectively.
10+
11+
As you get started doing whiteboards, we suggest that you stick to the steps we recommend, in the order that we recommend. Once you gain more confidence in the process of whiteboard interviewing, you are welcome to deviate from this process *at your own risk*. If you find that pieces of the process do not work well for you, or make more sense in a different order, that's allowed! And during an interview, you should always be prepared for an interviewer to ask you to complete steps in a different order than you're used to, or to ask you to clarify your thinking even when your normal process would move on. Listening to and working with your interviewer is always the best option, and you should expect that not every whiteboard interview will go the same way.
12+
13+
For an example of an instructor solving a whiteboard (quickly) with a modified version of this process, see [this YouTube video](https://youtu.be/9KAy1AampQc?t=1386){:target="_blank"}.
14+
15+
### 1. Problem Domain
16+
17+
Re-iterate the problem domain that you have been asked. This can be done either verbatim from the initial question, or a summary in your own words, whatever makes more sense to you.
18+
19+
### 2. Visual
20+
21+
Draw out what the problem domain is and visually solve the problem. Label all of the appropriate properties, define your input and output, and show how you will approach the problem towards a solution.
22+
23+
(It's common for people to switch up the ordering on visuals/problem domain depending on the problem; sometimes, drawing a picture helps you understand the problem better, at which point you can write out the problem domain.)
24+
25+
### 3. Algorithm
26+
27+
The algorithm is a breakdown of what you need to achieve. This should be a bulleted list or a general overview of what you plan to implement later in the interview.
28+
29+
The most practical way of creating an algorithm is often to focus on the example input/output in your visual. You should consider the steps that your algorithm will take to use the input in moving towards the output. This process of working through the problem yourself, and noticing the steps you take along the way, should naturally help you flesh out the steps that will be part of your algorithm.
30+
31+
### 4. Big O
32+
33+
Analyze the space AND time efficiency of the algorithm that you just proposed. You should revisit this analysis throughout the interview as you make updates to your algorithm during pseudocode/code/stepthrough.
34+
35+
### 5. Pseudocode
36+
37+
Write out pseudocode that defines your algorithm! Use the [pseudocode cheat sheet](./Pseudocode){:target="_blank"} as a guideline to what symbols are acceptable.
38+
39+
### 6. Code
40+
41+
Write out syntactically correct code in the language of your course to solve the problem presented. Your real code should be based off of your pseudocode.
42+
43+
### 7. Test
44+
45+
There are two main parts to testing. First, walk through both the problem domain and your solution to make sure that it both works and is efficient. This should be a careful, line-by-line stepthrough of your code, where you track variables in a written table along the way. It's very normal to start the stepthrough, realize that you have a bug in your code, and go back to your code to try and fix the bug; in this case, make sure to go back to careful stepthrough for any modified parts of your code.
46+
47+
Secondly, you should talk about how you would test this code if you were writing unit tests. This means listing out a variety of test cases; your goal is to show the interviewer that you know what kinds of tests are useful to ensure that a function is working. At a minimum, you want to list out:
48+
- a standard input and output
49+
- a standard input that has a different output than your first listed i/o
50+
- some edge cases in how the data is structured; you'll probably list several of these (the array is already sorted! the tree is very unbalanced! the string is just the character 'a' twelve times! etc.)
51+
- the input is null/negative/zero (the "normal" edge cases)
52+
53+
## Examples of What That Looks Like
54+
55+
In the best possible interview, you might have all of the ideas that you need and be able to move in this perfect linear order. In most interviews, though, you won't have that perfect flow from step 1 linearly through to step 7.
56+
57+
While no two interviews will look the same, here is one example of a normal interview process:
58+
59+
- Step 1: You write down the problem domain as the interviewer reads the problem to you.
60+
- Step 2: You draw a picture of what that input will look like and write down what you think the output will be.
61+
- Step 1 Again: The interviewer corrects you: your proposed output is incorrect. You revisit the problem domain.
62+
- Step 2 Again: Now that you understand the problem better, you come up with a more representative visual.
63+
- Steps 2 And 3: You develop your algorithm. You show with arrows in your visual how you'll transform the input into the output, and write down a bulleted list of steps as you go.
64+
- Step 4: You analyze the runtime and space complexity of the algorithm you just proposed, using big O notation.
65+
- Step 4.5: The interviewer asks you why you've chosen to use a particular data structure instead of some other choice, and how that impacts your runtime and space complexity. You reason through the use of that data structure vs. alternatives verbally with the interviewer, and decide your choice of data structure was good, and you'll continue using it.
66+
- Step 5: You decide your algorithm has some ambiguity, so you start writing pseudocode that matches your algorithm.
67+
- Step "Oh No": You realize which part of your algorithm was imprecise; there's more going on in this problem than you realized. You go back to your visual and algorithm and try to work through how this new realization fits in.
68+
- Steps 2 And 3 And 4 Again: You figure out how you'll work through this issue, and add that into your arrows and your bullet points. Since you've changed your approach, you also change your estimate of the runtime/space complexity.
69+
- Step 5 Again: You keep working through your pseudocode.
70+
- Step 6: You write out syntactically correct code that matches your pseudocode.
71+
- Step 7: You start stepping through your example input from Step 2, walking through your syntactically correct code line by line.
72+
- Step "Oh No" Again: You realize as you step through that your code doesn't actually generate the output that you expected.
73+
- Step 6 Again: You debug your code and get it working on your example input.
74+
- Step 4 Again: Since you changed your code while debugging, you re-analyze runtime/space complexity.
75+
- Step 6 Again: You finish your stepthrough on the example input, and it's now generating the correct output.
76+
- Step 7, Continued: You list out test cases that you would want to test this program on.
77+
- Step 8: Whatever your interviewer says!
78+
79+
## Advanced Whiteboard Interviewing: Making this process your own
80+
81+
After practicing whiteboard interviews, many people find that they want to modify this process. Here are some common things students want to do, and our analysis of those options.
82+
83+
### Skipping or Shortening the Problem Domain
84+
85+
It's possible to have a successful whiteboard without writing the problem domain on the whiteboard first. It's often okay to just write a few notes of the important pieces of the problem and use a visual with example input/output to verify with your interviewer that you understand the problem. Be aware that some interviewers will not correct you if you are working on the wrong problem, so it is *extremely* important that you verify the problem domain verbally, even if you don't write it on the whiteboard.
86+
87+
### Shortening Algorithm, Pseudocode, and Actual Code
88+
89+
We include all 3 of algorithm/pseudocode/actual code because, for many people, each of those steps helps to refine their algorithm. The first iteration of the algorithm helps get ideas of thoughts down on the whiteboard; the second iteration helps ensure that those ideas will translate well into code; and the third iteration allows you to focus on your language's syntax. If you are a person who writes an extremely exact code-like algorithm, or if you are very comfortable with your language's syntax, you may find that the pseudocode step slows you down without providing any benefits. In that case, it's fine to skip the pseudocode step.
90+
91+
### "Skipping Around" between Algorithm and Actual Code
92+
93+
**It is almost always a bad idea** to figure out half of your algorithm, write code for that half of your algorithm, and then figure out the rest of your algorithm. If you have half a strategy, but have no idea how to do the second half, you'll often need to change the first half of your strategy once you figure out a complete algorithm. You run the risk of coming up with the start of your strategy, taking the time to write out code for that part of your strategy, coming back to thinking about your strategy, and realizing you need a different strategy and no longer need the code that you wrote. It's best to have some idea of how you'll solve the entire problem before you start writing code.
94+
95+
There's one exception: sometimes you have the majority of your algorithm, and you're confident it will work, but you're not sure about some small piece (whether the loop should run n or n-1 times, or whether to use a HashTable or a HashSet, or something else insignificant compared to the "interesting" part of the algorithm). In that case, writing out your code and then coming back to the tiny-question afterwards is usually a good strategy; a good stepthrough will help you know the right solution.
96+
97+
## Writing Headings on the Whiteboard
98+
99+
Some people love writing the headings "Problem Domain", "Visual", etc. on the whiteboard to help them remember the steps they want to take. Other people find that feels robotic, and that they naturally flow among different parts of the whiteboard during problem solving. Either strategy is reasonable, as long as you're consistent (either lots of headings, or no headings).

0 commit comments

Comments
 (0)