#+SETUPFILE: https://fniessen.github.io/org-html-themes/org/theme-readtheorg.setup
#+TITLE: Org Mode
#+author: Yves-Jean DANIEL
#+email: yves-jean.daniel@isima.fr
#+STARTUP: inlineimages
#+BEGIN_SRC elisp
(eval-after-load 'org
(add-hook 'org-babel-after-execute-hook 'org-redisplay-inline-images))
#+END_SRC#+BEGIN_SRC elisp
(eval-after-load 'org
(add-hook 'org-babel-after-execute-hook 'org-redisplay-inline-images))
#+END_SRC
[lundi 08:30] Yves Jean DANIEL
import random
def generePermutationListe(L, p = None):
n = len(L)
if p == None:
p = n
out = list(L)
for i in range(p):
k = random.randint(i,n-1)
out[i], out[k] = out[k], out[i]
return out[:p]
def generePermutationChaine(ch, p = None):
return "".join(generePermutationListe(list(ch), p))
(org-babel-do-load-languages
'org-babel-load-languages
'((ditaa . t)
(C . t)
(dot . t)
(emacs-lisp . t)
(scheme . t)
(gnuplot . t)
(haskell . t)
(latex . t)
(js . t)
(ledger . t)
(matlab . t)
(ocaml . t)
(octave . t)
(plantuml . t)
(python . t)
(R . t)
(ruby . t)
(screen . nil)
(scheme . t)
(shell . t)
(sql . t)
(sqlite . t)))
(setq org-babel-python-command "python3")
** Graphviz
Pour débuter : http://magjac.com/graphviz-visual-editor/
#+BEGIN_SRC dot :file "graph1.png" :exports both
strict digraph {
a [shape="ellipse" style="filled" fillcolor="#1f77b4"]
b [shape="polygon" style="filled" fillcolor="#ff7f0e"]
a -> b [fillcolor="#a6cee3" color="#1f78b4"]
Père [ shape=ellipse style="filled" fillcolor="#FF44cc"]
Mère [ shape=octagon]
Frère [ style="radial, solid" color="#c22727" fillcolor="#99cb0b" shape=ellipse]
Père -> b
Frère -> Père
n6
n6 -> a
Frère -> b [ style=dashed color="#824848" fillcolor="#a361bb"]
n6 -> n6 [ style=dashed color="#824848" fillcolor="#a361bb"]
a -> n6 [ style="tapered, solid" color="#824848" fillcolor="#a361bb"]
n6 -> Mère [ style="dashed"]
Mère -> Père
Frère -> Pierre
n6 -> Frère
}
#+END_SRC
* Ditaa
Manuel : http://ditaa.sourceforge.net/#usage
#+BEGIN_SRC ditaa :file "ditaa1.png" :exports both
/------------------------------\ +-------------------+
| | | {d} cGRE |
| | | |
| | | Help +--------+ |
| Hello world +----->| | cYEL | |
| | | +--------+ |
| cBLU | +----------+--------+
| | | |
\-------------+----------------/ *----+ |
^ | | |
| v +-->*--+
| +---+---+ |
| | {s} | |
v | cPNK +-----+
+-------------+-----------------+ | Me... |
| {io} | +---+---+ /--\
| cRED | | | |
| Patatoes +<-----+ : /---* *---\
| | | | | +
| | | | ++ |
+-------------------------------+ +--+ \---------+
#+END_SRC
** C
*** Un exemple basique
#+BEGIN_SRC C :exports both
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
int find(char c, char dico[], int len_dico){
int i = 0;
char found = 0;
for (i = 0 ; i < len_dico && !found; ++i){
if (dico[i] == c){
found= 1;
}
}
if (found){
return i-1;
} else{
return -1;
}
}
void counting(char *s, char dico[], int len_dico, int counts[]){
int pos;
while (*s){
pos = find(*s, dico, len_dico);
if (pos != -1){
counts[pos]++;
}
s++;
}
}
void print_counts(char dico[], int len_dico, int counts[]){
int i;
for (i = 0 ; i < len_dico; ++i){
if (dico[i] !=' '){
printf("%c %d\n", dico[i], counts[i]);
} else {
printf("SPC %d\n", counts[i]);
}
}
}
int main(int argc, char** argv){
(void) argc;
(void) argv;
char *my_string = "HELLO MY FRIEND";
char dico[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ ";
int len_dico = strlen(dico);
int *counts = calloc(len_dico, sizeof *counts);
counting(my_string,dico, len_dico, counts);
print_counts(dico, len_dico, counts);
free(counts);
return 0;
}
#+END_SRC
#+RESULTS:
| A | 0 |
| B | 0 |
| C | 0 |
| D | 1 |
| E | 2 |
| F | 1 |
| G | 0 |
| H | 1 |
| I | 1 |
| J | 0 |
| K | 0 |
| L | 2 |
| M | 1 |
| N | 1 |
| O | 1 |
| P | 0 |
| Q | 0 |
| R | 1 |
| S | 0 |
| T | 0 |
| U | 0 |
| V | 0 |
| W | 0 |
| X | 0 |
| Y | 1 |
| Z | 0 |
| SPC | 2 |
*** Directives de compilation, ligne de commande
de faire appel à des bibliothèques (maths, **sdl**, ...)
#+begin_example
#+BEGIN_SRC C :flags -Wall -Wextra
......
#+end_src
#+end_example
On peut également préciser des paramètres d'entrée du programme (ce que l'on
mettrait sur la ligne de commande lors de /l'exécution/ après le nom de
l'exécutable)
#+begin_example
#+BEGIN_SRC C :flags -Wall -Wextra :cmdline <input.txt
......
#+end_src
#+end_example
* Graphiques
Créer des graphiques en python est très fréquent car c'est un langage qui
dispose de nombreuses bibliothèques très agréables pour manipuler des
données (en particulier /pandas/), et pour réaliser des graphiques (en
particulier /seaborn/).
La méthode (indépendante du langage) est simple, il suffit que le code
génère un fichier image, que l'on insère ensuite comme lien là où on désire
l'afficher. Afin qu'une nouvelle exécution du code mette à jour l'image
affichée, il est utile d'insérer dans le fichier de config d'emacs le code
proposé dans la partie [[Configuration]].
#+BEGIN_SRC python :exports code
import seaborn as sns
import matplotlib.pyplot as plt
import math
import numpy as np
import random
def f(x):
return math.sin(math.sqrt(7)*x)*x * math.sin(80*x)
def courbe():
x = list(np.linspace(0,5,1000))
y = map(f, x)
y = list(y)
sns.lineplot(x=x, y=y)
im = np.zeros((10,10), dtype=np.uint8)
for l in range(10):
for c in range(10):
im[l, c] = random.randint(0,255)
plt.clf()
plt.imshow(im)
plt.savefig('test2.png')
plt.clf()
courbe()
plt.savefig('test1.png')
#+END_SRC
#+RESULTS:
: None
On peut alors afficher les images en insérant le fichier comme un lien
~[[./test1.png]]~
[09:34] Yves Jean DANIEL
* Entrées utilisateur
S'il n'y a pas de 'réaction', on peut écrire la suite des entrées dans un
fichier, et utiliser ce fichier en entrée de la ligne de commande.
#+BEGIN_SRC C :results raw html :flags -Wall -Wextra :cmdline <input_entree_utilisateur.txt :exports both
#include "stdio.h" int main(int argc, char ** argv){
(void) argc;
(void) argv;
int tab[4];
char txt[255]; puts("Entrer 4 entiers");
for (int i = 0 ; i < 4 ; ++i){
scanf("%d", &tab[i]);
}
puts("\n-------------------- FAIT --------------------"); printf("Entrer une chaîne de caractères :");
scanf("%254s", txt);
puts("\n-------------------- FAIT --------------------"); for(int i = 0 ; i < 4 ; ++i){
printf("%s\tn° %d\n", txt, tab[i]);
} }
#+end_src #+RESULTS:
[09:37] Yves Jean DANIEL
* Pour expliquer un code
*** Référencer une portion de code
Il est parfois intéressant de référencer une portion de code afin d'y faire
appel dans le texte. Cela peut se faire en plaçant dans le code une référence
sur une ligne de code ~(ref:label)~ (où label est remplacé par une
étiquette de son choix). Dans le texte, on pourra alors faire un lien sur la
ligne de code par $[$[(label)][Texte à afficher]$]$
#+BEGIN_SRC python -r :exports code :results output replace :var n=6 :exports both
def fact(n):
if n <= 1: (ref:cb)
return 1
else: (ref:rec)
return n * fact(n-1) print("fact(5) =", fact(n) )
print("| hello |")
#+END_SRC #+RESULTS:
: fact(5) = 2
: | hello | "On pourra noter que le [[(cb)][cas de base]] est ici étendu au cas où l'argument vaut
1, ce qui n'est pas nécessaire, la [[(rec)][partie récursive]] est, elle, conforme à la
définition usuelle de la factorielle"
*** Numéroter les lignes
L'option ~-r~ permet d’afficher dans le texte le numéro de la ligne.
*** Bloc de code sans langage précisé
Permet d'obtenir un paragraphe séparé du reste avec une fonte à chasse
fixe.
#+begin_example
#+BEGIN_SRC python :tangle results value :exports both
def fact(n):
if n <= 1:
return 1
else:
return n * fact(n-1) print("fact(5) =", fact(5) )
#+END_SRC
#+end_example
* Export d'un code pour être utilisé ailleurs
** Export du code
Pour effectuer cette forme d'export, on utilise ~C-c C-v t~. Le résultat est un
nouveau fichier qui ne contient que ce code source.
#+BEGIN_SRC python :tangle fic1.py :results none
def hello():
print("hello World")
#+END_SRC
On peut complét#+RESULTS:
: Salut les copains !
#+RESULTS:
: Salut les copains !
er le fichier en réalisant des 'tangles' en utilisant le même nom
de fichier, mais attention, le 'tangle' ne fait que copier les textes dans le
fichier indiqué, il ne vérifie rien !
#+BEGIN_SRC python :tangle fic1.py :results none
hello()
#+END_SRC
Ou écrire dans un autre fichier :
#+BEGIN_SRC python :tangle fic2.py :results none
print("ici est ailleurs")
#+END_SRC
** Bash pour exécuter ce code
- On crée un fichier à l'aide de la méthode précédente
#+BEGIN_SRC C :tangle hello.c :results none
int main(){
puts("Salut les copains !");
return 0;
}
#+END_SRC
- Puis on travaille un peu en bash :
#+BEGIN_SRC bash
gcc -Wall -Wextra -o hello hello.c
./hello
#+END_SRC
* Appeler une fonction
*** un exemple en python
#+name: fct
#+BEGIN_SRC python -r :exports both :results value html :return fact(n) :var n=7
def fact(n):
if n <= 1:
return 1
else:
return n * fact(n-1)
def succ(n):
return n+1
#+END_SRC
#+RESULTS: fct
#+BEGIN_EXPORT html
5040
#+END_EXPORT
Lorsque comme ci-dessus une variable a été définie, il est possible de rappeler
le code en modifiant la valeur de la variable. Pour cela on utilise ~#+call:
fct(n=5)~, où (ATTENTION !) ~fct~ est le nom du bloc de code (et pas le nom de
la fonction), indiqué par le ~#+name: fct~ précédant le code. On peut noter
qu'el est possible de modifier les options lors de cet appel si on le désire.
#+call: fct(n=5) :exports results :results value latex
#+RESULTS:
#+BEGIN_EXPORT latex
120
#+END_EXPORT
On peut également appeler une autre fonction :
#+call: fct(n=5) :return succ(n)
#+RESULTS:
#+BEGIN_EXPORT html
6
#+END_EXPORT
*** un exemple en c
#+name: hello
#+BEGIN_SRC C -r :results value :var n = 3
int f(int n){
return n==0?1:n*f(n-1);
}
int main(){
//printf("| ");
for(int i = 0 ; i< n ; ++i){
printf(" %d | ", f(i));
}
return 0;
}
#+END_SRC
#+RESULTS: hello
| 1 | 1 | 2 | 6 | 24 |
et avec un appel avec la valeur 7 :
#+call: hello(7)
#+RESULTS:
| 1 | 1 | 2 | 6 | 24 | 120 | 720 |
Ce qui est bel et bien bon !
* Communiquer entre des blocs de code
** Utiliser des fichiers
Un premier code prodit ses résultats dans un fichier, qui sert d'entrée à un
autre code. Cela peut être fait sans utiliser de fonctionnalité d'orgmode
(les codes utilisent de façon normale des fichiers), ou en utilisant comme
variables d'entrées ou de sorties des fichiers (c'est alors très similaire
aux redirections ~<~ et ~>~ du bash).
*** Exemple en passant par la ligne de commande
Voici un bloc en c qui produit des données :
#+BEGIN_SRC C :output both :flags -Wall -Wextra :cmdline >c_to_py.txt
#include "stdio.h"
int main(int argc, char **argv){
(void) argc;
(void) argv;
int i;
for(i = 0 ; i < 100 ; ++i){
printf("%d\n", i);
}
printf("%s", "Hello!");
return 0;
}
#+END_SRC
#+RESULTS:
Maintenant un bloc en python qui consomme les données :
#+BEGIN_SRC python :output both :results output
import sys
import seaborn as sns
import matplotlib.pyplot as plt
sys.stdin = open('c_to_py.txt', 'r')
L = []
for a in range(10):
L.append(int(input("")))
sys.stdin.close()
L = list(map(lambda x: x**2, L) )
sns.lineplot(x = range(len(L)), y = L)
plt.savefig('test3.png')
print(L)
sys.stdout = open('py_to_c.txt', 'w')
for a in L:
print(a)
sys.stdout.close()
#+END_SRC
#+RESULTS:
: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
None
[[./test3.png]]
[[./py_to_c.txt]]
** Nommer les sorties
On peut nommer avec ~#+NAME mon_joli_nom~ un bloc . Ce bloc peut alors être
utilisé comme variable d'entrée à un autre bloc.
Un bloc en C qui fabrique des arcs :
#+BEGIN_SRC C :output both :flags -Wall -Wextra :results output
#include "stdio.h"
#include "stdlib.h"
int main(int argc, char ** argv){
(void) argc;
(void) argv;
srand(143);
int i, k;
for(i = 0 ; i < 10 ; ++i){
for (k = 0 ; k < rand()%5+1; ++k){
printf("%d -> %d\n", i, rand()%10);
}
}
return 0;
}
#+END_SRC
#+name: testa
#+RESULTS:
#+begin_example
0 -> 6
1 -> 9
1 -> 5
1 -> 5
2 -> 8
2 -> 3
2 -> 6
3 -> 7
3 -> 1
3 -> 8
4 -> 6
5 -> 5
5 -> 9
6 -> 4
6 -> 2
6 -> 1
6 -> 8
7 -> 9
7 -> 2
8 -> 1
9 -> 2
9 -> 8
9 -> 5
9 -> 0
#+end_example
[[./c_to_gv.txt]]
Pour finalement être représenté sous forme de graphe :
#+BEGIN_SRC dot :file "graph2.png" :exports both :var monGraph=testa
strict digraph {
$monGraph
}
#+END_SRC
#+RESULTS:
[[file:graph2.png]]
int main()
{
int W,H,N,X0,Y0;
scanf("%d%d%d%d%d", &W, &H,&N,&X0,&Y0);
int xd=0;
int xf=W-1;
int yd=0;
int yf=H-1;
while (N) {
char bomb[4];
scanf("%s", bomb);
if (bomb[0]=='R' ||bomb[1]=='R')xd=X0+1;
if (bomb[0]=='L'|| bomb[1]=='L')xf=X0-1;
if (bomb[0]=='U') yf=Y0-1;
if (bomb[0]=='D') yd=Y0+1;
X0=xd+(xf-xd)/2,Y0=yd+(yf-yd)/2;
printf("%d %d\n",X0,Y0);}
return 0;
}