COSC 301 Review class#

Review Session Outline#

  1. Writing For loops from scratch

    • Practice Questions

  2. Writing Assert statements

  3. Difference between try/except and assert

  4. Defining functions in a .py file

  5. Method Chaining

  6. GroupBy vs. Merge

## Data and imports

import pandas as pd
import seaborn as sns
import numpy as np

pokemon = pd.read_csv('https://github.com/firasm/bits/raw/master/pokemon.csv')
pokemon.head()
# Name Type 1 Type 2 Total HP Attack Defense Sp. Atk Sp. Def Speed Generation Legendary
0 1 Bulbasaur Grass Poison 318 45 49 49 65 65 45 1 False
1 2 Ivysaur Grass Poison 405 60 62 63 80 80 60 1 False
2 3 Venusaur Grass Poison 525 80 82 83 100 100 80 1 False
3 3 VenusaurMega Venusaur Grass Poison 625 80 100 123 122 120 80 1 False
4 4 Charmander Fire NaN 309 39 52 43 60 50 65 1 False

Writing for loops from scratch#

numbers = [1, 3, 4, 6, 81, 80, 100, 95]
# Your solution here

# Notes on how to write my for loop

# 1. loop over all numbers and print them (`for`)
# 2. write a conditional statement to see if the number is even or odd (`%2==0`)
# 3. write a conditional statement to see if the number is divisible by 5 (`%5 == 0)
# 4. add to `my_list` the appropriate string (`.append`)


# full solution

my_list = []
for i in numbers:
    if (i%5 == 0): # checks if num is divisible by 5
        if (i%2 == 0):
            my_list.append('five even')
        else:
            my_list.append('five odd')

    elif (i % 2 == 0) and (i % 5 !=0): # checks if num is even and NOT divisible by 5
        my_list.append('even')

    elif (i % 2 != 0) and (i % 5 !=0): # checks if num is odd and NOT divisible by 5
        my_list.append('odd')


# point 1

# for i in numbers:
#     print(i)

# point 2

# for i in numbers:
#     if (i%2 == 0):
#         print(i,'even')
#     else:
#         print(i,'odd')
        
# point 3

# for i in numbers:
#     if (i%5 == 0):
#         print(i,'divisble by 5')
#     else:
#         print(i,'NOT divisble by 5')

# point 4

# my_list = []

# for i in numbers:
#     if (i%5 == 0):
#         my_list.append('divisble by 5')
#     else:
#         my_list.append('NOT divisble by 5')
        
# my_list
assert my_list == ['odd', 'odd', 'even', 'even', 'odd', 'five even', 'five even', 'five odd']

Writing Assert statements#

test = ['1','2',3,4,5]
ans = [1,2,3,4,5]

assert test == ans, "Helium baloons fly" #Left side isn't the same as the right side
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
Cell In[6], line 4
      1 test = ['1','2',3,4,5]
      2 ans = [1,2,3,4,5]
----> 4 assert test == ans, "Helium baloons fly" #Left side isn't the same as the right side

AssertionError: Helium baloons fly
# method 1
for i,t in enumerate(test):
    test[i] = int(t)
    
test

assert test == ans, "Failure! Left != Right"
# method 2

assert [int(t) for t in test] == ans, "Failure! Left != Right"

Difference between try/except and assert#

num1 = 5
num2 = 0

def make_larger(n,denominator):
    """ Makes the number larger """
    
    #assert num2 != 0, "You provided 0 as the denominator - you are a terrible person"
    ret = np.nan
    try:
        ret = n**2 / denominator
    except ZeroDivisionError as e:
        print("You provided 0 as the denominator - you are a terrible person")
        raise e
    finally:
        print("Don't worry, you are the best coder in the history of the coders")
        return ret
make_larger(num1,num2)
You provided 0 as the denominator - you are a terrible person
Don't worry, you are the best coder in the history of the coders
nan

Defining functions in a .py folder#

# first, create a .py file (NOT a .ipynb file) to add your functions

# next, import that .py file:

import my_functions as mf

# next, you can now use the functions in the .py file

mf.make_larger2(10,4)
Don't worry, you are the best coder in the history of the coders
104

Method Chaining#

pokemon.head()
# Name Type 1 Type 2 Total HP Attack Defense Sp. Atk Sp. Def Speed Generation Legendary
0 1 Bulbasaur Grass Poison 318 45 49 49 65 65 45 1 False
1 2 Ivysaur Grass Poison 405 60 62 63 80 80 60 1 False
2 3 Venusaur Grass Poison 525 80 82 83 100 100 80 1 False
3 3 VenusaurMega Venusaur Grass Poison 625 80 100 123 122 120 80 1 False
4 4 Charmander Fire NaN 309 39 52 43 60 50 65 1 False
pokemon = (pokemon
    .rename(columns={"Type 1": "t1"})
    .rename(columns={"Type 2": "t2"})
    .rename(columns={"Total": "tot"})
)

pokemon.head()
# Name t1 t2 tot HP Attack Defense Sp. Atk Sp. Def Speed Generation Legendary
0 1 Bulbasaur Grass Poison 318 45 49 49 65 65 45 1 False
1 2 Ivysaur Grass Poison 405 60 62 63 80 80 60 1 False
2 3 Venusaur Grass Poison 525 80 82 83 100 100 80 1 False
3 3 VenusaurMega Venusaur Grass Poison 625 80 100 123 122 120 80 1 False
4 4 Charmander Fire NaN 309 39 52 43 60 50 65 1 False
pokemon = (pokemon
    .rename(columns={"Type 1": "t1",
                     "Type 2": "t2",
                     "Total": "tot"})
)

pokemon.head()
# Name t1 t2 tot HP Attack Defense Sp. Atk Sp. Def Speed Generation Legendary
0 1 Bulbasaur Grass Poison 318 45 49 49 65 65 45 1 False
1 2 Ivysaur Grass Poison 405 60 62 63 80 80 60 1 False
2 3 Venusaur Grass Poison 525 80 82 83 100 100 80 1 False
3 3 VenusaurMega Venusaur Grass Poison 625 80 100 123 122 120 80 1 False
4 4 Charmander Fire NaN 309 39 52 43 60 50 65 1 False

GroupBy vs. Merge#

gb_df = pokemon.groupby('t1').sum()#.reset_index()[['t1','tot','HP','Attack']]
gb_df
# tot HP Attack Defense Sp. Atk Sp. Def Speed Generation Legendary
t1
Bug 23080 26146 3925 4897 4880 3717 4471 4256 222 0
Dark 14302 13818 2071 2740 2177 2314 2155 2361 125 2
Dragon 15180 17617 2666 3588 2764 3099 2843 2657 124 12
Electric 15994 19510 2631 3040 2917 3961 3243 3718 144 4
Fairy 7642 7024 1260 1046 1117 1335 1440 826 70 1
Fighting 9824 11244 1886 2613 1780 1434 1747 1784 91 0
Fire 17025 23820 3635 4408 3524 4627 3755 3871 167 5
Flying 2711 1940 283 315 265 377 290 410 22 2
Ghost 15568 14066 2062 2361 2598 2539 2447 2059 134 2
Grass 24141 29480 4709 5125 4956 5425 4930 4335 235 3
Ground 11401 14000 2361 3064 2715 1807 2008 2045 101 4
Ice 10165 10403 1728 1746 1714 1861 1831 1523 85 2
Normal 31279 39365 7573 7200 5865 5470 6245 7012 299 2
Poison 7050 11176 1883 2091 1927 1692 1803 1780 71 0
Psychic 21706 27129 4026 4073 3858 5609 4918 4645 193 14
Rock 17280 19965 2876 4086 4435 2787 3321 2460 152 4
Steel 11957 13168 1761 2503 3412 1823 2177 1492 104 4
Water 33946 48211 8071 8305 8170 8379 7898 7388 320 4
gb_df2 = pokemon.groupby('t1').sum().reset_index()[['t1','tot','HP','Attack']]
t1 tot HP Attack
0 Bug 26146 3925 4897
1 Dark 13818 2071 2740
2 Dragon 17617 2666 3588
3 Electric 19510 2631 3040
4 Fairy 7024 1260 1046
5 Fighting 11244 1886 2613
6 Fire 23820 3635 4408
7 Flying 1940 283 315
8 Ghost 14066 2062 2361
9 Grass 29480 4709 5125
10 Ground 14000 2361 3064
11 Ice 10403 1728 1746
12 Normal 39365 7573 7200
13 Poison 11176 1883 2091
14 Psychic 27129 4026 4073
15 Rock 19965 2876 4086
16 Steel 13168 1761 2503
17 Water 48211 8071 8305