# Noemi Cabrera
# 16 November 2021
# In this lesson, I learned how to import the math and random python modules. Using the math module, I computed mathematical expressions,
# recognized the effect of operator precedence, and rounded real numbers to the nearest integer with the floor,ceiling, & trunchate functions.
# Using the random module, I generated (pseudo-)random integers using randint() and randrange(), selected a random element from a list
# with the choice() function, and shuffled the elements of a list with the shuffle() function.
# I didn't have any major diffulties in this lesson.

# In this code, the math module/library is imported using the import keyword. Then the integer -5 is assigned to the variable 'x'
# Then, the fabs function from the math library is used to return the float absolute value of -5.
import math
x = -5
math.fabs(x)

# In this code, the math module/library is imported and renamed to 'ml'. Then the integer 12 is assigned to the variable 'y'
# Then, the fabs function from the math library is used to return the float absolute value of 12.
import math as ml
y = 12
ml.fabs(y)

# In this code, just the fabs function is imported from the math module/library.
# Then, the fabs function from the math library is used to return the float absolute value of -5.
from math import fabs
fabs(-5)

# In this code, the math module/library is imported. Then, the gcd function from the math library is used to calculate
# the greates common divisor of 16 and 28.
# [ ] Import the math module and use an appropriate function to find the greatest common divisor of 16 and 28
import math
math.gcd(16,28)

# In this code, the only the gcd function is imported from the math library. This function is used to find the greater
# common divors of 2 positive integers the user enters.
# [ ] Prompt the user to input 2 positive integers then print their greatest common divisor
from math import gcd
pos_int = int(input("Enter a positive integer:"))
pos_int2 = int(input("Enter another positive integer"))
print(gcd(pos_int,pos_int2))

# In this code, just the sqrt(square root) function is imported from the math module. Then, this function is
# used to find the quare root of the a raised to the sencond plus b raised to the second power. This is stored
# in the variable h and the result is printed.
from math import sqrt
a = 3
b = 4
h = sqrt(a ** 2 + b ** 2)
print(h)

# In this code, the modulo operator(%) is used to find the remainder of the division of a number by 2. If the remainder is
# 0, this indicates the number is even. If remainder is greater than 0, then the number is odd.
# Even number (print 0)
print(102 % 2)
# Odd Number (print 1)
print(77 % 2)

# In this code, the function is_even is defined and takes 1 argument 'n'. This function returns True if the
# remainder of diving the number by 2 is 0. If not, the function returns False. Lastly, this function is tested
# by entering number 5 as an argument, which displays is an odd number since there is a reminder when you
# divide it by 2.
# [ ] Fill out the function is_even with a code block that returns True if n is even and returns False if n is odd
def is_even(n):
#TODO
if n % 2 == 0:
return True
else:
return False
# Test the function
x = 5
if is_even(x):
print("Number is even")
else:
print("Number is odd")

# In this code, the is_even function is defined and takes 1 argument 'n'. This function returns True if the
# remainder of the division of the number "n" by 2 equal 0. If the d=reminder doesn't equal 0, then the
# function returns false. Lastly, the sqrt function is imported from the math libreary and a for..in loop
# iterates through the list 'l'. Each of the numbers is checked if they're even by using the is_even function.
# If number is even, then the result of the square root of that number is displayed. If number is not even,
# then nothings happens with that number.
# [ ] Use the function is_even to print the square root of all the even numbers in the following list
l = [25, 34, 193, 2, 81, 26, 44]
def is_even(n):
return (n % 2) == 0
#TODO
from math import sqrt
for e_num in l:
if is_even(e_num) == True:
s_num = sqrt(e_num)
print(s_num)
else:
pass

# In this code, a math operation is done. The multiplication happens first and then the sum because it has
# a higher precedence.
5 + 2 * 8

# In this code, a math operation is done. The sum in parentheses is done first and then the multiplication
# because parentheses have a higher precedence.
(5 + 2) * 8

# In this code, the multiplication should happen first and then the divison. The result is a float, but it's not the
# correct answer, which is 1..
12 / 4 * 3

# To fix the issue in the above cell, we can put that multiplicationin parentheses so that it happens first
# and then the division. This results in 1.
# Method 1
12 / (4 * 3)

# Another way to fix the issue in the above cell is to divide all the numbers. The divisions starting from left to right
# are performed and the result is 1.
# Method 2
12 / 4 / 3

# The result of the original operation 4 + 16 / 2 was 12, but we want it to be 10. Therefore, to fix this, I
# place 4+16 in parentheses. This way the sum happens first and then teh division, which gives us 10 as a result.
# [ ] Correct the following expression so the answer is 10
(4 + 16) / 2

# The result of the original operation 2 * 3 + 2 ** 3 was 14, but we want it to be 250. Therefore, to fix this, I
# placed 3+2 in parentheses. This way the sum happens first and then the result is raised to the thrid power, which
# gets multiplied by 2 and gives us 250 as a result.
# [ ] Correct the following expression so the answer is 250; review the operator precedence table and use only one () pair
2* (3 + 2)** 3

# In this code, the floor, ceil, and trunc functions are imported from the math library. Then floor() is used
# to round the float of diving 213/2 down.
from math import floor, ceil, trunc
prize = 213
option1 = floor(213 / 2)
print("You get", option1, " and your friend gets ", prize - option1)

# In this code, the floor, ceil, and trunc functions are imported from the math library. Then ceil() is used
# to round the float of diving 213/2 up.
from math import floor, ceil, trunc
prize = 213
option2 = ceil(213 / 2)
print("You get", option2, " and your friend gets ", prize - option2)

# In this code, the function floor is used to round down the number 75.34, which results in 75. On the other hand,
# the ceil function is used to round up the number 75.34, which results in 76.
# [ ] Use an appropriate rounding function to round 75.34 to 75 and then to 76
import math
x = 75.34
print(math.floor(x))
print(math.ceil(x))

# In this code, the orginal price ouput was 869.99... However, we need it to be 870.To fix this, I imported the
# math module and used the ceil function to round up the total price, which results in 870.
# [ ] Use an appropriate rounding function to fix the following `float` error
import math
# Price of a chocolate box
p = 4.35
# Quantity needed
q = 200
# Order total price (Should be 4.35 * 200 = $870.00)
total = p * q
print("Total price: ", math.ceil(total))

# In this code, the randint function is imported from the random module. This function generates a random number
# ranging from 1 through 10, including the start and stop values too.
from random import randint
print(randint(1, 10))

# In this code, the randrange function is imported from the random module. This function generates a random number
# ranging from 1 through 10, including the start but not the stop value of 11.
from random import randrange
print(randrange(1, 11))

# In this code, the randrange function is imported from the random module. This function generates a random number
# ranging from 1 through 10 with a step of 2, including the start but not the stop value of 11.
# In this case, this function has 3 arguments: the start, stop, and step value.
from random import randrange
print(randrange(1, 11, 2))

# In this code, the randint function is imported from the random module.
# The die_roller() function is defined and returns a random number ranging from 1 through 6, including the start
# and stop values too because the randint() function is used.Laslty, the function is called and a random
# number displays.
from random import randint
def die_roller ():
return (randint(1, 6))
# roll a die
print(die_roller())

# In this code, the randrange function is imported from the random module. The odd_random() function is defined and returns
# a random number ranging from 1 through 102 with a step of 2, including the start but not the stop value of 102.
# In this case, this function has 3 arguments: the start, stop, and step value.Lastly, the function is called
# and a random number is displayed.
from random import randrange
def odd_random():
return (randrange(1, 102, 2))
# Generate an odd random integer
print(odd_random())

# The die_roller() function is defined and returns a random number ranging from 1 through 6, including the start
# but not the stop value because the randrange() function is used. Lastly, the function is called and a random
# number displays.
# [ ] Modify the die_roller() function to use randrange instead of randint
from random import randint
def die_roller ():
return (randrange(1, 7))
# roll a die
print(die_roller())

# In this code, the randint function is imported from the random module. The odd_random() function is defined and returns
# a random number ranging from 1 through 101, including the start and stop values.
# Lastly, the function is called and a random number is displayed.
# [ ] Modify the odd_random() function to use randint instead of randrange
from random import randrange
def odd_random():
return (randint(1, 101))
# Generate an odd random integer
print(odd_random())

# In this code, the randint function is imported from the random module. The die_roller() function is defined and returns
# a random number ranging from 1 through 6, including the start and stop values. This function is called
# in the next defined dice_roller function, which returns two random numbers ranging from 1 to 6.
# Lastly, the 2 random numbers are displayed.
# [ ] Complete the function dice_roller() so it rolls 2 dice
# Use the die_roller function
from random import randint
def die_roller():
return(randint(1, 6))
def dice_roller():
#TODO
return(randint(1, 6) , die_roller())
print(dice_roller())

# In this code, the choice function is imported from the random module. This function randomly chooses an item of
# the options list in the RPS() function. This item is returned by the function, which is later called and the
# the item is printed.
from random import choice
# Select Rock, Paper, or Scissors
def RPS():
options = ['Rock', 'Paper', 'Scissors']
# return one of the elements at random
return (choice(options))
# Generate an option
print(RPS());

# In this code, the shuffle function is imported from the random module. This function is used to shuffle the
# items in the 'x' list. The shuffled list is then printed.
from random import shuffle
x = ['Ana', 'John', 'Mike', 'Sally']
shuffle(x)
print(x)

# In this code, the choice function is imported from the random module. IN the pick_card() defined function, 'choice'
# is used to randomly select an item from the card_type and card_number list. Then, pick_card() returns a
# list with the random car number followed by the random card type. Lastly, the function is called and the list displays.
from random import choice
def pick_card():
card_type = ['Clubs', 'Diamonds', 'Hearts', 'Spades'];
card_number = ['Ace', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'Jack', 'Queen', 'King']
# choose a type at random
t = choice(card_type)
n = choice(card_number)
return [n, t]
# Show the randomly picked card
print(pick_card())

# In this code, the shuffle function is imported from the random module. IN the pick_card() defined function, 'shuffle'
# is used to randomly shuffle the items in the card_type and card_number list. Then, pick_card() returns the shuffled lists.
# Lastly, the function is called and the lists display.
# [ ] Modify the pick_card() function to use `shuffle` instead of choice
from random import shuffle
def pick_card():
card_type = ['Clubs', 'Diamonds', 'Hearts', 'Spades'];
card_number = ['Ace', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'Jack', 'Queen', 'King']
# choose a type at random
shuffle(card_type)
shuffle(card_number)
return print(card_type , "\n" , card_number)
# Show the randomly picked card
pick_card()

# In this code, the random module is imported. Then, using the choice function from the module, a city/item from
# the cities list is selected randomly. Lastly, the random city is displayed.
# [ ] The following list contain the 10 most populous American cities; write code to randomly select one of the cities to visit
cities = ["New York", "Los Angeles", "Chicago", "Houston", "Phoenix", "Philadelphia", "San Antonio", "San Diego", "Dallas", "San Jose"]
import random
city = random.choice(cities)
print(city)