Software
Introduction
Moodle’s logic is written in a programming language called PHP (www.php.net), this is ‘interpreted’ by another program that is run on the server that the web server program uses, both ‘compiled’ programs. Some programming languages are ‘interpreted’ and others are ‘compiled’. When a programming language is interpreted the instructions it contains are decoded into a form that the machine understands (machine code) as they are read from the source, then actually run (executed). When programs are compiled then all of the source is decoded into machine code and then that is executed when needed. The web browser you’re running will probably be compiled – unless on an Android phone where its written in Java – another story. But how are compiled programs / software created? That is what I’ll explain here.
If you want to learn more about how Moodle works with PHP then please read “Output three ways” and for the server (and client) concept, “The perils of ‘display: none’”.
Disclaimers and license
Moodle™ is a registered trademark of ‘Martin Dougiamas’ – moodle.com/trademarks.
Other names / logos can be trademarks of their respective owners. Please review their website for details.
I am independent from the organisations listed above and am in no way writing for or endorsed by them.
All code presented here has been written by myself. Please feel free to copy / use / modify under the terms of the GNU GPLv3 license: www.gnu.org/copyleft/gpl.html.
The idea, machine and language
To explain the concept of creating software we need an idea upon which to form the basis of the explanation. That idea is straight forward, to take some text and remove the vowels. So “The cat sat on the mat” becomes “Th ct st n th mt”.
Learning how to program requires an actual computer and a means of it understanding the chosen programming language. As I want to explain something that is ‘compiled’ and which you’ll be in a position to replicate, I’ve chosen to use ‘C’ on the Raspberry Pi. This is because:
- Its a machine designed for learning programming.
- It runs Raspbian (raspbian.org) which is a distribution of Linux upon which the operating system is written in ‘C’ (and C++ I believe. C++ is in effect object orientated C).
- It comes with a C compiler and linker (more about the linker later).
- You should be able to replicate what I’ve done on any other Unix based (Linux is a subset of Unix – long story) distribution, even on a virtual machine.
- Requires little or no setup once the standard Pi setup as been completed.
To find out more about what a compiler is, please see: en.wikipedia.org/wiki/Compiler.
Initial program
Software of any size greater than small is made up of multiple source files. This is to:
- Break the solution down into human manageable chunks.
- Provide a means of re-using those chunks in other programs that use the same part of the solution.
So demonstrate how we can create a program with multiple source files that are then combined into one program, lets first write the example in one file:
#include <stdio.h> char isVowel(char *theChar); const char no = 'n'; const char yes = 'y'; int main (int argc, char** argv) { if (argc > 1) { int count = 0; while (argv[1][count] != 0) { if (isVowel(&argv[1][count]) == no) { putchar(argv[1][count]); } count++; } } else { printf("Usage: %s word", argv[0]); } putchar('\n'); return 1; } char isVowel(char *theChar) { char retr = no; switch(*theChar) { case 'a': case 'e': case 'i': case 'o': case 'u': retr = yes; break; } return retr; }
it has some information at the top:
char isVowel(char *theChar); const char no = 'n'; const char yes = 'y';
which is then used in both the ‘main’ and ‘isVowel’ functions. The statement ‘char isVowel(char *theChar);’ just allows us to write ‘main’ before ‘isVowel’ is actually written.
Then there is the ‘main’ function that reads our input when we run the program, reads each input character and uses the ‘isVowel’ function to tell it if the current character is a vowel or not. If it is then nothing happens and we check the next character if any, if it is not then we output the character. When there are no more characters to read from the input we exit.
And finally the ‘isVowel’ function that says if the character passed to it is a vowel or not.
Our example will compile on the Pi with the command ‘gcc nov.c -o nov’ (which takes the source file ‘nov.c’ and creates the runnable output file ‘nov’) and then when we run it with ‘./nov “The cat sat on the mat” we get:
So clearly we have something that works. But what if we wanted to reuse the ‘isVowel’ function in another program? Or our program is instead of 38 lines long it is actually thousands and it needs to be broken apart? That’s when we not only have several source files but also employ the use of another program called a ‘linker’.
Linking
A compiler will take one source file and produce the machine language for it, the object file (which if self contained will run as a program). A linker will take two or more object files and combine them together to create a program or a library or another object. I’ll just demonstrate a program being created. To find out more about Linkers, see: en.wikipedia.org/wiki/Linker_(computing).
Breaking apart our program
So now that we know we have the tools to create a program with many source files, lets do so. Thus we will have ‘isVowel.h’:
char isVowel(char *theChar); extern const char no; extern const char yes;
Which defines what will be shared between the two files containing the implementation of the code. Then we have ‘isVowel.c’:
#include "isVowel.h" const char no = 'n'; const char yes = 'y'; char isVowel(char *theChar) { char retr = no; switch(*theChar) { case 'a': case 'e': case 'i': case 'o': case 'u': retr = yes; break; } return retr; }
which implements what the ‘isVowel.h’ says it will. And finally ‘noVowels.c’:
#include <stdio.h> #include "isVowel.h" int main (int argc, char** argv) { if (argc > 1) { int count = 0; while (argv[1][count] != 0) { if (isVowel(&argv[1][count]) == no) { putchar(argv[1][count]); } count++; } } else { printf("Usage: %s word", argv[0]); } putchar('\n'); return 1; }
which forms the ‘main’ wrapper around the logic that actually allows it to become a runnable program. Then all we need to do is use ‘gcc’ again, but this time as we specify two source files then it will invoke the linker for us using ‘gcc isVowel.c noVowels.c -o noVowels’:
Conclusion
Even if you don’t understand fully the language and syntax of ‘C’ as demonstrated, I hope that you now have the beginnings of an understanding of how software is written and constructed.
If you have a Raspberry Pi or a Unix based machine, then do try the example out.
And finally, a really technical problem: How can the ‘isVowel’ function be improved and why?
- Debugging SCSS – 16th November 2024
- Settings transfer – 16th October 2024
- Added value – 16th September 2024
Fascinating post.
Reading this I instantly know I’m not a programmer, and never will be.
It’s strange, it just doesn’t gel in my mind the way it must for others.
The only analogy I have, as an artist, is that when some people try to draw they just don’t ‘get it’ – it’s like their brains do not see the same things as I do.
Brains and the way we think and see, wow, constantly surprising.
Hi Stuart,
Imagine that a ‘Linker’ is the ‘Chef’ whom is making a Victoria Sponge cake, where the source ‘.c.’ files are the sponge layers and the ‘.h’ files are the cream / jam that is between them.
Gareth