<jupyter_start><jupyter_text>*This notebook was adapted from  [course notes by Dr. <NAME>](https://github.com/kfollette/ASTR200-Spring2017)* Further modified from notes by <NAME>, <NAME>, <NAME> (https://github.com/gurtina/P105A_2019)            CIERA Summer Camp 2019: Intro to Python Contents1. Variable Types2. Conditional Statements3. While Loops4. For Loops  1. Variable TypesComputers store data in memory, variables are the helpful names to refer to a location in memory. 1.1 Integers and Floats<jupyter_code>b=5<jupyter_output><empty_output><jupyter_text>The variable `b` is an integer, or `int` for short. We can find this out by asking python using one of its many built-in functions, namely `type`.<jupyter_code>type(b)<jupyter_output><empty_output><jupyter_text>Integers are exactly what they sound like: they hold whole numbers, and operations involving them and other whole numbers will always yield whole numbers. This is an important point in general programming, because variable types are not generally reassigned dynamically. So, for example, the operation 5/2 would yield 2 rather than 2.5 if 5 is an integer. In our case, however, we are using Python 3, which will automatically convert an integer to the next type of variable if the natural output is not a whole number, as below :<jupyter_code>c = b/2<jupyter_output><empty_output><jupyter_text>By defining `c` as `b/2`, `c` is not an integer.  Instead, it is a new type of variable: a floating point number, or `float` for short. You can see this using `type`, as in the below:<jupyter_code>c
type(c)<jupyter_output><empty_output><jupyter_text>A floating point variable is capable of holding real numbers. Why have different types of variables for integers versus non-integer real numbers? In mathematics there is no need to make the distinction, of course: all integers are real numbers, so it would seem that there should be no reason to have a separate type of variable to hold integers. However, this ignores the way computers work. On a computer, operations involving integers are exact: 1 + 1 is exactly 2. However, operations on real numbers are necessarily inexact. I say necessarily because a real number is capable of having an arbitrary number of decimal places. The number pi contains infinitely many digits, and never repeats, but my computer only comes with a finite amount of memory and processor power. Even rational numbers (like 2/3) run into this problem, because their decimal representation (or to be exact their representation in binary) may be an infinitely repeating sequence. Thus it is not possible to perform operations on arbitrary real numbers to exact precision. Instead, arithmetic operations on floating point numbers are approximate, with the level of accuracy determined by factors like how much memory one wants to devote to storing digits, and how much processor time one wants to spend manipulating them. On most computers a python floating point number is accurate to about 1 in 10^15, but this depends on both the architecture and on the operations you perform. That's enough accuracy for many purposes, but there are plenty of situations (for example counting things) when we really want to do things precisely, and we want 1 + 1 to be exactly 2. That's what integers are there for.You can also convert variable types. We can change the floating point `c` into an integer, which will drop the values after the decimal point. It will not round the value.<jupyter_code>d = int(c)
print(d)<jupyter_output><empty_output><jupyter_text>1.2 StringsA third type of very useful variable is strings, abbreviated str. A string is a sequence of characters, and one can declare that something is a string by putting characters in quotation marks (either `"` or `'` is fine):<jupyter_code>e = "stars"
type(e)<jupyter_output><empty_output><jupyter_text>The quotation marks are important here. To see why, try issuing the command without them:<jupyter_code>e = stars<jupyter_output><empty_output><jupyter_text>This is an error message, complaining that the computer doesn't know what stars is. The problem is that, without the quotation marks, python thinks that stars is the name of a variable, and complains when it can't find a variable by that name. Putting the quotation marks tells python that we mean a string, not a variable named stars.Obviously we can't add strings in the same sense that we add numbers, but we can still do operations on them. The plus (`+`) operation `concatenates` two strings together:<jupyter_code>f = "planets"
e+f
e + " and " + f<jupyter_output><empty_output><jupyter_text>**Special Characters**backslashes start special characters: `\n   = newline`   ` \t   = tab`<jupyter_code>print(e + "\nand \n" + f)
# this one won't work
print(5 + e + '\n and \n' + 7 + f)
# we need to turn the integers into strings to concatenate them.
print(str(5) + e + "\n and \n" + str(7) +f)
# fixing the text so that there is space between the number and the variable.
print(str(5) + "\t" + e + "\n and \n" + str(7) + "\t" + f)
print("'")<jupyter_output><empty_output><jupyter_text>1.3 BooleansIn addition to integers, floats, and strings, there are three other types of variables worth mentioning. The first is a Boolean variable (named after <NAME>), which represents a logical value. Boolean variables can be either True or False:<jupyter_code># capitalization matters here
g = True
type(g)
g<jupyter_output><empty_output><jupyter_text>Boolean variables can have logic operations performed on them. Here are three example logical operators:`not`, `and`, and `or`. Play around with the cells below and see if you can figure out what each one does, and then describe it below.<jupyter_code>not g
not not g
h = False
g and h
g or h
not(g and h)
(not g) and h<jupyter_output><empty_output><jupyter_text>Exercise 1-------------Double click here and edit the text below to describe what each operator does in your own wodsthe NOT operator ...the AND operator ...the OR operator ...  2. Conditional StatementsA conditional statement executes if a given boolean statement is true.The general syntax is `if BOOLEAN_EXPRESSION:`    STATEMENT 2.1. Using Boolean VariablesWe will first define a boolean variable x and set as default it to be True<jupyter_code>x = True<jupyter_output><empty_output><jupyter_text>Let's create a conditional statement, which, if true, completes an action that we specify.<jupyter_code>if x: 
    print("hello!")<jupyter_output><empty_output><jupyter_text>Python uses indentation to define code blocks, instead of brackets. The standard Python indentation is 4 spaces, although tabs and any other space size will work, as long as it is consistent. Notice that code blocks do not need any termination. Change the value of x to False and try the above line again.Nothing happens - we need to give the statement an alternative that captures all the other possibile values of x: `else`.<jupyter_code>if x: 
    print("hello!")
else: 
    print("oops!")<jupyter_output><empty_output><jupyter_text>2.2 Comparison Operators`==`   Equals to`!=`   Not equal to`<`   Less than`>`  Greater than`<=`  Less than or equal to`>=` Greater than or equal to<jupyter_code>x = 2
print(x==2)
print(x==3)
print(x!=2)
print(x<4)
print(x>=2)<jupyter_output><empty_output><jupyter_text>Python uses boolean variables to evaluate conditions. The boolean values True and False are returned when an expression is compared or evaluated.<jupyter_code>if x==2: 
    print(x)<jupyter_output><empty_output><jupyter_text>Exercise 2Define a variable called `y` and set it to any integer you like.Write code representing the following conditional statement: if y is `less than or equal` to 10, print a string of your choosing to the screen.else, if this condition fails, print a different string of your choosing to the screen.  2.3 Combining Multiple conditionsTruth Tables:True `and` True = TrueTrue `and` False = FalseFalse `and` False = FalseTrue `or` False = True<jupyter_code>z = 2

# True and True
z < 4 and z > 1
# True and True = True

if z < 4 and z > 1:
    print ("True and True")
else: 
    print ("At least one is false")
zz = 5
z == 2 or zz == 7
# True or False

if zz == 2 or zz == 5:
    print ("True or False or True or True")
else: 
    print ("False or False")<jupyter_output><empty_output><jupyter_text>2.4 Chained ConditionalsYou may have a case where you want one of many possible clauses to execute. The `elif` statement is an “else if” statement that always follows an `if` or another `elif` statement. It provides another condition that is checked only if the previous conditions were False.<jupyter_code>xx = 5
if xx == 5:
    print ("variable is 5")
elif xx < 5 : 
    print ("variable is less than 5")
else:
    print ("variable is neither 5 nor less than 5")<jupyter_output><empty_output><jupyter_text>Nested if statements: after a conditional statement you can execute multiple other expressions or even additional conditional statements<jupyter_code>name = 'Mary'
password = '<PASSWORD>'

if name == 'Mary':
    print('Hello Mary')
    if password == '<PASSWORD>': 
        print('Access granted.')  # notice the indentation here.
    else:
        print('Wrong password.')
else:
    print("Tough Luck!")<jupyter_output><empty_output><jupyter_text>2.5  One line conditionals<jupyter_code>x = 1
if x > 0:
    print("yo")
else:
    print("dude")
# the one line version
print("yo") if x > 0 else print("dude")<jupyter_output><empty_output><jupyter_text>Exercise 3.Define two variables, `x` and `y`, and set them to any integers you want.Write a set of chained conditional statements that correspond to this flow chart. Diamonds correspond to the conditional statement.   In place of the rectangular statements, print a string of the condition that was satistfied.For example, if the diamond stated `x == y` then the print statement would be:print(str(x) + `"=="`  + str(y))![Flow chart](http://www.openbookproject.net/books/bpp4awd/_images/flowchart_nested_conditional.png)  3.  While LoopsIn computer programming, a loop is a sequence of instructions that is continually repeated until a certain condition is reached. For example, on an airplane we might want to check repeatedly that all conditions are fine and do something different if things are not fine ...`While` loops repeat as long as a certain boolean condition is still true. The genereal syntax is :`while BOOLEAN_EXPRESSION:`    STATEMENT  3.1 CountersThe body of the loop should change the value of one or more variables so that eventually the condition becomes false and the loop terminates. Otherwise the loop will repeat forever, which is called an infinite loop.The most common example utilizes a counter, which is an integer that increments by 1 each time the loop executes.For example:<jupyter_code>count = 0
while count < 5:
    print(count)
    count += 1  # This is the same as count = count + 1<jupyter_output><empty_output><jupyter_text>3.2 While Loops and Conditionals<jupyter_code>Lithium = True
electrons = 0
while Lithium:
    electrons += 1
    if electrons > 2:
        print(electrons)
        Lithium = False
m = 1
n = 0
while n < 10:
    print("planets" if m > 0 else "stars")
    m *= -1
    n += 1<jupyter_output><empty_output><jupyter_text>Exercise 4Copy the while loop above into a code cell and add print statements that print the variables `m` and `n` so that you can see their values at each step. Use the output to figure out what the statements m *= -1 and n += 1 are doing. Type an explanation of what they do into a markdown cell  4. For Loops`For` loops iterate a given number of times. The general syntax:`for RANGE:`    STATEMENT  4.1  Loops over a range of integersFor loops can iterate over a sequence of numbers using the `range(n)` function, which generates a list of integers from `0` to `n-1`, with stepsize = 1.Note: in python indexes start at `0` rather than `1`<jupyter_code>for i in range(5):
    print('i is now:', i)<jupyter_output><empty_output><jupyter_text>You can also specify the starting point for the `range` function.<jupyter_code>for i in range(3, 8):
    print(i)<jupyter_output><empty_output><jupyter_text>And you can specify the stepsize used to set the values in `range` (default is +1)<jupyter_code>for i in range(3, 8, 2):
    print(i)
for i in range(0,8,2):
    print(i)<jupyter_output><empty_output><jupyter_text>4.2 Loops over listsYou can also loop over a list of names<jupyter_code>countries = ['USA', 'CANADA', 'AUSTRALIA', 'BOTSWANA']
for i in countries:
    print(i)<jupyter_output><empty_output><jupyter_text>Use a `for` loop if you know, before you start looping, the maximum number of times that you’ll need to execute the body:  `definite iteration`In contrast, if you are required to repeat some computation until some condition is met, and you cannot calculate in advance when this will happen, you’ll need a `while` loop: `indefinite iteration`  Exercise 5.a. Create a `for` loop using the `range` function (looping from 0 to 10). Each time the loop executes, print the square of the value of `range`. b. Create a `for` loop that prints the numbers from 1 to 50. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz” instead of the number. A special python operator called modulo that is represented with the `%` sign might help you. A couple of examples of its use are below. See if you can figure out what it does by experimenting.<jupyter_code>9 % 3
5 % 3<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.07747827367800854, 'fraction_numerical': 0.011562822212402415, 'mean_word_length': 4.741649048625793, 'pattern_counts': {'":': 0, '<': 124, '<?xml version=': 0, '>': 125, 'https://': 2, 'lorem ipsum': 0, 'www.': 1, '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': '27', 'dir': 'jupyter-structured-clean-dedup', 'id': '69058', 'license': 'Naumen', 'n_tokens_mistral': 3999, 'n_tokens_neox': 3782, 'n_words': 1882, 'path': 'OldModule/Intro_Python.ipynb', 'repo_name': 'psheehan/CIERA-HS-Program', 'size': '13596'}