Skip to content

Commit

Permalink
Merge pull request #1 from Paulocracy/extended_statistics
Browse files Browse the repository at this point in the history
Extended statistics
  • Loading branch information
Paulocracy authored Feb 6, 2024
2 parents ce3ee35 + 18e1af3 commit 71d1583
Show file tree
Hide file tree
Showing 12 changed files with 481 additions and 175 deletions.
24 changes: 16 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,40 @@

<img src="./screenshot.png" width="300" />

Dieses kleine Programm kann eine Unterstützung beim Lernen für die deutsche Amateurfunkprüfung der Klassen N, E und/oder A sein. Hierbei werden Fragen, die man falsch beantwortet hat, mit einer erhöhten Wahrscheinlichkeit wieder abgefragt im Vergleich zu den Fragen, die man schon häufiger richtig beantwortet hat.
Dieses kleine Programm kann einem beim Lernen für die deutsche Amateurfunkprüfung der Klassen N, E und/oder A helfen. Die gestellten Fragen entstammen aus dem offizielle Fragenkatalog der Bundesnetzagentur (siehe auch Abschnitt [Lizenzen](#lizenzen)). Hierbei kann man sich auf Fragen der Kategorien V (Vorschriften), B (Betriebliches), N (Technik Klasse N), E (Technik Klasse E) und/oder A (Technik Klasse A) konzentrieren.

Programmatisch ist der Funkfragenhelfer in Rust geschrieben, außer einem kleinen Pythonskript, welches den ursprünglichen Fragenkatalog in ein für den Funkfragenhelfer leichter lesbares Format umwandelt, und nutzt die Bibliotheken eframe, egui und egui-extras für die graphische Benutzeroberfläche, rayon für ein wenig Parallelisierung und serde bzw. serde-json für die (De)serialisierung von JSON-Dateien. Dies ist eines meiner ersten in Rust verfassten Programme, daher gibt es im Code wahrscheinlich ein großes Verbesserungspotential. Erweiterte Kommentare folgen in späteren Versionen.
Um den Lernfortschritt zu unterstützen, bietet der Funkfragenhelfer die Möglichkeit, die gestellten Fragen zu filtern, dabei lassen sich folgende Filterinstellungen frei kombinieren (falls solche Kombinationen bestehen):

Wer einen kompletten Lehrgang für die Amateurfunkprüfung, und alternative Apps mit mehr Funktionen und mehr unterstützten Systemen, für die Amateurfunkprüfung sucht, dem empfehle ich [50Ω](https://50ohm.de/) aus den Reihen des Deutschen Amateur-Radio-Clubs (DARC). Der hiesige kleine Funkfragenhelfer steht in keiner Verbindung mit 50Ω.
* Von einem markierte Fragen (dies bietet sich bspw. für schwere Fragen an)
* Fragen, die man mindestens einmal falsch beantwortet hat
* Fragen, die man noch nicht beantwortet hat

Mit aktiven Filtern, falls Fragen die zu den Filtern passen existieren, wird eine zufällige passende Frage aus den ausgewählten Fragekategorien gestellt. Ohne aktive Filter, oder wenn keine Frage zu den aktiven Filtern passen, werden alle Fragen der ausgewählten Fragekategorien, die man falsch beantwortet hat, mit einer erhöhten Wahrscheinlichkeit wieder abgefragt im Vergleich zu den Fragen, die man schon häufiger richtig beantwortet hat.

Programmatisch ist der Funkfragenhelfer in Rust geschrieben (außer einem kleinen, für das Starten des Funkfragenhelfers nicht notwendiges, Pythonskript, welches den ursprünglichen Fragenkatalog in ein für den Funkfragenhelfer leichter lesbares Format umwandelt), und nutzt die Bibliotheken [egui](https://github.com/emilk/egui), [eframe](https://docs.rs/eframe/latest/eframe/) sowie [egui-extras](https://docs.rs/egui_extras/latest/egui_extras/) für die graphische Benutzeroberfläche, [rayon](https://github.com/rayon-rs/rayon) für ein wenig Parallelisierung und [serde](https://github.com/serde-rs/serde) bzw. [serde_json](https://docs.rs/serde_json/latest/serde_json/) für die (De)serialisierung von JSON-Dateien. Dies ist eines meiner ersten in Rust verfassten Programme, daher gibt es im Code wahrscheinlich große Verbesserungspotentiale.

Wer einen kompletten Lehrgang für die Amateurfunkprüfung, und alternative Apps mit mehr Funktionen und mehr unterstützten Systemen, für die Amateurfunkprüfung sucht, dem empfehle ich [50Ω](https://50ohm.de/) aus den Reihen des Deutschen Amateur-Radio-Clubs (DARC). Der hiesige kleine Funkfragenhelfer steht in keiner Verbindung zu 50Ω.

## Installation

Unter Windows ist der einfachste Weg, die .zip-Datei "Funkfragenhelfer_Windows.zip" [im letzten Release](https://github.com/Paulocracy/Funkfragenhelfer/releases/latest) unter "Assets" herunterzuladen, an einem beliebigen Ort zu entpacken und dann im entpackten Ordner "Funkfragenhelfer" die "funkfragenhelfer.exe" auszuführen.

Unter anderen, vom Autor bislang nicht getesteten, Systemen (wie Linux und MacOS) empfiehlt sich die Nutzung von Git und cargo, hierfür kloniert man zunächst das Repository:
Unter anderen, vom Autor bislang nicht getesteten, Systemen (wie Linux und MacOS) empfiehlt sich die Nutzung von Git und cargo, hierfür kann man z.B. im Terminal zunächst das Repository clonen per

```sh
git clone https://github.com/Paulocracy/Funkfragenhelfer
```

...und kompiliert und führt das Programm mit Cargo aus:
und kompiliert und führt das Programm dann mit Cargo aus:

```sh
cd Funkfragenhelfer # Falls man noch nicht im neu erstellten Ordner ist
cd Funkfragenhelfer # Falls man noch nicht im von Git neu erstellten Ordner ist
cargo run
```

## Lizenzen

Als Quelle für die hier genutzten Fragen dient der von der von der Bundesnetzagentur für Elektrizität, Gas,
Telekommunikation, Post und Eisenbahnen bereitgestellte Datensatz "Prüfungsfragen zum Erwerb von Amateurfunkprüfungsbescheinigungen, 2. Auflage, Dezember 2023", der über [[diesen Link (Stand: Januar 2024)]](https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Amateurfunk/Fragenkatalog/PruefungsfragenZIP.zip) bezogen wurde und unter den Bedingungen der ["Datenlizenz Deutschland – Namensnennung – Version 2.0"](https://www.govdata.de/dl-de/by-2-0) lizenziert ist. Der Datensatz selber ist in diesem Repository im Unterordner "resources/fragenkatalog" auffindbar.
Telekommunikation, Post und Eisenbahnen bereitgestellte Datensatz "Prüfungsfragen zum Erwerb von Amateurfunkprüfungsbescheinigungen, 2. Auflage, Dezember 2023", der über [diesen Link (Stand: Januar 2024)](https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Amateurfunk/Fragenkatalog/PruefungsfragenZIP.zip) bezogen wurde und unter den Bedingungen der ["Datenlizenz Deutschland – Namensnennung – Version 2.0"](https://www.govdata.de/dl-de/by-2-0) lizenziert ist. Der Datensatz selber ist in diesem Repository im Unterordner "resources/fragenkatalog" auffindbar.

Das Programm selber, ohne den Prüfungskatalog, ist unter der Apache-Lizenz 2.0 lizensiert, welche in der Datei LICENSE abgerufen werden kann.
Der Funkfragenhelfer selber, ohne den Prüfungskatalog, ist unter der Apache-Lizenz 2.0 lizensiert, welche in der Datei [LICENSE](./LICENSE) abgerufen werden kann.
3 changes: 3 additions & 0 deletions config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@
"include_a": false,
"learning_filepath": "./learning/learning.json",
"max_learn_bin": 5,
"prefer_wrong": false,
"prefer_marked": false,
"prefer_new": false,
"questions_filepath": "./questions/questions.json"
}
24 changes: 1 addition & 23 deletions learning/learning.json
Original file line number Diff line number Diff line change
@@ -1,23 +1 @@
{
"BE413": {
"current_bin": 1
},
"NE207": {
"current_bin": 1
},
"BD205": {
"current_bin": 1
},
"VD733": {
"current_bin": 1
},
"VD716": {
"current_bin": 1
},
"NF109": {
"current_bin": 1
},
"VD731": {
"current_bin": 1
}
}
{}
13 changes: 13 additions & 0 deletions raw_json_to_ffh_json.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
"""
This little script converts the Bundesnetzegentur JSON with the
amateur radio questions into an easier format (easier for the
Funkfragenhelfer) without sections and titles. Just compare
"resources/fragenkatalog/fragenkatalog.json" to
"resources/ffh_questions.json" to see the difference.
This script has no special dependencies and should run with any
newer Python 3 interpreter (new as of 2024). It was tested with
Python 3.9, but can probably run with any newer version, and
maybe even older versions, too.
"""

import json
from typing import Any

Expand Down
16 changes: 0 additions & 16 deletions resources/fragenkatalog/test.json

This file was deleted.

Binary file modified screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,42 @@
//! Includes the struct and associated implementations
//! for Funkragenhelfer's main configuration, including
//! the selected question categories and question filters.
// IMPORTS SECTION //
use crate::helper;
use serde::{Deserialize, Serialize};
use std::path::Path;

// STRUCT SECTION //
#[derive(Serialize, Deserialize, Debug)]
pub struct Config {
/// Include question category V (Verordnungen)?
pub include_v: bool,
/// Include question category B (Betriebliches)?
pub include_b: bool,
/// Include question category N (Technik Klasse N)?
pub include_n: bool,
/// Include question category E (Technik Klasse E)?
pub include_e: bool,
/// Include question category A (Technik Klasse A)?
pub include_a: bool,
/// Filepath to learning.json (currently fixed)
pub learning_filepath: String,
/// Maximal learning "bin" (see learning module for more)
pub max_learn_bin: u64,
/// Filter for wrongly answered questions?
pub prefer_wrong: bool,
/// Filter for user-marked questions?
pub prefer_marked: bool,
/// Filter for questions that weren't asked yet?
pub prefer_new: bool,
/// Path to questions.json (currently fixed)
pub questions_filepath: String,
}

impl Config {
/// Return a Config with default values, as if someone
/// would learn for class E without filters.
fn new() -> Config {
Config {
include_v: true,
Expand All @@ -24,15 +46,22 @@ impl Config {
include_a: false,
learning_filepath: String::from("./learning/learning.json"),
max_learn_bin: 5,
prefer_wrong: false,
prefer_marked: false,
prefer_new: false,
questions_filepath: String::from("./questions/questions.json"),
}
}

/// Save the config in the config.json (the directory's existence
/// was ensured beforehand with this module's load_config()).
pub fn save(&self) {
let json_str = serde_json::to_string_pretty(&self).unwrap();
helper::overwrite_file_str("./config/config.json", &json_str);
}

/// Returns whether or not all categories were set off (used by the GUI to prevent that
/// a user shuts off all questions).
pub fn all_includes_false(&self) -> bool {
return !self.include_a
&& !self.include_b
Expand All @@ -42,6 +71,9 @@ impl Config {
}
}

// PUBLIC FUNCTION SECTION //
/// Loads the config.json Config, or, if it doesn't exist, creates
/// a new such JSON with default values.
pub fn load_config() -> Config {
let config_dir_path = Path::new("./config");
if !config_dir_path.exists() {
Expand Down
Loading

0 comments on commit 71d1583

Please sign in to comment.