From cc8cc53dfbd7aa3d98219775d96c1ca95517771a Mon Sep 17 00:00:00 2001 From: Krzysztof kuhy Rudnicki Date: Sun, 22 Feb 2026 22:00:50 +0100 Subject: [PATCH] feat: added run sh and makefile scripts --- .gitignore | 34 + .pre-commit-config.yaml | 12 + C/1dvelocitysimulator/Makefile | 19 + C/1dvelocitysimulator/main.c | 27 +- C/1dvelocitysimulator/run.sh | 4 + C/fps/run.sh | 12 + C/imageViewer/run.sh | 15 + C/lichess_random_engine/run.sh | 5 + C/misc/Makefile | 19 + C/misc/randomJPG/run.sh | 12 + C/misc/run.sh | 4 + C/misc/split/Makefile | 19 + C/misc/split/run.sh | 4 + C/opening_learner/chess.o | Bin 13784 -> 13720 bytes C/opening_learner/engine.o | Bin 7920 -> 8256 bytes C/opening_learner/gui.o | Bin 7152 -> 7128 bytes C/opening_learner/main.o | Bin 7984 -> 7992 bytes C/opening_learner/mistakes.o | Bin 4016 -> 4136 bytes C/opening_learner/opening_learner | Bin 40168 -> 40608 bytes C/opening_learner/run.sh | 2 +- C/scrapeWebsite/Makefile | 19 + C/scrapeWebsite/run.sh | 12 + C/tests/Makefile | 19 + ...generatingPolishLettersOnWindowsTerminal.c | 13 +- C/tests/run.sh | 4 + C/vocabulary_curve/run.sh | 4 + C/vocabulary_curve/vocabulary_curve | Bin 20936 -> 21416 bytes C/websocketServer/Makefile | 19 + C/websocketServer/run.sh | 17 + CPP/miscelanious/Makefile | 30 + CPP/miscelanious/Pi/Makefile | 19 + CPP/miscelanious/Pi/run.sh | 4 + CPP/miscelanious/brydz/Makefile | 19 + CPP/miscelanious/brydz/brydz.cpp | 2 +- CPP/miscelanious/brydz/run.sh | 4 + CPP/miscelanious/calculateShotsDarts/Makefile | 20 + .../calculateShotsDarts/basic.cpp | 1 - CPP/miscelanious/calculateShotsDarts/main.cpp | 74 ++- CPP/miscelanious/calculateShotsDarts/run.sh | 4 + .../findIntegerPercentageValue/Makefile | 19 + .../findIntegerPercentageValue/run.sh | 4 + .../howManyValidISBNNumbersAreThere/Makefile | 19 + .../howManyValidISBNNumbersAreThere/run.sh | 4 + .../markovChainGenerator/Makefile | 20 + .../markovChainGenerator/main.cpp | 51 +- CPP/miscelanious/markovChainGenerator/run.sh | 4 + .../mutiplicationWithoutStar/Makefile | 19 + .../mutiplicationWithoutStar/run.sh | 4 + CPP/miscelanious/randomDevice/Makefile | 19 + CPP/miscelanious/randomDevice/run.sh | 4 + CPP/miscelanious/run.sh | 7 + CPP/miscelanious/tictactoe/Makefile | 19 + CPP/miscelanious/tictactoe/run.sh | 4 + CPP/miscelanious/tierListConverter/Makefile | 19 + CPP/miscelanious/tierListConverter/run.sh | 4 + CPP/miscelanious/xGoesTo0/Makefile | 19 + CPP/miscelanious/xGoesTo0/run.sh | 4 + .../yousuckatcards/Bernouli/Makefile | 22 + .../yousuckatcards/Bernouli/run.sh | 5 + CPP/miscelanious/yousuckatcards/run.sh | 4 + CPP/tests/Makefile | 19 + CPP/tests/run.sh | 4 + .../LaTeX}/.gitignore | 0 {LaTeX => linux_configuration/LaTeX}/main.tex | 0 .../LaTeX}/mauin2.tex | 0 python_pkg/anki_decks/polish_gminy/run.sh | 3 +- .../anki_decks/polish_license_plates/run.sh | 9 + python_pkg/anki_decks/polish_powiaty/run.sh | 3 +- python_pkg/anki_decks/run.sh | 16 + python_pkg/anki_decks/warsaw_bridges/run.sh | 3 +- python_pkg/anki_decks/warsaw_districts/run.sh | 3 +- python_pkg/anki_decks/warsaw_landmarks/run.sh | 3 +- python_pkg/anki_decks/warsaw_metro/run.sh | 3 +- python_pkg/anki_decks/warsaw_osiedla/run.sh | 3 +- python_pkg/anki_decks/warsaw_streets/run.sh | 3 +- python_pkg/brightness_controller/run.sh | 9 + python_pkg/brother_printer/run.sh | 10 + python_pkg/download_cats/requirements.txt | 3 - python_pkg/download_cats/run.sh | 9 + python_pkg/keyboard_coop/run.sh | 11 + python_pkg/lichess_bot/run.sh | 2 +- python_pkg/mock_server/run.sh | 19 +- python_pkg/music_gen/run.sh | 10 + python_pkg/praca_magisterska_video/run.sh | 16 + python_pkg/random_jpg/run.sh | 8 + python_pkg/randomize_numbers/run.sh | 4 + python_pkg/repo_explorer/repo_explorer.py | 594 ++++++++++++++++++ python_pkg/repo_explorer/run.sh | 18 + python_pkg/scrape_website/run.sh | 10 + python_pkg/screen_locker/run.sh | 10 + python_pkg/split/run.sh | 4 + .../stockfish_analysis/analyze_chess_game.py | 20 +- python_pkg/stockfish_analysis/run.sh | 8 +- python_pkg/tag_divider/run.sh | 9 + python_pkg/word_frequency/run.sh | 5 + scripts/check_c_cpp_build_files.sh | 40 ++ 96 files changed, 1571 insertions(+), 66 deletions(-) create mode 100644 C/1dvelocitysimulator/Makefile create mode 100755 C/1dvelocitysimulator/run.sh create mode 100755 C/fps/run.sh create mode 100755 C/imageViewer/run.sh create mode 100755 C/lichess_random_engine/run.sh create mode 100644 C/misc/Makefile create mode 100755 C/misc/randomJPG/run.sh create mode 100755 C/misc/run.sh create mode 100644 C/misc/split/Makefile create mode 100755 C/misc/split/run.sh create mode 100644 C/scrapeWebsite/Makefile create mode 100755 C/scrapeWebsite/run.sh create mode 100644 C/tests/Makefile create mode 100755 C/tests/run.sh create mode 100755 C/vocabulary_curve/run.sh create mode 100644 C/websocketServer/Makefile create mode 100755 C/websocketServer/run.sh create mode 100644 CPP/miscelanious/Makefile create mode 100644 CPP/miscelanious/Pi/Makefile create mode 100755 CPP/miscelanious/Pi/run.sh create mode 100644 CPP/miscelanious/brydz/Makefile create mode 100755 CPP/miscelanious/brydz/run.sh create mode 100644 CPP/miscelanious/calculateShotsDarts/Makefile create mode 100755 CPP/miscelanious/calculateShotsDarts/run.sh create mode 100644 CPP/miscelanious/findIntegerPercentageValue/Makefile create mode 100755 CPP/miscelanious/findIntegerPercentageValue/run.sh create mode 100644 CPP/miscelanious/howManyValidISBNNumbersAreThere/Makefile create mode 100755 CPP/miscelanious/howManyValidISBNNumbersAreThere/run.sh create mode 100644 CPP/miscelanious/markovChainGenerator/Makefile create mode 100755 CPP/miscelanious/markovChainGenerator/run.sh create mode 100644 CPP/miscelanious/mutiplicationWithoutStar/Makefile create mode 100755 CPP/miscelanious/mutiplicationWithoutStar/run.sh create mode 100644 CPP/miscelanious/randomDevice/Makefile create mode 100755 CPP/miscelanious/randomDevice/run.sh create mode 100755 CPP/miscelanious/run.sh create mode 100644 CPP/miscelanious/tictactoe/Makefile create mode 100755 CPP/miscelanious/tictactoe/run.sh create mode 100644 CPP/miscelanious/tierListConverter/Makefile create mode 100755 CPP/miscelanious/tierListConverter/run.sh create mode 100644 CPP/miscelanious/xGoesTo0/Makefile create mode 100755 CPP/miscelanious/xGoesTo0/run.sh create mode 100644 CPP/miscelanious/yousuckatcards/Bernouli/Makefile create mode 100755 CPP/miscelanious/yousuckatcards/Bernouli/run.sh create mode 100755 CPP/miscelanious/yousuckatcards/run.sh create mode 100644 CPP/tests/Makefile create mode 100755 CPP/tests/run.sh rename {LaTeX => linux_configuration/LaTeX}/.gitignore (100%) rename {LaTeX => linux_configuration/LaTeX}/main.tex (100%) rename {LaTeX => linux_configuration/LaTeX}/mauin2.tex (100%) create mode 100755 python_pkg/anki_decks/polish_license_plates/run.sh create mode 100755 python_pkg/anki_decks/run.sh create mode 100755 python_pkg/brightness_controller/run.sh create mode 100755 python_pkg/brother_printer/run.sh create mode 100755 python_pkg/download_cats/run.sh create mode 100755 python_pkg/keyboard_coop/run.sh create mode 100755 python_pkg/music_gen/run.sh create mode 100755 python_pkg/praca_magisterska_video/run.sh create mode 100755 python_pkg/random_jpg/run.sh create mode 100755 python_pkg/randomize_numbers/run.sh create mode 100755 python_pkg/repo_explorer/repo_explorer.py create mode 100755 python_pkg/repo_explorer/run.sh create mode 100755 python_pkg/scrape_website/run.sh create mode 100755 python_pkg/screen_locker/run.sh create mode 100755 python_pkg/split/run.sh create mode 100755 python_pkg/tag_divider/run.sh create mode 100755 python_pkg/word_frequency/run.sh create mode 100755 scripts/check_c_cpp_build_files.sh diff --git a/.gitignore b/.gitignore index 137752d..f419996 100644 --- a/.gitignore +++ b/.gitignore @@ -252,6 +252,39 @@ fps_demo server_c Bash/ffmpeg-build/FFmpeg +# C/C++ compiled binaries +C/1dvelocitysimulator/1dvelocitysimulator +C/imageViewer/imageviewer +C/lichess_random_engine/random_engine +C/lichess_random_engine/perft +C/misc/generating_words +C/misc/randomJPG/generate_images +C/misc/split/split +C/opening_learner/opening_learner +C/scrapeWebsite/scrape +C/tests/polish_letters +C/vocabulary_curve/vocabulary_curve +C/websocketServer/websocket_server +CPP/miscelanious/brydz/brydz +CPP/miscelanious/calculateShotsDarts/darts +CPP/miscelanious/findIntegerPercentageValue/find_percentage +CPP/miscelanious/howManyValidISBNNumbersAreThere/isbn_counter +CPP/miscelanious/howOftenDoesCharOccur +CPP/miscelanious/quickchallenges +CPP/miscelanious/reverseString +CPP/miscelanious/solveQuadraticEquation +CPP/miscelanious/markovChainGenerator/markov +CPP/miscelanious/mutiplicationWithoutStar/multiplication +CPP/miscelanious/Pi/pi +CPP/miscelanious/randomDevice/random_device_demo +CPP/miscelanious/tictactoe/tictactoe +CPP/miscelanious/tierListConverter/tier_list_converter +CPP/miscelanious/xGoesTo0/xgoes +CPP/miscelanious/yousuckatcards/a.out +CPP/miscelanious/yousuckatcards/Bernouli/bernouli +CPP/miscelanious/yousuckatcards/Bernouli/test +CPP/tests/division_test + # Screen locker workout log python_pkg/screen_locker/workout_log.json python_pkg/music_gen/output/ @@ -282,3 +315,4 @@ python_pkg/cinema_planner/pasted_content.txt # FVM Version Cache .fvm/ +CPP/miscelanious/howManyValidISBNNumbersAreThere/ISBN.txt diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a95b147..2ac259f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -311,6 +311,18 @@ repos: types_or: [ts, tsx] files: ^TS/ + # =========================================================================== + # CHECK C/C++ BUILD FILES - Ensure every C/C++ dir has Makefile and run.sh + # =========================================================================== + - repo: local + hooks: + - id: check-c-cpp-build-files + name: check C/C++ dirs have Makefile and run.sh + entry: scripts/check_c_cpp_build_files.sh + language: script + types_or: [c, c++] + exclude: ^CPP/mini_browser/ + # =========================================================================== # REMOVE EMPTY DIRECTORIES - Clean up empty folders in the repo # =========================================================================== diff --git a/C/1dvelocitysimulator/Makefile b/C/1dvelocitysimulator/Makefile new file mode 100644 index 0000000..1fce470 --- /dev/null +++ b/C/1dvelocitysimulator/Makefile @@ -0,0 +1,19 @@ +CC := gcc +CFLAGS := -O2 -Wall -Wextra -std=c11 -D_DEFAULT_SOURCE +LDFLAGS := + +SRC := main.c +BIN := 1dvelocitysimulator + +all: $(BIN) + +$(BIN): $(SRC) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +run: $(BIN) + ./$(BIN) + +clean: + rm -f $(BIN) + +.PHONY: all run clean diff --git a/C/1dvelocitysimulator/main.c b/C/1dvelocitysimulator/main.c index d4ccc07..b5ea54a 100644 --- a/C/1dvelocitysimulator/main.c +++ b/C/1dvelocitysimulator/main.c @@ -1,7 +1,24 @@ #include #include #include + +#ifdef _WIN32 #include +#define SLEEP_MS(ms) Sleep(ms) +#define CLEAR_SCREEN() system("CLS") +#define PAUSE() system("PAUSE") +#else +#include +#define SLEEP_MS(ms) usleep((ms) * 1000U) +#define CLEAR_SCREEN() system("clear") +#define PAUSE() \ + do \ + { \ + printf("Press Enter to continue..."); \ + getchar(); \ + } while (0) +#endif + #define LINE_LENGTH 100 void C() @@ -13,27 +30,27 @@ void C() void printAcceleration(int acceleration) { printf("The value of acceleration is: %d\n", acceleration); - system("PAUSE"); + PAUSE(); return; } -void pauseSystem() { system("PAUSE"); } +void pauseSystem() { PAUSE(); } void clearScreen() { - system("CLS"); + CLEAR_SCREEN(); return; } void pauseForASecond() { - Sleep(1000); + SLEEP_MS(1000); return; } void pauseForGivenTime(float given_time) { - Sleep(fabs(given_time * 1000)); + SLEEP_MS((unsigned int)fabs(given_time * 1000)); return; } diff --git a/C/1dvelocitysimulator/run.sh b/C/1dvelocitysimulator/run.sh new file mode 100755 index 0000000..aa6f158 --- /dev/null +++ b/C/1dvelocitysimulator/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +make +./1dvelocitysimulator diff --git a/C/fps/run.sh b/C/fps/run.sh new file mode 100755 index 0000000..f90b626 --- /dev/null +++ b/C/fps/run.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -e +# Install dependencies +if command -v apt-get &>/dev/null; then + sudo apt-get install -y freeglut3-dev libglu1-mesa-dev libsdl2-dev +elif command -v pacman &>/dev/null; then + pacman -Q freeglut sdl2 &>/dev/null || sudo pacman -S --noconfirm freeglut sdl2 +elif command -v dnf &>/dev/null; then + sudo dnf install -y freeglut-devel mesa-libGLU-devel SDL2-devel +fi +make +./fps_demo diff --git a/C/imageViewer/run.sh b/C/imageViewer/run.sh new file mode 100755 index 0000000..2c44c2d --- /dev/null +++ b/C/imageViewer/run.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +set -e +# Install dependencies +if command -v apt-get &>/dev/null; then + sudo apt-get install -y libsdl2-dev libsdl2-image-dev +elif command -v pacman &>/dev/null; then + pacman -Q sdl2 sdl2_image &>/dev/null || sudo pacman -S --noconfirm sdl2 sdl2_image +elif command -v dnf &>/dev/null; then + sudo dnf install -y SDL2-devel SDL2_image-devel +fi +make +echo "Usage: ./imageviewer " +if [[ $# -gt 0 ]]; then + ./imageviewer "$@" +fi diff --git a/C/lichess_random_engine/run.sh b/C/lichess_random_engine/run.sh new file mode 100755 index 0000000..8082341 --- /dev/null +++ b/C/lichess_random_engine/run.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -e +make +echo "Usage: ./random_engine --fen \"\" move1 move2 ..." +echo " ./random_engine --fen \"\" --explain move1 ..." diff --git a/C/misc/Makefile b/C/misc/Makefile new file mode 100644 index 0000000..268edf2 --- /dev/null +++ b/C/misc/Makefile @@ -0,0 +1,19 @@ +CC := gcc +CFLAGS := -O2 -Wall -Wextra -std=c11 +LDFLAGS := + +SRC := generatingWordsEndingWIthalka.c +BIN := generating_words + +all: $(BIN) + +$(BIN): $(SRC) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +run: $(BIN) + ./$(BIN) + +clean: + rm -f $(BIN) + +.PHONY: all run clean diff --git a/C/misc/randomJPG/run.sh b/C/misc/randomJPG/run.sh new file mode 100755 index 0000000..28ddbc7 --- /dev/null +++ b/C/misc/randomJPG/run.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -e +# Install dependencies +if command -v apt-get &>/dev/null; then + sudo apt-get install -y libjpeg-dev +elif command -v pacman &>/dev/null; then + pacman -Q libjpeg-turbo &>/dev/null || sudo pacman -S --noconfirm libjpeg-turbo +elif command -v dnf &>/dev/null; then + sudo dnf install -y libjpeg-turbo-devel +fi +make +./generate_images diff --git a/C/misc/run.sh b/C/misc/run.sh new file mode 100755 index 0000000..683b87c --- /dev/null +++ b/C/misc/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +make +./generating_words diff --git a/C/misc/split/Makefile b/C/misc/split/Makefile new file mode 100644 index 0000000..5400fa9 --- /dev/null +++ b/C/misc/split/Makefile @@ -0,0 +1,19 @@ +CC := gcc +CFLAGS := -O2 -Wall -Wextra -std=c11 +LDFLAGS := + +SRC := main.c +BIN := split + +all: $(BIN) + +$(BIN): $(SRC) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +run: $(BIN) + ./$(BIN) + +clean: + rm -f $(BIN) + +.PHONY: all run clean diff --git a/C/misc/split/run.sh b/C/misc/split/run.sh new file mode 100755 index 0000000..ddfb785 --- /dev/null +++ b/C/misc/split/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +make +./split diff --git a/C/opening_learner/chess.o b/C/opening_learner/chess.o index ee51fb838b1b6ceba9e8e0b51b37f8c6a0eda08c..bebc2ad196cf62dc7fd7f01b1bd536b9342a07c7 100644 GIT binary patch delta 5961 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 l4Io?p&^Pe|Fr2+J!_mc;eUr?Uef>o diff --git a/C/opening_learner/engine.o b/C/opening_learner/engine.o index e400c89a000e4fead1eedb84e1f3145f63ad0002..60b65467c8bf155b2a55b39c03e44d52ca57a49b 100644 GIT binary patch literal 8256 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 nw+FyU@knix<) z8a2Dv%Mys3hrWnf=!1d}F8fmVA!cI&Dg}29k&w`09-^BFnq48r^=CbIRwWO5;C$!Y z^WF2^GiRoomzsy0$WlDGOlp6M4ag%tNs?OAJVW>1Y2&Av44YjW4lZzu`GSi!JvRTy z96GWlnB^IpJ`A&_)PkSfyD6G71wP3;SvMa`E&541>C{%Z$--G=rC28mTPUdh$e&oe zp9RdJn2&0Y)7)k z$vPJjM3Sg~CtP-Ktu*=HY#4j_b(nPr26iG98KsdHjDuNYPwa&JgGSHy;c=vZ*No%_ z#5`SBjX|>M^9MY~^B70bXD$9xyx*3mn>v{Q(`aNN{NglzBr_r-($lM5C@Am@+8E-wn)cy|qhJZ1m3z^{m#+dt`qTY>qC|NLmP-`MpA-kqME;%A%w6k0hr2cIvg;8HPqHV9skN zc9+Eod74-$PrIn?*kgU0W4GacrQ-eW+m_Hacv?9{EcU&0C(cctHX2Kz#Lb@P@ zc*@Dgo&2>x?UlFGC7RV$UG0!V_FUQL*;|4o&mG(j9kq&fSUia)bQ;hRlRrMt2%}Fz(71IP zcmC5t1Gq?GVq3z~U?}@Z3tUt#k|tx)ZiuToV$Q*krjv2#)pYN4C3eAu z>Y9oV^GPyfG(X8gPSahUDwtF1;K~{gSoO>$S3zI>4wR4A>m&_1#48YL&`BHgBK`vL GhQ{~cgK*;j diff --git a/C/opening_learner/main.o b/C/opening_learner/main.o index e59782fb2f1fdcf8c9e448ad8ae4cffdbfa1df79..c3080865d46a3fc0c62ba4b41711fb70673ba7f3 100644 GIT binary patch delta 2974 zcmZ`*4Qy0J5PsVqdZp6Wrlr^GkF>Cqt0>%oV)3tcwUs@6B|wOxmcImw7;J&GN{D(T z_by>`ocwHKBtcRP5fn_oVnYGp_-i52SWuKm3?)kFQ7RyRYJ_uU-yN(NHhphzzi(!C zc4lW@cRaWIxiwC*duMqb@i3RB&10dWkxot17~eoE0C1l%!rQ5bXqpk;MUTPU2du`s z<@VCr5(l%%IcZka7@pGU#PcCFE{8Maho`ccYv_L7tyT14Pt~_sq0a+ev9!|up_)l zIsW=?lYWH$0dCSYaz1^HZ9`vhW$@{AF|S>Sz}FQGxzxV7(J`WU|`CwB!*rKPTa_n`k}@Z=h|E7xw^W6n`0f9`)4n>ptGa zAi1tF2wh--qeO1E#|DNhLL5jQH}onPHp2Vp71+e!x6n!o5ra}DlZl|z_e^S8 z9Xi7JS?L5GZE?c8I5Hh>2AsBt_Ben0@verkg(3ljV1FN7A$N4?^$QV{F1jC-<}VlU}@1N(8pX)5p&aX z#J)j=eqCn2mG*%z7>+D9@z8GYLSy>#JuF;B*us-5A^9x1Rn{$51j_pODH#r5IJ^?1 z-4PZZifa2c6o&j__^r6c7cBe)3P{Y5J3&dO1tZOl{%6;S#c2ipUZ4$rM@pEHrXMk3 z7G{OM{|I{Mge_Y@GQOcZvL9F0RzNd(;e6q*?xK3fF4_`5o-J^bc=Qe{pI@ zy0#}<6GgV%sXswfWgPZkcF+S%j%A%6#F{fV0}_Xn_^~ULRjy#rxsHFX$+`n&Eg@*p!2uKzThhn-vCk#~c{b2Xc$b$S zk#cZz<*B@Z>!g~Wk52pxbAS!#KS8saZ*(NG5O6G@8utM92TybgWU`iDh<+h6iq{x2 z7rDD3ES$0*#KUfR47cU}rT}#$Rt+wEvR742Xx;<=rx`s3W!R^QGlNH@PH>HLO%%x) zOGt-k&Y(ptbCYeUgEK3We%iIxu!6s#Qoh$T68#}GI(4rB}9Nw8I7Q;ywtSYZnlb`+E(4%8}wC!sZ2!HX6A zeL-^VjxzECf1_xR$g(qS8YXu*!;A2n_22La3Nytxo0RE;p z2%aog*b+r+mADG*Mui=zut!DdP`l%YIE#lVQ`qxjDzFz7-BAjAU9151fV_elb~OBi z-u1Ry>;(2ioJA8(g*_wA4Ym7zRap41sxkjmoB-Xuif)Etxm)i0i=wOM_oi^$?Y^WmP=IlNY;zR+ zA>b3<=Ere7yBh7s#ajDV@~t>%w>zSW%y325CawZoVFL&TS{MsY!g8f3&9^%yDQvmI zz9yyuyFg*F6(w|+ixt3bQdqSXwuzm&dKRoO4H9d_atOW^&2@WOkB z*aYtt68TUfTP5;kd#7VHA)a<$;Us7UVr|irWTiM>R7v_odT}MWB7DV_Ne^MW$P;bF mPLd^#1MCs$4_A`Y!Uyk&;P9Ryjz3(PZbL6%d@j}&4*M58V#-Yb delta 3007 zcmZ`)du&rx7{8ZwP&V1!6llvjHo|d~_bLxJB+$+-o{?MQln5%X8J;qp>BvkVE%r9q zNv&)-7$ow?h$NB#0RjO=2zG#5@PQ0`keKk2R~>^8WPk|u`_AnhCo!J%oO|#0`@Zjd z?;e@9Z(5T_-M4?_VAbawuP6&?-2JjgQ54Fy5jzmPzw3$JL{Sw*PaGtT@Vo`6!aBsG zbuhf^?5@s2gz~UDMP15|s)e44zMvstkeR?wSqEhSQZ57<17wzw)Qs=4gd8vJ;|WJb zDN1{QELWlrR6VhoD5Fv6;o^<}X;75=yJ$QcuhiLZtv+~CwwWvi5mdUGvJ3a=E}9Up zA>u(|34Ye$Tba)4NWRWylG&*kh&Iu6lRpG7n*>&W zlLN|y-pG1zP>VGI0~+C>@tI%*Sdz~hvb2)-)9Eyg&ms9}NjZfmBtfzj9mlvY;9qAA zpK-SjMj=F;G_j2=fDn7TF**3AvxUSLWPeq&cC9!7cYu&G7U?%>^jlS!aMTXkOn_^) zR|ZW+xx_KD50lFtqN-C0f7dp7m;y+UT}LxeIZfF9r0hIK)ESI{n@PUMR;F&^7j15} zf{)_1UHK(J;y`38T>8*_O4v z6cGVTvd(%k!~pSNoM+M2_g2-fEeX}HrOdv#!)ITqq~3m-P7AiJ51*zA__OQ@VXWPS zbo4+`%v$Wc4X)gH3QPQhx&Ar+x&C?n`6spF2pUS`S;52xl}1n6D?5zc7!UXf5yXM^ODzIn%s%C}`;H3_61A|I?8HKY@Z<*? zb;xT?e(+zva5|y3p7!w>RCHPS5jsO0TG7k#HXYYn7v7w7=%K{6~TT?)PxyO zNW92HViGb4ny7u}5GZcw*-(uhhvunbKXnbY9OW(jhJ;&yU1xWMgpmyWipeu+cLlBM zR26%Sc6-o_2ykbN@FtJrm+(e#R)Zu`GKG0ew6#FALkEd3bYv*lpo1s*!eNYj*zEF$ zroUK2I=hM!rnjkjJI%~=?eNM~LyE8s ztGwMv^rdqDPN#$HW@;%sMaI$h2#BI}6QIJ(ac3nU6OI3l7U)JZ?YudsaAFGxQy6;< zkV8|%%puYx6`5jB{QwPpi~o@`JbO}ExpxB3&0VAJqn#N@!1pj(+r)=yv!A#f1iqfo=Kd;I)GtF1Lij-(oLXCD0lFgMP@{Kz5yk5=nLw zzXxcGgv$3G<-;6~+Vc`B*Vy$89la=(boNN}7bN-vnZiQfOJG~R z-{Dsr4p%;=4Hlx~U|Z-|Uf^`NCT38y1Vd|~Q@J0|po9*P&{=#9pdU$^<(h2f+X4Mj zLgh~RigyCKPeSFYJIz&>!*xTtSMI@5?sYlT*LX9WL0$`|At;*#WxJs4I?(3Yq^jiy zY6{-0i%nOR9^ZX(^pIub0+F)i(SM9tL&T?Kbbh>($*T8v%H^ccB M?}Ss~1;r!&1rg@XLjV8( diff --git a/C/opening_learner/mistakes.o b/C/opening_learner/mistakes.o index e8e7eba50469eb0de6dcce06d81eae2f0a3dafe7..91cbd2ec5e3b7e12e29f58d9ca1d128f38f5b999 100644 GIT binary patch delta 1763 zcmZ`(Z%iCT6yH7WVE1ls=dJ-34CF}In!{@4EEFk70S}ooCqihgv2B1rE|Oxc{P{%d zfp-|zWs@V*7)=@_CMK6?B8jG@6`O-93DggWe?n3l{bGd>LliBT*q(1@7ke5z$<4g| z{oZ@OH*eqVv@cnb@bk&ZG8{b;(tbaRwL9%te^$VHvj-b(Jg#0wu{n<8uu;U}vDA!* z+9xd@P0H)CKF$2v}?4uy)c+-Mh#f zwWGq-5sveLL>>z;iiD6Zseu&Meqbp=dRP^R#6J+Amgg!5`GGY)9j9r{sN*LaPOQ^# zS`*fDHYS)Jd4c~px|R)Y+F7*#YunhUq+UH(FWTz|18W!5Rp0|R?p3=0`NPJC>N4ZM zxLnW9)v&f1HhR?72--|-;Sa*bpjsaZq0?WYvLK*feMhZMY+O*6Aw>lBEm5H23@VdU zR2El9AQ3$i);VRJ)7F_{XAsgR$doNFy3KRkXw6eiEr$k=jn*_awI4z8Yv40l6AraB zq4+W2M`oGW{-Mtz=;b06>-3&bT1i;zQ_E4=3AKdXY$49>!!1C1y0vl}I`Y9iXVq`$ z`!f3y*3!)TN)%+GVeMxa0F0XFV>?2>tj&eByL0PVTloEuwjEeW+6SEtx}qsp?BJcW z4Z0i9B}s{Bl7eINwj@6&G@y%;GA=0#L3=B=UXV_wcjskf*nS9&9RS3V#!$((P>HFJ zO#R!IJ~qxX66zQ@7+3^lQFm(cWlLB>muj66tyaddIjWn3F6KJNb7hdN=hol5n@&d( z+CpF@c56rbDmD+}Ju6YI5QJ3!*1r)lD)K=hmtq@J5#$R(V~3-(!gnF~e=AHw^I;^g z@d>Leqfvr3XLgCTNYwN1bqETT@-rF)g-ZFfKXE&qHg0|U4sFp0wQ;Go$(k_(N-)#s z*`W5|eYtFMhxXvn&(}zg{R!SlrtGDTgXNEvSCb|CtCbIff0(9#b(?ODvS-2;lnY+Z z3d$uhyKTuS7c|J8Mp+2CfPNf)XNlpcan4Y0SgtIx;wZIG$yv9^pN{MB$8>NHn$$o0 zUNV=h6dr)*Jsi(@EWFq{Yss&`Hdt)Ag|ceEZlNsy9NRlcTaLoN#OwjK57WKyH7hnn zuMf+WWu6J<^CsKhAzq=%zCZkAC21Ch)b4>Zr@4-ffx)isQytwep6ZBn_4aXGff>lr zX>pQY1cjG~Lo6*^$iUrT{{_=X*N?<2DuqAYhfR}L#2WIwD3KXan;|Kau|uc*rDJ zL74*QGjK1&>=t@01E-(mU0kqU2BqEP5m!4uLPlK*KTFJAazG@k3Nq=gvK@AiC3l_exaBJQZJiGCv|J}9EH{Bn%2oU{S(Fdw jy_Ic-daUM3@FPrA+7c0zG>qgz;ATQ=8; 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 delta 15112 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/dev/null 2>&1; then sudo apt-get install -y libsdl2-dev ;; arch|manjaro|endeavouros) - sudo pacman -Syu --noconfirm sdl2 + pacman -Q sdl2 &>/dev/null || sudo pacman -S --noconfirm sdl2 ;; fedora) sudo dnf install -y SDL2-devel diff --git a/C/scrapeWebsite/Makefile b/C/scrapeWebsite/Makefile new file mode 100644 index 0000000..e8586c0 --- /dev/null +++ b/C/scrapeWebsite/Makefile @@ -0,0 +1,19 @@ +CC := gcc +CFLAGS := -O2 -Wall -Wextra -std=c11 -D_DEFAULT_SOURCE $(shell pkg-config --cflags libcurl libxml-2.0 2>/dev/null) +LDFLAGS := $(shell pkg-config --libs libcurl libxml-2.0 2>/dev/null) + +SRC := scrape.c +BIN := scrape + +all: $(BIN) + +$(BIN): $(SRC) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +run: $(BIN) + ./$(BIN) + +clean: + rm -f $(BIN) + +.PHONY: all run clean diff --git a/C/scrapeWebsite/run.sh b/C/scrapeWebsite/run.sh new file mode 100755 index 0000000..c859efb --- /dev/null +++ b/C/scrapeWebsite/run.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -e +# Install dependencies +if command -v apt-get &>/dev/null; then + sudo apt-get install -y libcurl4-openssl-dev libxml2-dev +elif command -v pacman &>/dev/null; then + pacman -Q curl libxml2 &>/dev/null || sudo pacman -S --noconfirm curl libxml2 +elif command -v dnf &>/dev/null; then + sudo dnf install -y libcurl-devel libxml2-devel +fi +make +./scrape diff --git a/C/tests/Makefile b/C/tests/Makefile new file mode 100644 index 0000000..bb1e434 --- /dev/null +++ b/C/tests/Makefile @@ -0,0 +1,19 @@ +CC := gcc +CFLAGS := -O2 -Wall -Wextra -std=c11 -D_DEFAULT_SOURCE +LDFLAGS := + +SRC := generatingPolishLettersOnWindowsTerminal.c +BIN := polish_letters + +all: $(BIN) + +$(BIN): $(SRC) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +run: $(BIN) + ./$(BIN) + +clean: + rm -f $(BIN) + +.PHONY: all run clean diff --git a/C/tests/generatingPolishLettersOnWindowsTerminal.c b/C/tests/generatingPolishLettersOnWindowsTerminal.c index d69be9a..c04be43 100644 --- a/C/tests/generatingPolishLettersOnWindowsTerminal.c +++ b/C/tests/generatingPolishLettersOnWindowsTerminal.c @@ -1,10 +1,17 @@ #include #include -#include -int main() +#ifdef _WIN32 +#include +#define SLEEP_S(s) Sleep((s) * 1000) +#else +#include +#define SLEEP_S(s) sleep(s) +#endif + +int main(void) { printf("Henlo\n"); - sleep(20); + SLEEP_S(20); return 0; } diff --git a/C/tests/run.sh b/C/tests/run.sh new file mode 100755 index 0000000..35a4386 --- /dev/null +++ b/C/tests/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +make +./polish_letters diff --git a/C/vocabulary_curve/run.sh b/C/vocabulary_curve/run.sh new file mode 100755 index 0000000..226f7cc --- /dev/null +++ b/C/vocabulary_curve/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +make +./vocabulary_curve diff --git a/C/vocabulary_curve/vocabulary_curve b/C/vocabulary_curve/vocabulary_curve index 360863e17a3c039fb64b9219a0128890b6205093..e41ae48b1bb891cb5294a7e0f45d3185416a44a4 100755 GIT binary patch delta 5397 zcmZu#3s@Z06~43Vh6RCL0%0LSSjcKXlL#6N+k~)71~MBKBGG7kb%Q)K&4WmGtw|$G zyP%y;CPwe~+1Qtl_G_(QZHcrswT}=<0JUnYO&d+Cq@N~3Neq}Y1|!-2XJ(f?+RL{y z_nz~g$36GlbMG+pW8sCL2|J5SMgAwQyFERa!1Olte&UJBq@HAh*z?5uHzZ9?HwKeD zUAQ6X0jn{3fcu1JxYOjEZY?(`7vKClrddy#tm#sWGxg>TraAu~|AsRYTF94W^{W`) zR5kmh>3{p>;hNC57GBlxS=PgyXM2C0kYW}X-$#dVC}4&XX~0sWb9Q6PwCl6ze)SxLNrQR1Q{y5?tgYX=x;hN zsb%$HXscD`UXbKd+EW0jw+h{T!C!&p1qW0))1^HEMt7gBy9G+cMRQ%Y9qsU1Hx{#@ zZ3P6nt$^*|V8ZC=uGYANy6IQ5zm^SmB(>s))ps$?3JFOqFFTfp0LaHnk7##*;#cRb zNlb^~0}@nqjioSV%lD8Ynl>4Ydgc9*bJ1XOc9JHA)hMnWsi_~( zXutUFX7d{Du_=krGu=mQ-6im!G~EDtq~aIT(xJR-7eXyHmHpmU&m=W9i15Ek!H1he zAZe$+j7CKz^#|xzcfa0ID=C&9^anknK#`A32;tzuYPCVwL+j&LEsCzFVjI1b1%o~% zvrpcqeAVN=%M(ga>P0EqCodQM?t`J>$TqCA?eTfj$OEjbDEnPjY2CRL387pq$^F_i zc4;g-CHdvg{9$x%LEO$0QJoPym&!%SCVJ;$#*|_70en1@}8P{{#Zy z?hk+Dbzkt>R-6!RD?ax|_xqxQShYniSLi84bU8_RQ8dMMU}EEt{55N|Pl~*jvcLbq z!U5sH#NVpUEW(Uz-9=GKp^6b?s$bcLXefw;R(KxNuv+2GWlYPWfm$&Lh?b20UfL7d z@E1C@!HNDEqu-5wX`goO6y^`0D`i{FNJh27f3?oFf~%B$E0t2EqQRh%yrK0whNkmm zEBqr8w=9M@!kg>vx7GL4-q=pty=mAlFLvn*D5-g8+ETEX%`OktQ2PpFzIFRk{K6RJ zKzV5&p1IgZB2q+I;1ZQ)S8iz^tare=s61p=ZWiUwM5I72epc;%n5}jnvxOheGc#uR zb!I}JZM)%b4SA`UUCIMiMA|B7?gKXUfQ3@9RX=EkxpuL#ys{IfG|diW#X!O zswwhENRg(4+EyZBR+3FE`^W^d36xCgf&u<)rjtLDnbqo3rb$h=h@FcwSSW44oFPa} zhcFFUJOob$tUmYI&_5!Rf^El3C>Gex3*6Y{^2qOK`-tkQs9zpvy=)u3)lnzP2aAU! zVW>{c?UUp&TYe|snK|>x?4)p56y00JjzmfBI48+=DbfcE{h^Pf=spS7{O;F7KlUjh zgc8$yJ_md8c2WE4Ih3bKA-G6B=~u7Wh11EWu0KgB_iZ3b`+Sl8R?Q8N522=zt<}jS zI-98O6QTEvl@I^=b1Zhm>`IXUEtlL2T(<5_s40Hrk%v}Fg7{wAC@&IHt@sA2F)XO} zxT4a!Bgn(k%1zqa;3=EUV0Yd&5Rt% zR*LaJ)<5nU@OZI9rK%#f};(;FF3CwC~*+E_8C+ayax9T z;?{r>=L#h1GMFzB({~ATE-@1g=1yW#4U0>~W)(@kWiW3CGyE!D zb>gBMh}&au-6VC>l}13sp>6(XpT*H6&}gZ`pH&j4LNXhzl}$q
C@;7sD6w>&G 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 E|9VeGng9R* diff --git a/C/websocketServer/Makefile b/C/websocketServer/Makefile new file mode 100644 index 0000000..a5212ff --- /dev/null +++ b/C/websocketServer/Makefile @@ -0,0 +1,19 @@ +CC := gcc +CFLAGS := -O2 -Wall -Wextra -std=c11 $(shell pkg-config --cflags libwebsockets 2>/dev/null) +LDFLAGS := $(shell pkg-config --libs libwebsockets 2>/dev/null) + +SRC := main.c +BIN := websocket_server + +all: $(BIN) + +$(BIN): $(SRC) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +run: $(BIN) + ./$(BIN) + +clean: + rm -f $(BIN) + +.PHONY: all run clean diff --git a/C/websocketServer/run.sh b/C/websocketServer/run.sh new file mode 100755 index 0000000..94b4383 --- /dev/null +++ b/C/websocketServer/run.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -e +# Install dependencies +if command -v pacman &>/dev/null; then + pacman -Q libwebsockets &>/dev/null || sudo pacman -S --noconfirm libwebsockets +elif command -v apt-get &>/dev/null; then + sudo apt-get install -y libwebsockets-dev +elif command -v dnf &>/dev/null; then + sudo dnf install -y libwebsockets-devel +elif command -v zypper &>/dev/null; then + sudo zypper install -y libwebsockets-devel +else + echo "Could not detect package manager. Please install libwebsockets manually." >&2 + exit 1 +fi +make +./websocket_server diff --git a/CPP/miscelanious/Makefile b/CPP/miscelanious/Makefile new file mode 100644 index 0000000..e790323 --- /dev/null +++ b/CPP/miscelanious/Makefile @@ -0,0 +1,30 @@ +CXX := g++ +CXXFLAGS := -O2 -Wall -Wextra -std=c++17 +LDFLAGS := + +BINS := howOftenDoesCharOccur quickchallenges reverseString solveQuadraticEquation + +all: $(BINS) + +howOftenDoesCharOccur: howOftenDoesCharOccur.cpp + $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) + +quickchallenges: quickchallenges.cpp + $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) + +reverseString: reverseString.cpp + $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) + +solveQuadraticEquation: solveQuadraticEquation.cpp + $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) + +run: all + ./howOftenDoesCharOccur + ./quickchallenges + ./reverseString + ./solveQuadraticEquation + +clean: + rm -f $(BINS) + +.PHONY: all run clean diff --git a/CPP/miscelanious/Pi/Makefile b/CPP/miscelanious/Pi/Makefile new file mode 100644 index 0000000..b7de6be --- /dev/null +++ b/CPP/miscelanious/Pi/Makefile @@ -0,0 +1,19 @@ +CXX := g++ +CXXFLAGS := -O2 -Wall -Wextra -std=c++17 +LDFLAGS := -lm + +SRC := main.cpp +BIN := pi + +all: $(BIN) + +$(BIN): $(SRC) + $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) + +run: $(BIN) + ./$(BIN) + +clean: + rm -f $(BIN) + +.PHONY: all run clean diff --git a/CPP/miscelanious/Pi/run.sh b/CPP/miscelanious/Pi/run.sh new file mode 100755 index 0000000..419b200 --- /dev/null +++ b/CPP/miscelanious/Pi/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +make +./pi diff --git a/CPP/miscelanious/brydz/Makefile b/CPP/miscelanious/brydz/Makefile new file mode 100644 index 0000000..105fb24 --- /dev/null +++ b/CPP/miscelanious/brydz/Makefile @@ -0,0 +1,19 @@ +CXX := g++ +CXXFLAGS := -O2 -Wall -Wextra -std=c++17 +LDFLAGS := + +SRC := brydz.cpp +BIN := brydz + +all: $(BIN) + +$(BIN): $(SRC) + $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) + +run: $(BIN) + ./$(BIN) + +clean: + rm -f $(BIN) + +.PHONY: all run clean diff --git a/CPP/miscelanious/brydz/brydz.cpp b/CPP/miscelanious/brydz/brydz.cpp index 36d9297..1e9a658 100644 --- a/CPP/miscelanious/brydz/brydz.cpp +++ b/CPP/miscelanious/brydz/brydz.cpp @@ -4,7 +4,7 @@ const std::vector ATUTY = {"BA", "Trefl", "Karo", "Kier", "Pik"}; const bool A_ID = 0; const bool B_ID = 1; -const std::vector GRACZE = {}; +const std::vector GRACZE = {"Gracz A", "Gracz B"}; const std::vector PO_PARTII{"Nikt", GRACZE[A_ID], GRACZE[B_ID], "Obaj Gracze"}; const int DOMYSLNE_LEWY = 6; diff --git a/CPP/miscelanious/brydz/run.sh b/CPP/miscelanious/brydz/run.sh new file mode 100755 index 0000000..2f96b54 --- /dev/null +++ b/CPP/miscelanious/brydz/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +make +./brydz diff --git a/CPP/miscelanious/calculateShotsDarts/Makefile b/CPP/miscelanious/calculateShotsDarts/Makefile new file mode 100644 index 0000000..873aa8c --- /dev/null +++ b/CPP/miscelanious/calculateShotsDarts/Makefile @@ -0,0 +1,20 @@ +CXX := g++ +CXXFLAGS := -O2 -Wall -Wextra -std=c++17 +LDFLAGS := + +# main.cpp includes basic.cpp directly +SRC := main.cpp +BIN := darts + +all: $(BIN) + +$(BIN): $(SRC) + $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) + +run: $(BIN) + ./$(BIN) + +clean: + rm -f $(BIN) + +.PHONY: all run clean diff --git a/CPP/miscelanious/calculateShotsDarts/basic.cpp b/CPP/miscelanious/calculateShotsDarts/basic.cpp index bc7c383..acdb536 100644 --- a/CPP/miscelanious/calculateShotsDarts/basic.cpp +++ b/CPP/miscelanious/calculateShotsDarts/basic.cpp @@ -4,7 +4,6 @@ #include #include #include -#include void print(const std::string s) { std::cout << s << std::endl; } void printErrorStringContainsNotNumber(const std::string s) { diff --git a/CPP/miscelanious/calculateShotsDarts/main.cpp b/CPP/miscelanious/calculateShotsDarts/main.cpp index 0dd4134..eb631ae 100644 --- a/CPP/miscelanious/calculateShotsDarts/main.cpp +++ b/CPP/miscelanious/calculateShotsDarts/main.cpp @@ -63,8 +63,78 @@ bool validInput(const std::string s) { return 1; } -// cppcheck-suppress missingReturn -std::vector requiredShoots(const int pointsLeft) {} +// Darts checkout finder: find combinations of up to 3 darts that reduce +// pointsLeft to exactly 0, finishing on a double (standard 501 rules). +std::vector requiredShoots(const int pointsLeft) { + // All valid dart scores with labels + std::vector> all_darts; + for (int i = MIN_SPOT; i <= MAX_SPOT; i++) + all_darts.push_back({i, std::to_string(i)}); + all_darts.push_back({25, "Bull"}); + for (int i = MIN_SPOT; i <= MAX_SPOT; i++) + all_darts.push_back({i * 2, "D" + std::to_string(i)}); + all_darts.push_back({50, "D-Bull"}); + for (int i = MIN_SPOT; i <= MAX_SPOT; i++) + all_darts.push_back({i * 3, "T" + std::to_string(i)}); + + // Doubles only (valid finishing darts) + std::vector> doubles; + for (int i = MIN_SPOT; i <= MAX_SPOT; i++) + doubles.push_back({i * 2, "D" + std::to_string(i)}); + doubles.push_back({50, "D-Bull"}); + + std::vector> checkouts; + const int MAX_RESULTS = 5; + + // 1-dart checkouts + for (auto &d : doubles) + if (d.first == pointsLeft) + checkouts.push_back({d.second}); + + // 2-dart checkouts + for (auto &d1 : all_darts) { + for (auto &d2 : doubles) { + if (d1.first + d2.first == pointsLeft) { + checkouts.push_back({d1.second, d2.second}); + if ((int)checkouts.size() >= MAX_RESULTS) + goto done; + } + } + } + + // 3-dart checkouts (stop early once we have enough results) + for (auto &d1 : all_darts) { + for (auto &d2 : all_darts) { + for (auto &d3 : doubles) { + if (d1.first + d2.first + d3.first == pointsLeft) { + checkouts.push_back({d1.second, d2.second, d3.second}); + if ((int)checkouts.size() >= MAX_RESULTS) + goto done; + } + } + } + } +done: + if (checkouts.empty()) { + print("No checkout possible for " + std::to_string(pointsLeft) + + " points."); + return {}; + } + + print("Possible checkouts (showing up to " + std::to_string(MAX_RESULTS) + + "):"); + std::vector firstCheckout; + for (auto &combo : checkouts) { + std::string line; + for (unsigned int i = 0; i < combo.size(); i++) { + if (i > 0) + line += " \u2192 "; + line += combo[i]; + } + print(line); + } + return firstCheckout; +} int main() { print("Enter points left: "); diff --git a/CPP/miscelanious/calculateShotsDarts/run.sh b/CPP/miscelanious/calculateShotsDarts/run.sh new file mode 100755 index 0000000..4c932f1 --- /dev/null +++ b/CPP/miscelanious/calculateShotsDarts/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +make +./darts diff --git a/CPP/miscelanious/findIntegerPercentageValue/Makefile b/CPP/miscelanious/findIntegerPercentageValue/Makefile new file mode 100644 index 0000000..a6f27ef --- /dev/null +++ b/CPP/miscelanious/findIntegerPercentageValue/Makefile @@ -0,0 +1,19 @@ +CXX := g++ +CXXFLAGS := -O2 -Wall -Wextra -std=c++17 +LDFLAGS := + +SRC := main.cpp +BIN := find_percentage + +all: $(BIN) + +$(BIN): $(SRC) + $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) + +run: $(BIN) + ./$(BIN) + +clean: + rm -f $(BIN) + +.PHONY: all run clean diff --git a/CPP/miscelanious/findIntegerPercentageValue/run.sh b/CPP/miscelanious/findIntegerPercentageValue/run.sh new file mode 100755 index 0000000..5e6738f --- /dev/null +++ b/CPP/miscelanious/findIntegerPercentageValue/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +make +./find_percentage diff --git a/CPP/miscelanious/howManyValidISBNNumbersAreThere/Makefile b/CPP/miscelanious/howManyValidISBNNumbersAreThere/Makefile new file mode 100644 index 0000000..b6f4eb0 --- /dev/null +++ b/CPP/miscelanious/howManyValidISBNNumbersAreThere/Makefile @@ -0,0 +1,19 @@ +CXX := g++ +CXXFLAGS := -O2 -Wall -Wextra -std=c++17 +LDFLAGS := + +SRC := 11.cpp +BIN := isbn_counter + +all: $(BIN) + +$(BIN): $(SRC) + $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) + +run: $(BIN) + ./$(BIN) + +clean: + rm -f $(BIN) + +.PHONY: all run clean diff --git a/CPP/miscelanious/howManyValidISBNNumbersAreThere/run.sh b/CPP/miscelanious/howManyValidISBNNumbersAreThere/run.sh new file mode 100755 index 0000000..e9f640c --- /dev/null +++ b/CPP/miscelanious/howManyValidISBNNumbersAreThere/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +make +./isbn_counter diff --git a/CPP/miscelanious/markovChainGenerator/Makefile b/CPP/miscelanious/markovChainGenerator/Makefile new file mode 100644 index 0000000..6d46e2d --- /dev/null +++ b/CPP/miscelanious/markovChainGenerator/Makefile @@ -0,0 +1,20 @@ +CXX := g++ +CXXFLAGS := -O2 -Wall -Wextra -std=c++17 +LDFLAGS := + +# main.cpp includes basic.cpp directly +SRC := main.cpp +BIN := markov + +all: $(BIN) + +$(BIN): $(SRC) + $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) + +run: $(BIN) + ./$(BIN) + +clean: + rm -f $(BIN) + +.PHONY: all run clean diff --git a/CPP/miscelanious/markovChainGenerator/main.cpp b/CPP/miscelanious/markovChainGenerator/main.cpp index 6a87674..248e922 100644 --- a/CPP/miscelanious/markovChainGenerator/main.cpp +++ b/CPP/miscelanious/markovChainGenerator/main.cpp @@ -9,21 +9,20 @@ struct wordOccurences { std::string word; int occurences; -} +}; struct previousWords { std::string word; std::vector previousWords; }; -struct wordProbabiliy { +struct wordProbability { std::string previousWord; std::string nextWord; float probability; -} +}; -bool validInput(const std::string userInput) -{ +bool validInput(const std::string userInput) { if (stringContainsNumbers(userInput)) return 0; return 1; @@ -61,8 +60,10 @@ int wordRepeats(const std::vector wordsList, bool alreadyExists(const std::vector wordsList, const std::string s) { for (unsigned int i = 0; i < wordsList.size(); i++) { - if(s == wordsList.previousWOrds + if (s == wordsList.at(i).word) + return true; } + return false; } std::vector @@ -73,17 +74,16 @@ getWordsAndTheirPrevious(const std::vector words) { previousWords temp; temp.word = words.at(i); wordOccurences tempTwo; - tempTwo.word = words.at(i - 1)); - tempTwo.occurences = 1; - temp.previousWords.push_back(tempTwo); - int position = wordRepeats(wordsList, temp.word); - if (position == -1) { - wordsList.push_back(temp); - } else { + tempTwo.word = words.at(i - 1); + tempTwo.occurences = 1; + temp.previousWords.push_back(tempTwo); + int position = wordRepeats(wordsList, temp.word); + if (position == -1) { + wordsList.push_back(temp); + } else { - wordsList.at(position).previousWords.push_back( - temp.previousWords.at(0)); - } + wordsList.at(position).previousWords.push_back(temp.previousWords.at(0)); + } } return wordsList; } @@ -92,7 +92,7 @@ void printPreviousWord(const previousWords word) { std::cout << "The word is \"" << word.word << "\" Words before it are: " << std::endl; for (unsigned int i = 0; i < word.previousWords.size(); i++) { - print(word.previousWords.at(i)); + print(word.previousWords.at(i).word); } } @@ -105,9 +105,22 @@ void printPreviousWordsVector(const std::vector v) { std::vector getWordProbability(const std::vector wordsList) { std::vector probalityVector; - for (unsigned int i = 0; i - 1 < wordsList.size(); i++) { - pro + for (unsigned int i = 0; i < wordsList.size(); i++) { + int total = 0; + for (unsigned int j = 0; j < wordsList.at(i).previousWords.size(); j++) + total += wordsList.at(i).previousWords.at(j).occurences; + for (unsigned int j = 0; j < wordsList.at(i).previousWords.size(); j++) { + wordProbability wp; + wp.previousWord = wordsList.at(i).previousWords.at(j).word; + wp.nextWord = wordsList.at(i).word; + wp.probability = + total > 0 + ? (float)wordsList.at(i).previousWords.at(j).occurences / total + : 0.0f; + probalityVector.push_back(wp); + } } + return probalityVector; } int main() { diff --git a/CPP/miscelanious/markovChainGenerator/run.sh b/CPP/miscelanious/markovChainGenerator/run.sh new file mode 100755 index 0000000..87d4b5b --- /dev/null +++ b/CPP/miscelanious/markovChainGenerator/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +make +./markov diff --git a/CPP/miscelanious/mutiplicationWithoutStar/Makefile b/CPP/miscelanious/mutiplicationWithoutStar/Makefile new file mode 100644 index 0000000..40d1289 --- /dev/null +++ b/CPP/miscelanious/mutiplicationWithoutStar/Makefile @@ -0,0 +1,19 @@ +CXX := g++ +CXXFLAGS := -O2 -Wall -Wextra -std=c++17 +LDFLAGS := + +SRC := multiplication.cpp +BIN := multiplication + +all: $(BIN) + +$(BIN): $(SRC) + $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) + +run: $(BIN) + ./$(BIN) + +clean: + rm -f $(BIN) + +.PHONY: all run clean diff --git a/CPP/miscelanious/mutiplicationWithoutStar/run.sh b/CPP/miscelanious/mutiplicationWithoutStar/run.sh new file mode 100755 index 0000000..4738372 --- /dev/null +++ b/CPP/miscelanious/mutiplicationWithoutStar/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +make +./multiplication diff --git a/CPP/miscelanious/randomDevice/Makefile b/CPP/miscelanious/randomDevice/Makefile new file mode 100644 index 0000000..c2550b9 --- /dev/null +++ b/CPP/miscelanious/randomDevice/Makefile @@ -0,0 +1,19 @@ +CXX := g++ +CXXFLAGS := -O2 -Wall -Wextra -std=c++17 +LDFLAGS := + +SRC := main.cpp +BIN := random_device_demo + +all: $(BIN) + +$(BIN): $(SRC) + $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) + +run: $(BIN) + ./$(BIN) + +clean: + rm -f $(BIN) + +.PHONY: all run clean diff --git a/CPP/miscelanious/randomDevice/run.sh b/CPP/miscelanious/randomDevice/run.sh new file mode 100755 index 0000000..79e8981 --- /dev/null +++ b/CPP/miscelanious/randomDevice/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +make +./random_device_demo diff --git a/CPP/miscelanious/run.sh b/CPP/miscelanious/run.sh new file mode 100755 index 0000000..d999467 --- /dev/null +++ b/CPP/miscelanious/run.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +set -e +make +./howOftenDoesCharOccur +./quickchallenges +./reverseString +./solveQuadraticEquation diff --git a/CPP/miscelanious/tictactoe/Makefile b/CPP/miscelanious/tictactoe/Makefile new file mode 100644 index 0000000..2bdc7e2 --- /dev/null +++ b/CPP/miscelanious/tictactoe/Makefile @@ -0,0 +1,19 @@ +CXX := g++ +CXXFLAGS := -O2 -Wall -Wextra -std=c++17 +LDFLAGS := + +SRC := tictactoe.cpp +BIN := tictactoe + +all: $(BIN) + +$(BIN): $(SRC) + $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) + +run: $(BIN) + ./$(BIN) + +clean: + rm -f $(BIN) + +.PHONY: all run clean diff --git a/CPP/miscelanious/tictactoe/run.sh b/CPP/miscelanious/tictactoe/run.sh new file mode 100755 index 0000000..0dc73eb --- /dev/null +++ b/CPP/miscelanious/tictactoe/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +make +./tictactoe diff --git a/CPP/miscelanious/tierListConverter/Makefile b/CPP/miscelanious/tierListConverter/Makefile new file mode 100644 index 0000000..0ee2271 --- /dev/null +++ b/CPP/miscelanious/tierListConverter/Makefile @@ -0,0 +1,19 @@ +CXX := g++ +CXXFLAGS := -O2 -Wall -Wextra -std=c++17 +LDFLAGS := + +SRC := tierListConverter.cpp +BIN := tier_list_converter + +all: $(BIN) + +$(BIN): $(SRC) + $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) + +run: $(BIN) + ./$(BIN) + +clean: + rm -f $(BIN) + +.PHONY: all run clean diff --git a/CPP/miscelanious/tierListConverter/run.sh b/CPP/miscelanious/tierListConverter/run.sh new file mode 100755 index 0000000..573f39b --- /dev/null +++ b/CPP/miscelanious/tierListConverter/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +make +./tier_list_converter diff --git a/CPP/miscelanious/xGoesTo0/Makefile b/CPP/miscelanious/xGoesTo0/Makefile new file mode 100644 index 0000000..0bfc1a7 --- /dev/null +++ b/CPP/miscelanious/xGoesTo0/Makefile @@ -0,0 +1,19 @@ +CXX := g++ +CXXFLAGS := -O2 -Wall -Wextra -std=c++17 +LDFLAGS := + +SRC := xgoes.cpp +BIN := xgoes + +all: $(BIN) + +$(BIN): $(SRC) + $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) + +run: $(BIN) + ./$(BIN) + +clean: + rm -f $(BIN) + +.PHONY: all run clean diff --git a/CPP/miscelanious/xGoesTo0/run.sh b/CPP/miscelanious/xGoesTo0/run.sh new file mode 100755 index 0000000..4f56cca --- /dev/null +++ b/CPP/miscelanious/xGoesTo0/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +make +./xgoes diff --git a/CPP/miscelanious/yousuckatcards/Bernouli/Makefile b/CPP/miscelanious/yousuckatcards/Bernouli/Makefile new file mode 100644 index 0000000..f42e63b --- /dev/null +++ b/CPP/miscelanious/yousuckatcards/Bernouli/Makefile @@ -0,0 +1,22 @@ +CXX := g++ +CXXFLAGS := -O2 -Wall -Wextra -std=c++17 +LDFLAGS := + +BINS := bernouli test + +all: $(BINS) + +bernouli: bernouli.cpp + $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) + +test: test.cpp + $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) + +run: all + ./bernouli + ./test + +clean: + rm -f $(BINS) + +.PHONY: all run clean diff --git a/CPP/miscelanious/yousuckatcards/Bernouli/run.sh b/CPP/miscelanious/yousuckatcards/Bernouli/run.sh new file mode 100755 index 0000000..7cbf675 --- /dev/null +++ b/CPP/miscelanious/yousuckatcards/Bernouli/run.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -e +make +./bernouli +./test diff --git a/CPP/miscelanious/yousuckatcards/run.sh b/CPP/miscelanious/yousuckatcards/run.sh new file mode 100755 index 0000000..3d2e80e --- /dev/null +++ b/CPP/miscelanious/yousuckatcards/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +make +./a.out diff --git a/CPP/tests/Makefile b/CPP/tests/Makefile new file mode 100644 index 0000000..24168f9 --- /dev/null +++ b/CPP/tests/Makefile @@ -0,0 +1,19 @@ +CXX := g++ +CXXFLAGS := -O2 -Wall -Wextra -std=c++17 +LDFLAGS := + +SRC := howCppHandlesDivision.cpp +BIN := division_test + +all: $(BIN) + +$(BIN): $(SRC) + $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) + +run: $(BIN) + ./$(BIN) + +clean: + rm -f $(BIN) + +.PHONY: all run clean diff --git a/CPP/tests/run.sh b/CPP/tests/run.sh new file mode 100755 index 0000000..cc8ac67 --- /dev/null +++ b/CPP/tests/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +make +./division_test diff --git a/LaTeX/.gitignore b/linux_configuration/LaTeX/.gitignore similarity index 100% rename from LaTeX/.gitignore rename to linux_configuration/LaTeX/.gitignore diff --git a/LaTeX/main.tex b/linux_configuration/LaTeX/main.tex similarity index 100% rename from LaTeX/main.tex rename to linux_configuration/LaTeX/main.tex diff --git a/LaTeX/mauin2.tex b/linux_configuration/LaTeX/mauin2.tex similarity index 100% rename from LaTeX/mauin2.tex rename to linux_configuration/LaTeX/mauin2.tex diff --git a/python_pkg/anki_decks/polish_gminy/run.sh b/python_pkg/anki_decks/polish_gminy/run.sh index e18a3d3..3f7765c 100755 --- a/python_pkg/anki_decks/polish_gminy/run.sh +++ b/python_pkg/anki_decks/polish_gminy/run.sh @@ -21,8 +21,7 @@ echo "Activating virtual environment..." source "$VENV_DIR/bin/activate" echo "Installing dependencies..." -pip install --quiet --upgrade pip -pip install --quiet matplotlib genanki geopandas requests shapely +pip show genanki &>/dev/null || pip install --quiet matplotlib genanki geopandas requests shapely cd "$SCRIPT_DIR" diff --git a/python_pkg/anki_decks/polish_license_plates/run.sh b/python_pkg/anki_decks/polish_license_plates/run.sh new file mode 100755 index 0000000..ba7a253 --- /dev/null +++ b/python_pkg/anki_decks/polish_license_plates/run.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" +VENV="$REPO_ROOT/.venv" +[[ ! -d "$VENV" ]] && python3 -m venv "$VENV" +_pip_sync() { local r="$1" h; h=$(md5sum "$r"|cut -d' ' -f1); local lf="$VENV/.req_${h:0:8}.lock"; [[ -f "$lf" ]] && return; "$VENV/bin/pip" install -r "$r" -q && touch "$lf"; } +_pip_sync "$REPO_ROOT/requirements.txt" +"$VENV/bin/python" "$SCRIPT_DIR/polish_license_plates_anki.py" "$@" diff --git a/python_pkg/anki_decks/polish_powiaty/run.sh b/python_pkg/anki_decks/polish_powiaty/run.sh index 3df7b8b..9c72b41 100755 --- a/python_pkg/anki_decks/polish_powiaty/run.sh +++ b/python_pkg/anki_decks/polish_powiaty/run.sh @@ -19,8 +19,7 @@ echo "Activating virtual environment..." source "$VENV_DIR/bin/activate" echo "Installing dependencies..." -pip install --quiet --upgrade pip -pip install --quiet matplotlib genanki geopandas +pip show genanki &>/dev/null || pip install --quiet matplotlib genanki geopandas cd "$SCRIPT_DIR" diff --git a/python_pkg/anki_decks/run.sh b/python_pkg/anki_decks/run.sh new file mode 100755 index 0000000..20bb77d --- /dev/null +++ b/python_pkg/anki_decks/run.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +VENV="$REPO_ROOT/.venv" +[[ ! -d "$VENV" ]] && python3 -m venv "$VENV" +_pip_sync() { local r="$1" h; h=$(md5sum "$r"|cut -d' ' -f1); local lf="$VENV/.req_${h:0:8}.lock"; [[ -f "$lf" ]] && return; "$VENV/bin/pip" install -r "$r" -q && touch "$lf"; } +_pip_sync "$REPO_ROOT/requirements.txt" + +# Run all deck generators in sequence +for deck_dir in "$SCRIPT_DIR"/*/; do + if [[ -f "$deck_dir/run.sh" ]]; then + echo "==> Building deck: $(basename "$deck_dir")" + bash "$deck_dir/run.sh" + fi +done diff --git a/python_pkg/anki_decks/warsaw_bridges/run.sh b/python_pkg/anki_decks/warsaw_bridges/run.sh index a848782..c5459c5 100755 --- a/python_pkg/anki_decks/warsaw_bridges/run.sh +++ b/python_pkg/anki_decks/warsaw_bridges/run.sh @@ -19,8 +19,7 @@ echo "Activating virtual environment..." source "$VENV_DIR/bin/activate" echo "Installing dependencies..." -pip install --quiet --upgrade pip -pip install --quiet matplotlib genanki geopandas requests shapely +pip show genanki &>/dev/null || pip install --quiet matplotlib genanki geopandas requests shapely cd "$SCRIPT_DIR" diff --git a/python_pkg/anki_decks/warsaw_districts/run.sh b/python_pkg/anki_decks/warsaw_districts/run.sh index 7af26d5..9812cfc 100755 --- a/python_pkg/anki_decks/warsaw_districts/run.sh +++ b/python_pkg/anki_decks/warsaw_districts/run.sh @@ -22,8 +22,7 @@ source "$VENV_DIR/bin/activate" # Install dependencies echo "Installing dependencies..." -pip install --quiet --upgrade pip -pip install --quiet matplotlib genanki geopandas +pip show genanki &>/dev/null || pip install --quiet matplotlib genanki geopandas # Export preview images echo diff --git a/python_pkg/anki_decks/warsaw_landmarks/run.sh b/python_pkg/anki_decks/warsaw_landmarks/run.sh index a602308..b9bb256 100755 --- a/python_pkg/anki_decks/warsaw_landmarks/run.sh +++ b/python_pkg/anki_decks/warsaw_landmarks/run.sh @@ -19,8 +19,7 @@ echo "Activating virtual environment..." source "$VENV_DIR/bin/activate" echo "Installing dependencies..." -pip install --quiet --upgrade pip -pip install --quiet matplotlib genanki geopandas requests shapely +pip show genanki &>/dev/null || pip install --quiet matplotlib genanki geopandas requests shapely cd "$SCRIPT_DIR" diff --git a/python_pkg/anki_decks/warsaw_metro/run.sh b/python_pkg/anki_decks/warsaw_metro/run.sh index 7e4415c..90960da 100755 --- a/python_pkg/anki_decks/warsaw_metro/run.sh +++ b/python_pkg/anki_decks/warsaw_metro/run.sh @@ -19,8 +19,7 @@ echo "Activating virtual environment..." source "$VENV_DIR/bin/activate" echo "Installing dependencies..." -pip install --quiet --upgrade pip -pip install --quiet matplotlib genanki geopandas requests shapely +pip show genanki &>/dev/null || pip install --quiet matplotlib genanki geopandas requests shapely cd "$SCRIPT_DIR" diff --git a/python_pkg/anki_decks/warsaw_osiedla/run.sh b/python_pkg/anki_decks/warsaw_osiedla/run.sh index 73c09bc..7bc6e69 100755 --- a/python_pkg/anki_decks/warsaw_osiedla/run.sh +++ b/python_pkg/anki_decks/warsaw_osiedla/run.sh @@ -19,8 +19,7 @@ echo "Activating virtual environment..." source "$VENV_DIR/bin/activate" echo "Installing dependencies..." -pip install --quiet --upgrade pip -pip install --quiet matplotlib genanki geopandas requests shapely +pip show genanki &>/dev/null || pip install --quiet matplotlib genanki geopandas requests shapely cd "$SCRIPT_DIR" diff --git a/python_pkg/anki_decks/warsaw_streets/run.sh b/python_pkg/anki_decks/warsaw_streets/run.sh index 6aa117a..5b4af30 100755 --- a/python_pkg/anki_decks/warsaw_streets/run.sh +++ b/python_pkg/anki_decks/warsaw_streets/run.sh @@ -19,8 +19,7 @@ echo "Activating virtual environment..." source "$VENV_DIR/bin/activate" echo "Installing dependencies..." -pip install --quiet --upgrade pip -pip install --quiet matplotlib genanki geopandas requests shapely +pip show genanki &>/dev/null || pip install --quiet matplotlib genanki geopandas requests shapely cd "$SCRIPT_DIR" diff --git a/python_pkg/brightness_controller/run.sh b/python_pkg/brightness_controller/run.sh new file mode 100755 index 0000000..a75161b --- /dev/null +++ b/python_pkg/brightness_controller/run.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +VENV="$REPO_ROOT/.venv" +[[ ! -d "$VENV" ]] && python3 -m venv "$VENV" +_pip_sync() { local r="$1" h; h=$(md5sum "$r"|cut -d' ' -f1); local lf="$VENV/.req_${h:0:8}.lock"; [[ -f "$lf" ]] && return; "$VENV/bin/pip" install -r "$r" -q && touch "$lf"; } +_pip_sync "$REPO_ROOT/requirements.txt" +"$VENV/bin/python" "$SCRIPT_DIR/brightness_controller.py" "$@" diff --git a/python_pkg/brother_printer/run.sh b/python_pkg/brother_printer/run.sh new file mode 100755 index 0000000..8a2a0fb --- /dev/null +++ b/python_pkg/brother_printer/run.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# No pip dependencies — script only uses stdlib +# Requires root for USB mode; pass printer IP as argument for network/SNMP mode +# Usage: ./run.sh # auto-detect +# ./run.sh # network/SNMP mode +echo "Note: sudo may prompt for your password (required for USB printer access)." +sudo python3 "$SCRIPT_DIR/check_brother_printer.py" "$@" diff --git a/python_pkg/download_cats/requirements.txt b/python_pkg/download_cats/requirements.txt index d90a3af..f229360 100644 --- a/python_pkg/download_cats/requirements.txt +++ b/python_pkg/download_cats/requirements.txt @@ -1,4 +1 @@ -json -os -pathlib requests diff --git a/python_pkg/download_cats/run.sh b/python_pkg/download_cats/run.sh new file mode 100755 index 0000000..fd42b6d --- /dev/null +++ b/python_pkg/download_cats/run.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +VENV="$REPO_ROOT/.venv" +[[ ! -d "$VENV" ]] && python3 -m venv "$VENV" +_pip_sync() { local r="$1" h; h=$(md5sum "$r"|cut -d' ' -f1); local lf="$VENV/.req_${h:0:8}.lock"; [[ -f "$lf" ]] && return; "$VENV/bin/pip" install -r "$r" -q && touch "$lf"; } +_pip_sync "$SCRIPT_DIR/requirements.txt" +"$VENV/bin/python" "$SCRIPT_DIR/generate_cats.py" "$@" diff --git a/python_pkg/keyboard_coop/run.sh b/python_pkg/keyboard_coop/run.sh new file mode 100755 index 0000000..2771441 --- /dev/null +++ b/python_pkg/keyboard_coop/run.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# pygame has no prebuilt wheel for Python 3.14+, use the system package +pacman -Q python-pygame &>/dev/null || sudo pacman -S --noconfirm python-pygame + +# Use a local venv with --system-site-packages so it can see system pygame +VENV="$SCRIPT_DIR/.venv" +[[ ! -d "$VENV" ]] && python3 -m venv "$VENV" --system-site-packages +"$VENV/bin/python" "$SCRIPT_DIR/main.py" "$@" diff --git a/python_pkg/lichess_bot/run.sh b/python_pkg/lichess_bot/run.sh index 1b51113..7fe7956 100755 --- a/python_pkg/lichess_bot/run.sh +++ b/python_pkg/lichess_bot/run.sh @@ -67,4 +67,4 @@ echo "Starting Lichess bot..." echo "Tip: Open another terminal to watch logs; press Ctrl+C here to stop." trap 'echo; echo "Stopping bot (Ctrl+C)."' INT -"$PY" -m PYTHON.lichess_bot.main "$@" +"$PY" -m python_pkg.lichess_bot.main "$@" diff --git a/python_pkg/mock_server/run.sh b/python_pkg/mock_server/run.sh index 8c4c6c2..17645ed 100755 --- a/python_pkg/mock_server/run.sh +++ b/python_pkg/mock_server/run.sh @@ -1,2 +1,17 @@ -#!/bin/sh -mitmdump -s mock_server.py +#!/usr/bin/env bash +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Use a local venv with pip-installed mitmproxy (not in Arch repos) +LVENV="$SCRIPT_DIR/.venv" +if [[ ! -d "$LVENV" ]]; then + echo "Creating local venv for mitmproxy..." + python3 -m venv "$LVENV" +fi +if ! "$LVENV/bin/python" -c "import mitmproxy" &>/dev/null; then + echo "Installing mitmproxy..." + "$LVENV/bin/pip" install mitmproxy -q +fi + +cd "$SCRIPT_DIR" +"$LVENV/bin/mitmdump" --scripts mock_server.py "$@" diff --git a/python_pkg/music_gen/run.sh b/python_pkg/music_gen/run.sh new file mode 100755 index 0000000..cb710a0 --- /dev/null +++ b/python_pkg/music_gen/run.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +VENV="$REPO_ROOT/.venv" +[[ ! -d "$VENV" ]] && python3 -m venv "$VENV" +"$VENV/bin/pip" show torch &>/dev/null || "$VENV/bin/pip" install torch transformers numpy scipy bark -q +echo "Loading models (this may take a minute on first run)..." +export PYTHONUNBUFFERED=1 +"$VENV/bin/python" "$SCRIPT_DIR/music_generator.py" "$@" diff --git a/python_pkg/praca_magisterska_video/run.sh b/python_pkg/praca_magisterska_video/run.sh new file mode 100755 index 0000000..8bf8a5e --- /dev/null +++ b/python_pkg/praca_magisterska_video/run.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +VENV="$REPO_ROOT/.venv" +[[ ! -d "$VENV" ]] && python3 -m venv "$VENV" +"$VENV/bin/pip" show moviepy &>/dev/null || "$VENV/bin/pip" install moviepy numpy -q +export PYTHONUNBUFFERED=1 +# Run all visualizations +echo "==> Rendering visualize_q02 (Dijkstra/Bellman-Ford/A*)" +"$VENV/bin/python" "$SCRIPT_DIR/visualize_q02.py" "$@" +echo "==> Rendering visualize_q23" +"$VENV/bin/python" "$SCRIPT_DIR/visualize_q23.py" "$@" +echo "==> Rendering visualize_q24" +"$VENV/bin/python" "$SCRIPT_DIR/visualize_q24.py" "$@" +echo "Done." diff --git a/python_pkg/random_jpg/run.sh b/python_pkg/random_jpg/run.sh new file mode 100755 index 0000000..ccbe6bf --- /dev/null +++ b/python_pkg/random_jpg/run.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +VENV="$REPO_ROOT/.venv" +[[ ! -d "$VENV" ]] && python3 -m venv "$VENV" +"$VENV/bin/pip" show pillow &>/dev/null || "$VENV/bin/pip" install pillow -q +"$VENV/bin/python" "$SCRIPT_DIR/generate_jpeg.py" "$@" diff --git a/python_pkg/randomize_numbers/run.sh b/python_pkg/randomize_numbers/run.sh new file mode 100755 index 0000000..33df461 --- /dev/null +++ b/python_pkg/randomize_numbers/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +"$SCRIPT_DIR/../../.venv/bin/python" "$SCRIPT_DIR/random_digits.py" "$@" diff --git a/python_pkg/repo_explorer/repo_explorer.py b/python_pkg/repo_explorer/repo_explorer.py new file mode 100755 index 0000000..c98e0d2 --- /dev/null +++ b/python_pkg/repo_explorer/repo_explorer.py @@ -0,0 +1,594 @@ +#!/usr/bin/env python3 +"""Repo Explorer - browse and run any project in the monorepo via a GUI.""" + +from __future__ import annotations + +import contextlib +import fcntl +import os +from pathlib import Path +import pty +import re +import select +import shutil +import subprocess +import threading +import tkinter as tk +from tkinter import font, ttk +from typing import cast + +# Strip ANSI/VT100 escape sequences so the Text widget shows plain text +_ANSI_ESCAPE = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])") + + +def _strip_ansi(text: str) -> str: + return _ANSI_ESCAPE.sub("", text) + + +def _find_terminal() -> list[str]: + """Return argv prefix for the first available terminal emulator.""" + candidates = [ + ("kitty", ["kitty", "--"]), + ("alacritty", ["alacritty", "-e"]), + ("konsole", ["konsole", "-e"]), + ("gnome-terminal", ["gnome-terminal", "--"]), + ("xfce4-terminal", ["xfce4-terminal", "-x"]), + ("xterm", ["xterm", "-e"]), + ] + for exe, args in candidates: + if shutil.which(exe): + return args + return [] + + +REPO_ROOT = Path(__file__).resolve().parent.parent.parent + +IGNORED_DIRS = { + ".git", + ".venv", + "__pycache__", + "node_modules", + "build", + "target", + ".mypy_cache", + ".ruff_cache", +} + + +# --------------------------------------------------------------------------- +# Discovery helpers +# --------------------------------------------------------------------------- + + +def _is_ignored(path: Path) -> bool: + return any(part in IGNORED_DIRS for part in path.parts) + + +def find_projects(root: Path) -> list[dict[str, object]]: + """Return every directory under *root* that contains a run.sh.""" + projects: list[dict[str, object]] = [] + for run_sh in sorted(root.rglob("run.sh")): + if _is_ignored(run_sh): + continue + proj_dir = run_sh.parent + rel = proj_dir.relative_to(root) + projects.append({"path": proj_dir, "rel": rel, "name": proj_dir.name}) + return projects + + +def _desc_from_run_sh(run_sh: Path) -> str: + """Extract leading comment block from run.sh as a description.""" + comments: list[str] = [] + for line in run_sh.read_text(errors="replace").splitlines(): + s = line.strip() + if s.startswith("#!"): + continue + if s.startswith("#"): + comments.append(s[1:].strip()) + elif comments: + break + return " ".join(comments)[:300] if comments else "" + + +def get_description(project_path: Path) -> str: + """Return a short description from README.md or leading run.sh comments.""" + for readme_name in ("README.md", "README.txt", "readme.md"): + readme = project_path / readme_name + if readme.exists(): + text = readme.read_text(errors="replace") + for line in text.splitlines(): + stripped = line.strip().lstrip("#").strip() + if stripped: + return stripped[:300] + + run_sh = project_path / "run.sh" + if run_sh.exists(): + desc = _desc_from_run_sh(run_sh) + if desc: + return desc + + return "(no description)" + + +# --------------------------------------------------------------------------- +# Main application +# --------------------------------------------------------------------------- + + +class RepoExplorer(tk.Tk): + """Main application window for browsing and running monorepo projects.""" + + # Catppuccin Mocha palette + _BG = "#1e1e2e" + _SURFACE = "#313244" + _TEXT = "#cdd6f4" + _TEXT_DIM = "#6c7086" + _ACCENT = "#89b4fa" + _GREEN = "#a6e3a1" + _RED = "#f38ba8" + _TERMINAL_BG = "#11111b" + _MAX_EXPAND = 60 # expand tree groups automatically when <= this many results + _IDLE_FLUSH_TICKS = 2 # flush partial PTY buffer after this many 50 ms timeouts + + def __init__(self) -> None: + """Initialise the window, build the UI and load all projects.""" + super().__init__() + self.title("Repo Explorer") + self.geometry("1200x750") + self.configure(bg=self._BG) + self._proc: subprocess.Popen[bytes] | None = None + self._master_fd: int | None = None + self._projects: list[dict[str, object]] = [] + self._terminal_args = _find_terminal() + self._build_style() + self._build_ui() + self._load_projects() + + # ------------------------------------------------------------------ + # UI construction + # ------------------------------------------------------------------ + + def _build_style(self) -> None: + s = ttk.Style(self) + s.theme_use("clam") + opts: dict[str, object] + opts = { + "background": self._BG, + "foreground": self._TEXT, + "fieldbackground": self._BG, + "font": ("Monospace", 10), + "rowheight": 24, + } + s.configure("Treeview", **opts) + s.configure( + "Treeview.Heading", background=self._SURFACE, foreground=self._ACCENT + ) + s.map( + "Treeview", + background=[("selected", self._SURFACE)], + foreground=[("selected", self._ACCENT)], + ) + s.configure("TFrame", background=self._BG) + s.configure("TLabel", background=self._BG, foreground=self._TEXT) + s.configure( + "TButton", background=self._SURFACE, foreground=self._TEXT, padding=4 + ) + s.map( + "TButton", + background=[("active", "#45475a"), ("disabled", self._BG)], + foreground=[("disabled", self._TEXT_DIM)], + ) + s.configure( + "TEntry", + fieldbackground=self._SURFACE, + foreground=self._TEXT, + insertcolor=self._TEXT, + ) + s.configure("TPanedwindow", background=self._BG) + s.configure("TSeparator", background=self._SURFACE) + + def _build_ui(self) -> None: + paned = ttk.PanedWindow(self, orient=tk.HORIZONTAL) + paned.pack(fill=tk.BOTH, expand=True, padx=6, pady=6) + + paned.add(self._build_left(paned), weight=1) + paned.add(self._build_right(paned), weight=3) + + def _build_left(self, parent: ttk.PanedWindow) -> ttk.Frame: + frame = ttk.Frame(parent) + + # Search bar + sf = ttk.Frame(frame) + sf.pack(fill=tk.X, padx=4, pady=(4, 2)) + ttk.Label(sf, text="Search:").pack(side=tk.LEFT) + self._search_var = tk.StringVar() + self._search_var.trace_add("write", lambda *_: self._filter_tree()) + ttk.Entry(sf, textvariable=self._search_var).pack( + side=tk.LEFT, fill=tk.X, expand=True, padx=(4, 0) + ) + + # Project count label + self._count_var = tk.StringVar(value="") + ttk.Label( + frame, + textvariable=self._count_var, + foreground=self._TEXT_DIM, + font=("sans-serif", 8), + ).pack(anchor=tk.W, padx=6) + + # Tree + scrollbar + tree_frame = ttk.Frame(frame) + tree_frame.pack(fill=tk.BOTH, expand=True, padx=4, pady=4) + self._tree = ttk.Treeview(tree_frame, show="tree", selectmode="browse") + scroll = ttk.Scrollbar(tree_frame, command=self._tree.yview) + self._tree.configure(yscrollcommand=scroll.set) + scroll.pack(side=tk.RIGHT, fill=tk.Y) + self._tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) + + self._tree.bind("<>", self._on_select) + self._tree.bind("", lambda _: self._run_embedded()) + self._tree.bind("", lambda _: self._run_embedded()) + + return frame + + def _build_right(self, parent: ttk.PanedWindow) -> ttk.Frame: + frame = ttk.Frame(parent) + + # Description section + info_frame = ttk.Frame(frame) + info_frame.pack(fill=tk.X, padx=6, pady=(4, 0)) + + ttk.Label( + info_frame, + text="Project", + font=("sans-serif", 11, "bold"), + foreground=self._ACCENT, + ).pack(anchor=tk.W) + self._title_var = tk.StringVar(value="Select a project from the list") + ttk.Label( + info_frame, + textvariable=self._title_var, + font=("Monospace", 9), + foreground=self._TEXT_DIM, + ).pack(anchor=tk.W) + + self._desc_var = tk.StringVar(value="") + ttk.Label( + info_frame, + textvariable=self._desc_var, + wraplength=700, + justify=tk.LEFT, + foreground=self._GREEN, + ).pack(anchor=tk.W, pady=(2, 0)) + + ttk.Separator(frame, orient=tk.HORIZONTAL).pack(fill=tk.X, padx=6, pady=4) + + # Args + buttons row + ctrl_frame = ttk.Frame(frame) + ctrl_frame.pack(fill=tk.X, padx=6, pady=(0, 4)) + + ttk.Label(ctrl_frame, text="Args:").pack(side=tk.LEFT) + self._args_var = tk.StringVar() + ttk.Entry(ctrl_frame, textvariable=self._args_var, width=30).pack( + side=tk.LEFT, padx=(4, 12) + ) + + self._run_btn = ttk.Button( + ctrl_frame, + text="▶ Run here", + command=self._run_embedded, + state=tk.DISABLED, + ) + self._run_btn.pack(side=tk.LEFT, padx=(0, 4)) + + term_label = self._terminal_args[0] if self._terminal_args else "terminal" + self._term_btn = ttk.Button( + ctrl_frame, + text=f"⧉ Open in {term_label}", + command=self._run_in_terminal, + state=tk.DISABLED, + ) + self._term_btn.pack(side=tk.LEFT, padx=(0, 4)) + + self._stop_btn = ttk.Button( + ctrl_frame, text="■ Stop", command=self._stop, state=tk.DISABLED + ) + self._stop_btn.pack(side=tk.LEFT, padx=(0, 4)) + + ttk.Button(ctrl_frame, text="✕ Clear", command=self._clear).pack(side=tk.LEFT) + + # Status indicator + self._status_var = tk.StringVar(value="") + ttk.Label( + ctrl_frame, textvariable=self._status_var, font=("sans-serif", 9) + ).pack(side=tk.RIGHT) + + # stdin input row (for interactive embedded processes) + stdin_frame = ttk.Frame(frame) + stdin_frame.pack(fill=tk.X, padx=6, pady=(0, 4)) + ttk.Label(stdin_frame, text="Send input:").pack(side=tk.LEFT) + self._stdin_var = tk.StringVar() + stdin_entry = ttk.Entry(stdin_frame, textvariable=self._stdin_var) + stdin_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(4, 4)) + stdin_entry.bind("", self._send_stdin) + ttk.Button(stdin_frame, text="↵ Send", command=self._send_stdin).pack( + side=tk.LEFT + ) + + # Output terminal + term_frame = ttk.Frame(frame) + term_frame.pack(fill=tk.BOTH, expand=True, padx=6, pady=(0, 6)) + + mono = font.Font(family="Monospace", size=9) + self._output = tk.Text( + term_frame, + bg=self._TERMINAL_BG, + fg=self._TEXT, + font=mono, + wrap=tk.WORD, + state=tk.DISABLED, + relief=tk.FLAT, + insertbackground=self._TEXT, + ) + out_scroll = ttk.Scrollbar(term_frame, command=self._output.yview) + self._output.configure(yscrollcommand=out_scroll.set) + out_scroll.pack(side=tk.RIGHT, fill=tk.Y) + self._output.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) + + self._output.tag_config("stderr", foreground=self._RED) + self._output.tag_config("info", foreground=self._ACCENT) + self._output.tag_config("success", foreground=self._GREEN) + self._output.tag_config("error", foreground=self._RED) + + return frame + + # ------------------------------------------------------------------ + # Project discovery / tree population + # ------------------------------------------------------------------ + + def _load_projects(self) -> None: + self._projects = find_projects(REPO_ROOT) + self._populate_tree(self._projects) + + def _populate_tree(self, projects: list[dict[str, object]]) -> None: + self._tree.delete(*self._tree.get_children()) + + groups: dict[str, list[dict[str, object]]] = {} + for p in projects: + rel = cast("Path", p["rel"]) + parts = rel.parts + group = parts[0] if len(parts) > 1 else "(root)" + groups.setdefault(group, []).append(p) + + icons = { + "python_pkg": "🐍", + "C": "⚙️", + "CPP": "⚙️", + "articles": "📰", + "TS": "📜", + "Bash": "🐚", + } + for group, items in sorted(groups.items()): + icon = icons.get(group, "📁") + gid = self._tree.insert("", tk.END, text=f"{icon} {group}", tags=("group",)) + for item in items: + rel2 = cast("Path", item["rel"]) + label = cast( + "str", + "/".join(rel2.parts[1:]) if len(rel2.parts) > 1 else item["name"], + ) + path_str = str(item["path"]) + self._tree.insert(gid, tk.END, text=f" {label}", values=[path_str]) + + self._tree.tag_configure("group", foreground=self._TEXT_DIM) + # Expand all groups if result set is small enough + if len(projects) <= self._MAX_EXPAND: + for gid in self._tree.get_children(): + self._tree.item(gid, open=True) + + n = len(projects) + self._count_var.set(f"{n} project{'s' if n != 1 else ''}") + + def _filter_tree(self) -> None: + q = self._search_var.get().lower() + if not q: + self._populate_tree(self._projects) + return + filtered = [ + p + for p in self._projects + if q in str(p["rel"]).lower() or q in str(p["name"]).lower() + ] + self._populate_tree(filtered) + + # ------------------------------------------------------------------ + # Selection / info panel + # ------------------------------------------------------------------ + + def _selected_path(self) -> Path | None: + sel = self._tree.selection() + if not sel: + return None + vals = self._tree.item(sel[0], "values") + if not vals: + return None + return Path(vals[0]) + + def _on_select(self, _event: object) -> None: + path = self._selected_path() + if path is None: + self._run_btn.configure(state=tk.DISABLED) + self._term_btn.configure(state=tk.DISABLED) + return + self._title_var.set(str(path.relative_to(REPO_ROOT))) + self._desc_var.set(get_description(path)) + self._run_btn.configure(state=tk.NORMAL) + self._term_btn.configure( + state=tk.NORMAL if self._terminal_args else tk.DISABLED + ) + + # ------------------------------------------------------------------ + # Run in external terminal (for interactive / keyboard-driven programs) + # ------------------------------------------------------------------ + + def _run_in_terminal(self) -> None: + path = self._selected_path() + if path is None or not self._terminal_args: + return + args_str = self._args_var.get().strip() + extra = args_str.split() if args_str else [] + subprocess.Popen([*self._terminal_args, "bash", "run.sh", *extra], cwd=path) + self._write_output( + f"$ Launched in {self._terminal_args[0]}: {path.relative_to(REPO_ROOT)}\n", + "info", + ) + + # ------------------------------------------------------------------ + # Run embedded with PTY (captures terminal-aware / ncurses output) + # ------------------------------------------------------------------ + + def _run_embedded(self) -> None: + path = self._selected_path() + if path is None: + return + if self._proc and self._proc.poll() is None: + self._stop() + + self._clear() + args_str = self._args_var.get().strip() + extra = args_str.split() if args_str else [] + display_cmd = ("bash run.sh " + args_str).strip() + self._write_output( + f"$ {display_cmd} [{path.relative_to(REPO_ROOT)}]\n", "info" + ) + + master_fd, slave_fd = pty.openpty() + self._master_fd = master_fd + # Non-blocking reads on master so the reader thread doesn't stall + fl = fcntl.fcntl(master_fd, fcntl.F_GETFL) + fcntl.fcntl(master_fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) + + self._proc = subprocess.Popen( + ["bash", "run.sh", *extra], # noqa: S607 + cwd=path, + stdin=slave_fd, + stdout=slave_fd, + stderr=slave_fd, + close_fds=True, + ) + os.close(slave_fd) + + self._run_btn.configure(state=tk.DISABLED) + self._stop_btn.configure(state=tk.NORMAL) + self._status_var.set("● running") + + threading.Thread(target=self._read_pty, daemon=True).start() + threading.Thread(target=self._wait_proc, daemon=True).start() + + def _read_pty(self) -> None: # noqa: C901, PLR0912 + """Stream PTY output to the widget, stripping ANSI codes. + + Partial lines (prompts without a trailing newline) are flushed after + ~100 ms of silence so interactive prompts like "Enter value: " appear. + """ + buf = b"" + idle_ticks = 0 # consecutive 50 ms timeouts while buf has content + while self._proc and self._proc.poll() is None: + mfd = self._master_fd + if mfd is None: + break + ready, _, _ = select.select([mfd], [], [], 0.05) + if not ready: + # No new data — flush partial buffer after ~100 ms (2 ticks) + if buf: + idle_ticks += 1 + if idle_ticks >= self._IDLE_FLUSH_TICKS: + text = _strip_ansi( + buf.decode("utf-8", errors="replace").replace("\r", "") + ) + if text: + self._write_output(text) + buf = b"" + idle_ticks = 0 + continue + idle_ticks = 0 + try: + chunk = os.read(mfd, 4096) + except OSError: + break + if not chunk: + break + buf += chunk + while b"\n" in buf: + line, buf = buf.split(b"\n", 1) + text = _strip_ansi( + line.decode("utf-8", errors="replace").replace("\r", "") + ) + if text: + self._write_output(text + "\n") + # flush remainder + if buf: + text = _strip_ansi(buf.decode("utf-8", errors="replace").replace("\r", "")) + if text: + self._write_output(text) + if self._master_fd is not None: + with contextlib.suppress(OSError): + os.close(self._master_fd) + self._master_fd = None + + # ------------------------------------------------------------------ + # stdin forwarding (typed into the "Send input" field) + # ------------------------------------------------------------------ + + def _send_stdin(self, _event: object = None) -> None: + text = self._stdin_var.get() + self._stdin_var.set("") + payload = (text + "\n").encode() + if self._master_fd is not None: + with contextlib.suppress(OSError): + os.write(self._master_fd, payload) + + def _wait_proc(self) -> None: + if self._proc: + code = self._proc.wait() + self.after(0, self._on_proc_done, code) + + def _on_proc_done(self, code: int) -> None: + if code == 0: + self._write_output(f"\n[exited with code {code}]\n", "success") + self._status_var.set("✓ done") + else: + self._write_output(f"\n[exited with code {code}]\n", "error") + self._status_var.set(f"✗ exit {code}") + self._run_btn.configure(state=tk.NORMAL) + self._stop_btn.configure(state=tk.DISABLED) + + def _stop(self) -> None: + if self._proc and self._proc.poll() is None: + self._proc.terminate() + self._status_var.set("stopped") + + def _clear(self) -> None: + self._output.configure(state=tk.NORMAL) + self._output.delete("1.0", tk.END) + self._output.configure(state=tk.DISABLED) + self._status_var.set("") + + def _write_output(self, text: str, tag: str | None = None) -> None: + """Thread-safe output append via after().""" + self.after(0, self._append_output, text, tag) + + def _append_output(self, text: str, tag: str | None) -> None: + self._output.configure(state=tk.NORMAL) + if tag: + self._output.insert(tk.END, text, tag) + else: + self._output.insert(tk.END, text) + self._output.see(tk.END) + self._output.configure(state=tk.DISABLED) + + +# --------------------------------------------------------------------------- + +if __name__ == "__main__": + RepoExplorer().mainloop() diff --git a/python_pkg/repo_explorer/run.sh b/python_pkg/repo_explorer/run.sh new file mode 100755 index 0000000..2b47ae2 --- /dev/null +++ b/python_pkg/repo_explorer/run.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# Repo Explorer - browse and run any project in the monorepo via a GUI. +# Requires tkinter (Arch: sudo pacman -S python-tkinter) +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +VENV="$REPO_ROOT/.venv" + +# Ensure tkinter is available (it's stdlib but needs the python-tkinter OS package) +if ! python3 -c "import tkinter" 2>/dev/null; then + echo "tkinter not found. Installing python-tkinter..." + sudo pacman -S --noconfirm python-tkinter 2>/dev/null \ + || sudo apt-get install -y python3-tk 2>/dev/null \ + || { echo "Please install python-tkinter manually."; exit 1; } +fi + +[[ ! -d "$VENV" ]] && python3 -m venv "$VENV" +"$VENV/bin/python" "$SCRIPT_DIR/repo_explorer.py" "$@" diff --git a/python_pkg/scrape_website/run.sh b/python_pkg/scrape_website/run.sh new file mode 100755 index 0000000..965ba47 --- /dev/null +++ b/python_pkg/scrape_website/run.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +VENV="$REPO_ROOT/.venv" +[[ ! -d "$VENV" ]] && python3 -m venv "$VENV" +_pip_sync() { local r="$1" h; h=$(md5sum "$r"|cut -d' ' -f1); local lf="$VENV/.req_${h:0:8}.lock"; [[ -f "$lf" ]] && return; "$VENV/bin/pip" install -r "$r" -q && touch "$lf"; } +_pip_sync "$SCRIPT_DIR/requirements.txt" +# Usage: ./run.sh [--output-dir DIR] [--max-pages N] +"$VENV/bin/python" "$SCRIPT_DIR/scrape_comics.py" "$@" diff --git a/python_pkg/screen_locker/run.sh b/python_pkg/screen_locker/run.sh new file mode 100755 index 0000000..f40d569 --- /dev/null +++ b/python_pkg/screen_locker/run.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +VENV="$REPO_ROOT/.venv" +[[ ! -d "$VENV" ]] && python3 -m venv "$VENV" +# tkinter is from Python stdlib; install python-tk system package if missing: +# Arch: sudo pacman -S python-tk +# Debian: sudo apt-get install python3-tk +"$VENV/bin/python" "$SCRIPT_DIR/screen_lock.py" "$@" diff --git a/python_pkg/split/run.sh b/python_pkg/split/run.sh new file mode 100755 index 0000000..f2639b1 --- /dev/null +++ b/python_pkg/split/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +"$SCRIPT_DIR/../../.venv/bin/python" "$SCRIPT_DIR/split_x_into_n_symmetrically.py" "$@" diff --git a/python_pkg/stockfish_analysis/analyze_chess_game.py b/python_pkg/stockfish_analysis/analyze_chess_game.py index afabb11..1f56c70 100755 --- a/python_pkg/stockfish_analysis/analyze_chess_game.py +++ b/python_pkg/stockfish_analysis/analyze_chess_game.py @@ -367,19 +367,19 @@ def _configure_hash( def _configure_multipv( - engine: chess.engine.SimpleEngine, options: EngineOptions, requested: int + _engine: chess.engine.SimpleEngine, options: EngineOptions, requested: int ) -> int: """Configure MultiPV and return effective value.""" effective = max(1, int(requested)) - if "MultiPV" not in options: - return effective - try: - max_mpv = getattr(options["MultiPV"], "max", None) - if isinstance(max_mpv, int): - effective = min(effective, max_mpv) - engine.configure({"MultiPV": int(effective)}) - except (AttributeError, TypeError, ValueError): - _logger.debug("Failed to configure MultiPV option") + # MultiPV is automatically managed by python-chess and passed directly to + # engine.analyse(..., multipv=N) — do not configure() it here. + if "MultiPV" in options: + try: + max_mpv = getattr(options["MultiPV"], "max", None) + if isinstance(max_mpv, int): + effective = min(effective, max_mpv) + except (AttributeError, TypeError, ValueError): + _logger.debug("Failed to read MultiPV max option") return effective diff --git a/python_pkg/stockfish_analysis/run.sh b/python_pkg/stockfish_analysis/run.sh index 2807671..1779a4a 100755 --- a/python_pkg/stockfish_analysis/run.sh +++ b/python_pkg/stockfish_analysis/run.sh @@ -24,8 +24,12 @@ fi # shellcheck disable=SC1090 source "$VENV_DIR/bin/activate" -# Install dependencies quietly -pip install -r "$SCRIPT_DIR/requirements.txt" >/dev/null +# Install dependencies only if requirements.txt has changed +_REQ="$SCRIPT_DIR/requirements.txt" +_HASH=$(md5sum "$_REQ" | cut -d' ' -f1) +_LOCK="$VENV_DIR/.req_${_HASH:0:8}.lock" +[[ -f "$_LOCK" ]] || { pip install -r "$_REQ" >/dev/null && touch "$_LOCK"; } +unset _REQ _HASH _LOCK # Default engine (can override with STOCKFISH env var) ENGINE_BIN="${STOCKFISH:-stockfish}" diff --git a/python_pkg/tag_divider/run.sh b/python_pkg/tag_divider/run.sh new file mode 100755 index 0000000..19c6de3 --- /dev/null +++ b/python_pkg/tag_divider/run.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +VENV="$REPO_ROOT/.venv" +[[ ! -d "$VENV" ]] && python3 -m venv "$VENV" +"$VENV/bin/pip" show opencv-python &>/dev/null || "$VENV/bin/pip" install opencv-python -q +# Usage: ./run.sh +"$VENV/bin/python" "$SCRIPT_DIR/tag_divider.py" "$@" diff --git a/python_pkg/word_frequency/run.sh b/python_pkg/word_frequency/run.sh new file mode 100755 index 0000000..063c63d --- /dev/null +++ b/python_pkg/word_frequency/run.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# Usage: ./run.sh [options] +"$SCRIPT_DIR/../../.venv/bin/python" "$SCRIPT_DIR/vocabulary_curve.py" "$@" diff --git a/scripts/check_c_cpp_build_files.sh b/scripts/check_c_cpp_build_files.sh new file mode 100755 index 0000000..d8a2bac --- /dev/null +++ b/scripts/check_c_cpp_build_files.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +# Check that every directory containing C/C++ source files has a Makefile and run.sh. +# Used as a pre-commit hook; receives staged file paths as arguments. + +set -uo pipefail + +errors=() +declare -A checked_dirs + +for file in "$@"; do + dir=$(dirname "$file") + + # Skip build directories and CMake artefact trees + if echo "$dir" | grep -qE '(^|/)build(/|$)'; then + continue + fi + + # Skip if already checked this directory + [[ -v checked_dirs["$dir"] ]] && continue + checked_dirs["$dir"]=1 + + # Check for Makefile (case-insensitive: Makefile or makefile) + if ! compgen -G "$dir/[Mm]akefile" > /dev/null 2>&1; then + errors+=("MISSING Makefile in: $dir") + fi + + # Check for run.sh + if [[ ! -f "$dir/run.sh" ]]; then + errors+=("MISSING run.sh in: $dir") + fi +done + +if [[ ${#errors[@]} -gt 0 ]]; then + printf 'C/C++ build file check failed:\n' + printf ' %s\n' "${errors[@]}" + printf '\nEvery directory with .c/.cpp files must have a Makefile and run.sh.\n' + exit 1 +fi + +exit 0