An algorithm is a set of instructions that solve a problem or accomplish a goal. In everyday life, you use many algorithms without even realizing it. For example, you can think of a cookbook as a long list of algorithms that tell you how to make specific dishes. Here is how you make oatmeal algorithmically:
Code is a word that essentially describes instructions that are written in a language that a computer can understand. In my videos I use the Python programming language to implement the featured algorithms.
Pseudocode is a word used to describe algorithms written in a similiar style to actual computer code, but is more understandable for people. You can think of the lyrics to my songs as pseudocode. I call my songs musicAlgos because they are musical algorithms.
A variable is a name we assign to a particular value. Multiple variables can be set to the same value (but two or more variables cannot have the same name).
Python example of variables:
Say we wanted to add two numbers and store their sum as a variable:
One interesting thing you can do to a variable is reassign it by recursively mentioning itself. Here is what I mean:
In Python each variable has a specific data type it is classified as. Based on the way you define the variable, Python will identify what type it is, which is known as implicit typing.
A boolean can only take on two values True and False. Certain statements involving logical operators will output booleans. For instance if I wrote 4 > 5 the output would be False since 4 is not greater than 5, here the operator was >. Here is a list of operators:
Ints and Floats
You can set a variable equal to an integer data type or int for short by setting it equal to a positive or negative whole number. If you set your variable equal to a number with anything after the decimal point even if it's zero, that is called a float. Here is what I mean:
So what are the main differences between ints and floats other than that ints can only be whole numbers? Well, you can only do list indexing (see lists) using integers. If you ask for list[0.3], Python won't know what you are talking about and throw an error. Division also can work differently. With floats division is more straightforward, and basically performs the way you would expect by carrying out the division until it can't store anymore values past the decimal point. In Python 3, integer division (division among two integer values) can work two ways: with the "/" operator, division may output a float since the answer might not be a whole number. With this operator "//" it will round down to the nearest whole number and the quotient will be an int. In Python 2.7 (the version I use), even the "/" operator will round down for integer division and output an int.
Division in Python 2.7:
Here is an example of how floats and ints interact with each other using division. The comments (followed by #) tell you the output.
The only difference between 2.7 and 3 would be that 1/2 would output 0.5 in Python 3. (And in Python 3 you need parentheses around the values which you want to print, i.e. print(5 / 2).)
The string data type is a sequence of characters, such as letters, numbers or symbols. In Python, you define a string by putting quotes around it. Some cool things you can do with strings: add them together with the + operator, and index them (see lists). For example:
A list is composed of a row of cells, where each cell holds a value. We identify the leftmost cell as index 0, the next index is 1, the following one is 2, and so on. Another name for index is position.
Lists in Python:
Let's create a list containing the values: 10, 20, 30, 40. Say we wanted to see what was at position 0 and then change that value to something else. To see what is at a certain position in the list we specify the position in brackets[ ], if we want to see the entire contents of the list we don't need brackets. Another use of brackets is to reset a value in the list. Here is what I mean:
Strings which are sequences of characters can be indexed like lists as well, where each letter holds a single position. For example:
The code inside an if statement is only executed if a certain condition is met. If there is a following else statement and the if condition is not met then the code inside the else statement will be exectued.
Real life example of an if/else statement:
I am deciding on what to do tomorrow. I'd prefer to go to the beach, but only if it is sunny. If it is not sunny, I will play ping pong:
Let's change it up a bit. Let's say that my second preference is actually to play tennis, but only if the courts are dry. To represent this, I could use an elif (short for else if), which is executed if no previous if or elif statement before it has been executed:
Python example if statements:
The following code would print out "x is greater than 10":
The following code would print out "x is equal to 10":
The following code would print out "x is less than 10":
For loops follow the same set of instructions for every item in a given sequence.
Real life example of a for loop:
Say you had to a pay a bunch bills. For every bill you need to 1) write a check, 2) get an envelope, 3) identify address of the recipient, and 4) put a stamp on the envelope (in this order). This can be expressed as a for loop:
for every bill I need to mail:
Python example of a for loop:
Say you wanted to print the numbers 0, 1, 2, 3 like this:
In Python you would express this as so:
The range(n) function returns an "iterable"; containing the values [0,1,2,...,n-1]. The implied lower bound is 0 and it includes integers up to, but not including n. For each value in this iterable the for loop performs the instruction indented within it (which simply prints out the value). Even though range(n) returns an iterable of integers, you don't have to say for number in range(4); you could say for elephant in range(4) or for donkey in range(4), etc. and Python would do the same thing (as long as you also told Python to print elephant or donkey depending on which was used in the for statement). Typically i is the variable used in for loops, which we refer to as a loop counter because it counts which iteration the for loop is at.
While loops follow the same set of instructions while a given condition is met. The condition is checked each time the instructions have been completed.
Real life example of a while loop:
Usually this is how my dinners at home go: 1) I eat a serving of the main course and starch, and 2) I'll eat a serving of vegetables. If I am not hungry after eating the the main entree, starch, and veggies, then I stop eating. If I am still hungry, I'll take another serving of each.
This can be expressed as a while loop:
while I am hungry:
Python example of a while loop:
Again, say you wanted to print the numbers 0, 1, 2, 3 like this:
In Python you would express this as such:
The variable i is initially set to 0. We enter the while loop because i is less than 4. On each iteration of the while loop, the value that i stores is printed out, and we add 1 to i. The loop concludes after four iterations since on the fourth, i was initially equal to 3, and then it was incremented or increased by 1. This caused the condition that i < 4 to break, and thus the while loop concluded.
A function is a set of instruction(s), which in order to execute must be "called" upon. Functions are useful because they allow us to organize a program such that when one reads it, the program's main function can give a big picture view of what's happening, and helper functions can help hide some of the details.
A function may accept input values or parameters from its caller and may return a value to whomever called it (this also makes them reusable in a variety of situations). Code written outside a function will execute automatically, but code inside a function is only executed if the respective function is called.
Real life example of functions:
Here our main() function walks us through the process of making an omelet. First you beat three eggs, next specify and prepare the ingredients, and then cook the eggs and ingredients in a pan. To abstract or hide away some of the nitty gritty details of each step, I declared three helper functions: beatTheEggs(n) takes in a parameter "n", that indicates how many eggs you want to cook, and yields n beaten eggs, prepareTheIngredients(listOfIngredients) allows you to specify a list of ingredients you would like in the omelet and cuts them up in small pieces, and cookItUp(listOfIngredients, beatenEggs) cooks the ingredients and eggs in a pan.
This is obviously not real code so don't get hung up with the details. Just understand that the main() function tells the high-level or big-picture story and each helper function hides the details so main() is very readable.
def cookItUp(ingredients, beatenEggs):
For every ingredient:
A few things to notice though: Again beatTheEggs(n) takes in a parameter n that specifies the number of eggs you want. It also returns a value, n beaten eggs. This function could be used in other situations as well, for example, I could be writing a program that makes a batch of brownies which requires eggs. The function prepIngredients(ingredients) takes in a list of ingredients as a parameter. Even though the contents of the list have been changed (each ingredient has been sliced into small pieces), the list does not need to be returned explicitly, since it is mutable.
A type is mutable if it can be changed outside of the function it is declared in. An immutable type cannot be changed outside of the function it is declared in.
List of some mutable objects: lists, sets, dictionaries
List of some immutable objects: ints, strings, floats, tuples
Python example of functions:
Say you wanted to write a program that finds the median value in a list of numbers (for the sake of ease let's assume it has an odd number of entries). First it would need to sort the list of values, and then find the middle element in that sorted list.
Log is short for logarithm. If ab = c then Logac = b and vice-versa (the two statements are equivalent). In other words the log tells you what power its base, a, should be raised, to yield c.