diff --git a/Programming_Languages/Python/Syntax/Dictionaries_in_Python.md b/Programming_Languages/Python/Syntax/Dictionaries_in_Python.md index 75ffa53..6668492 100644 --- a/Programming_Languages/Python/Syntax/Dictionaries_in_Python.md +++ b/Programming_Languages/Python/Syntax/Dictionaries_in_Python.md @@ -14,3 +14,113 @@ Dictionaries: - 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/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/Sets_in_Python.md b/Programming_Languages/Python/Syntax/Sets_in_Python.md index 585eef8..c2f1d45 100644 --- a/Programming_Languages/Python/Syntax/Sets_in_Python.md +++ b/Programming_Languages/Python/Syntax/Sets_in_Python.md @@ -54,6 +54,37 @@ 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/_meta/Topic_Log.md b/_meta/Topic_Log.md index 0113073..6c8915f 100644 --- a/_meta/Topic_Log.md +++ b/_meta/Topic_Log.md @@ -2,17 +2,24 @@ ## Python -- Get PEP8 working in VSCode as linter and add to execute on save. (These are conventions not syntactic enforcements, style) - -- Is there a thing like prettier to enforce double quotes over single for instance? - -- Research: How do I make sure I am using `conda` and not the default install in VSCode ? PyCharm makes it easy to select environment. - - 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?