<jupyter_start><jupyter_text>Chapter 5: Functions I - In the context of programming, a function is a named sequence of statements that performs a computation.- The specific name that we can call a function is called **name**.- The function input is called **argument**. - The result is called the **return value**.For example:<jupyter_code>type(32)
type('32')<jupyter_output><empty_output><jupyter_text>the function name, argument and return value are **type, 32 and int**, respectively.   Flow of executionIn order to ensure that a function is defined before its first use, you have to know the order in which statements are executed, which is called the flow of execution.  Parameters and arguments- Some of the built-in functions we have seen require arguments. For example, when you call math.sin you pass a number as an argument. - Some functions take more than one argument: math.pow takes two, the base and the exponent.- Inside the function, the arguments are assigned to variables called parameters.  Why functions?It may not be clear why it is worth the trouble to divide a program into functions. There are several reasons:1. Creating a new function gives you an opportunity to name a group of statements, which makes your program easier to read, understand, and debug.2. Functions can make a program smaller by eliminating repetitive code. Later, if you make a change, you only have to make it in one place.3. Dividing a long program into functions allows you to debug the parts one at a time and then assemble them into a working whole.4. Well-designed functions are often useful for many programs. Once you write and debug one, you can reuse it.  Built-in Functions<jupyter_code>lst = [12, 20, 3, 94, 33]
print('min = ', min(lst))
print('Max = ', max(lst))
print('Length = ', len(lst))
print('Summation = ', sum(lst))<jupyter_output>min =  3
Max =  94
Length =  5
Summation =  162<jupyter_text>Type Conversion Functions- int- str- float  Math Functions<jupyter_code>import math
dir(math)
pi = math.pi
pi
math.sin(30) # input is in form of radian and not degree.
deg = 30
rad = deg / 360.0 * 2 * pi  #convert from degrees to radians, divide by 360 and multiply by 2π:
math.sin(rad)
deg = 45
rad = deg / 360.0 * 2 * pi  #convert from degrees to radians, divide by 360 and multiply by 2π:
math.sin(rad)
math.sqrt(2)/2
# import cos method from math
from math import exp, cos, log
exp(0), log(pi), cos(rad)
math.floor(2.001), math.floor(2.999999), math.ceil(2.001), math.ceil(2.9999)
math.floor(-2.001), math.floor(-2.999999), math.ceil(-2.001), math.ceil(-2.9999)<jupyter_output><empty_output><jupyter_text>Random Numbers<jupyter_code>import random
dir(random)
help(random.random)
for i in range(10):
    x = random.random() 
    print(x)
while True:
    a = input('Enter a: ')
    if a == 'done': break
    b = input('Enter b: ')
    if a >= b:
        print('Wrong Order!')
        continue
    else:
        try:
            a = int(a)
            b = int(b)
            for i in range(5):
                x = random.random()
                x = math.floor(a + (b-a) * x)
                print(x)

        except:
            print('Wrong Numbers!')
random.randint(5, 20)
for i in range(20):
    print(random.randint(10, 100))
x = 50
while (x >= 15):
    x = random.randint(1,100)
    print(x)
t = [1, 2, 3, 10, 26, 46, 65]
random.choice(t)<jupyter_output><empty_output><jupyter_text>Adding a New Functions<jupyter_code>first = input('Enter Your First Name: ')
last = input('Enter Your Last Name: ')
email = input('Enter Your email Address: ')
d = {(first,last):email}
print(d)
d = dict()
while True:
    first = input('Enter Your First Name: ')
    if first == 'done': 
        break
    last = input('Enter Your Last Name: ')
    email = input('Enter Your email Address: ')
    d[(first,last)] = email
    
print(d)
def add_nums(a = 2,b = 6):
    try:
        a = int(a)
        b = int(b)
        c = a+b
    except:
        c = 'numbers are not integer'
    return c
add_nums(2,5)
add_nums(6)
def make_dictionary(email,first,last):
    d = {}
    d[(first,last)] = email
    return d
make_dictionary
make_dictionary('<EMAIL>', d = {('Armin','G'): '<EMAIL>'})
make_dictionary(first = 'Sahar', email = '<EMAIL>', last = 'Monfared')
d = dict()
while True:
    first = input('Enter Your First Name: ')
    if first == 'done': 
        break
    last = input('Enter Your Last Name: ')
    email = input('Enter Your email Address: ')
    make_dictionary(d,first,last,email)
    
print(d)<jupyter_output>Enter Your First Name: done
{}<jupyter_text>Exe: Imporve your Function<jupyter_code># Write a Python function to find the Max of three numbers.
def find_max(lst):
    return max(lst)
lst = list()
for i in range(15):
    lst.append(random.randint(1, 10000000))
lst
# write a function that take a list as input and return the multiplication of its elements
def mult_all(lst):
    multi = 1
    for item in lst:
        multi = multi * item
    return multi
# test
lst = [11,21,3,4]
mult_all(lst)
# Write a Python function to check whether a number falls in a given range.
def interval_checker(number, start, end):
    bl = (start <= number) and (number <= end) 
    return bl
interval_checker(0.5, 0, 1)
interval_checker(0.5, 1, 2)
# calculate the area of a circle
# improve this code to handle the potential errors!
from math import pi
def area(diameter):
    return pi * ((diameter/2)**2)
# test
area(2), area(4), area(100)
# is odd or even?
def is_even(number):
    if number%2 == 0:
        return True
    else:
        return False
lst
d = dict()
for item in lst:
    if is_even(item):
        d[item] = 'Even'
    else:
        d[item] = 'Odd'
        
print(d)
d1 = {'Even':0,'Odd':0}
for item in lst:
    if is_even(item):
        d1['Even'] += 1
    else:
        d1['Odd'] += 1
        
print(d1)
# input: start, end, num = how many times
# output: a dictionary that shows how many in the 1st, 2nd, 3rd, fouth quarters, respectively.
d = {'1':0, '2':0, '3':0, '4':0}
def q_dict(start = 0, end = 100, num = 20):
    
    
    return d
def print_lyrics():
    print("I'm a lumberjack, and I'm okay.") 
    print('I sleep all night and I work all day.')
    
print_lyrics()
def repeat_lyrics():
    print_lyrics()
    print_lyrics()
    
repeat_lyrics()<jupyter_output>I'm a lumberjack, and I'm okay.
I sleep all night and I work all day.
I'm a lumberjack, and I'm okay.
I sleep all night and I work all day.<jupyter_text>Lambda Functions We use lambda functions when we require a nameless function for a short period of time.<jupyter_code># Program to show the use of lambda functions
sq = lambda x: x ** 2

print(sq(5))
(lambda x, y: x + y)
s = _(4,8)
_(40,80)
(lambda x, y: x + y)(4,8)
summation = (lambda x, y: x + y)
summation(4,8)<jupyter_output><empty_output><jupyter_text>Lambda functions are used along with built-in functions like **filter()**, **map()**, etc.<jupyter_code># Program to filter out only the even items from a list
my_list = [1, 5, 4, 6, 8, 11, 3, 12]

new_list = list(filter(lambda x: (x%2 == 0) , my_list))

print(new_list)
new_list1 = [item for item in my_list if item%2 == 0]
print(new_list1)
my_list = [1, 5, 4, 6, 8, 11, 3, 12]
lst = list()
for item in my_list:
    lst.append(item **2)
    
lst
# Program to square each item in a list using map()

my_list = [1, 5, 4, 6, 8, 11, 3, 12]

new_list = list(map(lambda x: x ** 2 , my_list))

print(new_list)<jupyter_output><empty_output><jupyter_text>Higher Order Functions  A function is called Higher Order Function if it contains other functions as a parameter or returns a function as an output i.e, the functions that operate with another function are known as Higher order Functions.   Properties of higher-order functions:- You can store the function in a variable.- You can pass the function as a parameter to another function.- You can return the function from a function.- You can store them in data structures such as hash tables, lists, … In Python, we generally use it as an argument to a higher-order function (a function that takes in other functions as arguments).<jupyter_code># higher order functions
high_ord_func = lambda x, func: x + func(x)
high_ord_func(2, lambda x: x * x)
high_ord_func(2, lambda x: x + 3)
(lambda x: (x % 2 and 'odd' or 'even'))(3)
(lambda x: (x % 2 and 'odd' or 'even'))(30)
(lambda x: (x % 2 and 'odd' or 'even'))(12.25)
def myfunc(n):
    return lambda a : a * n

mydoubler = myfunc(2)
mytripler = myfunc(3)

print(mydoubler(11))
print(mytripler(11))<jupyter_output><empty_output><jupyter_text>Recursive FunctionRecursion is the process of defining something in terms of itself. In Python, we know that a function can call other functions. It is even possible for the function to call itself. These types of construct are termed as recursive functions.<jupyter_code># def fn():
#     # ...
#     if condition:
#         # stop calling itself
#     else:
#         fn()
#     # ...
# Count down from a number
def count_down(start):
    print(start)
    # call the count_down if the next
    # number is greater than 0
    next = start - 1
    if next > 0:
        count_down(next)


count_down(3)
def summation(n):
    if n > 0:
        return n + summation(n-1)
    return 0

result = summation(100)
print(result)
# improve your code
def new_sum(n):
    return n + new_sum(n-1) if n > 0 else 0
result = new_sum(100)
print(result)
#  find the factorial of an integer
def factorial(x):
    if x == 1:
        return 1
    else:
        return (x * factorial(x-1))

num = int(input('Enter a number'))
print("The factorial of", num, "is", factorial(num))<jupyter_output>Enter a number5
The factorial of 5 is 120<jupyter_text>Advantages of Recursion- Recursive functions make the code look clean and elegant.- A complex task can be broken down into simpler sub-problems using recursion.- Sequence generation is easier with recursion than using some nested iteration.  Disadvantages of Recursion- Sometimes the logic behind recursion is hard to follow through.- Recursive calls are expensive (inefficient) as they take up a lot of memory and time.- Recursive functions are hard to debug.  Exercise 1. Write a Python function to multiply all the numbers in a list.2. Write a Python function to calculate the factorial of a number (a non-negative integer). The function accepts the number as an argument.3. Write a Python function to check whether a number falls in a given range.4. Write a Python function that accepts a string and calculates the number of uppercase letters and lowercase letters.5. Write a Python function that takes a number as a parameter and check the number is prime or not.6. Write a Python program to print the even numbers from a given list.<jupyter_code>from math
def is_prime(n):
    if n == 1:
        return False
    for i in range(2,n):
    flag = True
    for j in range(2,math.ceil(math.sqrt(i))+1):
        if i%j == 0:
            flag = False
            
    if flag == True:<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10814504373177843, 'fraction_numerical': 0.026876822157434404, 'mean_word_length': 3.4932460090053215, 'pattern_counts': {'":': 0, '<': 46, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 1, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '316092', 'license': 'MIT', 'n_tokens_mistral': 3727, 'n_tokens_neox': 3474, 'n_words': 1442, 'path': 'Python_CH5.ipynb', 'repo_name': 'AminOroji/Elementary-Python-suf', 'size': '11013'}