<jupyter_start><jupyter_text>BEFORE YOU DO ANYTHING...In the terminal:1. Navigate to __inside__ your ILAS_Python repository.2. __COMMIT__ any un-commited work on your personal computer.3. __PULL__ any changes *you* have made using another computer.4. __PULL__ textbook updates (including homework answers).  Control Flow  Lesson GoalCompose simple programs to control the order in which the operators we have studied so far are executed.  ObjectivesControl the flow of a program using:- __control statements__- __loops__     Why we are studying this:Control flow allows us to make __choices__ using our program.Control statements result in a decision being made as to which of __two or more possible paths__ to follow.   Lesson structure: - Control Statements - `if` and `else`statements - `for` loops - `while` loops - `break` and `continue` statements - Review Exercises - Summary What is a *__control statement__*?Let's start with an example from the last seminar...  Control StatementsIn the last seminar we looked at a simple computer program that returned Boolean (True or False) variables...  Based on the current time of day, the program answers two questions:>__Is it lunchtime?__>`True`if it is lunch time.>__Is it time for work?__>`True`if it is `not`:- before work (`time < work_starts`)- after work (`time > work_ends `)- lunchtime (the previous question assigns the value `True` or `False` to variable `lunchtime`).<jupyter_code># Time-telling program

time = 13.05          # current time

work_starts = 8.00    # time work starts 
work_ends =  17.00    # time work ends

lunch_starts = 13.00  # time lunch starts
lunch_ends =   14.00  # time lunch ends

# variable lunchtime is True if the time is between the start and end of lunchtime
lunchtime = time >= lunch_starts and time < lunch_ends

# variable work_time is True if the time is not...  
work_time = not (   time < work_starts     # ... before work
                 or time > work_ends       # ... or after work
                 or lunchtime)             # ... or lunchtime
                 

print("Is it work time?")
print(work_time)
print("Is it lunchtime?")
print(lunchtime)<jupyter_output>Is it work time?
False
Is it lunchtime?
True<jupyter_text>What if we now want our computer program to do something based on these answers?To do this, we need to use *control statements*.Control statements allow us to make decisions in a program.This decision making is known as *control flow*. Control statements are a fundamental part of programming. Here is a control statement in pseudo code:This is an `if` statement.    if A is true            Perform task X        For example     if lunchtime is true            Eat lunch We can check if an alternative to the `if` statement is true using an `else if` statement.    if A is true        Perform task X (only)            else if B is true        Perform task Y (only) Example:    if lunchtime is true        Eat lunch            else if work_time is true        Do work Often it is useful to include an `else` statement.If none of the `if` and `else if` statements are satisfied, the code following the `else` statement will be executed.    if A is true        Perform task X (only)            else if B is true        Perform task Y (only)            else           Perform task Z (only)             if lunchtime is true        Eat lunch            else if work_time is true        Do work            else           Go home Let's get a better understanding of control flow statements by completing some examples.   `if` and `else` statementsLet's consider a simple example that demonstrates a Python  if-else control statement. It uses the lunch/work example from the previous seminar.__Note:__ In Python, "else if" is written: `elif`<jupyter_code># Time-telling program

time = 13.05          # current time

work_starts = 8.00    # time work starts 
work_ends =  17.00    # time work ends

lunch_starts = 13.00  # time lunch starts
lunch_ends =   14.00  # time lunch ends

# variable lunchtime is True if the time is between the start and end of lunchtime
lunchtime = time >= lunch_starts and time < lunch_ends

# variable work_time is True if the time is not...  
work_time = not (   time < work_starts     # ... before work
                 or time > work_ends       # ... or after work
                 or lunchtime)             # ... or lunchtime
                 

#print("Is it work time?")
#print(work_time)
#print("Is it lunchtime?")
#print(lunchtime)

if lunchtime:   # if lunchtime == True:
    print("Eat lunch")
        
elif work_time: # elif work_time == True:
    print("Do work")
        
else:   
    print("Go home")<jupyter_output>Eat lunch<jupyter_text>__Remember:__ The program assigns the variables lunchtime and work_time the values `True` or `False`.Therefore when we type: `if lunchtime`the meaning is the same as: `if lunchtime == True` Here is another example, using algebraic operators to modify the value of an initial variable, `x`. The modification of `x` and the message printed depend on the initial value of `x`.<jupyter_code>#The input to the program is variable `x`.
x = -10.0  # Initial x value

if x > 0.0:  
    print('Initial x is greater than zero') #The program prints a message... 
    x -= 20.0                               # ...and modifies `x`.
    
elif x < 0.0:  
    print('Initial x is less than zero')
    x += 21.0
    
else: 
    print('Initial x is not less than zero and not greater than zero, therefore it must be zero')
    x *= 2.5

print("Modified x = ", x)<jupyter_output>Initial x is less than zero
Modified x =  11.0<jupyter_text>__Note:__ The program  uses the short-cut algebraic operators that you learnt to use in the last seminar.  __Try it yourself__In the cell code cell above, try:- changing the operations performed on `x`- changing the value of `x` a few times.Re-run the cell to see the different paths the program can follow.  Look carefully at the structure of the `if`, `elif`, `else`, control statement:__The control statement begins with an `if`__, followed by the expression to check.    At the end of the `if` statement you must put a colon (`:`)  ````pythonif x > 0.0:    ```` After the `if` statement, indent the code to be run in the case that the `if` statement is `True`.  To end the code to be run, simply stop indenting: ````pythonif x > 0.0:    print('Initial x is greater than zero')    x -= 20.0```` The indent can be any number of spaces.The number of spaces must be the same for all lines of code to be run if the `if` statement is True.Jupyter Notebooks automatically indent 4 spaces.This is considered best practise.   `if x > 0.0` is: - `True`:    - The indented code is executed.    - The control block is exited.    - The program moves past any subsequent `elif` or `else` statements.                  - `False`:  the program moves past the inented code to the next (non-indented) part of the program...  In this the next (non-indented) part of the program is `elif` (else if).The elif statement is evaluated.(Notice that the code is structured in the same way as the `if` statement.):```pythonif x > 0.0:    print('Initial x is greater than zero')    x -= 20.0    elif x < 0.0:    print('Initial x is less than zero')    x += 21.0```   `elif x < 0.0`:- `True`:    - The indented code is executed.    - The control block is exited.     - The program moves past any subsequent `elif` or `else` statements.        - `False`:  the program moves past the indented code to the next (non-indented) part of the program.    If none of the preceding `if` or `elif` stements are true. e.g. in this example: - `x > 0.0` is `False`  - `x < 0.0` is `False`the code following the `else` statement is executed.```pythonif x > 0.0:    print('Initial x is greater than zero')    x -= 20.0elif x < 0.0:    print('Initial x is less than zero')    x += 21.0else:    print('Initial x is not less than zero and not greater than zero, therefore it must be zero')``` Evaluating data against different criteria is extremely useful for solving real-world mathematical problems. Let's look at a simple example...  Real-World Example: currency tradingTo make a comission (profit), a currency trader sells US dollars to travellers above the market rate. The multiplier used to calculate the amount recieved by customer is shown in the table:|Amount (JPY)                                |Multiplier               ||--------------------------------------------|-------------------------|| Less than $100$                            | 0.9                     |   | From $100$ and less than $1,000$           | 0.925                   |   | From $1,000$ and less than $10,000$        | 0.95                    |   | From $10,000$ and less than $100,000$      | 0.97                    |   | Over $100,000$                             | 0.98                    |    The currency trader charges more if the customer pays with cash.  If the customer pays with cash, the currency trader reduces the rate by an __additional__ 10% after conversion.  (If the transaction is made electronically, they do not).   __Current market rate:__ 1 JPY = 0.0091 USD.__Effective rate:__ The rate that the customer receives based on the amount in JPY to be changed. The program calculates the __effective rate__ using: - The reduction based on the values in the table. - An additional 10% reduction (mutiplier = 0.9) if the transaction is made in cash.<jupyter_code>JPY  = 1_000_000  # The amount in JPY to be changed into USD
cash = False   # True if transaction is in cash, otherwise False

market_rate = 0.0091  # 1 JPY is worth this many dollars at the market rate

# Apply the appropriate reduction depending on the amount being sold
if JPY < 10_000:
    multiplier = 0.9 
        
elif JPY < 100_000:  
    multiplier = 0.925 * market_rate * JPY
    
elif JPY < 1_000_000:
    multiplier = 0.95 * market_rate * JPY
      
elif JPY < 10_000_000:
    multiplier = 0.97 * market_rate * JPY

else: # JPY > 10,000,000
    multiplier = 0.98 * market_rate * JPY
    

    
# Apply the appropriate reduction depending if the transaction is made in cash or not
if cash:
    cash_multiplier = 0.9
else:
    cash_multiplier = 1 
    
    
    
# Calculate the total amount sold to the customer    
USD = JPY * market_rate * multiplier * cash_multiplier
    
print("Amount in JPY sold:", JPY)
print("Amount in USD purchased:", USD)
print("Effective rate:", USD/JPY)<jupyter_output>Amount in JPY sold: 1000000
Amount in USD purchased: 80325700.0
Effective rate: 80.3257<jupyter_text>__Note:__ - We can use multiple `elif` statements within a control block. - We can use multipe `if` statements.  When the program executes and exits a control block, it moves to the next `if` statement.  - __Readability:__ Underscores _ are placed between 0s in long numbers to make them easier to read.  You DO NOT need to include underscores for Python to interpret the number correctly. You can place the underscores wherever you like in the sequence of digits that make up the number.   __Try it yourself__In your textbook, try changing the values of `JPY` and `cash` a few times.Re-run the cell to see the different paths the program can follow.  `for` loops*Loops* are used to execute a command repeatedly.A loop is a block that repeats an operation a specified number of times (loops). To learn about loops we are going to use the function `range()`.  `range`The function `range` gives us a sequence of *integer* numbers.`range(3, 6)` returns integer values starting from 3 and ending at 6.i.e.> 3, 4, 5Note this does not include 6. We can change the starting value. For example for integer values starting at 0 and ending at 4: `range(0,4)`returns:> 0, 1, 2, 3`range(4)` is a __shortcut__ for range(0, 4) range (0,5)range (5,9)  Simple `for` loops The statement ```pythonfor i in range(0, 5):```says that we want to run the indented code five times.<jupyter_code>for i in range(0, 6):
    print(i)<jupyter_output>0
1
2
3
4
5<jupyter_text>The first time through, the value of i is equal to 0.The second time through, its value is 1.Each loop the value `i` increases by 1 (0, 1, 2, 3, 4) until the last time when its value is 4.  Look carefully at the structure of the `for` loop: - `for` is followed by the condition being checked. - : colon at the end of the `for` statement.    - The indented code that follows is run each time the code loops.   (The __same of spaces__ should be used for all indents)    - To end the `for` loop, simply stop indenting.<jupyter_code>for i in range(-2, 3):
    print(i)
print('The end of the loop')<jupyter_output>-2
-1
0
1
2
The end of the loop<jupyter_text>The above loop starts from -2 and executes the indented code for each value of i in the range (-2, -1, 0, 1, 2).When the loop has executed the code for the final value `i = 2`, it moves on to the next unindented line of code.<jupyter_code>for n in range(4):
    
    print("----")
    
    print(n, n**2)<jupyter_output>----
0 0
----
1 1
----
2 4
----
3 9<jupyter_text>The above executes 4 loops.The statement ```pythonfor n in range(4):```says that we want to loop over four integers, starting from 0. Each loop the value `n` increases by 1 (0, 1, 2 3). __Try it yourself__Go back and change the __range__ of input values in the last three cells and observe the change in output.  If we want to step by three rather than one:<jupyter_code>for n in range(0, 10, 3):
    print(n)<jupyter_output>0
3
6
9<jupyter_text>If we want to step backwards rather than forwards we __must__ include the step size:<jupyter_code>for n in range(10, 0, -1):
    print(n)<jupyter_output>10
9
8
7
6
5
4
3
2
1<jupyter_text>For example...<jupyter_code>for n in range(10, 0):
    print(n)<jupyter_output><empty_output><jupyter_text>...does not return any values because there are no values that lie between 10 and 0 when counting in the positive direction from 10.  __Try it yourself.__In the cell below write a `for` loop that:- starts at `n = 9`- ends at `n = 3` (and includes `n = 3`)- loops __backwards__ through the range in steps of -3 - prints `n`$^2$ at each loop.<jupyter_code># For loop
for n in range(9, 2, -3):
    print ("-----")
    print(n, n**2)<jupyter_output>-----
9 81
-----
6 36
-----
3 9<jupyter_text>For loops are useful for performing operations on large data sets.We often encounter large data sets in real-world mathematical problems.  A simple example of this is converting multiple values using the same mathematical equation to create a look-up table...  Real-world Example: conversion table from degrees Fahrenheit to degrees CelsiusWe can use a `for` loop to create a conversion table from degrees Fahrenheit ($T_F$) to degrees Celsius ($T_c$).Conversion formula:$$T_c = 5(T_f - 32)/9$$Computing the conversion from -100 F to 200 F in steps of 20 F (not including 200 F):<jupyter_code>print("T_f,      T_c")

for Tf in range(-100, 200, 20):
    print(Tf, "\t", round(((Tf - 32) * 5 / 9), 3))<jupyter_output>T_f,      T_c
-100 	 -73.333
-80 	 -62.222
-60 	 -51.111
-40 	 -40.0
-20 	 -28.889
0 	 -17.778
20 	 -6.667
40 	 4.444
60 	 15.556
80 	 26.667
100 	 37.778
120 	 48.889
140 	 60.0
160 	 71.111
180 	 82.222<jupyter_text>`while` loopsA __`for`__ loop performs an operation a specified number of times. ```python for x in range(5):    print(x)```   A __`while`__ loop performs a task *while* a specified statement is true. ```pythonx = 0while x < 5:    print(x)``` The structure of a `while` loop is similar to a `for` loop.- `while` is followed by the condition being checked.- : colon at the end of the `while` statement.   - The indented code that follows is repeatedly executed until the `while` statement (e.g. `x   It can be quite easy to crash your computer using a `while` loop. e.g. if we don't modify the value of x each time the code loops:```pythonx = 0while x < 5:    print(x)     x += 1  ```will continue indefinitely since `x < 5 == False`  will never be satisfied.This is called an *infinite loop*. To perform the same function as the `for` loop we need to increment the value of `x` within the loop:<jupyter_code>x = 0

print("Start of while statement")

while x < 5:
    print(x)
    x += 1  # Increment x
    
print("End of while statement")<jupyter_output>Start of while statement
0
1
2
3
4
End of while statement<jupyter_text>`for` loops are often safer when performing an operation on a set range of values.<jupyter_code>x = -2

print("Start of for statement")

for y in range(x,5):
    print(y)
    
print("End of for statement")<jupyter_output>Start of for statement
-2
-1
0
1
2
3
4
End of for statement<jupyter_text>Here is another example of a `while` loop.<jupyter_code>x = 0.9

while x > 0.001:
    # Square x (shortcut x *= x)
    x = x * x
    print(round(x, 6))<jupyter_output>0.81
0.6561
0.430467
0.185302
0.034337
0.001179
1e-06<jupyter_text>If we use an initial value of $x \ge 1$, an infinite loop will be generted.`x` will increase with each loop, meaning `x` will always be greater than 0.001.e.g. ```pythonx = 2while x > 0.001:    x = x * x    print(x)``` However, using a `for` loop is a less appropriate solution in this case.We may not know beforehand how many steps are required before `x > 0.001` becomes false. To avoid errors, it is good practice to check that $x < 1$ before entering the `while` loop e.g.<jupyter_code>x = 0.9

if x < 1:

    while x > 0.001:
        # Square x (shortcut x *= x)
        x = x * x
        print(round(x, 6))
        
else:
    print("x is greater than one, infinite loop avoided")<jupyter_output>0.81
0.6561
0.430467
0.185302
0.034337
0.001179
1e-06<jupyter_text>__Try it for yourself:__In the cell above change the value of x to above or below 1.Observe the output. __Try it for yourself:__In the cell below: - Create a variable,`x`, with the initial value 50 - Each loop:  1. print x  1. reduce the value of x by half - Exit the loop when `x` < 3<jupyter_code># While loop<jupyter_output><empty_output><jupyter_text>`break` and `continue`. `break`Sometimes we want to break out of a `for` or `while` loop. For example in a `for` loop we can check if something is true, and then exit the loop prematurely, e.g<jupyter_code>for x in range(10):
    print(x)
    
    if x == 5:
        print("Time to break out")
        break<jupyter_output>0
1
2
3
4
5
Time to break out<jupyter_text>Let's look at how we can use this in a program... The following program __finds prime numbers__.__Prime number:__ A positive integer, greater than 1, that has no positive divisors other than 1 and itself (2, 3, 5, 11, 13, 17....)The program checks (integer) numbers, `n` up to a limit `N` and prints the prime numbers.  We can determine in `n` is a prime nunber by diving it by every number in the range 2 to `n`.If any of these calculations has a remainder equal to zero, n is not a prime number.<jupyter_code>N = 50  # Check numbers up 50 for primes (excludes 50)

# Loop over all numbers from 2 to 50 (excluding 50)
for n in range(2, N):

    # Assume that n is prime
    n_is_prime = True

    # Check if n divided by (any number in the range 2 to n) returns a remainder equal to 0 
    for m in range(2, n):
        
        # If the remainder is zero, n is not a prime number
        if n % m == 0: 
            n_is_prime = False

    #  If n is prime, print to screen        
    if n_is_prime:
        print(n)<jupyter_output>2
3
5
7
11
13
17
19
23
29
31
37
41
43
47<jupyter_text>Notice that our program contains a second `for` loop. For each value of n, it loops through incrementing values of m in the range (2 to n):```python Check if n can be divided by m m ranges from 2 to n (excluding n)for m in range(2, n):```before incrementing to the next value of n.We call this a *nested* loop.The indents in the code show where loops are nested. Here it is again without the comments:<jupyter_code>N = 50  

# for loop 1
for n in range(2, N):    
    n_is_prime = True

    # for loop 2
    for m in range(2, n): 
        if n % m == 0:   
            n_is_prime = False
            
    if n_is_prime:
        print(n)<jupyter_output>2
3
5
7
11
13
17
19
23
29
31
37
41
43
47<jupyter_text>As n gets larger, dividing it by *every* number in the range (2, n) becomes more and more inefficient. A `break` statement allows us to exit the loop as soon as a remainder equal to zero is returned (indicating that n is not a prime number).  In the program below, a break statement is added.As soon as a number is found to be not prime, the program breaks out of loop 2 and goes to the next value of n in loop 1.By placing `else` *one level up* from `if` the program will iterate through all values of m before printing n if n is prime.<jupyter_code>N = 55  
# for loop 1
for n in range(2, N):
    
    # for loop 2
    for m in range(2, n):
        if n % m == 0:  
            break
            
    else: 
         # if n is prime
            print(n)<jupyter_output>3
5
5
5
7
7
7
7
7
9
11
11
11
11
11
11
11
11
11
13
13
13
13
13
13
13
13
13
13
13
15
17
17
17
17
17
17
17
17
17
17
17
17
17
17
17
19
19
19
19
19
19
19
19
19
19
19
19
19
19
19
19
19
21
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
23
25
25
25
27
29
29
29
29
29
29
29
29
29
29
29
29
29
29
29
29
29
29
29
29
29
29
29
29
29
29
29
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
33
35
35
35
37
37
37
37
37
37
37
37
37
37
37
37
37
37
37
37
37
37
37
37
37
37
37
37
37
37
37
37
37
37
37
37
37
37
37
39
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
41
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
45
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
49
49
49
49
49<jupyter_text>`continue`Sometimes, instead of stopping the loop we want to go to the next iteration in a loop, skipping the remaining code.For this we use `continue`.    The example below loops over 20 numbers (0 to 19) and checks if the number is divisible by 4. If the number is not divisible by 4:- it prints a message - it moves to the next value. If the number is divisible by 4 it *continues* to the next value in the loop, without printing.<jupyter_code>for j in range(1, 20):
    
    if j % 4 == 0:  # Check remainer of j/4
        continue    # continue to next value of j
        
    print(j, "is not a multiple of 4")<jupyter_output>1 is not a multiple of 4
2 is not a multiple of 4
3 is not a multiple of 4
5 is not a multiple of 4
6 is not a multiple of 4
7 is not a multiple of 4
9 is not a multiple of 4
10 is not a multiple of 4
11 is not a multiple of 4
13 is not a multiple of 4
14 is not a multiple of 4
15 is not a multiple of 4
17 is not a multiple of 4
18 is not a multiple of 4
19 is not a multiple of 4<jupyter_text>To compare, if we used `break` instead of `continue`:<jupyter_code>for j in range(1, 20):
    
    if j % 4 == 0:  # Check remainer of j/4
        break    # continue to next value of j
        
    print(j, "is not a multiple of 4")<jupyter_output>1 is not a multiple of 4
2 is not a multiple of 4
3 is not a multiple of 4<jupyter_text>__Try it yourself__We can use a `for` loop to perform an operation on each character of a string.```Pythonstring = "string"for i in range(len(sting)):    print(sting[i])``` In the cell below, loop through the characters of the string.Use `continue` to only print the letters of the word *sting*.<jupyter_code># Print the letters of the word sting
string = "string"<jupyter_output><empty_output><jupyter_text>Review ExercisesHere are a series of engineering problems for you to practise each of the new Python skills that you have learnt today.  Review Exercise: `while` loops.In the cell below, write a while loop that with each loop:- prints the value of `x`- then decreases the value of x by 0.5as long as `x` remains positive.Jump to While Loops<jupyter_code>x = 4
while x > 0:
    print(x)
    x -= 0.5
# Example Solution

while (x > 0):
    print(x)
    x -= 0.5<jupyter_output><empty_output><jupyter_text>Review Exercise: `for` loopsIn the cell below, write a `for` loop to print the even numbers from 2 to 100, inclusive.<jupyter_code># for loop to print the even numbers from 2 to 20, inclusive.
for n in range (2, 21):
    print (n)
# Example Solution

for i in range(2, 21, 2):
    print(i)<jupyter_output><empty_output><jupyter_text>Review Excercise: `for` loops and `if` statementsIn the cell below, write a for loop to alternately print `Red` then `Blue` 3 times. i.e. Red Blue Red Blue Red Blue<jupyter_code># Alternately print Red and Blue

for n in range (1, 7):
    if n % 2 == 0:
        print("red")
        elif 
# Example Solution

colour = "Red"

for n in range(6):
    print(colour)
    
    if colour == "Red":
        colour = "Blue"
        
    else:
        colour = "Red"<jupyter_output><empty_output><jupyter_text>Review Exercise: `continue`In the cell below, loop through the characters of the string.Use `continue` to only print the letters of the word *sing*.Hint: Refer to __Logical Operators__ (Seminar 2). Jump to continue<jupyter_code># Print the letters of the word sing
string = "string"
# Example Solution
string = "string"

for i in range(len(string)):
    
    if string[i] == "r" or string[i] == "t":
        continue
    
    print(string[i])<jupyter_output><empty_output><jupyter_text>Review Exercise: `for` loops and `if`, `else` and `continue` statements.__(A)__ In the cell below, use a for loop to print the square roots of the first 25 odd positive integers. (Remember, the square root of a number, $x$ can be found by $x^{1/2}$)__(B)__ If the number generated is greater than 3 and smaller than 5, print "`skip`" and __`continue`__ to the next iteration *without* printing the number.Hint: Refer to __Logical Operators__ (Seminar 2). Jump to for loopsJump to if and else statementsJump to continue<jupyter_code># square roots of the first 25 odd positive integers


# Example Solution

for x in range(1, 50, 2):
    
    if((x ** (1/2) > 3) and (x ** (1/2) < 5)): 
        print("skip")
        continue
        
    print(x ** (1/2))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.0830726981463117, 'fraction_numerical': 0.05671675947822107, 'mean_word_length': 3.024405218726017, 'pattern_counts': {'":': 2, '<': 118, '<?xml version=': 0, '>': 122, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 5, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '29', 'dir': 'jupyter-structured-clean-dedup', 'id': '2237', 'license': 'MIT', 'n_tokens_mistral': 9185, 'n_tokens_neox': 8190, 'n_words': 4020, 'path': '3_Control_flow.ipynb', 'repo_name': 'konshte/Python_K', 'size': '26218'}