diff options
| Commit | 010597ad71b3bc48784cb9a13b3e0fc8dccc69cd (patch) | |
|---|---|---|
| Author | 2024-10-06 07:59:36 +0000 | |
| Committer | 2024-10-06 07:59:36 +0000 | |
| Files | 784604f5818679987f940285077cd8e0460a6488 /src | |
| syndamia.com-010597ad71b3bc48784cb9a13b3e0fc8dccc69cd.tar syndamia.com-010597ad71b3bc48784cb9a13b3e0fc8dccc69cd.tar.gz syndamia.com-010597ad71b3bc48784cb9a13b3e0fc8dccc69cd.zip | ||
| Parent | 6fe00c6ec76028fc055084a3398004fbbefac0be (diff) | |
| Parent | c027ddea2e1d6ed69a012edf47d3b39e25b6c9d5 (diff) | |
Merge branch 'master' into 'blog/black-hole-shader'
# Conflicts:
# src/blog/index.md
79 files changed, 4842 insertions, 1554 deletions
diff --git a/src/_footer.html b/src/_footer.html index 61bf08d..605da32 100644 --- a/src/_footer.html +++ b/src/_footer.html @@ -8,7 +8,6 @@ </body> <script type="text/javascript" src="/scripts/theme-changer.js" crossorigin="anonymous" defer></script> -<script type="text/javascript" src="/scripts/image-show.js" crossorigin="anonymous" defer></script> <script type="text/javascript" src="/scripts/back-to-top.js" crossorigin="anonymous" defer></script> <script type="text/javascript" src="/scripts/keyboard.js" crossorigin="anonymous" defer></script> diff --git a/src/_header.html b/src/_header.html index 38046bc..a54be39 100644 --- a/src/_header.html +++ b/src/_header.html @@ -5,8 +5,8 @@ <meta charset="UTF-8"> <meta name="author" content="Kamen Mladenov"> <meta name="robots" content="index, follow"> - <link rel="icon" href="/img/favicon.png" type="image/png"> - <link rel="shortcut icon" href="/img/favicon.png" type="image/png"> + <link rel="icon" href="/img/favicon.ico" type="image/x-icon"> + <link rel="shortcut icon" href="/img/favicon.ico" type="image/x-icon"> <meta name="theme-color" content="#ffffff"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="/styles.css"> @@ -25,7 +25,7 @@ </head> <body id="content-wrapper" text="black" bgcolor="white" link="#336700" vlink="#336700"> <nav id="sidebar"> - <nav id="header"> + <nav id="header" class="sidebar-section"> <span class="nocss-aid">[[</span> <a href="/">Home</a> @@ -35,40 +35,53 @@ <span class="nocss-aid">]]</span> </nav> - <nav id="index"> - <span class="nocss-aid">[[</span> + <nav id="index" class="sidebar-section"> + <span class="nocss-aid"><br>[[</span> - <span>Content</span><span class="nocss-aid">:</span> - <span class="arrowed-list"> - <a href="/blog">Blog</a> - <a href="/slides">Slides</a> - <a href="/teaching">Teaching</a> - <a href="/tutorials">Tutorials</a> - <a href="/misc">Miscellaneous</a> + <span>Text</span><span class="nocss-aid">:</span> + <span class="index-list"> + <a class="index-list-item" href="/blog">Blog</a> + <a class="index-list-item" href="/teaching">Teaching</a> + <a class="index-list-item" href="/tutorials">Tutorials</a> </span> - <span class="nocss-aid">||</span> + <span class="nocss-aid">]]</span> + + <span class="nocss-aid"><br>[[</span> - <span>Preservation</span><span class="nocss-aid">:</span> - <span class="arrowed-list"> - <a href="/preserved-media">Media</a> - <a href="/preserved-web-pages">Web pages</a> + <span>Interactive</span><span class="nocss-aid">:</span> + <span class="index-list"> + <a class="index-list-item" href="/slides">Slides</a> + <a class="index-list-item" href="/preserved-web-pages">Preserved web</a> </span> - <span class="nocss-aid">||</span> + <span class="nocss-aid">]]</span> + + <span class="nocss-aid"><br>[[</span> + + <span>Files</span><span class="nocss-aid">:</span> + <span class="index-list"> + <a class="index-list-item" href="/preserved-media">Archived media</a> + <a class="index-list-item" href="/misc">Miscellaneous</a> + </span> + + <span class="nocss-aid">]]</span> + + <span class="nocss-aid"><br>[[</span> <span>Me</span><span class="nocss-aid">:</span> - <span class="arrowed-list"> - <a href="/about">About</a> - <a href="/software">Software</a> - <a href="/setup">Setup</a> + <span class="index-list"> + <a class="index-list-item" href="/about">About</a> + <a class="index-list-item" href="/setup">Setup</a> </span> <span class="nocss-aid">]]</span> </nav> - <nav id="settingsWrapper"> - <span class="nocss-aid">[[</span> + <span class="nocss-aid"><br></span> + + <nav id="settingsWrapper" class="sidebar-section"> + <span class="nocss-aid"><br>[[</span> <span id="changeThemeBtn" class="btn setting-btn"><span>Light</span><span class="br"></span>theme</span> <span id="changeWidthBtn" class="btn setting-btn"><span>Wide</span><span class="br"></span>article</span> @@ -76,26 +89,28 @@ <span class="nocss-aid">]]</span> </nav> - <nav id="footer"> + <span class="nocss-aid"><br></span> + + <nav id="footer" class="sidebar-section"> <span class="nocss-aid">[[</span> <a href="/license.html" title="CC BY-SA 4.0 and GNU GPLv3">CC BY-SA 4.0 and GNU GPLv3</a> - <span class="nocss-aid">||</span><span class="brt"></span> + <span class="nocss-aid"><br>[[</span><span class="brt"></span> <a href="/privacy.html" title="Privacy policy">Privacy policy</a> | <a href="/accessibility.html" title="Accessibility">Accessibility</a><span class="br"></span><span class="nocss-aid"> |</span> <a href="/regarding-js.html" title="Regarding usage of JavaScript">Regarding JavaScript</a><span class="br"></span><span class="nocss-aid"> |</span> <a href="/acknowledgements.html" title="Acknowledgements">Acknowledgements</a><span class="br"></span> - <span class="nocss-aid">||</span><span class="brt"></span> + <span class="nocss-aid">]]<br>[[</span><span class="brt"></span> <a href="https://gitlab.com/Syndamia" target="_blank" title="GitLab">GitLab</a> | <a href="https://github.com/Syndamia" target="_blank" title="GitHub">GitHub</a> | <a href="/about/#contact" target="_blank" title="Contact">Contact</a><span class="br"></span><span class="nocss-aid"> |</span> <a href="https://bg.linkedin.com/in/kamen-mladenov" target="_blank" title="Linkedin">LinkedIn</a><span class="br"></span> - <span class="nocss-aid">||</span><span class="brt"></span> + <span class="nocss-aid">]]<br>[[</span><span class="brt"></span> <a href="https://gitlab.com/Syndamia/syndamiadotcom" target="_blank" class="link-tab">Powered with:</a><span class="br"></span> <a href="https://gitlab.com/Syndamia/csg" target="_blank" class="link-tab">csg by me</a><span class="br"></span><span class="nocss-aid">, </span> diff --git a/src/about.md b/src/about.md index 964393e..52c6bf9 100644 --- a/src/about.md +++ b/src/about.md @@ -1,10 +1,10 @@ # About Me **Contact me casually** -: <a href="mailto:syndamia@protonmail.com">syndamia@protonmail.com</a> <a class="borderless" href="/files/publickey-syndamia@protonmail.com-2c9b555f61c33e30acbe477dcb2956a33e10cc8c.asc"><img class="borderless unzoomable" src="/img/pgpkey.gif" alt="PGP key"></a><br><a href="mailto:kamen.s@syndamia.com">kamen.s@syndamia.com</a> <a class="borderless" href="/files/publickey-kamen.s@syndamia.com-0xDFC9D42E.asc"><img class="borderless unzoomable" src="/img/pgpkey.gif" alt="PGP key"></a> *(for this one, make sure to check your spam folder!)* +: <a href="mailto:syndamia@protonmail.com">syndamia@protonmail.com</a> <a class="borderless" href="/files/publickey-syndamia@protonmail.com-2c9b555f61c33e30acbe477dcb2956a33e10cc8c.asc"><img class="borderless" src="/img/pgpkey.gif" alt="PGP key"></a><br><a href="mailto:kamen.s@syndamia.com">kamen.s@syndamia.com</a> <a class="borderless" href="/files/publickey-kamen.s@syndamia.com-0xDFC9D42E.asc"><img class="borderless" src="/img/pgpkey.gif" alt="PGP key"></a> *(for this one, make sure to check your spam folder!)* **Contact me about work and projects I'm maintaining** -: <a href="mailto:kamen.d.mladenov@protonmail.com">kamen.d.mladenov@protonmail.com</a> <a class="borderless" href="/files/publickey-kamen.d.mladenov@protonmail.com-62ca52e87475c874b9e6ebf3c4c9f716b6ce4c9d.asc"><img class="borderless unzoomable" src="/img/pgpkey.gif" alt="PGP key"></a> <br> <a href="mailto:kamen@syndamia.com">kamen@syndamia.com</a> <a class="borderless" href="/files/publickey-kamen@syndamia.com-0x354C5F95.asc"><img class="borderless unzoomable" src="/img/pgpkey.gif" alt="PGP key"></a> *(for this one, make sure to check your spam folder!)*<br>[linkedin.com/in/kamen-mladenov](https://www.linkedin.com/in/kamen-mladenov/) +: <a href="mailto:kamen.d.mladenov@protonmail.com">kamen.d.mladenov@protonmail.com</a> <a class="borderless" href="/files/publickey-kamen.d.mladenov@protonmail.com-62ca52e87475c874b9e6ebf3c4c9f716b6ce4c9d.asc"><img class="borderless" src="/img/pgpkey.gif" alt="PGP key"></a> <br> <a href="mailto:kamen@syndamia.com">kamen@syndamia.com</a> <a class="borderless" href="/files/publickey-kamen@syndamia.com-0x354C5F95.asc"><img class="borderless" src="/img/pgpkey.gif" alt="PGP key"></a> *(for this one, make sure to check your spam folder!)*<br>[linkedin.com/in/kamen-mladenov](https://www.linkedin.com/in/kamen-mladenov/) **Resume** : [Български](/files/resume-bg.pdf) | [English](/files/resume-en.pdf) @@ -13,7 +13,7 @@ ### Antibio [(opposite of bio, and much more fun)](https://www.brendangregg.com/antibio.html) -<img id="about-image" class="borderless unzoomable" src="/img/face.jpeg" alt=""> +<img id="about-image" class="borderless" src="/img/face.jpeg" alt=""> I'm a [university](https://www.fmi.uni-sofia.bg/en) student and general computer nerd. My current interests include: operating systems, functional programming, webdev (without **any** libraries, pure JavaScript), old tech, some amount of server administration and a teeny weeny bit of computer history. @@ -27,3 +27,42 @@ So, who knows what's gonna be next. Unfortunately there isn't too much I can show now, especially as content on this website... But hey, you gotta start somewhere! + +### Software + +This is a curated list of the more relevant software projects I've made or heavily contributed to + +<br> + +#### *2023* + +[gitlab / texty-office](https://gitlab.com/Syndamia/texty-office) + [gitlab / texty-office.vim](https://gitlab.com/Syndamia/texty-office.vim) +: An imperfect converter from DOCX, PPTX and XLSX to normal text with it's associated [Vim](https://www.vim.org/) plugin. <br> `GNU GPLv3` & `MIT` | `C++` `vimscript` | `Office file` `converter` `plugin` `Vim` `CLI tool` + +[gitlab / small-web-utilities](https://gitlab.com/Syndamia/small-web-utilities)   *maintained* +: A collection of small but fast utilities, like a checklist, that work locally on your browser. Also hosted [here](https://utils.syndamia.com). <br> `GNU GPLv3` | `HTML` `Javascript` | `checklist` `utilities` + +[gitlab / ss-law](https://gitlab.com/Syndamia/ss-law) + [github / ss-law](https://github.com/Syndamia/ss-law)   *maintained* +: A small, lightweight and simple static site generation system, extracted as a template from my own <br> `Markdown` `bash` `awk` | `ssg` `lowdown` `static site generator` `pipelines` + +[gitlab / homelander](https://gitlab.com/Syndamia/homelander)   *maintained* +: A very small and good looking, handmade prompt for zsh <br> `GPLv3` | `bash` | `zsh` `shell` `prompt` `script` `Linux` + +[gitlab / goodwolf](https://gitlab.com/Syndamia/goodwolf)   *abandoned* +: Fork of the [badwolf](https://hacktivis.me/projects/badwolf) browser, which aims to add features <br> `BSD-3-Clause` | `C` | `web browser` `GTK` `WebKitGTK` `Linux` + +#### *2021* + +[gitlab / RepoSync](https://gitlab.com/Syndamia/reposync)   *completed* +: Script and some config files for synchronizing a git repository with a server <br> `MIT` | `python` | `server` `git` `systemd` + +[github / filite-list](https://github.com/Syndamia/filite-list)   *completed* +: Script for managing [filite](https://github.com/raftario/filite) links <br> `GPLv3` | `bash` | `filite` `server` `script` `Linux` + +#### *2020* + +[github / DevHive](https://github.com/Team-Kaleidoscope/DevHive) and [github / DevHive-Angular](https://github.com/Team-Kaleidoscope/DevHive-Angular)   *completed* +: DevHive is a social network oriented towards programmers. It's FOSS, built from the ground up, and made from a team of three for a course. <br> `GPLv3` | `C#` `TypeScript` | `Angular` `ASP.NET Core` `social media` `mvc` `Docker` `CSS` + +[github / min-youtube-element-blocker](https://github.com/Syndamia/min-youtube-element-blocker)   *maintained* +: Userscript for hiding certain UI elements in YouTube <br> `MIT` | `JavaScript` | `youtube` `userscript` `css` diff --git a/src/about/index.md b/src/about/index.md index 964393e..52c6bf9 100644 --- a/src/about/index.md +++ b/src/about/index.md @@ -1,10 +1,10 @@ # About Me **Contact me casually** -: <a href="mailto:syndamia@protonmail.com">syndamia@protonmail.com</a> <a class="borderless" href="/files/publickey-syndamia@protonmail.com-2c9b555f61c33e30acbe477dcb2956a33e10cc8c.asc"><img class="borderless unzoomable" src="/img/pgpkey.gif" alt="PGP key"></a><br><a href="mailto:kamen.s@syndamia.com">kamen.s@syndamia.com</a> <a class="borderless" href="/files/publickey-kamen.s@syndamia.com-0xDFC9D42E.asc"><img class="borderless unzoomable" src="/img/pgpkey.gif" alt="PGP key"></a> *(for this one, make sure to check your spam folder!)* +: <a href="mailto:syndamia@protonmail.com">syndamia@protonmail.com</a> <a class="borderless" href="/files/publickey-syndamia@protonmail.com-2c9b555f61c33e30acbe477dcb2956a33e10cc8c.asc"><img class="borderless" src="/img/pgpkey.gif" alt="PGP key"></a><br><a href="mailto:kamen.s@syndamia.com">kamen.s@syndamia.com</a> <a class="borderless" href="/files/publickey-kamen.s@syndamia.com-0xDFC9D42E.asc"><img class="borderless" src="/img/pgpkey.gif" alt="PGP key"></a> *(for this one, make sure to check your spam folder!)* **Contact me about work and projects I'm maintaining** -: <a href="mailto:kamen.d.mladenov@protonmail.com">kamen.d.mladenov@protonmail.com</a> <a class="borderless" href="/files/publickey-kamen.d.mladenov@protonmail.com-62ca52e87475c874b9e6ebf3c4c9f716b6ce4c9d.asc"><img class="borderless unzoomable" src="/img/pgpkey.gif" alt="PGP key"></a> <br> <a href="mailto:kamen@syndamia.com">kamen@syndamia.com</a> <a class="borderless" href="/files/publickey-kamen@syndamia.com-0x354C5F95.asc"><img class="borderless unzoomable" src="/img/pgpkey.gif" alt="PGP key"></a> *(for this one, make sure to check your spam folder!)*<br>[linkedin.com/in/kamen-mladenov](https://www.linkedin.com/in/kamen-mladenov/) +: <a href="mailto:kamen.d.mladenov@protonmail.com">kamen.d.mladenov@protonmail.com</a> <a class="borderless" href="/files/publickey-kamen.d.mladenov@protonmail.com-62ca52e87475c874b9e6ebf3c4c9f716b6ce4c9d.asc"><img class="borderless" src="/img/pgpkey.gif" alt="PGP key"></a> <br> <a href="mailto:kamen@syndamia.com">kamen@syndamia.com</a> <a class="borderless" href="/files/publickey-kamen@syndamia.com-0x354C5F95.asc"><img class="borderless" src="/img/pgpkey.gif" alt="PGP key"></a> *(for this one, make sure to check your spam folder!)*<br>[linkedin.com/in/kamen-mladenov](https://www.linkedin.com/in/kamen-mladenov/) **Resume** : [Български](/files/resume-bg.pdf) | [English](/files/resume-en.pdf) @@ -13,7 +13,7 @@ ### Antibio [(opposite of bio, and much more fun)](https://www.brendangregg.com/antibio.html) -<img id="about-image" class="borderless unzoomable" src="/img/face.jpeg" alt=""> +<img id="about-image" class="borderless" src="/img/face.jpeg" alt=""> I'm a [university](https://www.fmi.uni-sofia.bg/en) student and general computer nerd. My current interests include: operating systems, functional programming, webdev (without **any** libraries, pure JavaScript), old tech, some amount of server administration and a teeny weeny bit of computer history. @@ -27,3 +27,42 @@ So, who knows what's gonna be next. Unfortunately there isn't too much I can show now, especially as content on this website... But hey, you gotta start somewhere! + +### Software + +This is a curated list of the more relevant software projects I've made or heavily contributed to + +<br> + +#### *2023* + +[gitlab / texty-office](https://gitlab.com/Syndamia/texty-office) + [gitlab / texty-office.vim](https://gitlab.com/Syndamia/texty-office.vim) +: An imperfect converter from DOCX, PPTX and XLSX to normal text with it's associated [Vim](https://www.vim.org/) plugin. <br> `GNU GPLv3` & `MIT` | `C++` `vimscript` | `Office file` `converter` `plugin` `Vim` `CLI tool` + +[gitlab / small-web-utilities](https://gitlab.com/Syndamia/small-web-utilities)   *maintained* +: A collection of small but fast utilities, like a checklist, that work locally on your browser. Also hosted [here](https://utils.syndamia.com). <br> `GNU GPLv3` | `HTML` `Javascript` | `checklist` `utilities` + +[gitlab / ss-law](https://gitlab.com/Syndamia/ss-law) + [github / ss-law](https://github.com/Syndamia/ss-law)   *maintained* +: A small, lightweight and simple static site generation system, extracted as a template from my own <br> `Markdown` `bash` `awk` | `ssg` `lowdown` `static site generator` `pipelines` + +[gitlab / homelander](https://gitlab.com/Syndamia/homelander)   *maintained* +: A very small and good looking, handmade prompt for zsh <br> `GPLv3` | `bash` | `zsh` `shell` `prompt` `script` `Linux` + +[gitlab / goodwolf](https://gitlab.com/Syndamia/goodwolf)   *abandoned* +: Fork of the [badwolf](https://hacktivis.me/projects/badwolf) browser, which aims to add features <br> `BSD-3-Clause` | `C` | `web browser` `GTK` `WebKitGTK` `Linux` + +#### *2021* + +[gitlab / RepoSync](https://gitlab.com/Syndamia/reposync)   *completed* +: Script and some config files for synchronizing a git repository with a server <br> `MIT` | `python` | `server` `git` `systemd` + +[github / filite-list](https://github.com/Syndamia/filite-list)   *completed* +: Script for managing [filite](https://github.com/raftario/filite) links <br> `GPLv3` | `bash` | `filite` `server` `script` `Linux` + +#### *2020* + +[github / DevHive](https://github.com/Team-Kaleidoscope/DevHive) and [github / DevHive-Angular](https://github.com/Team-Kaleidoscope/DevHive-Angular)   *completed* +: DevHive is a social network oriented towards programmers. It's FOSS, built from the ground up, and made from a team of three for a course. <br> `GPLv3` | `C#` `TypeScript` | `Angular` `ASP.NET Core` `social media` `mvc` `Docker` `CSS` + +[github / min-youtube-element-blocker](https://github.com/Syndamia/min-youtube-element-blocker)   *maintained* +: Userscript for hiding certain UI elements in YouTube <br> `MIT` | `JavaScript` | `youtube` `userscript` `css` diff --git a/src/acknowledgements.md b/src/acknowledgements.md index d5ad17b..3d0ae3e 100644 --- a/src/acknowledgements.md +++ b/src/acknowledgements.md @@ -26,7 +26,7 @@ [Cari D. Burstein](https://www.anybrowser.org/cdaveb/) : For his [Viewable with Any Browser](https://www.anybrowser.org/campaign/index.html) comapign and the awesome [provided badges](https://www.anybrowser.org/campaign/abgraphics.html) -[RusticCyberpunk/cypnk](https://sh2.us/) <img class="borderless unzoomable" src="https://sh2.us/buttons/btn-cypnk-at-sh2.png" alt=""> +[RusticCyberpunk/cypnk](https://sh2.us/) <img class="borderless" src="https://sh2.us/buttons/btn-cypnk-at-sh2.png" alt=""> : For his [archive](https://sh2.us/buttons/) of [Taylor McKnight's](https://gtmcknight.com/) collection of buttons [Adam Kalsey](https://kalsey.com/) diff --git a/src/blog.md b/src/blog.md index 4a711c3..b404428 100644 --- a/src/blog.md +++ b/src/blog.md @@ -4,42 +4,47 @@ Articles detailing personal experiences or exploration of certain topics. <br> -&&gb 30 Aug   [ThinkPad X270 - my favorite machine](/blog/thinkpad-x270-my-favorite-machine) +&.gb 20 Feb   [Microsoft and FOSS: a fire to be extinguished](/blog/microsoft-and-foss-extinguish) +: `Shallow dive` | `Opinion` | `Microsoft` `GitHub` `Linux` `FOSS` + +#### *2023* + +&.gb 30 Aug   [ThinkPad X270 - my favorite machine](/blog/thinkpad-x270-my-favorite-machine) : `Medium dive` | `Review` | `Lenovo` `ThinkPad` `Yoga` -&&gb 19 July   [Icon fonts aren't evil, you just have to care](/blog/icon-fonts-arent-evil-you-just-have-to-care) +&.gb 19 July   [Icon fonts aren't evil, you just have to care](/blog/icon-fonts-arent-evil-you-just-have-to-care) : `Shallow dive` | `Web development` | `Icon font` `SVG` `Accessibility` `FontForge` -&&bg 14 July   [ФМИ и висшето образование в програмистката индустрия](/blog/fmi-i-vissheto-obrazovanie-v-programistkata-industriq) +&.bg 14 July   [ФМИ и висшето образование в програмистката индустрия](/blog/fmi-i-vissheto-obrazovanie-v-programistkata-industriq) : `Deep dive` | `University` | `FMI` `Education` -&&gb 07 June   [Friendship ended with Funtoo, now Gentoo is my best friend](/blog/friendship-ended-with-funtoo-now-gentoo-is-my-best-friend) +&.gb 07 June   [Friendship ended with Funtoo, now Gentoo is my best friend](/blog/friendship-ended-with-funtoo-now-gentoo-is-my-best-friend) : `Shallow dive` | `Linux` | `Funtoo` `Gentoo` `portage` `packages` `emerge` `ebuild` -&&gb 01 May   [BASH is weird](/blog/bash-is-weird) +&.gb 01 May   [BASH is weird](/blog/bash-is-weird) : `Shallow dive` | `bash` | `Linux` `scripting` -&&gb 18 Apr   [Sane explanation of compilers: Part 1](/blog/sane-explanation-of-compilers/part-1.html) +&.gb 18 Apr   [Sane explanation of compilers: Part 1](/blog/sane-explanation-of-compilers/part-1.html) : `Deep dive` | `Compilers` | `C` `yacc` `bison` `math` `Trees` `Regex` `Grammar` `Languages` -&&gb 13 Jan   [Plan 9 in Linux: Mouse menus](/blog/plan9-in-linux-mouse-menus) +&.gb 13 Jan   [Plan 9 in Linux: Mouse menus](/blog/plan9-in-linux-mouse-menus) : `Medium dive` | `Linux` | `Plan 9` `mouse` `bash` `script` `X11` `openbox` `jgmenu` `plumber` #### *2022* -&&gb 23 Dec   [2.6 years of web design](/blog/2.6-years-of-web-design) +&.gb 23 Dec   [2.6 years of web design](/blog/2.6-years-of-web-design) : `Shallow dive` | `Web design` -&&gb 13 Dec   [When a language forces simpler thinking](/blog/when-a-language-forces-simpler-thinking) +&.gb 13 Dec   [When a language forces simpler thinking](/blog/when-a-language-forces-simpler-thinking) : `Shallow dive` | `Common Lisp` | `Advent of Code` -&&gb 04 Dec   [Taming The Fun-too](/blog/taming-the-fun-too) +&.gb 04 Dec   [Taming The Fun-too](/blog/taming-the-fun-too) : `Story` | `Funtoo` | `Linux` `Gentoo` `packages` -&&gb 10 Sep   [Encrypted email](/blog/encrypted-email) +&.gb 10 Sep   [Encrypted email](/blog/encrypted-email) : `Medium dive` | `Email` | `Encryption` `Security` `PGP` `S/MIME` `Protonmail` `Tutanota` #### *2020* -&&gb 20 May   [Mundus: My first shot at game development](/blog/mundus-first-shot-at-gamedev) +&.gb 20 May   [Mundus: My first shot at game development](/blog/mundus-first-shot-at-gamedev) : `Deep dive` | `Gamedev` | `2D` `Sandbox` `Crafting` `Building` `Fighting` `GtkSharp 2.0` `C#` diff --git a/src/blog/index.md b/src/blog/index.md index 435014a..d521d40 100644 --- a/src/blog/index.md +++ b/src/blog/index.md @@ -7,44 +7,47 @@ Articles detailing personal experiences or exploration of certain topics. &&gb 06 Oct   [The physics behind a black hole shader](/blog/the-physics-behind-a-black-hole-shader) : `Deep dive` | `Physics` | `General theory of relativity` `Celestial mechanics` `Gravity` `Black Hole` `Algorithm` +&.gb 20 Feb   [Microsoft and FOSS: a fire to be extinguished](/blog/microsoft-and-foss-extinguish) +: `Shallow dive` | `Opinion` | `Microsoft` `GitHub` `Linux` `FOSS` + #### *2023* -&&gb 30 Aug   [ThinkPad X270 - my favorite machine](/blog/thinkpad-x270-my-favorite-machine) +&.gb 30 Aug   [ThinkPad X270 - my favorite machine](/blog/thinkpad-x270-my-favorite-machine) : `Medium dive` | `Review` | `Lenovo` `ThinkPad` `Yoga` -&&gb 19 July   [Icon fonts aren't evil, you just have to care](/blog/icon-fonts-arent-evil-you-just-have-to-care) +&.gb 19 July   [Icon fonts aren't evil, you just have to care](/blog/icon-fonts-arent-evil-you-just-have-to-care) : `Shallow dive` | `Web development` | `Icon font` `SVG` `Accessibility` `FontForge` -&&bg 14 July   [ФМИ и висшето образование в програмистката индустрия](/blog/fmi-i-vissheto-obrazovanie-v-programistkata-industriq) +&.bg 14 July   [ФМИ и висшето образование в програмистката индустрия](/blog/fmi-i-vissheto-obrazovanie-v-programistkata-industriq) : `Deep dive` | `University` | `FMI` `Education` -&&gb 07 June   [Friendship ended with Funtoo, now Gentoo is my best friend](/blog/friendship-ended-with-funtoo-now-gentoo-is-my-best-friend) +&.gb 07 June   [Friendship ended with Funtoo, now Gentoo is my best friend](/blog/friendship-ended-with-funtoo-now-gentoo-is-my-best-friend) : `Shallow dive` | `Linux` | `Funtoo` `Gentoo` `portage` `packages` `emerge` `ebuild` -&&gb 01 May   [BASH is weird](/blog/bash-is-weird) +&.gb 01 May   [BASH is weird](/blog/bash-is-weird) : `Shallow dive` | `bash` | `Linux` `scripting` -&&gb 18 Apr   [Sane explanation of compilers: Part 1](/blog/sane-explanation-of-compilers/part-1.html) +&.gb 18 Apr   [Sane explanation of compilers: Part 1](/blog/sane-explanation-of-compilers/part-1.html) : `Deep dive` | `Compilers` | `C` `yacc` `bison` `math` `Trees` `Regex` `Grammar` `Languages` -&&gb 13 Jan   [Plan 9 in Linux: Mouse menus](/blog/plan9-in-linux-mouse-menus) +&.gb 13 Jan   [Plan 9 in Linux: Mouse menus](/blog/plan9-in-linux-mouse-menus) : `Medium dive` | `Linux` | `Plan 9` `mouse` `bash` `script` `X11` `openbox` `jgmenu` `plumber` #### *2022* -&&gb 23 Dec   [2.6 years of web design](/blog/2.6-years-of-web-design) +&.gb 23 Dec   [2.6 years of web design](/blog/2.6-years-of-web-design) : `Shallow dive` | `Web design` -&&gb 13 Dec   [When a language forces simpler thinking](/blog/when-a-language-forces-simpler-thinking) +&.gb 13 Dec   [When a language forces simpler thinking](/blog/when-a-language-forces-simpler-thinking) : `Shallow dive` | `Common Lisp` | `Advent of Code` -&&gb 04 Dec   [Taming The Fun-too](/blog/taming-the-fun-too) +&.gb 04 Dec   [Taming The Fun-too](/blog/taming-the-fun-too) : `Story` | `Funtoo` | `Linux` `Gentoo` `packages` -&&gb 10 Sep   [Encrypted email](/blog/encrypted-email) +&.gb 10 Sep   [Encrypted email](/blog/encrypted-email) : `Medium dive` | `Email` | `Encryption` `Security` `PGP` `S/MIME` `Protonmail` `Tutanota` #### *2020* -&&gb 20 May   [Mundus: My first shot at game development](/blog/mundus-first-shot-at-gamedev) +&.gb 20 May   [Mundus: My first shot at game development](/blog/mundus-first-shot-at-gamedev) : `Deep dive` | `Gamedev` | `2D` `Sandbox` `Crafting` `Building` `Fighting` `GtkSharp 2.0` `C#` diff --git a/src/blog/microsoft-and-foss-extinguish/index.md b/src/blog/microsoft-and-foss-extinguish/index.md new file mode 100644 index 0000000..ebd3ab5 --- /dev/null +++ b/src/blog/microsoft-and-foss-extinguish/index.md @@ -0,0 +1,83 @@ +# Microsoft and FOSS: a fire to be extinguished + +## Contents + +1. [GitHub's embrace and extensions](#githubs-embrace-and-extensions) +2. [Blowtorch to the penguin](#blowtorch-to-the-penguin) +3. [But these are good things for the user](#but-these-are-good-things-for-the-user) + 1. [The practical answer](#the-practical-answer) + 2. [The moral answer](#the-moral-answer) + +A week ago [Microsoft announced they'll be adding "sudo" to Windows](https://devblogs.microsoft.com/commandline/introducing-sudo-for-windows/). +I'm not really knowledgeable enough to be certain what I'm saying is true, so I could be wrong, but upon hearing these news, my mind immediately jumped to the [EEE: Embrace, Extend, Extinguish](https://en.wikipedia.org/wiki/Embrace,_extend,_and_extinguish). + +As it is explained on Wikipedia, this is a very old and successful tactic, where Microsoft would enter new markets by: + +1. Embracing public standards and implementing all features the current product landscape offers, then +2. Extending their offering with proprietary features, which will be pushed to customers and finally +3. Extinguishing their competition, since the vast majority of consumers would be depending on the proprietary features of Microsoft's product + +## GitHub's embrace and extensions + +Thinking about the development of GitHub under Microsoft's rule, this pattern seems to show up. +Open-source by itself is primarily about publishing the source code of your project, but GitHub isn't just about that. +Now we have: + +- [GitHub Octoverse](https://octoverse.github.com/), yearly reports on open-source globally, but quite often through the lens of GitHub +- [GitHub Insider](https://resources.github.com/newsletter/), a monthly newsletter +- [GitHub Copilot](https://github.com/features/copilot/), an AI developer tool +- [GitHub Enterprise](https://github.com/enterprise), an AI developer platform +- [GitHub blog](https://github.blog/), mostly a set of tutorials and informational articles regarding GitHub + +and the list just goes on. + +GitHub isn't just a public place to view open-source software anymore, if you are a novice developer or you just don't care that much, it will be very easy to associate the FOSS community with the GitHub community. +Once you've started using all of those services and tools, there is no coming back, because other repository platforms focus only on repositories. + +I mean, [GitLab](https://gitlab.com/) doesn't offer a developer forum like [GitHub Discussions](https://docs.github.com/en/discussions/collaborating-with-your-community-using-discussions/about-discussions), you won't find a [sourcehut](https://sourcehut.org/)-branded FOSS newsletter, [SourceForge](https://sourceforge.net/) won't allow you to add [animations, graphics, games, etc. on your profile](https://github.com/abhisheknaiidu/awesome-github-profile-readme), there isn't a [codeberg](https://codeberg.org/) [command-line repository management app](https://cli.github.com/), so *obviously GitHub is where it's at for FOSS*. + +And you'll be introduced to GitHub before any of the others, thanks to the [GitHub Student Developer Pack](https://education.github.com/pack), where students can get free access to a variety of services, or to [GitHub classroom](https://docs.github.com/en/education/manage-coursework-with-github-classroom/get-started-with-github-classroom/about-github-classroom), where newer developers will probably publish their first pieces of code. + +Why learn to use the git terminal command when [GitHub Desktop](https://desktop.github.com/) abstract everything away in a beautiful clicky interface (as a "bonus", this will make you associate git with GitHub too), why follow [Hacker News](https://news.ycombinator.com/) or multiple different FOSS websites, when Microsoft provides. + +Why learn anything, when Microsoft's GitHub serves it to you on a silver platter? +Well, for an increasing number of developers, I fear, the answer is: "there is no point". + +## Blowtorch to the penguin + +Now let's talk about Microsoft's other plaything: Linux. +Here, I feel, the tactic is even more obvious: thanks to [WSL](https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux), Linux applications look and run like any other Windows app. +Thanks to [Windows Terminal](https://en.wikipedia.org/wiki/Windows_Terminal), Windows can't be seen as a lesser OS for developers, all benefits of having a proper, fully-fledged, UNIX-like command-line can now be found on Windows. + +I mean, they've added the sudo command for crying out loud, there is even an official [Windows package manager](https://en.wikipedia.org/wiki/Windows_Package_Manager)! + +For a novice or someone uninterested, you wouldn't ever have to learn how to use Linux. +You'll use Windows as you've known for your entire life, and if you need something even vaguely related to Linux, you'll just easily get it on another silver platter. +I'm certain over the coming decade, the true Linux desktop market share, as in machines running natively Linux, will shrink, but since WSL users will contribute to that number, we'll see the opposite. + + +## But these are good things for the user + +It could be argued that Microsoft is creating something good for the user, that GitHub's extensions will pull more people into FOSS, it will make developers stronger and more connected than ever. +You could argue that integrating Linux into Windows just gives you the best of both worlds, that for a user you don't have to chose anymore, but reap the benefits of both OSs. +Why should any of this be seen as a problem? + +### The practical answer + +The whole point of FOSS is to oppose business, to oppose the idea that everything is a product which must be sold, which must be unchangeable and fully under the control of the company who made it. +A product which can be changed and regulated to feed the bottomless greed of businessmen. +If everyone thinks Microsoft equals FOSS, then they can start changing that definition and people will follow. + +I can easily imagine a future where, all of a sudden, you can view GitHub repositories only if you have a GitHub account, when it will be on a subscription, when to access Microsoft's open-source projects you need to go through some enlisting process (similar to that for Unreal Engine), when Microsoft adds some sort of authentication mechanism, where you cannot run modified versions of certain FOSS projects (so even if you have the source code, and can modify and compile it, you cannot run the executable, forcing you to use the official version only). + +If everyone thinks Linux is found in Windows, then developers will focus on integrating it better with Windows, until most new Linux software is somehow available only through WSL, but doesn't work on distributions. +It's tempting to imagine Linux software or Linux projects turn into Windows software and Windows projects, when less and less people try to make something new, something good, something for everyone, and more and more create proprietary garbage. + +### The moral answer + +[We do things, not because they are easy, but because they are hard](https://en.wikipedia.org/wiki/We_choose_to_go_to_the_Moon). +Knowledge is the most important resource we have, everything humanity has achieved has been with the creation, expansion and distribution of knowledge. +Developers are the craftsmen of computer software and to create you need knowledge, the more you have the more you can do. + +Tools we make must be used to make our job easier, but we must be able, or at least understand, how to do the job without the tool. +Walking down this path, at a certain point, entire concepts can become forgotten to history, which makes developers worse at their craft, and software worse to use. diff --git a/src/darkmode.css b/src/darkmode.css index c8dc59d..64a6a53 100644 --- a/src/darkmode.css +++ b/src/darkmode.css @@ -38,9 +38,9 @@ } #scrollBtn { - background-color: var(--bg-color); - } + background-color: var(--bg-color); +} @media print { - body, article { background-color: var(--bg-color) } - } + body, article { background-color: var(--bg-color) } +} diff --git a/src/favicon.ico b/src/favicon.ico Binary files differnew file mode 100644 index 0000000..79143ba --- /dev/null +++ b/src/favicon.ico diff --git a/src/img/face.jpeg b/src/img/face.jpeg Binary files differindex 977b9fb..ef89a01 100644 --- a/src/img/face.jpeg +++ b/src/img/face.jpeg diff --git a/src/img/favicon.ico b/src/img/favicon.ico Binary files differnew file mode 100644 index 0000000..79143ba --- /dev/null +++ b/src/img/favicon.ico diff --git a/src/img/favicon.png b/src/img/favicon.png Binary files differdeleted file mode 100644 index 01863d8..0000000 --- a/src/img/favicon.png +++ /dev/null diff --git a/src/index.md b/src/index.md index 6d99115..c4da21c 100644 --- a/src/index.md +++ b/src/index.md @@ -15,18 +15,20 @@ Have a look around and enjoy your stay! <br> -<a class="borderless" href="https://www.vim.org/"><img class="oldschool-badge unzoomable" src="./img/created.with.vim.gif" alt="Created With VIM"></a> -<a class="borderless" href="https://www.anybrowser.org/campaign/"><img class="oldschool-badge unzoomable" src="./img/abasat.gif" alt="Viewable With Any Browser"></a> -<a class="borderless" href="https://spyware.neocities.org/"><img class="oldschool-badge unzoomable" src="./img/watchdog.png" alt="Spyware Watchdog"></a> -<a class="borderless" href="https://observatory.mozilla.org/analyze/syndamia.com"><img class="borderless unzoomable" src="/img/mozilla-observatory.png" alt="Mozilla Observatory Score"></a> -<a class="borderless" href="https://securityheaders.com/?q=syndamia.com&followRedirects=on"><img class="borderless unzoomable" src="/img/security-headers.png" alt="Security Headers Score"></a> -<a class="borderless" href="https://www.ssllabs.com/ssltest/analyze.html?d=syndamia.com"><img class="borderless unzoomable" src="/img/ssl-labs.png" alt="SSL Report"></a> +<a class="borderless" href="https://www.vim.org/"><img class="oldschool-badge" src="./img/created.with.vim.gif" alt="Created With VIM"></a> +<a class="borderless" href="https://www.anybrowser.org/campaign/"><img class="oldschool-badge" src="./img/abasat.gif" alt="Viewable With Any Browser"></a> +<a class="borderless" href="https://spyware.neocities.org/"><img class="oldschool-badge" src="./img/watchdog.png" alt="Spyware Watchdog"></a> +<a class="borderless" href="https://observatory.mozilla.org/analyze/syndamia.com"><img class="borderless" src="/img/mozilla-observatory.png" alt="Mozilla Observatory Score"></a> +<a class="borderless" href="https://securityheaders.com/?q=syndamia.com&followRedirects=on"><img class="borderless" src="/img/security-headers.png" alt="Security Headers Score"></a> +<a class="borderless" href="https://www.ssllabs.com/ssltest/analyze.html?d=syndamia.com"><img class="borderless" src="/img/ssl-labs.png" alt="SSL Report"></a> ### Keyboard navigation (requires javascript) |Key|Available|Action| |---|---------|------| |C |Everywhere|Toggles the theme between light and dark| +|W |Everywhere|Toggles the page width| +|E |Everywhere|Expands/shrinks the sidebar| |K, Backspace, PageUp, Left arrow, Up arrow|Presentations|Go to previous slide| |J, Spacebar, Enter key, PageDown, Right arrow, Down arrow|Presentations|Go to next slide| |P, T|Presentations|Start or stop (toggle) presenting| diff --git a/src/misc.md b/src/misc.md index caf61d7..876a4ee 100644 --- a/src/misc.md +++ b/src/misc.md @@ -6,8 +6,8 @@ Other types of content I've made, including documents, images, videos and web de #### 2022 -&&ft-text 19.09   [Университетски бележки](/misc/universitetski-belejki) +&.ft-text 19.09   [Университетски бележки](/misc/universitetski-belejki) : Различни материали, които съм правил през следването ми във ФМИ -&&ft-photo 16.07   [Layout engines and browsers](/files/misc/Layout%20engines%20and%20browsers.svg) +&.ft-photo 16.07   [Layout engines and browsers](/files/misc/Layout%20engines%20and%20browsers.svg) : A diagram which roughly outlines the main layout engines throughout the web's history diff --git a/src/misc/index.md b/src/misc/index.md index caf61d7..876a4ee 100644 --- a/src/misc/index.md +++ b/src/misc/index.md @@ -6,8 +6,8 @@ Other types of content I've made, including documents, images, videos and web de #### 2022 -&&ft-text 19.09   [Университетски бележки](/misc/universitetski-belejki) +&.ft-text 19.09   [Университетски бележки](/misc/universitetski-belejki) : Различни материали, които съм правил през следването ми във ФМИ -&&ft-photo 16.07   [Layout engines and browsers](/files/misc/Layout%20engines%20and%20browsers.svg) +&.ft-photo 16.07   [Layout engines and browsers](/files/misc/Layout%20engines%20and%20browsers.svg) : A diagram which roughly outlines the main layout engines throughout the web's history diff --git a/src/misc/universitetski-belejki/index.md b/src/misc/universitetski-belejki/index.md index 8e1ed85..560e63e 100644 --- a/src/misc/universitetski-belejki/index.md +++ b/src/misc/universitetski-belejki/index.md @@ -13,20 +13,20 @@ ### Алгебра 1 -&&ft-text [Разписани теми за устен изпит](/files/misc/uni-notes/algebra1/topics.pdf)   [източник](https://gitlab.com/Syndamia/uni-projects/-/blob/main/Year%201/Algebra/Topics/) [\*](#*) +&.ft-text [Разписани теми за устен изпит](/files/misc/uni-notes/algebra1/topics.pdf)   [източник](https://gitlab.com/Syndamia/uni-projects/-/blob/main/Year%201/Algebra/Topics/) [\*](#*) : Всичките теми, които имах да разписвам за устния изпит. Нещата са взети кажи-речи директно от лекции. ### Диференциално и интегрално смятане 1 -&&ft-text [Записки върху материала](/files/misc/uni-notes/dis1/notes.pdf)   [източник](https://gitlab.com/Syndamia/uni-projects/-/blob/main/Year%201/Calculus/) [\*](#*) +&.ft-text [Записки върху материала](/files/misc/uni-notes/dis1/notes.pdf)   [източник](https://gitlab.com/Syndamia/uni-projects/-/blob/main/Year%201/Calculus/) [\*](#*) : Главните дефиниции, формулировки на теореми и формули, които поне аз сметнах за достатъчни по ДИС 2. Обхваща материала от лекция 1 до 13 включително. -&&ft-text [Основни доказателства](/files/misc/uni-notes/dis1/notes-appendix.pdf)   [източник](https://gitlab.com/Syndamia/uni-projects/-/blob/main/Year%201/Calculus/) [\*](#*) +&.ft-text [Основни доказателства](/files/misc/uni-notes/dis1/notes-appendix.pdf)   [източник](https://gitlab.com/Syndamia/uni-projects/-/blob/main/Year%201/Calculus/) [\*](#*) : По-важните доказателства от лекции, като съм се опитал да ги формулирам по по-разбираем за мен начин. Не е завършено, напълно обхваща само лекции 1 до 5 и от части лекции 6, 8 и 9. ### Дискретни структури -&&ft-text [Записки върху материала](/files/misc/uni-notes/dstr/notes.pdf)   [източник](https://gitlab.com/Syndamia/uni-projects/-/blob/main/Year%201/Discrete%20math/) [\*](#*) +&.ft-text [Записки върху материала](/files/misc/uni-notes/dstr/notes.pdf)   [източник](https://gitlab.com/Syndamia/uni-projects/-/blob/main/Year%201/Discrete%20math/) [\*](#*) : Съществените за мен дефиниции, формулировки на теореми и формули. Обхваща лекции 1 до 7 включително. <br> diff --git a/src/presentation.css b/src/presentation.css index cc82b04..a508f23 100644 --- a/src/presentation.css +++ b/src/presentation.css @@ -1,157 +1,171 @@ -/* These styles are located here for easy retrieval in JS */ +/*## These styles are located here for easy retrieval in JS ##*/ .slide { - box-sizing: border-box; - height: 210mm; - padding: 1em; - width: 297mm; /* Size of landscape A4 paper */ - font-size: 30px; - transform-origin: 0 0; - margin-bottom: 1em; - } + box-sizing: border-box; + height: 210mm; + padding: 30px; + width: 297mm; /* Size of landscape A4 paper */ + font-size: 30px; + transform-origin: 0 0; + margin-bottom: 30px; +} .absolute-slide { - border: none !important; - left: 50%; - margin: 0 auto; - position: absolute; - right: 0; - top: 50%; - transform: translate(-50%, -50%); - transform-origin: center center; - visibility: visible; - } - .absolute-slide .clicked-image { - left: 50%; - top: 50%; - transform: translate(-50%, -50%); - } - -/* Stylesheet override */ + border: none !important; + left: 50%; + margin: 0 auto; + position: absolute; + right: 0; + top: 50%; + transform: translate(-50%, -50%); + transform-origin: center center; + visibility: visible; +} +.absolute-slide .clicked-image { + left: 50%; + top: 50%; + transform: translate(-50%, -50%); +} -/* Presentation controller */ +/*## Presentation controller ##*/ #presentCont { margin: 0.5em 0.5em 0.5em 0; } - #presentCont > span { font-size: 1.4em; } - /* Presenting mode */ - #presentCont { display: initial; } +#presentCont > span { font-size: 1.4em; } +/* Presenting mode */ +#presentCont { display: initial; } -/* Slides styles +/*## Slide ##*/ -.slide {...} */ - .slide img:not(.clicked-image) { - height: auto; - max-height: 100%; - max-width: 100%; - /* width: auto; */ - } - .slide:not(.absolute-slide) img { pointer-events: none; } - .slide td { font: inherit; } - .slide > *:first-child, .slide > div:only-child > *:first-child, - .slide > ul:first-child > li:first-child > *:first-child, - .slide > div:only-child > ul:first-child > li:first-child > *:first-child, - .slide > ol:first-child > li:first-child > *:first-child, - .slide > div:only-child > ol:first-child > li:first-child > *:first-child { - margin-top: 0; - } - .slide ul, .slide ol { padding-inline-start: 30px; } - .slide .svg { max-height: 1em !important; } - .slide h2, .slide h3, .slide h4, .slide h5, .slide h6 { - display: block; - margin-block-start: 0; - margin-block-end: 0.5em; - } - .slide .h-anchor, .slide .gap, .slide .gap-small { display: none; } +.centered-slide { display: flex; flex-direction: column; } +.centered-slide > * { flex: 1; } - .clide { display: flex; flex-direction: column; } - .clide > * { flex: 1; } +/*### Slide > * ###*/ - .centered, - .centered .width5, .centered .width10, .centered .width15, .centered .width20, - .centered .width25, .centered .width30, .centered .width35, .centered .width40, - .centered .width45, .centered .width50, .centered .width55, .centered .width60, - .centered .width65, .centered .width70, .centered .width75, .centered .width80, - .centered .width85, .centered .width90, .centered .width95 - { margin-left: auto; margin-right: auto; text-align: center; } - .fright { float: right; text-align: right; } - * + .fright { margin-left: 1em; } +.slide img:not(.clicked-image) { + height: auto; + max-height: 100%; + max-width: 100%; + /* width: auto; */ +} - .layout-table { - margin: 0; - padding: 0; - display: table; - width: 100%; - } - .layout-table > .layout-row { - display: table-row; - } - .layout-row > * { - display: table-cell; - border: none; - padding: 0.1em; - vertical-align: middle; - } - .layout-row li { margin-left: 30px; } - .fixed-layout { table-layout: fixed; } +.slide > *:first-child, .slide > div:only-child > *:first-child, +.slide > ul:first-child > li:first-child > *:first-child, +.slide > div:only-child > ul:first-child > li:first-child > *:first-child, +.slide > ol:first-child > li:first-child > *:first-child, +.slide > div:only-child > ol:first-child > li:first-child > *:first-child +{ + margin-top: 0; +} - .font18 { font-size: 18px; } - .font20 { font-size: 20px; } - .font22 { font-size: 22px; } - .font25 { font-size: 25px; } - .font27 { font-size: 27px; } - .font35 { font-size: 35px; } +.slide:not(.absolute-slide) img { pointer-events: none; } +.slide td { font: inherit; } +.slide ul, .slide ol { padding-inline-start: 30px; margin: 0; } +.slide .svg { max-height: 1em !important; } +.slide h2, .slide h3, .slide h4, .slide h5, .slide h6 { + display: block; + margin-block-start: 0; + margin-block-end: 0.5em; +} +.slide .h-anchor, .slide .gap, .slide .gap-small { display: none; } - .lineb1 { padding: 0.5em; } - .lineb2 { padding: 1.0em; } - .lineb3 { padding: 1.5em; } - .lineb4 { padding: 2.0em; } - .lineb5 { padding: 2.5em; } - .lineb6 { padding: 3.0em; } - .lineb7 { padding: 3.5em; } - .lineb8 { padding: 4.0em; } - .lineb9 { padding: 4.5em; } +/*### Slide > centered, width ###*/ - .width5 { width: 5%; } - .width10 { width: 10%; } - .width15 { width: 15%; } - .width20 { width: 20%; } - .width25 { width: 25%; } - .width30 { width: 30%; } - .width35 { width: 35%; } - .width40 { width: 40%; } - .width45 { width: 45%; } - .width50 { width: 50%; } - .width55 { width: 55%; } - .width60 { width: 60%; } - .width65 { width: 65%; } - .width70 { width: 70%; } - .width75 { width: 75%; } - .width80 { width: 80%; } - .width85 { width: 85%; } - .width90 { width: 90%; } - .width95 { width: 95%; } +.centered, +.centered .width5per, .centered .width10per, .centered .width15per, .centered .width20per, +.centered .width25per, .centered .width30per, .centered .width35per, .centered .width40per, +.centered .width45per, .centered .width50per, .centered .width55per, .centered .width60per, +.centered .width65per, .centered .width70per, .centered .width75per, .centered .width80per, +.centered .width85per, .centered .width90per, .centered .width95per +{ + margin-left: auto; + margin-right: auto; + text-align: center; +} -/* Presenting mode +.width5per { width: 5%; } +.width10per { width: 10%; } +.width15per { width: 15%; } +.width20per { width: 20%; } +.width25per { width: 25%; } +.width30per { width: 30%; } +.width35per { width: 35%; } +.width40per { width: 40%; } +.width45per { width: 45%; } +.width50per { width: 50%; } +.width55per { width: 55%; } +.width60per { width: 60%; } +.width65per { width: 65%; } +.width70per { width: 70%; } +.width75per { width: 75%; } +.width80per { width: 80%; } +.width85per { width: 85%; } +.width90per { width: 90%; } +.width95per { width: 95%; } -absolute-slide {...} */ - .invisible { visibility: hidden; } - .no-overflow { overflow: hidden; } - .body-bg-color { background-color: var(--bg-color); } +/*### Slide > float-right ###*/ + +.float-right { float: right; text-align: right; } +* + .float-right { margin-left: 1em; } + +/*### Slide > layout table ###*/ + +.layout-table { + margin: 0; + padding: 0; + display: table; + width: 100%; +} +.layout-table > .layout-row { + display: table-row; +} +.layout-row > * { + display: table-cell; + border: none; + padding: 0.1em; + vertical-align: middle; +} +.layout-row li { margin-left: 30px; } +.fixed-layout { table-layout: fixed; } + +/*### Slide > font, br ###*/ + +.font18 { font-size: 18px; } +.font20 { font-size: 20px; } +.font22 { font-size: 22px; } +.font25 { font-size: 25px; } +.font27 { font-size: 27px; } +.font35 { font-size: 35px; } + +.br1 { padding: 0.5em; } +.br2 { padding: 1.0em; } +.br3 { padding: 1.5em; } +.br4 { padding: 2.0em; } +.br5 { padding: 2.5em; } +.br6 { padding: 3.0em; } +.br7 { padding: 3.5em; } +.br8 { padding: 4.0em; } +.br9 { padding: 4.5em; } + +/*## Presenting ##*/ + +.invisible { visibility: hidden; } +.no-overflow { overflow: hidden; } +.body-bg-color { background-color: var(--bg-color); } .absolute-cont { - bottom: 0; - opacity: 0.4; - position: absolute; - right: 0; - transition: opacity 0.5s linear 0s; - visibility: visible; - z-index: 10; - } - .absolute-cont:hover { opacity: 0.4; } - /* In case your browser doesn't support :hover */ - .absolute-cont:not(:hover) { opacity: 0; } - #slideIndex { border: none; font-size: 1.6em; } + bottom: 0; + opacity: 0.4; + position: absolute; + right: 0; + transition: opacity 0.5s linear 0s; + visibility: visible; + z-index: 10; +} +.absolute-cont:hover { opacity: 0.4; } +/* In case your browser doesn't support :hover */ +.absolute-cont:not(:hover) { opacity: 0; } +#slideIndex { border: none; font-size: 1.6em; } -/* Media specific stylings */ +/*## Media specific stylings ##*/ @media screen { .slide { diff --git a/src/preserved-media.md b/src/preserved-media.md index 30c8782..c7ada8e 100644 --- a/src/preserved-media.md +++ b/src/preserved-media.md @@ -6,8 +6,8 @@ If you are an owner of something listed here, [contact me](/about) and I'll remo <br> -&&ft-zip 22.09.2022   [Reconstructed source](/files/media/BrilliantButtonMaker-LucaZappa-updated.zip) of Luca Zappa's Brilliant Button Maker +&.ft-zip 22.09.2022   [Reconstructed source](/files/media/BrilliantButtonMaker-LucaZappa-updated.zip) of Luca Zappa's Brilliant Button Maker : Using what archive.org had, I reconstructed most of the source code for the "Brilliant Button Maker" by [Luca Zappa](https://www.linkedin.com/in/lucazappa/). I also host it [here](https://hob.syndamia.com/brilliant-button-maker/). -&&ft-text 14.10.1991   [Прибор электроизмерительный комбинированный типа 43208-У](/files/media/43208-%D0%A3/43208-%D0%A3.pdf) +&.ft-text 14.10.1991   [Прибор электроизмерительный комбинированный типа 43208-У](/files/media/43208-%D0%A3/43208-%D0%A3.pdf) : A scanned manual (in Russian) for the Soviet Analog Multimeter [43208-У](http://radioamator.ru/izmereniya/multimetry-testery/221-kombinirovannyj-pribor-43208-u-osobennosti-skhemy-i-remonta) diff --git a/src/preserved-media/index.md b/src/preserved-media/index.md index 30c8782..c7ada8e 100644 --- a/src/preserved-media/index.md +++ b/src/preserved-media/index.md @@ -6,8 +6,8 @@ If you are an owner of something listed here, [contact me](/about) and I'll remo <br> -&&ft-zip 22.09.2022   [Reconstructed source](/files/media/BrilliantButtonMaker-LucaZappa-updated.zip) of Luca Zappa's Brilliant Button Maker +&.ft-zip 22.09.2022   [Reconstructed source](/files/media/BrilliantButtonMaker-LucaZappa-updated.zip) of Luca Zappa's Brilliant Button Maker : Using what archive.org had, I reconstructed most of the source code for the "Brilliant Button Maker" by [Luca Zappa](https://www.linkedin.com/in/lucazappa/). I also host it [here](https://hob.syndamia.com/brilliant-button-maker/). -&&ft-text 14.10.1991   [Прибор электроизмерительный комбинированный типа 43208-У](/files/media/43208-%D0%A3/43208-%D0%A3.pdf) +&.ft-text 14.10.1991   [Прибор электроизмерительный комбинированный типа 43208-У](/files/media/43208-%D0%A3/43208-%D0%A3.pdf) : A scanned manual (in Russian) for the Soviet Analog Multimeter [43208-У](http://radioamator.ru/izmereniya/multimetry-testery/221-kombinirovannyj-pribor-43208-u-osobennosti-skhemy-i-remonta) diff --git a/src/preserved-web-pages.md b/src/preserved-web-pages.md index 9b8d3b2..db3fa83 100644 --- a/src/preserved-web-pages.md +++ b/src/preserved-web-pages.md @@ -6,5 +6,5 @@ If you are an owner of something listed here, [contact me](/about) and I'll remo <br> -&&ft-browser 2005   [Brilliant Button Maker](https://hob.syndamia.com/brilliant-button-maker/) by Luca Zappa   [source code](https://syndamia.com/files/hob/BrilliantButtonMaker-LucaZappa-updated.zip) +&.ft-browser 2005   [Brilliant Button Maker](https://hob.syndamia.com/brilliant-button-maker/) by Luca Zappa   [source code](https://syndamia.com/files/hob/BrilliantButtonMaker-LucaZappa-updated.zip) : A nice web button maker from the 2000s, written in PHP. Since it was no longer available, I found and fixed up most of the PHP that archive.org saved. diff --git a/src/preserved-web-pages/index.md b/src/preserved-web-pages/index.md index 9b8d3b2..db3fa83 100644 --- a/src/preserved-web-pages/index.md +++ b/src/preserved-web-pages/index.md @@ -6,5 +6,5 @@ If you are an owner of something listed here, [contact me](/about) and I'll remo <br> -&&ft-browser 2005   [Brilliant Button Maker](https://hob.syndamia.com/brilliant-button-maker/) by Luca Zappa   [source code](https://syndamia.com/files/hob/BrilliantButtonMaker-LucaZappa-updated.zip) +&.ft-browser 2005   [Brilliant Button Maker](https://hob.syndamia.com/brilliant-button-maker/) by Luca Zappa   [source code](https://syndamia.com/files/hob/BrilliantButtonMaker-LucaZappa-updated.zip) : A nice web button maker from the 2000s, written in PHP. Since it was no longer available, I found and fixed up most of the PHP that archive.org saved. diff --git a/src/scripts/expand-navbar.js b/src/scripts/expand-navbar.js index 4cea31c..988d211 100644 --- a/src/scripts/expand-navbar.js +++ b/src/scripts/expand-navbar.js @@ -1,15 +1,15 @@ const expandBtn = document.getElementById('expandNavbarBtn'); -const sidebarElem = document.getElementById('sidebar'); +const wrapperElem = document.getElementById('content-wrapper'); if (localStorage.getItem('navbar') === 'hidden' || window.innerWidth <= 610 || window.innerHeight <= 610) { expandBtn.innerText = '\u25BC'; - sidebarElem.classList.add('sidebar-hidden'); + wrapperElem.classList.add('content-wrapper-vertical'); } expandBtn.onclick = function() { - sidebarElem.classList.toggle('sidebar-hidden'); + wrapperElem.classList.toggle('content-wrapper-vertical'); - if (!sidebarElem.classList.contains('sidebar-hidden')) { + if (!wrapperElem.classList.contains('content-wrapper-vertical')) { expandBtn.innerText = '\u25B2'; // triangle pointing up if (window.innerWidth > 610) localStorage.setItem('navbar', 'norm'); } diff --git a/src/scripts/image-show.js b/src/scripts/image-show.js deleted file mode 100644 index 8664ef4..0000000 --- a/src/scripts/image-show.js +++ /dev/null @@ -1,24 +0,0 @@ -let scrollPosition = 0; - -function clickToView() { - if (scrollPosition === 0) { - scrollPosition = window.scrollY; - window.scrollTo(0, 0); - } - - this.classList.toggle('clicked-image'); - document.body.classList.toggle('body-on-clicked-image'); - - if (!this.classList.contains('clicked-image')) { - window.scrollTo(0, scrollPosition); - scrollPosition = 0; - } -} - -const images = document.getElementsByTagName('img'); - -for (const image of images) { - if (image.alt !== '🔗' && !image.classList.contains('unzoomable')) { - image.onclick = clickToView; - } -} diff --git a/src/scripts/keyboard.js b/src/scripts/keyboard.js index bacbea1..1de93cf 100644 --- a/src/scripts/keyboard.js +++ b/src/scripts/keyboard.js @@ -2,11 +2,16 @@ document.addEventListener('keydown', function (e) { if (e.ctrlKey) return; switch (e.code) { - /* theme-changer.js */ - case 'KeyC': + case 'KeyC': // theme-changer.js themeBtn.click(); break; + case 'KeyW': // page-width.js + widthBtn.click(); + break; + case 'KeyE': // expand-navbar.js + expandBtn.click(); + break; /* presentation.js */ diff --git a/src/scripts/page-width.js b/src/scripts/page-width.js index 784c0f2..353dc4d 100644 --- a/src/scripts/page-width.js +++ b/src/scripts/page-width.js @@ -4,11 +4,11 @@ const articleElem = document.getElementsByTagName('article')[0]; if (localStorage.getItem('width') === 'wide') { widthLabel.innerText = 'Narrow'; - articleElem.classList.add('noMaxWidth'); + articleElem.classList.add('article-wide'); } widthBtn.onclick = function() { - articleElem.classList.toggle('noMaxWidth'); + articleElem.classList.toggle('article-wide'); if (localStorage.getItem('width') !== 'norm') { widthLabel.innerText = 'Wide'; diff --git a/src/setup.md b/src/setup.md index dc15b6f..eb09499 100644 --- a/src/setup.md +++ b/src/setup.md @@ -7,9 +7,11 @@ Here are mine. |Designation|OS |Motherboard / device|CPU|GPU|RAM| |-----------|---|------------------|---|---|---| -|Main desktop tower|Gentoo|ASRock Z97 Anniversary|[Intel Core i3-4160](https://www.intel.com/content/www/us/en/products/sku/77488/intel-core-i34160-processor-3m-cache-3-60-ghz/specifications.html)|AMD Sapphire Radeon R7 265|2x Corsair CMV8GX3M1A1600C11| +|Main desktop tower|NixOS (24.05)|ASRock B550 Phantom Gaming 4|[AMD Ryzen 9 5900X](https://www.amd.com/en/products/processors/desktops/ryzen/5000-series/amd-ryzen-9-5900x.html)|[AMD Radeon RX 6800 XT](https://www.amd.com/en/products/graphics/desktops/radeon/6000-series/amd-radeon-rx-6800-xt.html)|1x Corsair CMK32GX4M2E3200C16| +|||Bought: 2024|[39125 mark](https://www.cpubenchmark.net/cpu.php?cpu=AMD+Ryzen+9+5900X&id=3870), 12 cores, 24 threads, 3.70 GHz, L1: 768 KB, L2: 6 MB, L3: 64 MB, 64-bit|[25027 mark](https://www.videocardbenchmark.net/gpu.php?gpu=Radeon+RX+6800+XT&id=4312), 2000 MHz, 16 GB memory|DDR4, 32 GB (2x 16GB), 3200 MHz| +|Old desktop tower|NixOS (24.05)|ASRock Z97 Anniversary|[Intel Core i3-4160](https://www.intel.com/content/www/us/en/products/sku/77488/intel-core-i34160-processor-3m-cache-3-60-ghz/specifications.html)|AMD Sapphire Radeon R7 265|2x Corsair CMV8GX3M1A1600C11| |||Bought: 2015|[3510 mark](https://www.cpubenchmark.net/cpu.php?cpu=Intel+Core+i3-4160+%40+3.60GHz&id=2317), 2 cores, 4 threads, 3.60 GHz, L1: 128 KB, L2: 512 KB, L3: 3 MB, 64-bit|[3849 mark](https://www.videocardbenchmark.net/gpu.php?gpu=Radeon+HD+7850&id=323), 900 MHz, 2 GB memory|DDR3, 16 GB (2x 8GB), 1600 MHz -|Main laptop|NixOS (23.05)|Lenovo ThinkPad X270|Intel Core i5-6300U|Intel HD Graphics 520|1x Samsung M471A2k43BB1-CRC| +|Main laptop|NixOS (24.05)|Lenovo ThinkPad X270|Intel Core i5-6300U|Intel HD Graphics 520|1x Samsung M471A2k43BB1-CRC| |||Bought: 2023<br>Released: 2017|[3240 mark](https://www.cpubenchmark.net/cpu.php?cpu=Intel+Core+i5-6300U+%40+2.40GHz&id=2609), 2 cores, 4 threads, 2.40 GHz, L1: 128 KB, L2: 512 KB, L3: 3 MB, 64-bit|[871 mark](https://www.videocardbenchmark.net/gpu.php?gpu=Intel+HD+520&id=3255), 300 MHz|DDR4, SODIMM, 16 GB, 2133 MHz| |Second laptop|NixOS (23.05)|Lenovo Yoga S730|Intel Core i7-8565U|Intel UHD Graphics 620|2x Samsung K4EBE304EC-EGCG| |||Bought: 2019<br>Released: 2018|[6152 mark](https://www.cpubenchmark.net/cpu.php?cpu=Intel+Core+i7-8565U+%40+1.80GHz&id=3308), 4 cores, 8 threads, 4.60 GHz, L1: 128 KB, L2: 1 MB, L3: 8 MB, 64-bit|[1039 mark](https://www.videocardbenchmark.net/gpu.php?gpu=Intel+UHD+Graphics+620&id=3805), 300 MHz|LPDDR3 (soldered), 16 GB, 2133 MHz| @@ -29,6 +31,7 @@ Here are mine. |Distro|Fully switched|Configuration files/scripts| |------|--------------|-------------| |**Desktop OS**||| +|NixOS|11.2023|[NixOS configuration](https://gitlab.com/Syndamia/nix) |Gentoo|03.2023|[portage configuration files](https://gitlab.com/Syndamia/dotfiles/-/tree/main/.b/etc/portage), [Installation Makefile](https://gitlab.com/Syndamia/application-setup/-/blob/main/gentoo/Makefile) |Funtoo|12.2021|[portage configuration files](https://gitlab.com/Syndamia/dotfiles/-/tree/ef18469c90c8e90d3db436a1a204aec5c92cac73/.b/etc/portage) |Fedora 33-34|12.2020|[Installation from Minimal](https://gitlab.com/Syndamia/application-setup/-/blob/main/scratch-fedora-setup.sh), [Installation from Cinnamon](https://gitlab.com/Syndamia/application-setup/-/blob/main/fedora-setup.sh), [Cinnamon setup](https://gitlab.com/Syndamia/application-setup/-/tree/main/cinnamon-setup), [openbox setup](https://gitlab.com/Syndamia/dotfiles/-/blob/main/.c/fedora-openbox.sh) @@ -41,11 +44,19 @@ Here are mine. [Dotfiles here](https://gitlab.com/Syndamia/dotfiles). Primary shell is [zsh](https://www.zsh.org/). -For desktop environment, I used [Cinnamon](https://projects.linuxmint.com/cinnamon/), until 06.2021 (midway during Fedora usage), after which I created a custom configuration, based around the [openbox](http://openbox.org/wiki/Main_Page) window manager. -Exact programs used for my "desktop environment" can be found [here](https://gitlab.com/Syndamia/dotfiles/-/blob/main/.c/Application%20Stack.md). +### Desktop environment -## Software development +|Name|Fully switched|List of apps| +|----|--------------|------------| +|[openbox wm](http://openbox.org/wiki/Main_Page) + custom apps|06.2021|[Application Stack](https://gitlab.com/Syndamia/dotfiles/-/blob/main/.c/Application%20Stack.md) +|[Cinnamon](https://projects.linuxmint.com/cinnamon/)|12.2019|-| -My primary text editor is [vim](https://www.vim.org/), though I have used [Visual Studio](https://visualstudio.microsoft.com/), [Monodevelop](https://www.monodevelop.com/) and a little bit of [Visual Studio Code](https://code.visualstudio.com/) and [Atom](https://en.wikipedia.org/wiki/Atom_%28text_editor%29). +## Text editor -Vim configuration [here](https://gitlab.com/Syndamia/dotfiles/-/tree/main/.vim). +|Name|Fully switched|Configuration files| +|----|--------------|-------------------| +|[neovim](https://neovim.io/)|08.2024|[anderson](https://gitlab.com/Syndamia/anderson/)| +|[vim](https://www.vim.org/)|10.2020|[dotfiles](https://gitlab.com/Syndamia/dotfiles/-/tree/main/.vim)| +|[Atom](https://en.wikipedia.org/wiki/Atom_%28text_editor%29)|05.2020 - 07.2020|Switched back after| +|[Monodevelop](https://www.monodevelop.com/)|01.2020|- +|[Visual Studio 2017](https://visualstudio.microsoft.com/)|11.2018|- diff --git a/src/setup/index.md b/src/setup/index.md index dc15b6f..eb09499 100644 --- a/src/setup/index.md +++ b/src/setup/index.md @@ -7,9 +7,11 @@ Here are mine. |Designation|OS |Motherboard / device|CPU|GPU|RAM| |-----------|---|------------------|---|---|---| -|Main desktop tower|Gentoo|ASRock Z97 Anniversary|[Intel Core i3-4160](https://www.intel.com/content/www/us/en/products/sku/77488/intel-core-i34160-processor-3m-cache-3-60-ghz/specifications.html)|AMD Sapphire Radeon R7 265|2x Corsair CMV8GX3M1A1600C11| +|Main desktop tower|NixOS (24.05)|ASRock B550 Phantom Gaming 4|[AMD Ryzen 9 5900X](https://www.amd.com/en/products/processors/desktops/ryzen/5000-series/amd-ryzen-9-5900x.html)|[AMD Radeon RX 6800 XT](https://www.amd.com/en/products/graphics/desktops/radeon/6000-series/amd-radeon-rx-6800-xt.html)|1x Corsair CMK32GX4M2E3200C16| +|||Bought: 2024|[39125 mark](https://www.cpubenchmark.net/cpu.php?cpu=AMD+Ryzen+9+5900X&id=3870), 12 cores, 24 threads, 3.70 GHz, L1: 768 KB, L2: 6 MB, L3: 64 MB, 64-bit|[25027 mark](https://www.videocardbenchmark.net/gpu.php?gpu=Radeon+RX+6800+XT&id=4312), 2000 MHz, 16 GB memory|DDR4, 32 GB (2x 16GB), 3200 MHz| +|Old desktop tower|NixOS (24.05)|ASRock Z97 Anniversary|[Intel Core i3-4160](https://www.intel.com/content/www/us/en/products/sku/77488/intel-core-i34160-processor-3m-cache-3-60-ghz/specifications.html)|AMD Sapphire Radeon R7 265|2x Corsair CMV8GX3M1A1600C11| |||Bought: 2015|[3510 mark](https://www.cpubenchmark.net/cpu.php?cpu=Intel+Core+i3-4160+%40+3.60GHz&id=2317), 2 cores, 4 threads, 3.60 GHz, L1: 128 KB, L2: 512 KB, L3: 3 MB, 64-bit|[3849 mark](https://www.videocardbenchmark.net/gpu.php?gpu=Radeon+HD+7850&id=323), 900 MHz, 2 GB memory|DDR3, 16 GB (2x 8GB), 1600 MHz -|Main laptop|NixOS (23.05)|Lenovo ThinkPad X270|Intel Core i5-6300U|Intel HD Graphics 520|1x Samsung M471A2k43BB1-CRC| +|Main laptop|NixOS (24.05)|Lenovo ThinkPad X270|Intel Core i5-6300U|Intel HD Graphics 520|1x Samsung M471A2k43BB1-CRC| |||Bought: 2023<br>Released: 2017|[3240 mark](https://www.cpubenchmark.net/cpu.php?cpu=Intel+Core+i5-6300U+%40+2.40GHz&id=2609), 2 cores, 4 threads, 2.40 GHz, L1: 128 KB, L2: 512 KB, L3: 3 MB, 64-bit|[871 mark](https://www.videocardbenchmark.net/gpu.php?gpu=Intel+HD+520&id=3255), 300 MHz|DDR4, SODIMM, 16 GB, 2133 MHz| |Second laptop|NixOS (23.05)|Lenovo Yoga S730|Intel Core i7-8565U|Intel UHD Graphics 620|2x Samsung K4EBE304EC-EGCG| |||Bought: 2019<br>Released: 2018|[6152 mark](https://www.cpubenchmark.net/cpu.php?cpu=Intel+Core+i7-8565U+%40+1.80GHz&id=3308), 4 cores, 8 threads, 4.60 GHz, L1: 128 KB, L2: 1 MB, L3: 8 MB, 64-bit|[1039 mark](https://www.videocardbenchmark.net/gpu.php?gpu=Intel+UHD+Graphics+620&id=3805), 300 MHz|LPDDR3 (soldered), 16 GB, 2133 MHz| @@ -29,6 +31,7 @@ Here are mine. |Distro|Fully switched|Configuration files/scripts| |------|--------------|-------------| |**Desktop OS**||| +|NixOS|11.2023|[NixOS configuration](https://gitlab.com/Syndamia/nix) |Gentoo|03.2023|[portage configuration files](https://gitlab.com/Syndamia/dotfiles/-/tree/main/.b/etc/portage), [Installation Makefile](https://gitlab.com/Syndamia/application-setup/-/blob/main/gentoo/Makefile) |Funtoo|12.2021|[portage configuration files](https://gitlab.com/Syndamia/dotfiles/-/tree/ef18469c90c8e90d3db436a1a204aec5c92cac73/.b/etc/portage) |Fedora 33-34|12.2020|[Installation from Minimal](https://gitlab.com/Syndamia/application-setup/-/blob/main/scratch-fedora-setup.sh), [Installation from Cinnamon](https://gitlab.com/Syndamia/application-setup/-/blob/main/fedora-setup.sh), [Cinnamon setup](https://gitlab.com/Syndamia/application-setup/-/tree/main/cinnamon-setup), [openbox setup](https://gitlab.com/Syndamia/dotfiles/-/blob/main/.c/fedora-openbox.sh) @@ -41,11 +44,19 @@ Here are mine. [Dotfiles here](https://gitlab.com/Syndamia/dotfiles). Primary shell is [zsh](https://www.zsh.org/). -For desktop environment, I used [Cinnamon](https://projects.linuxmint.com/cinnamon/), until 06.2021 (midway during Fedora usage), after which I created a custom configuration, based around the [openbox](http://openbox.org/wiki/Main_Page) window manager. -Exact programs used for my "desktop environment" can be found [here](https://gitlab.com/Syndamia/dotfiles/-/blob/main/.c/Application%20Stack.md). +### Desktop environment -## Software development +|Name|Fully switched|List of apps| +|----|--------------|------------| +|[openbox wm](http://openbox.org/wiki/Main_Page) + custom apps|06.2021|[Application Stack](https://gitlab.com/Syndamia/dotfiles/-/blob/main/.c/Application%20Stack.md) +|[Cinnamon](https://projects.linuxmint.com/cinnamon/)|12.2019|-| -My primary text editor is [vim](https://www.vim.org/), though I have used [Visual Studio](https://visualstudio.microsoft.com/), [Monodevelop](https://www.monodevelop.com/) and a little bit of [Visual Studio Code](https://code.visualstudio.com/) and [Atom](https://en.wikipedia.org/wiki/Atom_%28text_editor%29). +## Text editor -Vim configuration [here](https://gitlab.com/Syndamia/dotfiles/-/tree/main/.vim). +|Name|Fully switched|Configuration files| +|----|--------------|-------------------| +|[neovim](https://neovim.io/)|08.2024|[anderson](https://gitlab.com/Syndamia/anderson/)| +|[vim](https://www.vim.org/)|10.2020|[dotfiles](https://gitlab.com/Syndamia/dotfiles/-/tree/main/.vim)| +|[Atom](https://en.wikipedia.org/wiki/Atom_%28text_editor%29)|05.2020 - 07.2020|Switched back after| +|[Monodevelop](https://www.monodevelop.com/)|01.2020|- +|[Visual Studio 2017](https://visualstudio.microsoft.com/)|11.2018|- diff --git a/src/slides.md b/src/slides.md index f5a368f..0a23cca 100644 --- a/src/slides.md +++ b/src/slides.md @@ -4,10 +4,12 @@ These are the different presentations I've made and possibly presented. <br> -&&gb 19 Jan   [Linuxgraphy by Strabo](./linuxgraphy-by-strabo)   *Last presented: 22.01.2023* +#### *2023* + +&.gb 19 Jan   [Linuxgraphy by Strabo](./linuxgraphy-by-strabo)   *Last presented: 22.01.2023* : A presentation talking about some of the history of UNIX and how Linux works #### *2022* -&&gb 27 Sep   [Demo presentation](./demo)   *Won't be presented* +&.gb 27 Sep   [Demo presentation](./demo)   *Won't be presented* : Showcase of my presentation system diff --git a/src/slides/demo/index.md b/src/slides/demo/index.md index ebe95bb..c9e26de 100644 --- a/src/slides/demo/index.md +++ b/src/slides/demo/index.md @@ -2,12 +2,14 @@ This is a small presentation, explaining how my custom system for making presentations works. -&&presentation +&:important This page is [due for rework](/rework.html), I've switched to MEL from ftags -&&clide &&font35 &¢ered +&.presentation + +&[title35 # My presentation system -&&font18 *Syndamia AT [syndamia.com](https://syndamia.com)* &&/font +&(font18 *Syndamia AT [syndamia.com](https://syndamia.com)* &) Before we go any further, click the **icon in the middle** right above this rectangle, to the left. @@ -15,15 +17,15 @@ Now the presentation should fill out the entire page. On the bottom right are yo Press the *right arrow* in the controls to go to the next slide. -&&/centered &&/font &&/clide +&] -&&slide &&font27 +&[slide27 # Key bindings -&&lineb3 +&.br3 |Action |Keyboard keys | |--------------------|-------------------------------------------------| @@ -34,15 +36,15 @@ Press the *right arrow* in the controls to go to the next slide. |Go to first slide | Home | |Go to last slide | End | -&&/font &&/slide +&] -&&slide +&[slide # Introduction -&&lineb1 +&.br1 I created a simple system for making presentations with slides in them. The gist of it is: different [Markdown](https://en.wikipedia.org/wiki/Markdown) paragraphs are put into a rectangle, each rectangle representing a slide, with some added options for layout and format. @@ -54,11 +56,11 @@ Each ftag is a "marker" that gets replaced by some other text (usually [HTML tag An easy example is the image of the Great Britain flag (part of [Flags.awk](https://gitlab.com/Syndamia/syndamiadotcom/-/blob/master/awk-edits/Flags.awk), not the presentation system!): typing out &&GB (in lowecase), gets replaced by the actual image - &&gb. -&&/slide +&] -&&slide +&[slide ## Why? @@ -74,11 +76,11 @@ An easy example is the image of the Great Britain flag (part of [Flags.awk](http Creating ftags that are transformed to DZSlide HTML is possible, but at that point I should just make my own system. + and pretty much everything else falls into either category -&&/slide +&] -&&slide +&[slide # Formatting @@ -87,7 +89,7 @@ To summarize, each slide is wrapped in `&&slide` and `&&/slide` (or `&&clide` an And they can work together in most different combination. -&&lineb1 +&.br1 Though, remember that everything gets translated to HTML, so don't do (even if it works) @@ -97,39 +99,39 @@ Though, remember that everything gets translated to HTML, so don't do (even if i Enough talking, here are examples! -&&/slide +&] -&&slide +&[slide -&&font18 Font-size 18px &&/font -&&font20 Font-size 20px &&/font &&font22 Font-size 22px &&/font &&font25 Font-size 25px &&/font +&(font18 Font-size 18px &) +&(font20 Font-size 20px &) &(font22 Font-size 22px &) &(font25 Font-size 25px &) Font-size 30px (default) -&&font35 Font-size 35px &&/font +&(font35 Font-size 35px &) -&&lineb5 +&.br5 -&&fright +&(fright This text is floated to the right -&&/fright +&) -&&lineb2 +&.br2 -&¢ered While this one is centered &&/centered +&(centered While this one is centered &) -&&lineb2 +&.br2 -&&fright Floated right<br>Floated right<br>Floated right &&/fright +&(fright Floated right<br>Floated right<br>Floated right &) But you may realize that text floated to the right will make other text wrap around it! Maybe this should be changed? -&&/slide +&] -&&slide &&font18 +&[slide18 The source Markdown for the predvious slide (without the pipes to the left) is: @@ -161,40 +163,40 @@ Maybe this should be changed? &&/slide ``` -&&/font &&/slide +&] -&&clide &&table +&[middle &{row You can also easily tabularize -&&cont &&fright +&{column &(fright - List Element 1 - List Element 2 -&&/fright &&/cont +&) &} -&&tarow +&.newrow **any** sort of content -&&/table +&} -&&lineb1 +&.br1 -&&ftable +&{sqrow So you can very easily put images next to your text -&¢ered  &&/centered +&(centered  &) -&&/table &&/clide +&} &] -&&slide &&font18 +&[slide18 The source Markdown for the predvious slide (without the pipes to the left) is: @@ -227,11 +229,11 @@ So you can very easily put images next to your text &&/table &&/clide ``` -&&/font &&/slide +&] -&&slide &&font27 +&[slide27 # Other features @@ -248,18 +250,16 @@ Everything is contained in 3 files: [Presentation.awk](https://gitlab.com/Syndam `Presentation.awk` handles replacement of ftags (only in `/talks` pages!). `presentation.js` is inserted into the HTML by `&&presentation`, and handles the navigation bar as well as insertion of `presentation.css` (the overall presentation-specific styling). -&&/font &&/slide +&] -&&clide +&[title -&¢ered # Thats All. Thank you for your time! -&&/centered -&&fright &&font18 +&(fright &(font18 *P.S. Press the same button (next to the print button) with which you started presenting, to stop presenting ;)* -&&/font &&/fright +&) &) -&&/clide +&] diff --git a/src/slides/index.md b/src/slides/index.md index f5a368f..0a23cca 100644 --- a/src/slides/index.md +++ b/src/slides/index.md @@ -4,10 +4,12 @@ These are the different presentations I've made and possibly presented. <br> -&&gb 19 Jan   [Linuxgraphy by Strabo](./linuxgraphy-by-strabo)   *Last presented: 22.01.2023* +#### *2023* + +&.gb 19 Jan   [Linuxgraphy by Strabo](./linuxgraphy-by-strabo)   *Last presented: 22.01.2023* : A presentation talking about some of the history of UNIX and how Linux works #### *2022* -&&gb 27 Sep   [Demo presentation](./demo)   *Won't be presented* +&.gb 27 Sep   [Demo presentation](./demo)   *Won't be presented* : Showcase of my presentation system diff --git a/src/slides/linuxgraphy-by-strabo/index.md b/src/slides/linuxgraphy-by-strabo/index.md index 196df80..5780cfa 100644 --- a/src/slides/linuxgraphy-by-strabo/index.md +++ b/src/slides/linuxgraphy-by-strabo/index.md @@ -10,52 +10,54 @@ ### Presented at -&&bg Unofficial [FMI](https://fmi.uni-sofia.bg/en) Computer Science Discord server   *04.03.2023 || 14:50 - 17:20* +&.bg Unofficial [FMI](https://fmi.uni-sofia.bg/en) Computer Science Discord server   *04.03.2023 || 14:50 - 17:20* : In front of a tiny audience of other uni students. Exact revision [here](https://gitlab.com/Syndamia/syndamiadotcom/-/blob/6feed223ff48fe00cf12fcd63f3f56179c298cae/src/talks/linuxgraphy-by-strabo/index.md). -&&bg Unofficial [FMI](https://fmi.uni-sofia.bg/en) Computer Science Discord server   *22.01.2023 || 18:00 - 21:00* +&.bg Unofficial [FMI](https://fmi.uni-sofia.bg/en) Computer Science Discord server   *22.01.2023 || 18:00 - 21:00* : In front of a tiny audience of other uni students. Exact revision [here](https://gitlab.com/Syndamia/syndamiadotcom/-/blob/6eb7a8fff01c6814253a0e738efb53734d297be9/src/talks/linuxgraphy-by-strabo/index.md). -&&presentation +&.presentation -&&clide &¢ered +&[title # Linuxgraphy by Strabo *Made by [Syndamia](https://syndamia.com)* -&&lineb4 &&ftable +&.br4 +&{sqrow -&&lineb1 +&.br1 -&&font22 +&(font22 2000 years ago [Strabo](https://en.wikipedia.org/wiki/Strabo) published [Geography](https://en.wikipedia.org/wiki/Geography), in which he laid out the world as it was known to the Romans and Greeks. -&&lineb1 +&.br1 Today, I'll lay out Linux as it is known to me. -&&/font +&)  -&&lineb1 +&.br1 -&&/table &&/centered &&/clide +&} &] -&&slide &&font35 +&[slide35 # Contents -&&ftable &&cont +&{sqrow +&{column 1. Historical context 2. Structure of UNIX-likes 1. Shell 2. UNIX-style file system 2. Kernel -&&lineb2 +&.br2 3. Linux from the inside 1. Shells 2. Files and directories @@ -63,7 +65,7 @@ Today, I'll lay out Linux as it is known to me. 4. System management 4. Software licensing -&&/cont &&cont +&} &{column 5. What makes up a useful OS 1. Bootloader @@ -71,20 +73,20 @@ Today, I'll lay out Linux as it is known to me. 2. Package manager 3. Desktop manager 6. War on distros -&&lineb4 +&.br4 7. Demos - virtual machine and setup from zero -&&/cont &&/table +&} &} -&&/font &&/slide +&] -&&slide +&[slide # 1. Historical context -&&lineb1 +&.br1 #### 1945 - 1955 @@ -101,15 +103,15 @@ Computers became faster, but a lot of time was spend on managing jobs. Jobs were loaded in series ([batches](https://en.wikipedia.org/wiki/Batch_processing)). When the current job finished, memory would be dumped and the next one would automatically be loaded and started. -&&/slide +&] -&&slide +&[slide #### 1960s -&&lineb1 +&.br1 Peripherals (tapes, punch cards, ...) were extremely slow. [Multiprogramming](https://en.wikipedia.org/wiki/Computer_multitasking#Multiprogramming): the current job is waiting for a peripheral, another job would be started. @@ -122,15 +124,15 @@ A computer system now had to support: - Storage organization, also following the rise of disks - Data communication links (often phone lines) -&&lineb1 +&.br1 More and more business started using computers, thanks to [minicomputers](https://en.wikipedia.org/wiki/Minicomputer), so demand for OS software increased. -&&/slide +&] -&&slide +&[slide #### 1964 - 1969 @@ -145,112 +147,113 @@ Some of it's novel ideas include, but are not limited to: - [Hierarchical file system](https://en.wikipedia.org/wiki/Directory_%28computing%29): Arbitrary directories with subdirectories, rather than just having files next to each other or having directories which could only contain files. - [Command processor](https://en.wikipedia.org/wiki/Shell_%28computing%29) (that is separated from the OS): More on that later -&&/slide +&] -&&slide +&[slide #### 1969: Death of Multics and birth of UNIX Ultimately Multics grew too large, becoming unusable and unmaintainable. In the beginning, programming was done mostly by [Bell Labs](https://en.wikipedia.org/wiki/Bell_Labs), with [Ken Thompson](https://en.wikipedia.org/wiki/Ken_Thompson) being one of the developers. -&&lineb1 &&ftable +&.br1 +&{sqrow -&&font18 +&(font18  *Ken Thompson image by National Inventors Hall of Fame*  *Ken Thompson and Dennis Ritchie in 1973* -&&/font +&) -&&cont +&{column Thompson still had some desire to work on operating systems, after Bell Labs pulled out. The tools he made while rewriting [his own video game](https://en.wikipedia.org/wiki/Space_Travel_%28video_game%29) on a PDP-7 lead to a whole operating system: UNIX. Based, expanded on and improved upon many of Multic's ideas, UNIX became the father of modern OSs. -&&/cont +&} -&&/table &&/slide +&} &] -&&slide +&[slide # 2. Structure of UNIX-likes Ignoring [standards](https://unix.stackexchange.com/questions/14368/difference-between-posix-single-unix-specification-and-open-group-base-specifi/14415) and [specifications](https://unix.stackexchange.com/questions/87686/what-makes-an-operating-system-unix-like), in my opinion, from the point of a user, a UNIX-like OS has the following components: -&&lineb2 +&.br4 1. **shell**: A programmable replaceable command-line interpreter, with utilities for managing the whole system and support for pipelines and I/O redirection 2. **UNIX-style file system**: [Filesystem](https://en.wikipedia.org/wiki/Unix_filesystem) as a single rooted tree, objects (nodes) in the file system are [inodes](https://en.wikipedia.org/wiki/Inode) and an inode can be [(at least)](https://en.wikipedia.org/wiki/Unix_file_types) either a regular file, directory or devices. Permissions per users and group. 3. **kernel**: Program that manages all communication and operations between the hardware and software -&&lineb4 +&.br4 -&&font18 *For now we'll generally just look over some of the common stuff and go into detail later, while in Linux.* &&/font +&(font18 *For now we'll generally just look over some of the common stuff and go into detail later, while in Linux.* &) -&&/slide +&] -&&slide &&font35 +&[slide35 ## 2.1. shell -&&lineb2 &&ftable +&.br2 &{sqrow -&&cont +&{column The operating system is divided into layers, [like an onion](https://youtu.be/-FtCTW2rVFM?t=57). Only the kernel has access to the hardware. shells and executables (binaries) have access to the kernel. shells provide user interfaces, [both](http://en.wikipedia.org/wiki/Shell_%28computing%29) command-line and graphical. While on the topic of UNIX, we'll only discuss the former. -&&/cont +&} -&¢ered  &&/centered +&(centered  &) -&&/table &&/font &&/slide +&} &] -&&slide +&[slide ### Command-line shells Command-line shells operate solely with text, often only with ASCII characters. Usually connecting to a computer (to the shell) is said to be done with either a "terminal" ("console") or "teleprinter" ("teletype"). -&&table +&{row Video displays became widely available in the late 1970s, so before that access was done with a "teleprinter", a typewriter-printer combo. -&&font18 +&(font18  *Teletype Model 33 by [Arnold Reinhold](https://commons.wikimedia.org/wiki/User:ArnoldReinhold)* -&&/font +&) -&&tarow +&.newrow With the advent of computer displays, teleprinters were replaced with terminals, video display-keyboard combo. Thanks to the widely popular [VT100](https://en.wikipedia.org/wiki/VT100), almost all terminals support [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code). -&&font18 +&(font18  *DEC VT100 by [Jason Scott](https://www.flickr.com/people/54568729@N00)* -&&/font +&) -&&/table &&/slide +&} &] -&&slide +&[slide Today we don't usually use such specialised hardware, but the names persist with slightly different meanings. @@ -264,11 +267,11 @@ Today we don't usually use such specialised hardware, but the names persist with - ssh, a program to remotely connect to a device's shell, establishes a pseudoterminal. Your local terminal thinks it's connected to a local shell and vice versa with the remote shell, however the pty in between handles the true communication. -&&/slide +&] -&&clide +&[middle ### Command location and parameters @@ -284,11 +287,11 @@ Options usually start with a hyphen `-` (like `-c` or `-current-time`) and often Newer conventions also allow start with two hyphens `--` (`--current-time`), though if shown as-is indicate the rest is a string. More rarely you might see `--OPTION=VALUE` or just `OPTION=VALUE`. -&&/clide +&] -&&clide +&[middle ### Thompson shell @@ -308,11 +311,11 @@ The two major features that every other shell supports are: command1 [args...] | command2 [args...] | ... ``` -&&/clide +&] -&&slide +&[slide ## 2.2. UNIX-style file system @@ -322,17 +325,17 @@ The two major features that every other shell supports are:  -&&/slide +&] -&&clide +&[middle ### Attributes of an inode - [file type](https://en.wikipedia.org/wiki/Unix_file_types): Each inode represents some sort of file (data), but a "file" can also be a directory or device, so we need to know how to handle it. There are 7 main types (but there can exist more, depending on OS): - &&lineb1 + &.br1 + **regular**: just a plain old file + **directory**: as explained, a file containing hard links to other files. Each directory is allowed to appear *only once* in a single parent. + **symbolic link**: points to any file (or directory). It contains the (relative) path to that object (as a simple string), so a symlink not could even be valid. @@ -343,11 +346,11 @@ The two major features that every other shell supports are: exec(/bin/mprog); -> Executes /usr/local/bin/mprog ``` -&&/clide +&] -&&slide +&[slide + **FIFO special**: aka [named pipe](https://en.wikipedia.org/wiki/Named_pipe), a special type of regular file, where at any moment only one process can read from it and one can write to it. It takes the concept of shell pipes to inter-process communication. @@ -370,11 +373,11 @@ The two major features that every other shell supports are: CharacterSpecial << 1 ; CharacterSpecial >> var ``` -&&/slide +&] -&&clide +&[middle + **sockets**: file for inter-process communication. Compared to FIFO specials, they can be used by more than two processes, used in both directions and support [file descriptors](https://en.wikipedia.org/wiki/File_descriptor) and packets @@ -387,15 +390,15 @@ The two major features that every other shell supports are: \-read--> [Process C] ``` -&&/clide +&] -&&slide +&[slide #### Side-step into users and groups -&&lineb3 +&.br3 A user in UNIX is essentially a small collection of data, most important of it being a **unique ID** (number), a **name** (string), a **group id** (number; files created by the user are in that group) and a **password**. @@ -404,16 +407,16 @@ Groups are also small collections of data, but much simpler, comprised only of a User with ID 0 is called root, it is the "system administrator", all actions made by the system itself are done as that user. Every user has their own "home" folder (under "/home/USERNAME/", except for root, which is "/root/"), in which they store personal files, as well as user-specific configuration files. -&&/slide +&] -&&slide +&[slide - [file permissions](https://en.wikipedia.org/wiki/File_system_permissions): control the freedom of a user to read (navigate for directories), change and execute files File permissions are split into three sets: what the **owner** can do, what **group** members can do and what **anyone else** can do. Each set contains a mix of three permissions: **r**ead, **w**rite and e**x**ecute, and each set stores some combination of them. - &&lineb1 + &.br1 Each is represented by a bit in the order above (`101` means you *can* read, *cannot* write, *can* execute) and the overall permissions are often shown as a three digit number or character string. Example: `111101100` will be shown as `754` or `rwxr-xr--` @@ -421,15 +424,15 @@ Every user has their own "home" folder (under "/home/USERNAME/", except for root - User ID of owner, Group ID, file size and timestamps -&&/slide +&] -&&slide +&[slide ## 2.3. Kernel -&&font18 &&lineb1 &&/font +&(font18 &.br1 &) The kernel has the core functionality of the operating system and bridges the gap between programs and hardware. Some important subsystems include scheduling, file, device, process and memory management. @@ -437,23 +440,23 @@ Some important subsystems include scheduling, file, device, process and memory m To preserve the [everything is a file](https://en.wikipedia.org/wiki/Everything_is_a_file) methodology, devices and processes can be handled as files (inside `/dev` and `/proc`). They (most of the time, in modern kernels) aren't actual files on a hard drive, but "virtual" files, where operations on them are handled in a different manner than normal by the kernel. -&&lineb2 +&.br2 -&&font35 Linux is **not** an operating system, it is a kernel!!! &&/font +&(font35 Linux is **not** an operating system, it is a kernel!!! &) -&&lineb2 +&.br2 Two of the important things a kernel does is manage **processes** and **memory**. -&&/slide +&] -&&slide &&font35 +&[slide35 ### 2.3.1 Processes -&&lineb1 +&.br1 A program is some collection of code and other data, stored in a file (or noncompiled code). A process is the program in motion, the program itself *alongside* certain system states. @@ -465,11 +468,11 @@ The system states include (but are not limited to): - [file descriptors](https://en.wikipedia.org/wiki/File_descriptor), unique identifiers for files -&&/font &&/slide +&] -&&clide &&font35 +&[middle35 On a multitasking (multiprocessing) system, which is any modern desktop system, multiple processes are always running "at once". @@ -478,11 +481,11 @@ All "waiting" processes are put in a prioritized queue ([run queue](https://en.w Stopping is either done by the process itself (more on that later), or by the system when the process has been actively running for too much time. -&&/font &&/clide +&] -&&slide &&font35 +&[slide35 #### Process Control Block @@ -497,11 +500,11 @@ A PCB's data can be split into three categories: A process can be **forked**, meaning a new process is created, with the same underlying code (but not process states and ...). -&&/font &&/slide +&] -&&clide &&font35 +&[middle35 #### Process states @@ -511,11 +514,11 @@ A process can be **forked**, meaning a new process is created, with the same und - **Blocked**: When a process cannot continue without external change, usually when waiting for an I/O device. - **Terminated**: The process has either completed execution or has been killed. The process itself is called a ["zombie process"](https://en.wikipedia.org/wiki/Zombie_process) (until it is removed). -&&/font &&/clide +&] -&&clide &&font35 +&[middle35 #### Exit status @@ -525,15 +528,15 @@ For all intents and purposes, this number is an 8bit unsigned integer, meaning i Pretty much universally, an exit code of 0 signifies a successful termination, and anything else specifies some sort of error code. Different programs specify the meaning of an exit code in different ways, some assign each number to a specific error, other use the bits representing the number as flags. -&&/font &&/clide +&] -&&slide &&font35 +&[slide35 ### 2.3.2 Memory management -&&lineb2 +&.br2 In ye olde days, you would save a bit of memory for the operating system and give all of the rest to the current process ([monoprogramming](https://en.wiktionary.org/wiki/monoprogramming)), which we wait until completion. @@ -541,34 +544,34 @@ This doesn't allow for context switching (disks are slow) and a blocked state fo Some bad ideas include: depending on the code of all processes to not use the same addresses, use only [relative addresses](https://en.wikipedia.org/wiki/Position-independent_code) (`-fPIC` option in `gcc`) or use a [table](https://en.wikipedia.org//wiki/Relocation_%28computing%29#Relocation_table) that the kernel fills out with addresses. -&&/font &&/slide +&] -&&slide &&font35 +&[slide35 ### Virtual memory -&&lineb2 +&.br2 -&&fright +&{fright  -&&font18 *Image by [Ehamberg](https://commons.wikimedia.org/wiki/File:Virtual_memory.svg)* &&/font -&&/fright +&(font18 *Image by [Ehamberg](https://commons.wikimedia.org/wiki/File:Virtual_memory.svg)* &) +&} A program (process) works with some (sequential) addresses, and the OS (with the help of [hardware](https://en.wikipedia.org/wiki/Memory_management_unit)) translates/maps the process' addresses (logical/[virtual addresses](https://en.wikipedia.org/wiki/Virtual_address_space)) to real ones (physical addresses). Simplified memory management for the program, protected address space for each process and improved flexibility. -&&/font &&/slide +&] -&&slide &&font35 +&[slide35 #### Segmentation (without paging) -&&lineb2 +&.br2 Initially, virtual memory was implemented with segmentation, where a process' memory is divided into segments for code, stack, heap, etc. Each segment is given a chunk of contiguous memory, which can be resized, and addresses are defined as the base segment (physical) address with an offset. @@ -576,15 +579,15 @@ Each segment is given a chunk of contiguous memory, which can be resized, and ad In the modern day, segmentation isn't used by itself, since resizing segments could require reordering of memory and [external fragmentation](https://en.wikipedia.org/wiki/Fragmentation_%28computing%29#External_fragmentation), where there simply isn't enough contiguous memory, could occur. -&&/font &&/slide +&] -&&slide &&font35 +&[slide35 #### Paging -&&lineb3 +&.br3 The virtual and physical memory is divided into fixed-sized chunks of consecutive addresses. A virtual memory chunk is called a **page**, while a physical memory chunk is called a (page) **frame**. @@ -593,11 +596,11 @@ Usually both have the same size of (at least) 4 KiB. Every process has a [page table](https://en.wikipedia.org/wiki/Page_table), which maps the process' pages to system frames. Thus every memory address is translated from it's page location to a frame location. -&&/font &&/slide +&] -&&slide &&font35 +&[slide35 Advantages include: @@ -612,11 +615,11 @@ Disadvantages include: - longer memory access, because of the page table - [internal fragmentation](https://en.wikipedia.org/wiki/Fragmentation_%28computing%29#Internal_fragmentation), where one or multiple pages might be partially empty, leaving free space that cannot be used -&&/font &&/slide +&] -&&slide +&[slide # 3. Linux from the inside @@ -625,7 +628,7 @@ Enough theory, time to have some fun and learn Linux! We'll be using [Linux Minimal Live](https://ivandavidov.github.io/minimal/#home) (just a bootable ISO) because it's: - very small, comprised of only the Linux kernel, GNU C library and Busybox -- made by a fellow Bulgarian &&bg +- made by a fellow Bulgarian  We're going to explore and look around the following stuff: @@ -634,11 +637,11 @@ We're going to explore and look around the following stuff: - **Common configuration files**: Relevant configuration files, their purpose and syntax - **System management**: Other commands with which to modify your system -&&/slide +&] -&&clide &&font18 +&[middle18 #### If you're following at home @@ -654,15 +657,15 @@ That is because, out of the box, MLL doesn't really support secure connections ( The script, in summary, installs bash, coreutils and shadow "packages" (from [http://s.minos.io/archive/bifrost/x86\_64](http://s.minos.io/archive/bifrost/x86_64)) to /usr/local/bin, creates /etc/passwd, /etc/bashrc and /etc/profile with some values in them and starts bash. -&&/font &&/clide +&] -&&slide +&[slide ## 3.1. Shells -&&lineb2 +&.br2 ### Variables and data types @@ -676,11 +679,11 @@ name=value Where `name` is either a combination of letters (upper and lower case), numbers and the underscore character, which cannot begin with a number, or one of select few **positional** and **special** parameters. -&&/slide +&] -&&slide &&font35 +&[slide35 #### Positional and special parameters @@ -696,11 +699,11 @@ Some of the [special parameters](https://www.gnu.org/savannah-checkouts/gnu/bash `value`, without any special surrounding characters (more on that later), is treated as a string (but it mustn't have spaces!), however it may also be omitted, in which case it is the empty string `""`. -&&/font &&/slide +&] -&&slide &&font35 +&[slide35 #### Data types @@ -716,11 +719,11 @@ An indexed array can also be created by specifying the value at any index: name[index]=value ``` -&&/font &&/slide +&] -&&slide +&[slide #### Mixing types and operations @@ -734,11 +737,11 @@ name=value |integer| |empty string, but sometimes value |value |value when index is 0, empty string otherwise| |array | |operation is done on element at index 0|operation is done on element at index 0|value | -&&/slide +&] -&&slide +&[slide #### Parameter expansion @@ -755,11 +758,11 @@ Some parameter expansions in bash: - `${parameter/pattern/string}` return a string, where every match on pattern is replaced by string - `${name[@]}` a (space separated) sequence of indices from 0 to length (for defined values) of array name -&&/slide +&] -&&slide +&[slide #### Arithmetic expansion @@ -779,11 +782,11 @@ Some useful expressions are: Expressions work with both variable names and integers. -&&/slide +&] -&&clide +&[middle ### Bourne shell @@ -801,11 +804,11 @@ Most modern shells support a lot of the more defying features of the [Bourne She + `fg`: resume the last job to be put in the background and make it the current job with which we're interacting + `jobs`: list all active (background) jobs -&&/clide +&] -&&clide +&[middle -   + Every job is identified with a **Job ID** (number), which you can use by prepending a percentage sign. Example, to resume the job with JID 4: @@ -819,11 +822,11 @@ Most modern shells support a lot of the more defying features of the [Bourne She + `kill`: send a signal to the process or job. Then that process will have to handle it accordingly. Common ones are `-KILL` to immediately stop the process, `-QUIT` to quit it, `-ABRT` to cancel the current action, `-TERM` shut down (orderly), `-STOP` shut down (forcefully) -&&/clide +&] -&&clide &&font27 +&[middle27 - [heredoc](https://en.wikipedia.org/wiki/Here_document): File literal, meaning it is a user "string" which is interpreted as a file + start with `<< NAME`, where NAME can be anything you want, it is used to mark the beginning and end of a heredoc. `<<` is also a redirection symbol @@ -843,10 +846,10 @@ Most modern shells support a lot of the more defying features of the [Bourne She + `expr1 || expr2`: Run expr2 if expr1 exited unsuccessfully + `expr1 ; expr2`: Run expr2 after expr1 (sequential execution) -&&/font &&/clide +&] -&&clide &&font27 +&[middle27 - [redirection](https://en.wikipedia.org/wiki/Redirection_%28computing%29): Outside of having `<` and `>` for I/O redirection, often there is also + `>>`: Acts like `>`, putting text into a file, but rather than overwriting everything, it appends it @@ -865,11 +868,11 @@ Most modern shells support a lot of the more defying features of the [Bourne She * `N<inputfile`: redirects input file contents to standard stream N * `N<&M`: redirects standard stream M to standard stream N -&&/font &&/clide +&] -&&clide &&font27 +&[middle27 - [built-in test command](https://en.wikipedia.org/wiki/Test_%28Unix%29): With `test` you can do conditional expressions. You can also often use brackets `[ args... ]` instead of `test args...` + Some of the available file checks @@ -888,11 +891,11 @@ Most modern shells support a lot of the more defying features of the [Bourne She + Operators: `!` - negation, `-a` - binary AND, `-o` - binary OR, parentheses for grouping (escaped with `\`) -&&/font &&/clide +&] -&&slide +&[slide - [scripting support](https://en.wikipedia.org/wiki/Shell_script): Running commands from top to bottom of a file + `#`: Everything between a # and the end of the line denotes a comment @@ -912,14 +915,14 @@ Most modern shells support a lot of the more defying features of the [Bourne She elif statements can appear multiple times, both elif and else are optional -&&/slide +&] -&&slide +&[slide -   - &&lineb1 + &.br1 ``` case word in (pattern | ...) commands-if-true ;; ... esac @@ -939,29 +942,29 @@ Most modern shells support a lot of the more defying features of the [Bourne She ``` If `in words...` is ommited, positional arguments are used -&&/slide +&] -&&clide &&font35 +&[middle35 ## 3.2. Files and directories - `/dev`: devices - `/proc`: process information -&&lineb3 +&.br3 - `/bin`: main command programs (binaries), used by users - `/sbin`: command programs, used for the system operation - `/usr`: other system resources + `/usr/bin`: all other user command binaries -&&/font &&/clide +&] -&&slide +&[slide #### Everyday file system commands @@ -983,11 +986,11 @@ Most modern shells support a lot of the more defying features of the [Bourne She - `chmod`: change file modes - `find`: search for a file inside a directory (recursively) -&&/slide +&] -&&slide +&[slide #### Everyday text (file) commands @@ -1008,11 +1011,11 @@ Most modern shells support a lot of the more defying features of the [Bourne She - `wc`: count words inside file - `diff`: compare files and show their differences -&&/slide +&] -&&clide +&[middle #### Device commands @@ -1027,11 +1030,11 @@ Most modern shells support a lot of the more defying features of the [Bourne She - `hostname`: show (or set) the systems hostname (network name) - `free`: display free memory on the system -&&/clide +&] -&&slide +&[slide #### User and group management @@ -1040,27 +1043,27 @@ Most modern shells support a lot of the more defying features of the [Bourne She - `usermod`: modify a user account, including his name and groups - `passwd`: change password of a user. With `-l` user could be locked (impossible to log in) -&&lineb1 +&.br3 - `groupadd`: create a new group - `groupdel`: remove a group - `groupmod`: modify an existing group -&&lineb1 +&.br3 - `w`: show who is logged in and what they are doing - `who`: show who is logged in - `whomai`: print username - `login`: establish a new connection to the system -&&/slide +&] -&&slide +&[slide - `/etc`: system configuration files - &&lineb2 + &.br2 + `/etc/group`: the data for all groups is stored here, in the format @@ -1080,11 +1083,11 @@ Most modern shells support a lot of the more defying features of the [Bourne She USERNAME:PASSWORD:LASTCHANGED:MINBETWEENCHANGES:MAXBETWEENCHANGES:WARNEXPIRE:INACTIVEDAYS:EXPIRE ``` -&&/slide +&] -&&slide &&font27 +&[slide27 -   @@ -1108,11 +1111,11 @@ Most modern shells support a lot of the more defying features of the [Bourne She + `/etc/bashrc`: global defaults and aliases used by the bash shell + `/etc/motd`: message of the day (unexecuted text), shown after login but before the shell is ran -&&/font &&/slide +&] -&&clide &&font35 +&[middle35 - `/usr`: other system resources + `/usr/lib`: library files @@ -1124,11 +1127,11 @@ Most modern shells support a lot of the more defying features of the [Bourne She - `/mnt`: mounted temporary filesystems - `/root`: home directory for the root user -&&/font &&/clide +&] -&&slide +&[slide # 4. Software licensing @@ -1144,29 +1147,29 @@ Some commonly used ones, with a (NON-LEGALLY BINDING) summary include: This is important, since pretty much everything can be freely modified by anyone (for the better or worse, but generally better). -&&/slide +&] -&&slide &&font35 +&[slide35 # 5. What makes up a useful OS A Linux-based operating system is nothing more than the Linux kernel, combined with an assortment of programs. Overall, the main elements that make up a useful *desktop* operating system (alongside a command-line shell) are: -&&lineb1 +&.br1 1. **Bootloader**: load the kernel and operating system 2. **Init system**: well managed way to start everything inside the OS 3. **Package manager**: way to manage our binaries 4. **Desktop manager**: graphical shell -&&/font &&/slide +&] -&&slide +&[slide ## 5.1. Bootloader @@ -1184,11 +1187,11 @@ BIOS -> Master Boot Record -> Active Parition -> Bootloader -> - Active partition: MBR loads and runs code from the beginning of the partition (boot sector), which starts the bootloader - [Bootloader](https://en.wikipedia.org/wiki/Bootloader): the first complex program, which manages kernels, shows a menu, allows for debugging and so on -&&/slide +&] -&&clide +&[middle The BIOS is baked into the motherboard, the MBR is pretty universal (and it's less than 512 bytes) and the kernel we know and love. @@ -1206,11 +1209,11 @@ GRUB_CMDLINE_LINUX_DEFAULT="" GRUB_GFXMODE=640x480 ``` -&&/clide +&] -&&slide &&font27 +&[slide27 ## 5.2. Init system @@ -1233,15 +1236,15 @@ ExecStart=/usr/local/sbin/script.sh WantedBy=multi-user.target ``` -&&/font &&/slide +&] -&&slide +&[slide ## 5.3. Package manager -&&lineb1 +&.br1 Programs are just executable files, usually placed in a specific folder, like `/usr/bin`. @@ -1254,11 +1257,11 @@ Updating all of them means replacing all of the binaries, means tracking where e On modern systems, managing binaries is automated by an application called a package manager. -&&/slide +&] -&&clide &&font35 +&[middle35 Additional benefits of package management automation include: @@ -1268,7 +1271,7 @@ Additional benefits of package management automation include: - version caveats - (indirectly) improved stability because of maintainer compatibility checks -&&lineb1 +&.br1 ``` apt install PKG @@ -1276,18 +1279,18 @@ apt remove PKG apt upgrade ``` -&&/font &&/clide +&] -&&slide +&[slide ## 5.4. Window systems A widow system is your graphical shell: the graphical way to interact with your computer (the kernel). It's main components are: -&&lineb1 +&.br1 - **Window manager**: the overall system with which you create, remove, resize and work with windows. They are generally separated into two types: + *Stacked*: this is what you know, windows are just rectangles floating about, and can be put one over each other @@ -1295,11 +1298,11 @@ It's main components are: - **Compositor**: adds an unseen window buffer, allowing additional processing, before a window is shown. This powers transparency, animation effects and more. - **Session manager**: graphical application that manages the window managers (outside WMs), think of it as a login window -&&/slide +&] -&&slide &&font27 +&[slide27 # 6. War on distros @@ -1317,15 +1320,15 @@ We haven't touched too much, but Linux distributions aren't limited to desktop o 1. [AOSP](https://en.wikipedia.org/wiki/Android_%28operating_system%29#AOSP): the base of the whole Android operating system 2. [OpenWRT](https://en.wikipedia.org/wiki/OpenWrt): a router operating system -&&/font &&/slide +&] -&&slide &&font35 +&[slide35 # 7. Demos - virtual machine and setup from zero -&&lineb2 +&.br2 Now for the best part: we'll be installing a Linux distribution on a virtual machine and then directly on a laptop, running Windows 10! @@ -1333,19 +1336,19 @@ I've chosen to install [Linux Mint](https://linuxmint.com/), since it is general Currently there won't be an official recording of the process, you should've been here live! -&&/font &&/slide +&] -&&clide &&font35 &¢ered +&[title35 # Thank you for your time -&&/centered &&/font &&/clide +&] -&&slide &&font18 +&[slide18 # Sources @@ -1376,4 +1379,4 @@ They served as personal educational and reference tools. Images on slides "2.1. shell" and "2.2. UNIX-style file system" are made by me and [licensed as content](/license.html). The script [mll-set.sh](http://syndamia.com/talks/linuxgraphy-by-strabo/mll-set.sh) is licensed under MIT (though I don't see it as substatial enough to be licensed under anything). -&&/font &&/slide +&] diff --git a/src/software.md b/src/software.md deleted file mode 100644 index 37722dc..0000000 --- a/src/software.md +++ /dev/null @@ -1,36 +0,0 @@ -# Software - -This is a curated list of the more relevant software projects I've made or heavily contributed to - -<br> - -[gitlab / texty-office](https://gitlab.com/Syndamia/texty-office) + [gitlab / texty-office.vim](https://gitlab.com/Syndamia/texty-office.vim) -: An imperfect converter from DOCX, PPTX and XLSX to normal text with it's associated [Vim](https://www.vim.org/) plugin. <br> `GNU GPLv3` & `MIT` | `C++` `vimscript` | `Office file` `converter` `plugin` `Vim` `CLI tool` - -[gitlab / small-web-utilities](https://gitlab.com/Syndamia/small-web-utilities)   *maintained* -: A collection of small but fast utilities, like a checklist, that work locally on your browser. Also hosted [here](https://utils.syndamia.com). <br> `GNU GPLv3` | `HTML` `Javascript` | `checklist` `utilities` - -[gitlab / ss-law](https://gitlab.com/Syndamia/ss-law) + [github / ss-law](https://github.com/Syndamia/ss-law)   *maintained* -: A small, lightweight and simple static site generation system, extracted as a template from my own <br> `Markdown` `bash` `awk` | `ssg` `lowdown` `static site generator` `pipelines` - -[gitlab / homelander](https://gitlab.com/Syndamia/homelander)   *maintained* -: A very small and good looking, handmade prompt for zsh <br> `GPLv3` | `bash` | `zsh` `shell` `prompt` `script` `Linux` - -[gitlab / goodwolf](https://gitlab.com/Syndamia/goodwolf)   *abandoned* -: Fork of the [badwolf](https://hacktivis.me/projects/badwolf) browser, which aims to add features <br> `BSD-3-Clause` | `C` | `web browser` `GTK` `WebKitGTK` `Linux` - -#### *2021* - -[gitlab / RepoSync](https://gitlab.com/Syndamia/reposync)   *completed* -: Script and some config files for synchronizing a git repository with a server <br> `MIT` | `python` | `server` `git` `systemd` - -[github / filite-list](https://github.com/Syndamia/filite-list)   *completed* -: Script for managing [filite](https://github.com/raftario/filite) links <br> `GPLv3` | `bash` | `filite` `server` `script` `Linux` - -#### *2020* - -[github / DevHive](https://github.com/Team-Kaleidoscope/DevHive) and [github / DevHive-Angular](https://github.com/Team-Kaleidoscope/DevHive-Angular)   *completed* -: DevHive is a social network oriented towards programmers. It's FOSS, built from the ground up, and made from a team of three for a course. <br> `GPLv3` | `C#` `TypeScript` | `Angular` `ASP.NET Core` `social media` `mvc` `Docker` `CSS` - -[github / min-youtube-element-blocker](https://github.com/Syndamia/min-youtube-element-blocker)   *maintained* -: Userscript for hiding certain UI elements in YouTube <br> `MIT` | `JavaScript` | `youtube` `userscript` `css` diff --git a/src/software/index.md b/src/software/index.md deleted file mode 100644 index 37722dc..0000000 --- a/src/software/index.md +++ /dev/null @@ -1,36 +0,0 @@ -# Software - -This is a curated list of the more relevant software projects I've made or heavily contributed to - -<br> - -[gitlab / texty-office](https://gitlab.com/Syndamia/texty-office) + [gitlab / texty-office.vim](https://gitlab.com/Syndamia/texty-office.vim) -: An imperfect converter from DOCX, PPTX and XLSX to normal text with it's associated [Vim](https://www.vim.org/) plugin. <br> `GNU GPLv3` & `MIT` | `C++` `vimscript` | `Office file` `converter` `plugin` `Vim` `CLI tool` - -[gitlab / small-web-utilities](https://gitlab.com/Syndamia/small-web-utilities)   *maintained* -: A collection of small but fast utilities, like a checklist, that work locally on your browser. Also hosted [here](https://utils.syndamia.com). <br> `GNU GPLv3` | `HTML` `Javascript` | `checklist` `utilities` - -[gitlab / ss-law](https://gitlab.com/Syndamia/ss-law) + [github / ss-law](https://github.com/Syndamia/ss-law)   *maintained* -: A small, lightweight and simple static site generation system, extracted as a template from my own <br> `Markdown` `bash` `awk` | `ssg` `lowdown` `static site generator` `pipelines` - -[gitlab / homelander](https://gitlab.com/Syndamia/homelander)   *maintained* -: A very small and good looking, handmade prompt for zsh <br> `GPLv3` | `bash` | `zsh` `shell` `prompt` `script` `Linux` - -[gitlab / goodwolf](https://gitlab.com/Syndamia/goodwolf)   *abandoned* -: Fork of the [badwolf](https://hacktivis.me/projects/badwolf) browser, which aims to add features <br> `BSD-3-Clause` | `C` | `web browser` `GTK` `WebKitGTK` `Linux` - -#### *2021* - -[gitlab / RepoSync](https://gitlab.com/Syndamia/reposync)   *completed* -: Script and some config files for synchronizing a git repository with a server <br> `MIT` | `python` | `server` `git` `systemd` - -[github / filite-list](https://github.com/Syndamia/filite-list)   *completed* -: Script for managing [filite](https://github.com/raftario/filite) links <br> `GPLv3` | `bash` | `filite` `server` `script` `Linux` - -#### *2020* - -[github / DevHive](https://github.com/Team-Kaleidoscope/DevHive) and [github / DevHive-Angular](https://github.com/Team-Kaleidoscope/DevHive-Angular)   *completed* -: DevHive is a social network oriented towards programmers. It's FOSS, built from the ground up, and made from a team of three for a course. <br> `GPLv3` | `C#` `TypeScript` | `Angular` `ASP.NET Core` `social media` `mvc` `Docker` `CSS` - -[github / min-youtube-element-blocker](https://github.com/Syndamia/min-youtube-element-blocker)   *maintained* -: Userscript for hiding certain UI elements in YouTube <br> `MIT` | `JavaScript` | `youtube` `userscript` `css` diff --git a/src/styles.csma b/src/styles.csma deleted file mode 100644 index 2b8f9d3..0000000 --- a/src/styles.csma +++ /dev/null @@ -1,639 +0,0 @@ -:root { - --bg-color: white; - --fg-color: black; - - --body-bg: #ebe3d2; - --accent-line-color: #004080; - - --a-color: #336700; - --a-hover-color: #3ea100; - --bg-selection-color: #338fff; - --blockquote-color: #6a737d; - --blockquote-border-color: #dfe2e5; - --border-color: black; - --code-bg-color: var(--hi-bg); - --em-color: black; - --fg-selection-color: white; - --header-color: #006b8f; - --pre-bg-color: var(--hi-bg); - --strong-color: black; - --table-border-color: black; - --tr-bg-color: #fbfdff; - --alternating-row-color: #eef0f2; - - --terminal-fg: black; - --terminal-bg: white; - - /* https://github.com/morhetz/gruvbox/blob/master/autoload/gruvbox.vim */ - --hi-fg: var(--fg-color); - --hi-bg: #f5f5e2; - --hic-gray: #928374; - --hic-red: #fb4934; - --hic-green: #79740e; - --hic-blue: #076678; - --hic-yellow: #b57614; - --hic-purple: #8f3f71; - --hic-aqua: #427b58; - --hic-orange: #af3a03; - - --hi-comment: var(--hic-gray); - --hi-const: var(--hic-purple); - --hi-string: var(--hic-green); - --hi-char: var(--hic-purple); - --hi-number: var(--hic-purple); - --hi-bool: var(--hic-purple); - --hi-float: var(--hic-purple); - --hi-identifier: var(--hic-blue); - --hi-function: var(--hic-green); - --hi-statement: var(--hic-red); - --hi-conditional: var(--hic-red); - --hi-repeat: var(--hic-red); - --hi-operator: var(--hi-fg); - --hi-keyword: var(--hic-red); /* Label and Exception are keywords */ - --hi-preproc: var(--hic-aqua); - --hi-type: var(--hic-yellow); - --hi-storageclass: var(--hic-orange); - --hi-structure: var(--hic-aqua); - --hi-typedef: var(--hic-aqua); - --hi-ignore: var(--hi-fg); -} - -/* Global */ - -@font-face { - font-family: 'Tabler'; - src: url('/font/tabler-icons-subset.ttf') format('truetype'); -} - -<Webpage> -<Webpage> { - body { - min-height: calc(100vh - 16px); - background-color: var(--body-bg); - border-color: var(--border-color); - color: var(--fg-color); - overflow-wrap: break-word; - - /* Stuff to make sure the font is rendered correctly on Safari - * https://stackoverflow.com/a/56065714/12036073 */ - font-rendering: optimizeLegibility; - font-weight: 400; - -webkit-font-kerning: normal; - -webkit-font-smoothing: antialiased; - } - body, td, th { font-size: 18px; font-family: 'Tabler', sans-serif; } - * { line-height: 1.3em; } - - <Button> { - .btn, .h-anchor { - /* Thanks https://stackoverflow.com/a/4407335/12036073 */ - - -webkit-touch-callout: none; /* iOS Safari */ - -webkit-user-select: none; /* Safari */ - -khtml-user-select: none; /* Konqueror HTML */ - -moz-user-select: none; /* Old versions of Firefox */ - -ms-user-select: none; /* Internet Explorer/Edge */ - user-select: none; - } - .btn:hover { cursor: pointer; } - .btn:active { transform: scale(0.9); } - } - - <Browser compatibility> { - /* Inside _header we use <span class="br"></span>, instead of <br>, because if your browser - * doesn't support CSS, we want most stuff to be aligned on a single line, rather than preserve - * the "vertical" layout */ - .br { display: block; } - .brt { display: block; height: 0.8em; } - /* Without CSS, certain stuff look bad or confusing, so with this I can add elements which - * add elements for helping with website usage, but which shouldn't be seen otherwise */ - .nocss-aid { display: none; } - } - - nav, article { background-color: var(--bg-color); } - <Sidebar> {} - <Content> {} - - <JavaScript/image-show.js> - - <Lowdown> { - .footnotes { font-size: 0.9em; margin-top: 3em; } - a[rev="footnote"] { border: none; } - } -} - -<Sidebar> -<Content> - -<Sidebar> { -/* - * Sidebar - */ - - #sidebar { - background-color: var(--body-bg); - font-size: 1.2em; - margin-right: 8px; - max-width: 11.2em; - } - #sidebar > * { - border: 3px solid var(--accent-line-color); - box-sizing: border-box; - padding: 1rem 1rem; - width: 100%; - } - #sidebar > :not(:first-child) { margin-top: 8px; } - #sidebar a { border: none; } - - <Header> {} - <Page links> {} - <Settings> {} - <Footer> {} - - <JavaScript/expand-navbar.js> -} - -<Sidebar> { -<Header> -{ - #header { - border-right: none; - font-size: 1.5em; - } -} -} - -<Sidebar> { -<Page links> -{ - #index { - border-right: none; - border-bottom: none; - } - .arrowed-list { - margin: 0 0 0.5em 0.3em; - padding-left: 0.5em; - row-gap: 0; - grid-column-start: 1; - grid-column-end: 1; - display: grid; - border-left: 2px solid var(--border-color); - } - .arrowed-list > *, .arrowed-list > *:hover { - line-height: 1.2em; - display: block; /* Compatibility with Chrome 49.0.2623.112 (for old machines) */ - } -} -} - -<Sidebar> { -<Settings> -{ - #settingsWrapper { - border-top: none; - border-bottom: none; - font-size: 1.2em; - line-height: 1em; - } - .setting-btn { - text-align: center; - display: inline-block; - line-height: 1em; - border: 1px solid var(--border-color); - padding: 0.4em; - } - #settingsWrapper > .setting-btn { font-size: 0.5em; } -} -} - -<Sidebar> { -<Footer> -{ - #footer { - font-size: 0.7em; - overflow-x: hidden; - border-left: none; - border-top: none; - } - #footer > * { white-space: nowrap; } -} -} - -<Content> { -/* - * Content - */ - - #content-wrapper { - min-height: calc(100vh - 16px); - display: flex; - flex-direction: row; - border-right: 3px solid var(--accent-line-color); - } - - <Article> {} -} - -<Article> -<Article> { - article { - border-top: 3px solid var(--accent-line-color); - box-sizing: border-box; - flex: 1; - max-width: 56em; /* Equivalent to 50em on 19px font-size */ - margin-bottom: 1em; - overflow: auto; - padding: 0 1em; - } - article { - margin-left: auto; - margin-right: auto; - } - .noMaxWidth { max-width: initial; } - - <Gap> {} - <Footer> {} - - <Contents in page> {} - <Pagenav> {} - <Paragraphs with icons> {} - <Page specific> {} - - <Headers> - <Anchor> - <Italics> - <Bold> - <Blockquote> - <Post card> - <Images> - <Code> - <Table> - - .no-wrap { - color: inherit; - vertical-align: baseline; - white-space: nowrap; - } - - <JavaScript/back-to-top.js> -} - -<Article> { -<Gap> -{ - .gap, .gap-small { - background-color: var(--body-bg); - margin: 0 -1em; - } - .gap { height: 1.5em; } - .gap-small { height: 0.5em; } -} -} - -<Article> { -<Footer> -{ - article > footer { - margin: 0 -1em; - padding: 0.5em; - border: 3px solid var(--accent-line-color); - border-left: none; - border-right: none; - } -} -} - -<Article> { -<Contents in page> -{ - #contents-container { float: right; margin-left: 2.5em; background-color: var(--bg-color); padding-right: 0.5em; } - #contents-container > h2 { margin-top: -1rem; } -} -} - -<Article> { -<Pagenav> -{ - #pagenav { - filter: opacity(64%); - font-size: 0.8em; - margin: 0 0 3rem 2rem; - } - #pagenav > * { white-space: nowrap; } - #pagenav + h2, #pagenav + h3, #pagenav + h4 { margin-top: 0; } -} -} - -<Article> { -<Paragraphs with icons> -{ - .special-par { - position: relative; - padding: 0.5em; - padding-left: calc(32px + 1em); - } - .question-par { border-left: 2px solid #4a85cb; } - .warn-par { border: 2px dashed #fac848; } - .important-par { border: 2px solid #f46062; } - .special-par-icon { vertical-align: middle; } - .special-par > .special-par-icon { - position: absolute; - left: 0.5em; - top: calc(50% - 16px); - } -} -} - -<Article> { -<Page specific> -{ - <About page> { - #about-image { - float: right; - margin-right: 1em; - margin-top: 2em; - max-width: 7.6em; - } - } -} -} - -<Headers> { - h1, h2, h3, h4, h5, h6 { - color: var(--header-color); - display: inline-block; - line-height: 1.25em; - border-bottom: 2px solid var(--border-color); - } - h1 { display: block; font-size: 1.7em; margin-block-end: 0.5em; } - - h1 + *, h1 ~ h1, h2 + a + *, h3 + a + *, h4 + a + *, h5 + a + *, h6 + a + * { - margin-top: 0; - } - .h-anchor { color: var(--fg-color); border: none; } - - /* Slightly smaller than browser defaults https://stackoverflow.com/a/70720104/12036073 */ - h2 + .h-anchor { font-size: 1.4em; } - h3 + .h-anchor { font-size: 1.1em; } -} - -<Anchor> { - a, a strong { - border-bottom: 1px dashed; - color: var(--a-color); - text-decoration: none; - } - sup a, dt a { border: none; } - a * { color: var(--fg-color); } - a:hover, a strong:hover { color: var(--a-hover-color); } -} - -<Italics> { - i, em { color: var(--em-color); } -} - -<Bold> { - strong { color: var(--strong-color); } -} - -<Blockquote> { - blockquote { - border-left: .25em solid var(--blockquote-border-color); - color: var(--blockquote-color); - margin: 0; - margin-top: 0; - margin-bottom: 16px; - padding: 0 1em; - } - blockquote > :first-child { margin-top: 0; } - blockquote > :last-child { margin-bottom: 0; } -} - -<Post card> { - dt, dd { - border: 2px solid var(--border-color); - border-bottom: none; - border-top: none; - padding: 0 0.5em; - } - dt { font-size: 1.2em; padding-top: 0.2em; } - dt * { vertical-align: middle; } - dd { - line-height: 1.5em; - margin-bottom: 1em; - margin-left: 0; - padding-bottom: 0.4em; - padding-left: 49px; - } -} - -<Images> { - img { - box-sizing: border-box; - max-width: 100%; - } - img, hr { border: 1px solid var(--border-color); } - dt img, .svg { box-sizing: border-box; max-height: 1em; } - .pixelated-render { image-rendering: pixelated; } - .oldschool-badge { height: 38px; } - .flag { max-width: 1.3em; } /* Compatibility with Chrome 49.0.2623.112 (for old machines) */ - - .file-type-icon { min-width: 1.3em; vertical-align: middle; } - .borderless, .oldschool-badge, .file-type-icon { border: none; } -} - -<Code> { - /* The following CSS is a modified version of sindresorhus's github-markdown-css repo: https://github.com/sindresorhus/github-markdown-css */ - code, pre { - font-family: monospace; - font-size: 85%; - } - - <Pre elem> { - pre { - overflow: auto; - word-break: normal; - word-wrap: normal; - } - } - - <Code elem> { - code { - background-color: var(--pre-bg-color); - margin: 0; - padding: 0 0.4em; - } - pre code { - border: 0; - display: inline-block; - font-size: 100%; - overflow: visible; - padding: 0; - word-wrap: normal; - } - pre > code { - white-space: pre-wrap; - word-break: break-all; - padding: 0.9em; - width: 100%; - box-sizing: border-box; - } - - table code { - font-size: 0.7em; - white-space: normal; - } - dd code { font-size: 0.8em; } - } - - <Syntax highlighting> {} - .language-terminal { - color: var(--terminal-fg); - background-color: var(--terminal-bg); - } -} - -<Table> { - table { - border-spacing: 0; - border-collapse: collapse; - margin: 1em 0; - overflow: auto; - } - table td, table th { word-break: normal !important; } - table td:not(:first-of-type), table th:not(:first-of-type) { - border-left: 2px dashed var(--table-border-color); - } - table td, table th { padding: 0.5em; } - table th { - font-size: 1.1em; - font-weight: bold; - } - table td:empty { height: 1em; } - - table tr { - background-color: var(--tr-bg-color); - } - thead tr { - border-bottom: 2px dashed var(--table-border-color); - } - table tr:nth-child(2n), thead tr { - background-color: var(--alternating-row-color); - } -} - -/* Small screen support */ - -@media screen and ((max-width: 610px) or (max-height: 610px)) { - article { - border-top: none; - max-width: calc(100vw - 16px - 3px); - } - table td, table th { word-break: break-all; } - - #about-image { max-width: 4.38em; } - - #content-wrapper { flex-direction: column; } - #sidebar { - max-width: initial; - margin: 0; - } - #sidebar > * { border-right: none; } - .sidebar-hidden { position: initial; } - .sidebar-hidden > :not(#header) { display: none; } - .sidebar-hidden + .noMaxWidth { margin-top: 0; } - /* page-width.js */ - #changeWidthBtn { display: none; } -} - -/* Printing support */ - -@media print { - h2 + a img, h3 + a img, h4 + a img, h5 + a img, h6 + a img, - nav, #scrollBtn, .gap, .gap-small { - display: none !important; - } - - body { margin: 0; } - body, article { - background-color: white; - border: none !important; - } - - pre, code { white-space: pre-wrap !important; } - .language-terminal { color: var(--fg-color); background-color: var(--bg-color); } - .slide, .absolute-slide { transform: none !important; margin: 0; } -} - -<JavaScript> { - <expand-navbar.js> { - #expandNavbarBtn { float: right; margin-left: 1em; } - .sidebar-hidden { min-height: auto; position: absolute; } - .sidebar-hidden > :not(#header) { display: none; } - .sidebar-hidden + .noMaxWidth { margin-top: 6em; } - } - - <back-to-top.js> { - #scrollBtn { - font-size: 1.66rem; - padding: 0 0.15em; - bottom: 1rem; - right: 1rem; - z-index: 1; - transition-duration: 0.5s; - background-color: var(--bg-color); - display: none; - position: fixed; - border: 1px solid; - } - } - - <image-show.js> { - .clicked-image { - height: 100vh; - width: 100vw; - max-width: none; - max-height: none; - padding: 1em; - background-color: var(--bg-color); - left: 0; - top: 0; - z-index: 2; - border: none; - object-fit: contain; - position: fixed; - } - .body-on-clicked-image { overflow: hidden; } - } - - <presentation.js> { - .nodisplay { display: none; } - } -} -<JavaScript/presentation.js> - -<Code> { -<Syntax highlighting> { - .HI-comment { color: var(--hi-comment); } - .HI-const { color: var(--hi-const); } - .HI-string { color: var(--hi-string); } - .HI-char { color: var(--hi-char); } - .HI-number { color: var(--hi-number); } - .HI-bool { color: var(--hi-bool); } - .HI-float { color: var(--hi-float); } - .HI-identifier { color: var(--hi-identifier); } - .HI-function { color: var(--hi-function); } - .HI-statement { color: var(--hi-statement); } - .HI-conditional { color: var(--hi-conditional); } - .HI-repeat { color: var(--hi-repeat); } - .HI-operator { color: var(--hi-operator); } - .HI-keyword { color: var(--hi-keyword); /* Label and Exception are keywords */ } - .HI-preproc { color: var(--hi-preproc); } - .HI-type { color: var(--hi-type); } - .HI-storageclass { color: var(--hi-storageclass); } - .HI-structure { color: var(--hi-structure); } - .HI-typedef { color: var(--hi-typedef); } - .HI-ignore { color: var(--hi-ignore); } - .HI-comment * { color: inherit; } /* If text inside a comment is matched, don't show it */ -} -} diff --git a/src/styles.css b/src/styles.css new file mode 100644 index 0000000..8721bbc --- /dev/null +++ b/src/styles.css @@ -0,0 +1,499 @@ +:root { + --bg-color: white; + --fg-color: black; + + --body-bg: #ebe3d2; + --accent-line-color: #004080; + + --a-color: #336700; + --a-hover-color: #3ea100; + --bg-selection-color: #338fff; + --blockquote-color: #6a737d; + --blockquote-border-color: #dfe2e5; + --border-color: black; + --code-bg-color: var(--hi-bg); + --em-color: black; + --fg-selection-color: white; + --header-color: #006b8f; + --pre-bg-color: var(--hi-bg); + --strong-color: black; + --table-border-color: black; + --tr-bg-color: #fbfdff; + --alternating-row-color: #eef0f2; + + --terminal-fg: black; + --terminal-bg: white; + + /* https://github.com/morhetz/gruvbox/blob/master/autoload/gruvbox.vim */ + --hi-fg: var(--fg-color); + --hi-bg: #f5f5e2; + --hic-gray: #928374; + --hic-red: #fb4934; + --hic-green: #79740e; + --hic-blue: #076678; + --hic-yellow: #b57614; + --hic-purple: #8f3f71; + --hic-aqua: #427b58; + --hic-orange: #af3a03; + + --hi-comment: var(--hic-gray); + --hi-const: var(--hic-purple); + --hi-string: var(--hic-green); + --hi-char: var(--hic-purple); + --hi-number: var(--hic-purple); + --hi-bool: var(--hic-purple); + --hi-float: var(--hic-purple); + --hi-identifier: var(--hic-blue); + --hi-function: var(--hic-green); + --hi-statement: var(--hic-red); + --hi-conditional: var(--hic-red); + --hi-repeat: var(--hic-red); + --hi-operator: var(--hi-fg); + --hi-keyword: var(--hic-red); /* Label and Exception are keywords */ + --hi-preproc: var(--hic-aqua); + --hi-type: var(--hic-yellow); + --hi-storageclass: var(--hic-orange); + --hi-structure: var(--hic-aqua); + --hi-typedef: var(--hic-aqua); + --hi-ignore: var(--hi-fg); +} + +/*## Global ##*/ + +@font-face { + font-family: 'Tabler'; + src: url('/font/tabler-icons-subset.ttf') format('truetype'); +} + +body { + background-color: var(--body-bg); + border-color: var(--border-color); + color: var(--fg-color); + min-height: calc(100vh - 16px); + overflow-wrap: break-word; + + /* Stuff to make sure the font is rendered correctly on Safari + * https://stackoverflow.com/a/56065714/12036073 */ + font-rendering: optimizeLegibility; + font-weight: 400; + -webkit-font-kerning: normal; + -webkit-font-smoothing: antialiased; +} +body, td, th { font-size: 18px; font-family: 'Tabler', sans-serif; } +* { line-height: 1.3em; } + +/*## No-CSS compatibility ##*/ + + /* Inside _header we use <span class="br"></span>, instead of <br>, because if your browser + * doesn't support CSS, we want most stuff to be aligned on a single line, rather than preserve + * the "vertical" layout */ +.br { display: block; } +.brt { display: block; height: 0.8em; } + /* Without CSS, certain stuff look bad or confusing, so with this I can add elements which + * add elements for helping with website usage, but which shouldn't be seen otherwise */ +.nocss-aid { display: none; } + +nav, article { background-color: var(--bg-color); } + +/*## Wrapper ##*/ + +#content-wrapper { + min-height: calc(100vh - 16px); + display: flex; + flex-direction: row; + border-right: 3px solid var(--accent-line-color); +} + +#content-wrapper.content-wrapper-vertical { border: none; flex-direction: column; } +.content-wrapper-vertical > #sidebar { max-width: initial; margin: 0; } +.content-wrapper-vertical .sidebar-section:not(#header) { display: none; } +.content-wrapper-vertical > article { margin-top: 8px; } + +/*## Wrapper > Sidebar ##*/ + +#sidebar { + background-color: var(--body-bg); + font-size: 1.2em; + margin-right: 8px; + max-width: 11.2em; +} +#sidebar a { border: none; } + +.sidebar-section { + border: 3px solid var(--accent-line-color); + box-sizing: border-box; + padding: 1rem 1rem; +} +.sidebar-section ~ .sidebar-section { margin-top: 8px; } + +/*### Wrapper > Sidebar > header ###*/ + +#header { border-right: none; + font-size: 1.5em; +} +#expandNavbarBtn { float: right; margin-left: 1em; } + +/*### Wrapper > Sidebar > index ###*/ + +#index { border-right: none; border-bottom: none; } +.index-list { + margin: 0 0 0.5em 0.3em; + padding-left: 0.5em; + display: block; + border-left: 2px solid var(--border-color); +} +.index-list-item, .index-list-item:hover { + line-height: 1.2em; + display: block; /* Compatibility with Chrome 49.0.2623.112 (for old machines) */ +} + +/*### Wrapper > Sidebar > settingsWrapper ###*/ + +#settingsWrapper { border-top: none; border-bottom: none; + font-size: 1.2em; + line-height: 1em; +} +#settingsWrapper > .setting-btn { font-size: 0.5em; } + +/*### Wrapper > Sidebar > footer ###*/ + +#footer { border-left: none; border-top: none; + font-size: 0.7em; + overflow-x: hidden; + white-space: nowrap; +} + +/*## Wrapper > Article ##*/ + +article { + border-top: 3px solid var(--accent-line-color); + box-sizing: border-box; + flex: 1; + max-width: 56em; /* Equivalent to 50em on 19px font-size */ + margin-bottom: 1em; + overflow: auto; + padding: 0 1em; + + margin-left: auto; + margin-right: auto; +} +.article-wide { + max-width: initial; + margin-left: initial; + margin-right: initial; +} + +/*### Wrapper > Article > page navigation ###*/ + +#pagenav { + filter: opacity(64%); + font-size: 0.8em; + margin: 0 0 3rem 2rem; +} +#pagenav + h2, #pagenav + h3, #pagenav + h4 { margin-top: 0; } + +/*### Wrapper > Article > contents ###*/ + +#contents-container { + float: right; + margin-left: 2.5em; + background-color: var(--bg-color); + padding-right: 0.5em; +} +#contents-container > h2 { margin-top: -1rem; } + +/*### Wrapper > Article > section gap ###*/ + +.gap, .gap-small { + background-color: var(--body-bg); + margin: 0 -1em; +} +.gap { height: 1.5em; } +.gap-small { height: 0.5em; } + +/*### Wrapper > Article > special paragraphs ###*/ + +.special-par { + position: relative; + padding: 0.5em; + padding-left: calc(32px + 1em); +} +.special-par-icon { + vertical-align: middle; + position: absolute; + left: 0.5em; + top: calc(50% - 16px); +} + +.question-par { border-left: 2px solid #4a85cb; } +.warn-par { border: 2px dashed #fac848; } +.important-par { border: 2px solid #f46062; } + +/*### Wrapper > Article > page-specific ###*/ + +/*#### Exercise solution ####*/ + +.exercise-solution { float: right; font-weight: bold; } + +/* Slightly smaller than browser defaults https://stackoverflow.com/a/70720104/12036073 https://stackoverflow.com/a/47560151/12036073 */ +h2 ~ .exercise-solution { font-size: 1.4em; margin-top: 0.6em; } +h3 ~ .exercise-solution { font-size: 1.1em; margin-top: 0.8em; } + +/*#### Face in about page ####*/ + +#about-image { + float: right; + margin: 2em 1em 0 0; + max-width: 7.6em; +} + +/*#### Markdown overrides ####*/ + +.footnotes { font-size: 0.9em; margin-top: 3em; } +a[rev="footnote"] { border: none; } + +.language-terminal { + color: var(--terminal-fg); + background-color: var(--terminal-bg); +} + +/*#### No-property ####*/ + +.nodisplay { display: none !important; } +.no-wrap { + color: inherit; + vertical-align: baseline; + white-space: nowrap; +} + +/*### Wrapper > Article > buttons ###*/ + +.btn:hover { cursor: pointer; } +.btn:active { transform: scale(0.9); } + +.setting-btn { + text-align: center; + display: inline-block; + line-height: 1em; + border: 1px solid var(--border-color); + padding: 0.4em; +} + +.btn, .h-anchor { + /* Thanks https://stackoverflow.com/a/4407335/12036073 */ + + -webkit-touch-callout: none; /* iOS Safari */ + -webkit-user-select: none; /* Safari */ + -khtml-user-select: none; /* Konqueror HTML */ + -moz-user-select: none; /* Old versions of Firefox */ + -ms-user-select: none; /* Internet Explorer/Edge */ + user-select: none; +} + +/*### Wrapper > Article > footer ###*/ + +article > footer { + margin: 0 -1em; + padding: 0.5em; + border: 3px solid var(--accent-line-color); + border-left: none; + border-right: none; +} + +/*### Wrapper > Article > h, h-anchor ###*/ + +h1, h2, h3, h4, h5, h6 { + color: var(--header-color); + display: inline-block; + line-height: 1.25em; + border-bottom: 2px solid var(--border-color); +} +h1 { display: block; font-size: 1.7em; margin-block-end: 0.5em; } + +h1 + *, h1 ~ h1, .h-anchor + * { margin-top: 0; } +.h-anchor { color: var(--fg-color); border: none; } + +/* Slightly smaller than browser defaults https://stackoverflow.com/a/70720104/12036073 */ +h2 + .h-anchor { font-size: 1.4em; } +h3 + .h-anchor { font-size: 1.1em; } + +/*### Wrapper > Article > a ###*/ + +a, a strong { + border-bottom: 1px dashed; + color: var(--a-color); + text-decoration: none; +} +a:hover, a strong:hover { color: var(--a-hover-color); } +sup a, dt a { border: none; } +a * { color: var(--fg-color); } + +/*### Wrapper > Article > i, em, strong ###*/ + +i, em { color: var(--em-color); } +strong { color: var(--strong-color); } + +/*### Wrapper > Article > blockquote ###*/ + +blockquote { + border-left: 0.25em solid var(--blockquote-border-color); + color: var(--blockquote-color); + margin: 0 0 16px 0; + padding: 0 1em; +} +blockquote > :first-child { margin-top: 0; } +blockquote > :last-child { margin-bottom: 0; } + +/*### Wrapper > Article > dt, dd ###*/ + +dt, dd { + border: 2px solid var(--border-color); + border-bottom: none; + border-top: none; + padding: 0 0.5em; +} +dt { font-size: 1.2em; padding-top: 0.2em; } +dt * { vertical-align: middle; } +dd { + line-height: 1.5em; + margin: 0 0 1em 0; + padding: 0 0 0.4em 49px; +} + +/*### Wrapper > Article > img, hr ###*/ + +img { + box-sizing: border-box; + max-width: 100%; +} +img, hr { border: 1px solid var(--border-color); } +dt img, .svg { box-sizing: border-box; max-height: 1em; } +.pixelated-render { image-rendering: pixelated; } +.oldschool-badge { height: 38px; } +.flag { max-width: 1.3em; } /* Compatibility with Chrome 49.0.2623.112 (for old machines) */ + +.file-type-icon { min-width: 1.3em; vertical-align: middle; } +.borderless, .oldschool-badge, .file-type-icon { border: none; } + +/*### Wrapper > Article > code, pre ###*/ + +/* The following CSS is a modified version of sindresorhus's github-markdown-css repo: https://github.com/sindresorhus/github-markdown-css */ +code, pre { + font-family: monospace; + font-size: 85%; +} + +pre { + overflow: auto; + word-break: normal; + word-wrap: normal; +} + +code { + background-color: var(--pre-bg-color); + margin: 0; + padding: 0 0.4em; +} +pre code { + border: 0; + display: inline-block; + font-size: 100%; + overflow: visible; + padding: 0; + word-wrap: normal; +} +pre > code { + white-space: pre-wrap; + word-break: break-all; + padding: 0.9em; + width: 100%; + box-sizing: border-box; +} + +table code { + font-size: 0.7em; + white-space: normal; +} +dd code { font-size: 0.8em; } + +.HI-comment { color: var(--hi-comment); } +.HI-const { color: var(--hi-const); } +.HI-string { color: var(--hi-string); } +.HI-char { color: var(--hi-char); } +.HI-number { color: var(--hi-number); } +.HI-bool { color: var(--hi-bool); } +.HI-float { color: var(--hi-float); } +.HI-identifier { color: var(--hi-identifier); } +.HI-function { color: var(--hi-function); } +.HI-statement { color: var(--hi-statement); } +.HI-conditional { color: var(--hi-conditional); } +.HI-repeat { color: var(--hi-repeat); } +.HI-operator { color: var(--hi-operator); } +.HI-keyword { color: var(--hi-keyword); /* Label and Exception are keywords */ } +.HI-preproc { color: var(--hi-preproc); } +.HI-type { color: var(--hi-type); } +.HI-storageclass { color: var(--hi-storageclass); } +.HI-structure { color: var(--hi-structure); } +.HI-typedef { color: var(--hi-typedef); } +.HI-ignore { color: var(--hi-ignore); } +.HI-comment * { color: inherit; } /* If text inside a comment is matched, don't show it */ + +/*### Wrapper > Article > table ###*/ + +table { + border-collapse: collapse; + margin: 1em 0; + overflow: auto; +} +td, th { word-break: normal !important; padding: 0.5em; } +tr { background-color: var(--tr-bg-color); } +thead > tr, tr:nth-child(2n) { background-color: var(--alternating-row-color); } +th { border: 1px solid var(--table-border-color); font-size: 1.1em; font-weight: bold; } +td + td { border-left: 1px dashed var(--table-border-color); } +td:empty { height: 1em; } + +/*## Wrapper > Scroll Button ##*/ + +#scrollBtn { + font-size: 1.66rem; + padding: 0 0.15em; + bottom: 1rem; + right: 1rem; + z-index: 1; + transition-duration: 0.5s; + background-color: var(--bg-color); + display: none; + position: fixed; + border: 1px solid; +} + +/*## Small screen support ##*/ + +@media screen and ((max-width: 610px) or (max-height: 610px)) { + article { max-width: calc(100vw - 16px - 3px); margin-top: 8px; } + table td, table th { word-break: break-all; } + + #about-image { max-width: 4.38em; } + + #content-wrapper { border: none; flex-direction: column; } + #sidebar { max-width: initial; margin: 0; } + /* page-width.js */ + #changeWidthBtn { display: none; } +} + +/*## Printing support ##*/ + +@media print { + h2 + a img, h3 + a img, h4 + a img, h5 + a img, h6 + a img, + nav, #scrollBtn, .gap, .gap-small { display: none !important; } + + body { margin: 0; } + body, article { + background-color: white; + border: none !important; + } + + pre, code { white-space: pre-wrap !important; } + .language-terminal { color: var(--fg-color); background-color: var(--bg-color); } + .slide, .absolute-slide { transform: none !important; margin: 0; } +} diff --git a/src/teaching.md b/src/teaching.md index 29bad9b..c36de4d 100644 --- a/src/teaching.md +++ b/src/teaching.md @@ -4,5 +4,8 @@ This is a list of all the subjects I've taught professionally. <br> -&&bg 2023-2024   [3107 Увод в програмирането - практикум, КН, 8 група](/teaching/upp-2023) +&.bg 2023-2024   [З520 Обектно-ориентрано програмиране - практикум, КН, 8 група](/teaching/oop-2023) +: Хоноруван преподавател във [ФМИ](https://www.fmi.uni-sofia.bg/) на специалност [Компютърни науки](https://www.fmi.uni-sofia.bg/bg/kompyutrni-nauki) + +&.bg 2023-2024   [3107 Увод в програмирането - практикум, КН, 8 група](/teaching/upp-2023) : Хоноруван преподавател във [ФМИ](https://www.fmi.uni-sofia.bg/) на специалност [Компютърни науки](https://www.fmi.uni-sofia.bg/bg/kompyutrni-nauki) diff --git a/src/teaching/index.md b/src/teaching/index.md index 29bad9b..c36de4d 100644 --- a/src/teaching/index.md +++ b/src/teaching/index.md @@ -4,5 +4,8 @@ This is a list of all the subjects I've taught professionally. <br> -&&bg 2023-2024   [3107 Увод в програмирането - практикум, КН, 8 група](/teaching/upp-2023) +&.bg 2023-2024   [З520 Обектно-ориентрано програмиране - практикум, КН, 8 група](/teaching/oop-2023) +: Хоноруван преподавател във [ФМИ](https://www.fmi.uni-sofia.bg/) на специалност [Компютърни науки](https://www.fmi.uni-sofia.bg/bg/kompyutrni-nauki) + +&.bg 2023-2024   [3107 Увод в програмирането - практикум, КН, 8 група](/teaching/upp-2023) : Хоноруван преподавател във [ФМИ](https://www.fmi.uni-sofia.bg/) на специалност [Компютърни науки](https://www.fmi.uni-sofia.bg/bg/kompyutrni-nauki) diff --git a/src/teaching/oop-2023/index.md b/src/teaching/oop-2023/index.md new file mode 100644 index 0000000..63acb0f --- /dev/null +++ b/src/teaching/oop-2023/index.md @@ -0,0 +1,32 @@ +# Обектно-ориентирано програмиране - практикум, Компютърни науки, 8 група + +Материали на проведените през 2023/2024 практикуми по Обектно-ориентирано програмиране на Компютърни науки (2 поток), 8 група. + +**Зала:** ФМИ 120 || +**Време:** 13:15 - 15:00 || +**Ден:** Четвъртък +<br> +**Директни връзки:** +[Контакт с мен](../upp-2023/week1/welcome.html?a#section-4) | +[Решения на задачи](https://github.com/Syndamia/oop-2023-solutions) | +[Материали от семинари](https://github.com/Aleksis99/Object-Oriented-Programming_FMI_2023-2024) | +[Курс в мудъл](https://learn.fmi.uni-sofia.bg/course/view.php?id=10041) + +|№|Дата|Материали| +|-------|----|---------| +|1 |22.02.2024|[Организационно](./week1/organization.html?a) \|\| [Основни добри софтуерни практики](./week1/good-software.html?a) \|\| [Задачи](./week1/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week01) \|\| [GitHub classroom](https://classroom.github.com/a/UPJOzHty)| +|2 |29.02.2024|[Задачи](./week2/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week02) \|\| [GitHub classroom](https://classroom.github.com/a/3qPsfyyI)| +|3 |07.03.2024|[Задачи](./week3/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week03) \|\| [GitHub classroom](https://classroom.github.com/a/KPMqXsFp)| +|4 |14.03.2024|[Задачи](./week4/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week04) \|\| [GitHub classroom](https://classroom.github.com/a/qa_FfWeG)| +|5 |21.03.2024|[Задачи](./week5/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week05) \|\| [GitHub classroom](https://classroom.github.com/a/42ZZ56Mg)| +|6 |28.03.2024|[Задачи](./week6/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week06) \|\| [GitHub classroom](https://classroom.github.com/a/rzSTn5pu)| +|7 |04.04.2024|[Задачи](./week7/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week07) \|\| [GitHub classroom](https://classroom.github.com/a/vvZENbkX)| +|8 |11.04.2024|[Задачи](./week8/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week08) \|\| [GitHub classroom](https://classroom.github.com/a/7d0MBjcK)| +|9 |18.04.2024|[Задачи](./week9/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week09) \|\| [GitHub classroom](https://classroom.github.com/a/wlL1oUg2)| +|10|25.04.2024|[Задачи](./week10/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week10) \|\| [GitHub classroom](https://classroom.github.com/a/PbkITWhF)| +|11|09.05.2024|[Задачи](./week11/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week11) \|\| [GitHub classroom](https://classroom.github.com/a/oYQehcnN) **Това упражнение е от 11:15 до 13:15**| +|12|09.05.2024|[Задачи](./week12/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week12) \|\| [GitHub classroom](https://classroom.github.com/a/o7hNz1pr)| +|13|16.05.2024|[Задачи](./week13/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week13) \|\| [GitHub classroom](https://classroom.github.com/a/GvV1wrC1)| +|14|23.05.2024|[Задачи](./week14/) <!-- \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week12) --> \|\| [GitHub classroom](https://classroom.github.com/a/K0XomKEP)| +|15|30.05.2024|[Задачи](./week15/) <!-- \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week12) --> \|\| [GitHub classroom](https://classroom.github.com/a/z2QadyEE) **Това упражнение е от 11:15 до 13:15**| +|16|06.06.2024|[Задачи](./week16/) <!-- \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week12) --> \|\| [GitHub classroom](https://classroom.github.com/a/BWjw2dUC)| diff --git a/src/teaching/oop-2023/week1/good-software.md b/src/teaching/oop-2023/week1/good-software.md new file mode 100644 index 0000000..79a51b0 --- /dev/null +++ b/src/teaching/oop-2023/week1/good-software.md @@ -0,0 +1,519 @@ +# Основни добри софтуерни практики - ООП, Седмица 1, 22.02.2024 + +Миналия семестър не ни стигна времето да обсъдим домашното по-сериозно. +Главния проблем, който забелязах, беше колко грозно и нагласено бяха написани решенията. +Като въведение в ООП, ще поговорим по тази тема. + +&.presentation + +&[title + +# Основни идеи<br>при добро писане на код + +&] + + + +&[slide35 + +## Какво прави програмиста с чужд код? + +&.br4 + +1. Чете +2. Разучава как се ползва/какво прави +3. Използва го/Модифицира го + +Добър код прави тези задачи лесни! + +&] + + + +&[slide35 + +## Подобряване на четене + +&.br4 + +- Лично вярвам, че четимост е по-важна от конвенции +- Човек вижда най-лесно "контрастни" шаблони + + +``` + . . 0.00.0 010010 815213 + 000000 000000 738438 +. . .0000. 100001 122481 + .... 0....0 011110 511119 +``` + +&] + + + +Както виждате, в примера има усмихнато личице, "закодирано" по различни начини. +С точка и шпации е най-ясно, като заменим шпациите с нули става по-неясно, като заменим точките с единици става още повече и като заменим нулите със случайни не-единични цифри, става пък съвсем невидимо. +Важното е шаблона да се намира в среда на други шаблони, иначе трудно се забелязва. + +При код, ще илюстрирам идеята си с един пример, но няма да задълбавам, следващата секция е много по-важна. +Пък и тази тема е малко религиозна и ще чувате различни мнения според човека който питате. + + + +&[middle + +Труден за четене код *(забелязвате ли грешките?)*: + +&(font22 + +``` +int a, b; +std::cout << "Enter coordinates" << std::endl; +std::cin >> a; +if (a == -1) return layerNavigation(board, rows, cols, layers); +if (a < 0 || a >= rows || b < 0 || a >= cols) return false; +for (int i = 0; i < layers; i++) { +if (board[a][b][i] == ' ') { + for (int j = 0; j < 8; j++){ + if (enptyRow[j] != ' ') { + emptyRow[j] = board[a][b][i]; + board[a][b][i] = ' '; + return true; + } + } + return false; +} +} +``` + +&) &] + + + +Нарочно съм премахнал оцветяването, то драстично помага, но тук повече се интересуваме от "формата" на код. + +Вмъкнал съм три грешки: едно нещо липсва, има една печатна и една логическа грешка. +Разбира се, ако се зачетете дума по дума сигурно ще ги откриете, но сега да сравним. + + + +&[middle + +По-лесен за четене код *(а сега виждат ли се по-лесно?)*: + +&(font18 + +``` +std::cout << "Enter coordinates" << std::endl; +int a, b; + +std::cin >> a; +if (a == -1) { + return layerNavigation(board, rows, cols, layers); +} + +if (a < 0 || a >= rows || b < 0 || a >= cols) { + return false; +} + +for (int i = 0; i < layers; i++) +{ + if (board[a][b][i] == ' ') + { + for (int j = 0; j < 8; j++) + { + if (enptyRow[j] != ' ') { + emptyRow[j] = board[a][b][i]; + board[a][b][i] = ' '; + + return true; + } + } + return false; + } +} +``` + +&) &] + + + +Би трябвало да е малко по-лесно, в последния `if` имаме "e**n**ptyRow", което е печатната грешка, `!=` което трябва да бъде `==` и липсва въвеждането на `b` след първия `if`. + +Примерът не е перфектен, но илюстрира какво се опитвам да кажа: формата на код е от огромно значение, обръщайте ѝ внимание. + + + +&[slide + +## Абстракцията - улеснява изучаване И употреба/модификация + +&.br1 + +- Разделяме обработване на стойностите от директната имплементацията +- Създаваме нови "машинни инструкции" + +&.br1 + +- `doX()` е по-лошо от `do(X)` + - можем да преизползваме `do()` за неща, различни от `X` + - един път разбрано, всяка употреба на `do()` също е разбрана; този стил кара `do()` да бъде по-обща функция, което я прави по-лесна за разбиране + - модификация на `do(X)` се свежда до заменяне на `do()` с `doOther()` или до заменяне на `X` с `Y`; променяме "инструкцията" или променяме данната + +&] + + + +Нека сега разгледаме няколко примера, първият е много груб и елементарен, но служи за добро начало: + + + +&[middle + + +```cpp +Лошо - doX() │ Добро - do(X) + │ +int fib5() │ int fib(int n) +{ │ { + int prev = 0, curr = 1; │ int prev = 0, curr = 1; + for (int i = 1; i < 5; i++) │ for (int i = 1; i < n; i++) + { │ { + int tempPrev = prev; │ int tempPrev = prev; + prev = curr; │ prev = curr; + curr = curr + prev; │ curr = curr + prev; + } │ } + return curr; │ return curr; +} │ } +``` + +&] + + + +Би трябвало да е супер очевидно, никой няма да пише отделна функция на Фибоначи за всяко число. + +Нека сега да разгледаме няколко "реални" примера, свързани с домашното (за припомняне, условието се намира [тук](https://learn.fmi.uni-sofia.bg/mod/assign/view.php?id=296069)). +Самите решения няма винаги да са добре форматирани, това е направено с цел да се поберат добре в слайда. + +Първия е върху функция, която приема координатите на плочка, премахва я от дъската (ако съществува) и я слага в края на празния ред. + + + +&[slide + +Лошо - `doX()` в тялото на функцията + +```cpp +void tryTakeTile(char** board, int rows, int cols, + char emptyRow[8]) { + int x, y; + std::cin >> x >> y; + if (x<0 || x>=rows || y<0 || y>=cols || board[x][y] == ' ') { + std::cout << "Invalid coordinates!" << std::endl; + } + else { + int emptyRowIndex = -1; + for (int i = 0; i < 8; i++) { + if (emptyRow[i] == ' ') { + emptyRowIndex = i; + break; + } + } + emptyRow[emptyRowIndex] = board[x][y]; + board[x][y] = ' '; + } +} +``` + +&] + + + +Повечето предадени работи са имплементирали функционалността по точно този начин. +Замислете се обаче, какво става ако сменим типа данна, тоест ако дъската е триизмерна? +Тогава трябва да добавим още една `int` променлива, още едно условие в `if`, трябва да я добавим при трите индексирания на `board`. + +Какво става ако променим самата структура от данни за `emptyRow` (за сега сте учили само масиви, но скоро ще видите, че има и други начини да съхраняваш редица информация), тогава ще трябва да пренапишем целия цикъл. + +Тоест, ако променим нещо, трябва да пренапишем значителни части от самия код, и като разширим това върху 10-20 функции, изведнъж малка промяна става голяма. +Нека сега да пренапишем функцията, използвайки колкото се може повече абстракция. + + +&[middle + +Добро - `do(X)` + +```cpp +bool tryReadCoordinates(int& x, int& y) { + std::cin >> x >> y; + if (!availablePosition(board, rows, cols, x, y)) { + std::cout << "Invalid coordinates!" << std::endl; + return false; + } + return true; +} + +void tryTakeTile(char** board, int rows, int cols, + char emptyRow[8]) { + int x, y; + if (tryReadCoordinates(x, y)) { + appendToArray(emptyRow, 8, board[x][y]); + board[x][y] = ' '; + } +} +``` + +&] + + + +Искаме трето измерение на `board`? +Няма проблем, написали сме нова `tryReadCoordinates`, която приема три променливи, и в `tryTakeTile` добавяме една декларация и обновяваме двете индексирания на `board`. +Ако `emptyRow` стане друг тип данна, просто променяме функцията да бъде `appendToOtherDataType` и сме готови. + +И ако тази промяна трябва да се направи в много функции, даже бихме могли да употребяваме функционалност на самия текстов редактор да търси и заменя срещания на един низ с друг. + +Нека сега да увеличим сложността още малко, да разгледаме функция за генерирането на дъската. +Отново, повечето предадени решения изглеждаха подобни на примера. + + + +&[slide + +Лошо - всички цикли са `doX()` + +```cpp +void generateLayer(char** layer, int rows, int cols, + char* tiles, int* tileCounts, int tilesSize) { + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + layer[i][j] = ' '; + } + } + for (int i = 0; i < tilesSize; i++) { + for (int j = 0; j < tileCounts[i]; j++) { + int x, y; + do { // randNum(x,y) връща случайно число∈[x,y] + x = randNum(0, rows - 1); + y = randNum(0, cols - 1); + } while(layer[x][y] != ' '); + layer[x][y] = tileCounts[i]; + } + } +} +``` + +&] + + + +Стария проблем, някакви цикли, ако искаме да променям някоя данна или как нещо работи, трябва да пренапишем половината функция. + +Този сегмент е по-интересен за променяне от преди, понеже за да го направим хубаво трябва да променим самата ни логика. +Запълването със шпации е ясно, обаче случайното поставяне на плочки не е. + +Ако имаме функция `placeRandomЕлемент` която само поставя една плочка в слоя, пак ще имаме вложени цикли, трябва да има начин да останем с един цикъл. +Ако направим `placeRandomElementNTimes`, тогава пък абстрахираната функция става твърде специфична и вече имаме `doX()` при самата нея. + +Чрез функционално програмиране този проблем може да се разреши лесно, обаче вие ще го учите следващия семестър. +С достатъчно размишления, може да стигнем до следния вариант: вместо всяка плочка да я поставяме на случайна позиция, защо не поставим всички плочки една след друга и не разбъркаме слоя? + + + +&[middle + +Добро - `do(X)` + +```cpp +void generateLayer(char** layer, int rows, int cols, + char* tiles, int* tileCounts, int tilesSize) { + fillMatrix(layer, rows, cols, '\0'); + for (int i = 0; i < tilesSize; i++) { + // appendToMatrix(mat,rows,cols,fill,max): + // замества първите (най-много) max празни клетки с fill + // връща колко клетки наистина е заместило + appendToMatrix(layer, rows, cols, + tiles[i], tileCounts[i]); + } + shuffleMatrix(layer, rows, cols); +} +``` + +**Бонус:** работи по-коректно от преди + +&] + + + +В предходния вариант, ако примерно цялата е пълна освен една клетка, и трябва да поставим една финална плочка, тогава трябва да чакаме докато случайните стойности се напаснат точно с координатите на тази една клетка. +Това може да се случи след половин секунда, но може да отнеме и един час докато се случи. +Даже, този проблем става все по-тегав с времето: с всяка запълнена клетка, шанса случайните стойности да ударят на заети координати се увеличава. + +Докато тук, нямаме този проблем, отнема някакво консистентно предопределено време да разбъркаме матрицата. +Как имплементираме `shuffleMatrix` си има и своите тънкости, но най-елементарния начин е просто да направим сортираш алгоритъм, при който вместо да сравним две стойности, използваме случайна стойност, която определя дали ще разменим плочките. + +Друго хубаво нещо на решения с абстракция, е един лек лавинен ефект, където веднъж като почнем да мислим за абстракции, намираме къде да ги ползваме навсякъде. +Да разгледаме същата функция, обаче при D подточка. + + + +&[middle + +Решения със слоеве правят същото. Лошо - `doX()` при циклите: + +```cpp +void generate(char*** board, int rows, int cols, int layers, + char* tiles, int* tileCounts, int tilesSize) { + ... + do { + x = randNum(0, rows - 1); y = randNum(0, cols - 1); + layer = randNum(0, layers - 1); + } while(layer[x][y][layer] != ' '); + ... +} +``` + +&] + + + +Без абстракция отново ще пренапишем голяма част от `generate` функцията, за да се побере на слайда съм оставил само "най-сложната" промяна - случайните стойности. +Пак, имаше решения на подточката, без преизползване на `generate` за един слой. +Айде да разгледаме решението, заедно с абстрахираната `generate`. + + + +&[slide + +Добро - `do(X)` + +```cpp +void generateLayer(char** layer, int rows, int cols, + char* tiles, int* tileCounts, int tilesSize) { + fillMatrix(layer, rows, cols, '\0'); + for (int i = 0; i < tilesSize; i++) { + int actuallyAppended = + appendToMatrix(layer, rows, cols, + tiles[i], tileCounts[i]); + tileCounts[i] -= actuallyAppended; + } + shuffleMatrix(layer, rows, cols); +} +void generate(char*** board, int rows, int cols, int layers, + char* tiles, int* tileCounts, int tilesSize) { + for (int i = 0; i < layers; i++) { + generateLayer(board[i], rows, cols, + tiles, tileCounts, tilesSize); + } +} +``` + +&] + + + +Супер елементарно, има-няма 5-6 реда код промяна, при генериране за всеки слой, просто извикваме функцията за генериране върху един слой, за всеки слой. +А в самата функция само премахваме броя вмъкнати плочки от сумата на даден тип. + +Наблюдателните са забелязали, че в "ръчното" решение слоевете са третия индекс, тоест имаме `board[x][y][layer]`, докато в това решение е първия, тоест `board[layer][x][y]`. +Разликата е значителна, но от гледна точка на код, особено когато използваме абстракция, промяната е лесна. + +Иначе, в момента се намираме в много добра позиция, без абстракция как правим рестартирането на играта? +По условие броя и типовете плочки трябва да се запазят, но позиции не. +Истината е, че става малко тромаво: цикълът за намираме на позиции се преизползва, и броя плочки трябва да се запази. + +Обаче, сега това става с едно `shuffleMatrix`, не е нужно нищо специално да правим! + + + +&[middle35 + +### Абстракцията - подобрява и коментари + +- Целта на коментарите е да направи разбиране и модификация на код по-лесни. +- В повечето случаи, коментарът трябва да ни дава *нова* информация или да *свърже* парчета информация + +&] + + + +Да разгледаме следния пример. + + + +&[middle + +Лошо: + +```cpp +// Fill matrix with '\0' +for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + matrix[i][j] = '\0'; + } +} +``` + +Добро: + +```cpp +// Prepare matrix for functionX +// (for which empty cells are '\0') +for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + matrix[i][j] = '\0'; + } +} +``` + + +&] + + + +При добрия вариант, получаваме нова информация, че това запълване се случва понеже ще подаваме към някаква си `functionX`, и че евентуално може да има други функции, при които празни клетки може да не се обозначават с `'\0'`. +В лошия можем да стигнем до същото заключение като погледнем самия код. + +<!-- +<br> + +Всичко това е много хубаво, обаче цитирайки Дийкстра, малки изолирани примери не са достатъчни: + + + +&[middle + +> For practical reasons, the demonstration programs must be small, many times smaller than the "life-size programs" I have in mind. My basic problem is that precisely this difference in scale is one of the major sources of our difficulties in programming! + +— Edsger W. Dijkstra, [Notes on Structured Programming, On our inability to do much](https://www.cs.utexas.edu/users/EWD/ewd02xx/EWD249.PDF) + +&.br1 + +Решение на цялото домашно, с описаните методи TODO + +&] + + + +Окуражавам ви да разгледате решенията, да ги сравните с вашите и поне да придобиете някаква интуиция за нещата. +Така да мислиш не е лесно, отнема време и усилия. +--> + +Умението да разрешиш един проблем *не те* прави добър програмист, да го разрешиш по четим, разширяем, лесен, ефикасен, ... начин *те* прави добър програмист. + + + +&[slide35 + +## Изводи + +&.br4 + +- Форматирайте/подравнявайте си кода, искате лесно четене +- Вдигайте абстракция + - Обширни функции > код за конкретни стойности + - Преизползване на възможно най-много код + - Коментари които дават или разширяват знание + +&] diff --git a/src/teaching/oop-2023/week1/index.md b/src/teaching/oop-2023/week1/index.md new file mode 100644 index 0000000..df05b2e --- /dev/null +++ b/src/teaching/oop-2023/week1/index.md @@ -0,0 +1,111 @@ +# Задачи - ООП, Седмица 1, 22.02.2024 + +GitHub classroom: [classroom.github.com/a/UPJOzHty](https://classroom.github.com/a/UPJOzHty) + +## Задача 1 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise1.cpp) + +Имплементирайте низ чрез структура. +В структурата трябва да запазвате указател към низа и неговата дължина. + +Имплементирайте функция `concatString`, която приема две структури от този тип и връща низ, пак в същата структура, който е конкатенация (слепване) на първите два низа. + +&:question Има ли значение дали типовете на аргументите, или на върнатата стойност, са референции или указатели (или нито едното)? + +В самия код тествайте функциите (не е нужен потребителски вход). + +## Задача 2 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise2.cpp) + +Имплементирайте структура за динамично-заделен масив от целочислени числа. +Тя трябва да запазва указател към масива, размера на масива и бройката на елементи в масива. + +Заделянето на динамична памет е бавна операция, затова винаги ще заделяме повече клетки, отколкото са ни нужни. + +Имплементирайте функция `resize`, която удвоява размера на масива (нека първоначалния размер на масива е 2), на подадена стойност от тип вашата структура. + +Имплементирайте функция `addToEnd`, която приема (инстанция на) структурата ви и вмъква елемент в първата незаета позиция. + +В самия код тествайте функциите (не е нужен потребителски вход). + +## Задача 3 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise3.cpp) + +Разглеждате "пакети" (логове) информация от редица датчици. +Един пакет запазва времето, когато информацията е била отчетена от датчиците, и стойностите на всички датчици: температура, атмосферно налягане, влажност и надморска височина. +Всички типове данни са целочислени. + +От входа получавате N, броя пакети, които трябва да запазите, и след това 5N на брой целочислени стойности. +Накрая получавате буква: `t`, `p`, `h`, `e`, всяка съответства на някоя отделна стойност от датчиците. + +Трябва да изкарате на екрана всичките стойности от пакетите, подредени в нарастващ ред на времето, като всички след първата са разликите им спрямо първата. + +**Пример:** + +|Вход|Изход| +|----|-----| +|6<br>56 45 64 -8 98<br>14 40 -15 -18 -1<br>22 89 72 62 4<br>85 44 60 17 13<br>75 18 -12 48 21<br>27 10 94 -5 16<br>p|-15 87 109 79 3 75| + +## Задача 4 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise4.cpp) + +Направете структура за съхранение на полети[^sabre]. +Трябва да запазите имената на началния и крайния град като низове (допускаме, че няма шпации в имената на градовете), часът на излитане и на кацане в целочислен формат (като на циферблат на дигитален часовник, без разделителното двоеточие) и цената на полета в тип с плаваща запетая (в долари). + +### а) въвеждане + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise4.cpp#L15-L36) + +От входа получавате N, това определя броя полети, които трябва да се добавят в системата. +Всеки полет е редица от 5 стойности, в реда в който са дефинирани. + +*Напомням, че това е нагласено да ползвате `std::cin` вместо ръчно да обработвате целия ред.* + +Изкарайте началните и крайните градове, както и цената на полетите, подредени в нарастващ ред на час на излитане. + +**Пример:** + +|Вход|Изход| +|----|-----| +|5<br>Berlin Paris 1105 1255 140<br>Sofia Paris 0915 1115 140<br>Paris NewYork 1225 1610 500<br>Sofia NewYork 0610 1345 800<br>Sofia Berlin 1020 1130 200|Sofia NewYork 800<br>Sofia Paris 140<br>Sofia Berlin 200<br>Berlin Paris 140<br>Paris NewYork 500| + +### б) търсене + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise4.cpp#L38-L247) + +След като се въведат всички полети, получавате от входа два низа - имена на градове. +Трябва да изкарате най-евтиния, и след него най-бързия, вариант за пътуване от първия град към втория. + +Прикачване между полети е позволено, така че под "вариант" трябва да изкарате всичките полети, които са решение. +За един полет е нужно да изкарате само началния град, крайния град, час на излитане и цена, като градовете трябва да са подредени в нарастващ ред на часа на излитане. + +**Пример:** + +|Вход|Изход| +|----|-----| +|5<br>Berlin Paris 1105 1255 140<br>Sofia Paris 0915 1115 140<br>Paris NewYork 1225 1610 500<br>Sofia NewYork 0610 1245 800<br>Sofia Berlin 1020 1130 200<br>Sofia NewYork|Cheapest:<br>Sofia Paris 0915 140<br>Paris NewYork 1225 500<br>Quickest:<br>Sofia NewYork 0610 800| + + +## Задача 5 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise5.cpp) + +Имате система за потребители, всеки потребител си има име и приятели (един приятел е **указател към потребител**). + +В началото се въвежда N, това е броят потребители в системата. +За един потребител, първо се въвежда на нов ред името му, след това броя на неговите приятели и накрая, на отделни редове, имената на всички тези приятели. + +Накрая получавате едно име, това е началния потребител. +Трябва да намерите, започвайки от него, с колко други потребителя има някаква приятелска връзка (директна, приятел на приятел, приятел на приятел на приятел, ...). + +**Пример:** + +|Вход|Изход| +|----|-----| +|5<br>Георги<br>2<br>Асен Гьонов<br>Майстора<br>Асен Гьонов<br>2<br>Георги<br>др. Божидаров<br>Майстора<br>1<br>Георги<br>др. Божидаров<br>1<br>Асен Гьонов<br>Павел<br>0<br>Майстора|3| + +[^sabre]: Защото една от първите индустрии, които са се нуждаели от компютърни системи, била [авиационната индустрия](https://en.wikipedia.org/wiki/Sabre_%28travel_reservation_system%29#History). diff --git a/src/teaching/oop-2023/week1/organization.md b/src/teaching/oop-2023/week1/organization.md new file mode 100644 index 0000000..92fdcc8 --- /dev/null +++ b/src/teaching/oop-2023/week1/organization.md @@ -0,0 +1,61 @@ +# Организация - ООП, Седмица 1, 22.02.2024 + +&.presentation + +&[title35 + +# Добре дошли в ООП + +&] + + + +За разлика от Увод в програмиране, по ООП практикума е малко по-специален. + + + +&[middle35 + +- ООП практикум е избираема, която няма смисъл да не запишете + - Само плюсове за вас +- Оценката е според контролни/изпити по ООП + +&] + + + +Така ви помагаме с избираемите: по учебен план трябва да имате поне 2 практикума, сравнително безплатно получавате единия. +Относно оценяване: + + + +&[middle35 + +- Освобождаване от изпит според работата ви по време на практикум +- Няма намаляване на оценка +- Оценявам общите ви умения<br> + Важното е да умеете да сте програмисти: коректност, брой и трудност на решени задачи се зачитат по-малко отколкото успех да напишете прилично-изглеждаща програма (дори с малко мой тласък) + +&] + + + +Все пак не може да ви даваме безплатни оценки, затова: + + + +&[middle35 + +- Зачитат се **единствено нещата, качени в GitHub classroom, качени в срок** + - До **15** минути след края на часа +- Както преди, не е нужно да присъствате, за да качвате решения +- Ако случайно някой не знае как се ползва: + +&(centered [syndamia.com/upp-2023/week1/setup.html?a](../upp-2023/week1/setup.html?a) &) + +&] + + + +Който по време на УП е използвал GitHub classroom не би трябвало да прави нещо, продължавате си по старо му, със същите акаунти. +Разбира се, за всякакви проблеми се [свържете с мен](../upp-2023/week1/welcome.html?a#section-4). diff --git a/src/teaching/oop-2023/week10/index.md b/src/teaching/oop-2023/week10/index.md new file mode 100644 index 0000000..06d9a7b --- /dev/null +++ b/src/teaching/oop-2023/week10/index.md @@ -0,0 +1,146 @@ +# Задачи - ООП, Седмица 10, 25.04.2024 + +GitHub classroom: [classroom.github.com/a/PbkITWhF](https://classroom.github.com/a/PbkITWhF) + +## Преговорни + +&:warn Моля, не отделяйте на преговорните задачи повече от 30мин + +### Задача 1 - Шаблони + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise01) + +Реализирайте шаблонен клас `Array`, който запазва динамично-заделен и оразмеряем масив от елементи с подаден тип. +Имплементирайте голяма четворка. + +### Задача 2 - Оператори + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise02) + +За предходния шаблонен клас имплементирайте оператори: + +- [], който връща референция към елемента на подадения индекс +- == и !=, които сравняват поелементно +- +, += които конкатенират (слепват) два масива + +### Задача 3 - Грешки + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise03) + +Имплементирайте функция, която приема име на текстов файл и изкарва на екрана първия ред от него. +Ако файлът не може да бъде отворен, хвърлете грешка - низ. +Ако във файлът няма други редове (няма знакът `'\n'`), тогава хвърлете грешка число - размерът на файла. + +В главната функция, приемете името на файла от потребителския вход и извикайте функцията. +Ако файлът не може да бъде отворен, тогава изкарайте хвърлената грешка на терминала и приключете програмата (успешно). +Ако няма други редове в него, тогава изкарайте съобщението "In X characters, there is no newline!", където X е хвърленото число, и пробвайте да приемете пак име на файла от потребителския вход. + +## Лесни + +### Задача 4 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise04) + +Реализирайте клас `Time24`, който запазва час и минути (в 24-часов формат) в две отделни целичислени член-данни. +Имплементирайте член-функция `Print24`, която изкарва часа на екрана в 24-часов формат. +Нека конструкторът му приема две целочислени променливи, една за часа и втора за минутите. + +Реализирайте негов наследник `Time12`, който имплементира метод `Print12`, принтиращ часа в 12-часов формат. +Имплементирайте и негов конструктор, който приема две целочислени променливи (една за часа и една за минутите), заедно с булева променлива описваща дали часа е следобеден или не. + +### Задача 5 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise05) + +Реализирайте клас `FN`, който запазва факултетен номер като неотрицателно цяло число от 5 цифри. +Реализирайте негов наследник `ModernFN`, който запазва и начален (префиксен) низ, състоящ се от цифра, две букви и още две цифри. + +Имплементирайте конструктори, като този на `FN` приема число, докато този на `ModernFN` приема низ, състоящ се от целия факултетен номер (и трябва да конвертирате последните 5 цифри към число). +Имплементирайте метод `PrintOldFN` на класа `FN` и метод `PrintNewFN` на класа `ModernFN`, които изкарват целия факултетен номер на съответния клас. + +### Задача 6 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise06) + +Реализирайте клас `Grade`, който запазва оценка (от 2 до 6) като неотрицателна целочислена член-данна. +Реализирайте и негов наследник `GradeWithName`, който запазва и името на оценката като низ с произволна дължина. + +Конструктора на `Grade` приема само числовата стойност, докато този на наследника приема и името на оценката. +Имплементирайте голяма петица на `GradeWithName`. + +### Задача 7 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise07) + +Реализирайте клас `String`, който запазва низ с произволна дължина. +Имплементирайте голяма петица и член-функция `At`, която приема индекс и връща референция към буквата на този индекс (при невалиден индекс хвърляте грешка). + +Реализирайте негов наследник `FileString`, който запазва и името на текстов файл като низ с произволна дължина. +Ако е нужно, имплементирайте голяма петица. + +Самия низ в `FileString` е първия низ (начало първата буква и край `'\n'`) от файла с подадено име. + +Имплементирайте метод `ChangeAt`, който приема индекс и нова буква, променя буквата на дадения индекс с подадената и обновява файла със запазеното име. + +### Задача 8 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise08) + +Реализирайте клас `User`, който запава име и парола като два низа с произволна дължина. +Реализирайте негов наследник `Moderator`, който запазва и подпис, който също е низ с произволна дължина. +Реализирайте наследник `Administrator` на `Moderator`, който запазва и оразмеряващ се масив от цели числа. + +Идеята е, че всяко действие от модератор или администратор се "подписва" публично (за да се знае, че той го е направил, дори да си смени името), а за администратор допълнително пазим масив от идентификатори на форуми, които администрира. + +За всеки клас имплементирайте голяма петица и гетъри и сетъри за името и паролата, когато е нужно. +За `Moderator` имплементирайте гетър за подписа, но без сетър. +За `Administrator` имплементирайте методи за добавяне и премахване на идентификатор на форум. + +### Задача 9 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise09) + +Реализирайте клас `CommunicationPacket`, който запазва начален и краен адрес като две неотрицателни цели числа, заедно с трето число за размера на данните. +В този клас никога няма данни, затова размера винаги е нула. + +Реализирайте негови наследници `StringPacket` и `IntPacket`, където първия запазва и низ с произволна дължина (и дължината му е размера на данните) докато втория запазва и едно цяло число (и размера на `int` е размера на данните). + +Размерът не се подава на конструктори, а се изчислява в конструктори. +Имплементирайте голяма петица и конструктори с нужните параметри. + +### Задача 10 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise10) + +Реализирайте клас `String`, който запазва низ с произволна дължина, и имплементира оператори ==, !=, + (който връща нов низ с конкатенацията на двата низа). + +Реализирайте негов наследник `ModifiableString`, който имплементира оператор[] (връщащ референция към буквата на дадения индекс) и оператор+=. + +Реализирайте наследник на `ModifiableString`, `ShowableString`, който имплементира оператори << и >>. +Реализирайте наследник на `ModifiableString`, `SaveableString`, който имплементира методи write и read, приемащи име на двоичен файл и записващи или четещи низа от този файл. + +За всички класове имплементирайте голяма петица, когато е нужно. + +## Трудни + +### Задача 11 + +Реализирайте шаблонен клас `Array`, който запазва оразмеряем масив с елементи от подаден тип. +Имплементирайте оператор== и оператор!=, заедно с метод `isEmpty`. +Концептуално идеята е, че този масив не може да се променя след като му се въведат стойностите от конструктора. + +Реализирайте негов наследник `PrintableArray`, който имплементира оператори << и >>. +Реализирайте наследник `SaveableArray` на `Array`, който имплементира методи write и read, приемащи име на файл и булева стойност дали е двоичен или не, и съответно прочитат или запазват елементите от този масив във файла. + +Реализирайте трети наследник, `ModifiableArray`, на `Array`, в който са имплементирани член-функции: + +- `push`, която приема елемент и го вмъква в (десния) края на масива +- `pop`, който премахва елемент от (десния) края на масива +- `last`, който връща последния елемент от масива + +Може да се налага масива да се оразмерява. +Като подсказка, имплементирайте си метод, наличен за класа и наследници, който вмъква елемент на произволен индекс. + +Реализирайте наследник `IndexableArray` на `ModifiableArray`, който имплементира оператор[]. +Ако индекса е след края, тогава "вмъквате" елементи по подразбиране между края и подадения индекс, и връщате елемента от сега новия край. +Реализирайте наследник `FrontableArray` на `ModifiableArray`, който имплементира методи `pushf` и `popf`, които работят като `push` и `pop`, но с елемента в началото на масива (първия елемент). diff --git a/src/teaching/oop-2023/week11/index.md b/src/teaching/oop-2023/week11/index.md new file mode 100644 index 0000000..8ac676b --- /dev/null +++ b/src/teaching/oop-2023/week11/index.md @@ -0,0 +1,201 @@ +# Задачи - ООП, Седмица 11, 09.05.2024 + +GitHub classroom: [classroom.github.com/a/oYQehcnN](https://classroom.github.com/a/oYQehcnN) + +## Преговорни + +&:warn Моля, не отделяйте на преговорните задачи повече от 30мин + +&:important Всеки бащин клас, във всички случаи, трябва да има виртуален деструктор (`virtual ~ClassName();`). + +### Задача 1 - Шаблони и оператори + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise01) + +Реализирайте шаблонен клас множество, който запазва фиксиран брой елементи от подаден тип. +Реализирайте голяма петица и оператори: + +- `+`, `+=` които действат като обединение +- `*`, `*=` които действат като сечение +- `-`, `-=` които действат като допълнение + +### Задача 2 - Наследяване + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise02) + +Реализирайте клас `Employee`, съхраняващ име на човек, позиция и департамент като низове със съответно дължина 512, 128 и 64, заедно със заплата като число с плаваща запетая. + +Реализирайте негов наследник `Manager`, който допълнително пази масив с фиксиран размер от Employee. + +Реализирайте наследника на `Employee`, `Developer`, който допълнително пази брой проекти върху който работи. + +Наследниците не могат да достъпят заплатата, но трябва да могат да достъпят другите данни на `Employee`. + +## Лесни + +### Задача 3 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise03) + +<!-- Динамично свързване, Inherit 3 --> + +Реализирайте клас `Electronics`, който съдържа модел (низ с максимална дължина от 255 знака), `needsVolts` и `needsAmps` (стойности с плаваща запетая). + +Имплементирайте негови наследници: + +- `Laptop`, който допълнително съхранява размер на екрана като число с плаваща запетая +- `WashingMachine`, който допълнително запазва максимално тегло на прането, като цяло неотрицателно число +- `Camera`, която допълнително запазва резолюция като число с плаваща запетая (в мегапиксели) + +За всеки клас реализирайте член-функция `Print`, която изкарва всички данни на екрана. + +&:question Чрез статично или динамично свързване сте имплементирали `Print`? Каква е разликата? + +### Задача 4 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise04) + +<!-- Dynamic linking, Inherit 2 --> + +Реализирайте клас `String`, който запазва динамично-заделен масив. + +Имплементирайте негов наследник `Name`, който допълнително запазва число: номер на името (първо име, бащино име (второ име), фамилия (трето име)). + +Имплементирайте втори наследник на `String`, `Street`, който запазва и число: номер на улицата. + +Във всеки клас имплементирайте голяма петица, член-функция `Length`, като: + +- в `String` връща дължината на низа, +- в `Name` връща дължината на името умножена по номера си и +- в `Street` връща дължината на името на улицата плюс броя цифри в номера на улицата. + +Самият низ в `String` **не** може да се достъпва от наследниците. + +### Задача 5 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise05) + +<!-- Templates 1 type --> + +Реализирайте шаблонен клас `Counted`, който запазва елемент от подаден тип и неговата бройка (цяло неотрицателно число). +Имплементирайте оператори `++`, `--`, `+=`, `-=`, които променят бройката, както и гетъри за елемента и бройката. + +### Задача 6 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise06) + +<!-- Templates 2 types --> + +Реализирайте шаблонен клас `TwoArray`, който запазва два динамично-заделени масива с подадени типове. +Масивите не могат да се оразмеряват и имат еднаква дължина. + +Имплементирайте: + +- голяма петица, +- оператор `[]`, който по подаден индекс връща елемент от първия масив, и +- оператор `()`, който по подаден индекс връща елемент от втория масив. + +### Задача 7 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise07) + +<!-- Abstract class --> + +Реализирайте абстрактен клас `DynamicArray`, който задължава наследниците да имплементират оператор `[]` и оператор `+=`. + +Реализирайте негови наследници: + +- `Numbers`, който "имплементира" динамично-заделен масив от цели числа, като + + оператор `[]` връща първия елемент, по-малък от подадения индекс. Ако няма такъв, връщате първия елемент. + + оператор `+=` вмъква елементите в началото на масива +- `String`, който "имплементира" динамично-заделен масив от букви, като + + оператор `[]` връща индекс на брой (първата, втората, ...) главна буква в низа. Ако няма такава, тогава връща последната буква. + + оператор `+=` вмъква елементите в края на масива + +Имплементирайте голяма петица. + +&:question Къде ще имплементирате динамичния масив и голямата петица? + +&:question Можем ли да използваме оператор `+=` в полиморфна йерархия? + +### Задача 8 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise08) + +<!-- Abstract class --> + +Имплементирайте абстрактен клас `Message`, който съдържа динамично-заделен низ (текстово съобщение, което се показва на екрана) и задължава наследниците да имплементират: + +- метод `size`, който връща общия размер на всички данни в байтове. + +Реализирайте негов наследник `Link` (хипервръзка), който запазва и втори динамично-заделен низ, запазващ адресът към който линкът сочи. + +Реализирайте втори негов наследник `Location`, чието текстово съдържание е адрес, и който допълнително запазва две стойности с плаваща запетая: една за географска ширина и втора за географска дължина. + +За всички класове реализирайте член-функция `Length`, която връща размера на **текстовото съобщение** и оператор `<<`. + +&:question Има ли разлика между оператор `<<` на трите класа? + +### Задача 9 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise09) + +Реализирайте абстрактен шаблонен клас `MixedArray`, който съхранява алтерниращи елементи от два типа. +Тоест, на индекс 0 имаме елемент от първия тип, на индекс 1 от втория, на индекс 2 от първи и так. нат. + +Елементите не е нужно да могат да се конвертират помежду си (тоест не може да използвате полиморфен контейнер), затова се достъпват с член функция `At`, приемаща индекс и референции към указатели към всеки тип. +При подаден индекс, на единия указател се записва адресът на съответната стойност, а на другия `nullptr`. + +Също имплементира голяма петица и задължава наследниците да имплементират оператори `+=`, върщащи указател. + +Реализирайте негов наследник `DirectConcat`, който реализира `+=` като директно слепване (конкатениране). + +Реализирайте втори негов наследник, `MixedConcat`, който реализир `+=` като алтернира елемент от първия масив с елемент от втория. + +## Трудни + +### Задача 10 + +Реализирайте система за документ с форматиран текст. +В нея всеки елемент от документа е от тип Node, като за един Node трябва да имате: + +- id, автоматично-избрано число, с което отличава Node +- operator<< +- operator[] + +Реализирайте следните типове Node: + +- paragraph, това е най-обикновен низ +- anchor, това е хипервръзка (линк), която съхранява видимо съдържание и уеб адрес +- emplaced link, това е хипервръзка при която видимото съдържание съвпада с уеб адреса +- заглавие, което е като хипервръзка, но уеб адресът започва с '#' и останалото съвпада със текстовото съдържание, като всяка буква е малка и вместо шпации има тирета +- bulletpoint list, който съхранява редица Node-ове и ги изкарва на екрана, всяко на нов ред, започващи с '-' +- table, която съхранява таблица с Node-ове + +Имплементирайте клас Document, който запазва масив от Node-ове и за който са имплементирани: + +- методи save и load, които запазват и четат цялото съдържание на документа в **текстов** файл с произволен формат. + +### Задача 11 + +Ще реализирате система за изпълнение на крайни автомати (от Теоретични Компютърни науки, ЕАИ). + +За тази цел е нужен абстрактен шаблонен клас State, чиито тип определя азбуката, който съхранява динамично-заделен масив от преходи (Transition) и задължава protected имплементация на член-функцията equal, която приема два елемента от азбуката и връща дали са равни. +Имплементирайте голяма петица и оператор +=, който вмъква нов преход в състоянието. + +Реализирайте абстрактен шаблонен клас Transition, чиито тип определя азбуката, и който съхранява елемент от този тип (стойността, която ако е равна на подадената ще изпълним прехода) и указател към следващо състояние. +Класът задължава имплементацията на оператор [], който по подаден елемент от азбуката или връща указателя към следващото състояние, или връща nullptr. + +Реализирайте наследник на State, ArrayState, който (допускате че) приема указател на динамичо-заделен масив. + +Реализирайте наследник на Transition, PrintedTransition, който при всяко извикване на оператор [] също изкарва съобщение на екрана. + +Реализирайте клас FiniteStateMachine, който съхранява динамичен масив от състояния. +За него имплементирайте голяма петица и конструктор, приемащ име на текстов файл в CSV формат, в който са запазени: + +- на първия ред обща информация във формата "Transitions,StartStateName", след това +- състояния и преходи във формата "StateName,OnValue,TransitionTo", после +- финални състояния във формата "FinalStateName1,FinalStateName2,...", и накрая +- входни букви от азбуката "Letter1,Letter2,...". + +Имплементирайте метод Run, който изпълнява автомата и връща булева стойност: дали приема входните букви или не. diff --git a/src/teaching/oop-2023/week12/index.md b/src/teaching/oop-2023/week12/index.md new file mode 100644 index 0000000..b492678 --- /dev/null +++ b/src/teaching/oop-2023/week12/index.md @@ -0,0 +1,94 @@ +# Задачи - ООП, Седмица 12, 09.05.2024 + +GitHub classroom: [classroom.github.com/a/o7hNz1pr](https://classroom.github.com/a/o7hNz1pr) + +### Задача 1 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week12/Exercise1) + +<!-- Multiple inheritance --> + +Реализирайте клас `Publication`, който пази: + +- низ от максимална дължина 1023, съхраняващ автори и +- втори низ с максимална дължина от 255, съхраняващ име на (научно) списание. + +Реализирайте клас `TextDocument`, който пази неоразмеряем низ с текстово съдържание и неговия размер. + +Реализирайте наследник на двата класа `ScientificPaper`, който допълнително пази и низ от максимално 511 знака, съдържащ име на научна дисциплина. +За всички класове реазлизирайте оператор <<. + +### Задача 2 + +*Не говорим за нея, условието беше толкова сбъркано, че се наложи да я сваля* + +### Задача 3 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week12/Exercise3) + +Реализирайте абстрактен клас `MobileDevice`, който запазва: + +- телефонен номер като цяло неотрицателно число и +- масив с максимална дължина от 511 знака за текстово съобщение. + +Допълнително нека: + +- класът да задължава имплементацията на метод `Show`, +- да има член-функция `CanAccept`, която по подадено "хиперсъобщение" връща дали неговия номер съвпада с този на класа. + Под "хиперсъобщение" имаме предвид низ, който започва с телефонния номер, след това има шпация и след това е самото съобщение. +- да има член-функция `Accept`, която по подадено "хиперсъобщение" запазва текстовото съобщение. + Ако номерът не съответства тогава хвърля грешка. + +Реализирайте негов наследник `Telephone`, за който `Show` изкарва съобщението на екрана. + +Реализирайте втори негов наследник `Pager`[^pager], който съхранява име на файл (като динамично-заделен низ) и `Show` изкарва съобщението в съответния файл. +Разбира се, имплементирайте голяма петица. + +Реализирайте клас `TelecommunicationCompany`, който съхранява динамично-заделен и оразмеряем масив от (указатели към) `MobileDevice`. +Имплементирайте всичко от голяма петица. + +### Задача 4 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week12/Exercise4) + +<!-- Multiple inheritance with mixed class types, polymorphic container, and copying --> + +Реализирайте клас `Employee`, който запазва: + +- заплата като число с плаваща запетая и +- производителост също като число с плаваща запетая. + +Производителността е множител на заплатата, тоест ако има производителност 0.5 значи работи като човек на който му плащат с половината заплата. + +Реализирайте абстрактен клас `Person`, който запазва: + +- име като низ с произволна дължина и +- възраст като цяло неотрицателно число + +Допълнително задължава реализацията на член-функция `Workload`, връщаща стойност с плаваща запетая. +Разбира се имплементирайте голяма петица. + +Реализирайте наследник на двата класа на име `Developer`, който допълнително запазва: + +- цяло неотрицателно число - брой проекти в които участва, и +- второ което е брой проекти на които ще се пуска нова версия. + +Реализирайте оператори `++` и `--`, като префиксните променят броя проекти на които ще се пуска нова версия, докато постфиксните променя броя проекти в които участва. +За него `Workload` се определя като 1.1 по всеки проект и допълнително по 2.3 за всеки проект на който ще се пуска нова версия. + +Реализирайте наследник на двата класа на име `Manager`, който допълнително запазва динамично-заделен и оразмеряем масив от `Person`, които менижира. + +Имплементирайте голяма петица и: + +- оператори `==` и `!=`, сравняващи хора по име +- член-функция `StartManaging`, която приема `Person` и го запазва, и +- член-функция `StopManaging`, която приема `Person` и го премахва от масива ако съществува в него. + +`Workload` се определя като 0.6 на човек който менижира. + +Финално реализирайте клас `Company`, който запазва масив от 128 указателя `Person` в компанията. +Имплементирайте негова член-функция: + +- `PaymentDifference`, която връща с колко платената заплата на всички служители се отличава с тази според тяхната производителност + +[^pager]: От времето без мобилни телефони, хората са си купували пейджъри, които ти пращат нотификация ако някой ти звънне и не вдигнеш. Пейджърите са "заключени" за определени региони, тоест някой ти се обажда, не вдигаш, и всички телекомуникционни кули в региона изпращат съобщение "на теб ти звънна този", и пейджъра като засече сигнала ти писука. Мисля че също можеш да пращаш кратки съобщения. Не е било хич сигурна система, все още се ползва от болници в някои държави. diff --git a/src/teaching/oop-2023/week13/index.md b/src/teaching/oop-2023/week13/index.md new file mode 100644 index 0000000..5d2ad35 --- /dev/null +++ b/src/teaching/oop-2023/week13/index.md @@ -0,0 +1,138 @@ +# Задачи - ООП, Седмица 13, 16.05.2024 + +GitHub classroom: [classroom.github.com/a/GvV1wrC1](https://classroom.github.com/a/GvV1wrC1) + +&:warn Навсякъде, където е нужно, реализирайте голяма петица. + +## Преговорни + +### Задача 1 - Множествено наследяване + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week13/Exercise1) + +Реализирайте клас `String`, който запазва динамичен низ с фиксиран размер. + +Реализирайте клас `IndexArray`, който запазва динамичен масив с фиксиран размер от цели числа - индекси. + +&:warn **Не** правете общ родител, който имплементира динамичен масив! + +Реализирайте наследник на двата класа, `WordsString`, при който индексите определят началото на всяка дума от запазения низ. +Индексите се дефинират при конструктора. + +## Лесни + +### Задача 2 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week13/Exercise2) + +<!-- Диамант --> + +Реализирайте шаблонен клас `Container`, който съхранява масив с фиксиран размер от елементи с подаден тип. +**Не** трябва да реализирате нищо повече от задължителните компоненти (голяма петица). + +Реализирайте негов наследник `Indexable`, който реализира оператор[]. + +Реализирайте втори негов наследник `Resizeable`, който реализира член-функция `InsertAt`, приемаща елемент и индекс, и която вмъква елемента на даден индекс. +Разбира се, може да се наложи оразмеряване на масива. + +Реализирайте наследник `Vector` на `Indexable` и `Resizeable`, който реализира оператор[] и член-функции: + +- `pop_back`, премахваща последния елемент +- `pop_front`, премахваща първия елемент +- `push_back`, приемаща елемент който се вкарва в края на масив +- `push_front`, приемаща елемент който се вкарва в началото на масив + +&:important Не забравяйте за диамантния проблем! + +### Задача 3 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week13/Exercise3) + +<!-- Диамант --> + +Реализирайте клас `User`, който запазва потребителско име и парола като низове с произволна дължина, заедно с булев флаг `banned`, определящ дали акаунтът може да прави действия. +Потребителско име не може да съдържа шпации. + +Реализирайте клас `Thread`, който запазва масив с произволна дължина, от низове с произволна дължина. +Имплементирайте член-функция: + +- `PostMessage`, която приема потребител и негово съобщение и добавя съобщението с потребителското име като един низ. + Ако потребителя е `banned`, тогава хвърлете грешка. + +Реализирайте наследник `ThreadModerator` на `User`, който може да променя `Thread` обекти, без да се нуждае от публични член-функции в `Thread`. +Имплементирайте методи: + +- `RemoveMessage`, който приема `Thread` и индекс на съобщение и премахва съответното съобщение +- `RemoveByUser`, който приема `Thread` и потребител, и премахва всички съобщения, направени от дадения потребител + +Реализирайте наследник `UserModerator` на `User`, който може да променя `User` обекти, без да се нуждае от публични член-функции в `User`. +Имплементирайте методите: + +- `BanUser`, който приема потребител и вдига `banned` флага +- `UnbanUser`, който приема потребител и сваля `banned` флага + +Реализирайте наследник `Administrator` на `ThreadModerator` и `UserModerator`, който може да прави всичко, което и родителите могат. + +&:important Не забравяйте за диамантния проблем! + +## Трудни + +### Задача 4 + +Реализирайте абстрактен клас `ShopLocation`, който съхранява член-данни: + +- адрес като низ с максимална дължина от 511 знака. + Всеки адрес съдържа произволни символи и задължително завършва на число, определящо неговия район. +- време на отваряне и време на затваряне + +Имплементирате методи: + +- `IsOpen`, който връща по подаден час дали локацията е отворена +- `InCenter`, който връща дали локацията се намира в центъра на града. + Всички адреси с регион, по-малък от 11, се намират в центъра. + +Реализирайте шаблонен клас `Inventory`, който съхранява **фиксиран** брой елементи и техните неотрицателни бройки (количества). +Имплементирайте член-функции: + +- оператор[], който връща елемент на дадения индекс +- оператор(), който връща бройка на елемент на дадения индекс +- `Stock`, приемащ индекс на елемент и бройка (положителна/отрицателна) с която бройката на дадения елемент се променя. + Бройката може да бъде най-малко 0. +- `List`, който връща всички елементи и техните индекси + +Реализирайте абстрактен шаблонен наследник `DeliverableInventory` на `Inventory`, който е инвентар с максимум 2048 елемента и допълнително задължава имплементацията на: + +- `ShippingDelay`, който приема адрес и връща времето в което ще може да се достави обекта + +Реализирайте наследник на `DeliverableInventory`, склад `Warehouse`, който допълнително запазва разстояние от града в километри и имплементира `ShippingDelay` по следната логика: + +- доставки в центъра отнемат един ден + регионът в който се доставя +- доставки извън центъра отнемат толкова време, колкото е нужно да се стигне до града ако пътува с 80 километра в час + времето което ще отнеме да се измине номер на региона на брой километри при скорост от 20 километра в час + +Доставка не може да се случи преди 9 сутринта и след 18 вечерта. +Ако попадне в този диапазон, тогава се отлага за най-скорошния следващ възможен час. + +Реализирайте шаблонен наследник магазин `Shop` на `ShopLocation` и `Inventory`, който е инвентар с максимум 256 елемента, запазващ: + +- **оразмеряем** масив от низове с произволен размер, всеки низ който е "отчет на продажба" +- общо бройка продажби + +и който имплементира методи: + +- `SellItems`, който приема масив от идентификатори на обекти, намалява бройката на всеки от тях и създава нов отчет. + Отчета е в произволен формат, но трябва да съдържа идентификаторите и бройките на всеки обект. + Ако за някой обект няма достатъчно бройки или изобщо не се пази, хвърлете грешка. + +Реализирайте шаблонен клас `WebStore`, който запазва оразмеряеми масиви от `Shop` и `Warehouse`. +Имплементирайте: + +- оператор<<, който изкарва всички уникални (unique) обекти от всички магазини и складове, с индекс до тях +- `GetEstimate`, който приема индекс на уникален обект от всички магазини и складове, сегашно време и адрес, и изкарва на екрана всички магазини които са отворени в дадения час и кое е най-скорошното време в което може обектът да се достави от склад. + Ако няма отворени магазини, ако няма магазин с наличност и так. нат. изкарайте съответно съобщение. + +Последно реализирайте клас `Book`, който запазва заглавие на книга и име на автор като низове с максимална дължина от 127 знака. +Имплементирайте оператор<<, който изкарва съответната книга в произволен формат. + +В главната функция реализирайте `WebStore` от книги, заедно с набор от книги, магазини и складове по ваш избор. +Нека в началото на програмата да приемате от потребителя сегашното време и адрес, след това изкарайте на екрана всички ункални книги с индекси. +Накрая потребителя може да въведе индекс на книга и да получи информация кои отворени сега магазини имат съответната книга и кога най-скоро може да бъде доставена от склад. diff --git a/src/teaching/oop-2023/week14/index.md b/src/teaching/oop-2023/week14/index.md new file mode 100644 index 0000000..917c11b --- /dev/null +++ b/src/teaching/oop-2023/week14/index.md @@ -0,0 +1,73 @@ +# Задачи - ООП, Седмица 14, 23.05.2024 + +GitHub classroom: [classroom.github.com/a/K0XomKEP](https://classroom.github.com/a/K0XomKEP) + +## Задача + +В тази задача се оставя голямо количество свобода на имплементация, за всяко нещо сами преценете типове, помощни класове/член функции, оператори и так. нат. +Както винаги, реализирайте голяма петица където е нужно. + +Препоръчително е първо да изчетете цялото условие и след това да пишете код. + +Реализирайте система като СУСИ. +Преди да стигнем до потребителите, ще се нуждаем от някои други компоненти. + +Реализирайте предмет, като в един предмет се пазят: + +- име +- тип (задължителен/избираем) +- брой ECTS кредити, които носи +- код, комбинация от главна буква и 3-цифрено число + +Реализирайте семестър, като в един семестър се пазят: + +- учебната година +- тип (зимен/летен) +- учебния план (низ във формата "СПЕЦИАЛННОСТ(УЧЕБЕН КУРС)") +- предмети; разбира се един предмет може да се споделя от няколко семестъра + +Реализирайте специалност, която пази: + +- свое име +- катедра към която е свързана +- всички семестри, в които е (била) активна +- предмети, съответстващи на всеки тип семестър + +и имплементира метод: + +- `NewSemester`, който приема учебна година и тип, и връща нов обект от семестър с попълнени данни + +Имаме потребители, като всеки си има роля, определяща неговите способности в системата. +Ролята може да бъде студент, преподавател или администратор, като при конкретизиране в условието на някои от тях трябва да се извършат съответните проверки. +Ваш избор е какво да бъде ролята. + +За един потребител със сигурност се пазят: + +- име +- факултетен номер (от модерния стил) +- потребителско име, което се определя като първата буква от първото име, конкатенирана с фамилията. + Ако съществува потребител с такова потребителско име, тогава добавяте букви от бащиното име, и накрая в краен случай, от първото име. +- парола +- година на учебния план +- име на сегашна специалност + +<br> + +- данни за контакт, като една данна съдържа тип и описание (произволни низове) + +<br> + +- семестри, в които е (бил) включен +- изпити, които са комбинация от предмети, преподаватели и оценки (която е възможно да не е въведена) + +Реализирайте мениджър на факултета, който съхранява, създава, обновява и премахва всички потребители и специалности. +Имплементирайте съответни член-функции, които да правят тези действия. + +Имплементирйате и методи, приемащи потребителско име, които: + +- за един потребител изкарва всички негови лични данни, заедно с кратко описание на семестрите в които е включен +- за един студент изкарва всички изпити, заедно със семестрите към които са свързани и сума на всички успешно получени кредити за дадения семестър (кредитите се броят само когато има оценка, която не е двойка) +- един преподавател може да създаде нов предмет +- един администратор може да създаде нов потребител, специалност, семестър, както и да свързва предмети със семестри и специалности + +Реализирайте конзолен интерфейс. diff --git a/src/teaching/oop-2023/week15/index.md b/src/teaching/oop-2023/week15/index.md new file mode 100644 index 0000000..6719bf0 --- /dev/null +++ b/src/teaching/oop-2023/week15/index.md @@ -0,0 +1,37 @@ +# Задачи - ООП, Седмица 15, 30.05.2024 + +GitHub classroom: [classroom.github.com/a/z2QadyEE](https://classroom.github.com/a/z2QadyEE) + +## Задача + +В тази задача се оставя голямо количество свобода на имплементация, за всяко нещо сами преценете типове, помощни класове/член функции, оператори и так. нат. +Както винаги, реализирайте голяма петица където е нужно. + +Препоръчително е първо да изчетете цялото условие и след това да пишете код. + +Реализирайте система за чат. +В нея имаме съобщения, като едно съобщение може да бъде: + +- текст, като низ +- локация, като съвкупност от държава, град, област (число), улица и номер на улица +- линк (хипервръзка) като текст и (уеб) адрес +- време: дата и час + +Всеки тип трябва да имплементира `Print` член-функция, която изкарва текстово съдържание на съобщението. +За текстово съобщение това е самия текст, за локация това е низ във формата "[ДЪРЖАВА] ГРАД(ОБЛАСТ) УЛИЦА NoНОМЕР НА УЛИЦА", за линк е самия текст и за време е "ЧАС:МИНУТИ ДЕН.МЕСЕЦ.ГОДИНА". + +Реализирайте потребители, като за всеки потребител имаме потребителско име и парола. + +Реализирайте чатруум, който съхранява записани потребители в групата, съобщения и съответните потребителски имена на авторите. +Един потребител може да се добави в чатруум, да създава нови съобщения и може да излезе, като един излязъл потребител може да вижда историята на чата до момента в който е излязъл. +Ако обратно бъде вкаран, тогава пак може да вижда всички съобщения от историята и да създава нови. + +Всеки потребител може да създаде чатруум и да запише хора в него (по потребителски имена), и може да излезе. +Допълнително собственика на чатруум може да изтрие самия чатруум и да премахва хора. +Ако собственикът се отпише тогава новият собственик е следващия по ред записан потребител. + +Реализирайте "платформа" в която се съхраняват всички чатове и потребители, от която също се създават потребители. + +Имплементирайте конзолен интерфейс, от който може да създадете потребител, да влезете в акаунта на потребител, след като сте влезли да разглеждате всички налични чатове. +Ако сте член на даден чат да създавате ново съобщение и да излезете. +Ако сте собственик да изтриете чат и да премахвате потребители от чата. diff --git a/src/teaching/oop-2023/week16/index.md b/src/teaching/oop-2023/week16/index.md new file mode 100644 index 0000000..f95271d --- /dev/null +++ b/src/teaching/oop-2023/week16/index.md @@ -0,0 +1,30 @@ +# Задачи - ООП, Седмица 16, 06.06.2024 + +GitHub classroom: [classroom.github.com/a/BWjw2dUC](https://classroom.github.com/a/BWjw2dUC) + +## Задача + +Първо си разпишете структурата, след това пишете код. +НЕ е нужно да реализирайте пълно решение, това е по-блико до архитектурното контролно, не е нужно да конкретизирате всички член-функции. + +В добре реализираните операционни системи, комуникация със свързани устройства се свежда до работа с файлове: ако искаш да кажеш устройството да прави нещо, ти пишеш във файла, ако устройството иска да ти каже на тебе нещо, четеш от файла. +Разбира се, отдолу няма истински файлове които се запазват в харддиск (примерно), просто ОС превежда всички тези операции върху файлове със съответни действия към устройството. + +Реализирайте подобна система. +Първо трябва ни обща схема за файлове, за всеки файл имаме `Read` и `Write` методи, и пазим името на файла. + +За всяко устройство само по себе си знаем, че трябва да използваме определен драйвър (по име) и че то има малко информация за себе си: марка като низ и модел като цяло число. +По-конкретно разглежаме два основни типа устройства: индексируемо и поточно (streamable). + +Първия тип са устройства като харддиск, където можем да си изберем индекс в който да запазваме или четем данни. +Втория тип са устройства като клавиатура или тонколони, можем или да прочетем или пишем по един байт, и този байт "изчезва" (клавиатурата изпраща байт като е натиснат бутон, тонколоните изкарват звук според байт, но никъде тази информация не се запазва дълготрайно). +Имплементирйате съответните оператори. + +Допълнително имаме поточно-индексируеми устройства, това са примерно фенси дигитални камери, които позволяват да се свържат като нормални уеб камери (тоест серийни устройства, изпращат данни за сегашния кадър) и могат да пазят снимки (тоест индексируеми устройства). + +Последно, с популярността на интернетът е добавен мрежов интерфейс, за който трябва да реализираме член-функции за изпращане и приемане на пакет с данни. +Един пакет съдържа начален и краен адрес като цели неотрицателни числа, име на протокола (низ с 4 знака) и данни (масив от байтове). + +Имаме и конкретен тип поточно устройство: мрежов адаптер. +Разбира се, той е и мрежов интерфейс, като идеята е, че по файловия интерфейс се предават статистични и информативни данни, но не и пакети. + diff --git a/src/teaching/oop-2023/week2/index.md b/src/teaching/oop-2023/week2/index.md new file mode 100644 index 0000000..f8f27d9 --- /dev/null +++ b/src/teaching/oop-2023/week2/index.md @@ -0,0 +1,194 @@ +# Задачи - ООП, Седмица 2, 29.02.2024 + +GitHub classroom: [classroom.github.com/a/3qPsfyyI](https://classroom.github.com/a/3qPsfyyI) + +## Задача 0 - Преговорна + +&::solution-link [Решения](https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise0.cpp) + +Ще работим върху N-мерен [морски шах](https://en.wikipedia.org/wiki/Tic-tac-toe), тоест ще имаме дъска за морски шах, която може да е по-голяма от 3 на 3 (примерно 5 на 5, 7 на 7 и т.н.). +Няма да се занимаваме с проверки дали (и кой) е спечелил след даден ход, интересуваме се само от запазването на данни. + +Основната логика е следната, като във всяка подточка правила по имплементацията са зададени. + +&:warn Не почвайте веднага да имплементирайте, погледнете подточките! + +В началото от входа се въвеждат два реда, всеки съответстващ на имената на даден играч (в тези имена може да има шпации). +Първият играч винаги играе като X, вторият винаги като O. + +След това се въвежда цяло число N, това е размерът на дъската. +Накрая се въвеждат NxN на брой X-ове и O-та. + +За всеки играч трябва съответно да изкарате общия брой X-ове или броя O-та в цялата дъска, както и дължината на най-дългата последователност от Х-ове или О-та в един реда на дъската (примерно за първия играч, търсим реда с най-много последователни X-ове, и изкарваме тяхната бройка). + +**Пример:** + +|Вход|Изход| +|----|-----| +|Emil Petkov<br>BoburaBG<br>5<br>X X O O O<br>O X O X X<br>O X X X O<br>O X X X X<br>O X O O O<br>|Emil Petkov: Total - 13, Longest - 4<br>BoburaBG: Total - 12, Longest - 3| + +### а) без структури + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise0.cpp#L3-L83) + +&:important Решете подточката **без** структури, тоест без знания по ООП + +Имплементирайте **функция** `boardCounts`, която приема дъската и връща по някакъв начин нужните бройки: общ брой X-ове, общ брой O-та, брой X-ове в най-дългата последователност от X-ове в ред, брой O-та в най-дългата последователност от O-та в ред. + +След това имплементирайте фукция `printResult`, която приема имената на двата играча, както и бройките, върнати от `boardCounts`, и изкарва на екрана съобщенията във формата от примера. + +### б) структура за board + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise0.cpp#L85-L166) + +"Слепете" в една съвкупност (структура) указателя към самата дъска за морски шах, както и нейния размер N. +Нека името на структурата да бъде `GameBoard`. + +Обновете `boardCounts`, така че вместо да приема дъската и размера ѝ чрез две променливи, да ги приема чрез една променлива от тип `GameBoard`. + +### в) структура за числата + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise0.cpp#L168-L255) + +"Слепете" в една съвкупност (структура) на име `BoardCounts` четирите променливи, които `boardCounts` връща. + +Обновете `boardCounts` да връща една стойност от тип `BoardCounts`, вместо да връща четирите бройки като отделни числа. +Обновете `printResult` да приема стойност от тип `BoardCounts`, вместо да приема четирите бройки като отделни числа. + +### г) структура за цялата игра + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise0.cpp#L257-L300) + +Сега "слепете" предходните две структури, заедно с имената на нашите играчи, в една голяма обща структура за цялата игра на име `Game`. +Тоест, всичките ни данни: дъската, бройките и имената на играчите, да се намират в `Game`. + +&:important Искам да *композирате*, тоест искам да използвате `GameBoard` и `BoardCounts` структурите в `Game` структурата. + +Обновете `boardCounts` и `printResult`, така че да използват тази структура. + +## Задача 1 - Основи от материала + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise1.cpp) + +Работите върху система за инвентар на книжарница. + +&:warn Не е задължително, но е препоръчително да си направите и една структура `String` с конструктор и деструктор + +Създайте структура `Book` със скрити (private) данни за: + +- заглавие, като един низ +- автори, като масив от низове +- година на публикация, като целочислено число +- цена, като число с плаваща запетая + +За всяка от тях създайте съответните публични селектор (get-ър) и мутатор (set-ър) член-функции (методи). +Set-ърите трябва да записват стойности в данните, само когато съответните проверки са изпълнени: + +- заглавието не може да бъде празния низ +- трябва да има поне един автор, името на даден автор не може да бъде празния низ +- годината на публикация не може да надвишава 2024, не може да е по-малка от -2100 (2100 п.н.е.) и не може да бъде нула +- цената не може да е отрицателна + +Всеки от мутаторите трябва да връща булева стойност, `true` ако проверките са изпълнени (и запазването на данни е извършено) и `false` ако съответната проверка не е изпълнена (и няма промяна в данните). +Създайте съответните конструктори и деструктори. + +След това направете структура `Library`, която държи масив от книги и бройката за всяка книга (отново като скрити данни). +Най-лесния вариант е да имате втори масив, като за всеки индекс в масива с книги, на същия индекс в масива за бройки се намира съответната бройка. +Можете и да го направите чрез структура `Pair` и да имате един масив. + +Като публични методи на `Library` имплементирайте `AddBook`, която вмъква нова книга в масива, и `RemoveBook` която съответно "премахва" книга по заглавие и година. +Допълнително направете член-функция `StockBook`, която приема заглавие на книга, годината ѝ, и цяло число с което наличната бройка се увеличава. +Аналогично направете и `SellBook`. +За всики тези методи трябва да имате съответните проверки: + +- ако напълно идентична книга вече съществува, `AddBook` не трябва да я добавя на ново +- `RemoveBook` не трябва да "гърми" ако книгата не съществува +- бройката на добавени/продадени книги, подадени на `SellBook` и `StockBook`, трябва да бъдат положителни, както и книгите да съществуват + +Аналогично като при `Book`, тези функции трябва да връщат булева стойност, дали проверките са изпълнени. +Не забравяйте за конструктор и деструктор! + +&:question Можете ли да си улесните работата, ако използвате скрити член-функции? + +Не е нужно да правите потребителски вход/изход, но тествайте ръчно кода си в `main`. + +## Задача 2 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise2.cpp) + +Работите върху система за Excel-ски таблици. +Една клетка може да съдържа някаква числена стойност, или проста формула която определя тази стойност. + +Създайте структура `Cell`, която запазва (скрито) целочислена стойност, знак, който определя опреацията във формулата, и два указателя на `Cell` към двете страни на оператора. +Оператора (знака) може да бъде `+`, `-`, `*` или `/`. + +Идеята е, че ако клетката само запазва стойност, тогава оператора ще бъде нещо празно (терминираща нула например). +Обаче ако се определя от формула, тогава оператора и указателите също ще са попълнени, а запазената стойност ще действа като кеш, тоест вместо всеки път да преизчисляваме стойността когато я искаме, преизчислили сме я веднъж и я запазваме. + +За тази цел имплементирайте публична член-функция `evaluate`, ако не е запазена формула, тя не прави нищо, ако е, прави съответното изчисление и запазва резултата. +Разбира се, направете и мутатори `setValue` и `setFormula`, със съответните проверки. +Не забравяйте за конструктор и деструктор. + +Сега направете структура `Table`, която пази (скрито) двумерен масив от клетки. +Имплементирайте селектор `getCell`, който връща указател на клетка по координати и мутатор `setCell`, който приема клетка и координати в масива. + +&:question Какъв ще е типа на подадената клетка и стойностите в масива? + +Направете метод `updateCell`, чрез която стойностите на клетка по координати могат да бъдат променени, и след това всички клетки в таблицата се преизчисляват. + +Последно, имплементирайте и член-функция `printTable`, която изкарва на екрана цялата таблица, като клетката на индекси 0,0 се намира в горния ляв ъгъл, всички клетки са разделени с `|`. + +Не е нужно да правите потребителски вход/изход, но тествайте ръчно кода си в `main`. + +## Задача 3 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise3.cpp) + +Изграждате "симулация" за трафик върху секция от магистрала. + +Самата магистрала се характеризира от брой платна (ширина) и дължина. + +Върху магистралата се слагат произволен брой коли. +Всяка кола се определя с координатите си върху магистралата и своета скорост. +Всички коли се движат от "ляво" на "дясно" по магистралата, винаги в едно и също платно, без да могат да се надминават или заобикалят. +Една кола има скорост: число между 0 и 8 включително. + +В началото на симулацията, всяка кола се разпределя по случаен начин върху магистралата, и всяка кола има случайна скорост между 4 и 6 включително. +Разглеждайки от най-десните към най-левите, всяка кола се опитва да се придвижи, като нейната скорост определя с колко клетки надясно ще се мръдне. + +Ако по пътя ѝ няма други коли, тя се премества спокойно. +Ако има, тогава нейната скорост се намалява на половина, и пробва да се придвижи пак. +Ако и с намалената скорост има кола на пътя ѝ, двете коли се удрят, "предната" кола застава на място, "задната" застава директно зад нея и двете получават скорост 0. + +След като една кола успешно се е придвижила напред, тя увеличва своета скорост със случайно количество между 0 и 3. +Ако една кола се е блъснала или просто е спряла (има скорост 0), тогава увеличава своета скорост на единица, и след това продължава както нормално. + +Ако една кола успешно "излиза" от участака на магистралата, тоест тя се опитва да се придвижи някъде след края ѝ, зачитаме че успешно е минала пътя и спираме да я разглеждаме. + +Сами определете как ще изглеждат структурите за колата и магистралата, както и нужните методи. +Имайте предвид, че трябва цялата логика да присъства в тези структури, тоест в `main` трябва да присъства само някакъв инициализиращ код. + +&:important Не е позволено магистралата да бъде двумерна матрица, координатите на всяка кола се пазят в самата кола. + +Накрая пуснете симулацията няколко пъти, на всяко извикване трябва да изкарате на екрана брой получили се сблъсаци, както и броя нужни итерации с които сте обходили всички коли на пътя, докато всички те излязат от магистралата. +Симулации се различават с позиции и началните скорости на колите, бройката коли и размерите на магистралата си стоят. + +## Задача 4 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise4.cpp) + +Имате фабрика, цялата ѝ структура се разглежда като един конвейер, тоест като една редица машини, всяка от които приема някакъв материал и връща този материал преобразуван. + +Един материал се определя с три целочислени стойности: идентификационен номер, начален тип (тоест като какво се подава) и краен тип (тоест в какво се очаква да се преобразува). + +Една машина се характеризира с ефикасност спрямо материали: представете си една таблица, от едната колона има идентификационни номера на материали, от друга има числа с плаваща запетая, определящи процент ефикасност. +Допълнително за нея знаем колко материал може да преобразува, преди да се нуждае от ремонт. + +Когато даден материал е подаден на машината, тя го преобразува в материал от дадения краен тип. +Типовете на материалите са отделни стойности от идентификационните номера, тоест като е подаден материал, той се превръща в крайния тип, и трябва да намерите на кой материал точва число е началния тип. + +Всички тези данни трябва да са скрити, трябва за съответните структури да присъстват конструктори и деструктори. +Допълнително при машините трябва да има член-функция `convertMaterial`, която получава идентификационен номер на материал и бройка, и връща колко от резултатния материал е успяла да създаде (спрямо ефикасността, закръглена надолу, и дали се нуждае от ремонт по средата на работата). + +Ще получите данни за всички материали и машини, както и задачи, тоест идентификационни номера на начален и краен материал, както и бройката на началния материал. +Трябва да намерите редицата от машини, които ще създадат възможно най-много краен материал. diff --git a/src/teaching/oop-2023/week3/index.md b/src/teaching/oop-2023/week3/index.md new file mode 100644 index 0000000..c9b4963 --- /dev/null +++ b/src/teaching/oop-2023/week3/index.md @@ -0,0 +1,175 @@ +# Задачи - ООП, Седмица 3, 07.03.2024 + +GitHub classroom: [classroom.github.com/a/KPMqXsFp](https://classroom.github.com/a/KPMqXsFp) + +## Преговорни + +### Задача 1 - Структури + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise1.cpp) + +Имплементирайте структура `Lightbulb`, която запазва идентифициращите данни за една крушка: + +- диаметър и дължина: и двете са целочислени стойности +- тип: низ с максимална дължина от 100 знака +- серия: буква на латиница + +### Задача 2 - Капсулация + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise2.cpp) + +Имплементирайте структура `Alarm`, която съдържа следните **скрити** данни: + +- име на модел: низ с максимална дължина от 1024 знака +- пин код: целочислено число +- ревизия на модела: число с плаваща запетая + +За всяка данна трябва да създадете съответните get-ъри и set-ъри: публични член-функции, които съответно връщат и записват всяка от изброените скрити стойности. + +При set-ърите имплементирайте следните проверки: + +- името на модела може да има само главни букви +- пин кода трябва да бъде 4 цифри (нули са позволени) +- ревизията трябва да бъде положително число + +Ако дадена проверка не е изпълнена, не записвате новата стойност (и оставяте старата). + +### Задача 3 - Капсулация с динамична памет + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise3.cpp) + +Имплементирайте структура `Person`, която запазва двете имена на човек, възраст като целочислено число и неговия имейл. +Имената и имейла са низвое с произволна дължина. + +Направете конструктор, който приема възрастта и тези три низа, и **копира** стойностите им в динамичната памет. +Също напишете и деструктор, който коректно трие нужните данни. + +### Задача 4 - Динамично-заделени структури в други структури + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise4.cpp) + +Имплементирайте структура `Bus`, която публично запазва капацитета хора и километража на един автобус. + +Имплементирайте структура `BusWarehouse`, която запазва динамично-заделен масив от автобуси. +В конструктора се въвежда максималния брой автобуси, който може един `BusWarehouse` да съдържа. + +Имплементирайте конструктор, който само инициализира нужните данни, и деструктор който трие каквото трябва. +Имплементирайте член-функция `AddBus`, която добавя автобус в инстанция на `BusWarehouse`, ако има място за него. + +## Лесни задачи + +### Задача 5 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise5.cpp) + +Имплементирайте структура `Car`, всяка кола пази скрито своя модел като низ с произволна дължина, брой врати и брой седалки като целочислени числа. +Направете съответните get-ъри, set-ъри, конструктор и деструктор. + +Имплементирайте структура `TrafficJam`, която пази произволно дълга редица коли в задръстване. +Направете и член-функция `AddCar`, която вмъква кола в края на редицата. +Тази функция може да се извиква произволен брой пъти, затова имплементирайте и оразмеряване на вътрешната редица. + +`TrafficJam` трябва да има конструктор, деструктор и тази член-функция. + +### Задача 6 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise6.cpp) + +Ще работите с N-мерна шахматна дъска. + +Направете структура `ChessPiece`, която запазва цвета и типа на фигурата от шах, като първото е целочислена стойност, второто е буква. + +Направете структура `ChessBoard`, която по подадено N в конструктора създава шахматна дъска с размер NxN с **указатели** към съответните фигури на дъската. +Разбира се, някои от тези указатели трябва да сочат към някакви създадени шахматни фигури. + +При създаване на дъската, трябва да подредите фигурите. +На най-долните два реда присъстват белите фигури, на най-горните два - черните. +За дъска 8х8, фигурите са подредени както нормално: + + + +При по-големи дъски започвате да повтаряте редиците, докато при по-малките ги режете, от дясната страна. +Тоест в дъска 10x10 първите 8 колони изглеждат като на картинката, на 9та колона (отгоре-надолу) имате черен топ, черна пешка, 6 празни места, бяла пешка, бял топ и на последната колона са черен кон, черна пешка, 6 празни места, бяла пешка, бял кон. + +Ако N не е поне 5, програмата ви трябва да хвърли грешка. +Не забравяйте да напишете и деструктор. + +### Задача 7 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise7.cpp) + +Имате затворени интервали от целочислени числа. +Разглеждаме смесване на интервали: + +- смеската на допиращи се интервали е тяхното слепване, тоест смеската на `[0, 3]` и `[3, 5]` е `[0, 5]` +- смеската на препокриващи се интервали е тяхното обединение, тоест смеската на `[0, 5]` и `[3, 8]` е `[0, 8]` + +В противен случай не можем да смесим интервалите (примерно не можем да смесим `[0, 3]` и `[4, 8]`). + +Започвайки от някакво множество с интервали, смесете колкото се може повече от тях и изкарайте всичките резултатни интервали, които не могат повече да се смесят. +Използвайте структури и член-функции. + +### Задача 8 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise8.cpp) + +"Моделирайте" (тоест сами се сетете за типовете данни и нужните структури) един град със следните харакетристики. + +В града имате два типа сгради: жилищни и търговски. + +- Жилищните се харакетиризират с цена на апратамент, бройката етажи, количеството хора, които се побират на един етаж (една стойност за всички етажи) и дали имат мазе, паркомясто и/или таван. +- Търговските се характеризират с цена на магазин, бройка етажи с паркинг, бройка етажи с магазини и максимално количество магазини, които се побират на един етаж (една стойност за всички етажи). + +Градът трябва да пази всички отделни сгради, като допълнително за всяка жилищна трябва да съхранява общата бройка жители, a за всяка търговска - общата бройка отворени магазини. +Освен това трябва да се съхрани и нещо като карта на всичките сгради: допускаме Старозагоско/Манхатънско подреждане на сградите, тоест всички сгради се намират върху някаква "решетка". + +&:question Познавате ли структурата `Pair`? + +Имплементирайте възможност за построяване и събаряне на сгради. +Направете нужните проверки на всички данни: цената да не е отрицателна, бройката жители да не надвишава капацитета на сградата и так. нат. + +## Трудни задачи + +### Задача 9 + +Ще разглеждаме нещо като UNIX-базирана файлова система. + +Един файл във файловата система се характеризира с идентификационен номер (цяло неотрицателно число), брой твърди връзки (пак цяло неотрицателно число), тип (определен от цяло число) и данни (масив от цели числа). +Ще разглеждаме два типа файлове: нормални и директории. + +В нормалните файлове, данните се интерпретират като една редица от числа. + +Директориите запазват имена на файлове (кодирани в числа, по начин който вие решите) и съответните им идентификационни номера. +Нека имената да са закодирани на четните индекси в данните, докато идентификационните номера: нечетните. +Когато една директория е запазила име към някакъв файл, броят твърди връзки на съответния файл се увеличава. + +Имплементирайте файловата система, чрез нея трябва да можем да създадем или изтрием файлове. +При изтриване на файл, броят твърди връзки към него се намалява. +Ако той стане нула, паметта за файла се освобождава. + +Във файловата система, всички файлове са подредени на случаен принцип (затова използваме идентификационен номер, вместо индекс в масив). +Винаги започваме с една празна начална директория. + +Двете функции, за създаване и изтриване, трябва да приемат масив от низове, който определя път от директории към желания файл, започвайки от началния файл. +Тоест, ако бяха подадени низовете `Documents`, `Personal`, `Health`, `receipt.txt`, тогава от началния файл намираме името `Documents` и "влизаме" в директорията със съответния идентификационен номер, в нея намираме името `Personal` и так. нат. + +### Задача 10 + +Намираме се в равнината, при която всички (двуизмерни) координати са **целочислени**. + +В нея имаме стъклени панели (прави отсечки), дефинирани с координатите на двете им крайни точки. +Допълнително всеки панел си има свой цвят (като проценти, между 0 и 1, от цветовете червено, зелено и синьо) и прозрачност (като процент, между 0 и 1). + +Също имаме и един лъч, той се характеризира с началния си координат и единичен двуизмерен вектор, определящ неговата посока на движение. +Този лъч не се пречупва и винаги се движи напред (преместването на лъча се извършва чрез `позиция = позиция + посока`). + +Чрез този лъч трябва да изкарате композитния цвят, след като лъча е минал през всички стъклени панели пред него. +Нека също композитния цвят винаги да има 100% прозрачност. + +Примерно, ако лъча премине през един панел с цветови проценти `0,1,0` и прозрачност `0.5` и още един панел с цветови проценти `0,1,1` и прозрачност `0.5`, тогава композитния цвят е `0,1,0.5`. + +&:question Колко структури ще ви трябват? + +## Признания + +Изображението на шахматната дъска от chess.com, направено от Hfjhjoiijklij4 за [Уикипедия](https://commons.wikimedia.org/w/index.php?curid=106440749) под лиценз CC BY-SA 4.0 diff --git a/src/teaching/oop-2023/week4/img/Rotation_matrix.png b/src/teaching/oop-2023/week4/img/Rotation_matrix.png Binary files differnew file mode 100644 index 0000000..76faa6f --- /dev/null +++ b/src/teaching/oop-2023/week4/img/Rotation_matrix.png diff --git a/src/teaching/oop-2023/week4/index.md b/src/teaching/oop-2023/week4/index.md new file mode 100644 index 0000000..b89a7a6 --- /dev/null +++ b/src/teaching/oop-2023/week4/index.md @@ -0,0 +1,110 @@ +# Задачи - ООП, Седмица 4, 14.03.2024 + +GitHub classroom: [classroom.github.com/a/qa_FfWeG](https://classroom.github.com/a/qa_FfWeG) + +## Преговорни + +### Задача 1 - Капсулация + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week04/Exercise1.cpp) + +Имплементирайте структура `Smartphone`, която запазва **скрито**: + +- марка, низ с максимална дължина от 128 знака +- модел, низ с максимална дължина от 512 знака +- година на произвеждане, неотрицателно целочислено число +- резолюция на камера, число с плаваща запетая (обозначаващо мегапиксели) + +За всяка стойност напревете съответните get-ъри и set-ъри, правейки следните проверки при set-ърите: + +- марката и моделът не могат да бъдат празни низове, или пък да надвишават максималната дължина +- годината трябва да бъде между 2000 и 2024 +- резолюцията не може да бъде отрицателна (може да бъде нула, което показва, че смартфонът няма камера) + +При неизпълнено условие, хвърляте грешка. + +### Задача 2 - Капсулация с динамична памет + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week04/Exercise2.cpp) + +Имплементирайте структура `Bee`, която запазва възрастта на пчела чрез число с плаваща запетая и типа пчела с буква. + +Имплементирайте структура `BeeHive`, която запазва динамично-заделен масив с всички реещи се пчели и друг динамично-заделен масив с всички яйца в кошера. +Размерите на двата масива се подават на конструктора. +Имплементирайте нужните конструктор и деструктор. + +## Лесни задачи + +### Задача 3 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week04/Exercise3.cpp) + +Имплементирайте структура `Paper`, която запазва своето текстово съдържание като низ от максимум 1024 знака и положително цяло число, определящо номера на страницата. + +От входа получавате на един ред цялото текстото съдържание за един обект от тип `Paper` и на следващия ред - бройките копия `N` на дадения обект. + +Създайте `Paper` обект със съответното съдържание и номер на страницата `1`. +Създайте динамично-заделен масив от `Paper` с размер `N`, като първия му елемент е новосъздадения обект, докато останалите са **копия** на първия обект. + +При всяко копие, трябва да увеличите номера на страницата. +Имплементирейте логиката чрез копиращ конструктор. + +### Задача 4 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week04/Exercise4.cpp) + +Създайте структура `DynamicString`, чиито конструктор приема низ с терминираща нула, заделя точно толкова динамична памет, колкото е нужно да се запази целия низ и копира буквите на низа в тази памет. +Имплементирайте оператор равно. + +&:question Какви данни трябва `DynamicString` да запазва скрито? + +&:question Какво трябва оператор равно да направи, ако записваме в `DynamicString` с вече заделена памет? + Тоест ако имахме: + `DynamicString s1("Hello"); DynamicString s2("World"); s2 = s1;` + +### Задача 5 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week04/Exercise5.cpp) + +Имплементирайте структура `TVProgram`, която запазва името на предаването като низ от максимум 1024 знака, начало на излъчване и край на излъчване като неотрицателни целочислени числа (като примерно 1347 е един часа и 47 минути следобед). +Имплементирайте конструктор, деструктор, оператор равно и копиращ конструктор. + +Имплементирайте структура `TVChannel`, която запазва динамично заделен масив от `TVProgram`, размера на динамично заделената памет и броя "ненулеви" елементи (програми, добавени с `AddProgram`). + +Имплементирайте нейн метод `AddProgram`, който приема `TVProgram` **по копие** и го вмъква на последната свободна позиция в масива. +Ако масива е пълен, трябва да го "оразмерите" (да направите нов, по-голям масив, да копирате данните от стария в новия, да изтриете стария и да обновите указателя да сочи към новия). + +&:question Кога използвате копиращия конструктор на `TVProgram` и кога използвате оператор равно? + +## Трудни задачи + +### Задача 6 + +Ще разработим (изключително груба) симулация на вселената. +За нас, гравитацията няма да бъде сила, която просто привлича тела към себе си, а сила която кара телата около нея да се въртят ("орбитират") в перфектен кръг. +Имаме много звезди и една планета, като звездите са винаги неподвижни, а планетата се влияе от тях. + +Гравитационното привличане на звезда в своя център се определя от ъгъла θ<sub>max</sub> (в градуси). +Планетата се върти около една звезда, използвайки стандартната матрица за ротация: + + + +Ъгълът на въртене θ, спрямо разстоянието до една звезда, се определя чрез [закона на обратните квадрати](https://en.wikipedia.org/wiki/Inverse-square_law), тоест в зависимост от разстоянието `d` между центъра на звездата и центъра на планетата, то истинският ъгъл на завъртане е θ = θ<sub>max</sub> * 1 / d^2. + +Допълнително, ако имаме повече от една звезда, тогава ще използваме θ' = max(θ<sub>i</sub> - average(θ<sub>1</sub>, ..., θ<sub>n</sub>)), където θ<sub>i</sub> е намереният ъгъл θ за i-тата звезда и имаме n на брой звезди. + +Ефектът на това е, че ако имаме две звезди на еднакво разстояние с еднакъв ъгъл, тогава планетата е неподвижна, а ако някоя планета е с малко по-близка, тогава се върти около нея и то съвсем бавно. + +Приемаме, че отнема единица време планетата да се завърти с ъгъл θ', без значение размера на ъгъла. +Целта на задачата е да върнете при коя звезда и за колко единици време планетата е успяла да извърши пълна ротация (разбира се, θ' и планетата може да се измени след всяка ротация). + +Имплементирайте структури: + +- `Matrix2x2` и `Matrix2x1`, чиито стойности са числа с плаваща запетая, и с член функции за събиране и умножение (не оператор+, оператор\*) +- `Coordinate`, която запазва (**не наследява**) точките в пространството като `Matrix2x1` и имплементира събиране, умножение и разстояние между координати и матрици +- `Star`, запазваща координатата на своя център (`Matrix2x1`) и ъгълът θ<sub>max</sub> като число с плаваща запетая. + Имплементирайте и метод, който приема планета и връща ъгълът θ. +- `Planet`, запазваща своите координати (`Matrix2x1`) и изминалото време (тоест колко пъти се е движела от началото на симулацията). + Имплементирайте метод `OrbitPlanet`, която приема планета и ъгъл θ', и се завърта около нея. +- `Universe`, запазваща всички звездите и планетата. + Имплементирайте метод `FullOrbit`, която връща звездата около която планетата е успяла да извърши пълна ротация и времето за което това се е случило. diff --git a/src/teaching/oop-2023/week5/index.md b/src/teaching/oop-2023/week5/index.md new file mode 100644 index 0000000..be66316 --- /dev/null +++ b/src/teaching/oop-2023/week5/index.md @@ -0,0 +1,116 @@ +# Задачи - ООП, Седмица 5, 21.03.2024 + +GitHub classroom: [classroom.github.com/a/42ZZ56Mg](https://classroom.github.com/a/42ZZ56Mg) + +## Преговорни + +### 1 задача - Капсулация с динамична памет + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week05/Exercise1.cpp) + +Пациент в болница се характеризира с идентификационен номер (неотрицателно целочислено число) и име (низ от максимум 1024 знака). +Една болница има максимален капацититет на болни, които може да държи (максимален брой легла за тях). + +Конструктора за болницата приема максималния капацитет, като структурата за болницата пази всичките си пациенти. +Имплементирайте методи `AddPatient`, който добавя нов пациент и `RemovePatient`, който го премахва от болницата. + +Не е нужно данните за пациентите да са скрити, но данните в болницата трябва да са. + +### 2 задача - Копиращ конструктор и оператор= + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week05/Exercise2.cpp) + +Имплементирайте структура `FloatArray`, която запазва динамично-заделен масив от `float` стойности. +Размерът на масива се подава в конструктора. + +Имплементирайте копиращ конструктор, оператор= и get-ър/set-ър за елемент на индекс `i`. + +## Лесни задачи + +### 3 задача + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week05/Exercise3.cpp) + +Имейл се характеризира с две стойности: адресът от който е изпратен (низ с максимална дължина от 128 знака) и съдържание (низ с неограничен размер). +Съобщението се подава като указател към знак, и трябва да заделите точно толкова динамична памет, колкото ви трябва за целия текст. + +Имплементирайте голяма четворка за имейла. + +### 4 задача + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week05/Exercise4.cpp) + +Имплементирайте структура за касов бон, която запазва скрит динамично-заделен масив от цени (числа с плаваща запетая). +Можете да добавяте неограничен брой цени в края на касовия бон (ако масива е пълен, създавате по-голям и пренасяте стойностите). +Можете да премахвате цени според индекс (и всички следващи се преместват с една позиция назад). + +Имплементирайте тези функционалности в методи. +Имплементирайте голяма четворка. + +### 5 задача + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week05/Exercise5.cpp) + +Един контролен списък (checklist) пази няколко неща: булева стойност, дали е избран или не, текстово съдържание (низ с "произволна" дължина) и масив от контролни списъци (всеки списък от този масив ще наричам "подсписък" за удобство). +Нека текстовото съдържание да не може да се редактира (задава се в конструктора и няма set-ър). + +Имплементирайте добавяне и премахване на подсписък, както и придвижване на подсписък с една позиция наляво или надясно. +Имплементирайте голяма четворка. + +### 6 задача + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week05/Exercise6.cpp) + +Имате телефонен указател, който запазва масив от имена (низове). +В началото винаги започва празен. +Имплементирайте голяма четворка. + +Имплементирайте метод `InsertPerson`, който вмъква ново име в указателя, като вмъкването запазва сортировка по азбучен ред. +Тоест ако указателя беше `{ "Atanas", "Yavor" }`, тогава след вмъкване на `Boris` ще имаме `{ "Atanas", "Boris", "Yavor" }`. + +&:important Имплементирайте вмъкване, запазващо "сортираност" без функция за сортиране! + +### 7 задача + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week05/Exercise7.cpp) + +Имплементирайте структура водомер, която скрито запазва отчетеното количество вода (double). +Има **единствено** конструктор по подразбиране, при който отчетеното количество е нула, метод `AddWater`, който увеличава брояча с подаденото количество вода и метод `Print`, който изкарва стойността на брояча на екрана. +Имплементирайте голяма четворка (когато е нужно). + +Имплементирайте структура сграда, която има инсталирани подаден брой водомери. + +Имплементирайте метод `SimulateDay`, който "симулира" ден в сградата - към всички датчици се добавят между 0 и 0.42 вода (разглеждаме само числа с максимум 3 цифри след запетаята). +Количеството е случайно за всеки ден. + +Имплементирайте метод `SimulateMonth`, който "симулира" 30 дена в сградата, като на всеки 5 дена се прави "отчет" - всичките водомери се **копират** и запазват във вътрешен масив. +На края на месеца изкарайте на екрана, на един ред, всичките водомери от първите дни (първи ден на първи отчет, първи ден на втори отчет, ...), вторите дни, ... + +### 8 задача + +Една интернет заявка се характеризира с тип (низ от максимум 4 знака), версия на протокола (положително число с плаваща запетая) и идентификатор (буква). +Нека тези данни да са скрити, като единствено могат да се set-нат от конструктора (тоест няма set-ъри, но има get-ъри) и е имлементирана голяма четворка (когато е нужно). + +Интернет сървър обработва интернет заявки, като всяка получена заявка я запазва в нормалните логове (динамично-заделен масив със заявки) **и** в логовете за грешки (друг динамично-заделен масив със заявки). + +Разглеждаме четири типа заявки: `GET`, `HEAD`, `POST` и `PUT`. +За всяка сървърът съдържа динамично-заделен масив от низове. +Имплементирайте методи за добавяне на низ към всеки тип. +Ако съответния масив от низове е пълен, тогава трябва да го уголемите. + +Имплементирайте метод `HandleRequest`, който приема интернет заявка **по копие**, запазва я в нормалните логове и връща първия низ от масива на съответния тип, който започва с идентификатор-буквата. +Ако такъв низ не съществува, тогава връща низа "Bad request" и добавя заявката **и** в логовете за грешки. + +Размерите на логовете се подават на конструктора. +По принцип добавяте нови заявки в края на лога. +Логовете са циклични, тоест ако един лог е запълен, тогава трябва да почнете да презаписвате от началото. +Имплементирайте голяма четворка. + +## Трудни задачи + +### 9 задача + +Имате точки в равнината. +Намерете най-малкия полукръг, който съдържа половината точки в себе си. +Точки върху ръбовете на полукръга се броят като част от кръга. +Центърът на полукръгът трябва да съвпада с някоя от точките. diff --git a/src/teaching/oop-2023/week6/index.md b/src/teaching/oop-2023/week6/index.md new file mode 100644 index 0000000..c5bd777 --- /dev/null +++ b/src/teaching/oop-2023/week6/index.md @@ -0,0 +1,102 @@ +# Задачи - ООП, Седмица 6, 28.03.2024 + +GitHub classroom: [classroom.github.com/a/rzSTn5pu](https://classroom.github.com/a/rzSTn5pu) + +&:warn В задачите за файлове имплементирайте всички нужни проверки и затваряния + +## Преговорни + +### 1 задача - Копиращ конструктор и оператор= + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise01.cpp) + +Имплементирайте структура `WoodenPlank`, която скрито запазва ширина, дължина и височина на дъската (целочислено), цената ѝ (число с плаваща запетая) и типа дърво (низ с максимум 1024 знака). + +Имплементирайте get-ъри, set-ъри, копиращ конструктор, оператор= + +### 2 задача - Голяма четворка + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise02.cpp) + +Имплементирайте структура `DynamicString`, която скрито запазва указател към низ (в динамичната памет) и неговия размер. + +Имплементирайте голяма четворка. + +## Лесни задачи + +### 3 задача + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise03.cpp) + +Имплементирайте програма, която отваря файл (създава го, ако вече не е създаден) и вкарва текста "Hello World!" във файла. +Името на файла се подава от стандартния вход на един ред. + +### 4 задача + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise04.cpp) + +Имплементирайте програма, която приема име на файл от стандартния вход. +Изкарайте последния ред от файла. + +Редовете са разделени със знака `\n`. + +### 5 задача + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise05.cpp) + +Имплементирайте програма, която приема име на файл от стандартния вход. +Изкарайте броя редове и броя думи във файла. + +### 6 задача + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise06.cpp) + +От стандартния вход получавате, на два отделни реда, две имена на файлове. +Вмъкнете съдържанието на втория файл по средата на първия файл. + +### 7 задача + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise07.cpp) + +От стандартния вход получавате числата m и n, както и името на файл (на свой си ред). +Изкарайте на екрана от m-тата до n-тата буква (включително) от всеки ред във файла. +Първата буква на един ред е на индекс 1. + +### 8 задача + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise08.cpp) + +Имплементирайте структура `FileBuffer`, която в конструктора си приема име на файл, отваря го и запазва (копира) цялото му съдържание в динамичната памет (с указател член-данна). + +&:question Кога трябва да затворим файла? + +Имплементирайте голяма четворка. + +### 9 задача + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise09.cpp) + +Имплементирайте структура `Person`, която приема име на човек (низ с максимална дължина от 1024 знака) и неговата възраст (целочислена стойност). +Имплементирайте методи `Save` и `Load`, които съответно запазват/прочитат данните в (двоичен) файл с подадено име. + +## Трудни задачи + +### 10 задача + +Имплементирайте структура `Table`, която запазва произволен брой колони и редове с низови стойности. +Броя редове/колони може да се уразмерява по време на изпълнение. +Имплементирайте голяма четворка. + +Имплементирайте методи `AddRow` и `AddColumn`, които вмъкват подадените стойности като нов ред/колона на дадения индекс. +Аналогично имплементирайте методи `RemoveRow` и `RemoveColumn`. +**Чрез всички тези** имплементирайте метода `ModifyValue`, който променя стойността на клетката на дадените индекси. + +Имплементирайте методи `Save` и `Load`, които запазват/зреждат таблицата в/от файл с подадено име, в текстовия CSV формат (всеки ред в таблицата е ред във файла, всички стойности в реда от таблицата са разделени със запетая в реда във файла). + +### 11 задача + +Имплементирайте структура `City`, която запазва името на даден град (низ с максимална дължина от 1024 знака) и масив от указатели към други градове, които са негови съседи. +Имплементирайте методи `AddNeighbour` и `RemoveNeighbour` (броя съседи може да се променя), както и голяма четворка. + +Имплементирайте методи `Save` и `Load`, които запазват/зреждат всичките достижими градове от сегашния в/от (бинарен) файл с подадено име. +Подсказвам, че не можете да запазите указателите ей-така. diff --git a/src/teaching/oop-2023/week7/index.md b/src/teaching/oop-2023/week7/index.md new file mode 100644 index 0000000..0eb3899 --- /dev/null +++ b/src/teaching/oop-2023/week7/index.md @@ -0,0 +1,83 @@ +# Задачи - ООП, Седмица 7, 04.04.2024 + +GitHub classroom: [classroom.github.com/a/vvZENbkX](https://classroom.github.com/a/vvZENbkX) + +## Преговорни + +### Задача 1 - Голяма петица + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week07/Exercise1.cpp) + +Една съставка е композирана от низ (с максимална дължина от 511 знака) определящ името ѝ и грамаж (число с плаваща запетая). + +Създайте клас `Recipe`, към който могат да се прибавят и премахват произволен брой съставки. +Имплементирайте голяма петица (голяма четворка плюс move семантики) за него. + +### Задача 2 - Работа с файлове + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week07/Exercise2.cpp) + +От един ред на входа получавате името на текстови файл. +Изкарайте на екрана средната една трета от файла, като буквите са в обратен ред. + +## Лесни задачи + +### Задача 3 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week07/Exercise3.cpp) + +Имплементирайте клас `Thermometer`, който запазва максималната и минималната възможна температура за измерване, както и сегашната температура, всичките които са цели неотрицателни числа. + +Имплементирайте методи `SaveText` и `LoadText`, които съответно записват и четат (тоест член-данните стават равни на тези от файла) данните си в/от **текстови** файл с подадено име. +Аналогично имплементирайте `SaveBinary` и `LoadBinary`, които работят с **двоични** файлове. + +### Задача 4 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week07/Exercise4.cpp) + +Имплементирайте клас `Street`, който запазва скрито името на улицата като низ с произволна дължина и номер като цяло число. +Имплементирайте голяма петица. + +Имплементирайте методите `SaveText`, `LoadText`, `SaveBinary`, `LoadBinary`. + +### Задача 5 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week07/Exercise5.cpp) + +За един транспортен билет е нужно скрито да пазим началната и крайната дестинация като динамично-заделени низове с произволна дължина, неговата цена като число с плаваща запетая и идентификационен номер като цяло неотрицателно число. + +Имплементирайте голяма петица и четирите функции за запазване и четене от файлове на съответния клас. + +### Задача 6 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week07/Exercise6.cpp) + +Имплементирайте клас `Matrix`, който запазва стойностите на матрица 2 на 2. +Предефинирайте операторите за инкрементиране, декрементиране, събиране, изваждане, умножение и вход/изход от/към поток. + +Имплементирайте четирите функции за записване и четене от файлове. + +### Задача 7 + +Имплементирайте клас `Paragraph`, който съдържа текст с много редове в него. +Текстът се запазва като низ с произволна дължина, а редовете се разделят със знака `'\n'`. + +Имплементирайте голяма петица. +Имплементирайте четирите функции за записване и четене от файлове. + +Имплементирайте операторите за събиране, които копират текстът от подадения параграф и го вмъкват в края на сегашния; оператор[] който връща начален указател на i-тия ред; операторите за (лексикографско) сравнение; вход/изход от/към поток. + +## Трудни задачи + +### Задача 8 + +Имплементирайте клас `MatrixNМ`, който запазва стойностите на матрица с N реда и M колони (подадени на конструктор). + +Имплементирайте голяма петица. +Имплементирайте четирите функции за записване и четене от файлове. + +Имплементирайте операторите за събиране, изваждане, умножение и деление (нека да дефинираме деление на две матрици като умножението на първата матрица по транспонираната втората матрица върху детерминантата ѝ). +Ако някоя операция не е възможна, върнете съответна стойност по подразбиране. + +Имплементирайте оператор[], като индекса i е числена конкатенация на двете координати, разделени с нула (тоест ако искаме стойността на ред 27 и колона 9, тогава ще въведем индекса 2709). +Имплементирайте оператори за равенство, инкрементиране, декрементиране, побитово отместване (прилага се върху всяка стойност в матрицата), логически (&& връща true само ако двете матрици са равни, || връща true ако имат еднакви размерности и съществува поне един равен елемент на еднакви индекси). diff --git a/src/teaching/oop-2023/week8/index.md b/src/teaching/oop-2023/week8/index.md new file mode 100644 index 0000000..be78f9f --- /dev/null +++ b/src/teaching/oop-2023/week8/index.md @@ -0,0 +1,167 @@ +# Задачи - ООП, Седмица 8, 11.04.2024 + +GitHub classroom: [classroom.github.com/a/7d0MBjcK](https://classroom.github.com/a/7d0MBjcK) + +## Преговорни + +### Задача 1 - Голяма петица + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise1.cpp) + +Имплементирайте клас `StreetList`, който запазва имената на улици (низове с произволна дължина) в динамичен масив. +Може да се добавят нови имена в края на списъка, като съответния (вътрешен) масив трябва да се уголеми. + +Имплементирайте голяма петица за класа. + +### Задача 2 - Файлове и класове + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise2.cpp) + +Имплементирайте клас `Person`, който запазва трите имена (низове с произволна дължина) и идентификационния номер (цяло неотрицателно число) на човек. +Имплементирайте голяма петица. + +Имплементирайте методи `SaveText` и `LoadText`, които съответно записват и четат (тоест член-данните стават равни на тези от файла) данните си в/от **текстови** файл с подадено име. +Аналогично имплементирайте `SaveBinary` и `LoadBinary`, които работят с **двоични** файлове. + +## Лесни + +### Задача 3 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise3.hpp) + +Имплементирайте шаблонната структура `Pair`, която приема два типа и запазва по една стойност от всеки тип. + +### Задача 4 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise4.cpp) + +Имплементирайте клас `FloatArray`, който съдържа списък с числа с плаваща запетая. +Може да добавяте нови числа в края на този списък. +Имплементирйате голяма петица. + +Имплементирайте оператори: + +- += и +, които конкатенират два FloatArray-я. += вмъква елементите от десния масив в края на левия, + връща нов масив в който първо са елементите от левия масив и след тях са тези от десния. +- += и +, които приемат FloatArray и число (с плаваща запетая) и го прибавят към всеки елемент на FloatArray-я +- [], които връщат референция към елементът на подадения индекс. При невалиден хвърлят грешка. +- == и !=, които сравняват два FloatArray-я покомпонентно. + Ако се различават по брой елементи или ако имат две различни стойности на еднакъв индекс, тогава не са равни. +- <<, който вмъква всички стойности в подадения поток, разделени с шпация +- >>, който презаписва всички стойности, разделени с шпация, четейки от подадени поток + +### Задача 5 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise5.hpp) + +Имплементирайте класът и неговите оператори от предходната задача като темплейтен (шаблонен) клас с име `DynamicArray`. +Очевидно шаблонния тип определя типа на списъка с елементи. + +### Задача 6 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise6.cpp) + +Имплементирайте клас `NumberInput`, който запазва целочислена стойност. +В конструктора се подава минимална и максимална възможна стойност, след това (все още в конструктора) се изкарва на екрана съответно съобщение и се приема потребителски вход. +Ако той не е валиден или е извън подадения обхват, трябва да хвърлите грешка. + +В main създайте обект от този клас. +Ако се хвърли грешка, прихванете я, изкарайте на екрана съответното съобщение и пробвайте пак. +Това се повтаря докато обекта не е успешно създаден, след което изкарвате въведената стойност по две. + +### Задача 7 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise7.cpp) + +Имплементирайте клас `UserError`, чиято употреба е да се хвърля като грешка. +За тази цел нека да запазва два низа, които се приемат в конструктора: името на клас и името на член-данната. + +Имплементирайте голяма петица и оператор<<, който изкарва съобщение с информация за класа и член-данната в подадения поток. +Следете бройката на създадени `UserError` инстанции в самия клас (статична променлива) и имплементирате нужната (статична) член-функция, която връща този брой. + +Преобразувайте последната задача, така че да хвърля грешка от този клас. +В края на програмата изкарайте колко грешки са се хвърлили **използвайки статичните членове на UserError**. + +## Трудни задачи + +### Задача 8 + +Имплементирайте шаблонен клас `UserInput`, който запазва стойност от подадения тип. +Ако типа е указател, тогава заделяте динамична памет за един такъв елемент. +За проверка на типа използвайте [partial template specialization](https://en.cppreference.com/w/cpp/language/partial_specialization). + +В шаблона (`template <...>`) се приема указател към валидираща функция, която приема стойността от съответния тип и връща булева стойност. +В конструктора се приема от входа нужната стойност и ако стойността е неуспешно приета или валидиращата функция върне false, тогава хвърляте грешка. +Ако типа е указател, не забравяйте да освободите паметта. + +В класа следете статично за броя пъти когато е хвърлена грешка. + +### Задача 9 + +&:important В тази задача се изикват помощни класове, прочетете цялото условие преди имплементиране! + +Имплементирайте шаблонен клас `Dictionary`, който запазва два динамично-заделени масива: първия е със стойност от подадения тип, втория е с низове. +Низовете ще се използват за индексиране, вместо числа. +Разбира се, очаквайте да може да се уразмерява. +Имплементирайте голяма петица. + +Имплементирайте оператор: + +- <<=, който вмъква всички стойности от десния `Dictionary` в левия +- [], който приема низ и връща референция "към" стойността. + Ако няма записана стойност на съответния индекс, тогава връщате референция в която може да се запише стойност. +- [], който приема число, което се конвертира до низ и работи както предходния оператор +- [], който приема низове (или числа), разделени със запетая и връща "масив" само с тези стойности +- delete, който приема стойност, върната от оператор[] и "премахва" съответната стойност от `Dictionary` +- префиксен++, префиксен+ и префиксен-, които ще се използват за итериране. + - ++ връща инкрементира индекса на сегашната стойност. + Ако индекса е равен на броя запазени стойности, тогава става нула. + По подразбиране индекса е броя. + Връща true ако след инкрементиране индекса не е броя. + - + връща референция към стойността на сегашния индекс + - - връща сегашния (низов) индекс +- ->, такъв че можем да правим `a->(&func1)->(&func2)` и `a->[&func3]->[&func4]`. + Върху всяка двойка индекс-стойност се прилагат &func1 и &func2 (приемат индекс и стойност като параметри), които връщат нова стойност, заместваща сегашната. + &func3, &func4 аналогично приемат индекс и стойност, но връщат нов индекс. + +В края на задачата трябва да можете да правите: + +```cpp +int doubleUp(const char* index, int value) { + return value * 2; +} +int sumIndexValue(const char* index, int value) { + return atoi(index) + value; +} +const char* indToName(const char* index, int value) { + if (strcmp(index, "2")) { + return "two"; + } + return index; +} + +int main() { + Dictionary<int> a; + a["first"] = 8; + a[2] = 13; + a[89] = -68; + + Dictionary<int> b; + b["wow"] = 99; + b["nth"] = 773; + + a <<= b; + + /* някакъв тип */ two = a["first", 2]; + + delete a["wow"]; + + a->(&doubleUp)->(&sumIndexValue)->[&indToName]; + + while (++a) { + std::cout << +a << " at " << -a << ","; + /* Ще изкара на конзолата: + * 16 at first,52 at two,-12104 at 89,1546 at nth, + */ + } +} +``` diff --git a/src/teaching/oop-2023/week9/index.md b/src/teaching/oop-2023/week9/index.md new file mode 100644 index 0000000..50cea93 --- /dev/null +++ b/src/teaching/oop-2023/week9/index.md @@ -0,0 +1,112 @@ +# Задачи - ООП, Седмица 9, 18.04.2024 + +На днешното упражнение ще решаваме [задачата от Контролно 1](https://learn.fmi.uni-sofia.bg/mod/resource/view.php?id=311448), затова задачите ще са в същия дух (макар и да не включват най-новия материал). + +Решението, което писахме по време на практикума, с някои разширения и коментари, може да намерите [тук](https://github.com/Syndamia/oop-2023-solutions/tree/main/week09/Exam1). + +GitHub classroom: [classroom.github.com/a/wlL1oUg2](https://classroom.github.com/a/wlL1oUg2) + +## Преговорни + +### Задача 1 - Голяма петица + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week09/Exercise1) + +Реализирайте клас Printer, който съдържа модел като низ с произволна дължина и брой принтирани страници като неотрицателно цяло число. +Имплементирайте голяма петица. + +### Задача 2 - Файлове и класове + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week09/Exercise2) + +Реализирайте клас Date, който съдържа номера на деня, месеца и годината в три отделни целочислени член-данни. +Имплементирайте член-методи `storeText`, `storeBinary`, които съответно запазват данните в текстов файл (във формата "YEAR MONTH DAY") и в двоичен файл с подадени имена. +Аналогично имплементирайте `loadText` и `loadBinary`, които презаписват член-данните с тези от подадените (имена на) файлове. + +В главната функция създайте 5 дати, запазете всяка в **един и същ текстов файл**, след това прочетете датите в **нови** 5 променливи и изкарайте датите в обратен ред. + +## Лесни + +### Задача 3 + +&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week09/Exercise3) + +Реализирайте клас Train, който съдържа: + +- модел като низ с максимална дължина от 127 знака +- идентификационен номер на релсовата линия върху която се намира, като целочислена неотрицателна стойност +- име на текстов файл, съдържащ всички райони от сегашната релсова линия, всеки на нов ред. + Самото име представяйте като низ с произволна дължина. +- сегашна локация (район) от релсовата линия като низ с произволна дължина. + Тази локация не се подава, и при създаване на обекта винаги е първата във файла. + +Имплементирайте методите: + +- от голямата петица +- `TransferNextRegion`, който променя сегашната локация на следващата по ред в текстовия файл (чието име е подадено в конструктор). + Ако няма следващо по ред, тогава локацията да си остане същата и да се хвърли грешка. + Ако се срещнат проблеми с файла, хвърлете грешка. +- `SwitchRailLine`, който приема идентификационен номер на релсовата линия и име на текстов файл, и променя вътрешните стойности. + Съответно локацията трябва да бъде първата в подадения файл. + Ако се срещнат проблеми с файла, хвърлете грешка. + +Реализирайте клас TrainNetwork, който съдържа: + +- идентификационен код, като низ с максимална дължина от 7 знака +- масив, запазващ максимум 511 влака (типа се оставя по ваша преценка) + +За този клас имплементирайте методите: + +- `HaveCollided`, който приема индекс на два влака и връща дали са се блъснали. + Това се случва ако в една и съща релсова линия и един и същи регион, когато регионът не е последния възможен. +- `RunTrains`, който придвижва напред всички влакове, докато не стигнат финалната си възможна дестинация. + Влакове които са се ударили не се придвижват напред. + Връщате броя ударили се влакове. + +Да се имплементира главна функция, в която приемате име на двоичен файл от потребителя. +В този файл имате някакъв брой редици с идентификационен номер на релсова линия, брой локации върху съответната линия и всички локации като нормални низове, разделени с нови редове. + +Допълнително в главната функция приемайте от потребителя влаковете, като имената на текстовите файлове се избират от програмата (**НЕ** от потребителя) според идентификационния номер на релсовата линия и информацията във файла с редиците. +**Не може да променяте Train класа!** + +Последно в главната функция създайте обект от тип TrainNetwork и изкарайте резултата от `RunTrains` на екрана. + +## Трудни + +### Задача 4 + +Реализирайте клас Car, в който се запазват: + +- марка като низ с максимум 31 знака +- модел като низ с произволна дължина +- брой седалки като положително цяло число +- гладност на човека на всяка седлка като целочислен масив с размер броя седалки + +Имплементирайте методи: + +- от голямата петица +- `AddPassenger`, който добавя нов човек на дадения индекс на седалка +- `RemovePassenger`, който премахва човека от дадения индекс +- `TotalHunger`, който връща общото количество гладност в колата +- `StoreData`, който запазва всички данни от колата в **двоичен** файл с подадено име +- `LoadData`, който презаписва всички данни с тези от подадения по име **двоичен** файл + +Реализирайте клас DriveThrough, в който се запазват: + +- име на ресторант, към който е свързано съответния проход, като низ с произволна дължина +- коли на опашка, като масив с коли с произволна дължина + +Имплементирайте методи: + +- от голяма петица +- `QueueUp`, който приема кола и я вкарва в края на опашката. + Разбира се, масивът се уголемява ако е нужно. +- `Serve`, който изпълнява поръчката на най-предната кола в опашката. + За единица глад, ресторанта може да сготви достатъчно храна (за да нахрани клиента с "единица" храна) за единици време между половината от дължината на името на ресторанта и три пъти дължината на името на ресторанта време. + Максималното възможно количество време за изпълнение на поръчката варира и според броя коли в опашка: ако са под 6 на брой, тогава тогава се увеличава с 10%, а ако са над 10 тогава се намалява с по 5% за всяка кола след десетата. +- `EfficiencyService`, който изпълнява поръчките на всички коли в опашката и връща средно колко време е отнело на поръчка. +- `StoreData`, който запазва всички данни в **текстов** файл с подадено име +- `LoadData`, който презаписва всички данни с тези от подадения по име **текстов** файл + +Имплементирайте главна функция, в която от потребителския вход приемате име на текстов файл. +Създайте обект от тип DriveThrough, който да запълни своите стойности с тези от подадения файл и изкарайте на екрана стойността от `EfficiencyService`. diff --git a/src/teaching/upp-2023/additional1/index.md b/src/teaching/upp-2023/additional1/index.md index cf1dfce..f366858 100644 --- a/src/teaching/upp-2023/additional1/index.md +++ b/src/teaching/upp-2023/additional1/index.md @@ -2,13 +2,13 @@ GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com/a/nlFuKALw) -При изображението &&question трябва да спрете, да помислите и да си отговорите на дадения въпрос. +При изображението  трябва да спрете, да помислите и да си отговорите на дадения въпрос. Почти винаги ако не може да отговорите, ще имате проблеми в бъдеще с решаването. Понякога ще ви спираме и ще ви питаме за тези въпроси. ## Задача - База гаднни -&&warn **Нямате** право да използвате каквито и да е функции, които вие не сте написали, както и неизучаван материал като двуизмерни масиви или динамична памет. +&:warn **Нямате** право да използвате каквито и да е функции, които вие не сте написали, както и неизучаван материал като двуизмерни масиви или динамична памет. **Не** употребявайте търсачки, ако ви трябва информация за нещо, ще може да си я изкарате с една проста тестова програма или калкулатор. <br> @@ -18,7 +18,7 @@ GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com Таблица А има максимум 8 реда, като всеки ред е едно цяло число с 9 цифри. Таблица Б има максимум 8 реда, като всеки ред е число между 1 и 4294967295. -&&question В какъв тип ще запазим всяка таблица? +&:question В какъв тип ще запазим всяка таблица? В задачата винаги номерираме редовете (числата) на всяка таблица, започвайки от индекс 1. Чрез различни комбинации на ред в таблица А и ред в таблица Б получаваме различни стойности. @@ -39,11 +39,11 @@ GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com Стойностите от таблица А са винаги ограничени отгоре с най-големия брой битове, които комфортно може да поберем в 7 цифри. Тоест 9999999 не е валидна стойност от таблица А, докато 8388608 e. -&&question Колко най-много *битове* можем със сигурност да поберем в 7 цифри? +&:question Колко най-много *битове* можем със сигурност да поберем в 7 цифри? Понеже редовете са от 1 до 9, ако в таблица А имаме ред 0 правим нещо специално, но това ще видите в бъдеще. -&&question Разбрахте ли как таблиците "изглеждат"? +&:question Разбрахте ли как таблиците "изглеждат"? ### a) разделяне на реда от таблица А @@ -52,7 +52,7 @@ GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com `getRow` - приема ред от таблица А и указатели към променливи за ред, тип и стойност; не връща нищо В подадените указатели пази съответните стойности от реда -&&question Защо приемаме указатели към променливи? Каква е "сигнатурата" на функцията? +&:question Защо приемаме указатели към променливи? Каква е "сигнатурата" на функцията? <br> **Примери:** @@ -68,7 +68,7 @@ GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com Ако типа е цифрата "0", тогава стойността в базата данни е някакво число с плаваща запетая. Самото число е разделено на две части: цифрите преди запетаята се намират в стойността от таблица А, докато цифрите след запетаята са в реда от таблица Б. -&&question В какъв тип данни трябва да запазим числото? Как ще "слепим" двете му части. +&:question В какъв тип данни трябва да запазим числото? Как ще "слепим" двете му части. Имплементирайте функция: @@ -107,14 +107,14 @@ GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com Тоест ако в нашия тип данни запазваме само 10 бита, тогава числото "2" ще бъде `0000000010` и имаме низа "AC". Игнорирайте старшите битове, които остават като "остатък" (по-малко от 5 бита ширина). -&&question Колко бита наистина запазваме в нашия тип данни? Колко бита ще трябва да игнорираме? Колко най-много букви може да поберем? +&:question Колко бита наистина запазваме в нашия тип данни? Колко бита ще трябва да игнорираме? Колко най-много букви може да поберем? Имплементирайте функция: `decodeNumberText` - приема ред от таблица Б и указател към "низ"; не връща нищо Записва декодиран текстът от реда в указателя -&&question Нарочно има кавички около думата "низ", какъв трябва наистина да е типа на указателя? +&:question Нарочно има кавички около думата "низ", какъв трябва наистина да е типа на указателя? <br> **Примери:** @@ -135,7 +135,7 @@ GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com Как декодираме? Отместваме буквите назад, тоест ако имаме текста "KHOOR" и ви кажа, че съм го кодирал като съм отместил всяка буква напред с 3 позиции, тогава при декодиране от K става на H, от H става на E, от О става на L и от R става на O. -&&question Какво става със знака "!"? Има ли лесен (математически) начин да дешифрираме всяка буква? +&:question Какво става със знака "!"? Има ли лесен (математически) начин да дешифрираме всяка буква? Текстът, преди да е въведен в нашата база данни, ще бъде кодиран с шифъра на Цезар, като броя позиции с които сме отместили буквите се намира в стойността в таблица А. @@ -162,7 +162,7 @@ GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com Ако типа е "2", тогава в реда от Б сме вложили масив от стойности (числа). Всеки 4 бита определят една стойност, като първия елемент е старшите (най-левите) битове, докато последния е младшите (най-десните) битове. -&&question Коколо на брой елемента пазим в реда от Б? +&:question Коколо на брой елемента пазим в реда от Б? Имплементирайте функцията: @@ -207,7 +207,7 @@ GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com Ако редът в таблица А е 0, тогава цялата стойност в базата данни е побрана в стойността на таблица А. Очевидно само в стойност на таблица А имаме по-малко битове, отколкото в стойност на таблица А плюс ред в таблица Б, затова се налага по някакъв начин да "компресираме" информацията, така че да се побере. -&&question Колко бита побираме в стойност на таблица А? Колко бита ни трябват общо, за да обработим една стойност в базата данни? +&:question Колко бита побираме в стойност на таблица А? Колко бита ни трябват общо, за да обработим една стойност в базата данни? Ще го направим така: в стойността от таблица А ще пазим индекси, и всеки индекс ще съответства на някакво по-голямо число, което се съдържа в друг масив, който ще наричаме криптографски ред. @@ -225,7 +225,7 @@ GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com Първите (най-левите) три бита от стойността в таблица А не са индекси, а трябва да се копират дословно. След тях има 4 индекса, всеки с по 5 бита. -&&question Как е разделена побитово една стойност от таблица А? Кои индекси за кои стойности ще се ползват? Достатъчно ли е всеки индекс към криптографския ред да бъде само 5 бита (тоест може ли да има повече от 2⁵ числа в реда)? Защо имаме само 4 индекса? +&:question Как е разделена побитово една стойност от таблица А? Кои индекси за кои стойности ще се ползват? Достатъчно ли е всеки индекс към криптографския ред да бъде само 5 бита (тоест може ли да има повече от 2⁵ числа в реда)? Защо имаме само 4 индекса? Напишете функция: @@ -266,4 +266,4 @@ GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com Пробвате се да я запазите, използвайки и двете таблици, но ако Б вече е запълнена, добавяте я като компресирана стойност в таблица А. Ако и А е запълнена, изкарвате съобщение за запълнена база данни и не запазвате стойността. -&&question Какво трябва да направите, ако получите компресирана стойност за таблица А? +&:question Какво трябва да направите, ако получите компресирана стойност за таблица А? diff --git a/src/teaching/upp-2023/additional2/index.md b/src/teaching/upp-2023/additional2/index.md index 75530f8..d4e07b4 100644 --- a/src/teaching/upp-2023/additional2/index.md +++ b/src/teaching/upp-2023/additional2/index.md @@ -2,7 +2,7 @@ GitHub classroom: [classroom.github.com/a/CrerXpf6](https://classroom.github.com/a/CrerXpf6) -&&important Следете внимателно дали триете всичката си динамична памет коректно на всяка подточка! +&:important Следете внимателно дали триете всичката си динамична памет коректно на всяка подточка! Случвало се е на контролни да се пишат двойки ако всичко друго е коректно, но има неизтрита памет! ## Задача - текстов редактор @@ -18,7 +18,7 @@ GitHub classroom: [classroom.github.com/a/CrerXpf6](https://classroom.github.com Като за начало, нека да имплементираме запазването на текст. От конзолата ще получавате редове текст, всеки ред ще е с максимална дължина от 1024 знака, след това трябва да го запазите. -&&important Може да използвате масив със статична дължина за буфер, обаче трябва да използвате възможно най-малко памет за "перманентното" запазване на реда текст във вашата програма. +&:important Може да използвате масив със статична дължина за буфер, обаче трябва да използвате възможно най-малко памет за "перманентното" запазване на реда текст във вашата програма. Използвайте многомерен масив за запазване на редовете, вместо всичко да се запазва в един голям низ. Това е нужно за бъдещи подточки. @@ -58,10 +58,10 @@ est. It was a high bank, and he paused to breathe at the top. Ако низът е команда, тогава връща масив от низове, първия от които съдържа буквата, определяща командата, докато останалите низове са параметрите. Ако низът не е команда, тогава връща празен масив. -&&warn Какво означава празен масив зависи от имплементацията ви. +&:warn Какво означава празен масив зависи от имплементацията ви. За предпочитане е да не заделяте памет, когато не е нужно. -&&question Как ще върнем масив? Нужно ли е да връщаме бройката елементи? +&:question Как ще върнем масив? Нужно ли е да връщаме бройката елементи? *Само за тестване*, след всеки въведен ред, ако е команда, изкарайте извлечените стойности от `extractCommand`, със запетайки след всяка. Като при [подточка a)](#section), ако редът започва с `Q`, спирате приемане на вход и изкарвате запазения текст. @@ -195,9 +195,9 @@ the man turned aside from the main Yukon trail. He climbed the high Имплементирайте функцията `deleteRow`, която получава целия текст, въведен до сега, и номер на реда (редовете се индексират от 1 до N). Тя променя текста, като премахва реда на дадения номер. -&&important Не забравяйте да промените размера на масива с низове! Не е решение просто да промените указателя към дадения ред на `nullptr`, не искаме да използваме излишна памет. +&:important Не забравяйте да промените размера на масива с низове! Не е решение просто да промените указателя към дадения ред на `nullptr`, не искаме да използваме излишна памет. -&&question Какъв ще бъде типа на аргумента, който приема целия текст? +&:question Какъв ще бъде типа на аргумента, който приема целия текст? Добавете командата `D`, която приема един параметър - цяло положително число, и го прилага върху функцията `deleteRow`. Ако номера на реда е невалиден, трябва да изкарате съобщение "; Invalid row number". @@ -297,7 +297,7 @@ He excused Ред N+1 се изтрива. Ако N е 0 или номера на последния ред, не прави нищо. -&&important Не забравяйте да промените размера на масива с низове! Не е решение просто да промените указателя към дадения ред на `nullptr`, не искаме да използваме излишна памет. +&:important Не забравяйте да промените размера на масива с низове! Не е решение просто да промените указателя към дадения ред на `nullptr`, не искаме да използваме излишна памет. Добавете команда `J`, която приема номер на ред - положително число. Следващия ред ще се вмъкне в края на сегашния, с една шпация между тях, използвайки функцията `joinRows`. @@ -372,7 +372,7 @@ est. It was a high bank, and he paused to breathe at the top. Имплементирайте функция `substituteWord`, която приема целия текст и две думи (низове без шпации). В текстът, всяко срещане на първата дума е заменено с втората дума. -&&question Какво ще стане с размера на един ред, ако някоя дума/някои думи трябва да се заменят? +&:question Какво ще стане с размера на един ред, ако някоя дума/някои думи трябва да се заменят? Добавете команда `s`, която приема две думи - низове без шпации. Използвайки функцията `substituteWord` замества всяко срещане на първата дума с втората. diff --git a/src/teaching/upp-2023/index.md b/src/teaching/upp-2023/index.md index 9ef5d77..624a312 100644 --- a/src/teaching/upp-2023/index.md +++ b/src/teaching/upp-2023/index.md @@ -2,7 +2,7 @@ Материали на проведените през 2023/2024 практикуми по Увод в програмирането на Компютърни науки (2 поток), 8 група. -&&warn От сега нататък ще може да продължите да предавате решения след крайния срок в classroom. +&:warn От сега нататък ще може да продължите да предавате решения след крайния срок в classroom. Не мога да гарантирам кога ще погледна предадени решения след срока, но ще ги погледна! **Зала:** ФМИ 309 || @@ -26,5 +26,10 @@ |6 |10.11.2023|[Задачи](./week6) \|\| [Решения](https://github.com/Syndamia/upp-2023-solutions/tree/main/week06) \|\| [GitHub classroom](https://classroom.github.com/a/BBLlWMOy)| |7 |17.11.2023|[Задачи](./week7) \|\| [Решения](https://github.com/Syndamia/upp-2023-solutions/tree/main/week07) \|\| [GitHub classroom](https://classroom.github.com/a/m5M2_CWD)| |8 |24.11.2023|[Задачи](./week8) \|\| [Решения](https://github.com/Syndamia/upp-2023-solutions/tree/main/week08) \|\| [GitHub classroom](https://classroom.github.com/a/Big7FRUG)| -|9 |01.12.2023|[Задачи](./week9) \|\| [GitHub classroom](https://classroom.github.com/a/lGXxCRZO)| -| |04.12.2023|[Допълнително упражнение 2](./additional2/) \|\| [GitHub classroom](https://classroom.github.com/a/CrerXpf6)| +|9 |01.12.2023|[Задачи](./week9) \|\| [Решения](https://github.com/Syndamia/upp-2023-solutions/tree/main/week09) \|\| [GitHub classroom](https://classroom.github.com/a/lGXxCRZO)| +| |04.12.2023|[Допълнително упражнение 2](./additional2/) \|\| [Решения](https://github.com/Syndamia/upp-2023-solutions/tree/main/additional2) \|\| [GitHub classroom](https://classroom.github.com/a/CrerXpf6)| +|10|15.12.2023|[Задачи](./week10) \|\| [Решения](https://github.com/Syndamia/upp-2023-solutions/tree/main/week10) \|\| [GitHub classroom](https://classroom.github.com/a/EJcTQRz4)| +|11|22.12.2023|[Задачи](./week11) \|\| [Решения](https://github.com/Syndamia/upp-2023-solutions/tree/main/week11) \|\| [GitHub classroom](https://classroom.github.com/a/cZRnZj9y)| +|12|05.01.2024|[Задачи](./week12) \|\| [Решения](https://github.com/Syndamia/upp-2023-solutions/tree/main/week12) \|\| [GitHub classroom](https://classroom.github.com/a/KEDSxDjl)| +|13|12.01.2024|[Задачи](./week13) \|\| [GitHub classroom](https://classroom.github.com/a/bgiFD6SB)| +|14|19.01.2024|[Задачи](./week14) \|\| [GitHub classroom](https://classroom.github.com/a/B08TtnnW)| diff --git a/src/teaching/upp-2023/week1/setup.md b/src/teaching/upp-2023/week1/setup.md index 73507a7..9327b2b 100644 --- a/src/teaching/upp-2023/week1/setup.md +++ b/src/teaching/upp-2023/week1/setup.md @@ -1,15 +1,16 @@ # Конфигуриране на GitHub classroom и Visual Studio - УПП, Седмица 1, 06.10.2023 -&&presentation -&&clide &¢ered +&.presentation + +&[title # Конфигуриране на GitHub classroom и Visual Studiо -&&/centered &&/clide +&] -&&slide +&[slide ## Теория относно GitHub classroom @@ -26,15 +27,15 @@ - Обединението на труда на всички, особено в огромни екипи, става супер трудно -&&/slide +&] -&&slide +&[slide ### Git -&&lineb1 +&.br1 git е програма (система) за [контрол на версиите](https://en.wikipedia.org/wiki/Distributed_version_control). В един проект, git пази **списък от всички commit-и**. @@ -47,15 +48,15 @@ git е програма (система) за [контрол на версииÑ Така, когато смесваме кода от многото разработчици, ще можем да засечем **какви точно са различията** между работата на двама човека. Често промените не си "противоречат" и могат да бъдат смесени директно, понякога се налага ръчно да решим какво точно да се случи с тези парчета код. -&&/slide +&] -&&slide +&[slide ### GitHub -&&lineb5 +&.br5 Всички repository-та трябва да се пазят някъде и да може лесно да се споделят и гледат. Има много сайтове за тази цел, най-популярния се нарича [GitHub](https://github.com). @@ -63,11 +64,11 @@ git е програма (система) за [контрол на версииÑ Напомням, че git и GitHub са напълно отделни неща, направени от различни хора с различни функционалности. Свързаността с имената е както свързаността между думите "чар" и "чаршаф". -&&/slide +&] -&&slide +&[slide ## Сега всички трябва да си направят GitHub акаунти @@ -75,24 +76,24 @@ git е програма (система) за [контрол на версииÑ  -&&/slide +&] -&&clide +&[middle След това, като влезете в акаунтите си (което става автоматично след регистрация), на заглавната страница ще имате нещо такова: -&&width75  &&/width +&(width75%  &) В горния десен ъгъл, където е иконката с квадрати на бял фон, след натискане получавате sidebar. От него, може да достъпите профила си, repository-та които имате, и так. нат. -&&/clide +&] -&&slide +&[slide ### Проверете дали сте маркирани! @@ -105,15 +106,15 @@ git е програма (система) за [контрол на версииÑ  -&&/slide +&] -&&slide +&[slide ## GitHub classroom -&&lineb3 +&.br3 За всеки практикум ще ви направя линк, чрез който след малко кликане ще се създаде ново лично repository за всеки от вас. @@ -124,38 +125,37 @@ GitHub предоставя лесни начини да правите пром Те ще се намират в таба "Pull Requests" на конкретното repository. Четете ги, отговаряйте, целта е да дискутираме какво сте направили. -&&/slide +&] -&&slide +&[slide ### Как ползваме GitHub classroom За всяко упражнение ще има отделен линк. Този за днеска е: [classroom.github.com/a/W7hZDMgC](https://classroom.github.com/a/W7hZDMgC) -&&lineb1 +&.br1 -&&table +&{row След като го отворите, ще видите съобщение за разрешение, авторизирайте го.  -&&/table - -&&/slide +&} +&] -&&clide +&[middle -&&table +&{row -&&width60  &&/width +&(width60%  &) -&&cont +&{column При първо влизане ще получите страница с имената и факултетните имена на всички студенти от групата. @@ -163,30 +163,29 @@ GitHub предоставя лесни начини да правите пром Това се прави само веднъж, и след това никога пак. -&&/cont - -&&/table +&} -&&/clide +&} +&] -&&slide +&[slide След това, би трябвало да видите страницата за "Приемане на заданието". -&&width40  &&/width +&(width40%  &) След като го приемете, на новата страница, изчакайте няколко секунди и презаредете. Трябва да видите това: -&&width40  &&/width +&(width40%  &) -&&/slide +&] -&&clide +&[middle Сега сте готови, кликнете върху синия линк и ще стигнете във вашето GitHub repository. @@ -197,28 +196,28 @@ GitHub предоставя лесни начини да правите пром В края на презентация показвам как точно е най-лесно да качите работата си. -&&/clide +&] -&&slide +&[slide В таба "Pull requests", още от началото, ще имате едно "Feedback". В него ще ви връщам отзиви относно работата ви, и вие също можете да пишете неща и да ми отговаряте. Целта е да видя какво правите и да ви помогна, моля проверявайте какво съм ви писал, по подразбиране би трябвало да получавате известия на имейл-а. -&¢ered &&width80  &&/width &&/centered +&(centered &(width80%  &) &) -&&/slide +&] -&&slide +&[slide ## Къде пишем код? -&&lineb2 +&.br2 **Кодът е чисто и просто текст**, компилаторът е специалната програма, която превръща този текст в нещо, което може компютъра да изпълни. @@ -228,11 +227,11 @@ GitHub предоставя лесни начини да правите пром За някои и това не е било достатъчно удобно, затова са създадени **Integrated Development Environment** (IDE), програми които съдържат в себе си всичко нужно за разработка на код. Тоест, те са текстови редактори, но "вградено" могат да компилират код, да менижират сегашното repository, ... -&&/slide +&] -&&clide +&[middle Главно очакваме да пишете на IDE-то наречено Visual Studio. Разработено е от Microsoft и е едно от най-използваните и развитите IDE-та на пазара. @@ -246,15 +245,15 @@ GitHub предоставя лесни начини да правите пром Извън това, по лично желание, с мен може да говорите за vim, а за neovim може би ще мога да ви насоча към някой с опит. -&&/clide +&] -&&slide +&[slide ### Инсталация -&&lineb1 +&.br1 Намираме се в компютърна зала, така че всички предоставени компютри би трябвало вече да са налични на предоставените компютри. За ваши лични машини, ще минем набързо през информацията тук. @@ -265,79 +264,79 @@ GitHub предоставя лесни начини да правите пром - Ако искате да ползвате по-стара ОС, като Windows 8.1 или Windows 7 ще трябва да използвате "Community 2019"[^vs-2022-old-win], разликата между версиите не е съществена, затова не се притеснявайте. -&&/slide +&] -&&slide +&[slide След като изтеглите инсталатора за Visual Studio и след като изчакате да заредят работи, би трябвало да имате прозорец на име "Installing - Visual Studio Community 2022". Единствено избирате "Desktop development with C++" в таба Worloads, и натискате "Install". Би трябвало да заема към 11 GB памет и в моето тестване се инсталира за 10тина минути. -&¢ered &&width80  &&/width &&/centered +&(centered &(width80%  &) &) -&&/slide +&] -&&slide +&[slide Когато е готово, би трябвало да се включи автоматично и да имате прозорец с име "Sign in to Visual Studio". За сега това не е нужно, спокойно изберете "Not now, maybe later." След това, на "Start with a familiar environment", отново, не е нужно да променяте нищо, просто натиснете "Start Visual Studio". -&¢ered &&width75 &&table +&(centered &(width75% &{row   -&&/table &&/width &&/centered +&} &) &) -&&/slide +&] -&&slide +&[slide ### Как да създадем проект с Visual Studio Това е първия прозорец, който се отваря. В лявата колона имате скорошни проекти, в дясната имате начини да създадете нов проект. -&¢ered &&width80  &&/width &&/centered +&(centered &(width80%  &) &) -&&/slide +&] -&&slide +&[slide Нека да направим нов проект, кликнете "Create a new project". В този прозорец избирате началната "конфигурация" на проекта. В този курс ще работим само и единствено с "Console App", затова изберете него и кликнете "Next". -&¢ered &&width75  &&/width &&/centered +&(centered &(width75%  &) &) -&&/slide +&] -&&slide +&[slide Последния прозорец преди писането на код е за конфигурация на проекта. Тук единствено може да искате да промените Project Name и Location, другото не е важно. -&¢ered &&width80  &&/width &&/centered +&(centered &(width80%  &) &) -&&/slide +&] -&&slide +&[slide #### Бърза вметка, какво и защо конзолата? @@ -351,50 +350,50 @@ GitHub предоставя лесни начини да правите пром Чисто практически, ние това знаем като конзолата: устройство (или в модерно време, програма) което може да получи входен текст и да изкара текст. -&&/slide +&] -&&slide +&[slide ### Как да компилираме с Visual Studio След малко чакане, най-после ще се намираме в средата за писане на код. -&¢ered &&width60  &&/width &&/centered +&(centered &(width60%  &) &) В Solution Explorer имате всички файлове от проекта (Visual Studio позволява да групирате няколко проекта в едно, наречено Solution, не е нужно да се занимавате). Тук **единственото важно за вас се намира в папката "Source Files"**. В нея ще се намира вашия код, всичко останало са допълнителни неща, които са релевантни за по-големи проекти. -&&/slide +&] -&&slide +&[slide -&&table +&{row Компилирането на код става от менюто "Debug" най-отгоре, и след това избиране на "Start Without Debugging". -&&width50 &&fright  &&/fright &&/width +&(width50% &(fright  &) &) -&&/table +&} След малко чакане, би трябвало да излезе един прозорец, който изглежда горе-долу така:  -&&/slide +&] -&&slide +&[slide ### Как да дебъгваме с Visual Studio -&&lineb1 +&.br1 Bug е когато нещо непланирано се случи в кода. Debuging е глаголът за откриване на причината за един bug. @@ -406,11 +405,11 @@ Visual Studio предоставя много функционалности, к  -&&/slide +&] -&&slide +&[slide Нека да натиснем "No" и да погледнем Visual Studio. @@ -419,13 +418,13 @@ Visual Studio предоставя много функционалности, к Грешки също се виждат в така наречения "Error List", който се намира директно под кода. Той се появява когато при компилиране получим грешки и изчезва когато няма. -&¢ered &&width70  &&/width &&/centered +&(centered &(width70%  &) &) -&&/slide +&] -&&slide +&[slide ### Качване на решенията @@ -443,14 +442,14 @@ Visual Studio предоставя много функционалности, к Горе в дясно натискате "Commit changes...", в pop-up-a после пак натискате "Commit changes" (ако искате, променяйте "Commit message" и "Extended description", но не е нужно) и сте готови с този файл/задача. -&&/slide +&] -&&clide +&[middle ## Вече имате достатъчно информация да пишете код сами, [време е за задачи](./) -&&/clide +&] [^vs-2022-old-win]: Може би има трикове с които да инсталирате 2022 версията, но те не са официални и затова няма да го преподам diff --git a/src/teaching/upp-2023/week1/welcome.md b/src/teaching/upp-2023/week1/welcome.md index dfa46f0..a1cb6a0 100644 --- a/src/teaching/upp-2023/week1/welcome.md +++ b/src/teaching/upp-2023/week1/welcome.md @@ -1,52 +1,52 @@ # Добре дошли - УПП, Седмица 1, 06.10.2023 -&&presentation +&.presentation -&&slide &¢ered &&font35 +&[title35 # Добре дошли -&&width65 +&(width65% [](https://en.wikipedia.org/wiki/Infinite_monkey_theorem) -&&/width +&) -&&/font &&/centered &&/slide +&] -&&slide +&[slide ## Кой съм аз -&&lineb2 +&.br2 -&&font35 +&(font35 Казвам се Камен (моля не ми говорете на Вие), в момента съм третокурсник в КН2. -&&lineb1 +&.br1 Ще водя практикуми - давам ви задачи, вие ги решавате и на живо оправяме проблеми. -&&lineb1 +&.br1 Също ще проверявам част от домашните и контролните през семестъра. -&&/font +&) -&&/slide +&] -&&slide +&[slide ## Кои сте вие Айде сега, ред по ред: -&&lineb2 +&.br3 -&&font35 +&(font35 - Име - Едва ли ще го запомня сега, не ми се сърдете :) @@ -56,24 +56,24 @@ - в какво IDE/текстов редактор? - как сте се научили (чрез интернет, курсове, ...)? Ходили ли сте на курсове? Къде? -&&/font +&) -&&/slide +&] -&&slide +&[slide ## Чисто организационно -&&lineb3 +&.br3 -&¢ered &&font35 +&(centered35 Задачи, презентации, ... [syndamia.com/teaching/upp-2023](/teaching/upp-2023) -&&/font &&/centered +&) -&&lineb3 +&.br3 - Не сме в училище, ако трябва да излезете за разговор или до тоалетна, просто си излезте (за предпочитане по-тихичко). @@ -82,11 +82,11 @@ - Оценяване: ще разберете на първата лекция -&&/slide +&] -&&slide +&[slide ## Как можете да се свържете @@ -101,11 +101,11 @@ Директни линкове към Facebook и Discord има на [профила ми в мудъл](https://learn.fmi.uni-sofia.bg/user/profile.php?id=23229). -&&/slide +&] -&&slide +&[slide ## Как ще протичат практикумите @@ -121,11 +121,11 @@ - Ще качвам решения на задачите, заедно с подробно коментари върху тях, тук: [github.com/Syndamia/upp-2023-solutions](https://github.com/Syndamia/upp-2023-solutions). Това ще се случва в началото на следващия практикум, тоест ще имате една седмица, от деня в който ви давам задачите, през която няма да имате решения. -&&/slide +&] -&&clide +&[middle - Ще използваме GitHub classroom, където ще трябва да качите работата си през упражнението. Целта е да видя какво сте правили и да връщам обратна връзка на всеки. @@ -136,11 +136,11 @@ - Обратна връзка със сигурност ще правя за нещата, предадени по време на практикума. Окуражавам ви да си решите всички задачи и след упражнението, обаче все пак имам лимитирано време, ако искате можете да се свържете с мен за работата ви по някоя от тях, но не гарантирам кога ще мога да го видя. -&&/clide +&] -&&slide +&[slide ## Оплаквайте се! @@ -149,7 +149,7 @@ Ако задачите са трудни, зле направени, ако нещо не обяснявам като хората, изобщо ако нещо не е ок, свържете се с мен, ще го обсъдим. -&&lineb3 +&.br3 ## Помагайте си! @@ -159,17 +159,17 @@ Със сигурност няма да успея да помогна на всеки по всяко време от практикума, не се страхувайте да питате съседите си за помощ. -&&/slide +&] -&&slide +&[slide ## Няколко съвета в позицията ми на третокурсник -&&lineb2 +&.br2 -&&font35 +&(font35 - **НЕ плагиатствайте!** **НЕ си качвайте решенията на контролни или домашни онлайн!** @@ -179,47 +179,47 @@ За хората с опит, ще дойде време когато ще искате да приложите лични знания и практики. Ако не е казано някъде, не го правите и не го обмисляте! -&&/font &&/slide +&) &] -&&clide &¢ered +&[title # Въпроси ? -&&/centered &&/clide +&] -&&clide &¢ered +&[title # ФМИ в контекста на програмирането Или защо учим толкова много математика -&&lineb2 +&.br2 -&&font22 +&(font22 Ще си позволя едно отклонение. Искам да обясня как **аз лично** виждам математиката в компютърния свят. -&&/font +&) -&&/centered &&/clide +&] -&&slide +&[slide ## В КН2 има много и трудна математика -&&table +&{row -&&width35 +&(width35%  -&&/width +&) -&&cont +&{column - Жълто - математически предмет - Червено - проблемни предмети @@ -230,14 +230,14 @@ - Към половината предмети са математики - Почти всички проблемни са наблъскани в 1ви курс -&&/cont +&} -&&/table -&&/slide +&} +&] -&&slide +&[slide ## Защо учим толкова много математика? @@ -248,40 +248,38 @@ Смесица на уводите в няколко предмета: -&&table +&{row -&&font35 +&(font35  Claude Shannon -&&/font +&) -&&cont +&{column - **Булева алгебра**: как работим с истина/лъжа, с 0/1 - Доказана е [еквивалентност между ел. вериги и булевата алгебра](https://en.wikipedia.org/wiki/A_Symbolic_Analysis_of_Relay_and_Switching_Circuits). - Много типове данни и математически операции могат да се сведат до булева алгебра и работа с памет. -&&/cont +&} +&} &] -&&/table &&/slide - - -&&slide +&[slide ### Дискретни структури (продължение) -&&lineb1 +&.br1 - **Теория на множествата**: множество е някаква съвкупност от обекти - Позволява ни да третираме колекция от математически обекти като математически обект[^importance-of-sets]. Използва се в основата на много математики; колкото са полезни те, толкова са и множествата. -&&lineb2 +&.br2 - **Комбинаторика**[^importance-of-combinatorics]: изследва бройки на неща @@ -289,55 +287,55 @@ Claude Shannon - Употребява се при оптимизации и теория на кодирането (компресиране на данни, отстраняване на грешки, криптография) - Есенциална в теория на графите -&&/slide +&] -&&slide +&[slide ### Дискретни структури (продължение) -&&lineb5 +&.br5 - **Теория на графите**: граф е съвкупност от някакви обекти и връзки между тях. - Позволява моделиране на много естествени структури: интернет мрежите, географски карти (места и пътищата между тях), йерархии, биологически мрежи и так. нат. - Използва се във важни структури от данни като [heap](https://en.wikipedia.org/wiki/Heap_%28data_structure%29) (и интересната [fibonacci heap](https://www.youtube.com/watch?v=6JxvKfSV9Ns)) и [trie](https://en.wikipedia.org/wiki/Trie) -&&/slide +&] -&&slide +&[slide ### Езици, автомати и изчислимост -&&lineb5 +&.br5 -&&table +&{row -&&font35 -&&width85  &&/width +&(font35 +&(width85%  &) Stephen Kleene -&&/font +&) -&&cont +&{column Това е част от материала в по-общото "theoretical computer science". Можем формално да опишем и работим с теоретични компютри и програми. - Позволява ни да използваме математика за създаване, обработка и доказване на програми -&&/cont +&} -&&/table -&&/slide +&} +&] -&&slide +&[slide -&&lineb1 +&.br1 ### Алгебра 1 @@ -347,7 +345,7 @@ Stephen Kleene - Основоположна в компютърната графика - Много използвана в machine learning -&&lineb3 +&.br3 ### Диференциално и интегрално смятане @@ -357,11 +355,11 @@ Stephen Kleene - Напреднал machine learning, главно заради употребата на статистиката (която на свой ред се основава на линейната алгебра) - Анализ на алгоритми -&&/slide +&] -&&slide &&font35 +&[slide35 ## В по-общ план @@ -378,11 +376,11 @@ Stephen Kleene Математиката е **неразделима** част от софтуера! Друг е въпросът дали на вас лично ще ви се налага да я използвате... -&&/font &&/slide +&] -&&slide +&[slide ## Какво означава да пишеш софтуер? @@ -394,32 +392,32 @@ Stephen Kleene - Най-великият труд на тази дисциплина е постигнат чрез **синхрон** между тези три предмета - &¢ered &&width60 &&table + &(centered &(width60% &{row   - &&/table &&/width &&/centered + &} &) &) -&&/slide +&] -&&clide &¢ered &&font35 +&[title35 # Означава да създадеш<br>deus ex machina С други думи, позволява ни да разрешим неразрешими проблеми -&&/font &&/centered &&/clide +&] -&&clide &¢ered &&font35 +&[title35 # [Достатъчно философия, сега ще конфигурираме всичко нужно за първото ни упражнение](./setup.html) -&&/font &&/centered &&/clide +&] ### Употреба на изображения diff --git a/src/teaching/upp-2023/week10/img/fib.png b/src/teaching/upp-2023/week10/img/fib.png Binary files differnew file mode 100644 index 0000000..b0bc958 --- /dev/null +++ b/src/teaching/upp-2023/week10/img/fib.png diff --git a/src/teaching/upp-2023/week10/index.md b/src/teaching/upp-2023/week10/index.md new file mode 100644 index 0000000..722e705 --- /dev/null +++ b/src/teaching/upp-2023/week10/index.md @@ -0,0 +1,90 @@ +# Задачи - УПП, Седмица 10, 15.12.2023 + +GitHub classroom: [classroom.github.com/a/EJcTQRz4](https://classroom.github.com/a/EJcTQRz4) + +&:important Във всички задачи **трябва** да използвате рекурсия! + +## Задача 1 + +Най-големия общ делител на числата `a` и `b` е най-голямото, число което ги дели без остатък. +Евклидовият алгоритъм се базира на факта, че за две положителни числа `a` и `b`, като `a > b`, НОД на `a` и `b` е същия като НОД на `a - b` и `b` и когато `a = b`, тогава НОД на `a` и `b` е тяхната стойност. + +От входа получавате две цели положителни числа и трябва да изкарате техния НОД, чрез алгоритъма на Евклид **имплементиран с рекурсия**. + +**Примери:** + +|Вход|Изход| +|----|-----| +|6 6 |6 | +|48 18|6 | + +## Задача 2 + +От входа получавате неотрицателно число `N`, което ще бъде някое число на Фибоначи. +Трябва да върнете кое по ред е, като 0 е нулевото, 1 е първото, 2 е третото, 3 е четвъртото и так. нат. +Напомням, че математически фибоначи се дефинира така: + +<!-- +\begin{align*} +F_n = \left\{ \begin{array}{ll} +0, & n=0 \\ +1, & n=1 \\ +F_{n-1} + F_{n-2} & \text{иначе} \\ +\end{array} \right. +\end{align*} +--> + + + +**Примери:** + +|Вход|Изход| +|----|-----| +|0 |0 | +|1 |1 | +|3 |4 | +|144 |12 | +|1597 |17 | +|46368|24 | + +## Задача 3 + +От входа получавате положително число `N`, трябва да изкарате на екрана "рисунка", показваща формата на пясъчен часовник с височина `2N` (вижте примерите). + +**Примери:** + +|Вход|Изход| +|----|-----| +|1 |<pre>+<br>#</pre>| +|2 |<pre>+++<br> +<br> #<br>###</pre>| +|3 |<pre>+++++<br> +++<br> +<br> #<br> ###<br>#####</pre>| +|5 |<pre>+++++++++<br> +++++++<br> +++++<br> +++<br> +<br> #<br> ###<br> #####<br> #######<br>#########</pre>| + +## Задача 4 + +От входа получавате число `N`, след това тябва да изкарате на нови редове, в нарастващ ред, всички двоични числа, които могат да се представят с `N`-бита. +Вкарвате и водещи нули, тоест всяко число е съставено от точно `N` букви (`N` нули и единици). + +**Примери:** + +|Вход|Изход| +|----|-----| +|1 |0<br>1| +|2 |00<br>01<br>10<br>11| +|3 |000<br>001<br>010<br>011<br>100<br>101<br>110<br>111| +|4 |0000<br>0001<br>...<br>0111<br>1000<br>1001<br>...<br>1101<br>1110<br>1111| + +## Задача 5 + +Получавате един ред от терминала, в който ще имате скоби, знакът `+` и `*`, шпации и числа. +Това е прост математически израз, трябва да изкарате резултата след неговото пресмятане, като винаги около `число + число` и `число * число` има скоби (тоест не е нужно да се притеснявате от приоритет и асоциативност). + +За удобство спокойно може да ползвате `atoi` за конверитране на числовите части от низа в числа. + +**Примери:** + +|Вход|Изход| +|----|-----| +|(1 + 2)|3 | +|((2 + 9) * 3)|33| +|(((8 * 1) * (56 + 4)) + (19 * 2))|518| diff --git a/src/teaching/upp-2023/week11/index.md b/src/teaching/upp-2023/week11/index.md new file mode 100644 index 0000000..92ce89e --- /dev/null +++ b/src/teaching/upp-2023/week11/index.md @@ -0,0 +1,127 @@ +# Задачи - УПП, Седмица 11, 22.12.2023 + +GitHub classroom: [classroom.github.com/a/cZRnZj9y](https://classroom.github.com/a/cZRnZj9y) + +&:important Във всички задачи **трябва** да използвате рекурсия! + +&:warn Някои задачи се повтарят с тези от миналия път, ако преди не сте ги решили, сега ги решете + +## Алтернативни задачи + +Считайте [задачите от семинара](https://github.com/ivanahristova/introduction-to-programming-2023-2024/tree/main/sem11#%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8) като задачи преди тези. +Тоест, за хората които се затрудняват повечко, решете семинарните и след това се върнете тук. +Разбира се, ще помагам и със семинарните задачи. + +## Задача 1 + +От входа получавате неотрицателно число `N`, което ще бъде някое число на Фибоначи. +Трябва да върнете кое по ред е, като 0 е нулевото, 1 е първото, 2 е третото, 3 е четвъртото и так. нат. + +Напомням, че нормално Фибоначи се дефинира като редица, която започва с числата 0 и 1, и всяко следващо е сумата на предходните две. +Тоест, нулевото число е 0, първото 1, второто е `0 + 1 = 1` (понеже 1 се повтаря, зачитаме го за първото число), третото е `1 + 1 = 2`, четвъртото е `1 + 2 = 3` и так. нат. + +**Примери:** + +|Вход|Изход| +|----|-----| +|0 |0 | +|1 |1 | +|3 |4 | +|144 |12 | +|1597 |17 | +|46368|24 | + +## Задача 2 + +От входа получавате положително число `N`, трябва да изкарате на екрана "рисунка" на триъгълници. + +### a) горен триъгълник + +Рисунката е един правоъгълен равнобедрен триъгълник от знака `+`, като `N` определя размера на равнобедрените страни (вижте примерите). + +**Примери:** + +|Вход|Изход| +|----|-----| +|1 |<pre>+</pre>| +|2 |<pre>+<br>++</pre>| +|3 |<pre>+<br>++<br>+++</pre>| +|5 |<pre>+<br>++<br>+++<br>++++<br>+++++</pre>| + +### б) долен триъгълник + +Подобно на предходната подточка, обаче обърнат по хоризонтала, и със знака `#`. + +**Примери:** + +|Вход|Изход| +|----|-----| +|1 |<pre>#</pre>| +|2 |<pre>##<br>#</pre>| +|3 |<pre>###<br>##<br>#</pre>| +|5 |<pre>#####<br>####<br>###<br>##<br>#</pre>| + +### в) пълен триъгълник + +**Използвайки само една рекурсивна функция,** сега трябва да изкарате първо горния триъгълник и след това долния. +Ако просто извикате предходните две функции една след друга, задачата се обезсмисля. + +**Примери:** + +|Вход|Изход| +|----|-----| +|1 |<pre>+<br>#</pre>| +|2 |<pre>+<br>++<br>##<br>#</pre>| +|3 |<pre>+<br>++<br>+++<br>###<br>##<br>#</pre>| +|5 |<pre>+<br>++<br>+++<br>++++<br>+++++<br>#####<br>####<br>###<br>##<br>#</pre>| + +## Задача 3 + +Направете програма която разрешава проблема с [възрастта на трите деца](https://en.wikipedia.org/wiki/Ages_of_Three_Children_puzzle). + +Една жена има три деца за които знаем три неща: умножението на техните възрасти, сбора на техните възрасти и факта, че има едно дете, което е най-голямо. +Трябва да намерите възрастта на всяко дете, само по тази информация. + +Разбира се, от входа получавате две числа, съответно умножението и сбора на възрастите им. +Трябва на екрана да изкарате три числа - възрастите на трите деца. + +**Подсказка:** най-лесното решение е да пробвате всички възможни възрасти, като избягвате техни пермутации + +**Примери:** + +|Вход|Изход| +|----|-----| +|72 14|3 3 8| +|36 13|2 2 9| +|350 42|2 5 35| + +## Задача 4 + +От входа получавате число `N`, след това трябва да изкарате на нови редове, в нарастващ ред, всички двоични числа, които могат да се представят с `N`-бита. +Вкарвате и водещи нули, тоест всяко число е съставено от точно `N` букви (`N` нули и единици). + +**Примери:** + +|Вход|Изход| +|----|-----| +|1 |0<br>1| +|2 |00<br>01<br>10<br>11| +|3 |000<br>001<br>010<br>011<br>100<br>101<br>110<br>111| +|4 |0000<br>0001<br>...<br>0111<br>1000<br>1001<br>...<br>1101<br>1110<br>1111| + +## Задача 5 + +Направете програма която разрешава [Такузо пъзели](https://en.wikipedia.org/wiki/Takuzu). + +Започвате с дъска 4х4, в тази дъска може да имате само цифрите 0 и 1, като няколко клетки вече идват с попълнени стойности (но повечето са празни). +Обаче, на всяка колона и ред трябва да има еднакъв брой 0ли и 1ци, и не трябва да има повече от две последователни еднакви цифри (в реда или колоната). + +От входа получавате дъската, като с -1 обозначаваме празна клетка. + +**Примери:** + +|Вход|Изход| +|----|-----| +|-1 1 -1 0<br>-1 -1 0 -1<br>-1 0 -1 -1<br>1 1 -1 0|0 1 1 0<br>1 0 0 1<br>0 0 1 1<br>1 1 0 0| +|-1 0 1 -1<br>1 -1 0 -1<br>0 1 -1 -1<br>0 0 1 -1|1 0 1 0<br>1 1 0 0<br>0 1 0 1<br>0 0 1 1| +|-1 0 -1 -1<br>-1 0 0 -1<br>0 -1 -1 -1<br>-1 -1 -1 0|0 0 1 1<br>1 0 0 1<br>0 1 1 0<br>1 1 0 0| diff --git a/src/teaching/upp-2023/week12/index.md b/src/teaching/upp-2023/week12/index.md new file mode 100644 index 0000000..d914431 --- /dev/null +++ b/src/teaching/upp-2023/week12/index.md @@ -0,0 +1,109 @@ +# Задачи - УПП, Седмица 12, 05.01.2024 + +GitHub classroom: [classroom.github.com/a/KEDSxDjl](https://classroom.github.com/a/KEDSxDjl) + +&:important Във всички задачи **трябва** да използвате рекурсия! + +## Алтернативни задачи + +Считайте [задачите от семинара](https://github.com/ivanahristova/introduction-to-programming-2023-2024/tree/main/sem12) и [тези от миналия път](../week11/) като част от днешните задачи. +Тоест, за хората които се затрудняват повечко, решете ги и след това се върнете тук. +Разбира се, ще помагам и с тях. + +## Задача 1 + +Имате някакъв брой предмети, като всеки предмет има ценност (число) и тежест (число пак). +Искате в раница да сложите предмети, като целта е ценността да бъде максимална, обаче раницата има капацитет на тежест, тоест тази ценност трябва да бъде спрямо максималната обща тежест. + +От входа получавате число N, след това толкова на брой предмета (тоест 2N на брой числа, като броейки от нула, четните са ценностти, а нечетните тежести). +Накрая получавате максималната обща тежест за раницата. +Трябва да изкарате на екрана максималната възможна обща ценност. + +**Примери:** + +|Вход|Изход| +|----|-----| +|3<br>1 4<br>2 5<br>3 1<br>4|3| +|3<br>1 4<br>2 5<br>3 6<br>3|0| +|6<br>50 56<br>50 59<br>64 80<br>46 64<br>50 75<br>5 17<br>190|150<!-- https://people.sc.fsu.edu/~jburkardt/datasets/knapsack_01/knapsack_01.html -->| + + +## Задача 2 + +Получавате N и M, съответно броя редове и колони в дъска. +Всяка клетка от дъската е пълна или празна. +След това получавате NxM на брой символа за всяка клетка, като `-` означава празна клетка, докато `#` означава пълна. +Накрая получавате две числа - координати (започващи от нула, като 0,0 е горния-ляв ъгъл) в дъската. + +От подадените координати трябва да запълните "фигурата" в която се намира (фигурата която огражда) дадената плочка. +С други думи, представете си че дъската е изображение, всяка клетка е пиксел, в изображението има бели и черни пиксели, и на дадените координати е кликнато с "Bucket fill" за да се оцвети в черно дадена фигура. + +Оцветяването да се случва само в 4те прави посоки (без диагонали). + + + +**Пример:** + +|Вход|Изход| +|----|-----| +|5 11<br><pre>- - # # - - - - - - -<br>- # - - # - - - - - -<br># - - - - # # # # # #<br>- # - - # - - - # - #<br>- - # # - - - - - - -</pre>2 2|<pre>- - # # - - - - - - -<br>- # # # # - - - - - -<br># # # # # # # # # # #<br>- # # # # - - - # - #<br>- - # # - - - - - - -</pre>| + +## Задача 3 + +Имате шахматна дъска (8 на 8) и върху нея имате 8 царици. +Напомням, че царицата в шаха може да се движи вертикално, хоризонтално и диагонално произволен брой клетки в един ход. + +Интересуваме се от такова поставяне на всички царици, че нито една няма да вземе никоя друга царица в един ход. +Пример: + + + +Напишете програма, която намира броя на възможните такива поставяния на цариците. +От входа не получавате нищо. + +**Пример:** + +|Вход|Изход| +|----|-----| +| |92 | + +**Бонус:** направете програмата да изкарва всяко решение + +## Задача 4 + +<!-- https://mathcenter.oxford.emory.edu/site/cs171/probSetUsingStacks/ --> + +Нормално ние представяме математически операции чрез "инфиксен" запис, тоест операторът е по средата, между нещата върху които работи (пример: `1 + 2`). +Обаче, това не е задължително, по обратната полска нотация винаги слагаме оператът след нещата върху които работи (пример: `1 2 +`). + +Бонусът на това, е че не ни трябва скобуване и ред на операциите. +В инфиксния израз `(2 + 3) * (2 ^^ 2)`, без скобите, сбора ще се извърши след умножението и степенуването ще се извърши след умножението. +Обаче, ако искаме да изразим това в обратен полски запис, просто правим `2 3 + 2 2 ^^ *`. +А ако искаме оригиналното действие, без скоби, записваме `2 3 2 * 2 ^^ +`. + +Ако изглежда объркващо, идеята е че всеки оператор работи върху предходните две стойности, изчисляваме изразите от ляво надясно и заместваме веднага. +Тоест, при последния пример, пропускаме първите три числа, стигаме до `*`, умножаваме последните две и заместваме трите неща (`3 2 *`) с резултата, следователно имаме `2 6 2 ^^ +`, пропускаме две, стигаме до `^^` и так.нат. + +Направете програма, която чисто рекурсивно изчислиява изрази в обратен полски запис, който поддържа цели числа и операциите събиране, умножение, деление, изваждане и степенуване (за степенуване ще използваме знакът `^`). + +&:important Обаче, за едно извикване на рекурсивната функция, може да пазите само един елемент на израза (число или оператор)! + +Изразът винаги завършва на знака `$`. + +&:warn Относно вход/изход, понеже няма как да знаем дали i-тата стойност е число или знак (операция), трябва да използваме функцията `std::cin.fail()`, която връща булева стойност, която ни казва дали записването на входа е било успешно.<br> + Тоест, може винаги да запазвате входа в целочислен тип, когато стигнете до знак `std::cin.fail()` ще върне `true`. + След това трябва да "забравите" за грешката чрез `std::cin.clear()` и може втори път да запазите входа (провалените данни ще се препрочетат) в променлива от знаков тип.<br> + Но това поражда друг проблем, понеже записваме в целочислен тип, когато въведем `+` или `-`, `std::cin` ще очаква това да е водещ знак на число, и ще продължи да чака входа докато не въведем друг знак, тоест `+` и `-` ще бъдат пропуснати. + Като компромисен вариант, просто пред тях винаги ще слагаме `'` и в кода ще го пропускаме. + +**Примери:** + +|Вход|Изход| +|----|-----| +|1 2 '+ 3 / $|1| +|1 4 3 2 ^ * '+ 14 7 / '- $|35| + +## Attribution + +- Анимация в [Задача 2](#2) от André Karwath (Aka) на [Уикипедия](https://commons.wikimedia.org/w/index.php?curid=481651) под лиценз CC BY-SA 2.5 +- Изображение на шахматна дъска в [Задача 3](#3) от Encik Tekateki в [Уикипедия](https://commons.wikimedia.org/w/index.php?curid=77832290) под лиценз CC BY-SA 4.0 diff --git a/src/teaching/upp-2023/week13/index.md b/src/teaching/upp-2023/week13/index.md new file mode 100644 index 0000000..f0e4b9a --- /dev/null +++ b/src/teaching/upp-2023/week13/index.md @@ -0,0 +1,145 @@ +# Задачи - УПП, Седмица 13, 12.01.2024 + +GitHub classroom: [classroom.github.com/a/bgiFD6SB](https://classroom.github.com/a/bgiFD6SB) + +## Алтернативни задачи + +Считайте [задачите от семинара](https://github.com/ivanahristova/introduction-to-programming-2023-2024/tree/main/sem13) и [тези от миналия път](../week12/) като част от днешните задачи. +Тоест, за хората които се затрудняват повечко, решете ги и след това се върнете тук. +Разбира се, ще помагам и с тях. + + +## 1 задача + +От входа получавате число N, това е броя на "пробни" думи. +След тях получавате още една дума, която е желаната дума. +Трябва да изкарате коя пробна дума е най-близка до (различава се с най-малко знаци с) желаната дума. + +Всяка дума е на нов ред и е съставена от малки латински букви. +Ако има няколко думи с еднаква "близкост", изкарайте последната от тях. + +**Примери:** + +|Вход|Изход| +|----|-----| +|5<br>cate<br>cot<br>dog<br>cote<br>co<br>cat|cot| +|4<br>nask<br>nmaskl<br>msdal<br>task<br>mask|task| + +## 2 задача + +В началото получавате неотрицателно цяло число N. +След това получавате N на брой редове. +Всеки ред е във формата "(Име) (Фамилия) (Брой продадени продукти)". + +Редовете са разбъркани, изкарайте първо име и фамилия на хората с най-много продадени продукти. +Ако има няколко хора, които са продали най-много продукти, изкарайте имената им в азбучен ред, първо по фамилия, после по име. + +Използвайте **само една функция за сортиране!** +Като подсказка, използвайте указатели към функции за да променяте как тя работи. + +&:question Какво свойство трябва да е изпълнено за сортиращата функция? + +**Примери:** + +|Вход|Изход| +|----|-----| +|Antony Garcia 10<br>John Doe 9<br>Joseph Carmichael 10<br>Steven Wayne 1<br>Bob Carmichael 10<br>Holy Wilson 9|Bob Carmichael<br>Joseph Carmichael<br>Antony Garcia| + +## 3 задача + +Ще дефинираме обвито изречение, като редица от букви, за които са изпълнени следните правила: + +- първата е главна +- последната е точка +- между тях има само малки букви, цифри и шпации +- всяко изречение е "обвито" до някакъв брой колони + + Тоест за всяко изречение са избрани максимален брой колони, и знаците са обвити, така че да се поберат. + Примерно, ако имахме изречението "Hello world." и бяхме избрали 5 колони, тогава получаваме: + + ``` + Hello + worl + d. + ``` + +От входа получавате N и M, те съответстват на матрица от символи с N реда и M колони. +В матрицата имате обвити изречения, подредени по такъв начин, че между съседни има със сигурност поне една шпация (която действа като разделител). +Допускаме, че при "двусмислици" възможно най-много шпации са част от изречението (а не от разделителя), тоест ако имаме: + +``` +A B +. . +``` + +тогава двете ни изречения са: + +``` +B. +A . +``` + +Изкарайте на конзолата всички обвити изречения в матрицата (редът им няма значение). + +**Примери:** + +|Вход|Изход| +|----|-----| +|<pre>7 13<br>Thi A Someth<br>s i n ing. <br>s c . <br>ool <br>. Good Hel<br> luc lo.<br>Ha. k. <br></pre>|Something.<br>An.<br>This is cool.<br>Hello.<br>Good luck.<br>Ha.<br>| +|<pre>2 7<br>B A.<br>. </pre>|<pre>A.<br>B .</pre>| +|<pre>3 7<br> A.<br>B <br>. </pre>|<pre>A.<br>B .</pre>| +|<pre>4 7<br> A.<br> <br>B <br>. </pre>|<pre>A.<br>B .</pre>| +|<pre>3 6<br>Big <br>jumper<br>. </pre>|<pre>Big jumper.</pre>| + +## 4 задача + +В префиксния (или полския) запис слагаме оператора за смятане пред (в ляво от) елементите върху които работи (нормален запис - `1 + 2`, полски запис - `+ 1 2`). +Ще разглеждаме "многоредови" изрази в полски запис, тоест изрази в които има няколко реда от целочислени стойности, така че трябва да се изчислят няколко израза с еднаква "форма", но различни стойности. + +Един такъв израз изглежда така: + +``` ++ 1 2 + 3 4 + 5 6 . +``` + +Точката на края на последния ред задава край на израза. +В този пример ще изчислим `1 + 2`, `3 + 4` и `5 + 6`, тоест ще "върне" три стойности: 3, 7 и 11. +Всяка колона в израза е от един и същи "тип", тоест в една колона винаги ще има числова стойност или някакъв знак. +С изключение на точката, всеки знак може да се постави на произволен ред (обаче в една колона не може да има повече от един знак). + +Примерно: + +``` + 1 - 2 2 63 ++ 3 4 7 7 + 5 6 * 8 9 . +``` + +Това ще изчисли `1 + (2 - 2 * 63)`, `3 + (4 - 7 * 7)` и `5 + (6 - 8 * 9)`. +Израза би направил същото нещо ако примерно всички знаци бяха на първия ред или на последния. + +От входа получавате няколко такива израза, докато не получите знака `$`. + +Може да достъпвате стойност от предходни изрази чрез синтаксиса "ИНДЕКС.ИНДЕКС", където индексите са от 0, първия определя номера на израза, докато втория определя коя стойност искаме. +Примерно: + +``` + 1 2 ++ 3 4 + 5 6 . +* 0.0 0.2 . +``` + +В последния израз умножаваме от нулевия израз, първата и третата стойност, тоест умножаваме 3 и 11. + +Накрая трябва да изкарате всички стойности от последния израз. + +&:warn Погледнете пояснението за вход/изход от [последната задача от миналия път](../week12/#4). + +**Пример:** + +|Вход|Изход| +|----|-----| +|<pre> 1 5<br>+ 2 6<br> 3 7<br> 4 8 .<br>- 0.3 0.2 .<br>* 1.0 0.1 .<br> 1.0 3 0.2 3<br> - 3 0.3 0.1 1.0<br>* 0.0 2.0 / 2.0 0.1 .<br>$<br></pre>|-3 -36 -20| diff --git a/src/teaching/upp-2023/week14/index.md b/src/teaching/upp-2023/week14/index.md new file mode 100644 index 0000000..cf28fe7 --- /dev/null +++ b/src/teaching/upp-2023/week14/index.md @@ -0,0 +1,239 @@ +# Задачи - УПП, Седмица 14, 19.01.2024 + +GitHub classroom: [classroom.github.com/a/B08TtnnW](https://classroom.github.com/a/B08TtnnW) + +Това е последния практикум, затова ви давам по-лесни и приятни задачи: имплементации на игри! +Всичките са взети от [101 BASIC Computer Games](https://en.wikipedia.org/wiki/BASIC_Computer_Games) (книгата е налична в [archive.org](https://archive.org/details/bitsavers_decBooks10Mar75_26006648)). + +Разбира се, който иска, може да решава задачи от предходни практикуми, давал съм достатъчно задачи. + +## 1 задача - Ним + +Ним е една много стара игра за два играча. +В произволен брой купчини са сложени произволен брой предмети (предметите не се различават, примерно камъни или пръчки). +Алтернативно, всеки играч взема някакъв брой (поне един) предмети от една купчина. +Играчът който вземе последния предмет печели. + +В нашия вариант, предметите са пръчки. +Компютъра автоматично (и случайно) генерира между 5 и 20 купчини с между 1 и 10 пръчки. +Разбира се, трябва компютъра да съобщи за конкретните стойности: + +```terminal +X piles +Y sticks in pile 1 +Z sticks in pile 2 +[...] +K sticks in pile X +``` + +След това се редуват, първия играч, втория играч: + +```terminal +Player 1 turn +``` + +Избирате купчина с пръчки: + +```terminal +Which pile do you want sticks from? _ +``` + +където _ е мястото на курсора. +След това броя пръчки от купчината: + +```terminal +How many sticks? _ +``` + +Ако някоя стойност е невалидна, питате пак. +След това идва редът на втория играч: + +```terminal +Player 2 turn +``` + +Накрая, този който вземе последната пръчка печели играта и се пита дали искате наново да почнете играта: + +```terminal +Player X won. Do you want to play again? _ +``` + +## 2 задача - Хамураби + +Вие играете като древния Вавилонски цар Хамураби над своя малък град. +Управлявате три ресурса във вашето царство: хора, земя и жито. +Имате власт 10 години, обаче обществото може да ви изгони и преди това. + +Не е от голямо значение да знаете, но акър земя е приблизително 4000 квадратни метра, а бушел жито е приблизително 4 килограма жито. + +В началото вашия съветник казва: + +```terminal +Hamurabi, I beg to report to you +In year X, Y people starved, Z came to the city. +``` + +Разбира се, X, Y и Z са положителни целочислени стойности. +По-късно ще определим как се изменят и какви са началните стойности. + +След това имате 1/7 шанс чума да сполети вашия град. +Ако се случи, съветника ви съобщава за това и загубвате половината си население: + +```terminal +A horrible plague struck! Half of the people died. +``` + +След това съветника ви дава информация за града: + +```terminal +Population is now X. +The city now owns X acres. +You harvested Z bushels per acre. +Rats ate K bushels. +You now have L bushels in store. +``` + +Разбира се, X, Y, Z, K и L са целочислени стойности. + +Ако тази информация е в последната година от вашето царуване, играта свършва и получавате мнението на населението за вас. + +Иначе, сега съветника започва да ви дава информация и да ви пита за вашето действие: + +```terminal +Land is trading at X bushels per acre. +How many acres do you wish to buy? _ +``` + +Където X е произволно цяло число между 17 и 27, долна черта показва мястото на курсора. +Трябва да се въведе цяло число. +В този случай, както и всеки други, ако то е отрицателно, съветника напуска и играта свършва: + +```terminal +Hamurabi, I cannot do what you wish, get yourself another steward!!!!! +So long for now. +``` + +Последния ред винаги се показва, когато играта свърши. + +Ако нямате достатъчно бушели в резерв, за да купите всичката въведена земя, съветника ви казва: + +```terminal +Hamurabi, think again, you have only X bushels of grian. Now then, +``` + +и същото съобщение за "Land is trading at [...] How many acres ..." се изписва и приемате нов вход. + +Ако сте въвели 0, значи искате да продавате земя и съветника ви пита: + +```terminal +How many acres do you wish to sell? _ +``` + +Ако се въведе отрицателно число, случва се същото като при купуване на земя. + +Ако въведете повече земя, отколкото имате, съветника казва: + +```terminal +Hamurabi think again, you own only X acres. Now then, +``` + +и пак пита "How many acres [...]". + +След като сте купили или продали земя, сега съветника ви пита колко бушели жито ще отделите за нахранване на населението: + +```terminal +How many bushels do you wish to feed your people? _ +``` + +Ако се въведе твърде голямо число, съветника предупреждава и пита пак: + +```terminal +Hamurabi, think again, you have only X bushels of grain. Now then, +How many bushels do you wish to feed your people? _ +``` + +Остава последния въпрос от съветника за годината: + +```terminal +How many acres do you wish to plant with seed? _ +``` + +Разбира се, ако се въведат повече акри отколкото има, съветника предупреждава и пита пак: + +```terminal +Hamurabi, think again, you own only X acres. Now then, +How many acres do you wish to plant with seed? _ +``` + +Предполагам може да се сетите какво съобщение съветника връща при отрицателни акри. + +Един бушел жито може да засее два акъра земя, ако няма достатъчно жито, съветника предупреждава и пита пак. +Отнема 10 човека да се грижат за един акър земя, ако няма достатъчно хора, съветника предупреждава и пита пак: + +```terminal +But you have only X people to tend the fields. Now then, +``` + +Това са въпросите на съветника, сега остава годината да се изиграе. +Хората жънат (произволно число) между 1 и 6 бушела жито на всеки акър. + +След това избирате друго произволно число между 1 и 6. +Ако числото е по-голямо от 1, тогава плъховете ще изядат по толкова голяма дроб бушели жито от резерва (при числото 5, плъховете изяждат 1/5; тук бушелите жито се смятат преди жътва). + +Сега населението расте, броя хора които са "дошли" в града се определя по формулата `R * (20 * АКРИ ЗЕМЯ + БУШЕЛИ ЖИТО) / БРОЙ ХОРА / 100 + 1`, където R е цяло число между 1 и 6. +Бушелите жито се смятат след жътва. + +Предпоследно, определя се колко хора са умрели от глад, като всеки човек консумира 20 бушели жито. +Ако над 45% от населението са умрели от глад, останалите хора ви свалят от власт и играта свършва: + +```terminal +You starved X people in one year, due to this extreme mismanagement, +you have not only been impeached and thrown out of office but you have +also been declared national fink! +So long for now. +``` + +Накрая на годината, трябва да обновите общия брой хора, които са умрели от глад, за цялото ви царуване, заедно със средния процент хора които са умирали на година. + +Ако успешно царувате 10 години, накрая съветника ви казва как сте се справили: + +```terminal +In your 10-year term of office, X percent of the population starved per year on average, +I.E., a total of Y people died. +``` + +Сега изчислявате пропорцията между земя и хора, съветника ви казва: + +```terminal +You started with 10 acres per person and ended with X acres per person. +``` + +Ако средно над 33% от населението е умирало от глад всяка година или съотношението ви е под 7 акъра на човек, тогава се случва същото нещо, като когато над 45% от населението умира от глад. + +Ако средно над 10% (но под 34%) от населението е умирало от глад всяка година или съотношението ви е под 9 акъра на човек (но над 6), тогава оставате в историята като лош владетел: + +```terminal +Your heavy-handed performance smacks of Nero and Ivan IV. +The people (remaining) find you an unpleasant ruler, and frankly, hate your guts. +So long for now. +``` + +Ако средно над 3% (но под 11%) от населението е умирало от глад всяка година или съотношението е между 9 и 10 акъра на човека, тогава оставате със средно впечатление: + +```terminal +Your performance could have been somewhat better but really wasn't too bad at all. +X people would dearly like to see you assassinated but we all have our trivial problems. +So long for now. +``` + +Където х съответства на бройката, между 0 и 80 процента от населението. + +В противен случай, тоест средно под 4% от населението е умирало от глад всяка година или съотношението е над 10 акъра на човека, тогава хората ви харесват: + +```terminal +A fantastic performance!!! +Charlemange, Disraeli and Jefferson combined could not have done better. +So long for now. +``` + +В началото на играта започвате с 100 човека население, като 5 от тях са дошли в града, 1000 акри земя, жътва от 3 бушела на акър, плъхове са изяли 200 бушела и имате 2800 бушела в хранилището. diff --git a/src/teaching/upp-2023/week2/revision.md b/src/teaching/upp-2023/week2/revision.md index ebf6db6..73e897f 100644 --- a/src/teaching/upp-2023/week2/revision.md +++ b/src/teaching/upp-2023/week2/revision.md @@ -1,20 +1,20 @@ # Преговор - УПП, Седмица 2, 13.10.2023 -&&presentation +&.presentation -&&clide &¢ered +&[title # Конвертиране на данни, побитови оператори, условни оператори -&&/centered &&/clide +&] -&&slide +&[slide ## Конвертиране на данни -&&lineb3 +&.br3 - Неявно (скрито, експлицитно): компилаторът сам се досеща да промени типа @@ -30,13 +30,13 @@ int m = (int)a + (int)b; ``` -&&/slide +&] -&&slide +&[slide -&&lineb5 +&.br5 - Със загуба на информация (от по-голям тип в по-малък) @@ -52,11 +52,11 @@ long b = a; ``` -&&/slide +&] -&&slide +&[slide ## Побитови оператори @@ -67,7 +67,7 @@ **Означавам побитовите числа с водеща буква "b"!** Тоест, числото `b1001` е двоичното число `1001`, което е десетичното число `9`. -&&lineb3 +&.br3 - Отрицание/негация, `~`: обръща 0 в 1 и 1 в 0 @@ -75,11 +75,11 @@ ~ b0010 = b1101 ``` -&&/slide +&] -&&slide +&[slide - Побитово "и", `&`: за два бита, ако и двете са 1, връща 1, иначе връща 0 @@ -102,11 +102,11 @@ b0011 ^ b0101 = b0110 ``` -&&/slide +&] -&&clide &&font27 +&[middle27 - Побитово отместване на ляво, `<<`: отмества всеки бит с n позиции на ляво Винаги "запълва" с нули (няма разлика между логическо и аритметично ляво отместване) @@ -128,11 +128,11 @@ b1010 >> 3 = b0001 или пък b1111 ``` -&&/font &&/clide +&] -&&clide +&[middle Примери с код: @@ -156,19 +156,19 @@ int r4 = (unsigned int)b >> 1; // 2 int r5 = (unsigned int)-b >> 1; // 2147483645 ``` -&&/clide +&] -&&slide +&[slide ## Логически оператори Много приличат на побитовите, обаче побитовите работят върху битове, докато логическите работят върху bool. -&&lineb4 +&.br4 - `!`: обръща `true` във `false` и обратно @@ -177,11 +177,11 @@ int r5 = (unsigned int)-b >> 1; // 2147483645 ! false // true ``` -&&/slide +&] -&&clide +&[middle - `&&`: "логическо и", ако и двете стойности са `true`, тогава и резултатът е `true` @@ -199,11 +199,11 @@ int r5 = (unsigned int)-b >> 1; // 2147483645 false || false // false ``` -&&/clide +&] -&&slide +&[slide ## Условни конструкции @@ -225,11 +225,11 @@ int r5 = (unsigned int)-b >> 1; // 2147483645 dootherthing; ``` -&&/slide +&] -&&clide &&font25 +&[middle25 - `if-else`: работи като `if`, обаче след къдравите скоби добавяме `else { ... }`. @@ -256,11 +256,11 @@ int r5 = (unsigned int)-b >> 1; // 2147483645 dootherthing; ``` -&&/font &&/clide +&] -&&slide &&font25 +&[slide25 - благодарение на изпускането на къдрави скоби, можем да пишем @@ -290,11 +290,11 @@ int r5 = (unsigned int)-b >> 1; // 2147483645 } ``` -&&/font &&/slide +&] -&&slide +&[slide - `expression` винаги се конвертира до тип `bool` (ако е нужно) **Никога не правете такива неща:** @@ -320,11 +320,11 @@ int r5 = (unsigned int)-b >> 1; // 2147483645 Просто правите `bool a = ! expression;` -&&/slide +&] -&&slide +&[slide - Тернарен оператор: ако искате да имате такава условна конструкция като част от израз (който взема стойност) използвате @@ -348,11 +348,11 @@ int r5 = (unsigned int)-b >> 1; // 2147483645 std::cout << ((grade < 300) ? 2.0 : grade / 100.0); ``` -&&/slide +&] -&&clide &&font27 +&[middle27 - `switch`: приема стойност и изпълнява случая, при който стойността съвпада с определената @@ -377,12 +377,12 @@ int r5 = (unsigned int)-b >> 1; // 2147483645 Без `break` изпълнението продължава към следващия `case` -&&/font &&/clide +&] -&&clide +&[middle ```cpp char characterInput; @@ -395,4 +395,4 @@ switch(characterInput) { } ``` -&&/clide +&] diff --git a/src/teaching/upp-2023/week3/revision.md b/src/teaching/upp-2023/week3/revision.md index cb0ac61..b1dab08 100644 --- a/src/teaching/upp-2023/week3/revision.md +++ b/src/teaching/upp-2023/week3/revision.md @@ -1,17 +1,17 @@ # Преговор - УПП, Седмица 3, 20.10.2023 -&&presentation +&.presentation -&&clide &&font35 &¢ered +&[title35 # Цикли, assert -&&/centered &&/font &&/clide +&] -&&slide &&font25 +&[slide25 ## Бележки от миналия път @@ -42,11 +42,11 @@ bool b = !condition; ``` -&&/font &&/slide +&] -&&clide +&[middle - второ: @@ -64,15 +64,15 @@ a >= '0' && a <= '9' ``` -&&/clide +&] -&&slide +&[slide ## С/без загуба на данни -&&lineb3 +&.br3 Получи се малко разногласие между това, което Ивана ви е казала и това което аз ви казах. В края на деня, **конвертиране от int към unsigned int не губи информация!** @@ -83,11 +83,11 @@ Тоест, конвертирания при които не губиш битове, нямаш загуба на данни. -&&/slide +&] -&&slide +&[slide ## 2s compliment @@ -109,11 +109,11 @@ 000 0 ``` -&&/slide +&] -&&clide +&[middle Това работи, обаче имаме един гигантски проблем: събирането не работи! От математика знаем, че "2 - 1 = 2 + (-1)", тоест би трябвало да можем да съберем побитово 2 и -1 и да получим 1. @@ -133,11 +133,11 @@ Да не говорим, че ние имаме -0, което не ни трябва много. -&&/clide +&] -&&clide +&[middle Нека да помислим пак, да вземем само положителните: @@ -156,11 +156,11 @@ Нека тогава "-1 = 111". -&&/clide +&] -&&slide +&[slide Правейки същото за "2 + -2", намираме че @@ -186,11 +186,11 @@ 100 не сме го използвали, обаче намерихме отрицателното число за всяко положително. Да видим как работим с него, побитово "100 + 001 = 101", тоест "x + 1 = -3", следователно x ще бъде -4. -&&/slide +&] -&&clide +&[middle Това е идеята на "complements", дефинираме отрицателни числа, така че да използваме едно и също събиране между положителни и отрицателни. @@ -212,15 +212,15 @@ 11111111111111111111111111111110 ``` -&&/clide +&] -&&slide +&[slide ## Цикли -&&lineb4 +&.br4 - `while` цикъл @@ -232,11 +232,11 @@ "условие" е булева стойност, като ако е `false` цикъла спира, докато ако е `true` "тяло" се изпълнява и после пак се проверява условие -&&/slide +&] -&&clide +&[middle - Може да си го представите като @@ -258,11 +258,11 @@ ... ``` -&&/clide +&] -&&slide +&[slide - `do-while` цикъл, като `while`, но "тяло" се изпълнява поне един път @@ -289,11 +289,11 @@ ... ``` -&&/slide +&] -&&clide +&[middle - `for` цикъл @@ -307,11 +307,11 @@ "условие" се изпълнява преди всяка итерация, като ако е `false` цикъла спира, докато ако е `true` продължава "инкрементация" се изпълнява след края на всяка итерация -&&/clide +&] -&&slide +&[slide - Може да си представяте, че това на практика извършва: @@ -336,11 +336,11 @@ ... ``` -&&/slide +&] -&&clide +&[middle - или използвайки `while` цикъл: @@ -352,36 +352,36 @@ } ``` -&&/clide +&] -&&slide +&[slide ### Ключови думи -&&lineb3 +&.br3 - `break`: моментално прекратява изпълнението на цикъла При `for` цикли инкрементацията не се изпълнява след `break` -&&lineb2 +&.br2 - `continue`: продължи след края на сегашната итерация; тоест изпълнението на тяло се прекратява и започваме нова итерация При `for` цикли директно отива на инкрементация -&&/slide +&] -&&slide +&[slide ## Assert -&&lineb3 +&.br3 Понякога е полезно да тестваме нашия код вътре в самия код. Тоест, искаме на конкретно място в кода да проверим нещо. @@ -394,4 +394,4 @@ assert(condition); Използва се повече като програмистки уред, тоест ако програмата спре заради `assert`, това е защото има някаква програмистка грешка. -&&/slide +&] diff --git a/src/teaching/upp-2023/week4/revision.md b/src/teaching/upp-2023/week4/revision.md index b5de82d..3650875 100644 --- a/src/teaching/upp-2023/week4/revision.md +++ b/src/teaching/upp-2023/week4/revision.md @@ -1,16 +1,16 @@ # Преговор - УПП, Седмица 4, 27.10.2023 -&&presentation +&.presentation -&&clide &&font35 &¢ered +&[title35 # Функции и алгоритмични задачи -&&/centered &&/font &&/clide +&] -&&slide &&font27 +&[slide27 ## От сега нататък ще направим няколко промени @@ -26,7 +26,7 @@ - Ще може да предавате задания след срока! Искам да решите колкото се може повече вкъщи. -&&/font &&/slide +&] @@ -34,7 +34,7 @@ -&&slide +&[slide ## 2s compliment @@ -56,11 +56,11 @@ 000 0 ``` -&&/slide +&] -&&clide +&[middle Това работи, обаче имаме един гигантски проблем: събирането не работи! От математика знаем, че "2 - 1 = 2 + (-1)", тоест би трябвало да можем да съберем побитово 2 и -1 и да получим 1. @@ -80,11 +80,11 @@ Да не говорим, че ние имаме -0, което не ни трябва много. -&&/clide +&] -&&clide +&[middle Нека да помислим пак, да вземем само положителните: @@ -103,11 +103,11 @@ Нека тогава "-1 = 111". -&&/clide +&] -&&slide +&[slide Правейки същото за "2 + -2", намираме че @@ -133,11 +133,11 @@ 100 не сме го използвали, обаче намерихме отрицателното число за всяко положително. Да видим как работим с него, побитово "100 + 001 = 101", тоест "x + 1 = -3", следователно x ще бъде -4. -&&/slide +&] -&&clide +&[middle Това е идеята на "complements", дефинираме отрицателни числа, така че да използваме едно и също събиране между положителни и отрицателни. @@ -159,7 +159,7 @@ 11111111111111111111111111111110 ``` -&&/clide +&] diff --git a/src/teaching/upp-2023/week6/index.md b/src/teaching/upp-2023/week6/index.md index 991f987..34c3f53 100644 --- a/src/teaching/upp-2023/week6/index.md +++ b/src/teaching/upp-2023/week6/index.md @@ -189,7 +189,7 @@ $ 1 1 |6 1 3 7 3 0 958|959| |17 5 9 8 6 1 8 3 9 5 9 9 2 7 8 0 91461 772000|863461| -&&question Какво прави последната програма? +&:question Какво прави последната програма? **Бонус:** направете програми за симулаторния компютър, които diff --git a/src/teaching/upp-2023/week7/index.md b/src/teaching/upp-2023/week7/index.md index 329581c..b216992 100644 --- a/src/teaching/upp-2023/week7/index.md +++ b/src/teaching/upp-2023/week7/index.md @@ -10,7 +10,7 @@ GitHub classroom: [classroom.github.com/a/m5M2_CWD](https://classroom.github.com Направете функция, която получава два двуизмерни координата, покомпонентно ги сумира и връща резултатните координати. Няма как функцията да върне две стойности, затова добаваете още два аргумента, които да са указатели към променливи в които да запазим сумираните координати. -&&warn **Трябва** да използвате референции вместо указатели! +&:warn **Трябва** да използвате референции вместо указатели! От входа получавате два координата, след това връщате тяхната покомпонентна сума **използвайки функцията**. @@ -31,7 +31,7 @@ GitHub classroom: [classroom.github.com/a/m5M2_CWD](https://classroom.github.com Ако буквата е `a`, `b` или `c`, тогава този продукт става "сегашния" продукт. Ако буквата е `S`, тогава намаляте бройката на сегашния продукт с 1, а ако е `R` - увеличаваме с 10. -&&warn **НЕ** може да използвате масиви! **Трябва** действията на `S` и `R` да се изкарат във функции! +&:warn **НЕ** може да използвате масиви! **Трябва** действията на `S` и `R` да се изкарат във функции! Когато получите `$`, изкарвате броя на всеки продукт и спирате програмата. @@ -46,7 +46,7 @@ GitHub classroom: [classroom.github.com/a/m5M2_CWD](https://classroom.github.com В началото получавате буква - тя съответства на дадена **функция**, след това получавате 5 числа с плаваща запетая. След всяко въведено трябва да изкарате резултата от съответната функция при подадено входното число. -&&warn **Трябва** да използвате указател към функция! +&:warn **Трябва** да използвате указател към функция! Буквите съответстват на следните функции: diff --git a/src/teaching/upp-2023/week8/index.md b/src/teaching/upp-2023/week8/index.md index f3ab415..561dc71 100644 --- a/src/teaching/upp-2023/week8/index.md +++ b/src/teaching/upp-2023/week8/index.md @@ -2,7 +2,7 @@ GitHub classroom: [classroom.github.com/a/Big7FRUG](https://classroom.github.com/a/Big7FRUG) -&&warn **Трябва** да използвате възможно най-малко памет във всички задачи! +&:warn **Трябва** да използвате възможно най-малко памет във всички задачи! ## Задача 1 @@ -77,7 +77,7 @@ GitHub classroom: [classroom.github.com/a/Big7FRUG](https://classroom.github.com Друг начин по който да го разберем, е че първото число е на първа позиция, второто число е на последната, третото число е на втора позиция, четвъртото е на предпоследна и так. нат. Обаче ние не знаем финалния размер на масива, затова се нуждаем от логиката с чертата. -&&important Моля не правете решенето със запазване на входа и разместване на елементите +&:important Моля не правете решенето със запазване на входа и разместване на елементите Напомням, че тази права само си я представяте. В началото масива е с размер 2. diff --git a/src/teaching/upp-2023/week9/index.md b/src/teaching/upp-2023/week9/index.md index 86e7cca..557b89a 100644 --- a/src/teaching/upp-2023/week9/index.md +++ b/src/teaching/upp-2023/week9/index.md @@ -2,7 +2,7 @@ GitHub classroom: [classroom.github.com/a/lGXxCRZO](https://classroom.github.com/a/lGXxCRZO) -&&warn Освен ако не е казано друго, може да зачитате, че максималната дължина на един низ е 1024 знака. +&:warn Освен ако не е казано друго, може да зачитате, че максималната дължина на един низ е 1024 знака. ## Задача 1 @@ -21,7 +21,7 @@ GitHub classroom: [classroom.github.com/a/lGXxCRZO](https://classroom.github.com Изкарайте на екрана втората половина от низа и след това директно долепена първата половина. Ако низа е с нечетна дължина, зачитаме средния елемент като част от втората половина. -&&important Трябва да използвате динамична памет +&:important Трябва да използвате динамична памет **Примери:** diff --git a/src/tutorials.md b/src/tutorials.md index a620a5c..bfd957d 100644 --- a/src/tutorials.md +++ b/src/tutorials.md @@ -4,54 +4,60 @@ Educational articles with the sole goal of explaining technologies, processes or <br> -&&gb 28 Jun   [Fix networked Brother printers not working in Linux](/tutorials/fix-network-brother-printers) +#### *2023* + +&.gb 16 Dec   [Fix "qc timeout" kernel log error](/tutorials/fix-qc-timeout) +: `Linux` | `kernel` | `libata` `qc` `logs` `DMA` + + +&.gb 28 Jun   [Fix networked Brother printers not working in Linux](/tutorials/fix-network-brother-printers) : `Linux` | `CUPS` | `Printers` `Brother` `Network` `avahi` -&&gb 14 Jun   [Fix "exec /gns3/init.sh: no such file or directory"](/tutorials/gns3-initsh-no-such-file) +&.gb 14 Jun   [Fix "exec /gns3/init.sh: no such file or directory"](/tutorials/gns3-initsh-no-such-file) : `Linux` | `GNS3` | `Docker` `busybox` -&&gb 26 Apr   [Install drivers for Epson scanners](/tutorials/install-drivers-for-epson-scanners) +&.gb 26 Apr   [Install drivers for Epson scanners](/tutorials/install-drivers-for-epson-scanners) : `Linux` | `SANE` | `Scanners` `Epson` `epkowa` `iscan` -&&gb 25 Apr   [Managing Android apps with ADB (and without root)](/tutorials/managing-apps-with-adb-without-root) +&.gb 25 Apr   [Managing Android apps with ADB (and without root)](/tutorials/managing-apps-with-adb-without-root) : `Android` | `ADB` | `Apps` `Linux` `Windows` -&&gb 01 Jan   [virt-manager freezing up when clicking Browse in any window](/tutorials/virt-manager-freeze-on-browse) +&.gb 01 Jan   [virt-manager freezing up when clicking Browse in any window](/tutorials/virt-manager-freeze-on-browse) : `Linux` | `virt-manager` | `QEMU/KVM` `libvirt` `Linux` `GTK` #### *2022* -&&gb 16 Sep   [How to encrypt email](/tutorials/how-to-encrypt-email) +&.gb 16 Sep   [How to encrypt email](/tutorials/how-to-encrypt-email) : `All` | `Email` | `PGP` `S/MIME` `Email Client` `Gmail` `Outlook` `Protonmail` -&&gb 30 Jul   [Fix "No frame buffer" error in <span class="no-wrap">Plan 9</span>](/tutorials/fix-no-frame-buffer-plan9) +&.gb 30 Jul   [Fix "No frame buffer" error in <span class="no-wrap">Plan 9</span>](/tutorials/fix-no-frame-buffer-plan9) : `Plan 9` | `Configuration` | `QEMU/KVM` `Linux` `monitor` -&&gb 30 Jul   [Install <span class="no-wrap">Plan 9</span> with virt-manager](/tutorials/install-plan9-with-virt-manager) +&.gb 30 Jul   [Install <span class="no-wrap">Plan 9</span> with virt-manager](/tutorials/install-plan9-with-virt-manager) : `Plan 9` | `Installation` | `Setup` `QEMU/KVM` `virt-manager` `Linux` #### *2021* -&&gb 01 Nov   [How to turn off notifications on Windows](/tutorials/turn-off-notifications-windows) +&.gb 01 Nov   [How to turn off notifications on Windows](/tutorials/turn-off-notifications-windows) : `Windows 10` | `Settings` | `Notifications` -&&gb 01 Nov   [How to disable Sticky Keys prompt](/tutorials/disable-sticky-keys-popup) +&.gb 01 Nov   [How to disable Sticky Keys prompt](/tutorials/disable-sticky-keys-popup) : `Windows` | `Settings` | `Sticky Keys` -&&gb 26 Oct   [How to remove Windows Weather Widget](/tutorials/remove-weather-widget) +&.gb 26 Oct   [How to remove Windows Weather Widget](/tutorials/remove-weather-widget) : `Windows 10` | `Settings` | `Taskbar` `Weather Widget` -&&gb 04 Oct   [Windows Run dialog](/tutorials/windows-run-dialog) +&.gb 04 Oct   [Windows Run dialog](/tutorials/windows-run-dialog) : `Windows` | `Commands` | `Run` `Settings` -&&gb 03 Oct   [How to export Skype data](/tutorials/export-skype) +&.gb 03 Oct   [How to export Skype data](/tutorials/export-skype) : `Skype` | `Export` | `Archive` `skype-parser` #### *2020* -&&gb 24 Jul   [How to use Jira](/tutorials/how-to-use-jira) +&.gb 24 Jul   [How to use Jira](/tutorials/how-to-use-jira) : `Project Management` | `Jira` | `Agile` `Issue tracking` `Bug tracking` `Kanban` `Atlassian` -&&gb 21 May   [Connect to Mysql in .NET and Entity Framework](/tutorials/connect-to-mysql-in-dotnet-ef) +&.gb 21 May   [Connect to Mysql in .NET and Entity Framework](/tutorials/connect-to-mysql-in-dotnet-ef) : `ASP.Net` | `MySQL` | `Entity Framework` `Pomelo` diff --git a/src/tutorials/fix-qc-timeout/index.md b/src/tutorials/fix-qc-timeout/index.md new file mode 100644 index 0000000..9b02a48 --- /dev/null +++ b/src/tutorials/fix-qc-timeout/index.md @@ -0,0 +1,60 @@ +# Fix "qc timeout" kernel log error + +Depending on your harddrive, you may get a 15 second delay on boot. +Looking at the kernel logs (with `dmesg`), you may find the following errors: + +``` +kernel: ata1.00: qc timeout after 15000 msecs (cmd 0x47) +kernel: ata1.00: Read log 0x00 page 0x00 failed, Emask 0x40 +kernel: ata1.00: NCQ Send/Recv Log not supported +kernel: ata1.00: Read log 0x00 page 0x00 failed, Emask 0x40 +kernel: ata1.00: ATA Identify Device Log not supported +``` + +## Solution + +Add a kernel parameter which tells Linux that the drive doesn't support DMA logs. +Meaning, add the following parameter: + +``` +libata.force=1.00:nodmalog +``` + +where `1.00` is the thing between "ata" and ":". + +So, if your logs were + +``` +kernel: ata3.01: qc timeout after 15000 msecs (cmd 0x47) +... +``` + +then the parameter would be: + +``` +libata.force=3.01:nodmalog +``` + +## Explanation + +&:important The following is how I understand the issue, but I did not find definitive proof thats exactly what happens. + Take this section with a grain of salt. + +A harddrive can support [dma transfers](https://en.wikipedia.org/wiki/Direct_memory_access), normally the CPU would handle data transfer from the harddrive to the system memory (RAM), meaning it asks for a bit of data, waits, when the data comes, puts it in memory, then asks for next bit and so on. +With DMA, the CPU could ask the drive for everythng it wants (not a tiny bit), and then the DMA controller (DMAC) on the drive will handle the actual data transfer from the drive to the memory (when the transfer is done, the drive will tell the CPU). +The benefit is that the CPU can do other work while the transfer is going on, greatly improving efficiency, but the downside is that the harddrive has to support it (have a DMAC chip on it). + +Normally it would be useful for the DMAC to keep logs in a special place on the drive. +This is where the issue comes from: your harddrive supports DMA but does not support logs for it. +However, the Linux kernel has no good way of knowing that, there is no "property" on the drive which tells us this. +The only way is to try and read from that log: if it succeeds, then there is support, if it fails, then there isn't. + +But what does it mean to fail? +The simplest definition would be for the drive to return an error singal, but in our case, the drive would just not return anything, ignoring our request. +In that case, how would we know if the drive just doesn't know how to respond (meaning it doesn't support the logs) or if it's just very slow? +Well, we can't, so we put a time limit, if it doesn't respond in 15 seconds, then it probably doesn't support it. + +That's what the error is saying: `qc` is short for ["queued command"](https://docs.kernel.org/driver-api/libata.html#origins-of-commands), it's used to represent a (S)ATA command (hence the `cmd` at the end, telling us which command it's referring to). +So, the kernel is telling us "The hard drive (ATA) command to read (DMA) logs timed out after 15 seconds" (it first says a command timed out, then it says which one). + +By adding that kernel parameter, we're telling Linux that the drive doesn't support DMA logs, therefore the kernel doesn't need to do this "wait 15 seconds for response if support exists" routine. diff --git a/src/tutorials/index.md b/src/tutorials/index.md index a620a5c..bfd957d 100644 --- a/src/tutorials/index.md +++ b/src/tutorials/index.md @@ -4,54 +4,60 @@ Educational articles with the sole goal of explaining technologies, processes or <br> -&&gb 28 Jun   [Fix networked Brother printers not working in Linux](/tutorials/fix-network-brother-printers) +#### *2023* + +&.gb 16 Dec   [Fix "qc timeout" kernel log error](/tutorials/fix-qc-timeout) +: `Linux` | `kernel` | `libata` `qc` `logs` `DMA` + + +&.gb 28 Jun   [Fix networked Brother printers not working in Linux](/tutorials/fix-network-brother-printers) : `Linux` | `CUPS` | `Printers` `Brother` `Network` `avahi` -&&gb 14 Jun   [Fix "exec /gns3/init.sh: no such file or directory"](/tutorials/gns3-initsh-no-such-file) +&.gb 14 Jun   [Fix "exec /gns3/init.sh: no such file or directory"](/tutorials/gns3-initsh-no-such-file) : `Linux` | `GNS3` | `Docker` `busybox` -&&gb 26 Apr   [Install drivers for Epson scanners](/tutorials/install-drivers-for-epson-scanners) +&.gb 26 Apr   [Install drivers for Epson scanners](/tutorials/install-drivers-for-epson-scanners) : `Linux` | `SANE` | `Scanners` `Epson` `epkowa` `iscan` -&&gb 25 Apr   [Managing Android apps with ADB (and without root)](/tutorials/managing-apps-with-adb-without-root) +&.gb 25 Apr   [Managing Android apps with ADB (and without root)](/tutorials/managing-apps-with-adb-without-root) : `Android` | `ADB` | `Apps` `Linux` `Windows` -&&gb 01 Jan   [virt-manager freezing up when clicking Browse in any window](/tutorials/virt-manager-freeze-on-browse) +&.gb 01 Jan   [virt-manager freezing up when clicking Browse in any window](/tutorials/virt-manager-freeze-on-browse) : `Linux` | `virt-manager` | `QEMU/KVM` `libvirt` `Linux` `GTK` #### *2022* -&&gb 16 Sep   [How to encrypt email](/tutorials/how-to-encrypt-email) +&.gb 16 Sep   [How to encrypt email](/tutorials/how-to-encrypt-email) : `All` | `Email` | `PGP` `S/MIME` `Email Client` `Gmail` `Outlook` `Protonmail` -&&gb 30 Jul   [Fix "No frame buffer" error in <span class="no-wrap">Plan 9</span>](/tutorials/fix-no-frame-buffer-plan9) +&.gb 30 Jul   [Fix "No frame buffer" error in <span class="no-wrap">Plan 9</span>](/tutorials/fix-no-frame-buffer-plan9) : `Plan 9` | `Configuration` | `QEMU/KVM` `Linux` `monitor` -&&gb 30 Jul   [Install <span class="no-wrap">Plan 9</span> with virt-manager](/tutorials/install-plan9-with-virt-manager) +&.gb 30 Jul   [Install <span class="no-wrap">Plan 9</span> with virt-manager](/tutorials/install-plan9-with-virt-manager) : `Plan 9` | `Installation` | `Setup` `QEMU/KVM` `virt-manager` `Linux` #### *2021* -&&gb 01 Nov   [How to turn off notifications on Windows](/tutorials/turn-off-notifications-windows) +&.gb 01 Nov   [How to turn off notifications on Windows](/tutorials/turn-off-notifications-windows) : `Windows 10` | `Settings` | `Notifications` -&&gb 01 Nov   [How to disable Sticky Keys prompt](/tutorials/disable-sticky-keys-popup) +&.gb 01 Nov   [How to disable Sticky Keys prompt](/tutorials/disable-sticky-keys-popup) : `Windows` | `Settings` | `Sticky Keys` -&&gb 26 Oct   [How to remove Windows Weather Widget](/tutorials/remove-weather-widget) +&.gb 26 Oct   [How to remove Windows Weather Widget](/tutorials/remove-weather-widget) : `Windows 10` | `Settings` | `Taskbar` `Weather Widget` -&&gb 04 Oct   [Windows Run dialog](/tutorials/windows-run-dialog) +&.gb 04 Oct   [Windows Run dialog](/tutorials/windows-run-dialog) : `Windows` | `Commands` | `Run` `Settings` -&&gb 03 Oct   [How to export Skype data](/tutorials/export-skype) +&.gb 03 Oct   [How to export Skype data](/tutorials/export-skype) : `Skype` | `Export` | `Archive` `skype-parser` #### *2020* -&&gb 24 Jul   [How to use Jira](/tutorials/how-to-use-jira) +&.gb 24 Jul   [How to use Jira](/tutorials/how-to-use-jira) : `Project Management` | `Jira` | `Agile` `Issue tracking` `Bug tracking` `Kanban` `Atlassian` -&&gb 21 May   [Connect to Mysql in .NET and Entity Framework](/tutorials/connect-to-mysql-in-dotnet-ef) +&.gb 21 May   [Connect to Mysql in .NET and Entity Framework](/tutorials/connect-to-mysql-in-dotnet-ef) : `ASP.Net` | `MySQL` | `Entity Framework` `Pomelo` |