You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/features/logging.md
+23-3Lines changed: 23 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,27 @@
1
1
# Logging != print()
2
2
3
-
Logging is not the same as printing to the console. Logging is a more sophisticated way of recording events in a program.
4
-
It is a way to track the flow of the program and to record errors and exceptions.
3
+
Logging records the flow of a program, including its errors and exceptions, to the console and to a file at once. It is more than printing.
4
+
5
+
## Usage
6
+
7
+
Call `setup_logger` once at startup, then use the shared `logger` everywhere. The `time_it` decorator logs how long a function takes:
8
+
9
+
```python
10
+
from pathlib import Path
11
+
12
+
from py_app_dev.core.logging import logger, setup_logger, time_it
13
+
14
+
15
+
@time_it()
16
+
defbuild() -> None:
17
+
logger.info("building ...")
18
+
19
+
20
+
setup_logger(Path("build.log")) # console + file
21
+
build()
22
+
```
23
+
24
+
## Requirements
5
25
6
26
```{item} REQ-LOGGING_FILE-0.0.1 Print to file
7
27
@@ -41,7 +61,7 @@ It is a way to track the flow of the program and to record errors and exceptions
41
61
```
42
62
43
63
:::{note}
44
-
This module is based on the [loguru](https://github.com/Delgan/loguru)library, which is a Python logging library that provides powerful logging system.
64
+
This module is built on the [loguru](https://github.com/Delgan/loguru) logging library.
Copy file name to clipboardExpand all lines: docs/features/runnable.md
+39Lines changed: 39 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,6 +4,45 @@ To optimize an application, you want to avoid executing tasks with high computat
4
4
A simple way to avoid unnecessary executions is to check whether the inputs and outputs of a task have changed since the last execution.
5
5
If there are no changes, the task is skipped, saving time and resources.
6
6
7
+
## Usage
8
+
9
+
Subclass `Runnable`, declare the task's inputs and outputs, then hand it to an `Executor`. The executor skips the task when nothing changed since the last run:
10
+
11
+
```python
12
+
from pathlib import Path
13
+
14
+
from py_app_dev.core.runnable import Executor, Runnable
Copy file name to clipboardExpand all lines: docs/features/scoop_wrapper.md
+19Lines changed: 19 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,6 +3,25 @@
3
3
The [Scoop](https://scoop.sh/) package manager for Windows has certain limitations, particularly in handling of tool versions and path prioritization via shims.
4
4
This module allows users to specify which versions of apps they want installed and actively manage the accessibility of these apps within their environment.
5
5
6
+
## Usage
7
+
8
+
Point `ScoopWrapper` at a scoop file (the JSON listing the apps and versions you want). `install` installs anything missing and returns every required app, located on disk:
9
+
10
+
```python
11
+
from pathlib import Path
12
+
13
+
from py_app_dev.core.scoop_wrapper import ScoopWrapper
Copy file name to clipboardExpand all lines: docs/internals/mvp/index.md
+2-24Lines changed: 2 additions & 24 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -43,33 +43,11 @@ The Presenter subscribes to the Event Manager to handle these events and updates
43
43
Presenter "1" *-- EventManager
44
44
```
45
45
46
-
The implementation above uses the Model-View-Presenter (MVP) design pattern along with the Event Manager to handle events and communication between the components.
47
-
Here are some advantages of this implementation:
48
-
49
-
-**Separation of Concerns:**
50
-
: This pattern pattern separates the responsibilities of the View and Presenter into distinct components, which makes the code easier to read, test, and maintain.
51
-
The Event Manager also helps to decouple the components, making it easier to modify and extend the code without affecting other parts.
52
-
-**Testability:**
53
-
: The Presenter acts as a mediator between the View and the underlying functionality, which allows for easy unit testing of the Presenter without needing to test the user interface.
54
-
-**Flexibility:**
55
-
: It allows for different user interfaces to be used with the same underlying functionality.
56
-
For example, if we wanted to switch from a graphical user interface to a command-line interface, we could do so without affecting the underlying functionality of the application.
46
+
Keeping the View and Presenter apart, with the Event Manager between them, makes the Presenter unit-testable without a user interface and lets the same logic drive a different View (for example, swapping a GUI for a command line).
57
47
58
48
## Event Manager
59
49
60
-
The EventManager class is a utility class that can be used in conjunction with the Model-View-Presenter design pattern to facilitate communication between the View and the Presenter.
61
-
Its primary purpose is to handle events that are raised by the View and forward them to the appropriate Presenter methods.
62
-
63
-
By using the EventManager class, the View can raise events using the create_event_trigger method, and the Presenter can subscribe to those events using the subscribe method.
64
-
When the event is triggered, the EventManager calls all of the registered callbacks for that event, allowing the Presenter to handle the event appropriately.
65
-
The unsubscribe method can be used to remove callbacks from the list of subscribers if needed.
66
-
67
-
It's worth noting that the EventManager class, as described above, is actually an implementation of the Observer design pattern.
68
-
In this pattern, the EventManager acts as the Subject or Observable, while the callbacks registered through the subscribe method serve as the Observers.
69
-
70
-
When an event is triggered, the EventManager notifies all registered Observers by calling their respective callback functions. This decouples the components of the system and allows for easier maintenance and modifications in the future.
71
-
72
-
By using the Observer pattern with the EventManager class, the View can raise events without knowing anything about the Presenter, and the Presenter can handle events without knowing anything about the View. This promotes a more modular and flexible architecture, making it easier to develop and maintain complex systems.
50
+
The `EventManager` decouples the View from the Presenter: the View raises events with `create_event_trigger`, and the Presenter reacts to them with `subscribe`. When an event fires, the manager calls every registered callback; `unsubscribe` removes one. This is the Observer pattern, with the manager as the subject and the callbacks as the observers, so neither side needs to know about the other.
0 commit comments