Skip to content

Commit

Permalink
move stuff from soft eng repo
Browse files Browse the repository at this point in the history
  • Loading branch information
Kristian Rother committed Jan 3, 2024
1 parent 9a52263 commit 7b8a63d
Show file tree
Hide file tree
Showing 10 changed files with 535 additions and 66 deletions.
63 changes: 2 additions & 61 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,68 +1,9 @@

# Advanced Python

Examples of advanced Python programming techniques

## Functions

* [Function Parameters](functions/function_parameters.md)
* [Variable Scope](functions/scope.md)
* [Lambda Functions](functions/lambda_functions.md)
* [Generator Functions](functions/generators.md)
* [Map-Filter-Reduce](functions/functools.md)
* [Decorators](functions/decorators.md)
* [Exercise](functions/exercises.md)

## Shortcuts

* [Collections](shortcuts/collections.md)
* [Comprehensions](shortcuts/comprehensions.md)
* [Enumerations](shortcuts/enums.md)

## Structuring Code

* [Structure of a Python script](structure/main_block.md)
* [Command-line Arguments](structure/commandline_args.md)
* [Writing Modules](structure/modules/)
* [Writing Packages](structure/package/)

## Object-Oriented Programming in Python

* [Classes](classes/classes.md)
* [Inheritance](classes/inheritance.md)
* [Object Composition](classes/composition.md)
* [Operator Overloading](classes/operator_overloading.md)
* [Abstract Base Classes](classes/abc.md)
* [Decorator Classes](classes/decorator_class.md)
* [Metaclasses](classes/metaclasses.md)


## Error Handling

* [Exception Handling](error_handling/exceptions/)
* [Warnings](error_handling/warnings.md)
* [Logging](error_handling/logging/)

## Parallel Programming

* [Concurrency](concurrency/)

## Challenges

| Challenge | Difficulty |
|-----------|---------------|
| [Factorial](challenges/factorial.rst) ||
| [Sorting Algorithms](challenges/sorting.md) ||
| [Tennis](challenges/tennis.md) | ⭐⭐ |
| [Magic Square](challenges/magic_square.md) | ⭐⭐ |
| [Josephus Problem](challenges/josephus.md) | ⭐⭐ |
| [Tree Traversal](challenges/tree_traversal.md) | ⭐⭐ |
| [Maze](challenges/maze.md) | ⭐⭐ |
| [Backpack Problem](challenges/backpack_problem.md) | ⭐⭐⭐ |
| [Chained List](challenges/chained_list.md) | ⭐⭐ |
| [Traveling Salesman](challenges/tsp.md) | ⭐⭐⭐ |
| [Decorator-Metaclass](challenges/metaclass.md) | ⭐⭐⭐⭐⭐ |
Examples and Exercises for advanced Python programming techniques

The Live Website is available at [http://www.academis.eu/advanced_python](http://www.academis.eu/advanced_python)

## Source

Expand Down
147 changes: 147 additions & 0 deletions classes/class_diagram.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@

# Class Diagrams

One of the first and most important things converting ideas and into code is to structure data.
You want to start structuring your core business data.
In the case of a snake game, this means how the playing field, the snake and the food items are represented.

Class diagrams are a graphical tool to structure your data and check whether it is complete and non-redundant before writing code.

## What does a class diagram contain?

Here is a class diagram for a `PlayingField` class, the box in which a snake will move:

![class diagram for the PlayingField](images/class_playing_field.png)

On top, the class diagram contains a **title**, the name of the class in `SnakeCase` notation.

The second section lists the **attributes** of the class and their **data types**:

* the x/y size of the playing field, a tuple of two integers
* the x/y position of the food item, also a tuple of two integers

The third section lists the **methods** of the class with their **arguments** and **return types**:

* the `add_food()` method takes two integer arguments and returns nothing
* the `add_random_food()` method has no arguments and returns nothing
* the `get_walls()` method takes no arguments and returns a list of x/y integer tuples

## What the PlayingFiled does not contain

It is worth pointing out that the `PlayingField` class lacks two things on purpose:

First, it does not contain an attribute `snake`.
To be precise, it does not know that snakes even exist.
It does not have to know about it.
We want the `PlayingField` and the `Snake` to manage themselves as independently as possible.
This will make debugging a lot easier.

Second, there is no method `draw()`.
Drawing things is usually not part of your core business.
In the snake game, you may want to change the user interface later (e.g. by adding graphics and sound effects).
The core logic of how the snake moves should not change because of that.

----

## Write Skeleton Code

A great thing about class diagrams is that you can create them to code easily.
The Python `dataclasses` module saves you a lot of typing:

from dataclasses import dataclass

@dataclass
class PlayingField:

size: (int, int)
food: (int, int) = None

def add_food(self, x, y):
...

def add_random_food(self):
...

def get_walls(self):
...

This code defines the `size` and `food` attributes and annotates their data types.
The `food` attribute has a default value.
The class also defines the methods from the class diagram (each with the obligatory `self`).
But we leave the method bodies empty for now.

The `@dataclass` automatically creates the `__init__()` and `__repr__()` methods for you, so that you can set and inspect the attribute values.
The code is already executable:

pf = PlayingField(size=(10, 10))
print(pf)
print(pf.size)
print(pf.get_walls())

Although our class does nothing yet, it helps to think about your desing and write other code that depends on it.

----

## Alternative Designs

Usually, there is more than one way to design a class.
Consider this alternative design for `PlayingField`:

![alternative PlayingField class](images/class_playing_field_alt.png)

There are a few differences:

* size and food have separate x and y attributes instead of being tuples
* the walls are represented by a list of `(int, int)` tuples
* the `add_food()` method expects a tuple instead of two integers
* there methods `is_wall()` and `get_walls()` are no longer there

One could discuss a lot which design is better.
You are better off postponing that discussion to a cleanup stage once the code is running.
The differences are very small and easy to change.
In Python, one could even state that the data structures are practically *identical*.

Using the `@property` decorator, you can translate attributes into each other.
The following code translates the `size` attribute into two new attributes `size_x` and `size_y`:

@property
def size_x(self):
return self.size[0]

@property
def size_y(self):
return self.size[1]

Now you can use all three attributes without storing redundant data:

pf = PlayingField(size=(5, 5))
print(pf.size)
print(pf.size_x)
print(pf.size_y)


More complex and difficult questions arise when planning relationships between multiple classes.
There will be multiple working alternatives, but some may fall on your feet in the long run.
You may want to read more about **SOLID principles**, **Object Composition** and **Design Patterns**.

## Classes vs SQL

If you have worked with SQL, there is a striking parallel between SQL tables and classes.
Tables have columns, classes have attributes.
Tables have rows, classes have instances.
Both structure data.
Class diagrams are conceptually very close to Entity-Relationship (ER) diagrams used in the database world.

----

## Exercise

Turn the class diagram of the Snake class into skeleton code.
Leave all methods empty.

![Snake class diagram](images/class_snake.png)

----
## Further Reading

The class diagrams in this article were designed with the online tool [Creately](https://app.creately.com).
2 changes: 1 addition & 1 deletion conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
]

templates_path = ['_templates']
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'README.md']

language = 'ls'

Expand Down
Binary file added getting_started/create_repo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added getting_started/git_dialog.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 7b8a63d

Please sign in to comment.