├── .gitattributes ├── .gitignore ├── README.md ├── change-description-example-diff-style.png ├── change-description-example.png └── executable-tutorials.org /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | See [executable-tutorials](executable-tutorials.org) 2 | -------------------------------------------------------------------------------- /change-description-example-diff-style.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dharmatech/executable-tutorials/13e1db3edf4f6eca04165e6200bc9ed0b9905a9e/change-description-example-diff-style.png -------------------------------------------------------------------------------- /change-description-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dharmatech/executable-tutorials/13e1db3edf4f6eca04165e6200bc9ed0b9905a9e/change-description-example.png -------------------------------------------------------------------------------- /executable-tutorials.org: -------------------------------------------------------------------------------- 1 | 2 | * The issue with writing long complex tutorials 3 | 4 | When building a large and complex software project, you'd like to be able to make a change to the code base and be sure that the software still works as intended. Nowadays, folks use automated tests to check that things work after code changes. 5 | 6 | Let's say you're working on a long and complex tutorial for building some kind of software application. At some point, you decide to change something in the middle of the tutorial. Now, how do you know that your tutorial still works? Experienced tutorial writers know that one option is to occasionally go through the entire tutorial again to make sure that the steps still lead to the expected resultant project. Another option is to rely on readers of the tutorial to report issues after any changes are made. 7 | 8 | Or, you can make your tutorial executable and unit tested. 9 | 10 | * Executable tutorial 11 | 12 | The idea with an executable tutorial is that the steps that the user is expected to take are in a machine readable format. Then, the whole tutorial can be executed at any point to make sure that the steps still lead to the expected project. 13 | 14 | * Unit tested tutorial 15 | 16 | You can include steps in your tutorial to unit test your project. Then if your project tests pass, you can consider your tutorial to also be in a passing state. By having your generated project be unit tested, your tutorial is also tested. 17 | 18 | * Course writers 19 | 20 | Authors of courses on sites like Udemy or Pluralsight could benefit from first writing their course as an executable tutorial. They can then use the tutorial as their script when recording videos, confident that the instructions lead to a working project (without having to go through the steps manually, again and again). 21 | 22 | * Example 1 - Saturn project (F#) 23 | 24 | [[https://saturnframework.org/][Saturn]] is an MVC web framework for F#. 25 | 26 | [[https://github.com/dharmatech/MvcMovieSaturnTutorial/blob/main/MvcMovieSaturnTutorial.md][MvcMovieSaturnTutorial]] is a tutorial for building a simple web app in Saturn. That markdown file is generated from [[https://github.com/dharmatech/MvcMovieSaturnTutorial/blob/main/MvcMovieSaturn-unit-tested-tutorial.ps1][this source file]] which is written in PowerShell. [[https://github.com/dharmatech/MvcMovieSaturnTutorial/blob/main/convert-to-markdown.ps1][This script]] is used to convert the source file to markdown. 27 | 28 | ** English-language change descriptions 29 | 30 | Programming tutorials contain instructions to the reader regarding what file to change and what to change about it. 31 | 32 | Here's a screenshot from the MvcMovieSaturnTutorial which shows an example of how file changes are described: 33 | 34 | [[file:change-description-example.png]] 35 | 36 | Here's the part of the source document from which that is generated: 37 | 38 | #+begin_src PowerShell 39 | $file = '.\src\MvcMovieSaturn\Movies\MoviesModel.fs' 40 | 41 | $original_text = @" 42 | let validators = [ 43 | fun u -> if isNull u.Id then Some ("Id", "Id shouldn't be empty") else None 44 | ] 45 | "@ 46 | 47 | $replacement_text = @" 48 | let validators = [] 49 | "@ 50 | 51 | Edit $file -Replacing $original_text -With $replacement_text 52 | #+end_src 53 | 54 | As you can see there, the filename to be edited is stored in the variable =$file=. The text that is to be replaced is stored in =$original_text=. Finally, the new text goes in =$replacement_text=. Then the =Edit= function is called: 55 | 56 | #+begin_src PowerShell 57 | Edit $file -Replacing $original_text -With $replacement_text 58 | #+end_src 59 | 60 | * Example 2 - ASP.NET Core project 61 | 62 | The next example is a tutorial for building a very simple link aggregator application in ASP.NET core. 63 | 64 | - [[https://github.com/dharmatech/LinkAggregatorTutorial/blob/main/LinkAggregatorTutorial.md][Markdown]] 65 | - [[https://github.com/dharmatech/LinkAggregatorTutorial/blob/main/LinkAggregatorTutorial.ps1][Source]] (PowerShell) 66 | - [[https://github.com/dharmatech/LinkAggregatorTutorial/blob/main/ConvertToMarkdown.ps1][Script]] to convert from PowerShell to markdown 67 | 68 | ** diff-style change descriptions 69 | 70 | In this tutorial, I took a different approach to the change descriptions. I simply included the output of =git diff=: 71 | 72 | [[file:change-description-example-diff-style.png]] 73 | 74 | I think the english-language change descriptions from example 1 are visually nicer. However, the diff-style ones are obviously much easier to create. With the former, I had to manually create each change description. With the latter, all I need to do is =git diff=, and include that in the tutorial source. 75 | 76 | Something to consider is having a way to automatically convert from =git diff= output to the friendlier style. 77 | 78 | ** Automated screenshots 79 | 80 | Many tutorials often contain screenshots. Some issues with these: 81 | 82 | - Generating these can be labor intensive 83 | - If you update the tutorial, the screenshots have to be updated 84 | - Tutorial writers often let the screenshots fall out of sync with the tutorial. 85 | 86 | The LinkAggregator tutorial contains a screenshot at the beginning. This screenshot is generated when the source file is run. 87 | 88 | *** Using Canopy for screenshots 89 | 90 | [[https://lefthandedgoat.github.io/canopy/][Canopy]], an F# web testing framework, is used to write the tests for LinkAggregator. In these tests I have a step to take a screenshot: 91 | 92 | #+begin_src fsharp 93 | "take screenshot" &&& fun _ -> 94 | 95 | resize (850, 450) 96 | 97 | screenshot "." "screenshot-links" |> ignore 98 | #+end_src 99 | 100 | This solves the issue of screenshots being out of date. Each time I run the tutorial source file to test it, fresh screenshots are generated. 101 | 102 | * Future areas to explore 103 | 104 | ** Cross-platform executable tutorials 105 | 106 | The two examples discussed have only been tested on Windows. 107 | 108 | PowerShell works on Windows, Linux, and macOS. So conceivably, it could be used to write tutorials which work on all three platforms. 109 | 110 | ** Source file in other lanuages 111 | 112 | The source files in two examples discussed are written in PowerShell. 113 | 114 | Other scripting languages comparable to PowerShell could conceivably be used to author source files. 115 | 116 | ** DSL for tutorial source files 117 | 118 | PowerShell was quite a comfortable language for writing the tutorial source files. 119 | 120 | That said, it maybe worth exploring a DSL designed for authoring source files. Perhaps Racket or Haskell could be used for such a DSL. 121 | 122 | ** Alternate presentation of file change descriptions 123 | 124 | In some programming books, file changes that the user is expected to make are sometimes indicated by displaying the entire file, but bolding lines that the user should edit. Offering this style of change description to the user would be nice. It may also be nice to have it be up to the user what style to see; i.e. show diff-style by default, but allow the user to switch to the whole-file view on demand. 125 | 126 | ** Targets besides markdown 127 | 128 | It would be nice to target a document format that is richer than standard github rendered markdown. An automatically generated table of contents would be nice, for example. 129 | 130 | * Feedback 131 | 132 | If you write an executable tutorial and would like to share your work, feel free to post a link to your work in the [[https://github.com/dharmatech/executable-tutorials/discussions][discussions]]. 133 | 134 | If you know of any tutorials written in such a style, also feel free to post these in the discussions. 135 | --------------------------------------------------------------------------------