# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# # 01- Conditional Structure and Loops

# Python provides different control structures that allow us to adapt to all possible cases. It allows the make decision (alternative structure) and loops (repetitive structures).

# ## 01.0. Comparisons
#
# Python comes with literal comparison operators.  Namely, `< > <= >= == !=`.  All comparisons return the lirteral boolean values: `True` or `False`.  These can be used to test values against one another. For example,

2 + 2 == 41

's' > 'basdf'

# Comparisons can be chained together with the **and** & **or** Python keywords.

1 == 1.0 and 'hello' == 'hello'

1 >10 or False

42 < 24 or True and 'wow' != 'mom'

# Comparisons may also be negated using the **not** keyword.

not 2 + 2 == 5

# Finally, the **is** opperator says wherer two objects are the same because they occupy the same place in memory.  This is a test of *equality* (is) rather than *equivalence* (==).

x = 'hello'
y = x
x is y

5 is 5.0

5 is not 5.0

# ## 01.1. Making Decision or If statements

# The decision structure is to run something in the event that a condition is true. Decision structures evaluate multiple expressions which produce TRUE or FALSE as result. You need to determine which action to take and which statements to execute if outcome is TRUE or FALSE otherwise.
#
# That said, these comparisons can be placed inside of an **if** statement.  Such statements have the following form:
#
#     if <condition>:
#         <indented block of code>
#
# The indented code will only be execute if the condition evaulates to `True`, which is a special boolean value.
#

x=10
y=12
if x == 5:
    print ("x vaut 5")

y = -x
if y < 0:
    print ("y is negative")

# The **if** statement can be combined to great effect with a corresponding **else** clause. 
#
#     if <condition>:
#         <if-block>
#     else:
#         <else-block>
#         
# When the condition is `True` the if-block is executed.  When the condition is `False` the else-block is executed instead.

x = 5
if x < 0:
    print "x is negative"
else:
    print "x in non-negative"

# Many cases may be tested by using the **elif** statement.  These come between all the if and else statements:
#
#     if <if-condition>:
#         <if-block>
#     elif <elif-condition>:
#         <elif-block>
#     else:
#         <else-block>
#         
# When if-condition is true then only the if-block is executed.  When elif-condition is true then only the elif-block is executed.  When neither of these are true then the else-block is executed.

x = 5
if x < 0:
    print "x is negative"
elif x == 0:
    print "x is zero"
else:
    print "x is positive"

# While there must be one if statetment, and there may be at most one else statement, there maybe as many elif statements as are desired.
#
#     if <if-condition>:
#         <if-block>
#     elif <elif-condition1>:
#         <elif-block1>
#     elif <elif-condition2>:
#         <elif-block2>
#     elif <elif-condition3>:
#         <elif-block3>
#     ...
#     else:
#         <else-block>
#         
# Only the block for top most condition that is true is executed.

x = 5
if x < 0:
    print ("x is negative")
elif x == 0:
    print ("x is zero")
#elif x > 0:    
   # print ("x is positive")
elif x == 1:
    print ("x is one")
elif x == 2:
    print ("x is two")
else:
    print ("x is positive and greater than 2")

# **Exercise:** Write an if statement that prints whether x is even or odd.

x = 11
f = x / 2
z = float(y * 2)
if z == x:
    print("Even number")
else:
    print("Odd number")

# ### Lists of Sequential Numbers
#
# Many times it is helpful to have a list of numbers in a row. In Python, this is called a `range`. 

range(5)

# Note that the list that you get will start at 0 by default (like list indicies) and goes up to _but does not include_ the number requested. This may seem nonintutitive, but the rationale is the following: 
#
# - the default is to start with `0`
# - the goal is to provide a list of `N` total number (for example, `range(5)` provides 5 numbers total
#

# However, you can make them start with 1 if you want!

range(1, 5)

# Lear more about the range command.

# +
# range?
# -

# ## 01.2. Loops

# In programming, a loop is a sequence of instructions that is continually repeated until a certain condition is reached. Imagine we want to compute the mean of 2 real numbers, we will need 2 variables to store this two values. For 3 numbers, we will need 3 variables as follows:

a=10.1
b=4
c=8
var_mean=(a+b+c)/3
print (var_mean)

# What about 1000 real numbers? Will we declare 1000 variables as done for 3 variables? I think the answer is NOT. A loop is required in this case. There are two types of loops in Python: **for loop** and **while loop**.
#
# ### 01.2.1. Syntax
#
#
#     while <condition>:
#         <indented block of code>
# As long as the condition is True, the code in the block will continue to execute.  This may lead to infitinely executing loops!

N = 10
i=0
while i < 8:
    print (i)
    i = i+1

# Meanwhile, for-loops have the following structure:
#
#     for <loop variable name> in <iterable>:
#          <indented block of code>
#          
# The loop will continue to execute as long as there are more iterations left in the iterable.  Upon each iteration, the value of that iteration is assigned to the loop variable.

for i in range(N):
    print (i)

# To solve our previous problem as follows:

# While version:

var_mean=0 #mean variable
n=10 #total number of real numbers
i=0
while i<n:
    number=input("input value "+str(i+1)+" : ")
    var_mean=var_mean+float(number)
    i+=1
var_mean=var_mean/n
print ("the mean is: ", var_mean)

# Meanwhile, for-loops have the following structure:
#
#     for <loop variable name> in <iterable>:
#          <indented block of code>
#          
# The loop will continue to execute as long as there are more iterations left in the iterable.  Upon each iteration, the value of that iteration is assigned to the loop variable.

# For version

var_mean=0 #mean variable
n=10 #total number of real numbers
for i in range(n):
    number=input("input value "+str(i+1)+" : ")
    var_mean=var_mean+float(number)
var_mean=var_mean/n
print ("the mean is: ", var_mean)

# ## Short Exercise
# Using a loop, calculate the factorial of 42 (the product of all integers up to and including 42).

var = 6
summ = 1
while(var >= 1):
    print (var)
    summ = summ * var
    var = var - 1
print (summ)


def fact(0) = 1
def fact(1) = 1
def fact(x):
    while(x > 1):
        fact(x) = x * fact(x-1)
    print (fact(x))
x = input('Enter number to get factorial >>> ')
fact(x)

# ## break, continue and pass
#
# Break terminates the loop statement and transfers execution to the statement immediately following the loop. A break statement cuts off a loop from within an inner loop. It helps
# avoid infinite loops by cutting off loops when they're clearly going
# nowhere.

reasonable = 10
for n in range(1,2000):
    if n == reasonable :
        break
    print (n)

var_mean=0 #mean variable
n=10 #total number of real numbers
i=0
while i<n:
    if (i+1)==5:
        break
    number=input("input value "+str(i+1)+" : ")
    var_mean=var_mean+float(number)
    i+=1    
var_mean=var_mean/n
print ("the mean is: ", var_mean)

# Something you might want to do instead of breaking is to continue to the
# next iteration of a loop, giving up on the current one. Continue statement causes the loop to skip the remainder of its body and immediately retest its condition prior to reiterating.

reasonable = 10
for n in range(1,20):
    if n == reasonable :
      continue
    print (n)

var_mean=0 #mean variable
n=10 #total number of real numbers
for i in range(n):
    if (i+1)==2:
        continue
    number=input("input value "+str(i+1)+" : ")
    var_mean=var_mean+float(number )
var_mean=var_mean/n
print ("the mean is: ", var_mean)

# The pass statement is used when a statement is required syntactically but you do not want any command or code to execute. The pass statement is a null operation; nothing happens when it executes.

var_mean=0 #mean variable
n=10 #total number of real numbers
for i in range(n):
    if (i+1)==2:
        pass
    number=input("input value "+str(i+1)+" : ")
    var_mean=var_mean+float(number) 
var_mean=var_mean/n
print ("the mean is: ", var_mean)

# #### We can have nested loops: find for loop in while loop, or while loop in an other while loop, or for loop in an other for loop. Brief, any loop can contain other loops inside it. 

StarcoderdataJupyterScriptsDedupFiltered