diff --git a/assets/recursion.jpg b/assets/recursion.jpg new file mode 100644 index 0000000..8611549 Binary files /dev/null and b/assets/recursion.jpg differ diff --git a/nested-for-loops-demo/style.css b/nested-for-loops-demo/style.css index 3c0c243..f6767d5 100644 --- a/nested-for-loops-demo/style.css +++ b/nested-for-loops-demo/style.css @@ -183,26 +183,45 @@ button:active { /* The page-specific styling */ /* TODO: Put whatever styles you need for just your demo here */ -/*# sourceMappingURL=style.css.map */ - .big-code { - font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; - font-size: 1.25em; - color: #153570; + font-family: "Anonymous Pro", monospace; + font-size: 14px; + color: #153570 } .big-code .comment { - color: #2F2D2C; + color: #2f2d2c; } -.big-code .values { - color: #FF8900; +.instructions { + margin-bottom: 0; + border-bottom: none; +} + +#p-code-1 { + color: white; + background-color: #1e1e1e; +} + +#p-code-2 { + color: white; + background-color: #1e1e1e; +} + +#p-code-3 { + color: white; + background-color: #1e1e1e; +} + +.big-code .special { + color: #153570; } .big-code .identifier { - color: #38BFE7; + color: #38bfe7; } -.img-bot { - width: 100px -} \ No newline at end of file +.big-code .values { + color: #ff8900; +} +/*# sourceMappingURL=style.css.map */ \ No newline at end of file diff --git a/recursion-demo/README.md b/recursion-demo/README.md new file mode 100644 index 0000000..ae5f377 --- /dev/null +++ b/recursion-demo/README.md @@ -0,0 +1,125 @@ +# interactive-tutorials Template Files + +This folder is made to show what the start of an interactive tutorial might look like. +Remember, however, that a lot of creating a tutorial is creative freedom. +Thus, don't take these as hard fast rules but rather guidelines. +We want to show a uniform look in all the tutorials and so that's why this template exists. +With this said, this document will walk you through how to create your own interactive tutorial. + +### Jumping In + +First, we need to get the back-bone of the tutorial page. +There is an `index.html` file inside the `template` directory, this is an example of a minimal demo. +In fact, this demo isn't even functional. +With no editor, input, or real result, you'll have to add all those yourself. +To do this we need a `script.js` and some understanding of how each of the common assets work. + +Let's start! +Copy the `template` folder to a new folder in the same root `interactive-demos` directory. +For our purposes, we'll call this the `test-demo`. +Then open the `index.html` file. +Inside you'll find HTML comments with the prefix `TODO:`, these point to places that need replaced. +For example, the header below the `` comment should be replaced with the name of your demo. +Inside the `"content"` div there is already a few sections. +Open the page up to see what this layout produces and read the contents of each section. + +### The First Common + +There's already styling on the page, but how exactly does it work? +There's a `style.css` file, but this isn't our css file. +Another file, `style.scss`, is what we use to modify the styling on the page. +If you don't already know SASS, quickly read up on it [here][0]. +Then, install it using the instructions [here][1]. +(The best method is just using `npm install -g sass`.) + +Notice the top of the `style.scss` file, `@import "../assets/common.scss";`. +This takes the common SASS file and using its styling and then overwrites them with whatever your styles are. +The `..` is there because the assets directory is one level up from where the demos are. +If you use any other assets such as CodeJar, line numbers, or the options files, don't forget this `..` before the path. + +### Proper Local Development + +So far, we've been viewing the file as the `index.html` file, and sometimes this is fine. +However, for the best results, we should use a local webserver. +To do this we will use `serve` on npm. +Install it using `npm install -g serve`. +Then run it using `serve` inside the `interactive-demos` directory. +It's recommended to do this in a new terminal window. +It should then start hosting a static webserver at `localhost:5000`. +When making changes to any files be sure to also reload your web view. +To stop it, press `Ctrl + C`. + +### Code Editor + +The code editor that the demos use is called CodeJar. +First, we must add the assets to the html file. +Add these three script tags to the bottom of the body in the `index.html` file. + +```html + + + +``` + +The first asset, CodeJar, is the actual code editor. +We'll add the editor in a moment. +Next, `linenumbers.js` is an extension to the CodeJar library. +Finally, Prism is a code highlighting library. +We also need to add a CSS file to the head for this one to work. +The link tag should be as follows: + +```html + +``` + +Take note that there is a `../assets/` preceeding each filename. +This is very important for the way the file URL's work. + +Let's add an editor to the HTML page now. +To whichever section you want to make the editor section, add the class `editor-section`. +Then place another div inside of this section with the class `editor`. +Best practice is also to give the editor div an ID so that it identifiable from the script. +For the code highlighting to work, also add a language class to the editor. +This should be something like `"lang-html"` or `"lang-js"`. +The final result should look something like this: + +```html +
+
+
+``` + +We now add this editor as a CodeJar in the script. +First, create a `script.js` file and add it to the end of the body, after the other three script tags. +In this file, we'll create a CodeJar and test the methods of manipulating it. +First, get the div element with the class `"editor"`, in this case it has an id of `"editor"` as well. +Then pass this into the `Codejar` class constructor. +For the basic highlighting use `Prism.highlightElement`; for line numbers wrap this in the `withLineNumbers` function. +The last argument is for the options of the editor. +A final Codejar with line numbers and prism highlighting would look something like this. + +```js +let editorElement = document.getElementById("editor"); +let jar = CodeJar(editorElement, withLineNumbers(Prism.highlightElement, { + color: '#000', + backgroundColor: 'rgb(232, 232, 232)' +}), { + tab: ' ', + indentOn: /[\[({]$/ +}); +``` + +The last options are the tab size/character, and when to auto-indent. +For JavaScript this can be kept to default, however, for HTML it should be changed to something like `/<[a-zA-Z =\"\-]+>$/`. + +There are three methods that are used on this code jar: `updateCode`, `toString`, and `onUpdate`. +First, `updateCode` takes in a string and sets the code in the editor. +The method `toString` returns a string containing the code in the editor. +Finally, `onUpdate` takes a function as the only parameter, which is called any time the code in the editor changes. + +Examples of these functions being used include: an execute button that calls `toString` and passes it into the source of an iframe, auto saving 3 seconds after the last code update, and creating an animated code/result display. +All three of these examples are in the `div-demo/script.js` file. + + +[0]: https://sass-lang.com/guide +[1]: https://sass-lang.com/install diff --git a/recursion-demo/index.html b/recursion-demo/index.html new file mode 100644 index 0000000..ffa7f03 --- /dev/null +++ b/recursion-demo/index.html @@ -0,0 +1,141 @@ + + + + + Recursion Demo | Bit by Bit + + + + + + + + + +
+ +
+

Introduction

+

+ The process of a function calling itself is called recursion, and this function is called a recursive function. By using recursion, we can solve certain type of tasks easily. +

+

+ You may ask, if a function calls itself, it will lead to calling itself again, and again, and again... when would it stop? This is why it is always important to add a stop condition for recursive functions, + which is called the base case of the recursion. +

+
+
+
+

Example

+

+ Let's investigate an interesting topic! How do bit by bots "reproduce"? Well, a newly created bit by bot need to learn how to create new bit by bots for a month; + after that, the bit by bot will create a new bit by bot every month. If we start with one single newly created bit by bot, as shown in the picture below, + it takes the bit by bot one month to learn how to create a new bit by bot and it will be creating one new bit by bot every month. + Remember, each newly created bit by bot only starts to create new bit by bots after it has spent one month learning the way to do so. +

+

+ In this picture, each row represents the total number of bit by bot of the corresponding month. For each month, each bit by bot that knows how to build bit by bots will + still be in the group in the next month (represented by the black branches) and will make a new bit by bot (represented by the red branches). +

+ +
+
+

Analysis of example

+

+ The number of bit by bots for each month actually follows a pattern. 1, 1, 2, 3, 5, 8, ... Starting from the third term, each term is the sum of the previous two terms. + This is a famous sequence called the Fibonacci sequence. Now, let's write a function that will give us the total number of bit by bots produced in such fashion + for any given month. +

+

+ The function should take a single input, namely the month, and output the total number of bit by bots for that month. (You can pause here briefly and try to write + a function that will work as described without using recursion. ) The code below is the recursive function that completes the task: +

+ + function fibonacci(month) {
+   // Here the two ifs are the base case for the recursion, as
+   you can see they are not calling the function itself anymore

+   if (n == 0)
+     return 0;
+   if (n == 1 || n == 2)
+     return 1;
+   // This is where recursion occurs, the function is calling itself.
+   It says the output should be the sum of previous two months

+   else
+     return fibonacci(month - 1) + fibonacci(month - 2);
+ }
+

+ One important thing worth noting is how the function is evaluated. The only three cases where the function does not call itself repeatedly are month 0, 1, and 2. + These are our base cases and we set them to 0, 1, and 1 correspondingly. For any larger input, the function will need to call itself. +

+

+ For instance, if our input is 5, + fibonacci(5) will call fibonacci(4) and fibonacci(3); both of fibonacci(4) and fibonacci(3) are not fully evaluated yet, and they go on to call fibonacci(3) and + fibonacci(2), and fibonacci(2) and fibonacci(1). As stated before, fibonacci(2) and fibonacci(1) are just defined numbers, thus fibonacci(3) is determined, and is used to determine + the value of fibonacci(4); with both fibonacci(3) and fibonacci(4) completely evaluated, the value of fibonacci(5) is returned. +

+
+
+
+

Quick exercise

+
+
+

+ See if you can figure out the console output of the following code, where input n is a positive number.
+

+ + function exercise(n) {
+   if (n == 1)
+     return 1;
+   else
+     return n + exercise(n - 1) + n;
+ }
+ console.log(exercise(5));
+
+
+
+ your answer = +
+
+ +
+ +
+
+
+ +
+ + diff --git a/recursion-demo/style.css b/recursion-demo/style.css new file mode 100644 index 0000000..9a7d090 --- /dev/null +++ b/recursion-demo/style.css @@ -0,0 +1,350 @@ +/* style.scss */ +/* Import the common styling */ +/* common.scss */ +/* Define all the colors */ +body { + margin: 5em 0 0 0; + padding: 0; + background-color: #fff; + font-family: "Nunito", sans-serif; + font-weight: 600; +} + +button { + border: none; + background: #38bfe7; + padding: 0.5em 1em; + -webkit-box-shadow: 0.125em 0.125em 0.2em #bfbfbf; + box-shadow: 0.125em 0.125em 0.2em #bfbfbf; + cursor: pointer; +} + +button:hover { + background-color: #19a8d3; +} + +button:active { + -webkit-box-shadow: none; + box-shadow: none; +} + +#header { + padding: 1em 2em; + background-color: white; + color: #000; + position: fixed; + top: 0; + left: 0; + width: 100%; + max-height: 3em; + z-index: 1000; + opacity: 95%; + -webkit-box-shadow: 0 2px 2px #eee; + box-shadow: 0 2px 2px #eee; +} + +#header > * { + margin: 0; +} + +#header button { + width: 3em; +} + +#back-button { + padding: 0.25em 1em; + font-size: 1em; + height: 48px; +} + +.content { + padding: 1em; + max-width: 80%; + margin: 0 auto; +} + +/*Flexbox*/ +.flex-container-header { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} + +.flex-container-left { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: space-evenly; + -ms-flex-pack: space-evenly; + justify-content: space-evenly; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + max-width: -webkit-max-content; + max-width: -moz-max-content; + max-width: max-content; +} + +.flex-item-header { + -webkit-box-flex: 1; + -ms-flex: 1 1 200px; + flex: 1 1 200px; +} + +.flex-item-left { + -webkit-box-flex: 1; + -ms-flex: 1 1 100px; + flex: 1 1 100px; + max-width: -webkit-max-content; + max-width: -moz-max-content; + max-width: max-content; +} + +#top-heading { + width: -webkit-max-content; + width: -moz-max-content; + width: max-content; +} + +#bxb-logo { + max-height: 3em; + display: block; + text-align: left; + margin-left: calc(100% - 200px); +} + +.section { + margin: 1em 0; + padding: 0.5em; + border: 0.2em solid #38bfe7; + background-color: #fff; + color: #000; +} + +.flex-box { + display: -webkit-box; + display: -ms-flexbox; + display: flex; +} + +.flex-col { + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; + padding: 0.5em; +} + +.flex-col:not(:last-child) { + margin: 0 0.2em 0 0; +} + +.flex-col:last-child { + margin: 0 0 0 0.2em; +} + +.no-flex-col { + -webkit-box-flex: 0; + -ms-flex: 0; + flex: 0; +} + +.showcase-section { + padding: 0; +} + +.editor-section { + position: relative; + overflow: scroll; + padding: 0; +} + +.editor { + margin: 0; + height: 20em; + width: calc(100% - 35px - calc(0.625em * 2)); + font-family: "Anonymous Pro", monospace; + font-size: 0.875em; + line-height: 1.25em; + padding: 1px 0.625em; +} + +.editor-button-overlay { + position: absolute; + bottom: 1em; + right: 1em; + padding: 0; +} + +@font-face { + font-family: "NunitoBold"; + src: url("https://fonts.googleapis.com/css2?family=Nunito:wght@1000&display=swap"); +} + +.code { + display: inline-block; + color: #000; + font-size: 18px; + font-weight: 600; + font-family: "Anonymous Pro", monospace; +} + +.code-gray { + display: inline-block; + color: #2f2d2c; +} + +.code-orange { + display: inline-block; + color: #ff8900; +} + +.code-light-blue { + display: inline-block; + color: #38bfe7; +} + +.code-dark-blue { + display: inline-block; + color: #153570; +} + +/* Footer */ +footer { + background: #153570; + color: #fff; + width: 100vw; + padding: 0.5vh 2vw; + bottom: 0; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + -ms-flex-pack: distribute; + justify-content: space-around; +} + +footer a { + color: #fff; +} + +footer h4 { + text-align: center; + font-family: "NunitoBold", sans-serif; +} + +footer .footer-home { + width: 315px; +} + +footer .footer-home h4 { + text-align: left; +} + +footer .footer-socials { + -ms-flex-item-align: center; + -ms-grid-row-align: center; + align-self: center; +} + +footer .footer-socials h4 { + text-align: center; +} + +footer .footer-socials .socials { + list-style: none; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + padding: 0; + margin: 1rem 0 3rem 0; +} + +footer .footer-socials .socials li { + display: inline-block; + width: 1.5em; + height: 1.5em; + margin: 0 5px; + text-align: center; + line-height: 1.5em; + font-size: 1.8em; + border-radius: 50%; + background-color: #fff; +} + +footer .footer-socials .socials li a { + color: #153570; +} + +footer .footer-socials .socials li:hover { + background-color: #153570; +} + +footer .footer-socials .socials li:hover a { + color: #fff; +} + +footer .footer-info { + text-align: right; + line-height: 0.8em; + padding: 1em; +} + +/* The page-specific styling */ +/* TODO: Put whatever styles you need for just your demo here */ +.big-code { + font-family: "Anonymous Pro", monospace; + font-size: 14px; + color: #153570 +} + +.big-code .comment { + color: #2f2d2c; +} + +.instructions { + margin-bottom: 0; + border-bottom: none; +} + +#p-code-1 { + color: white; + background-color: #1e1e1e; +} + +#p-code-2 { + color: white; + background-color: #1e1e1e; +} + +#p-code-3 { + color: white; + background-color: #1e1e1e; +} + +.big-code .special { + color: #153570; +} + +.big-code .identifier { + color: #38bfe7; +} + +.big-code .values { + color: #ff8900; +} +/*# sourceMappingURL=style.css.map */ \ No newline at end of file diff --git a/recursion-demo/style.scss b/recursion-demo/style.scss new file mode 100644 index 0000000..29314c9 --- /dev/null +++ b/recursion-demo/style.scss @@ -0,0 +1,7 @@ +/* style.scss */ + +/* Import the common styling */ +@import "../assets/common.scss"; + +/* The page-specific styling */ +/* TODO: Put whatever styles you need for just your demo here */