Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
pge_lectures
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Badmaanyambuu Enkhbayar
pge_lectures
Commits
c1b66a81
Commit
c1b66a81
authored
1 month ago
by
Škoviera, Radoslav, Mgr., Ph.D.
Browse files
Options
Downloads
Patches
Plain Diff
Added TOC to lecture 1
parent
37c8ce30
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/pge_lectures/lecture_01/l1_intro_strctures.qmd
+45
-16
45 additions, 16 deletions
src/pge_lectures/lecture_01/l1_intro_strctures.qmd
with
45 additions
and
16 deletions
src/pge_lectures/lecture_01/l1_intro_strctures.qmd
+
45
−
16
View file @
c1b66a81
# Basic data structures, intro to asymptotic complexity
# Basic data structures, intro to asymptotic complexity
---
---
title: "Lecture 1"
title: Programming for Engineers
subtitle: "Lecture 1 - basic data structures"
author: Radoslav Škoviera
format:
format:
pdf:
code-fold: false
html:
html:
code-fold: false
code-fold: false
jupyter: python3
jupyter: python3
toc: true
jupyter: python3
---
---
## Basic data structures (in Python)
## Basic data structures (in Python)
...
@@ -192,7 +199,9 @@ print("[1, 2, 3.0] == [1, 2, 3]: ", [1, 2, 3.0] == [1, 2, 3]) # True
...
@@ -192,7 +199,9 @@ print("[1, 2, 3.0] == [1, 2, 3]: ", [1, 2, 3.0] == [1, 2, 3]) # True
print("[1, 2, 3] == [3, 2, 1]: ", [1, 2, 3] == [3, 2, 1]) # False
print("[1, 2, 3] == [3, 2, 1]: ", [1, 2, 3] == [3, 2, 1]) # False
# Be (ALWAYS) aware of precision/numerical issues
# Be (ALWAYS) aware of precision/numerical issues
print("[1, 2, 3.0000000000000000001] == [1, 2, 3]: ", [1, 2, 3.0000000000000000001] == [1, 2, 3]) # True, depends on the precision
print(
"[1, 2, 3.000000000000000001] == [1, 2, 3]: ",
[1, 2, 3.000000000000000001] == [1, 2, 3]) # True, depends on the precision
```
```
##### Precision side-quest
##### Precision side-quest
...
@@ -202,7 +211,7 @@ print("3 == 2.99999999", 3 == 2.99999999) # False
...
@@ -202,7 +211,7 @@ print("3 == 2.99999999", 3 == 2.99999999) # False
print("1/3 == 0.33333333", 1/3 == 0.33333333) # False
print("1/3 == 0.33333333", 1/3 == 0.33333333) # False
print("3.00000000000000001 == 3: ", 3.00000000000000001 == 3) # True
print("3.00000000000000001 == 3: ", 3.00000000000000001 == 3) # True
print("2.99999999999999999 == 3: ", 2.99999999999999999 == 3) # True
print("2.99999999999999999 == 3: ", 2.99999999999999999 == 3) # True
print("1/3 == 0.3333333333333333333
33
: ", 1/3 == 0.3333333333333333333
33
) # True
print("1/3 == 0.3333333333333333333: ", 1/3 == 0.3333333333333333333) # True
```
```
End of side-quest.
End of side-quest.
...
@@ -621,7 +630,8 @@ print(f"My list after running my_function: {my_list}")
...
@@ -621,7 +630,8 @@ print(f"My list after running my_function: {my_list}")
my_tuple = (1, 2, 3) # precious data we don't want to change
my_tuple = (1, 2, 3) # precious data we don't want to change
try:
try:
print(my_function(my_tuple))
print(my_function(my_tuple))
except TypeError: # this will catch the error raised whe the function tries to change the tuple
except TypeError: # this will catch the error raised
# when the function tries to change the tuple
print("Aha! The function tried to change my tuple!")
print("Aha! The function tried to change my tuple!")
```
```
...
@@ -739,7 +749,9 @@ Most common way to iterate over a dictionary is to use the `items()` method, whi
...
@@ -739,7 +749,9 @@ Most common way to iterate over a dictionary is to use the `items()` method, whi
```{python}
```{python}
import string
import string
alphabet_dict = {k: v for k, v in zip(string.ascii_letters, range(26)) if v < 12 and v % 2 == 0}
alphabet_dict = {
k: v for k, v in zip(string.ascii_letters, range(26))
if v < 12 and v % 2 == 0}
for key, value in alphabet_dict.items():
for key, value in alphabet_dict.items():
print(f"The letter {key} is at position {value + 1} in the alphabet.")
print(f"The letter {key} is at position {value + 1} in the alphabet.")
```
```
...
@@ -747,7 +759,9 @@ for key, value in alphabet_dict.items():
...
@@ -747,7 +759,9 @@ for key, value in alphabet_dict.items():
There are also `keys()` and `values()` methods that return the keys and values respectively.
There are also `keys()` and `values()` methods that return the keys and values respectively.
```{python}
```{python}
for key in alphabet_dict.keys():
for key in alphabet_dict.keys():
print(f"The letter {key} is at position {alphabet_dict[key] + 1} in the alphabet.")
print(f"The letter {key} is at position "
f"{alphabet_dict[key] + 1} in the alphabet.")
# Yes, you can break strings in Python like that...
```
```
```{python}
```{python}
...
@@ -815,10 +829,19 @@ b = [1, 2, 3]
...
@@ -815,10 +829,19 @@ b = [1, 2, 3]
c = a
c = a
d = a[:]
d = a[:]
e = a.copy()
e = a.copy()
print(a is b) # the elements have the same value but `a` is not the same object as `b`
# the elements have the same value but `a` is not the same object as `b`
print(a is c) # `a` and `c` reference the same object
print(a is b)
print(a is d) # `d` got the values from `a` but it is still a different object (different memory location)
print(a is e) # copy makes a new object with the same values (essentially, similar process to defining `d`)
# `a` and `c` reference the same object
print(a is c)
# `d` got the values from `a` but it is still a different object
# (different memory location)
print(a is d)
# copy makes a new object with the same values
# (essentially, similar process to defining `d`)
print(a is e)
```
```
It is not?
It is not?
...
@@ -834,7 +857,8 @@ Some 'objects' are the same but it makes no sense to compare them using `is`. Al
...
@@ -834,7 +857,8 @@ Some 'objects' are the same but it makes no sense to compare them using `is`. Al
# this will get you a syntax warning
# this will get you a syntax warning
print(1 is 1.0) # False, because float != int
print(1 is 1.0) # False, because float != int
print(1.0 is 1.0) # True
print(1.0 is 1.0) # True
print((1, 2, 3) is (1, 2, 3)) # Unexpectedly, True but also not advised; just use equality `==`
print((1, 2, 3) is (1, 2, 3)) # Unexpectedly, True but also not advised;
#just use equality `==`
```
```
For number type check, see below.
For number type check, see below.
...
@@ -886,10 +910,12 @@ print(multiply_two_numbers_unchecked("3", 2)) # 33 !?
...
@@ -886,10 +910,12 @@ print(multiply_two_numbers_unchecked("3", 2)) # 33 !?
Code with run-time type checking and assertions:
Code with run-time type checking and assertions:
```{python}
```{python}
def multiply_two_numbers(a, b):
def multiply_two_numbers(a, b):
assert isinstance(a, (int, float)), f"'a' must be a number! But it was: {type(a)}"
assert isinstance(a, (int, float)), "'a' must be a number! "
assert isinstance(b, (int, float)), f"'b' must be a number! But it was: {type(b)}"
f"But it was: {type(a)}"
assert isinstance(b, (int, float)), "'b' must be a number! " f"But it was: {type(b)}"
# Alternatively, this will also work:
# Alternatively, this will also work:
assert issubclass(type(my_integer), (int, float)), f"'a' must be a number! But it was: {type(a)}"
assert issubclass(type(my_integer), (int, float)), "'a' must be a number! "
f"But it was: {type(a)}"
return a * b
return a * b
print(multiply_two_numbers(3, 2))
print(multiply_two_numbers(3, 2))
...
@@ -909,7 +935,10 @@ More info about basic types and comparison: https://docs.python.org/3/library/st
...
@@ -909,7 +935,10 @@ More info about basic types and comparison: https://docs.python.org/3/library/st
```{python}
```{python}
from typing import Union, Optional
from typing import Union, Optional
def nice_multiply_two_numbers(a: Union[int, float], b: Union[int, float], raise_error: bool = True) -> Optional[Union[int, float]]:
def nice_multiply_two_numbers(
a: Union[int, float],
b: Union[int, float],
raise_error: bool = True) -> Optional[Union[int, float]]:
if not isinstance(a, (int, float)):
if not isinstance(a, (int, float)):
if raise_error:
if raise_error:
raise TypeError(f"'a' must be a number! But it was: {type(a)}")
raise TypeError(f"'a' must be a number! But it was: {type(a)}")
...
@@ -928,7 +957,7 @@ try:
...
@@ -928,7 +957,7 @@ try:
print(nice_multiply_two_numbers(3.0, 2))
print(nice_multiply_two_numbers(3.0, 2))
print(nice_multiply_two_numbers("3", 2)) # this will cause an error
print(nice_multiply_two_numbers("3", 2)) # this will cause an error
except TypeError as e:
except TypeError as e:
print(f"One of the inputs had an incorrect type. See the error:
{e}")
print(f"One of the inputs had an incorrect type. See the error:
\n
{e}")
print("\nUsing None return type:")
print("\nUsing None return type:")
result = nice_multiply_two_numbers("3", 2, raise_error=False)
result = nice_multiply_two_numbers("3", 2, raise_error=False)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment