Python is an unbelievably powerful programming language that is used by millions of developers in production systems around the world. It's easy to learn, free to use, and has a huge community of developers that are always willing to help. If you're interested in , data science, , or just want to automate some of your boring tasks, Python is a great place to start. back-end web development data engineering Would you rather learn by doing? I've included all the static read-only material you'll need here in this tutorial, but if you would like a , you can take the interactive version of this course, complete with coding challenges and projects on . more hands-on experience Boot.dev here Chapter 1: Introduction Thousands of students start their coding journey right here with Python. We think it's the best programming language to get started with. Python is famous for being a simple language that's easy to read and write. However, just because it's simple that doesn't mean it's not useful! Python is an popular language in the industry, and is well-known for: extremely Backend web servers DevOps and cloud engineering Machine learning Scripting and automation etc... On the other hand, it's not particularly well-known for front-end work. While it's to do so, Python isn't typically used to build visual user interfaces. possible Setup a Local Development Environment To get started with Python, you'll need to install the command on your computer, and then install a text editor or IDE. If you're not already familiar with how to do that, I have a full step-by-step that you can follow. python project guide here If you're able to edit and run Python code on your computer, you're ready to continue! What is "Code"? Code is just a series of instructions that computers can follow. Computers obey each instruction, . one after another Programs can be comprised of instructions. Like many. Like millions. many Addition is one of the most common instructions in coding. Printing numbers can print text using quotes: print() print("some text here") but it can also print numbers without quotes: print(1) and you can do math directly inside the parentheses: print(1 + 2) Try some of these code snippets in your editor! For example, you could create a file called and write the following code: hello.py print("Hello, world!") print(1 + 2) Then, run the file with and see what happens. python hello.py Multiple Instructions Code runs in order, starting at the top of the program. For example: print("this prints first") print("this prints second") print("this prints last") Syntax Errors is jargon for "valid code that the computer can understand". For example, Syntax prnt("hello world") is invalid because is not a valid function, "print" is spelled incorrectly. As a result, an error will be thrown and the code won't execute. syntax prnt() Syntax varies from langauge to language A coding language's syntax makes up the rules that define what properly structured expressions and statements look like in that language. For example, in Python, the following would be considered syntax: correct print("hello world") While in a different programming language, like Go, the correct syntax would be: fmt.Println("hello world") Code can have many different problems that prevent it from working as intended. Some examples include: A bug in the logic. For example, a program that should add numbers multiplies them instead A problem with speed. A program that calculates how to play the perfect game of chess might never be able to finish because it requires too many calculations. A problem with syntax. This is the most common problem for new developers. Luckily the Python interpreter will try to give you a descriptive error message in the console to help you find the problem. Chapter 2: Variables are how we store data in our program. So far we've been directly printing data by passing it directly into the function. Variables print() Now we are going to learn to save the data in variables so we can use and change it before we need to print it. A variable is a name that we define that will point to some data. For example, I could define a new variable called and set its value to 100. I could also define a variable called and set it equal to "Lane". my_height my_name Creating variables To create a new variable in Python we use the following syntax: my_new_variable_two = 2 this_can_be_called_anything = 3 Variables Vary Variables are called "variables" because they can hold any value and that value can change (it varies). For example, the following will print : 20 acceleration = 10 acceleration = 20 print(acceleration) The line the value of to 20. It whatever was being held in the variable before. acceleration = 20 reassigns acceleration overwrites acceleration Let's do some math Now that we know how to store and change the value of variables let's do some math! Here are some examples of common mathematical operators in Python syntax. sum = a + b difference = a - b product = a * b quotient = a / b Comments Comments don't run like code, they are by the computer. Comments are useful for adding reminders or explaining what a piece of code does in plain English. ignored Single line comment # speed is a variable describing how fast your player moves speed = 2 Multi-line comments (aka docstrings) You can use triple quotes to start and end multi-line comments as well: """ the code found below will print 'Hello, World!' to the console """ print('Hello, World!') This is useful if you don't want to add the to the start of each line when writing paragraphs of comments. # Variable Names Variable names can't have spaces, they're continuous strings of characters. In Python you should use " " when creating variable names - it's become the "rule of thumb" for the language. By way of comparison, "camel case" is where the beginning of each new word except the first is capitalized. snake_case No casing (pure insanity) somevariablehere = 10 Camel Case someVariableHere = 10 Snake Case some_variable_here = 10 Basic Variable Types In Python there are several basic data types. String Type "Strings" are raw text in coding speak. They are called "strings" because they are a list of characters strung together. Strings are declared in Python by using single quotes or double quotes. That said, for consistency's sake, we prefer double quotes. name_with_single_quotes = 'boot.dev' name_with_double_quotes = "boot.dev" Numeric Types Numbers aren't surrounded by quotes when created, but they can have decimals and negative signs. Integers are numbers without a decimal x = 5 y = -5 A "Float" is a number with a decimal x = 5.2 y = -5.2 Boolean Type A "Boolean" (or "bool") is a type that can only have one of two values: or . As you may have heard computers really only use 1's and 0's. These 1's and 0's are just values. True False Boolean 0 = False 1 = True is_tall = True NoneType Variables Not all variables have a value. We can declare an "empty" variable by setting it to . None empty = None The value of in this instance is until we use the assignment operator, , to give it a value. empty None = None is NOT a specific string Note that the type is the same as a string with a value of "None": None not my_none = None # this is a None-type my_none = "None" # this is a string Dynamic Typing Python is . All this means is that a variable can store any type, and that type can change. dynamically typed For example, if I make a number variable, I can later change that variable to a string: This is valid: speed = 5 speed = "five" Just because you can doesn't mean you should! In almost all circumstances, it's a to change the type of a variable. The "proper" thing to do is to just create a new one. For example: bad idea speed = 5 speed_description = "five" What if it weren't dynamically typed? Statically typed languages like Go (which you'll learn in a later course) are statically typed instead of dynamically typed. In a statically typed language, if you try to assign a value to a variable of the wrong type, an error would crash the program. If Python were statically-typed, the first example from before would crash on the second line, . The computer would give an error along the lines of speed = "five" you can't assign a string value ("five") to a number variable (speed) https://www.youtube.com/watch?v=GqXpFycPWLE&embedable=true Math With Strings Most of the math operators we went over earlier don't work with strings, aside from the addition operator. When working with strings the operator performs a "concatenation". + + "Concatenation" is a fancy word that means the joining of two strings. first_name = "Lane " last_name = "Wagner" full_name = first_name + last_name now holds the value "Lane Wagner". full_name Notice the extra space at the end of in the variable. That extra space is there to separate the words in the final result: . "Lane " first_name "Lane Wagner" Multi-Variable Declaration We can save space when creating many new variables by declaring them on the same line: sword_name, sword_damage, sword_length = "Excalibur", 10, 200 Which is the same as: sword_name = "Excalibur" sword_damage = 10 sword_length = 200 Any number of variables can be declared on the same line, and variables declared on the same line be related to one another in some way so that the code remains easy to understand. should We call code that's easy to understand "clean code". Chapter 2: Computing Basics Python Numbers In Python, numbers without a decimal part are called - just like they are in mathematics. Integers Integers are simply whole numbers, positive or negative. For example, and are both examples of integers. 3 -3 Arithmetic can be performed as you might expect: Addition 2 + 1 # 3 Subtraction 2 - 1 # 1 Multiplication 2 * 2 # 4 Division 3 / 2 # 1.5 (a float) This one is actually a bit different - division on two integers will actually produce a . A float is, as you may have guessed, the number type that allows for decimal values. float Integers In Python, numbers without a decimal part are called . Contrast this to JavaScript where all numbers are just a type. Integers Number Integers are simply whole numbers, positive or negative. For example, and are both examples of integers. 3 -3 Floats A float is, as you may have guessed, the number type that allows for decimal values. my_int = 5 my_float = 5.5 Floor division Python has great out-of-the-box support for mathematical operations. This, among other reasons, is why it has had such success in artificial intelligence, machine learning, and data science applications. Floor division is like normal division except the result is afterward, which means the remainder is . As you would expect, this means the result is an instead of a . floored removed integer float 7 // 3 # 2 (an integer) https://www.youtube.com/watch?v=fmM07zqoT5c&embedable=true Exponents Python has built-in support for exponents - something most languages require a library for. math # reads as "three squared" or # "three raised to the second power" 3 ** 2 # 9 https://www.youtube.com/watch?v=sP8yhvtvipo&embedable=true Changing In Place It's fairly common to want to change the value of a variable based on its current value. player_score = 4 player_score = player_score + 1 # player_score now equals 5 player_score = 4 player_score = player_score - 1 # player_score now equals 3 Don't let the fact that the expression is not a valid mathematical expression be confusing. , it . It's valid because the way the expression should be read in English is: player_score = player_score - 1 It doesn't matter is valid code Assign to player_score the old value of player_score minus 1 Plus Equals Python makes reassignment easy when doing math. In JavaScript or Go you might be familiar with the syntax for incrementing a number variable. In Python, we use the operator instead. ++ += star_rating = 4 star_rating += 1 # star_rating is now 5 Scientific Notation As we covered earlier, a is a positive or negative number . float with a fractional part You can add the letter or followed by a positive or negative integer to specify that you're using . e E scientific notation print(16e3) # Prints 16000.0 print(7.1e-2) # Prints 0.071 If you're not familiar with scientific notation, it's a way of expressing numbers that are too large or too small to conveniently write normally. In a nutshell, the number following the specifies how many places to move the decimal to the right for a positive number, or to the left for a negative number. e Underscores for readability Python also allows you to represent large numbers in the decimal format using underscores instead of commas to make it easier to read. num = 16_000 print(num) # Prints 16000 num = 16_000_000 print(num) # Prints 16000000 Logical Operators You're probably familiar with the logical operators and . AND OR Logical operators deal with , and . boolean values True False The logical operator requires that inputs are to return . The logical operator only requires that input is to return . AND both True True OR at least one True True For example: True AND True = True True AND False = False False AND False = False True OR True = True True OR False = True False OR False = False Python Syntax print(True and True) # prints True print(True or False) # prints True Nesting with parentheses We can nest logical expressions using parentheses. print((True or False) and False) First, we evaluate the expression in the parentheses, . It evaluates to : (True or False) True print(True and False) evaluates to : True and False False print(False) So, prints "False" to the console. print((True or False) and False) Binary Numbers Binary numbers are just "base 2" numbers. They work the same way as "normal" base 10 numbers, but with 2 symbols instead of 10. Each in a binary number represents a greater multiple of 2. In a 4-digit number, that means you have the eight's place, the four's place, the two's place, and the one's place. Similar to how in decimal you would have the thousandth's place, the hundredth's place, the ten's place, and the one's place. 1 = 1 0001 = 2 0010 = 3 0011 = 4 0100 = 5 0101 = 6 0110 = 7 0111 = 8 1000 https://www.youtube.com/watch?v=M3VLyEDPDR8&embedable=true Bitwise "&" Operator Bitwise operators are similar to logical operators, but instead of operating on boolean values, they apply the same logic to all the bits in a value. For example, say you had the numbers and represented in . You could perform a bitwise operation and the result would be . 5 7 binary AND 5 0101 = 5 & 0111 = 7 = 0101 = 5 A in binary is the same as , while is . So really a bitwise operation is just a bunch of logical operations that are completed in tandem. 1 True 0 False is the bitwise operator in Python. , while . & AND 5 & 7 = 5 5 & 2 = 0 0101 = 5 & 0010 = 2 = 0000 = 0 Binary notation When writing a number in binary, the prefix is used to indicate that what follows is a binary number. 0b is 5 0b0101 is 7 0b0111 Example: Guild Permissions It's common practice in backend development to store user permissions as binary values. Think about it, if I have different permissions a user can have, then I can store that as a 4-digit binary number, and if a certain bit is present, I know the permission is enabled. 4 Let's pretend we have 4 permissions: - Leftmost bit can_create_guild - Second to left bit can_review_guild - Second to right bit can_delete_guild - Rightmost bit can_edit_guild Which are represented by . For example, if a user only has the permission, their binary permissions would be . A user with and would be . 0b0000 can_create_guild 0b1000 can_review_guild can_edit_guild 0b0101 To check for, say, the permission, we can perform a bitwise operation on the user's permissions and the enabled bit ( ). If the result is again, we know they have that specific permission! can_review_guild AND can_review_guild 0b0100 0b0100 Bitwise "|" Operator As you may have guessed, the bitwise "or" operator is similar to the bitwise "and" operator in that it works on binary rather than boolean values. However, the bitwise "or" operator "ORs" the bits together. Here's an example: is 5 0101 is 7 0111 0101 | 0111 = 0111 A in binary is the same as , while is . So a bitwise operation is just a bunch of logical operations that are completed in tandem. When two binary numbers are "OR'ed" together, the result has a in any place where of the input numbers has a in that place. 1 True 0 False 1 either 1 is the bitwise operator in Python. and as well! | OR 5 | 7 = 7 5 | 2 = 7 0101 = 5 | 0010 = 2 = 0111 = 7 Not We skipped a very important logical operator - . The operator reverses the result. It returns if the input was and vice-versa. not not False True print(not True) # Prints: False print(not False) # Prints: True Chapter 3: Comparisons Comparison Operators When coding it's necessary to be able to compare two values. is the name for these kinds of comparison operations that always result in or . Boolean logic True False The operators: "less than" < "greater than" > "less than or equal to" <= "greater than or equal to" >= "equal to" == "not equal to" != For example: 5 < 6 # evaluates to True 5 > 6 # evaluates to False 5 >= 6 # evaluates to False 5 <= 6 # evaluates to True 5 == 6 # evaluates to False 5 != 6 # evaluates to True https://www.youtube.com/watch?v=QZdCkBWsC-4&embedable=true Evaluations When a comparison happens, the result of the comparison is just a boolean value, it's either or . True False Take the following two examples: is_bigger = 5 > 4 is_bigger = True In both of the above cases, we're creating a variable called with a value of . Boolean is_bigger True Since , is always assigned the value of . 5 > 4 is_bigger True Why would I use the comparison if I can just set it to "True"? You wouldn't in case. However, let's imagine that instead of hard-coding the numbers and , we had some variables that we don't know the values of. For example, perhaps you're making a video game and need to keep track of player scores. this 5 4 dynamic To calculate who wins, you would need to write something like: # player_one_points and player_two_points are defined and change somewhere else in the game's code player_one_wins = player_one_points > player_two_points print(player_one_wins) # prints "True" when player one is winning, otherwise prints "False" Increment / Decrement If we're changing a number and simply want to increment (add to) or decrement (subtract from) there are special operators for that. shield_armor = 4 shield_armor += 1 # shield_armor now equals 5 shield_armor += 2 # shield_armor now equals 7 shield_armor = 4 shield_armor -= 1 # shield_armor now equals 3 shield_armor -= 2 # shield_armor now equals 1 Notice that is just short-hand for shield_armor+=1 shield_armor = shield_armor + 1 If Statements It's often useful to only execute code if a certain condition is met: if CONDITION: # do some stuff here for example: if bob_score > bill_score: print("Bob Wins!") If-Else An statement can be followed by zero or more (which stands for "else if") statements, which can be followed by zero or one statement. For example: if elif else if score > high_Score: print('High score beat!') elif score > second_highest_score: print('You got second place!') elif score > third_highest_score: print('You got third place!') else: print('Better luck next time') First the statement is evaluated. If it is then the if statement's body is executed and all the other s are ignored. if True else If the first is false then the next is evaluated. Likewise, if it is then its body is executed and the rest are ignored. if elif True If none of the statements evaluate to then the final statement will be the only body executed. if True else If-Else Rules You can't have an or an without an elif else if You have an without an can else elif Chapter 5: Loops Loops are a programmer's best friend. Loops allow us to do the same operation multiple times without having to write it explicitly each time. For example, let's pretend I want to print the numbers 0-9. I could do this: print(0) print(1) print(2) print(3) print(4) print(5) print(6) print(7) print(8) print(9) Even so, it would save me a lot of time typing to use a . Especially if I wanted to do the same thing or times. loop one thousand one million A in Python is written like this: "for loop" for i in range(0, 10): print(i) In English, the code says: Start with equals . ( ) i 0 i in range(0 If is not less than 10 ( ), exit the loop. i range(0, 10) Print to the console. ( ) i print(i) Add to . ( defaults to incrementing by 1) 1 i range Go back to step 2 The result is that the numbers are logged to the console in order. 0-9 Whitespace matters in Python! The body of a for-loop be indented, otherwise you'll get a syntax error. must Example This code print the numbers 0-9 to the console. for i in range(0, 10): print(i) Range Continued The function we've been using in our loops actually has an optional 3rd parameter: the "step". range() for for i in range(0, 10, 2): print(i) # prints: # 0 # 2 # 4 # 6 # 8 The "step" parameter determines how much to increment by in each iteration of the loop. You can even go backwards: i for i in range(3, 0, -1): print(i) # prints: # 3 # 2 # 1 F-strings in Python You can create a string with dynamic values by using in Python. It's a beautiful syntax that I wish more programming languages used. f-strings num_bananas = 10 print(f"You have {num_bananas} bananas") # You have 10 bananas The opening quotes need to be proceeded by an , then any variables within curly brackets have their values interpolated into the string. f Chapter 6: Lists A natural way to organize and store data is in the form of a . Some languages call them "arrays", but in Python we just call them lists. Think of all the apps you use and how many of the items in the app are organized into lists. List For example: A twitter feed is a list of posts An online store is a list of products The state of a chess game is a list of moves This list is a list of things that are lists Lists in Python are declared using square brackets, with commas separating each item: inventory = ["Iron Breastplate", "Healing Potion", "Leather Scraps"] Arrays can contain items of any data type, in our example above we have a of strings. List Vertical syntax Sometimes when we're manually creating lists it can be hard to read if all the items are on the same line of code. We can declare the array using multiple lines if we want to: flower_types = [ "daffodil", "rose", "chrysanthemum" ] Keep in mind this is just a styling change. The code will run correctly either way. Counting in Programming In the world of programming, counting is a bit strange! We don't start counting at , we start at instead. 1 0 Indexes Each item in an array has an index that refers to its spot in the array. Take the following array as an example: names = ["Bob", "Lane", "Alice", "Breanna"] Index 0: Bob Index 1: Lane Index 2: Alice Index 3: Breanna Indexing into Lists Now that we know how to create new lists, we need to know how to access specific items in the list. We access items in a list directly by using their . Indexes start at 0 (the first item) and increment by one with each successive item. The syntax is as follows: index best_languages = ["JavaScript", "Go", "Rust", "Python", "C"] print(best_languages[1]) # prints "Go", because index 1 was provided List length The length of a List can be calculated using the function. Again, we'll cover functions in detail later, but this is the syntax: len() fruits = ["apple", "banana", "pear"] length = len(fruits) # Prints: 3 The length of the list is equal to the number of items present. Don't be fooled by the fact that the length is not equal to the index of the last element, in fact it will always be one greater. List Updates We can also change the item that exists at a given index. For example, we can change to in the array in the following way: Leather Leather Armor inventory inventory = ["Leather", "Healing Potion", "Iron Ore"] inventory[0] = "Leather Armor" # inventory: ['Leather Armor', 'Healing Potion', 'Iron Ore'] Appending in Python It's common to create an empty list then fill it with values using a loop. We can add values to the end of a list using the method: .append() cards = [] cards.append("nvidia") cards.append("amd") # the cards list is now ['nvidia', 'amd'] Pop Values is the opposite of . Pop removes the last element from the array and returns it for use. For example: .pop() .append() vegetables = ["broccoli", "cabbage", "kale", "tomato"]; last_vegetable = vegetables.pop() # vegetables = ['broccoli', 'cabbage', 'kale'] # last_vegetable = 'tomato' Counting the items in a list Remember that we can iterate (count) over all the items in an array using a loop. For example, the following code will print each item in the array. sports for i in range(0, len(sports)): print(sports[i]) No-index Syntax In my opinion, Python has syntax for iterating directly over the items in a list without worrying about index numbers. If you don't need the index number you can use the following syntax: the most elegant trees = ['oak', 'pine', 'maple'] for tree in trees: print(tree) # Prints: # oak # pine # maple , the variable declared using the keyword, directly accesses the value in the array rather than the index of the value. If we don't need to update the item, and only need to access its value then this is a more clean way to write the code. tree in Find an item in a list Example of "no-index" or "no-range" syntax: for fruit in fruits: print(fruit) Modulo operator in Python The modulo operator can be used to find a remainder: For example, would be , because 2 can be multiplied evenly into 7 at most 3 times: 7 modulo 2 1 2 * 3 = 6 Then there is 1 to get from to . remaining 6 7 7 - 6 = 1 The d operator is the percent sign: . It's important to recognize modulo is a percentage though! That's just the symbol we're using. % not remainder = 8 % 3 # remainder = 2 An odd number is a number that when divided by , the remainder is . 2 not 0 Slicing lists Python makes it easy to slice and dice lists to work only with the section you care about. One way to do this is to use the simple slicing operator, which is just a colon . : With this operator, you can specify where to start and end the slice, and how to step through the original. List slicing returns a from the existing list. new list The syntax is as follows: Lst[ Initial : End : IndexJump ] scores = [50, 70, 30, 20, 90, 10, 50] # Display list print(scores[1:5:2]) # Prints [70, 20] The above reads as "give me a slice of the list from index 1, up to but not including 5, skipping every 2nd value. . scores All of the sections are optional scores = [50, 70, 30, 20, 90, 10, 50] # Display list print(scores[1:5]) # Prints [70, 30, 20, 90] scores = [50, 70, 30, 20, 90, 10, 50] # Display list print(scores[1:]) # Prints [70, 30, 20, 90, 10, 50] List Operations - Concatenate Concatenating two lists (smushing them together) is really easy in Python, just use the operator. + all = [1, 2, 3] + [4, 5, 6] print(all) # Prints: [1, 2, 3, 4, 5, 6] List Operations - Contains Checking whether a value exists in a list is also really easy in Python, just use the keyword. in fruits = ["apple", "orange", "banana"] print("banana" in fruits) # Prints: True Tip: Quotes within quotes To use quotes within quotes, they either need to be or you need to use the kind of quotes. Because we usually use double quotes, we can nest strings with single quotes: escaped other f"banana is in fruits list: {'banana' in fruits}" List deletion Python has a built-in keyword that deletes items from objects. In the case of a list, you can delete specific indexes or entire slices. del nums = [1, 2, 3, 4, 5, 6, 7, 8, 9] # delete the fourth item del nums[3] print(nums) # Output: [1, 2, 3, 5, 6, 7, 8, 9] # delete items from 2nd to 3rd nums = [1, 2, 3, 4, 5, 6, 7, 8, 9] del nums[1:3] print(nums) # Output: [1, 4, 5, 6, 7, 8, 9] # delete all elements nums = [1, 2, 3, 4, 5, 6, 7, 8, 9] del nums[:] print(nums) # Output: [] Tuples are collections of data that are ordered and unchangeable. You can think of a tuple as a with a fixed size. Tuples are created with round brackets: Tuples List my_tuple = ("this is a tuple", 45, True) print(my_tuple[0]) # this is a tuple print(my_tuple[1]) # 45 print(my_tuple[2]) # True While it's typically considered bad practice to store items of different types in a List it's not a problem with Tuples. Because they have a fixed size, it's easy to keep track of which indexes store which types of data. Tuples are often used to store very small groups (like 2 or 3 items) of data. For example, you might use a tuple to store a dog's name and age. dog = ("Fido", 4) Because Tuples hold their data, multiple tuples can be stored within a list. Similar to storing other data in lists, each tuple within the list is separated by a comma. my_tuples = [("this is the first tuple in the list", 45, True),("this is the second tuple in the list", 21, False)] print(my_tuples[0][0]) # this is the first tuple in the list Chapter 7: Functions Functions allow us to and code. For example, let's pretend we need to calculate the area of a circle. We can use the formula , or in code: reuse organize area = pi * r^2 r = 5 area = 3.14 * r * r This works great! The problem arises when multiple places in our code need to get the area of a circle r = 5 area1 = 3.14 * r * r r2 = 7 area2 = 3.14 * r2 * r2 r3 = 11 area3 = 3.14 * r3 * r3 We want to use the same code, why repeat the work? Let's declare a new function . Notice that the keyword is written before the function name, and tells the computer that we're declaring, or defining, a new function. area_of_circle() def def area_of_circle(r): return 3.14 * r * r The function takes one input (which can also be called a parameter or argument), and returns a single output. We give our function the radius of a circle and we get back the area of that circle! area_of_circle To use or " " the function we can pass in any number as the input, and capture the output into a new variable: call radius = 5 area = area_of_circle(radius) Let's talk through this code example step by step. The variable is created with a value of . radius 5 The function is called with a single argument: area_of_circle radius The function is executed, with being equal to area_of_circle r 5 The result of is returned from , which happens to be 3.14 * r * r area_of_circle 78.75 resolves to the returned value of area_of_circle(radius) 78.75 The variable is created with a value of area 78.75 Multiple Parameters Functions can have multiple parameters, or inputs: def subtract(a, b): return a - b Where to Declare Functions You've probably noticed that a variable needs to be declared it's used. For example, the following doesn't work: before print(my_name) my_name = 'Lane Wagner' It needs to be: my_name = 'Lane Wagner' print(my_name) Lines of code execute in , so a variable needs to be created before it can be used. That means that if you define a function, you can't call that function until after the definition. order from top to bottom The function is a convention used in many programming languages to specify the entrypoint of an application. By defining a single function, and only calling at the end of the entire program we ensure that all of our function are defined before they're called. main() main main() Order of functions All functions be defined before they're used. must You might think this would make structuring Python code difficult because the order in which the functions are declared can quickly become so dependent on each other that writing anything becomes impossible. As it turns out, most Python developers solve this problem by simply defining all the functions first, then finally calling the entrypoint function . If you do that, then the order that the functions are declared in . The entrypoint function is usually called "main". last doesn't matter def main(): func2() def func2(): func3() def func3(): print("I'm function 3") main() # entrypoint Scope Scope refers to a variable or function name is available to be used. For example, when we create variables in a function (by giving names to our parameters for example), that data is available outside of that function. where not For example: def subtract(x, y) return x - y result = subtract(5, 3) print(x) # ERROR! "name 'x' is not defined" When the function is called, we assign the variable to 5, but only exists in the code the function. If we try to print outside of that function then we won't get a result, in fact we'll get a big fat error. subtract x x within subtract x https://www.youtube.com/watch?v=CKv_WHCcR-w&embedable=true Global Scope So far we've been working in the global scope. That means that when we define a variable or a function, that name is accessible in in our program, even within other functions. every other place For example: pi = 3.14 def get_area_of_circle(radius): return pi * radius * radius Because was declared in the parent "global" scope, it is usable within the function. pi get_area_of_circle() Infinity The built-in function can be used to create a that represents the negative infinity value. I've added it for you as a starting point. float() numeric floating point value negative_infinity = float('-inf') positive_infinity = float('inf') None Return When no return value is specified in a function, (for example, maybe it's a function that prints some text to the console, but doesn't explicitly return a value) it will return . The following code snippets all return exactly the same thing: None def my_func(): print("I do nothing") return None def my_func(): print("I do nothing") return def my_func(): print("I do nothing") Parameters vs arguments Parameters are the names used for inputs when a function. Arguments are the names of the inputs supplied when a function is . defining called To reiterate, arguments are the actual values that go into the function, say , , or . Parameters are the names we use in the function definition to refer to those values, which at the time of writing the function, could be anything. 42.0 "the dark knight" True That said, it is important to understand that this is all semantics, and frankly developers are really lazy with these definitions. You'll often hear the words arguments and parameters used interchangeably. # a and b are parameters def add(a, b) return a + b # 5 and 6 are arguments sum = add(5, 6) Multiple return values In Python, we can return more than one value from a function. All we need to do is separate each value by a comma. # returns email, age, and status of the user def get_user(): return "name@domain.com", 21, "active" email, age, status = get_user() print(email, age, status) # Prints: "name@domain.com 21 active" def get_user(): return "name@domain.com", 21, "active" # this works, and by convention you should NOT use the underscore variable later email, _, _ = get_user() print(email) # Prints: "name@domain.com" print(_) # Prints: "active" Default values for function arguments Python has a way to specify a default value for function arguments. This can be convenient if a function has arguments that are essentially "optional", and you as the function creator want to use a specific default value in case the caller doesn't provide one. A default value is created by using the assignment ( ) operator in the function signature. = def get_greeting(email, name="there"): return f"Hello {name}, welcome! You've registered your email: {email}" msg = get_greeting("lane@example.com", "Lane") # Hello Lane, welcome! You've registered your email: lane@example.com msg = get_greeting("lane@example.com") # Hello there, welcome! You've registered your email: lane@example.com If the second parameter is omitted, the default value will be used in its place. As you may have guessed, for this structure to work, optional arguments that have defaults specified come all the required arguments. "there" after Chapter 8: Dictionaries Dictionaries in Python are used to store data values in -> pairs. Dictionaries are a great way to store groups of information. key value car = { "brand": "Tesla", "model": "3", "year": 2019 } Duplicate keys Because dictionaries rely on unique keys, you can't have two of the same key in the same dictionary. If you try to use the same key twice, the associated value will simply be overwritten. Accessing Dictionary Values Dictionary elements must be accessible somehow in code, otherwise they wouldn't be very useful. A value is retrieved from a dictionary by specifying its corresponding key in square brackets. The syntax looks similar to indexing into a list. car = { 'make': 'tesla', 'model': '3' } print(car['make']) # Prints: tesla Setting Dictionary Values You don't need to create a dictionary with values already inside. It is common to create a blank dictionary then populate it later using dynamic values. The syntax is the same as getting data out of a key, just use the assignment operator ( ) to give that key a value. = names = ["jack bronson", "jill mcarty", "john denver"] names_dict = {} for name in names: # .split() returns a list of strings # where each string is a single word from the original names_arr = name.split() # here we update the dictionary names_dict[names_arr[0]] = names_arr[1] print(names_dict) # Prints: {'jack': 'bronson', 'jill': 'mcarty', 'john': 'denver'} Updating Dictionary Values If you try to set the value of a key that already exists, you'll end up just updating the value of that key. names = ["jack bronson", "james mcarty", "john denver"] names_dict = {} for name in names: # .split() returns a list of strings # where each string is a single word from the original names_arr = name.split() # we're always setting the "jack" key names_dict["jack"] = names_arr[1] print(names_dict) # Prints: {'jack': 'denver'} Deleting Dictionary Values You can delete existing keys using the keyword. del names_dict = { 'jack': 'bronson', 'jill': 'mcarty', 'joe': 'denver' } del names_dict['joe'] print(names_dict) # Prints: {'jack': 'bronson', 'jill': 'mcarty'} Deleting keys that don't exist Notice that if you try to delete a key that doesn't exist, you'll get an . error names_dict = { 'jack': 'bronson', 'jill': 'mcarty', 'joe': 'denver' } del names_dict['unknown'] # ERROR HERE, key doesn't exist Checking for existence If you're unsure whether or not a key exists in a dictionary, use the keyword. in cars = { 'ford': 'f150', 'tesla': '3' } print('ford' in cars) # Prints: True print('gmc' in cars) # Prints: False Iterating over a dictionary in Python fruit_sizes = { "apple": "small", "banana": "large", "grape": "tiny" } for name in fruit_sizes: size = fruit_sizes[name] print(f"name: {name}, size: {size}") # name: apple, size: small # name: banana, size: large # name: grape, size: tiny Ordered or Unordered? As of Python version , dictionaries are . In Python and earlier, dictionaries were . 3.7 ordered 3.6 unordered Because dictionaries are ordered, the items have a defined order, and that order will change. not Unordered means that the items used to have a defined order, so you couldn't refer to an item by using an index. not The takeaway is that if you're on Python or later, you'll be able to iterate over dictionaries in the same order every time. 3.7 Chapter 9: Sets Sets are Lists, but they are and they guarantee uniqueness. There can be no two of the same value in a set. like unordered fruits = {'apple', 'banana', 'grape'} print(type(fruits)) # Prints: <class 'set'> print(fruits) # Prints: {'banana', 'grape', 'apple'} Adding values to a set fruits = {'apple', 'banana', 'grape'} fruits.add('pear') print(fruits) # Prints: {'banana', 'grape', 'pear', 'apple'} Empty set Because the syntax creates an empty dictionary, to create an empty set, just use the function. {} set() fruits = set() fruits.add('pear') print(fruits) # Prints: {'pear'} Iterate over values in a set (order is not guaranteed) fruits = {'apple', 'banana', 'grape'} for fruit in fruits: print(fruit) # Prints: # banana # grape # apple Removing values from a set fruits = {'apple', 'banana', 'grape'} fruits.remove('apple') print(fruits) # Prints: {'banana', 'grape'} Chapter 10: Errors You've probably encountered some errors in your code from time to time if you've gotten this far in the course. In Python, there are two main kinds of distinguishable errors. syntax errors exceptions Syntax errors You probably know what these are by now. A syntax error is just the Python interpreter telling you that your code isn't adhering to proper Python syntax. this is not valid code, so it will error If I try to run that sentence as if it were valid code I'll get a syntax error: this is not valid code, so it will error ^ SyntaxError: invalid syntax Exceptions Even if your code has the right syntax however, it may still cause an error when an attempt is made to execute it. Errors detected during execution are called "exceptions" and can be handled gracefully by your code. You can even raise your own exceptions when bad things happen in your code. Python uses a try-except pattern for handling errors. try: 10 / 0 except Exception as e: print(e) # prints "division by zero" The block is executed until an exception is raised or it completes, whichever happens first. In this case, a "divide by zero" error is raised because division by zero is impossible. The block is only executed if an exception is raised in the block. It then exposes the exception as data ( in our case) so that the program can handle the exception gracefully without crashing. try except try e Raising your own exceptions Errors are something to be scared of. Every program that runs in production is expected to manage errors on a constant basis. Our job as developers is to handle the errors gracefully and in a way that aligns with our user's expectations. not Errors are NOT bugs https://www.youtube.com/watch?v=k23hjyvvhcA&embedable=true When something in our own code happens that we don't expect, we should raise our own exceptions. For example, if someone passes some bad inputs to a function we write, we should not be afraid to raise an exception to let them know they did something wrong. An or is raised when something bad happens, but as long as our code handles it as users expect it to, it's a bug. A bug is when code behaves in ways our users don't expect it to. error exception not For example, if a player tries to forge an iron sword out of bronze metal, we might raise an exception and display an error message to the player. However, that's the expected behavior of the game, so it's not a bug. If a player can forge the iron sword out of bronze, that may be considered a bug because that's against the rules of the game. raise Exception("something bad happened") Software applications aren't perfect, and user input and network connectivity are far from predictable. Despite intensive debugging and unit testing, applications will still have failure cases. Loss of network connectivity, missing database rows, out of memory issues, and unexpected user inputs can all prevent an application from performing "normally". It is your job to catch and handle any and all exceptions gracefully so that your app keeps working. When you are able to detect that something is amiss, you should be raising the errors yourself, in addition to the "default" exceptions that the Python interpreter will raise. raise Exception("something bad happened") #Different types of exceptions We haven't covered classes and objects yet, which is what an really is at its core. We'll go more into that in the object-oriented programming course that we have lined up for you next. Exception For now, what is important to understand is that there are different types of exceptions and that we can differentiate between them in our code. More syntax for errors try: 10/0 except ZeroDivisionError: print("0 division") except Exception: print("unknown exception") try: nums = [0, 1] print(nums[2]) except ZeroDivisionError: print("0 division") except Exception: print("unknown exception") Which will print: 0 division unknown exception Chapter 11: Python Facts The Zen of Python Tim Peters, a long time Pythonista describes the guiding principles of Python in his famous short piece, . The Zen of Python Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than now. right If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those! Why Python? Here are some reasons we think Python is a future-proof choice for developers: Easy to read and write - Python reads like plain English. Due to its simple syntax, it's a great choice for implementing advanced concepts like AI. This is arguably Python's . best feature Popular - According to the Stack Overflow Developer Survey, coding language in 2020. Python is the 4th most popular Free - Python, like many languages nowadays, is developed under an open-source license. It's free to install, use, and distribute. Portable - Python written for one platform will work on any other platform. Interpreted - Code can be executed as soon as it's written. Because it doesn't need to take a long time to compile like Java, C++, or Rust, releasing code to production is typically faster. Why not Python? Python might not be the best choice for a project if: The code needs to run fast. Python code executes very slowly, which is why performance critical applications like PC games aren't written in Python. The codebase will become large and complex. Due to its dynamic type system, Python code can be harder to keep clean of bugs. The application needs to be distributed directly to non-technical users. They would have to install Python in order to run your code, which would be a huge inconvenience. Python 2 vs Python 3 One thing that's important to keep in mind as you continue your Python journey is that the Python ecosystem suffers from split personality syndrome. Python 3 was released on December 3rd, 2008, but over a decade later the web is still full of Python 2 dependencies, scripts and tutorials. In this course, - just like any good citizen should these days. we used Python 3 One of the most obvious breaking changes between Python 2 and 3 is the syntax for printing text to the console. Python 2 print "hello world" Python 3 print("hello world") Congratulations on making it to the end! If you're interested in doing the interactive coding assignments and quizzes for this course you can check out the . Learn Python course over on Boot.dev That course is a part of my full , made up of other courses and projects if you're interested in checking those out. back-end developer career path Also published . here