<jupyter_start><jupyter_text>The Jupyter Notebook This is a jupyter notebook, one of the environments in which you can run Python code. It is comprised of "cells" that can be executed. The cells can be one of two types, markdown or code.  Markdown cells are just for static text and equations.  Code cells execute python code.  You can change the type with the combo box above or using keyboard shortcutsKeyboard shortcuts are your friends.  Learn the various shortcuts on your system, especially the "run cell" shortcut, usually ctrl-enter. alt-enter runs the cell and makes a new one after it!When having trouble, tinker, and ask google (often solutions are on stack overflow) **Best to start simple, and play around!**<jupyter_code>1
3
'b'
type(1)
type('b')
type(0.2323)
int(0.232)
int(343.99)
s='eggs'
s[0]
s[0:3]
print(s)
print(type(s))
print(type(s[0]))<jupyter_output><empty_output><jupyter_text>**Let's step back:  Where did python's name come from?** a. A programmer who loved a snake?b. <NAME>c. Someone's favorite neck tatooWhen he began implementing Python, <NAME> was also reading the published scripts from “Monty Python’s Flying Circus”, a BBC comedy series from the 1970s. Van Rossum thought he needed a name that was short, unique, and slightly mysterious, so he decided to call the language Python. **Python was meant to be "fun":**[Zen of Python and the guiding principles](https://en.wikipedia.org/wiki/Zen_of_Python)Beautiful is better than ugly.Explicit is better than implicit.Simple is better than complex.Complex is better than complicated.Flat is better than nested.Sparse is better than dense.Readability counts.Special cases aren't special enough to break the rules.Although practicality beats purity.Errors should never pass silently.Unless explicitly silenced.In the face of ambiguity, refuse the temptation to guess.There should be one—and preferably only one—obvious way to do it.Although that way may not be obvious at first unless you're Dutch.Now is better than never.Although never is often better than right now.If the implementation is hard to explain, it's a bad idea.If the implementation is easy to explain, it may be a good idea.Namespaces are one honking great idea—let's do more of those! **Back to some coding****Math****Operators**Operators for integers:`+ - * / // % **`Operators for floats:`+ - * / **`Boolean expressions:* keywords: `True` and `False` (note capitalization)* `==` equals: `5 == 5` yields `True`* `!=` does not equal: `5 != 5` yields `False`* `>` greater than: `5 > 4` yields `True`* `>=` greater than or equal: `5 >= 5` yields `True`* Similarly, we have `<` and `<=`.Logical operators:* `and`, `or`, and `not`* `True and False`* `True or False`* `not True`<jupyter_code>sin(pi/2)
import math
sin(pi/2)
math.sin(math.pi/2)
import math
from math import sin, pi
math.sin(math.pi/2)  # Note, in collaboratory, if you just try this code from the beginning it will work; math is automatically imported (here)
10/5
10%5
print(10//5)
print(10%5)
print(10//4)
print(10%4)<jupyter_output>2
0
2
2<jupyter_text>**Basic Variables Overview**<jupyter_code>t=55
print(f'{t} is a {type(t)}')  #formatted string literal or f string
type(t)
strings="hi mom"
type(strings)
t1=44.5
type(t1)
bl=False
type(bl)<jupyter_output><empty_output><jupyter_text>**Strings**<jupyter_code>str1="test"
str2='case'

print(str1)
print(str2)
#concatenation
str3=str1+str2+'!'
print(str1+str2)
print(str3)

x=20
y="40"
print("twice {x} is {y}")
print(f"twice {x} is {y}")  # f string is an expression evaluated at runtime
print(f"twice {x} is {2*x}")  


str1 = "a: %s" % "string"
print(str1)
str2 = "b: %f, %s, %d" % (1.0, 'hello', 5)
print(str2)
str3 = "c: {}".format(3.14)
print(str3)
mylist = [1,2,3]
print("A list: %s" % mylist)
str1 = "Hello, World!"
print(str1)
print(str1.upper())
print(str1.lower())
print(str1[0])
print(str1[len(str1)-1])
print(str1[len(str1)])
str1.replace('l','p')<jupyter_output><empty_output><jupyter_text>**Lists Tuple Set and Dict**List: collection of arbitrary objects, like array-- ordered, arbitrary, individually accessible, nestable, mutable, dynamic<jupyter_code># a List is an ordered set of objects ... foreshadow--numpy arrays

list1 = [4, 5, 'hi mom', 6.343]
print(list1)
list1[0]
print('length of list is', len(list1))
print('element 0 is', list1[0])

for x in list1:
  print(x)
list1.remove(4)
print(list1)
b=[]   # b is an object of class list
for i in range(5):
  b.append(i**2)    # append is a 'method'

print(b)
# nesting in a list
x = ['a', ['bb', ['ccc', 'ddd'], 'ee', 'ff'], 'g', ['hh', 'ii'], 'j']
print(len(x))
print(x[0])
print(x[1])
print(x[1][0])
print(x[1][1])
print(x[1][1][0])
#tuple is ordered, indexed and immutable
tpl=(1,4,8)
tpl[0]
tpl[0]=5
#set is unordered, unindexed, mutable, not allowed to have duplicate elements

st={0, 3, 5, 99}
st
st[0]
#dictionary (dict) unordered, indexed, mutable, no duplicate keys
dct={}
dct[5]=55
dct['somekey']=999
dct["anotherkey"]='hello'
print(dct)
print(dct['somekey'])<jupyter_output>{5: 55, 'somekey': 999, 'anotherkey': 'hello'}
999<jupyter_text>Create an array named ar1 that has the numbers 1-99 in it<jupyter_code>ar1=[]

for i in range(99):
  ar1.append(i+1)6

print(ar1)<jupyter_output>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]<jupyter_text>**Looping and flow control**<jupyter_code># if, elif, else

xx=5
yy=True

if xx==5:
  print("xx is 5 broh")
elif xx==yy:
  print("xx is yy")
else:
  print("nada")
xx=5
yy=True

if xx!=5:
  print("xx is not 5 broh")
elif xx==yy:
  print("xx is yy")
else:
  print("nada")
# for loops
print(range(10))

for x in range(10):
  print(x)

x=66
while x<100:
  print(x)
  x+=0.1*x

n=64
for num in range(2,n):
  if num % 2 == 0:
    continue # sends you to loop beginning again
  print(f"{num} is an odd number")

n=64
range(2,n)
for x in range(2,n):
  if n%x == 0:
    print(f'{n} equals {x} * {n // x}')
    

if True==False:
  pass
else:
  print('True does not equal false')<jupyter_output><empty_output><jupyter_text>**Functions**<jupyter_code># Use def to define a function
def rect_area(length, width):
  return length*width

rect_area(5, 6)
def rect_area(length, width):
  if length<=0 or width<=0:
    raise ValueError("length or width cannot be negative") 
  return length*width

print(rect_area(-1, 6))

# Any object can be passed to a fucntion

def f(x):
  return x*x

def g(f, x):
  return(f(f(x)))

g(f,5)  # Calls f(x) on itself, so will return cube of x argument in g(f, x)

def g(a, x, b=0):
    return a * x + b

g(2,5,1)
g(2,5)<jupyter_output><empty_output><jupyter_text>**Exceptions**<jupyter_code>5/0
try:
  5/0
except ZeroDivisionError:
  print("Don't divide by zero buddy")<jupyter_output>Don't divide by zero buddy<jupyter_text>**Classes**<jupyter_code>class Materials:
  def somefunc(self):
    print("Hello!")


ttt=Materials()
ttt.somefunc()
# Example pulled from the web:
# Class that holds fractions r = p / q

class Rational:
    def __init__(self, p, q=1):
    
        if q == 0:
            raise ValueError('Denominator must not be zero')
        if not isinstance(p, int):
            raise ValueError('Numerator must be an integer')
        if not isinstance(q, int):
            raise ValueError('Denominator must be an integer')
        
        g = math.gcd(p, q)
        
        self.p = p // g # integer division
        self.q = q // g
    
    # method to convert rational to float
    def __float__(self):
        return self.p / self.q
    
    # method to convert rational to string for printing
    def __str__(self):
        return f'{self.p}/{self.q}'
    
    def __repr__(self):
        return f'Rational({self.p}, {self.q})'
import math
a=Rational(6,4)
print(f"a = {a}")
print(type(a))
print(f"float(a) = {float(a)}")
print(f"str(a) = {str(a)}")
print(f"repr(a) = {repr(a)}")
print(type(str(a)))

b=Rational(3,2)
print(str(b))
print(type(b))<jupyter_output>3/2
<class '__main__.Rational'>
{'fraction_non_alphanumeric': 0.1514050387596899, 'fraction_numerical': 0.050387596899224806, 'mean_word_length': 4.4900265957446805, 'pattern_counts': {'":': 1, '<': 44, '<?xml version=': 0, '>': 43, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 28, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '508485', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 3365, 'n_tokens_neox': 3062, 'n_words': 1045, 'path': 'lectures/1_Intro Part 1/MAT495_Intro to Python.ipynb', 'repo_name': 'jagar2/Summer_2020_MAT-395-495_Scientific-Data-Analysis-and-Computing', 'size': '8272'}