<jupyter_start><jupyter_text>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. ComparisonsPython 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,<jupyter_code>2 + 2 == 41
's' > 'basdf'<jupyter_output><empty_output><jupyter_text>Comparisons can be chained together with the **and** & **or** Python keywords.<jupyter_code>1 == 1.0 and 'hello' == 'hello'
1 >10 or False
42 < 24 or True and 'wow' != 'mom'<jupyter_output><empty_output><jupyter_text>Comparisons may also be negated using the **not** keyword.<jupyter_code>not 2 + 2 == 5<jupyter_output><empty_output><jupyter_text>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* (==).<jupyter_code>x = 'hello'
y = x
x is y
5 is 5.0
5 is not 5.0<jupyter_output><empty_output><jupyter_text>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 :        The indented code will only be execute if the condition evaulates to `True`, which is a special boolean value.<jupyter_code>x=10
y=12
if x == 5:
    print ("x vaut 5")
y = -x
if y < 0:
    print ("y is negative")<jupyter_output><empty_output><jupyter_text>The **if** statement can be combined to great effect with a corresponding **else** clause.     if :            else:                When the condition is `True` the if-block is executed.  When the condition is `False` the else-block is executed instead.<jupyter_code>x = 5
if x < 0:
    print "x is negative"
else:
    print "x in non-negative"<jupyter_output><empty_output><jupyter_text>Many cases may be tested by using the **elif** statement.  These come between all the if and else statements:    if :            elif :            else:                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.<jupyter_code>x = 5
if x < 0:
    print "x is negative"
elif x == 0:
    print "x is zero"
else:
    print "x is positive"<jupyter_output><empty_output><jupyter_text>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 :            elif :            elif :            elif :            ...    else:                Only the block for top most condition that is true is executed.<jupyter_code>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")<jupyter_output><empty_output><jupyter_text>**Exercise:** Write an if statement that prints whether x is even or odd.<jupyter_code>x = 11
f = x / 2
z = float(y * 2)
if z == x:
    print("Even number")
else:
    print("Odd number")<jupyter_output>Even number<jupyter_text>Lists of Sequential NumbersMany times it is helpful to have a list of numbers in a row. In Python, this is called a `range`.<jupyter_code>range(5)<jupyter_output><empty_output><jupyter_text>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!<jupyter_code>range(1, 5)<jupyter_output><empty_output><jupyter_text>Lear more about the range command.<jupyter_code>range?<jupyter_output><empty_output><jupyter_text>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:<jupyter_code>a=10.1
b=4
c=8
var_mean=(a+b+c)/3
print (var_mean)<jupyter_output><empty_output><jupyter_text>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 :        As long as the condition is True, the code in the block will continue to execute.  This may lead to infitinely executing loops!<jupyter_code>N = 10
i=0
while i < 8:
    print (i)
    i = i+1<jupyter_output><empty_output><jupyter_text>Meanwhile, for-loops have the following structure:    for  in :                  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.<jupyter_code>for i in range(N):
    print (i)<jupyter_output><empty_output><jupyter_text>To solve our previous problem as follows: While version:<jupyter_code>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)<jupyter_output><empty_output><jupyter_text>Meanwhile, for-loops have the following structure:    for  in :                  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<jupyter_code>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)<jupyter_output><empty_output><jupyter_text>Short ExerciseUsing a loop, calculate the factorial of 42 (the product of all integers up to and including 42).<jupyter_code>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)<jupyter_output><empty_output><jupyter_text>break, continue and passBreak 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 helpsavoid infinite loops by cutting off loops when they're clearly goingnowhere.<jupyter_code>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)<jupyter_output><empty_output><jupyter_text>Something you might want to do instead of breaking is to continue to thenext 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.<jupyter_code>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)<jupyter_output><empty_output><jupyter_text>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.<jupyter_code>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)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09094017094017094, 'fraction_numerical': 0.01698005698005698, 'mean_word_length': 4.081644470179502, 'pattern_counts': {'":': 0, '<': 92, '<?xml version=': 0, '>': 92, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '21', 'dir': 'jupyter-structured-clean-dedup', 'id': '485603', 'license': 'MIT', 'n_tokens_mistral': 2804, 'n_tokens_neox': 2668, 'n_words': 1119, 'path': '01-Iteration-and-Flow-control.ipynb', 'repo_name': 'sustecha/AIMS_Python_course', 'size': '8775'}