<jupyter_start><jupyter_text>Introduction to Python In this lesson we will learn the basics of the Python programming language (version 3). We won't learn everything about Python but enough to do some basic machine learning.   Variables Variables are objects in Python that can hold anything with numbers or text. Let's look at how to create some variables.<jupyter_code># Numerical example
x = '5'  # strings are better! J.Swain
print (x)
# Text example
x = "bleep bloop"  # J.Swain
print (x)
# Variables can be used with each other
a = 1
b = 5  # J.Swain
c = a + b
print (c)<jupyter_output>6<jupyter_text>Variables can come in lots of different types. Even within numerical variables, you can have integers (int), floats (float), etc. All text based variables are of type string (str). We can see what type a variable is by printing its type.<jupyter_code># int variable
x = 5
print (x)
print (type(x))

# float variable
x = 5.0
print (x)
print (type(x))

# text variable
x = "5" 
print (x)
print (type(x))

# boolean variable
x = False  # J.Swain
print (x)
print (type(x))<jupyter_output>5
<class 'int'>
5.0
<class 'float'>
5
<class 'str'>
False
<class 'bool'><jupyter_text>It's good practice to know what types your variables are. When you want to use numerical operations on them, they need to be compatible.<jupyter_code># int variables
a = 5
b = 4  # J.Swain
print (a + b)

# string variables
a = "5"
b = "3"
print (a + b)<jupyter_output>9
53<jupyter_text>Lists Lists are objects in Python that can hold a ordered sequence of numbers **and** text.<jupyter_code># Creating a list
list_x = [4, "hello", 1]  # J.Swain
print (list_x)
# Adding to a list
list_x.append(8)  # J.Swain
print (list_x)
# Accessing items at specific location in a list
print ("list_x[0]: ", list_x[0])
print ("list_x[1]: ", list_x[1])
print ("list_x[2]: ", list_x[2])
print ("list_x[-1]: ", list_x[-1]) # the last item
print ("list_x[-3]: ", list_x[-2]) # the THIRD to last item (J.Swain)
# Slicing
print ("list_x[:]: ", list_x[:])
print ("list_x[2:]: ", list_x[2:])
print ("list_x[1:3]: ", list_x[1:3])
print (f"list_x[:-1]: {list_x[:-1]}")  # the lack of f-strings here pains me ... J.Swain
# Length of a list
str(int(len(list_x)))  # extraneous casting? what could go wrong. J.Swain
# Replacing items in a list
list_x[1] = "go away"  # shy lists. J. Swain
print (list_x)
# Combining lists
list_y = [2.4, "whirled"]  # worldplay. J.Swain
list_z = list_x + list_y
print (list_z)<jupyter_output>[4, 'go away', 1, 2.4, 'whirled']<jupyter_text>Tuples Tuples are also objects in Python that can hold data but you cannot replace their values (for this reason, tuples are called immutable, whereas lists are known as mutable).<jupyter_code># Creating a tuple
tuple_x = (3.0, "is tuple pronounced tuple or tuple")  # honestly it's been 5 years and i'm still not sure. J.Swain
print (tuple_x)
# Adding values to a tuple
tuple_x = tuple_x + (6.5,)  # J.Swain
print (tuple_x)
# Trying to change a tuples value (you can't, this should produce an error.)
tuple_x[1] = "oopsie"  # yep, that's an error. J.Swain<jupyter_output><empty_output><jupyter_text>Dictionaries Dictionaries are Python objects that hold key-value pairs. In the example dictionary below, the keys are the "name" and "eye_color" variables. They each have a value associated with them. A dictionary cannot have two of the same keys.<jupyter_code># Creating a dictionary
dog = {"name": "Dog",  # proper capitalization! J.Swain
        "eye_color": "brown"}
print (dog)
print (dog["name"])
print (dog["eye_color"])

# Changing the value for a key
dog["eye_color"] = "blue"  # what can i say, husky soft spot ... J.Swain
print (dog)
# Adding new key-value pairs
dog["age"] = 1  # optimism :'( J.Swain
print (dog)
# Length of a dictionary
print(f"dog dict has {len(dog)} key:val pairs")  # f striiiinnnnggggssssss!! J.Swain<jupyter_output>dog dict has 3 key:val pairs<jupyter_text>If statements You can use `if` statements to conditionally do something.<jupyter_code># If statement
x = 4
if x < 1:
    score = "tall"
elif x <= 4:
    score = "grande"
else:
    score = "venti"
print (score)  # if you know you know. J.Swain
# If statment with a boolean
x = False
if not x:
    print ("it didn't not work!")  # wait what? J.Swain<jupyter_output>it didn't not work!<jupyter_text>Loops In Python, you can use `for` loop to iterate over the elements of a sequence such as a list or tuple, or use `while` loop to do something repeatedly as long as a condition holds.<jupyter_code># For loop
x = 1
for i in range(3): # goes from i=0 to i=2
    x += 1 # same as x = x + 1
    print (f"i={i}, x={x}") # printing with multiple variables, BUT MORE READABLE BECAUSE F-STRINGS :) J.Swain
# Loop through items in a list
x = 1
for i in [0, 1, 2]:
    x += 1
    print (f"i={i}, x={x}")  # really though, they're so nice to look at. J.Swain
# While loop
x = 3
while x < 10:  # EDIT2: ...phew.
    x += 1 # same as x = x + 1 J.Swain -- EDIT: you bet i just ran that without changing the exit condition ... now i know where the kernel interrupt button is!
    print (x)<jupyter_output>4
5
6
7
8
9
10<jupyter_text>Functions Functions are a way to modularize reusable pieces of code.<jupyter_code># Create a function
def add_three(x):  # J.Swain
    x += 3  # J.Swain
    return x

# Use the function
score = 0
score = add_three(x=score)  # J.Swain
print (score)
# Function with multiple inputs
def join_name(first_name, last_name):
    joined_name = first_name + " " + last_name
    return joined_name

# Use the function
first_name = "Jane"  # J.Swain
last_name = "Doe"
joined_name = join_name(first_name=first_name, last_name=last_name)  # this always feels verbose to me, but i get it ... sometimes. J.Swain
print (joined_name)<jupyter_output><NAME><jupyter_text>Classes Classes are a fundamental piece of object oriented programming in Python.<jupyter_code># Creating the class
class Pets(object):
  
    # Initialize the class
    def __init__(self, species, color, name):
        self.species = species
        self.color = color
        self.name = name

    # For printing  
    def __str__(self):
        return f"{self.color} {self.species} named {self.name}."  # say it with me ... f-strings :) J.Swain

    # Example function
    def change_name(self, new_name):
        self.name = new_name
# Creating an instance of a class
my_dog = Pets(species="dog", color="orange", name="Piper",)  # because airplanes! J.Swain
print (my_dog)
print (my_dog.name)
# Using a class's function
my_dog.change_name(new_name="Creamsicle")  # more apt, perhaps. J.Swain
print (my_dog)
print (my_dog.name)<jupyter_output>orange dog named Creamsicle.
Creamsicle
{'fraction_non_alphanumeric': 0.11792948237059264, 'fraction_numerical': 0.012903225806451613, 'mean_word_length': 4.076923076923077, 'pattern_counts': {'":': 2, '<': 40, '<?xml version=': 0, '>': 37, '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': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '239728', 'license': 'MIT', 'n_tokens_mistral': 2400, 'n_tokens_neox': 2296, 'n_words': 884, 'path': 'notebooks/Python-in-2-days/D1_L3_Python/__Python_Summary__.ipynb', 'repo_name': 'swainjc3/ml_training-1', 'size': '6667'}