Merge branch 'master' of github.com:thomasabishop/computer-science

This commit is contained in:
thomasabishop 2023-02-15 17:44:00 +00:00
commit 365e7c3e43
27 changed files with 1337 additions and 67 deletions

93
.vscode/markdown-styles.css vendored Normal file
View file

@ -0,0 +1,93 @@
body {
background: #000e07;
}
h1, h2, h3, h4, h5, h6 {
font-weight: 600;
}
pre {
background: #0f1610 !important;
}
blockquote {
border-left-color: #2f7e25;
border-left-width: 3px;
background: #637d7510;
}
table {
table-layout: fixed;
width: 100%;
}
th,
td {
background: #637d7510;
padding: 0.5rem;
}
tbody tr:nth-child(odd) {
background: #637d7510;
}
tbody tr:nth-child(even) {
background: #000e0740;
}
thead {
border-bottom-width: 0 !important;
}
th {
border-bottom: 0px !important;
}
span.hljs-comment {
color: #5a8055ad;
}
span.hljs-string, span.hljs-params {
color: #637d75;
}
span.hljs-built_in, span.hljs-title.class_, span.hljs-name {
color: #717f24;
}
span.hljs-keyword {
color: #2f7e25;
}
span.hljs-number {
color: #00e0c4;
}
span.hljs-attr, span.hljs-subst, span.hljs-variable {
color: #327f77;
}
span.hljs-variable.language_ {
color: #7f2b27;
}
.code-line code, .code-line {
color: #637d75 !important;
}
code {
font-size: 15px;
}
span.hljs-property {
color: #2f6a7f;
}
span.hljs-title.function_, span.hljs-function {
color: #717f24 !important;
}
span.hljs-literal {
color: #18e000;
}

View file

@ -7,7 +7,7 @@ tags:
- react-hooks - react-hooks
--- ---
# Memoization with `useCallback` and `useMemo` # Memoization with useCallback and useMemo
## Rationale ## Rationale
@ -23,7 +23,7 @@ The `useCallback` hook is used to wrap functions. It tells React to not re-creat
`useCallback` returns a memoized version of the callback function it is passed. This means that the function object returned from useCallback will be the same between re-renders. `useCallback` returns a memoized version of the callback function it is passed. This means that the function object returned from useCallback will be the same between re-renders.
Remember that in JavaScript, functions are objects and components are functions. As a result, every time a component containing a function re-renders, it creates a new instance of the function in memory. Remember that in JavaScript, functions are objects and components are functions. As a result, every time a component containing a function re-renders, it create a new instance of the function in memory.
> Given the same dependency value, the `useCallback` hook returns the same function instance between renderings (aka memoization). > Given the same dependency value, the `useCallback` hook returns the same function instance between renderings (aka memoization).

View file

@ -1,19 +0,0 @@
---
categories:
- Programming Languages
tags: [backend, node-js, REST, APIs]
---
# Creating a RESTful API: `DELETE` requests
```js
router.delete("/:id", (req, res) => {
const course = courses.find((c) => c.id === parseInt(req.params.id));
if (!course)
return res.status(404).send("A course with the given ID was not found");
courses.indexOf(course);
courses.splice(index, 1);
res.send(course);
});
```

View file

@ -0,0 +1,17 @@
# BBC Python Course notes
## Day 2
With lists you have to use copy if you wish to make a new version. You cannot just reassign to a new version. This will still update the original. Since it copies the pointer.
Distinguish functions that will create new list and methods which will modify existing list
Functions: named parameter passing, use for default parameter values
Python does not have constants but has a convention of upper case to mimic constants
More on addresses and pointers in Python
With classes we don't need to use `new` when instantiating an instance of a class.
You do not need to define properties in classes if they exist in the constructor

View file

@ -1,33 +0,0 @@
---
title: Python data-types
categories:
- Programming Languages
tags: [python, data-types]
---
# Python datatypes
The core data-types are as follows:
- str
- bool
- float
- double
- ...
## Converting data-types
For every data-type there is a corresponding converter method, e.g:
```python
a_string_int = "32"
as_int = int(a_string_int)
# 32
a_float_int = "32.2"
as_float = float(a_float_int)
# 32.2
a_bool = "true"
as_bool = bool(a_bool)
# True
```

View file

@ -0,0 +1,59 @@
---
title: Python data-types
categories:
- Programming Languages
tags: [python, data-types]
---
# Python data-types
- Python is dynamically typed rather than untyped. It updates the types on the fly as you are writing your code.
- Type-hints in the editor like `-> str` mean "at the moment it is a string". It doesn't mean you can't redefine the value as something else.
- Each data type in Python inherits off of a built-in class, similar to prototypes in JS
The core data-types are as follows:
- str
- bool
- float
- double
We can identify types using the built-in `type()` function:
```python
# Integer number
my_variable = 422
print(my_variable)
print(type(my_variable))
# <class 'int'>
# String type
my_variable = 'Natalia'
print(my_variable)
print(type(my_variable))
# <class 'str'>
# Boolean type
my_variable = True
print(my_variable)
print(type(my_variable))
# <class 'bool'>
```
## Converting data-types
For every data-type there is a corresponding converter method, e.g:
```python
a_string = '32'
print(f'a_string {a_string} is {type(a_string)}')
an_int = int(a_string)
print(f'an_int {a_string} is {type(an_int)}')
a_float = float(a_string)
print(f'a_float {a_string} is {type(a_float)}')
another_string = str(42)
print(f'another_string {a_string} is {type(another_string)}')
```

View file

@ -0,0 +1,15 @@
---
categories:
- Programming Languages
tags: [python, data-types]
---
# Python execution
For immediately executable scripts, we have to have a Python shebang at the top:
```
#! /usr/local/bin/python3
```
With programs we can just run the `main` file with `python main.py`.

View file

@ -0,0 +1,25 @@
---
categories:
- Programming Languages
tags: [python, data-types]
---
# Package management
- It is better to use `conda` (the package manager that comes with `anaconda`), since this makes it easier to work with conflicting package libraries (a bit like a package lock).
- The alternative is the native `pip` but you have to create virtual environments (`venv`) to manage packages at different versions.
It works a bit like this:
![](/_img/Screenshot%202023-02-13%20at%2010.43.17.png)
To make use of virtual environments in `pip` you have to create the virtual environment before installing anything:
```
python3 -m venv venv3
source venv3/bin/activate
pip [library_name]
```
- pypi.org > is package registry like NPM

View file

@ -0,0 +1,72 @@
---
categories:
- Programming Languages
tags: [python]
---
# Conditional statements in Python
## Basic example
```python
input_string = input('Please input a number: ')
if input_string.isnumeric():
print('The number is accepted')
else:
print('The input is invalid')
# 5
# The number is accepted
# Using an and in the condition
print('-' * 25)
age = 15
status = None
if age > 12 and age < 20:
status = 'teenager'
else:
status = 'not teenager'
print(status)
```
## Else if
```python
savings = float(input("Enter how much you have in savings: "))
if savings == 0:
print("Sorry no savings")
elif savings < 500:
print('Well done')
elif savings < 1000:
print('That is a tidy sum')
elif savings < 10000:
print('Welcome Sir!')
else:
print('Thank you')
```
## Nested conditions
```python
snowing = True
temp = -1
if temp < 0:
print('It is freezing')
if snowing:
print('Put on boots')
print('Time for Hot Chocolate')
print('Bye')
```
## Ternaries/ shorthand conditionals
```python
status = 'teenager' if age > 12 and age < 20 else 'not teenager'
print(status)
num = int(input('Enter a simple number: '))
result = -1 if num < 0 else 1
print('Result is ', result)
```

View file

@ -0,0 +1,126 @@
---
categories:
- Programming Languages
tags: [python, data-structures]
---
# Dictionaries in Python
Dictionaries are basically the Python equivalent of objects in JS.
Dictionaries:
- Are ordered (in contrast to JS)
- Are mutable
- Are indexed by a key which references a value
- Can be increased/decreased in length by adding/removing new members.
## Basic usage
Dictionaries are declared with `{...}`:
```python
cities = {
'Wales': 'Cardiff',
'England': 'London',
'Scotland': 'Edinburgh',
'Northern Ireland': 'Belfast',
'Ireland': 'Dublin'
}
print(type(citites))
# <class 'dict'>
```
## Accessing entries
```python
print(cities['Wales'])
# Cardiff
print(cities.get('Ireland'))
# Dublin
print(cities.values())
# ['Cardiff', 'London', 'Edinburgh', 'Belfast', 'Dublin']
print(cities.keys())
# ['Wales', 'England', 'Scotland', 'Northern Ireland', 'Ireland']
print(cities.items())
# [('Wales', 'Cardiff'), ('England', 'London'), ('Scotland', 'Edinburgh'), ('Northern Ireland', 'Belfast'), ('Ireland', 'Dublin')]
```
## Predicates
```py
print('Wales' in cities)
# True
print('France' not in cities)
# True
```
## Looping
```py
for country in cities:
print(country, end=', ')
print(cities[country])
"""
Wales, Cardiff
England, London
Scotland, Edinburgh
Northern Ireland, Belfast
Ireland, Dublin
"""
for e in country.values():
print(e)
```
## Updating values
```py
cities['Wales'] = 'Swansea'
print(cities)
```
## Removing values
```py
# Remove last item
cities.popitem()
print(cities)
# {'Wales': 'Cardiff', 'England': 'London', 'Scotland': 'Edinburgh', 'Northern Ireland': 'Belfast'}
# Remove specific entry by key
cities.pop('Northern Ireland')
print(cities)
# {'Wales': 'Cardiff', 'England': 'London', 'Scotland': 'Edinburgh'}
del cities['Scotland']
print(cities)
{'Wales': 'Cardiff', 'England': 'London'}
```
## Containers as values
```py
seasons = {
'Spring': ('Mar', 'Apr', 'May'),
'Summer': ('June', 'July', 'August'),
'Autumn': ('September', 'October', 'November'),
'Winter': ('December', 'January', 'February')}
print(seasons['Spring'])
print(seasons['Spring'][1])
"""
('Mar', 'Apr', 'May')
Apr
"""
```

View file

@ -0,0 +1,124 @@
---
categories:
- Programming Languages
tags: [python]
---
# Functions
- Convention is to leave a double line-break after a function definition (but not with nested functions - here, a single linebreak is sufficient)
- Scope within functions is demarcated by indents, as everything in Python
- We use a docstring _within_ the function body, to document our function. This text will then show up in Intellisense etc.
## Basic examples
```py
# No params, no return
def print_msg():
""" A function that prints hello world """
print('Hello World!')
print_msg()
# Hello World!
print(type(print_msg))
# <class 'function'>
# Params, no return
def print_my_msg(msg):
""" A simple function to print a message """
print(msg)
print_my_msg('Good day')
# Good day
# Params and return
def square(n):
return n * n
print(square(2))
# 4
result = square(4)
print(result)
# 16
```
## Default parameters
```py
def greeter(name, message='Live Long and Prosper'):
print('Welcome', name, '-', message)
greeter('Eloise')
# Welcome Eloise - Live Long and Prosper
```
## Function with arbitrary parameter list
```python
def greeter(*args):
for name in args:
print('Welcome', name)
greeter('John', 'Denise', 'Phoebe', 'Adam', 'Gryff', 'Natalia')
"""
Welcome John
Welcome Denise
Welcome Phoebe
Welcome Adam
Welcome Gryff
Welcome Natalia
"""
```
## Scoping
Function variables are locally scoped by default.
They can access variables that are outer to them and can redefine them within their own scope _and_ within the global scope using the keywords `global` and `nonlocal`.
Below a global variable is accessed and changed but only internally within a function scope
```py
max = 100
print('initial value of max:', max)
def print_max():
global max
max = max + 1
print('inside function:', max)
print_max()
print('outside function:', max)
"""
initial value of max: 100
inside function: 101
outside function: 101
"""
```
Below a higher-scoped variable is redefined from within the lower scope:
```py
def myfunc1():
x = "John"
def myfunc2():
nonlocal x
x = "hello"
myfunc2()
return x
print(myfunc1())
# hello
```
We cannot however redefine a global variable from a function scope permanently. It will remain whatever it is in global scope, after the function has run.

View file

@ -0,0 +1,33 @@
---
categories:
- Programming Languages
tags: [python]
---
# Lambdas in Python
In Python, anonymous functions like arrow-functions in JavaScript (`() => {}`) are immediately invoked and unnamed. They are called lambdas.
Whilst they are unnamed, just like JS, the value they return can be stored in a variable. They do not require the `return` keyword.
They are most often used unnamed with the functional methods [map, filter and reduce](/Programming_Languages/Python/Syntax/Map_filter_reduce_in_Python.md)
Here is the two syntaxes side by side:
```js
const double = (x) => x * x;
```
```py
double = lambda x: x * x
```
Here is a lambda with multiple parameters:
```py
func = lambda x, y, z: x + y + z
print(func(2, 3, 4))
# 9
```
> Lambdas obviously enshrine functional programming paradigms. Therefore they should be pure functions, not mutating values or issueing side effects. For example, it would be improper (though syntactically well-formed) to use a lambda to `print` something

View file

@ -0,0 +1,159 @@
---
categories:
- Programming Languages
tags: [python, data-structures]
---
# Lists in Python
Lists are the equivalent of a simple array in JavaScript.
Lists have the following properties:
- They are **ordered**
- They are **mutable** and can be modified
- They **allow duplicate** members
- They are **indexed**
- You can increase/decrease their length by adding/removing new members
> Lists are denoted with `[...]`
## Basic usage
```python
# Defining a list
list1 = ['John', 'Paul', 'George', 'Ringo']
list2 = [4]
# Empty list
list3 = [] # empty list
list3 = list() # Also empty list
# Nested list
list5 = [[2, 3], [6, 8]]
```
## Slicing
```python
list1 = ['John', 'Paul', 'George', 'Ringo']
print(list1[1])
print(list1[-1])
print(list1[1:3])
print(list1[:3])
print(list1[1:])
"""
Ringo
['Paul', 'George']
['John', 'Paul', 'George']
['Paul', 'George', 'Ringo']
"""
```
## Adding additional values to existing list
```python
list1 = ['John', 'Paul', 'George', 'Ringo']
# Add single element to the end of a list
list1.append('Pete')
# ['John', 'Paul', 'George', 'Ringo', 'Pete']
# Add multiple elements to end of a list
list1.extend(['Albert', 'Bob'])
list1 += ['Ginger', 'Sporty']
# ['John', 'Paul', 'George', 'Ringo', 'Pete', 'Albert', 'Bob', 'Ginger', 'Sporty']
## Insert at specific index
list1.insert(2, 7)
['John', 'Paul', 7, 'George', 'Ringo', 'Pete', 'Albert', 'Bob', 'Ginger', 'Sporty']
a_list = ['Adele', 'Madonna', 'Cher']
print(a_list)
a_list.insert(1, 'Paloma')
print(a_list)
# ['Adele', 'Paloma', 'Madonna', 'Cher']
```
## Removing elements
We distinguish `del` from `remove` when removing elements from lists:
- `del` requires an index value
- `remove` requires a value reference (i.e. the mame of the element rather than its index)
`del` is simple deletion whereas `remove` searches the list. Therefore `del` is more efficient.
```python
# Remove and return element removed
list6 = ['Once', 'Upon', 'a', 'Time']
print(list6.pop(2))
# a
# Remove and return last element
list6 = ['Once', 'Upon', 'a', 'Time']
print(list6.pop())
list6.pop()
print(list6)
# Time
list6.remove('Upon')
print(list6)
# ['Once', 'a']
my_list = ['A', 'B', 'C', 'D', 'E']
print(my_list)
# ['A', 'B', 'C', 'D', 'E']
del my_list[2]
print(my_list)
# ['A', 'B', 'D', 'E']
print(my_list)
# ['A', 'B', 'C', 'D', 'E']
del my_list[1:3]
print(my_list)
# ['A', 'D', 'E']
```
## Retrieve elements by index
```python
list7 = [2, 3, 6, 8]
print(list7.index(8))
# 3
list6 = ['Once', 'Upon', 'a', 'Time']
print(list6.index('a'))
# 2
```
## Nesting lists
```python
l1 = [1, 43.5, 'Phoebe', True]
l2 = ['apple', 'orange', 31]
root_list = ['John', l1, l2, 'Denise']
print(root_list)
# ['John', [1, 43.5, 'Phoebe', True], ['apple', 'orange', 31], 'Denise']
```
## List comprehension
> List comprehension is an older feature of Python. Now the same functionality can be achieved with greater concision using functional methods like `map` and `filter`. But you may see it used in older code.
```python
values = [1, 2, 4, 6, 8, 9]
new_values = [i + 1 for i in values]
print('new_values', new_values)
# new_values [2, 3, 5, 7, 9, 10]
new_list = [item + 1 for item in values if item % 2 == 0]
print('new_list:', new_list)
# new_list: [3, 5, 7, 9]
```

View file

@ -0,0 +1,126 @@
---
categories:
- Programming Languages
tags: [python]
---
# Loops in Python
## While
```python
count = 0
print('Starting')
while count < 10:
print(count, '', end='')
count += 1
print() # not part of the while loop
print('Done')
"""
Starting
0 1 2 3 4 5 6 7 8 9
Done
"""
```
> There are no `do while` loops in Python
## For
```python
# Loop over a set of values in a range
print('Print out values in a range')
for i in range(0, 10):
print(i, ' ', end='')
print()
print('Done')
"""
Print out values in a range
0 1 2 3 4 5 6 7 8 9
Done
"""
# Now use values in a range but increment by 2
print('Print out values in a range with an increment of 2')
for i in range(0, 10, 2):
print(i, ' ', end='')
print()
print('Done')
"""
Print out values in a range with an increment of 2
0 2 4 6 8
Done
"""
# Now use an 'anonymous' loop variable
for _ in range(0, 10):
print('.', end='')
print()
print('-' * 25)
# Illustrates use of break statement
print('Only print code if all iterations completed')
num = int(input('Enter a number to check for: '))
for i in range(0, 6):
if i == num:
break
print(i, ' ', end='')
print('Done')
"""
Only print code if all iterations completed
Enter a number to check for: 7
0 1 2 3 4 5 Done
"""
# Illustrates use of continue statement
for i in range(0, 10):
print(i, ' ', end='')
if i % 2 == 1:
continue
print('hey its an even number')
print('we love even numbers')
print('Done')
"""
0 hey its an even number
we love even numbers
1 2 hey its an even number
we love even numbers
3 4 hey its an even number
we love even numbers
5 6 hey its an even number
we love even numbers
7 8 hey its an even number
we love even numbers
9 Done
"""
# Illustrates use of else statement with a for loop
print('Only print code if all iterations completed')
num = int(input('Enter a number to check for: '))
for i in range(0, 6):
if i == num:
break
print(i, ' ', end='')
else:
print()
print('All iterations successful')
print('Done')
"""
Only print code if all iterations completed
Enter a number to check for: 6
0 1 2 3 4 5
All iterations successful
Done
"""
```

View file

@ -0,0 +1,55 @@
---
categories:
- Programming Languages
tags: [python]
---
# Map and filter in Python
## Map
```py
data = [1, 3, 5, 2, 7, 4, 10]
new_data = map(lambda i: i + 10, data)
print(new_data)
```
We can also pass-in a function rather than use a lambda:
```py
def add_one(i):
return i + 1
x = list(map(addOne, data))
# [2, 4, 6, 3, 8, 5, 11]
# necessary to add `list` to get some output
```
## Filter
```py
data = [1, 3, 5, 2, 7, 4, 10]
d1 = list(filter(lambda i: i % 2 == 0, data))
print(d1)
# [2, 4, 10]
def is_even(i):
return i % 2 == 0
# Filter for even numbers using a named function
d2 = list(filter(is_even, data))
# [2, 4, 10]
```
## Chaining
```py
data = [1, 3, 5, 2, 7, 4, 10]
new_data = list(map(lambda i: i + 10, filter(is_even, data)))
print(new_data)
# new_data: [12, 14, 20]
```

View file

@ -0,0 +1,44 @@
---
categories:
- Programming Languages
tags: [python]
---
# Match statements in Python
> A `match` statement is the equivalent of a switch or case statement in Python
```python
command = input("What are you doing next? ")
match command:
case "quit":
print("Goodbye!")
case "look":
print("Looking out")
case "up" | "down":
print("up or down")
case _:
print("The default")
"""
What are you doing next? up
up or down
"""
match command.split():
case ["go", "left"]:
print("go left")
case ["go", ("fast" | "slow")]:
print("go fast or slow")
point = (3, 3)
match point:
case (x, y) if x == y:
print(f"The point is located on the diagonal Y=X at {x}.")
case (x, y):
print(f"Point is not on the diagonal.")
"""
The point is located on the diagonal Y=X at 3.
"""
```

View file

@ -0,0 +1,43 @@
---
categories:
- Programming Languages
tags: [python, data-types]
---
# None in Python
`None` is not `null`, it is closer to `undefined` in JS. If you define a variable as `None`, the variable exists, it is just not yet defined.
Using `None` is a pattern similar to using `let` in JS to name a variable and definine it later on.
```python
temperature = None
```
If we logged `temperature` it would give us `None` rather than a null pointer error.
With None we can use `is None` and `is not None`, special predicates for working with `None` only. This is a akin to using `if (x !== undefined)` in TypeScript
```python
winner = None
print('winner:', winner)
# winner: None
print('winner is None:', winner is None)
# winner is None: True
print('winner is not None:', winner is not None)
# winner is not None: False
print(type(winner))
# <class 'NoneType'>
# Now set winner to be True
print('Set winner to True')
# Set winner to True
winner = True
print('winner:', winner)
# winner: True
print('winner is None:', winner is None)
# winner is None: False
print('winner is not None:', winner is not None)
# winner is not None: True
print(type(winner))
# <class 'bool'>
```

View file

@ -0,0 +1,34 @@
---
categories:
- Programming Languages
tags: [python, data-types]
---
# Numbers in Python
## Distinguishing `int` and `float`
- In Python we have floats and integers and we can coerce one into the other
- A `//` as an operator means float division. This obviously provides greater precision than int division `/`.
- There is no increment (`++`) or decrement (`--`) operator in Python
```python
# Integers and floats
count = 1
print(count)
# 1
print(type(count))
# <class 'int'>
exchange_rate = 1.83
print(exchange_rate)
# 1.83
print(type(exchange_rate))
# <class 'float'>
print(float(count))
# 1.0
print(int(exchange_rate))
# 1
```

View file

@ -0,0 +1,90 @@
---
categories:
- Programming Languages
tags: [python, data-structures]
---
# Sets in Python
- They are **unordered**
- You can increase/decrease their length by adding/removing new members
- They **do not allow duplicate members**
- **Can only hold immutable objects**
> Sets are denoted with `{...}`
## Basic usage
```python
basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
print(basket) # show that duplicates have been removed
print(len(basket))
# {'apple', 'pear', 'banana', 'orange'}
# 4
```
## Looping through sets
```python
for item in basket:
print(item)
"""
apple
pear
banana
orange
"""
```
## Check for membership
```python
basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
print('apple' in basket)
# True
```
## Remove items from set
> `remove` will raise an error if the specified item does not exist, `discard` will not
```python
basket.remove('apple')
basket.discard('apricot')
print(basket)
# {'pear', 'banana', 'orange'}
basket.clear()
print(basket)
#set
```
## Add items to a set
```python
basket.add('apricot')
print(basket)
# {'apricot', 'pear', 'banana', 'orange'}
```
## Apply unions and intersections
```python
s1 = {'apple', 'orange', 'banana'}
s2 = {'grapefruit', 'lime', 'banana'}
print('Union:', s1 | s2)
# Union: {'apple', 'orange', 'grapefruit', 'lime', 'banana'}
print('Intersection:', s1 & s2)
# Intersection: {'banana'}
print('Difference:', s1 - s2)
# Difference: {'orange', 'apple'}
print('Symmetric Difference:', s1 ^ s2)
#Symmetric Difference: {'apple', 'orange', 'grapefruit', 'lime'}
```

View file

@ -0,0 +1,78 @@
---
categories:
- Programming Languages
tags: [python, data-types]
---
# Strings in Python
> Generally, anything that changes a string will be a method on the `str` class, rather than a built-in function like `len()`, as such it will use dot notation
- Strings are **immutable**: string operations produce a new string.
```python
# Working with Strings
my_variable = 'Bob'
print(my_variable)
# Bob
my_variable = "Eloise"
print(my_variable)
# Eloise
# A multi line string
my_variable = """
Hello
World
"""
print(my_variable)
"""
Hello
World
"""
my_string = 'Hello World'
print(len(my_string))
# 11
string_1 = 'Good'
string_2 = " day"
string_3 = string_1 + string_2
print(string_3)
# Good day
msg = 'Hello Lloyd you are ' + str(21)
print(msg)
# Hello Lloyd you are 21
# Range of String operations
msg = 'Hello World'
print(msg.replace("Hello", "Goodbye"))
# Goodbye World
print('Edward Alan Rawlings'.find('Alan'))
# 7
print('Edward John Rawlings'.find('Alan'))
# -1
print('James' == 'James') # prints True
print('James' != 'John') # prints True
print("msg.startswith('H')", msg.startswith('H'))
# msg.startswith('H') True
print("msg.endswith('d')", msg.endswith('d'))
# msg.endswith('d') TRUE
print('some_string.upper()', msg.upper())
# some_string.upper() HELLO WORLD
print('sub string: ', 'Hello-World'[1:5])
# sub string: ello
# String interpolation
user_age = input("Please enter your age: ")
print(f'You are {user_age}')
```

View file

@ -0,0 +1,106 @@
---
categories:
- Programming Languages
tags: [python, data-structures]
---
# Tuples in Python
Tuples are one of the main data-structures or containers in Python.
Tuples have the following properties:
- They are **ordered**
- They have a **fixed size**
- They are **immutable** and cannot be modified
- **Allow duplicate** members
- They are **indexed**
As with all containers in Python they permit any data type.
> Tuples are denoted with `(...)`
## Basic usage
```python
tup1 = (1, 3, 5, 7)
print(tup1[0])
print(tup1[1])
print(tup1[2])
print(tup1[3])
"""
1
3
5
7
"""
```
## Slicing
```python
tup1 = (1, 3, 5, 7)
print(tup1[1:3])
print(tup1[:3])
print(tup1[1:])
print(tup1[::-1])
"""
(3, 5)
(1, 3, 5)
(3, 5, 7)
(7, 5, 3, 1)
"""
```
## Looping
```python
tup3 = ('apple', 'pear', 'orange', 'plum', 'apple')
for x in tup3:
print(x)
"""
apple
pear
orange
plum
apple
"""
```
## Useful methods and predicates
```python
tup3 = ('apple', 'pear', 'orange', 'plum', 'apple')
# Count instances of a member
print(tup3.count('apple'))
# 2
# Get index of a member
print(tup3.index('pear'))
# 1
# Check for membership
if 'orange' in tup3:
print('orange is in the Tuple')
# orange is in the Tuple
```
## Nest tuples
```python
tuple2 = ('John', 'Denise', 'Phoebe', 'Adam')
tuple3 = (42, tuple1, tuple2, 5.5)
print(tuple3)
# (42, (1, 3, 5, 7), ('John', 'Denise', 'Phoebe', 'Adam'), 5.5)
```
// TODO: How to flatten a tuple?

View file

@ -33,7 +33,7 @@ echo /tmp/{1..3}/file.txt
/tmp/1/file.txt /tmp/2/file.txt /tmp/3/file.txt /tmp/1/file.txt /tmp/2/file.txt /tmp/3/file.txt
``` ```
``` ```bash
echo {1..5} echo {1..5}
1 2 3 4 5 1 2 3 4 5
@ -46,7 +46,7 @@ a b c
We can also set sequences. If we wanted to count to twenty in intervals of two We can also set sequences. If we wanted to count to twenty in intervals of two
``` ```bash
echo {1..20..2} echo {1..20..2}
1 3 5 7 9 11 13 15 17 19 1 3 5 7 9 11 13 15 17 19
``` ```

View file

@ -15,7 +15,7 @@ So say we have this object:
```js ```js
const age = { const age = {
name: 'Thomas', name: "Thomas",
yearOfBirth: 1988, yearOfBirth: 1988,
currentYear: 2021, currentYear: 2021,
ageNow: function () { ageNow: function () {
@ -43,7 +43,7 @@ We could now re-write the first `age` object as an object of type `Age` :
let thomas: typeof Age; let thomas: typeof Age;
thomas = { thomas = {
name: 'Thomas', name: "Thomas",
yearOfBirth: 1988, yearOfBirth: 1988,
currentYear: 2021, currentYear: 2021,
ageNow: function () { ageNow: function () {
@ -67,7 +67,7 @@ We could then create objects based on this:
```tsx ```tsx
const thomas: Age = { const thomas: Age = {
name: 'Thomas', name: "Thomas",
yearOfBirth: 1988, yearOfBirth: 1988,
currentYear: 2021, currentYear: 2021,
ageNow: function () { ageNow: function () {
@ -97,10 +97,10 @@ With custom (object types) this means that the following expression of an object
```tsx ```tsx
const martha = { const martha = {
name: 'Martha', name: "Martha",
yearOfBirth: 1997, yearOfBirth: 1997,
currentYear: 2021, currentYear: 2021,
gender: 'female', gender: "female",
}; };
const addition: Age = martha; const addition: Age = martha;
@ -110,10 +110,10 @@ But if we tried to add this extra property whilst defining `martha` as an instan
```tsx ```tsx
const martha: Age = { const martha: Age = {
name: 'Martha', name: "Martha",
yearOfBirth: 1997, yearOfBirth: 1997,
currentYear: 2021, currentYear: 2021,
gender: 'female', gender: "female",
}; };
``` ```
@ -134,17 +134,17 @@ function logPoint(p: Point) {
} }
// logs "12, 26" // logs "12, 26"
const point = {x: 12, y: 26}; const point = { x: 12, y: 26 };
logPoint(point); logPoint(point);
``` ```
Shape matching only requires a subset of the object's fields to match: Shape matching only requires a subset of the object's fields to match:
```tsx ```tsx
const point3 = {x: 12, y: 26, z: 89}; const point3 = { x: 12, y: 26, z: 89 };
logPoint(point3); // logs "12, 26" logPoint(point3); // logs "12, 26"
const rect = {x: 33, y: 3, width: 30, height: 80}; const rect = { x: 33, y: 3, width: 30, height: 80 };
logPoint(rect); logPoint(rect);
``` ```

View file

@ -1 +0,0 @@
{}

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 KiB

View file

@ -96,6 +96,10 @@ A. Sweighart. 2020. **Beyond the Basic Stuff with Python**
A. Sweighart. 2015. **Automate the Boring Stuff with Python** A. Sweighart. 2015. **Automate the Boring Stuff with Python**
J. Hunt. 2019. **A Beginner's Guide to Python Programming**
J. Hunt. 2019. **An Advanced Guide to Python Programming**
[Tiny Python Projects (O'Reilly)](https://learning.oreilly.com/library/view/tiny-python-projects/9781617297519/) [Tiny Python Projects (O'Reilly)](https://learning.oreilly.com/library/view/tiny-python-projects/9781617297519/)
[Learning Arduino with Python](https://realpython.com/arduino-python/) [Learning Arduino with Python](https://realpython.com/arduino-python/)

View file

@ -1,5 +1,25 @@
# Learning Topic Log # Learning Topic Log
## Python
- Research: best practice for separating projects into `conda` environments like npm
- Read-up more on types: what does it mean for Python to be dynamically typed. What is type-hinting really?
- Use provided pdfs and John's books
- Is `dictionary.values()`/ `dictionary.keys()` of type list?
- Is `dictionary.items()` a list of tuples for key, value?
- How to run test suites via VSCode?
BBC Course, remaining topics:
- Classes and object-oriented paradigms in Python
- Modules
- Error handling
- Testing
## Bash ## Bash
- Best way to run a command in a script - is it to `echo` it? - Best way to run a command in a script - is it to `echo` it?