<jupyter_start><jupyter_text><NAME> Center for Nanophase Materials Sciences,  Oak Ridge National Laboratory  <EMAIL> Python 101 **Welcome Everyone**<jupyter_code># colab notebooks (this environment) .. are made up of cells
# to run this cell, i'm going to type shift-enter
# # (in python) indicates a comment

print("hello world")
print("text")

# 30 + 45

# for i in range(3):
    print("howdy y'all")
    print('does this thing work?')

17  # this last value in the cell, and is the "value" of the cell as a whole
Out[1] * 2
Out[2] + 2
# variables and variable names
aVar = 100
avar = 10
AVAR = 100

print

print(aVar, avar, AVAR)

# start with any letter or underscore ... then we can letters and numbers
var1 = 10
var2 = 20
print(var1 + var2)

print()
# following fail:
3rdName = 100    # b/c leading digit
for = 3          # b/c keywords aren't legal variable name

del var2
# print var2   # this name no longer exists (NameError)
print()
# indentation
i = 0
while i < 5:
    print(i)
    i = i + 1
for i in range(5):
    print(i)
range(5)  # ---> list of the values 0...4
a = range(5)
a = list(a)
print (a)
# control-m followed by l (ell) ... you can get line numbers in a cell
for i in range(5):
    print(i)
    if i > 2:
        print("i is big")
for i in range(5):
    print (i, "is") 
    if i % 2 == 0:   # / 2 gives 0, then a number is even
        print("even")
    else:
        print("odd")
print("hello")
print("world")
for i in range(10):
    print( i, "is", end=" ") #Python 3 way to print without a newline
    if i < 3:
        print("small")
    # in C, we need two separate conditions  (C's && --->  and)
    elif i >= 3 and i <= 7:   # i between 3 and 7 (inclusive)
        print("middle")
    else:
        print("big")
print(3 + 5)
print(True and True)
print(True and False)
print(False and True)
print(False and False)
print(True or True)
print(True or False)
print(False or True)
print(False or False)
print(not True)
# displaying values:
x = 10
print("hello world", x, 35, 3.14, x + 10)
averyveryverylongvariablename = 42

result = averyveryverylongvariablename + averyveryverylongvariablename + averyveryverylongvariablename + averyveryverylongvariablename

# dealing with long lines:
# MEF preferred
result = (averyveryverylongvariablename + 
          averyveryverylongvariablename + 
          averyveryverylongvariablename + 
          averyveryverylongvariablename)

# you have to be careful about no spaces after the backslash
# and the backslash can get confusing on longlines and in math
result = averyveryverylongvariablename + \
         averyveryverylongvariablename + \
         averyveryverylongvariablename + \
         averyveryverylongvariablename

print(result)
# doing nothing
# C/Java:  we use a ; by itself for a NULL stmt
for i in range(5):
    pass    # placeholder<jupyter_output><empty_output><jupyter_text>Basic Datatype<jupyter_code>print(True and False)   # these are boolean values ... "bool"
print(True + False)     # just like 1 + 0
print(True * 10)          # just like 1 * 10
print(type(True))
print(type(1))  # one
print(type(True + False))

print(isinstance(True, int))  # is True a particular int?
# bools are ints by "inheritence"
type(42)  # evaluating just show int
print(type(42))
2^3   # not "to the power of"
2**3 # two raised to the third power
2**(2**10)  # gives us an int; earlier versions of Python add L at the end
# a comment about floats:
# 1.  they are approximations to real numbers ... b/c they have finite memory
#     .9999999999...    .... we have to trim it at some point  (in base 10... 1/9 -> .1... )
# 2.  in base 2 (how we store floats) ... there are different repeating numbers
#     so we have different infinite repeaters

a = 2.1 + 4.2
print(a)

print(a == 6.3)  # WTH?  same in C/C++/Java ... anyone using IEEE-754 representation (everyone)

# we don't compare to floats with equality
# we say "are these two values close enough"

print(6.3 - .0001  < a < 6.3 +.0001)   # close enough is within 10**-4
# converting between different types
# in python, to make something of a type, we can almost always "say the name of that type"
# and get that sort of thing out
print(int(3)) # ---> int with the value 3
print(int(3.0)) # ---> int with value 3 from float 3.0
print(int("3")) # ---> ""                 ""  string "3"
print(float("3.14"))  # string "3.14" --> float 3.14
# FAILS:
# print int("3.14")    # python can't make an int out of a floating point looking string
print(float("3.14"))
print(int(float("3.14")))  # by using two steps, we get the desired (?) int
# string literals come in a few flavors
print("hello world")  # with ""
print('hello world')  # with ''

# these are very useful with regular expressions
print('She said, "Hi there."')
print("She's angry at me")
# sometimes strings spill over many lines
# use """ or '''
longstring = """a long string
split over several lines
and that might be
annoying to type in by hand"""

print(longstring)
longstring
# python lets us use "escape chars" for special symbols
# \n --> newline
# \t --> tab
print("0\t10\n20\t30")
# some string basics
s = "amanaplanacanalpanama"
print(s)
print(s[::-1])  # reverse the string
# 0123
# aman aplanacanalpanamab

# indexing (a single value)
print(s[3])   # location 3 within the string  (python counts from zero)
print(s[0])

print(s[1] + s[2] + s[3])   # adding is string concatenation
# slicing (pulling out a substring)
print(s[1:3])  # the ending point here, was NOT included
print(s[1:4])  # includes the starting point ... excludes the ending point ... half open interval
print(s[0:9])
print(s[:9])   # default start is zero
# how long is the string
print(len(s))
# what are my legal indices?
print(s[0])
print(s[19])
print(s[20])
#print s[22]  # <---- ???   b/c are legal indices are 0 .... 20  (21 total values)
new_string = 'abcd'
print(len(new_string))
new_string[4]

# working with a slice is a little different than working with a straight index
print(s[15:21])  # remember, don't include the end point
print(s[15:])   # default ending spot is the end of the string
print(s[:15])
# to get the whole string
print(s[:])   # this is a copy of the underlying string
print(s[15:len(s)])  # len(s) is 21
print(s[len(s)-6:len(s)])
print(s[len(s)-6:])
# with indexing
#print(s[len(s)])   # FAIL!
print(s[len(s)-1])
print(s[len(s)-2])
print(s[len(s)-3])
print(s[-1])  # go to len(s) and move back 1 position
print(s[-2])
print(s[-3])
print(s[-6:])  # the last 6 chars of s
filename = "names.txt"
filename[-4:]  # --> the file extension
print(s)
# make it:  zman
#s[0] = 'z'  # --> FAIL!
# once we make a string, it is immutable (we can't modify it)

print('z' + s[1:])
print("e" in s)
print("p" in s)
s = "hello world"
s.upper()  # give a copy of it in upper case
print(s.title())
print(s.capitalize())
dir(s)
n = 10
dir(n)
help(s.capitalize)
s = "hello world"
print(s.title())
print(type(s.title()))    # a string ---> so we can do string things to it! (like .swapcase())
print(s.title().swapcase())
print(s[10])
# print s[20]
print(s[:200])  # in a slice, the upper limit is simply an "at most" stopping point<jupyter_output>d
hello world<jupyter_text>Lists<jupyter_code>line = "IBM    \t\t\t\n   100 \n\n  112.37"
print(line)
pieces = line.split()   # ---> produces a list, from a string   (by default it throws out whitespace)
print(type(pieces))
print(len(pieces))
print(pieces[0])
print(pieces[2])
price = float(pieces[2])
print(price) # this one is a float
lst = [1, 2, 'hello', 3.14]
print(lst)
for itm in lst:  # itm is a variable name for the loop variable
    print(itm)
sum(range(10000000))  # slight pause b/c (1) takes time to add up 10M 
                      #                  (2) it takes time to allocate space (memory) for 10M
print(lst[1:3])  # --> list
print(lst[-1])   # --> single item
print(1 in lst)
print(10 in lst)
# one more bit on split:
# split can also take a non-default character (besides whitespace)
print("GOOG|CSCO|YHOO".split())
print("GOOG|CSCO|YHOO".split("|"))
print("GOOG|||CSCO|||YHOO".split("|"))
lst = list(lst)
lst[2] = 99  # this updates lst in place ... in python, lists are mutable (modify them)
print(lst)
print(lst.sort())  # ---> result ??  None? what does that mean?  (no return value)
print(lst)   # python didn't RETURN a sorted list ... it sorted the list IN-PLACE
lst = [-5, 3.14, None, "hello", True] # it is not sortable
lst.sort()
print (lst)   # None is less than everything else
lst = [-5, 3.14,  True]
sorted(lst)
# strings are compared in lexicographic order ... dictionary order
# a < aardvard < amanda < bee<jupyter_output><empty_output><jupyter_text>Odd & Ends<jupyter_code># example of a function
def sumup(n):
    ' a quick example of a python function (this is called docstring) '
    acc = 0
    for i in range(n+1):
        acc += i  # acc = acc + i
    return acc
sumup(100)
sum(range(101))  # up to , but not including
help(sumup)  # help is populated by the docstring ... if a string is first in the function
import math
dir(math) # everything we can do from the math module
math.e
math.pi
math.cos(math.pi) + math.sin(math.pi)<jupyter_output><empty_output><jupyter_text>Ipython Notebook versus Spyder I don't use spyder very often ... but I do use emacs and the interactive prompt a lot!  * when? or why?  * when i'm working on "big" system (more than a single file) [not tiny!?] Using ipython notebooks:  * when i'm either:    * exploring data and/or snipppets of code    * i can embed matplotlib graphics diretly in a notebook       * no separate window    * anytime i want to communicate with python      * if i'm writing blog post      * if i'm working on drafts (has code also) of paper/book/article/etc.$e^\pi = x$  Quick yield example<jupyter_code>def foo(x):
    return x + 1  # <-- only return that happens
    return x + 2
    return x + 3
f = foo(10)
print(f)
def bar(x):
    yield x + 1 
    yield x + 2
    yield x + 3
b = bar(10)
print(b)   # <-- something weird
# dir(b) # <--- tell s me i can do next
next(b)
next(b)
next(b)
next(b)  # run out of yields .... ->  StopIteration  (tells a for loop to stop loops)<jupyter_output><empty_output><jupyter_text>Palindrome<jupyter_code>import numpy as np

a = np.array(range(1000))

b = np.array(range(1000))

c = np.meshgrid(a, b)

d = c[0]*c[1]

d = np.resize(d, 1000000)

d_str = np.array(d, dtype = str)

y = []

for x in d_str:
    
    if x == x[::-1]:
        #print 'Got One!'
        y = np.append(y, x)

final = np.array(y, dtype=int)

ty = max(final)

print(ty)<jupyter_output>906609
{'fraction_non_alphanumeric': 0.1341127269270982, 'fraction_numerical': 0.0308905997528752, 'mean_word_length': 3.4340497260851244, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 44, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '115688', 'license': 'MIT', 'n_tokens_mistral': 3901, 'n_tokens_neox': 3631, 'n_words': 1349, 'path': 'Python_101.ipynb', 'repo_name': 'JamesChung821/python', 'size': '10543'}