The explanation below will make more sense if you open this file in emacs. That way you will see the headers of each block.
- Presentation
- How to use
- Why use org-mode for teaching programming?
- Demo
- Github
- header-args
- C specific
- C++ specific
- SQL specific
- Python specific
- Advanced org-features
- Some potential issues you might encounter
- Final words
- Conclusion
This is a 20 minute presentation on why and how I use emacs and org-mode to teach programming
- This repo is self-contained. It tries to be as easy to use as possible.
- If you want to try it, save/rename your .emacs.d configuration files
and use this repo instead
- it will install the required dependencies
- I have used emacs 27.2 (it might run with earlier versions)
- Then run emacs and open this file (readme.org) or create your own
Then you can decide how to integrate it to your workflow by:
- Run it as is
- I recommend you use chemacs to switch between your own configuration and this one
- when teaching, run one instance of emacs specifically configured for this purpose
or
- Cut-and-paste from prog_teaching_org.org to your own configuration files
Perhaps this code can one day become a module.
- Source and text in one place
- More important: easy to sync source code and its output
- It is a live format:
- Run the code and see its output from the presentation
- Very easy to do on-the-fly demonstrations
- Great typesetting of source code
- keyword highlighting for widely used programming languages
- Github is a great publishing/collaboration platform
- simple, automatic publishing
- do you need a PDF? print the Github page.
- worst case, give the students org-files, they will figure it out
- and you have the full power of emacs!!
- configure it to your own taste
- use yasnippets and macros
- It is not powerpoint
- no animations
- not trivial to annotate with a stylus (but possible, using Xournal)
- not suitable for very large code examples
- I create one long org file per lecture
- I used headers to break “slides”
- I scroll through it, like movie credits
- Students do not mind
- They like that examples are complete and runnable
- I have successfully used it to teach:
- C++
- SQL
- SML
- Ruby
- Racket
Some simple programming examples:
You can combine text with programming snippet. Once executed, its output is automatically inserted.
#include <stdio.h>
int main(void) {
int i;
for (i = 0;i<3;i++) {
printf("i : %d %d\n", i, 1<<i);
}
return 0;
}
i : 0 1 i : 1 2 i : 2 4
create table R(a, b);
insert into R values (1, "this"), (2, "is"), (3, "an"), (4, "example");y
select * from R;
a | b |
---|---|
1 | this |
2 | is |
3 | an |
4 | example |
l = range (0,3)
list(map(print, map(lambda i: (i,2**i), l)))
(0, 1) (1, 2) (2, 4)
l = Array.new(3) {|i| [i,2**i]}
l.map { |p| print(p, "\n")}
[0, 1] [1, 2] [2, 4]
R can output text or graphics.
attach(mtcars)
summary(mtcars)
mpg cyl disp hp drat wt qsec vs am gear carb Min. :10 Min. :4.0 Min. : 71 Min. : 52 Min. :2.8 Min. :1.5 Min. :14.5 Min. :0.00 Min. :0.00 Min. :3.0 Min. :1.0 1st Qu.:15 1st Qu.:4.0 1st Qu.:121 1st Qu.: 96 1st Qu.:3.1 1st Qu.:2.6 1st Qu.:16.9 1st Qu.:0.00 1st Qu.:0.00 1st Qu.:3.0 1st Qu.:2.0 Median :19 Median :6.0 Median :196 Median :123 Median :3.7 Median :3.3 Median :17.7 Median :0.00 Median :0.00 Median :4.0 Median :2.0 Mean :20 Mean :6.2 Mean :231 Mean :147 Mean :3.6 Mean :3.2 Mean :17.8 Mean :0.44 Mean :0.41 Mean :3.7 Mean :2.8 3rd Qu.:23 3rd Qu.:8.0 3rd Qu.:326 3rd Qu.:180 3rd Qu.:3.9 3rd Qu.:3.6 3rd Qu.:18.9 3rd Qu.:1.00 3rd Qu.:1.00 3rd Qu.:4.0 3rd Qu.:4.0 Max. :34 Max. :8.0 Max. :472 Max. :335 Max. :4.9 Max. :5.4 Max. :22.9 Max. :1.00 Max. :1.00 Max. :5.0 Max. :8.0
It will automatically insert them.
- Make sure to run org-toggle-inline-images
library(lattice)
xyplot(1:10 ~ 1:10)
Github is a great resource:
- simple publishing: no need to export
- readme.org will be rendered as the main entry point of a repo if no readme.md found
- it does a great job rendering source code blocks
- github will display the file with different colors and typesetting than in emacs
- but it will nicely typeset the file nonetheless
- It is not perfect
- by default it does not show #+RESULTS (more on this later)
- it does not support all org-mode features
- git, obvious ;)
- easy to collaborate with co-authors
- you can get pull requests
- navigation links
- cut-and-paste for code blocks
- edit in place
- automatic scrollbars for long blocks and results
- github only shows the results of a code block if :exports both
- but it does not respect header-args
- instead, you have to manually add it to each block
This block does not export its output, and github does not display it
#include <stdio.h>
int main(void) {
printf("hello world\n");
}
This one is properly displayed:
#include <stdio.h>
int main(void) {
printf("hello world\n");
}
hello world
Using header-args will reduce the amount of information you have to include in every block header (see top of this file)
Use :results output
#+PROPERTY: header-args :results output
- this guarantees that the result of any block is its output to stdout
- The org default is :results value, which keeps the result of the last expression (language dependent).
(+ 10 1)
11
Changing it to :results output keeps standard output:
(print "this is a test")
"this is a test"
#+PROPERTY: header-args:C :main no :flags -std=c99 -Wall --pedantic -Werror
- :main no do not wrap block in a main function (i.e. block must be complete program)
- :flags … provide the following “flags” to the compiler: -std=c99 -Wall –pedantic -Werror
Example:
#include <stdio.h>
int main(void) {
printf("hello world\n");
}
hello world
- Warnings and errors are displayed during compilation
- but line numbers do not match, due to code that is inserted by org
int f(void) {
return ; // this would create a warning
}
int main(void) {
f();
}
- A nice thing is that org can automatically insert a main function:
- and you can specify which #includes to add
int a = 0;
int b = 3;
printf("The result is %d\n", a + b);
The result is 3
Very similar to C.
But… PROPERTY is called C+++ (due to how org parses it)
#+PROPERTY: header-args:C+++ :main no :flags -std=c++17 -Wall --pedantic -Werror
You can also have a main automatically inserted, but you might need to indicate which headers to include
int a = 100;
int b = 'a';
if (a == b)
std::cout << "They are equal\n";
else
std::cout << "They are not\n";
They are not
- important:
- use :results table (results are rendered as tables)
- use :colnames yes (display the name of the attributes of the relation)
- You can use any of the major backends (postgresql, oracle, mysql, sqlite3…)
- Each backend has different PROPERTY parameters
- check its documentation
- The examples below are using sqlite3 (begin_src sqlite)
#+PROPERTY: header-args:sqlite :db /tmp/rip.db :colnames yes :results table
Create a table, and populate it. Note that the block does not generate a result.
drop table if exists R;
create table R(a,b);
insert into R values (1,'test'), (2, 'example'), (3, 'one more');
Simple select
select * from R;
a | b |
---|---|
1 | test |
2 | example |
3 | one more |
You can specify the version of python you want to run using the variable org-babel-python-command (see configuration file)
(setq org-babel-python-command "python3")
Simple program:
print("hello world")
hello world
A more complex program
def square(x):
return x*x
print(list(map(square, range(1,10))))
[1, 4, 9, 16, 25, 36, 49, 64, 81]
Of course you can use advanced org-features, but remember that students might be confused, since they will not be able to cut-and-paste the snippet.
def square(x):
return x*x
- so make sure you warn them
<<square>> # this is not Python! this is emacs
# it inserts the blocked name square (see above)
# here. i used it to avoid duplicating code
print(list(map(square, range(1,10))))
[1, 4, 9, 16, 25, 36, 49, 64, 81]
- Some programming characters are used by org
- _ (underscore): use the following in the header so it is exported properly:
#+OPTIONS: ^:nil
- | (pipe character): eg | and || operators in C/C++
- Example: I can’t add | inside the table.
operator meaning && and or Some database results might contain | and mess the rendering of the result
See my configuration file and demo presentation (link to come).
Some things that are important:
- Typeset the org-buffer so it is shown as close as it is meant to be presented
- highlight the current line
- set defaults for the org-mode properties of the language you are using
- use in tandem with github (not required, but makes life easier)
- use yasnippets
- make sure you can easily change the fontsize
- sometimes you need to show more/sometimes less
- experiment!
- org-mode and emacs make for a great environment to teach programming
- single format where code is executed and its results inserted
- github is a great tool that can make publishing easy