Day 0
Learning
Some notes about Learning
Functions
Functions are a grouping of instructions.
tip: functions can be as large as you want, but it's generally a good idea that functions should do one thing.
tip: Give functions descriptive names. Usually verbs are good for function names.
def greet(name):
return 'Hello {}'.format(name)
Anatomy of a Function
Let's analyze our hello
function.
def greet(name) -> str:
return 'Hello {}'.format(name)
greet('Dustin')
def
- keyword to define a functiongreet
- the functions name(name)
- the arguments (i.e. what we pass into the function)-> str
- return type declaration (optional)- function body - the set of instructions inside the function
- return statement (optional)
greet('Dustin')
- function call
Operators
Branching
In programming branching refers to when the processing flow of a program can go one way or another.
Basically, if conditions.
if False:
print("The first block of code ran")
elif True:
print("The second block of code ran")
else:
print("The third block of code ran")
Recursion
Recursion is when a function calls itself until it doesn't.
To achieve this, you will have a base case that must eventually get called.
for example:
def recurse(num):
if num == 10:
return
print(num)
return recurse(num+1)
The base case is if num == 10
. If the base case is not met, we call the function again, except we increase the passed in number by 1.
Exercises
Hello, World
Write a program that prints ‘Hello World’ to the screen.
Guessing Game
Write a guessing game where the user has to guess a secret number. After every guess the program tells the user whether their number was too large or too small. At the end the number of tries needed should be printed. It counts only as one try if they input the same number multiple times consecutively.
FizzBuzz
Write a program that prints out all numbers from 1 to 100. If the number is divisible by 3, print out Fizz. If the number if divisible by 5, print out Buzz.
Tips
Try to avoid nesting
You won't be able to avoid nesting entirely...
It may help you think about how to write the function if handle your edge cases at the top. Then the thing
that the function actually does would be at the end of the function.
This can reduce the amount of nesting and make it easier for someone to figure out what the function actually does.
If you're finding yourself wanted to do a bunch of nesting in the function, it may be an indication that you need to write additional functions.
e.g.
def is_odd(num):
return num % 2 != 0
def print_numbers(current_number):
if current_number == 100:
return
if is_odd(current_number):
print('\033[92m', end='')
else:
print('\033[94m', end='')
print(current_number)
print_numbers(current_number+1)
print_numbers(1)
Try to make it human readable
“... Clean code reads like well-written prose..." -- Grady Booch author of Object
Oriented Analysis and Design with
Applications”
It's important to try to communicate what the code does in a human readable way.
Rather than writing something like
if num % 2 != 0:
// do something
it would read better as:
if is_odd(num):
// do something
Referential Transparency
This is some fancy terminology.
Referential Transparency = given the same inputs, the function will always produce the same output.
e.g.
def add2(num) -> int:
return num + 2
add2(2)
If I pass 2 into the add2
function, it will always return 4.
This function is simple and easy to test.
Avoid side effects
It's ideal that your functions don't produce side effects.
A side effect is when your function reaches outside to of itself and modifies something.
You won't be able to entirely avoid side effects and you probably don't want to.
Writing functions that don't have side effects makes your program easier to test and can help you avoid confusion as you write your programs.