JnyJny:Devhttps://jnyjny.github.io/2018-10-21T10:57:00-05:00How I Started a Python Meetup2018-10-21T10:57:00-05:002018-10-21T10:57:00-05:00ejotag:jnyjny.github.io,2018-10-21:/how-i-started-a-python-meetup.html<p>Sometimes you just have to do things yourself.</p><h2><strong>Setting The Scene</strong></h2>
<p>I live just outside of Austin, Texas which is sometimes referred to as
“Silicon Hills”. There are many large computer and technology
companies here; <span class="caps">IBM</span>, <span class="caps">AMD</span>, Apple, Oracle, <span class="caps">NVIDA</span> to name just a
handful. Just as importantly, there is a teeming ecology of smaller
tech companies which provide goods and services across the entire
gamut of the technology space. Austin is awash in nerds and geeks of
every stripe.</p>
<p>Given all these talented people doing cool stuff, there are naturally
<a href="https://meetup.com">meetups</a> all over the greater Austin area where people get
together, network and share their knowledge. I really wanted to attend
the <a href="https://meetup.com/austinpython">Austin Python</a> meetup but their schedule and location wasn’t a
good fit for me.</p>
<p>I was feeling sorry for myself, discussing the situation with a friend
on the excellent <a href="https://pybites.slack.com">PyBites Slack</a> and he told me he’d just started a
Python meetup. And he’d already had a meeting. I was <a href="https://en.oxforddictionaries.com/definition/us/gobsmacked">gobsmacked</a>
and more than a little jealous of his initiative! I was motivated right
there to stop waiting for the right meetup for me and make it happen.</p>
<h2><strong>What Have I Done?</strong></h2>
<p>It doesn’t take much to create a new organization on meetup.com. You
are prompted for the following:</p>
<ol>
<li>A regional location</li>
<li>An organization name</li>
<li>Who the group is for.</li>
</ol>
<p>Then they will ask you for money. To be honest, I did this late at
night and the details on the cost are fuzzy. I signed up for a six
month “subscription” and pushed the ‘Pay’ button. And then I thought
to myself “Well great, now what?”.</p>
<h2><strong>If You Build It, Will They Come? </strong></h2>
<p>The next morning, I sat down and started digging into the tools
provided by Meetup for groups. I hacked together a logo with the help
of my exeedingly talented and patient wife and started branding the
group meetup pages. I wrote some verbiage describing the kind of group
I wanted to build and wrote some introductory text about myself.</p>
<p>When all was said and done, I spent maybe two hours on the graphic
design and copy writing. The group page looked a little less generic
and the text was ernest and forthcoming. </p>
<p>I spent some time discussing my efforts on Slack and received lots of
positive reinforcement. Then I got my first notification from Meetup
that someone had joined the group! Wow talk about a rush! I wasn’t
entirely alone!</p>
<p>That weekend the membership increased steadily and I soon found myself
with over 50 people interested in the group I proposed. Quick side
note, once you get over 50 people in your group Meetup will want to
increase the fee they charge. I blindly paid it, caught up in the
excitement of creating a new community.</p>
<p>Ok, now it was time to get them to show up to a meeting.</p>
<h2><strong>The First Meeting</strong></h2>
<p>Meetups are notorius for creating a buzz around a topic, having a lot
of people join up and then generating minimal attendence. I’m guilty
of this myself. It’s pretty easy to click a button and say “Yeah, I’m
kinda interested in that”. Re-iterating my introverted tendencies,
it’s hard for me to work against personal inertia and show up to a
meeting. And the little voice that whispers <em>“they won’t like you”</em> or
<em>“you’re not a real programmer”</em> or <em>“your socks aren’t alphabetized
yet”</em>. Two of those three thoughts really ocurred to me.</p>
<p>Having experienced this phenomenon myself, I wanted our first meeting
to be more of a social setting than a technical one. So I picked my
favorite upscale bar for the following reasons:</p>
<ul>
<li>Convenient to me geographically.</li>
<li>I was comfortable there.</li>
<li>Lots of room and table space for people to talk.</li>
<li>Not crowded in the early afternoon on a weekend.</li>
<li>Beer is a social lubricant.</li>
</ul>
<p>I recognize that not everybody would be interested in adult beverages,
but I am far more social after a pint of beer. Being in a comfortable
setting let me be welcoming and open. It’s super tough to show up out
of the blue and meet strangers, so my goal was to greet everyone with
a smile and a name tag.</p>
<p>I crafted a meeting notice on Meetup and sent it out to the membership.</p>
<h2><strong>Preparation <span class="amp">&</span> Anticipation</strong></h2>
<p>I’m not going to lie. I was more than a little apprehensive about
hosting a meeting. My very good reasons to be apprehensive included:</p>
<ul>
<li>No experience in running a group</li>
<li>No experience hosting a meeting</li>
<li>No experience running a meeting</li>
</ul>
<p>While I spun my wheels grappling with my <a href="https://en.wikipedia.org/wiki/Impostor_syndrome">imposter syndrome</a>, RSVPs
started to come in. Actual people’s actual names now associated with
the nebulous idea of a “python user group”. I needed to seriously
put my act together and make something happen.</p>
<p>While I might not have experience at running a group, I definitely
have been involved with different groups and I had ideas about the
things that worked and didn’t work for all of them. I haven’t hosted a
meeting, but I’ve attended plenty. I haven’t run a meeting, but I’ve
been to good, bad and horrible ones. Working from past experience, I
started preparing for the two hour meeting.</p>
<p>First, I knew I wanted those cheesy “Hello My Name Is:” stickers. I am
terrible with names and I wanted to address any stressors in a new social
situation. Knowing someone’s name is a great way to build rapport and
the nametags smooth over those awkward seconds when you forget the name
of the person you just met. It feels like the kernel of community to me.</p>
<p>Second, I wanted a clipboard because every “serious” organization has
one (totally kidding, I just like clipbards). I found a cheap
clipboard with integrated storage at the office supply store while
looking for the nametags and sharpies and lamination materials. At
home I printed out a 8.5x11” group logo, laminated it and taped it to
the front of the clipboard. Now I had a sign to set out on a table and
a “base of operations”. I also tucked in a couple dozen sheets of blank
paper and pens.</p>
<p>Last, every fun computer group has a sticker for their laptop. At
least as far as I know. I made a 2x3 inch design from my initial logo
work and ordered a roll of 100 stickers from <a href="https://stickermule.com">stickermule.com</a>.
Huge shout out to StickerMule for getting the stickers to me in
time for the event!</p>
<p><img alt="Sticker" src="https://jnyjny.github.io/images/nap_sticker.png"></p>
<h2><strong>The First Meeting</strong></h2>
<p>So you should probably contact your venue before scheduling your
meetup. And you’ve probably already guessed that advice like that is
hard won. I showed up thirty minutes early for the meetup, ordered a
beer and talked to the staff. Bringing in sixteen customers on a slow
afternoon will make any bar happy, but I had no plan B if they
would’ve declined to host us. Lesson learned, call ahead.</p>
<p>I sat down and filled out my name tag. I wanted to give people some
ice breakers, so I wrote my name, my favorite operating system, my
favorite editor and an interesting python module.</p>
<p><img alt="Your Host" src="https://jnyjny.github.io/images/hello_my_name_is.png"></p>
<p>As folks began to filter in, I invited them to fill out a name tag and
introduced them around. Pretty soon, I had over a dozen people talking
to each other about python, the computing industry and just hanging
out. It was totally working!</p>
<p>My only goal for the meeting, beyond quaffing a beer or two, was to
get some feedback on two things. First I wanted more ideas for places
the group could meet. The bar is fine for a casual conversation,
however everyone agreed it was too loud for a techincal
discussion. And second, I wanted to find out what python topics people
were interested in learning about.</p>
<p>Rather than interrupt the social flow with me pontificating, I bashed
together two sheets; one labeled “Venue Ideas” and the other “10
Minute Python Talk Topics”. Those circulated through the group and at
the end I didn’t have much in the way of venues (that’s a hard
problem). But I did get a list of over a dozen python related topics
that people were interested in learning about. That was huge. It gave
me a guage of where people were at skill/experience wise and a roadmap
for future meetings.</p>
<h2><strong>And Then It Was Over</strong></h2>
<p>The meeting lasted roughly two and half hours; thirty minutes longer
than scheduled. I paid my tab and walked out with the last couple of
people to leave. Everyone left with a sticker or two for their laptop
and assurances that the next meeting would be somewhere quieter and
have some actual python content. I was ridiculously happy with the
meeting; people showed up, people talked and I got some feedback
about the group and what other people were looking for.</p>
<p>Honestly, I am humbled and thrilled at the turn out for the first
meeting. More than 90% of people who <span class="caps">RSVP</span>’ed attended and the
anonymous event feedback was gratifyingly positive.</p>
<p><img alt="Feedback Brag" src="https://jnyjny.github.io/images/anonymous_feedback.png"></p>
<p>I talked to a
bunch of genuine people who shared a common interest and I am
really looking forward to seeing what comes next.</p>
<h2><strong>Next Steps</strong></h2>
<p>Our next meeting is tenatively scheduled for mid-November and I’ve
announced a simple agenda; I’ll deliver a short 20-30 minute talk
called “Python Crash Course” followed by 90 minutes of discussion and
hacking. I’m already working on the materials for the talk. With
any luck, I’ll have a quiet room that can accomodate 60 people.</p>
<p>If you can’t find a community that suits your schedule or needs,
consider building one from scratch. In my sample size of
two (<a href="https://meetup.com/pyandbeer">1</a>,<a href="https://meetup.com/north-austin-pythonistas">2</a>), there are people in the same position that are just
waiting for you to step up and do it.</p>How To Write a C Program Like Me2018-10-06T00:00:00-05:002018-10-06T00:00:00-05:00ejotag:jnyjny.github.io,2018-10-06:/how-to-write-a-c-program-like-me.html<p>Learn how to write a good C main function.</p><h3><strong>C is Dumb</strong></h3>
<p>I know, Python and Javascript are what the kids are writing all their
crazy ‘apps’ with these days. But don’t be so quick to dismiss C, it’s
a capable and concise language that has a lot to offer. If you need
speed, writing in C could be your answer. If you are looking for job
security and the opportunity to learn how to hunt down null pointer
dereferences, C could also be your answer! In this article, I’ll
explain how to structure a C file and write a C main function that
handles command-line arguments like a champ.</p>
<p><strong>Me</strong>: a crusty <span class="caps">UNIX</span> system programmer.<br>
<strong>You</strong>: someone with an editor, a C compiler and some time to kill.</p>
<p><em>Let’s do this.</em></p>
<h3><strong>A Boring But Correct C Program</strong></h3>
<p>A C program starts with a <code>main()</code> function, usually kept in a file named <code>main.c</code>.</p>
<div class="highlight"><pre><span></span><span class="cm">/* main.c */</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[])</span> <span class="p">{</span>
<span class="p">}</span>
</pre></div>
<p>This program <strong>compiles</strong> but doesn’t <strong>do</strong> anything:</p>
<div class="highlight"><pre><span></span>$ gcc main.c
$ ./a.out -o foo -vv
$
</pre></div>
<p>Correct and boring.</p>
<h3><strong>Main Functions Are Unique</strong></h3>
<p>The <code>main()</code> function is the first function in your program executed
when it begins executing, but it’s not the first function
executed. The <em>first</em> function is <code>_start()</code> which is typically
provided by the C runtime library, linked in automatically when your
program is compiled. The details are highly dependent on the operating
system and compiler toolchain, so I’m going to pretend like I didn’t
mention it.</p>
<p>The <code>main()</code> function has two arguments that traditionally are called
<code>argc</code> and <code>argv</code> and returns a signed integer. Most <span class="caps">UNIX</span> environments
expect programs to return zero on success and negative one on failure.</p>
<table>
<tr><th>Argument</th><th>Name</th><th>Description</th></tr>
<tr><td>argc</td><td>Argument Count </td><td>Length of the argument vector.</td></tr>
<tr><td>argv</td><td>Argument Vector</td><td>Array of character pointers.</td></tr>
</table>
<p>The argument vector, <code>argv</code>, is a tokenized representation of the
commmand line that invoked your program. In the example above, <code>argv</code>
would be a list of the following strings:</p>
<div class="highlight"><pre><span></span><span class="n">argv</span> <span class="o">=</span> <span class="p">[</span> <span class="s">"/path/to/a.out"</span><span class="p">,</span> <span class="s">"-o"</span><span class="p">,</span> <span class="s">"foo"</span><span class="p">,</span> <span class="s">"-vv"</span> <span class="p">];</span>
</pre></div>
<p>The argument vector is guaranteed to always have at least one string in the
first index, <code>argv[0]</code> which is the full path to the program executed. </p>
<h3><strong>Anatomy of a <code>main.c</code> File</strong></h3>
<p>When I write a <code>main.c</code> from scratch, it’s usually structured like this:</p>
<div class="highlight"><pre><span></span><span class="cm">/* main.c */</span>
<span class="cm">/* 0 copyright/licensing */</span>
<span class="cm">/* 1 includes */</span>
<span class="cm">/* 2 defines */</span>
<span class="cm">/* 3 external declarations */</span>
<span class="cm">/* 4 typedefs */</span>
<span class="cm">/* 5 global variable declarations */</span>
<span class="cm">/* 6 function prototypes */</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[])</span> <span class="p">{</span>
<span class="cm">/* 7 command-line parsing */</span>
<span class="p">}</span>
<span class="cm">/* 8 function declarations */</span>
</pre></div>
<p>I’ll talk about each of these numbered sections, except for zero. If you
have to put copyright or licensing text in your source, put it there.</p>
<p>Another thing I won’t talk about adding to your program is comments.</p>
<div class="highlight"><pre><span></span> "Comments lie."
- A cynical but smart and good looking programmer.
</pre></div>
<p>Instead of comments, use meaningful function and variable names.</p>
<p>Appealing to the innate laziness of programmers, once you add comments
you’ve doubled your maintenance load. If you change or refactor the
code, you need to update or expand the comments. Over time the code
mutates away from anything resembling what the comments describe.</p>
<p>If you have to write comments, do not write about <em>what</em> the code is
doing. Instead, write about <em>why</em> the code is doing what it’s doing.
Write comments that you would want to read five years from now when
you’ve forgotten everything about this code. And the fate of the
world is depending on you. <em>No pressure</em>.</p>
<h3><strong>1 Includes</strong></h3>
<p>The first things I add to a <code>main.c</code> file are includes to make a
multitude of standard C library functions and variables available to
my program. The standard C library does lots of things, explore header
files in <code>/usr/include</code> to find out what it can do for you.</p>
<p>The <code>#include</code> string is a <a href="https://en.wikipedia.org/wiki/C_preprocessor">C preprocessor</a> directive that causes
the inclusion of the referenced file in it’s entirety into the current
file. Header files in C are usually named with a <code>.h</code> extension and
should not contain any executable code; only macros, defines, typedefs
and external variable and function prototypes. The string <code><header.h></code>
tells <em>cpp</em> to look for a file called <code>header.h</code> in the system defined
header path, usually <code>/usr/include</code>.</p>
<div class="highlight"><pre><span></span><span class="cm">/* main.c */</span>
<span class="cp">#include</span> <span class="cpf"><stdio.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><stdlib.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><unistd.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><libgen.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><errno.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><string.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><getopt.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><sys/types.h></span><span class="cp"></span>
</pre></div>
<p>This is the minimum set of global includes that I’ll include by default for the following stuff.</p>
<table>
<tr><th>#include File</th><th>Stuff It Provides</th></tr>
<tr><td>stdio </td><td> Supplies <span class="caps">FILE</span>, stdin, stdout, stderr and the fprint() family of functions</td></tr>
<tr><td>stdlib </td><td> Supplies malloc(), calloc() and realloc() </td></tr>
<tr><td>unistd </td><td> Supplies EXIT_FAILURE, EXIT_SUCCESS </td></tr>
<tr><td>libgen </td><td> Supplies the basename() function. </td></tr>
<tr><td>errno </td><td> Defines the external errno variable and all the values it can take on. </td></tr>
<tr><td>string </td><td> Supplies memcpy(), memset() and the strlen() family of functions. </td></tr>
<tr><td>getopt </td><td> Supplies external optarg, opterr, optind and getopt() function. </td></tr>
<tr><td>sys/types</td><td>
Typedef shortcuts like uint32_t and uint64_t </td></tr>
</table>
<h3><strong>2 Defines</strong></h3>
<div class="highlight"><pre><span></span><span class="cm">/* main.c */</span>
<span class="o"><</span><span class="p">...</span><span class="o">></span>
<span class="cp">#define OPTSTR "vi:o:f:h"</span>
<span class="cp">#define USAGE_FMT "%s [-v] [-f hexflag] [-i inputfile] [-o outputfile] [-h]"</span>
<span class="cp">#define ERR_FOPEN_INPUT "fopen(input, r)"</span>
<span class="cp">#define ERR_FOPEN_OUTPUT "fopen(output, w)"</span>
<span class="cp">#define ERR_DO_THE_NEEDFUL "do_the_needful blew up"</span>
<span class="cp">#define DEFAULT_PROGNAME "george"</span>
</pre></div>
<p>This doesn’t make a lot of sense right now, but the <code>OPTSTR</code> define is
where we will define what command-line switches the program will
recommend. Consult the <a href="https://linux.die.net/man/3/getopt"><code>getopt(3)</code></a> manual page to learn how <span class="caps">OPTSTR</span>
will affect <code>getopt()</code><span class="quo">‘</span>s behavior.</p>
<p>The <code>USAGE_FMT</code> define is a <code>printf()</code>-style format string that is
referenced in the <code>usage()</code> function.</p>
<p>I also like to gather string constants as <code>#define</code><span class="quo">‘</span>s in this part of
the file. Collecting them makes it easier to fix spelling, reuse
messages and internationalize messages if required.</p>
<p>Finally, give <code>#define</code>s names with all capital letters to distinguish them
from variable and function names. You can run the words together if you want or
separate words with an underscore, just make sure it’s all upper case.</p>
<h3><strong>3 External Declarations</strong></h3>
<div class="highlight"><pre><span></span><span class="cm">/* main.c */</span>
<span class="o"><</span><span class="p">...</span><span class="o">></span>
<span class="k">extern</span> <span class="kt">int</span> <span class="n">errno</span><span class="p">;</span>
<span class="k">extern</span> <span class="kt">char</span> <span class="o">*</span><span class="n">optarg</span><span class="p">;</span>
<span class="k">extern</span> <span class="kt">int</span> <span class="n">opterr</span><span class="p">,</span> <span class="n">optind</span><span class="p">;</span>
</pre></div>
<p>An <code>extern</code> declaration brings that name into the namespace of the
current compilation unit ( a.k.a “file” ) and allows the program to
access that variable. Here we’ve brought in the definitions for three
integer variables and a character pointer. The <code>opt</code> prefaced
variables are used by the <code>getopt()</code> function and <code>errno</code> is used as
an out-of-band communication channel by the standard C library to
communicate why a function might have failed.</p>
<h3><strong>4 Typedefs</strong></h3>
<div class="highlight"><pre><span></span><span class="cm">/* main.c */</span>
<span class="o"><</span><span class="p">...</span><span class="o">></span>
<span class="k">typedef</span> <span class="k">struct</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">verbose</span><span class="p">;</span>
<span class="kt">uint32_t</span> <span class="n">flags</span><span class="p">;</span>
<span class="kt">FILE</span> <span class="o">*</span><span class="n">input</span><span class="p">;</span>
<span class="kt">FILE</span> <span class="o">*</span><span class="n">output</span><span class="p">;</span>
<span class="p">}</span> <span class="n">options_t</span><span class="p">;</span>
</pre></div>
<p>After external declarations, I like to declare <code>typedefs</code> for
structures, unions and enumerations. Naming <code>typedefs</code> is a religion
all to itself; I strongly prefer a ‘_t’ suffix to indicate that the
name is a type. In this example, I’ve declared <code>options_t</code> as a
<code>struct</code> with four members. <code>C</code> is a white-space neutral programming
language, so I use white space to line up field names in the same
column. I just like the way it looks. For the pointer declarations, I
prepend the asterisk to the name to make it clear that it’s a pointer.</p>
<h3><strong>5 Global Variable Declarations</strong></h3>
<p><span class="dquo">“</span>`c
/<em> main.c </em>/ <…></p>
<p>int dumb_global_variable = -11;</p>
<div class="highlight"><pre><span></span>Global variables are a bad idea and you should never use them. But if
you have to use a global variable, declare them here and be sure to
give them a default value. Seriously, _don't use global variables_.
### **6 Function Prototypes**
```c
/* main.c */
<...>
void usage(char *progname, int opt);
int do_the_needful(options_t *options);
</pre></div>
<p>As you write functions, added after the <code>main()</code> function and not
before, include the function prototypes here. Early C compilers used a
single-pass strategy which meant that every symbol (variable or
function name) you used in your program had to be declared before you
used it. Modern compilers are nearly all multi-pass compilers that
build a complete symbol table before generating code, so the use of
function prototypes is not strictly required. However you sometimes
don’t get to choose what compiler is used on your code, so write the
function prototypes and drive on.</p>
<p>As a matter of course, I always include a <code>usage()</code> function that
<code>main()</code> calls when it doesn’t understand something you passed in from
the command-line.</p>
<h3><strong>7 Command-Line Parsing</strong></h3>
<div class="highlight"><pre><span></span><span class="cm">/* main.c */</span>
<span class="o"><</span><span class="p">...</span><span class="o">></span>
<span class="kt">int</span> <span class="n">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[])</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">opt</span><span class="p">;</span>
<span class="n">options_t</span> <span class="n">options</span> <span class="o">=</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">,</span> <span class="n">stdin</span><span class="p">,</span> <span class="n">stdout</span> <span class="p">};</span>
<span class="n">opterr</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">while</span> <span class="p">((</span><span class="n">opt</span> <span class="o">=</span> <span class="n">getopt</span><span class="p">(</span><span class="n">argc</span><span class="p">,</span> <span class="n">argv</span><span class="p">,</span> <span class="n">OPTSTR</span><span class="p">))</span> <span class="o">!=</span> <span class="n">EOF</span><span class="p">)</span>
<span class="k">switch</span><span class="p">(</span><span class="n">opt</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="sc">'i'</span><span class="o">:</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">options</span><span class="p">.</span><span class="n">input</span> <span class="o">=</span> <span class="n">fopen</span><span class="p">(</span><span class="n">optarg</span><span class="p">,</span> <span class="s">"r"</span><span class="p">))</span> <span class="p">){</span>
<span class="n">perror</span><span class="p">(</span><span class="n">ERR_FOPEN_INPUT</span><span class="p">);</span>
<span class="n">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
<span class="cm">/* NOTREACHED */</span>
<span class="p">}</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="sc">'o'</span><span class="o">:</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">options</span><span class="p">.</span><span class="n">output</span> <span class="o">=</span> <span class="n">fopen</span><span class="p">(</span><span class="n">optarg</span><span class="p">,</span> <span class="s">"w"</span><span class="p">))</span> <span class="p">){</span>
<span class="n">perror</span><span class="p">(</span><span class="n">ERR_FOPEN_OUTPUT</span><span class="p">);</span>
<span class="n">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
<span class="cm">/* NOTREACHED */</span>
<span class="p">}</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="sc">'f'</span><span class="o">:</span>
<span class="n">options</span><span class="p">.</span><span class="n">flags</span> <span class="o">=</span> <span class="p">(</span><span class="kt">uint32_t</span> <span class="p">)</span><span class="n">strtoul</span><span class="p">(</span><span class="n">optarg</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="mi">16</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="sc">'v'</span><span class="o">:</span>
<span class="n">options</span><span class="p">.</span><span class="n">verbose</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="sc">'h'</span><span class="o">:</span>
<span class="k">default</span><span class="o">:</span>
<span class="n">usage</span><span class="p">(</span><span class="n">basename</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="n">opt</span><span class="p">);</span>
<span class="cm">/* NOTREACHED */</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">do_the_needful</span><span class="p">(</span><span class="o">&</span><span class="n">options</span><span class="p">)</span> <span class="o">!=</span> <span class="n">EXIT_SUCCESS</span><span class="p">)</span> <span class="p">{</span>
<span class="n">perror</span><span class="p">(</span><span class="n">ERR_DO_THE_NEEDFUL</span><span class="p">);</span>
<span class="n">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
<span class="cm">/* NOTREACHED */</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">EXIT_SUCCESS</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>Ok, that’s a lot. The purpose of the <code>main()</code> function is to collect the
arguments that the user provides, perform minimal input validation and
then pass the collected arguments to functions that will use them. In
this example, we declare an <code>options</code> variable initialized with
default values and parse the command-line, updating <code>options</code> as necessary.</p>
<p>The guts of this <code>main()</code> function is a while loop that uses <code>getopt()</code> to
step thru <code>argv</code> looking for command-line options and their arguments
(if any). The <span class="caps">OPTSTR</span> <code>#define</code> earlier in the file is the template
that drives <code>getopt()</code>s behavior. The <code>opt</code> variable takes on the
character value of any command-line options found by <code>getopt()</code> and the
program’s response to the detection of the command-line option happens
in the <code>switch</code> statement.</p>
<p>Those of you paying attention will now be questioning why <code>opt</code> is
declared as an 32-bit <code>int</code> but is expected to take on an 8-bit
<code>char</code>? It turns out <code>getopt()</code> returns an <code>int</code> value that takes on a
negative one when it gets the end of <code>argv</code>, which I check against
<code>EOF</code> or “End of File” marker. A <code>char</code> is a signed quantity, but I
like matching variables to their function return values.</p>
<p>When a known command-line option is detected, option specific behavior
happens. Some options have an argument, specified in <span class="caps">OPTSTR</span> with a
trailing colon. When an option has a argument, the next string in argv
is available to the program via the externally defined variable
<code>optarg</code>. We use <code>optarg</code> to open files for reading and writing or
converting a command-line argument from a string to an integer value.</p>
<p>There are a couple of points for style here:</p>
<ul>
<li>Initialize <code>opterr</code> to zero which disables <code>getopt</code> from emiting a ‘?’.</li>
<li><code>exit(EXIT_FAILURE);</code> or <code>exit(EXIT_SUCCESS);</code> in the middle of <code>main()</code>.</li>
<li><code>/* NOTREACHED */</code> is a lint directive that I like.</li>
<li><code>return EXIT_SUCCESS;</code> at the end of functions that return <code>int</code>.</li>
<li>Explicitly cast implicit type conversions.</li>
</ul>
<p>The command-line signature for this program if it were compiled would
look something like:</p>
<div class="highlight"><pre><span></span>$ ./a.out -h
a.out <span class="o">[</span>-v<span class="o">]</span> <span class="o">[</span>-f hexflag<span class="o">]</span> <span class="o">[</span>-i inputfile<span class="o">]</span> <span class="o">[</span>-o outputfile<span class="o">]</span> <span class="o">[</span>-h<span class="o">]</span>
</pre></div>
<p>In fact, that’s what <code>usage()</code> will emit to <code>stderr</code> once compiled.</p>
<h3><strong>8 Function Declarations</strong></h3>
<div class="highlight"><pre><span></span><span class="cm">/* main.c */</span>
<span class="o"><</span><span class="p">...</span><span class="o">></span>
<span class="kt">void</span> <span class="n">usage</span><span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="n">progname</span><span class="p">,</span> <span class="kt">int</span> <span class="n">opt</span><span class="p">)</span> <span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="n">USAGE_FMT</span><span class="p">,</span> <span class="n">progname</span><span class="o">?</span><span class="nl">progname</span><span class="p">:</span><span class="n">DEFAULT_PROGNAME</span><span class="p">);</span>
<span class="n">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
<span class="cm">/* NOTREACHED */</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="n">do_the_needful</span><span class="p">(</span><span class="n">options_t</span> <span class="o">*</span><span class="n">options</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">options</span><span class="p">)</span> <span class="p">{</span>
<span class="n">errno</span> <span class="o">=</span> <span class="n">EINVAL</span><span class="p">;</span>
<span class="k">return</span> <span class="n">EXIT_FAILURE</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">options</span><span class="o">-></span><span class="n">input</span> <span class="o">||</span> <span class="o">!</span><span class="n">options</span><span class="o">-></span><span class="n">output</span><span class="p">)</span> <span class="p">{</span>
<span class="n">errno</span> <span class="o">=</span> <span class="n">ENOENT</span><span class="p">;</span>
<span class="k">return</span> <span class="n">EXIT_FAILURE</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/* XXX do needful stuff */</span>
<span class="k">return</span> <span class="n">EXIT_SUCCESS</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>And now, finally, we write functions that aren’t boilerplate. In this
example, function <code>do_the_needful()</code> accepts a pointer to an
<code>options_t</code> structure. We validate that the <code>options</code> pointer is not
<span class="caps">NULL</span> and then go on to validate the <code>input</code> and <code>output</code> structure
members. We return EXIT_FAILURE if either test fails, and signal to
the caller a general reason by setting the external global variable
<code>errno</code> to a conventional error code. The convenience function
<code>perror()</code> can be used by the caller to emit human-readable-ish error
messages based on the value of <code>errno</code>.</p>
<p>Functions should almost always validate their input in some way. If
full validation is expensive, try to do it once and treat the
validated data as immutable. In the <code>usage()</code> function, we validate
the <code>progname</code> argument using a conditional assignment in the
<code>fprintf()</code> call. The <code>usage()</code> function is going to exit anyway, so I
don’t bother setting <code>errno</code> or making a big stink about using a
correct program name.</p>
<p>The big class of errors we are trying to avoid here is dereferencing a
<span class="caps">NULL</span> pointer. This will cause the operating system to send a special
signal to our process called <code>SYSSEGV</code> which results in unavoidable
death. The last thing your users want to see is a crash due to
<span class="caps">SYSSEGV</span>. It’s much better to catch a <span class="caps">NULL</span> pointer so you can emit
better error messages and shutdown the program gracefully.</p>
<p>Some people complain about having multiple <code>return</code> statements in a
function body. They make arguments about continuity of control-flow
and other stuff. Honestly, if the something goes wrong in the middle
of a function, it’s a good time to return an error condition. Writing
a ton of nested <code>if</code> statements just have one return is never a “good idea”™.</p>
<p>Finally, if you write a function that takes four or more arguments
consider bundling those arguments in a structure and passing a pointer
to the structure. This makes the function signatures simpler, making
them easier to remember and not screw up when you call them later. It
also makes calling the function slightly faster since fewer things
need to be copied into the function’s stack frame. In practice, this
will only become a consideration if the function is called millions or
billions of times. Don’t worry about it if that doesn’t make sense.</p>
<h3><strong>Wait, You Said No Comments!?!!</strong></h3>
<p>In the <code>do_the_needful()</code> function I wrote a specific type of comment
that is designed to be a placeholder rather than document the code.</p>
<div class="highlight"><pre><span></span><span class="cm">/* XXX do needful stuff */</span>
</pre></div>
<p>When you are in the zone, sometimes you don’t want to stop and write
some particularly gnarly bit of code. You’ll come back and do it
later, just not now. That’s where I’ll leave myself a little
breadcrumb. I insert a commment with a ‘<span class="caps">XXX</span>’ prefix and a short
remark describing what needs doing. Later on when I have more time,
I’ll grep thru source looking for <span class="caps">XXX</span>. It doesn’t matter what you
use, just make sure it’s not likely to show up in your code base
in another context; function name or variable for instance.</p>
<h3><strong>Putting It All Together</strong></h3>
<p>Ok, this progam <em>still</em> does almost nothing when you compile and run
it. But now you have a solid skeleton to build your own command-line
parsing <code>C</code> programs.</p>
<div class="highlight"><pre><span></span><span class="cm">/* main.c - the complete listing */</span>
<span class="cp">#include</span> <span class="cpf"><stdio.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><stdlib.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><unistd.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><libgen.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><errno.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><string.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><getopt.h></span><span class="cp"></span>
<span class="cp">#define OPTSTR "vi:o:f:h"</span>
<span class="cp">#define USAGE_FMT "%s [-v] [-f hexflag] [-i inputfile] [-o outputfile] [-h]"</span>
<span class="cp">#define ERR_FOPEN_INPUT "fopen(input, r)"</span>
<span class="cp">#define ERR_FOPEN_OUTPUT "fopen(output, w)"</span>
<span class="cp">#define ERR_DO_THE_NEEDFUL "do_the_needful blew up"</span>
<span class="cp">#define DEFAULT_PROGNAME "george"</span>
<span class="k">extern</span> <span class="kt">int</span> <span class="n">errno</span><span class="p">;</span>
<span class="k">extern</span> <span class="kt">char</span> <span class="o">*</span><span class="n">optarg</span><span class="p">;</span>
<span class="k">extern</span> <span class="kt">int</span> <span class="n">opterr</span><span class="p">,</span> <span class="n">optind</span><span class="p">;</span>
<span class="k">typedef</span> <span class="k">struct</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">verbose</span><span class="p">;</span>
<span class="kt">uint32_t</span> <span class="n">flags</span><span class="p">;</span>
<span class="kt">FILE</span> <span class="o">*</span><span class="n">input</span><span class="p">;</span>
<span class="kt">FILE</span> <span class="o">*</span><span class="n">output</span><span class="p">;</span>
<span class="p">}</span> <span class="n">options_t</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">dumb_global_variable</span> <span class="o">=</span> <span class="o">-</span><span class="mi">11</span><span class="p">;</span>
<span class="kt">void</span> <span class="nf">usage</span><span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="n">progname</span><span class="p">,</span> <span class="kt">int</span> <span class="n">opt</span><span class="p">);</span>
<span class="kt">int</span> <span class="nf">do_the_needful</span><span class="p">(</span><span class="n">options_t</span> <span class="o">*</span><span class="n">options</span><span class="p">);</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[])</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">opt</span><span class="p">;</span>
<span class="n">options_t</span> <span class="n">options</span> <span class="o">=</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">,</span> <span class="n">stdin</span><span class="p">,</span> <span class="n">stdout</span> <span class="p">};</span>
<span class="n">opterr</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">while</span> <span class="p">((</span><span class="n">opt</span> <span class="o">=</span> <span class="n">getopt</span><span class="p">(</span><span class="n">argc</span><span class="p">,</span> <span class="n">argv</span><span class="p">,</span> <span class="n">OPTSTR</span><span class="p">))</span> <span class="o">!=</span> <span class="n">EOF</span><span class="p">)</span>
<span class="k">switch</span><span class="p">(</span><span class="n">opt</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="sc">'i'</span><span class="o">:</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">options</span><span class="p">.</span><span class="n">input</span> <span class="o">=</span> <span class="n">fopen</span><span class="p">(</span><span class="n">optarg</span><span class="p">,</span> <span class="s">"r"</span><span class="p">))</span> <span class="p">){</span>
<span class="n">perror</span><span class="p">(</span><span class="n">ERR_FOPEN_INPUT</span><span class="p">);</span>
<span class="n">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
<span class="cm">/* NOTREACHED */</span>
<span class="p">}</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="sc">'o'</span><span class="o">:</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">options</span><span class="p">.</span><span class="n">output</span> <span class="o">=</span> <span class="n">fopen</span><span class="p">(</span><span class="n">optarg</span><span class="p">,</span> <span class="s">"w"</span><span class="p">))</span> <span class="p">){</span>
<span class="n">perror</span><span class="p">(</span><span class="n">ERR_FOPEN_OUTPUT</span><span class="p">);</span>
<span class="n">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
<span class="cm">/* NOTREACHED */</span>
<span class="p">}</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="sc">'f'</span><span class="o">:</span>
<span class="n">options</span><span class="p">.</span><span class="n">flags</span> <span class="o">=</span> <span class="p">(</span><span class="kt">uint32_t</span> <span class="p">)</span><span class="n">strtoul</span><span class="p">(</span><span class="n">optarg</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="mi">16</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="sc">'v'</span><span class="o">:</span>
<span class="n">options</span><span class="p">.</span><span class="n">verbose</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="sc">'h'</span><span class="o">:</span>
<span class="k">default</span><span class="o">:</span>
<span class="n">usage</span><span class="p">(</span><span class="n">basename</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="n">opt</span><span class="p">);</span>
<span class="cm">/* NOTREACHED */</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">do_the_needful</span><span class="p">(</span><span class="o">&</span><span class="n">options</span><span class="p">)</span> <span class="o">!=</span> <span class="n">EXIT_SUCCESS</span><span class="p">)</span> <span class="p">{</span>
<span class="n">perror</span><span class="p">(</span><span class="n">ERR_DO_THE_NEEDFUL</span><span class="p">);</span>
<span class="n">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
<span class="cm">/* NOTREACHED */</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">EXIT_SUCCESS</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">usage</span><span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="n">progname</span><span class="p">,</span> <span class="kt">int</span> <span class="n">opt</span><span class="p">)</span> <span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="n">USAGE_FMT</span><span class="p">,</span> <span class="n">progname</span><span class="o">?</span><span class="nl">progname</span><span class="p">:</span><span class="n">DEFAULT_PROGNAME</span><span class="p">);</span>
<span class="n">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
<span class="cm">/* NOTREACHED */</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="nf">do_the_needful</span><span class="p">(</span><span class="n">options_t</span> <span class="o">*</span><span class="n">options</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">options</span><span class="p">)</span> <span class="p">{</span>
<span class="n">errno</span> <span class="o">=</span> <span class="n">EINVAL</span><span class="p">;</span>
<span class="k">return</span> <span class="n">EXIT_FAILURE</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">options</span><span class="o">-></span><span class="n">input</span> <span class="o">||</span> <span class="o">!</span><span class="n">options</span><span class="o">-></span><span class="n">output</span><span class="p">)</span> <span class="p">{</span>
<span class="n">errno</span> <span class="o">=</span> <span class="n">ENOENT</span><span class="p">;</span>
<span class="k">return</span> <span class="n">EXIT_FAILURE</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/* XXX do needful stuff */</span>
<span class="k">return</span> <span class="n">EXIT_SUCCESS</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>Using Pelican to Publish Your Blog on GitHub2018-10-05T00:00:00-05:002018-10-05T00:00:00-05:00ejotag:jnyjny.github.io,2018-10-05:/using-pelican-to-publish-your-blog-on-github.html<p>How to use pelican to publish a blog on GitHub.</p><h3><strong>If You’ve Got a GitHub Account, You Can Have a Blog!</strong></h3>
<p><a href="https://github.com/">GitHub.com</a> is a hugely popular source code control web service
that uses <a href="https://git-scm.com">git</a> to synchronize local files with copies kept on
GitHub’s servers. This lets you easily share and back up your work.
For the purposes of this article I’ll assume that you have a GitHub
account, are comfortable with basic git commands and want a blog to
call your own using Pelican.</p>
<p>In addition to it’s repository user interface, GitHub also enables
users to <a href="https://help.github.com/categories/GitHub-pages-basics/">publish web pages</a> of their own directly from a
repository. The web site generation package that GitHub recommends is
<a href="https://jekyllrb.com">Jekyll</a>, written in Ruby. Since I’m a bigger fan of <a href="https://python.org">Python</a>, I
went with <a href="https://blog.getpelican.com">Pelican</a> instead.</p>
<p>I’ll describe how to install Pelican, set up your GitHub repository
and publish your first article. </p>
<h3><strong>The Basics</strong></h3>
<p>Pelican and Jekyll both transform content written in <a href="https://guides.github.com/features/mastering-markdown">Markdown</a> or
<a href="http://docutils.sourceforge.net/docs/user/rst/quickref.html">ReStructured Text</a> into <span class="caps">HTML</span> and generate a static web site. Both
generators support themes which allow for infinite amounts of
customization. We’ll install pelican, run a quick start helper, write
some Markdown files and then publish our website to GitHub.</p>
<p>Easy peasy.</p>
<h3><strong>Installing Pelican <span class="amp">&</span> Creating the Repo</strong></h3>
<p>First things first, you need pelican (and ghp-import) installed on
your local machine. This is super easy with the pip, the python package
installation tool (you have pip right?):</p>
<div class="highlight"><pre><span></span>$ pip install pelican ghp-import
</pre></div>
<p>Next, open up a browser and create a new repository on GitHub for your
new sweet blog. Name it as follows (use your GitHub user name):</p>
<div class="highlight"><pre><span></span>https://GitHub.com/username/username.github.io
</pre></div>
<p>and leave it empty, we will fill it up with compelling blog content in
a second.</p>
<p>Using a command-line (you command-line right?), clone your empty git
repository to your local machine:</p>
<div class="highlight"><pre><span></span>$ git clone https://GitHub.com/username/username.github.io blog
$ <span class="nb">cd</span> blog
</pre></div>
<h3><strong>That One Weird Trick…</strong></h3>
<p>Now here’s the trick with publishing web content on GitHub which isn’t
super obvious. For user pages, pages hosted in repos named
<em>username.github.io</em>, the content is served from the <code>master</code> branch.</p>
<p>I strongly prefer to not keep all the pelican configuration files
and raw Markdown files in <code>master</code>, just the web content. So I keep
the pelican configuration and the raw content in a seperate branch
that I like to call ‘content’. You can call it whatever you want, but
I’ll just assume you called it content too. I like this organization
since I can completely throw away all the files in <code>master</code> and
re-populate it with the <code>content</code> branch.</p>
<div class="highlight"><pre><span></span>$ git checkout -b content
Switched to a new branch <span class="s1">'content'</span>
</pre></div>
<h3><strong>Configuring Pelican</strong></h3>
<p>Now, here comes the content configuration. Pelican provides a great
initialization tool called ‘pelican-quickstart’ that will ask you a
series of questions about your blog.</p>
<div class="highlight"><pre><span></span>$ pelican-quickstart
Welcome to pelican-quickstart v3.7.1.
This script will <span class="nb">help</span> you create a new Pelican-based website.
Please answer the following questions so this script can generate the files
needed by Pelican.
> Where <span class="k">do</span> you want to create your new web site? <span class="o">[</span>.<span class="o">]</span>
> What will be the title of this web site? Super blog
> Who will be the author of this web site? username
> What will be the default language of this web site? <span class="o">[</span>en<span class="o">]</span>
> Do you want to specify a URL prefix? e.g., http://example.com <span class="o">(</span>Y/n<span class="o">)</span> n
> Do you want to <span class="nb">enable</span> article pagination? <span class="o">(</span>Y/n<span class="o">)</span>
> How many articles per page <span class="k">do</span> you want? <span class="o">[</span><span class="m">10</span><span class="o">]</span>
> What is your <span class="nb">time</span> zone? <span class="o">[</span>Europe/Paris<span class="o">]</span> US/Central
> Do you want to generate a Fabfile/Makefile to automate generation and publishing? <span class="o">(</span>Y/n<span class="o">)</span> y
> Do you want an auto-reload <span class="p">&</span> simpleHTTP script to assist with theme and site development? <span class="o">(</span>Y/n<span class="o">)</span> y
> Do you want to upload your website using FTP? <span class="o">(</span>y/N<span class="o">)</span> n
> Do you want to upload your website using SSH? <span class="o">(</span>y/N<span class="o">)</span> n
> Do you want to upload your website using Dropbox? <span class="o">(</span>y/N<span class="o">)</span> n
> Do you want to upload your website using S3? <span class="o">(</span>y/N<span class="o">)</span> n
> Do you want to upload your website using Rackspace Cloud Files? <span class="o">(</span>y/N<span class="o">)</span> n
> Do you want to upload your website using GitHub Pages? <span class="o">(</span>y/N<span class="o">)</span> y
> Is this your personal page <span class="o">(</span>username.github.io<span class="o">)</span>? <span class="o">(</span>y/N<span class="o">)</span> y
Done. Your new project is available at /Users/username/blog
</pre></div>
<p>The only questions I didn’t take the defaults on were:</p>
<ul>
<li>web site title</li>
<li>web site author</li>
<li>time zone</li>
<li>upload to GitHub</li>
</ul>
<p>After answering all the questions, pelican leaves the following
offerings in the current directory:</p>
<div class="highlight"><pre><span></span>$ ls
Makefile content/ develop_server.sh*
fabfile.py output/ pelicanconf.py
publishconf.py
</pre></div>
<p>You can go checkout the <a href="https://docs.getpelican.com">Pelican docs</a> to find out how to use
all of those files, but we’re all about getting things down <em>right now</em>.
No, I haven’t read the docs yet either.</p>
<h3><strong>Forging On</strong></h3>
<div class="highlight"><pre><span></span>$ git add .
$ git commit -m <span class="s1">'initial pelican commit to content'</span>
$ git push origin content
</pre></div>
<p>So here we’ve added all the pelican generated files to the <code>content</code>
branch of the local git repo, commited the changes and then pushed the
local changes to the remote repo hosted on GitHub. Not super exciting,
but it will be handy if we need to revert edits to one of these files.</p>
<h3><strong>Finally Getting Somewhere</strong></h3>
<p>Ok, now we get bloggy! All of your blog posts, photos, images, pdfs,
etc will live in the <code>content</code> directory which is initially
empty. I’ll talk you thru creating a first post and an ‘About’ page
with a photo.</p>
<div class="highlight"><pre><span></span>$ <span class="nb">cd</span> content
$ mkdir pages images
$ cp /Users/username/SecretStash/HotPhotoOfMe.jpg images
$ touch first-post.md
$ touch pages/about.md
</pre></div>
<p>Next open the empty file <code>first-post.md</code> in your favorite editor
and add the following text:</p>
<div class="highlight"><pre><span></span><span class="n">title</span><span class="o">:</span> <span class="n">First</span> <span class="n">Post</span> <span class="n">on</span> <span class="n">My</span> <span class="n">Sweet</span> <span class="n">New</span> <span class="n">Blog</span>
<span class="n">date</span><span class="o">:</span> <span class="o"><</span><span class="n">today</span><span class="err">'</span><span class="n">s</span> <span class="n">date</span><span class="o">></span>
<span class="n">author</span><span class="o">:</span> <span class="n">Your</span> <span class="n">Name</span> <span class="n">Here</span>
<span class="err">#</span><span class="n">I</span> <span class="n">am</span> <span class="n">On</span> <span class="n">My</span> <span class="n">Way</span> <span class="n">To</span> <span class="n">Internet</span> <span class="n">Fame</span> <span class="n">and</span> <span class="n">Fortune</span><span class="o">!</span>
<span class="n">This</span> <span class="k">is</span> <span class="n">my</span> <span class="n">first</span> <span class="n">post</span> <span class="n">on</span> <span class="n">my</span> <span class="k">new</span> <span class="n">blog</span><span class="o">.</span> <span class="n">While</span> <span class="n">not</span> <span class="kd">super</span> <span class="n">informative</span> <span class="n">it</span>
<span class="n">should</span> <span class="n">convey</span> <span class="n">my</span> <span class="n">sense</span> <span class="n">of</span> <span class="n">excitement</span> <span class="n">and</span> <span class="n">eagerness</span> <span class="n">to</span> <span class="n">engage</span> <span class="k">with</span> <span class="n">you</span><span class="o">,</span>
<span class="n">the</span> <span class="n">reader</span><span class="o">!</span>
</pre></div>
<p>The first three lines are metadata that pelican uses to organize things. There
are lots of different metadata you can put there, again the docs are your best
bet for learning more about them.</p>
<p>Now we’ll open up the empty file <code>pages/about.md</code> and add this text:</p>
<div class="highlight"><pre><span></span><span class="nl">title</span><span class="p">:</span> <span class="n">About</span>
<span class="nl">date</span><span class="p">:</span> <span class="o"><</span><span class="n">today</span><span class="err">'</span><span class="n">s</span> <span class="n">date</span><span class="o">></span>
<span class="o">!</span><span class="p">[</span><span class="n">So</span> <span class="n">Schmexy</span><span class="p">][</span><span class="n">my_sweet_photo</span><span class="p">]</span>
<span class="n">Hi</span><span class="p">,</span> <span class="n">I</span> <span class="n">am</span> <span class="o"><</span><span class="n">username</span><span class="o">></span> <span class="n">and</span> <span class="n">I</span> <span class="n">wrote</span> <span class="n">this</span> <span class="n">epic</span> <span class="n">collection</span> <span class="n">of</span> <span class="n">Interweb</span>
<span class="n">wisdom</span><span class="p">.</span> <span class="n">In</span> <span class="n">days</span> <span class="n">of</span> <span class="n">yore</span> <span class="n">much</span> <span class="n">of</span> <span class="n">this</span> <span class="n">would</span> <span class="n">have</span> <span class="n">been</span> <span class="n">deemed</span> <span class="n">sorcery</span>
<span class="n">and</span> <span class="n">I</span> <span class="n">would</span> <span class="n">probably</span> <span class="n">have</span> <span class="n">been</span> <span class="n">burned</span> <span class="n">at</span> <span class="n">the</span> <span class="n">stake</span><span class="p">.</span>
<span class="err">😆</span>
<span class="p">[</span><span class="n">my_sweet_photo</span><span class="p">]</span><span class="o">:</span> <span class="p">{</span><span class="n">filename</span><span class="p">}</span><span class="o">/</span><span class="n">images</span><span class="o">/</span><span class="n">HotPhotoOfMe</span><span class="p">.</span><span class="n">jpg</span>
</pre></div>
<p>So now we have three new pieces of web content in our content
directory. Of the content branch. That’s a lot of content.</p>
<h3><strong>Publishing</strong></h3>
<p>Don’t worry, the pay off is coming!</p>
<p>All that’s left to do is:</p>
<ul>
<li>Run pelican to generate the static <span class="caps">HTML</span> files in <code>output</code>:</li>
</ul>
<div class="highlight"><pre><span></span> $ pelican content -o output -s publishconf.py
</pre></div>
<ul>
<li>Use <code>ghp-import</code> to add the contents of the output directory to the <code>master</code> branch:</li>
</ul>
<div class="highlight"><pre><span></span> $ ghp-import -m <span class="s2">"Generate Pelican site"</span> --no-jekyll -b master output
</pre></div>
<ul>
<li>Push the local master branch to the remote repo:</li>
</ul>
<div class="highlight"><pre><span></span> $ git push origin master
</pre></div>
<ul>
<li>Commit and push the new content to the ‘content’ branch:</li>
</ul>
<div class="highlight"><pre><span></span> $ git add content
$ git commit -m <span class="s1">'added a first post, a photo and an about page'</span>
$ git push origin content
</pre></div>
<h3><strong><span class="caps">OMG</span> I Did It!</strong></h3>
<p>Now the exciting part is here, when you get to see what you’ve
published for everyone to see! Type into your browser the <span class="caps">URL</span>:</p>
<div class="highlight"><pre><span></span>https://username.github.io
</pre></div>
<p>Congratulations on your new blog, self-published on GitHub!</p>A Short Primer on Assembers, Compilers and Interpreters2018-10-03T00:00:00-05:002018-10-03T00:00:00-05:00ejotag:jnyjny.github.io,2018-10-03:/a-short-primer-on-assembers-compilers-and-interpreters.html<p>A gentle introduction to the historical evolution of programming practices.</p><h2><strong>Beginnings</strong></h2>
<p>In the early days of computing, hardware was expensive and programmers
were cheap. In fact, programmers were so cheap they weren’t even
called “programmers” and were in fact usually mathematicans or
electrical engineers. Early computers were used to solve complex
mathematical problems quickly, so mathematicans were a natural fit for
the job of “programming”.</p>
<p>First a little background on what a program is.</p>
<p>Computers can’t do anything by themselves, they require programs to
drive their behavior. Programs can be thought of as very detailed
recipes that take an input and produce an output. The steps in the
recipe are composed of instructions that operate on data. While that
sounds complicated, you probably know how this statement works:</p>
<p>1 + 2 = 3</p>
<p>The plus sign is the “instruction” while the numbers 1 and 2 are the
data. Mathematically, the equal sign indicates that both sides of an
equation are “equivalent”, however most computer languages use some
variant of equals to mean “assignment”. If a computer were executing
that statment, it would store the results of the addition, the “3”,
somewhere in memory.</p>
<p>Computers know how to do math with numbers and move data around the
machine’s memory heirarchy. I won’t say too much about memory except
to say it generally comes in two different flavors: fast/small, and
slow/big. <span class="caps">CPU</span> registers are very fast, very small and act as
scratch pads. Main memory is typically very big and not nearly as
fast as register memory. CPUs shuffle the data they are working with
from main memory to registers and back again while a program executes.</p>
<h2><strong>Assembler</strong></h2>
<p>Computers were very expensive and people were cheap. Programmers spent
endless hours translating hand written math into computer instructions
that the computer could execute. The very first computers had terrible
user interfaces, some only consisting of toggle switches on the front
panel. The switches represented 1s and 0s in a single “word” of
memory. The programmer would configure a word, indicate where to store
it and then commit the word to memory. It was time consuming and error prone.</p>
<p>Eventually, an <a href="https://en.wikipedia.org/wiki/Nathaniel_Rochester_%28computer_scientist%29">electrical engineer</a> decided his time wasn’t cheap
and wrote a program whose input was a recipe expressed in terms people
could read and output a computer readable version. This was the first
“assembler” and it was very controversial. The people that owned the
expensive machines didn’t want to “waste” compute time on a task that
people were already doing; albeit slowly and with errors. Over time,
people came to appreciate the speed and accuracy of the assembler
versus a hand-assembled program and the amount of “real work” done with
the computer increased.</p>
<p>While assembler programs were a big step up from toggling bit patterns
into the front panel of a machine, they were still pretty specialized.
The addition example from above might have looked something like this:</p>
<div class="highlight"><pre><span></span> <span class="err">01</span> <span class="nf">MOV</span> <span class="no">R0</span><span class="p">,</span> <span class="mi">1</span>
<span class="err">02</span> <span class="nf">MOV</span> <span class="no">R1</span><span class="p">,</span> <span class="mi">2</span>
<span class="err">03</span> <span class="nf">ADD</span> <span class="no">R0</span><span class="p">,</span> <span class="no">R1</span><span class="p">,</span> <span class="no">R2</span>
<span class="err">04</span> <span class="nf">MOV</span> <span class="mi">64</span><span class="p">,</span> <span class="no">R0</span>
<span class="err">05</span> <span class="nf">STO</span> <span class="no">R2</span><span class="p">,</span> <span class="no">R0</span>
</pre></div>
<p>Each line is a computer instruction, beginning with a shorthand name
of the instruction followed by the data the instruction works on. This
little program will first “move” the value 1 into a register called
R0, then 2 into register R1. Line 03 adds the contents of registers R0
and R1 and stores the resulting value into register R2. Finally, lines
04 and 05 identify where the result should be stored in main memory
(address 64). Mananaging where data is stored in memory is one of the
most time consuming and error-prone parts of writing computer programs.</p>
<h2><strong>Compiler</strong></h2>
<p>Assembly was much better than writing computer instructions by hand,
however early programmers yearned to write programs like they were
accustomed to writing mathematical formulae. This drove the
development of higher level compiled languages, some of which are
historical footnotes and others are still in use today. <a href="https://en.wikipedia.org/wiki/ALGO">Algo</a> is
one such footnote, while real problems continue to be solved today
with languages like <a href="https://en.wikipedia.org/wiki/Fortran"><span class="caps">FORTRAN</span></a> and <a href="https://en.wikipedia.org/wiki/C_(programming_language)">C</a>.</p>
<p>These new “high level” langagues allowed programmers to write their
programs in simpler terms. In the C language, our addition assembly
program would be written as:</p>
<div class="highlight"><pre><span></span> <span class="kt">int</span> <span class="n">x</span><span class="p">;</span>
<span class="n">x</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">+</span> <span class="mi">2</span><span class="p">;</span>
</pre></div>
<p>The first statement describes a piece of memory that the program
will use. In this case, the memory should be the size of an integer
and it’s name is ‘x’. The second statement is the addition, although
written “backwards”. A C programmer would read that as “X is assigned
the result of one plus two”. Notice the programmer doesn’t need to
say where to put ‘x’ in memory, the compiler takes care of that.</p>
<p>A new type of program, called a “compiler”, would turn the program
written in a high level language into an assembly language version and
then finally run it thru the assembler to produce a machine-readable
version of the program. This composition of programs is often called a
“tool chain”, in that one program’s output is sent directly to another
program’s input.</p>
<p>The huge advantage of compiled languages over assembly language
programs was porting from one computer model or brand to another. In
the early days of computing there was an explosion of different types
of computing hardware from companies like <span class="caps">IBM</span>, Digital Equipment
Corporation, Texas Instruments, <span class="caps">UNIVAC</span>, Hewlet Packard and others.
None of these computers shared much in common besides needing to be
plugged in to an electrical power supply. Memory and <span class="caps">CPU</span> architectures
differed wildly and it often took man-years to translate programs from
one computer to another.</p>
<p>With high level languages, it was only necessary to port the compiler
tool chain to the new platfrom. Once the compiler was available, high
level language programs could be re-compiled for the new computer with
little or no modification. Compliation of high level languages was
truly revolutionary.</p>
<p>Life was very good now for programmers. It was much easier to express
the problems they wanted to solve using high level languages. The cost
of computer hardware was falling dramatically due to advances in
semiconductors and the invention of integrated chips. Computers were
getting faster and more capable in addition to become much less
expensive. At some point, in the late 80s possibly, there was an
inversion and programmers became more expensive than the hardware they used.</p>
<h2><strong>Interpreter</strong></h2>
<p>Over time a new programming model arose where a special program
called an “interpreter” would read a program and turn it into computer
instructions to be executed immediately. The interpreter takes the
program as input and interprets it into an intermediate form, much
like a compiler. Unlike a compiler, the interpreter then executes the
intermediate form of the program. This happens every time an interpreted
program runs, whereas a compiled program is only compiled one time and
the computer only has to execute the machine instructions “as written”.</p>
<p>As a sidenote, when people say that “interpreted programs are slow”,
that is the main source of the perceived lack of performance. Modern
computers are so amazingly capable that most people aren’t usually
able to tell the difference between compiled and interpreted programs.</p>
<p>Interpreted programs, sometimes called “scripts”, are even easier to
port to different hardware platforms. Because the script doesn’t
contain any machine specific instructions, a single version of a
program can run on many different computers without change. The
catch of course is the interpreter must be ported to the new machine
to make that possible.</p>
<p>One example of a very popular interpreted language is <a href="https://python.org">Python</a>. A
complete python expression of our addition problem would be:</p>
<div class="highlight"><pre><span></span> <span class="n">x</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">+</span> <span class="mi">2</span>
</pre></div>
<p>While it looks and acts much like the C version, it lacks the variable
initialization statement. There are other differences which are beyond
the scope of this article, but you can see that we are able to write a
computer program that is very close to how a mathematician would write
it by hand with pencil and paper.</p>