From a2afca302c68b8b5d7c3bec13378180b60a3ac17 Mon Sep 17 00:00:00 2001 From: Filip Wandzio Date: Sun, 1 Mar 2026 11:29:12 +0100 Subject: Scaffold project Signed-off-by: Filip Wandzio --- .gitignore | 205 +++++++++++++++++++++++++++++++++++++++++++++++++ build/exam | Bin 0 -> 34952 bytes build/questions.txt | 42 ++++++++++ build/test_questions | Bin 0 -> 34688 bytes data/questions.txt | 42 ++++++++++ include/questions.h | 20 +++++ include/utils.h | 8 ++ src/main.c | 83 ++++++++++++++++++++ src/questions.c | 92 ++++++++++++++++++++++ src/utils.c | 34 ++++++++ tests/test_questions.c | 24 ++++++ 11 files changed, 550 insertions(+) create mode 100644 .gitignore create mode 100755 build/exam create mode 100644 build/questions.txt create mode 100755 build/test_questions create mode 100644 data/questions.txt create mode 100644 include/questions.h create mode 100644 include/utils.h create mode 100644 src/main.c create mode 100644 src/questions.c create mode 100644 src/utils.c create mode 100644 tests/test_questions.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d483172 --- /dev/null +++ b/.gitignore @@ -0,0 +1,205 @@ +# Created by https://www.toptal.com/developers/gitignore/api/cmake,c++ +# Edit at https://www.toptal.com/developers/gitignore?templates=cmake,c++ + +### C++ ### +# Prerequisites +*.d + +*.csv +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +### CMake ### +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps + +### CMake Patch ### +CMakeUserPresets.json + +# External projects +*-prefix/ + +### Intellij+all ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### Intellij+all Patch ### +# Ignore everything but code style settings and run configurations +# that are supposed to be shared within teams. + +.idea/* + +!.idea/codeStyles +!.idea/runConfigurations + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### macOS Patch ### +# iCloud generated files +*.icloud + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.toptal.com/developers/gitignore/api/intellij+all,macos,windows diff --git a/build/exam b/build/exam new file mode 100755 index 0000000..988b751 Binary files /dev/null and b/build/exam differ diff --git a/build/questions.txt b/build/questions.txt new file mode 100644 index 0000000..b462db6 --- /dev/null +++ b/build/questions.txt @@ -0,0 +1,42 @@ +#GENERAL +1. Zasady bezpieczeństwa informacji w przedsiębiorstwie. +2. Istota audytu. +3. Podmioty prawa cywilnego – osoba fizyczna a osoba prawna. +4. Rodzaje i formy zawierania umów. +5. Procedury zakładania własnego przedsiębiorstwa. +6. Przyczyny i rodzaje upadłości przedsiębiorstw. +7. Prawa i obowiązki pracownika i pracodawcy. +8. Ochrona baz danych. +9. Rozwój gospodarczy a poziom życia społeczeństwa w świetle podstawowych mierników makroekonomicznych. +10. Rynek pracy uwarunkowania, problemy, tendencje. +11. Polityka fiskalna państwa. +12. Polityka monetarna państwa. +13. Globalizacja i jej wpływ na sytuację gospodarczą. +14. Ocena członkostwa w Unii Europejskiej w wymiarze ekonomicznym i społecznym. +15. Rynek pracy – uwarunkowania, problemy, tendencje. +#MAJOR +1. Zarządzanie projektem informatycznym – istota, etapy, zadania. +2. Czynniki wyboru systemu informatycznego. +3. Interesariusze i ograniczenia w projektach informatycznych. +4. Metodyki zarządzania projektem informatycznym. +5. Znaczenie baz i hurtowni danych dla podejmowania decyzji. +6. Funkcje raportowania, analizy i eksploracji danych. +7. Narzędzia, metody wykorzystywane w obszarze Business Intelligence. +8. Zagrożenia i metody ochrony informacji i infrastruktury w przedsiębiorstwie. +9. Bezpieczeństwo informatyczne i identyfikacja zagrożeń w przedsiębiorstwie. +10. System zarządzania bezpieczeństwem. +11. Na czym polega złożoność obliczeniowa algorytmów. +12. Charakterystyka baz danych -cechy, przykłady. +13. Obiekty bazodanowe, pojęcie klucza, typy danych (przykłady). +14. Wykorzystanie systemów wspomagania decyzji w przedsiębiorstwie. +15. Systemy ekspertowe -budowa, znaczenie, wykorzystanie. +16. Internet rzeczy -istota działania, zalety, wady, wykorzystanie. +17. Zagrożenia w systemach Internetu rzeczy. +18. Uczenie maszynowe – analiza pojęcia, działanie, wykorzystanie. +19. Ograniczenia i problemy w uczeniu maszynowym. +20. Metody uczenia maszynowego. +21. Charakterystyka, bezpieczeństwo aplikacji internetowych i mobilnych. +22. Technologie backendowe i frontendowe -różnice, przykłady. +23. System operacyjny: rola, działanie, budowa, rodzaje. +24. Integracja systemów informatycznych. +25. Wymień i krótko omów wybrane zagrożenia cybernetyczne. diff --git a/build/test_questions b/build/test_questions new file mode 100755 index 0000000..04dac40 Binary files /dev/null and b/build/test_questions differ diff --git a/data/questions.txt b/data/questions.txt new file mode 100644 index 0000000..b462db6 --- /dev/null +++ b/data/questions.txt @@ -0,0 +1,42 @@ +#GENERAL +1. Zasady bezpieczeństwa informacji w przedsiębiorstwie. +2. Istota audytu. +3. Podmioty prawa cywilnego – osoba fizyczna a osoba prawna. +4. Rodzaje i formy zawierania umów. +5. Procedury zakładania własnego przedsiębiorstwa. +6. Przyczyny i rodzaje upadłości przedsiębiorstw. +7. Prawa i obowiązki pracownika i pracodawcy. +8. Ochrona baz danych. +9. Rozwój gospodarczy a poziom życia społeczeństwa w świetle podstawowych mierników makroekonomicznych. +10. Rynek pracy uwarunkowania, problemy, tendencje. +11. Polityka fiskalna państwa. +12. Polityka monetarna państwa. +13. Globalizacja i jej wpływ na sytuację gospodarczą. +14. Ocena członkostwa w Unii Europejskiej w wymiarze ekonomicznym i społecznym. +15. Rynek pracy – uwarunkowania, problemy, tendencje. +#MAJOR +1. Zarządzanie projektem informatycznym – istota, etapy, zadania. +2. Czynniki wyboru systemu informatycznego. +3. Interesariusze i ograniczenia w projektach informatycznych. +4. Metodyki zarządzania projektem informatycznym. +5. Znaczenie baz i hurtowni danych dla podejmowania decyzji. +6. Funkcje raportowania, analizy i eksploracji danych. +7. Narzędzia, metody wykorzystywane w obszarze Business Intelligence. +8. Zagrożenia i metody ochrony informacji i infrastruktury w przedsiębiorstwie. +9. Bezpieczeństwo informatyczne i identyfikacja zagrożeń w przedsiębiorstwie. +10. System zarządzania bezpieczeństwem. +11. Na czym polega złożoność obliczeniowa algorytmów. +12. Charakterystyka baz danych -cechy, przykłady. +13. Obiekty bazodanowe, pojęcie klucza, typy danych (przykłady). +14. Wykorzystanie systemów wspomagania decyzji w przedsiębiorstwie. +15. Systemy ekspertowe -budowa, znaczenie, wykorzystanie. +16. Internet rzeczy -istota działania, zalety, wady, wykorzystanie. +17. Zagrożenia w systemach Internetu rzeczy. +18. Uczenie maszynowe – analiza pojęcia, działanie, wykorzystanie. +19. Ograniczenia i problemy w uczeniu maszynowym. +20. Metody uczenia maszynowego. +21. Charakterystyka, bezpieczeństwo aplikacji internetowych i mobilnych. +22. Technologie backendowe i frontendowe -różnice, przykłady. +23. System operacyjny: rola, działanie, budowa, rodzaje. +24. Integracja systemów informatycznych. +25. Wymień i krótko omów wybrane zagrożenia cybernetyczne. diff --git a/include/questions.h b/include/questions.h new file mode 100644 index 0000000..75bc751 --- /dev/null +++ b/include/questions.h @@ -0,0 +1,20 @@ +#pragma once +#include + +typedef struct { + char **general; + char **major; + size_t general_count; + size_t major_count; +} QuestionSet; + +/** + * Load questions from file. + * Returns EXIT_SUCCESS or EXIT_FAILURE. + */ +int load_questions(const char *filename, QuestionSet *qs); + +/** + * Free all allocated memory in QuestionSet. + */ +void free_questions(QuestionSet *qs); diff --git a/include/utils.h b/include/utils.h new file mode 100644 index 0000000..74c0ca1 --- /dev/null +++ b/include/utils.h @@ -0,0 +1,8 @@ +#pragma once +#include + +void print_line(void); +void wait_enter(const char *msg); +char ask_yes_no(const char *msg); +void now_str(char *buf, size_t size); +size_t rand_index(size_t max); diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..33d4b39 --- /dev/null +++ b/src/main.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include + +#include "questions.h" +#include "utils.h" + +int main(void) { + srand((unsigned)time(NULL)); + + // utwórz katalog data/ jeśli nie istnieje + struct stat st = {0}; + if (stat("data", &st) == -1) { +#ifdef _WIN32 + _mkdir("data"); +#else + mkdir("data", 0755); +#endif + } + + QuestionSet qs; + if (load_questions("data/questions.txt", &qs) != EXIT_SUCCESS) { + fprintf(stderr, "Error: cannot load questions file\n"); + return EXIT_FAILURE; + } + + FILE *csv = fopen("data/results.csv", "a"); + if (!csv) { + perror("CSV open"); + free_questions(&qs); + return EXIT_FAILURE; + } + + int limit = 0; + printf("Time limit (sec, 0 = unlimited): "); + if (scanf("%d", &limit) != 1) limit = 0; + wait_enter(NULL); + + size_t total = 0, correct = 0; + char cont = 'y'; + + while (cont == 'y' || cont == 'Y') { + const char *g = qs.general[rand_index(qs.general_count)]; + const char *m = qs.major[rand_index(qs.major_count)]; + + print_line(); + printf("GENERAL:\n%s\n\nMAJOR:\n%s\n", g, m); + print_line(); + + wait_enter("Press ENTER to start..."); + time_t start = time(NULL); + + wait_enter("Press ENTER when done..."); + double duration = difftime(time(NULL), start); + + if (limit > 0 && duration > limit) + printf("Time exceeded!\n"); + + char ans = ask_yes_no("Correct? (y/n): "); + if (ans == 'y' || ans == 'Y') correct++; + total++; + + char ts[32]; + now_str(ts, sizeof(ts)); + fprintf(csv, "\"%s\",\"%s\",\"%s\",%c,%.0f\n", ts, g, m, ans, duration); + + printf("Score: %zu/%zu (%.1f%%)\n", + correct, total, + total ? (double)correct / total * 100 : 0.0); + + cont = ask_yes_no("Next? (y/n): "); + } + + printf("\nSession score: %.1f%%\n", + total ? (double)correct / total * 100 : 0.0); + + fclose(csv); + free_questions(&qs); + + return EXIT_SUCCESS; +} diff --git a/src/questions.c b/src/questions.c new file mode 100644 index 0000000..88671a7 --- /dev/null +++ b/src/questions.c @@ -0,0 +1,92 @@ +#include "questions.h" +#include +#include +#include + +#define MAX_LINE 512 + +static int add_question(char ***arr, size_t *count, const char *text) { + char **tmp = realloc(*arr, (*count + 1) * sizeof(char *)); + if (!tmp) + return EXIT_FAILURE; + *arr = tmp; + + (*arr)[*count] = malloc(strlen(text) + 1); + if (!(*arr)[*count]) + return EXIT_FAILURE; + + strcpy((*arr)[*count], text); + (*count)++; + return EXIT_SUCCESS; +} + +int load_questions(const char *filename, QuestionSet *qs) { + if (!filename || !qs) + return EXIT_FAILURE; + + FILE *f = fopen(filename, "r"); + if (!f) + return EXIT_FAILURE; + + qs->general = NULL; + qs->major = NULL; + qs->general_count = 0; + qs->major_count = 0; + + char line[MAX_LINE]; + enum { NONE, GENERAL, MAJOR } mode = NONE; + + while (fgets(line, sizeof(line), f)) { + line[strcspn(line, "\n")] = '\0'; + if (line[0] == '\0') + continue; + + if (strcmp(line, "#GENERAL") == 0) { + mode = GENERAL; + continue; + } + if (strcmp(line, "#MAJOR") == 0) { + mode = MAJOR; + continue; + } + + int res = EXIT_FAILURE; + switch (mode) { + case GENERAL: + res = add_question(&qs->general, &qs->general_count, line); + break; + case MAJOR: + res = add_question(&qs->major, &qs->major_count, line); + break; + default: + continue; // ignore lines before section + } + + if (res != EXIT_SUCCESS) { + fclose(f); + free_questions(qs); + return EXIT_FAILURE; + } + } + + fclose(f); + return (qs->general_count && qs->major_count) ? EXIT_SUCCESS : EXIT_FAILURE; +} + +void free_questions(QuestionSet *qs) { + if (!qs) + return; + + for (size_t i = 0; i < qs->general_count; i++) + free(qs->general[i]); + for (size_t i = 0; i < qs->major_count; i++) + free(qs->major[i]); + + free(qs->general); + free(qs->major); + + qs->general = NULL; + qs->major = NULL; + qs->general_count = 0; + qs->major_count = 0; +} diff --git a/src/utils.c b/src/utils.c new file mode 100644 index 0000000..c139929 --- /dev/null +++ b/src/utils.c @@ -0,0 +1,34 @@ +#include "utils.h" +#include +#include +#include + +void print_line(void) { + printf("--------------------------------------------------\n"); +} + +void wait_enter(const char *msg) { + if (msg) + printf("%s", msg); + int c; + while ((c = getchar()) != '\n' && c != EOF) + ; +} + +char ask_yes_no(const char *msg) { + char c = 'n'; + printf("%s", msg); + if (scanf(" %c", &c) != 1) + c = 'n'; + int flush; + while ((flush = getchar()) != '\n' && flush != EOF) + ; + return c; +} + +void now_str(char *buf, size_t size) { + time_t t = time(NULL); + strftime(buf, size, "%Y-%m-%d %H:%M:%S", localtime(&t)); +} + +size_t rand_index(size_t max) { return max ? (size_t)(rand() % max) : 0; } diff --git a/tests/test_questions.c b/tests/test_questions.c new file mode 100644 index 0000000..c605c1a --- /dev/null +++ b/tests/test_questions.c @@ -0,0 +1,24 @@ +#include "questions.h" +#include +#include + +int main(void) { + QuestionSet qs; + + if (load_questions("data/questions.txt", &qs) != EXIT_SUCCESS) { + fprintf(stderr, "TEST FAILED: cannot load file\n"); + return EXIT_FAILURE; + } + + if (qs.general_count == 0 || qs.major_count == 0) { + fprintf(stderr, "TEST FAILED: empty sets\n"); + free_questions(&qs); + return EXIT_FAILURE; + } + + printf("TEST OK: loaded %zu general, %zu major\n", qs.general_count, + qs.major_count); + + free_questions(&qs); + return EXIT_SUCCESS; +} -- cgit v1.2.3