diff --git a/.vscode/markdown-styles.css b/.vscode/markdown-styles.css new file mode 100644 index 0000000..b1b60d2 --- /dev/null +++ b/.vscode/markdown-styles.css @@ -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; +} diff --git a/Programming_Languages/Frameworks/React/Hooks/Memoization.md b/Programming_Languages/Frameworks/React/Hooks/Memoization.md index 9b2ddf1..d1e486a 100644 --- a/Programming_Languages/Frameworks/React/Hooks/Memoization.md +++ b/Programming_Languages/Frameworks/React/Hooks/Memoization.md @@ -7,7 +7,7 @@ tags: - react-hooks --- -# Memoization with `useCallback` and `useMemo` +# Memoization with useCallback and useMemo ## 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. -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). diff --git a/Programming_Languages/NodeJS/REST_APIs/4_DELETE.md b/Programming_Languages/NodeJS/REST_APIs/4_DELETE.md deleted file mode 100644 index 4f0ec73..0000000 --- a/Programming_Languages/NodeJS/REST_APIs/4_DELETE.md +++ /dev/null @@ -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); -}); -``` diff --git a/Programming_Languages/Python/BBC_Course_Notes.md b/Programming_Languages/Python/BBC_Course_Notes.md new file mode 100644 index 0000000..898f2bc --- /dev/null +++ b/Programming_Languages/Python/BBC_Course_Notes.md @@ -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 diff --git a/Programming_Languages/Python/Concepts/Data_types.md b/Programming_Languages/Python/Concepts/Data_types.md deleted file mode 100644 index e5d7896..0000000 --- a/Programming_Languages/Python/Concepts/Data_types.md +++ /dev/null @@ -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 -``` diff --git a/Programming_Languages/Python/Concepts/Python_data_types.md b/Programming_Languages/Python/Concepts/Python_data_types.md new file mode 100644 index 0000000..a81127b --- /dev/null +++ b/Programming_Languages/Python/Concepts/Python_data_types.md @@ -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)) +# + +# String type +my_variable = 'Natalia' +print(my_variable) +print(type(my_variable)) +# + +# Boolean type +my_variable = True +print(my_variable) +print(type(my_variable)) +# +``` + +## 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)}') +``` diff --git a/Programming_Languages/Python/Concepts/Python_execution.md b/Programming_Languages/Python/Concepts/Python_execution.md new file mode 100644 index 0000000..b40f114 --- /dev/null +++ b/Programming_Languages/Python/Concepts/Python_execution.md @@ -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`. diff --git a/Programming_Languages/Python/Concepts/Python_package_management.md b/Programming_Languages/Python/Concepts/Python_package_management.md new file mode 100644 index 0000000..0cedfb9 --- /dev/null +++ b/Programming_Languages/Python/Concepts/Python_package_management.md @@ -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 diff --git a/Programming_Languages/Python/Syntax/Conditional_statements_in_Python.md b/Programming_Languages/Python/Syntax/Conditional_statements_in_Python.md new file mode 100644 index 0000000..fb598b4 --- /dev/null +++ b/Programming_Languages/Python/Syntax/Conditional_statements_in_Python.md @@ -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) +``` diff --git a/Programming_Languages/Python/Syntax/Dictionaries_in_Python.md b/Programming_Languages/Python/Syntax/Dictionaries_in_Python.md new file mode 100644 index 0000000..6668492 --- /dev/null +++ b/Programming_Languages/Python/Syntax/Dictionaries_in_Python.md @@ -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)) +# +``` + +## 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 +""" + +``` diff --git a/Programming_Languages/Python/Syntax/Functions_in_Python.md b/Programming_Languages/Python/Syntax/Functions_in_Python.md new file mode 100644 index 0000000..2eae3cc --- /dev/null +++ b/Programming_Languages/Python/Syntax/Functions_in_Python.md @@ -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)) +# + +# 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. diff --git a/Programming_Languages/Python/Syntax/Lambdas_in_Python.md b/Programming_Languages/Python/Syntax/Lambdas_in_Python.md new file mode 100644 index 0000000..a849594 --- /dev/null +++ b/Programming_Languages/Python/Syntax/Lambdas_in_Python.md @@ -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 diff --git a/Programming_Languages/Python/Syntax/Lists_in_Python.md b/Programming_Languages/Python/Syntax/Lists_in_Python.md new file mode 100644 index 0000000..2bfe69b --- /dev/null +++ b/Programming_Languages/Python/Syntax/Lists_in_Python.md @@ -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] +``` diff --git a/Programming_Languages/Python/Syntax/Loops_in_Python.md b/Programming_Languages/Python/Syntax/Loops_in_Python.md new file mode 100644 index 0000000..3f2169c --- /dev/null +++ b/Programming_Languages/Python/Syntax/Loops_in_Python.md @@ -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 +""" + +``` diff --git a/Programming_Languages/Python/Syntax/Map_and_filter_in_Python.md b/Programming_Languages/Python/Syntax/Map_and_filter_in_Python.md new file mode 100644 index 0000000..18bb0ec --- /dev/null +++ b/Programming_Languages/Python/Syntax/Map_and_filter_in_Python.md @@ -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] +``` diff --git a/Programming_Languages/Python/Syntax/Match_statements_in_Python.md b/Programming_Languages/Python/Syntax/Match_statements_in_Python.md new file mode 100644 index 0000000..cb37da4 --- /dev/null +++ b/Programming_Languages/Python/Syntax/Match_statements_in_Python.md @@ -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. +""" +``` diff --git a/Programming_Languages/Python/Syntax/None_in_Python.md b/Programming_Languages/Python/Syntax/None_in_Python.md new file mode 100644 index 0000000..5a92ddd --- /dev/null +++ b/Programming_Languages/Python/Syntax/None_in_Python.md @@ -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)) +# +# 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)) +# +``` diff --git a/Programming_Languages/Python/Syntax/Numbers_in_Python.md b/Programming_Languages/Python/Syntax/Numbers_in_Python.md new file mode 100644 index 0000000..965c423 --- /dev/null +++ b/Programming_Languages/Python/Syntax/Numbers_in_Python.md @@ -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)) +# + +exchange_rate = 1.83 +print(exchange_rate) +# 1.83 +print(type(exchange_rate)) +# + +print(float(count)) +# 1.0 + +print(int(exchange_rate)) +# 1 +``` diff --git a/Programming_Languages/Python/Syntax/Sets_in_Python.md b/Programming_Languages/Python/Syntax/Sets_in_Python.md new file mode 100644 index 0000000..c2f1d45 --- /dev/null +++ b/Programming_Languages/Python/Syntax/Sets_in_Python.md @@ -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'} + +``` diff --git a/Programming_Languages/Python/Syntax/Strings_in_Python.md b/Programming_Languages/Python/Syntax/Strings_in_Python.md new file mode 100644 index 0000000..17c89f1 --- /dev/null +++ b/Programming_Languages/Python/Syntax/Strings_in_Python.md @@ -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}') +``` diff --git a/Programming_Languages/Python/Syntax/Tuples_in_Python.md b/Programming_Languages/Python/Syntax/Tuples_in_Python.md new file mode 100644 index 0000000..2381723 --- /dev/null +++ b/Programming_Languages/Python/Syntax/Tuples_in_Python.md @@ -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? diff --git a/Programming_Languages/Shell/Expansions_and_substitutions.md b/Programming_Languages/Shell/Expansions_and_substitutions.md index 0a93047..da549e0 100644 --- a/Programming_Languages/Shell/Expansions_and_substitutions.md +++ b/Programming_Languages/Shell/Expansions_and_substitutions.md @@ -33,7 +33,7 @@ echo /tmp/{1..3}/file.txt /tmp/1/file.txt /tmp/2/file.txt /tmp/3/file.txt ``` -``` +```bash echo {1..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 -``` +```bash echo {1..20..2} 1 3 5 7 9 11 13 15 17 19 ``` diff --git a/Programming_Languages/TypeScript/Custom_types.md b/Programming_Languages/TypeScript/Custom_types.md index d13430d..cc290ff 100644 --- a/Programming_Languages/TypeScript/Custom_types.md +++ b/Programming_Languages/TypeScript/Custom_types.md @@ -15,7 +15,7 @@ So say we have this object: ```js const age = { - name: 'Thomas', + name: "Thomas", yearOfBirth: 1988, currentYear: 2021, 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; thomas = { - name: 'Thomas', + name: "Thomas", yearOfBirth: 1988, currentYear: 2021, ageNow: function () { @@ -67,7 +67,7 @@ We could then create objects based on this: ```tsx const thomas: Age = { - name: 'Thomas', + name: "Thomas", yearOfBirth: 1988, currentYear: 2021, ageNow: function () { @@ -97,10 +97,10 @@ With custom (object types) this means that the following expression of an object ```tsx const martha = { - name: 'Martha', + name: "Martha", yearOfBirth: 1997, currentYear: 2021, - gender: 'female', + gender: "female", }; const addition: Age = martha; @@ -110,10 +110,10 @@ But if we tried to add this extra property whilst defining `martha` as an instan ```tsx const martha: Age = { - name: 'Martha', + name: "Martha", yearOfBirth: 1997, currentYear: 2021, - gender: 'female', + gender: "female", }; ``` @@ -134,17 +134,17 @@ function logPoint(p: Point) { } // logs "12, 26" -const point = {x: 12, y: 26}; +const point = { x: 12, y: 26 }; logPoint(point); ``` Shape matching only requires a subset of the object's fields to match: ```tsx -const point3 = {x: 12, y: 26, z: 89}; +const point3 = { x: 12, y: 26, z: 89 }; 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); ``` diff --git a/Untitled.canvas b/Untitled.canvas deleted file mode 100644 index 9e26dfe..0000000 --- a/Untitled.canvas +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/_img/Screenshot 2023-02-13 at 10.43.17.png b/_img/Screenshot 2023-02-13 at 10.43.17.png new file mode 100644 index 0000000..737a81e Binary files /dev/null and b/_img/Screenshot 2023-02-13 at 10.43.17.png differ diff --git a/_meta/Resources.md b/_meta/Resources.md index 329cda3..d555e9d 100644 --- a/_meta/Resources.md +++ b/_meta/Resources.md @@ -96,6 +96,10 @@ A. Sweighart. 2020. **Beyond the Basic 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/) [Learning Arduino with Python](https://realpython.com/arduino-python/) diff --git a/_meta/Topic_Log.md b/_meta/Topic_Log.md index 9cd1f61..6c8915f 100644 --- a/_meta/Topic_Log.md +++ b/_meta/Topic_Log.md @@ -1,5 +1,25 @@ # 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 - Best way to run a command in a script - is it to `echo` it?