dmgerman / teachingProgOrg

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Teaching Programming with Emacs, org-mode and github

The explanation below will make more sense if you open this file in emacs. That way you will see the headers of each block.

Table of contents

Presentation

This is a 20 minute presentation on why and how I use emacs and org-mode to teach programming

https://youtu.be/tSYL-ricWLg

How to use

  • 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

Perhaps this code can one day become a module.

Why use org-mode for teaching programming?

  • 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

Limitations

  • It is not powerpoint
    • no animations
    • not trivial to annotate with a stylus (but possible, using Xournal)
    • not suitable for very large code examples

How I do it

  • 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

Demo

Some simple programming examples:

C/C++

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

SQL

create table R(a, b);
insert into R values (1, "this"), (2, "is"), (3, "an"), (4, "example");y
select * from R;
ab
1this
2is
3an
4example

Python

l = range (0,3)
list(map(print, map(lambda i: (i,2**i), l)))
(0, 1)
(1, 2)
(2, 4)

Ruby

l = Array.new(3) {|i| [i,2**i]}
l.map { |p| print(p, "\n")}
[0, 1]
[1, 2]
[2, 4]

R

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)

testR.png

Github

Github is a great resource:

publishing

  • 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

version control

  • git, obvious ;)
  • easy to collaborate with co-authors
  • you can get pull requests

some nitfy features

  • navigation links
  • cut-and-paste for code blocks
  • edit in place
  • automatic scrollbars for long blocks and results

:exports both

  • 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

header-args

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"

C specific

#+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

warning and errors

  • 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();
}

using :main yes

  • 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

C++ specific

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

SQL specific

  • 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;
ab
1test
2example
3one more

Python specific

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]

Advanced org-features

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 potential issues you might encounter

  • 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.
    operatormeaning
    &&and
    or

    Some database results might contain | and mess the rendering of the result

Final words

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!

Conclusion

  • 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

About


Languages

Language:Emacs Lisp 82.5%Language:YASnippet 17.5%