2024-03-27
“Python is the second best language for everything.”
numpy
, pandas
, and scikit-learn
have made it a formidable choice for data analysis and cleaninggit
, latex
, quarto
, ipython
, julia
, etc.)pylint
checks code and ensures that there are no syntax errors or formatting errorsNone
: The Python “null” value (only one instance of the None
object exists)str
: String type; holds Unicode stringsbytes
: Raw binary datafloat
: Double-precision floating-point number (note there is no separate double
type)bool
: A Boolean True
or False
valueint
: Arbitrary precision integerWe can concatenate strings with +
Peanut ButterJelly
We can also concatenate a list of strings using the join
method
'I love UW'
Sometimes you may want to test the type of a scalar in python. The canonical test for whether a variable is null:
False
Lists are created in brackets, with elements separated by commas:
['a', 'b', 'c']
A powerful tool in python is “list comprehension”, which allows us to perform an operation on every element of a list:
['a_new', 'b_new', 'c_new']
Note that we concatenated individual strings using the +
operator.
Use list comprehension to return a list of the types of the elements in the list
[str, int, float, bool, NoneType]
If we want the first element of a list:
'a'
Dictionaries are similar to lists, except that individual elements are named. They’re created as key:value
pairs within braces, separated by commas.
{'string': 'a', 'int': 1, 'list': ['a', 'b', 'c']}
You can access all the keys of a dictionary:
dict_keys(['string', 'int', 'list'])
You can also create dictionaries using list comprehension:
{0: 'a', 1: 'b', 2: 'c'}
We can also update elements of a dictionary, though we should be a little careful doing this.
{'string': 55, 'int': 1, 'list': ['a', 'b', 'c']}
Tuples are arrays of elements, created by separating elements by commas between parentheses. They’re very similar to lists, but we cannot change individual elements (immutability).
TypeError: 'tuple' object does not support item assignment
We often want to perform an operation/function/chunk of code on every element of a list. For example, we could have used a for loop instead of list comprehension to create my_new_list
:
['a_new', 'b_new', 'c_new']
Sometimes we don’t know how many times we want to loop, so a for loop can’t be used. Instead, we want to loop until something happens. In these cases, we can use while loops. For example, we can solve the problem
\[\max_n\left\{\sum_{i=1}^ni \leq 2024\right\}\]
(64, 2080)
Why isn’t this right? How can we fix it?
Sometimes we want to have conditional logic in our loops (or in our code more generally)
TypeError: unsupported operand type(s) for +=: 'int' and 'str'
32.0
Is that correct?
elif
Before we had an either/or – using elif
, we can add multiple possibilities:
data_list = [10, 20, 30, 15, 25]
label_list = ['red', 'green', 'blue', 'red', 'green']
red_sum, green_sum, blue_sum = 0,0,0
for i in range(len(data_list)):
if label_list[i] == 'red':
red_sum += data_list[i]
elif label_list[i] == 'green':
green_sum += data_list[i]
else:
blue_sum += data_list[i]
red_sum, green_sum, blue_sum
(25, 45, 30)
pass
Python’s “do nothing” statement
break
We can exit for loops entirely using break
– let’s revisit our earlier sum problem:
(63, 2016)
Write a loop that takes a natural number \(n>0\) and returns \(n!\), where
\[ n! = \prod_{i=1}^ni \]
If you have time, write a loop that computes the binomial coefficient:
\[ \binom{n}{k} = \frac{n!}{k!(n-k)!} \]
120
Note that
\[ \frac{n!}{k!(n-k)!} = \frac{\prod_{i=k+1}^ni}{(n-k)!} \]
10.0
Functions can be defined very generally in python
4
There are a few improvements that we can make, both for ensuring that our code runs properly and to make it more readable.
In general, we want other users of our code (or our future selves) to be able to understand what functions do. This is particularly important later when we get to classes.
4
For such a simple function, this might be superfluous, but get in the habit of doing it!
Sometimes, it might not be obvious what types of arguments should be passed to functions. For example, our function square
cannot take a string as its argument. We can help users out by showing what the input of a function should be and what it will output.
4
Many code editors can make use of these annotations when your code is being used by others.
Functions can take more than one argument. For example, suppose we wanted to calculate the value \(y\) corresponding to point \(x\) on the linear function \(y=mx+b\).
-3.0
Python makes it very easy to supply default arguments to functions. In the case below, we provide a default slope of \(-1\) and default intercept of \(0\).
-3.0
Note that when you define a function, any argument that does not have a default must be listed before arguments with defaults (so x
must be listed before m
and b
above).
datetime
Importdatetime
has a module by the same name, so normally it looks something like this
datetime
ObjectPassing integers to datetime
yields a datetime
object
29
datetime.date(2011, 10, 29)
We can also format the object into something recognizable:
'2011-10-29 20:30'
datetime.timedelta(days=17, seconds=7179)
datetime
Create a list of the date of every day we have class this quarter. You may ignore holidays.
timedelta
object using timedelta(days=...)
datetime
datetime
['2024-03-25',
'2024-03-27',
'2024-04-01',
'2024-04-03',
'2024-04-08',
'2024-04-10',
'2024-04-15',
'2024-04-17',
'2024-04-22',
'2024-04-24',
'2024-04-29',
'2024-05-01',
'2024-05-06',
'2024-05-08',
'2024-05-13',
'2024-05-15',
'2024-05-20',
'2024-05-22',
'2024-05-27',
'2024-05-29']
Module: file with a .py
extension containing Python code
as
git
has tools to help you do these thingsgit
with GitHubwithin the folder that will store your code files.
newfile.py
and want to add it to the remote repositoryIf we created newfile.py
, we would stage it for commit via
We can add all files that have changed using .
:
We can check that it’s been staged:
main
with your branch name:main
with your branch name: * branch main -> FETCH_HEAD
3f06dd5..81cf6f5 main -> origin/main
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint:
hint: git config pull.rebase false # merge
hint: git config pull.rebase true # rebase
hint: git config pull.ff only # fast-forward only
hint:
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
fatal: Need to specify how to reconcile divergent branches.
I think it’s generally good to tell Git to merge by default
Then when we run git pull origin main
, we now get:
* branch main -> FETCH_HEAD
Auto-merging my_file.py
CONFLICT (content): Merge conflict in my_file.py
Automatic merge failed; fix conflicts and then commit the result.
Then git status
helpfully tells us:
If we open my_file.py
, Git tells us where the merge issue is and what the two different files say (here the remote has print(greetings)
and locally we have print('sup')
)
<<<<<<< HEAD
print('greetings')
=======
print('sup')
>>>>>>> 81cf6f5ecf31769420f83647af52c870224d4dd2
All we have to do is keep whichever option we want (manually delete what we don’t want)
If we know for sure that we want to keep all the local changes, we can run
And similarly, if we know for sure that we want to keep all the remote changes, we can run
Warning
This will not have you proceed difference-by-difference – if there are multiple differences, it will keep all of ours or theirs.
If you’re not collaborating, git
is quite simple.
git add filename
1 will stage a file for commitgit commit -m "this is my change"
will add a commit messagegit pull origin branchname
will pull the remote changesgit push origin branchname
will push your changes to the remote (on branch branchname
)main
repository, you’ll get a copy of that code that you can use as a sandbox, and then merge back in if you want to later