Began time estimates for first two sections

This also contains some minor tweaks.
master
Mike Gerwitz 2019-03-12 00:35:14 -04:00
parent 4f76c5c76f
commit 87ec000101
Signed by: mikegerwitz
GPG Key ID: 8C917B7F5DC51BA2
1 changed files with 175 additions and 156 deletions

View File

@ -120,7 +120,7 @@
#+BEGIN: columnview :hlines 2 :maxlevel 3 :indent t :id slides
| ITEM | DURATION | TODO | ENVIRONMENT |
|---------------------------------------------------+----------+--------+-------------|
| Slides | 1:00:00 | DEVOID | |
| Slides | 0:23:54 | DEVOID | |
|---------------------------------------------------+----------+--------+-------------|
| \_ Summary | | | |
|---------------------------------------------------+----------+--------+-------------|
@ -130,36 +130,36 @@
|---------------------------------------------------+----------+--------+-------------|
| \_ Practical Freedom | | DEVOID | fullframe |
|---------------------------------------------------+----------+--------+-------------|
| \_ Practical Example: Web Browser | 1:00 | RAW | |
| \_ Practical Example: Web Browser | 0:09:32 | DRAFT | |
| \_ Browser Topics | | | |
| \_ Example: Web Browser | 1:00 | RAW | frame |
| \_ Finding Text (Mouse-Driven GUI Interaction) | | RAW | frame |
| \_ GUIs Change Over Time | | RAW | frame |
| \_ Ctrl+F---Just Works | | RAW | frame |
| \_ Muscle Memory | | RAW | fullframe |
| \_ A Research Task | | RAW | fullframe |
| \_ Executing the Research Task | | RAW | frame |
| \_ GUIs of a Feather | | RAW | fullframe |
| \_ Macro-Like Keyboard Instructions | | RAW | fullframe |
| \_ Example: Web Browser | 0:00:40 | DRAFT | frame |
| \_ Finding Text (Mouse-Driven GUI Interaction) | 0:01:39 | DRAFT | frame |
| \_ GUIs Change Over Time | 0:00:45 | DRAFT | frame |
| \_ Ctrl+F---Just Works | 0:00:25 | DRAFT | frame |
| \_ Muscle Memory | 0:00:40 | DRAFT | fullframe |
| \_ A Research Task | 0:00:25 | DRAFT | fullframe |
| \_ Executing the Research Task | 0:03:00 | DRAFT | frame |
| \_ GUIs of a Feather | 0:00:40 | DRAFT | fullframe |
| \_ Macro-Like Keyboard Instructions | 0:01:19 | DRAFT | fullframe |
|---------------------------------------------------+----------+--------+-------------|
| \_ A New Perspective | | DEVOID | |
| \_ A New Perspective | 0:14:22 | DRAFT | |
| \_ Perspective Topics | | | |
| \_ Secrets? | | RAW | fullframe |
| \_ Lifting the Curtain | | RAW | frame |
| \_ Web Page Source Code | | RAW | block |
| \_ Text | | RAW | fullframe |
| \_ Text is a Universal Interface | | RAW | fullframe |
| \_ The Shell Command Prompt | | RAW | frame |
| \_ Eliminating the Web Browser | | RAW | frame |
| \_ Browser vs. =wget= Comparison | | RAW | frame |
| \_ Finding Text on the Command Line | | RAW | frame |
| \_ A More Gentle Reply | | RAW | frame |
| \_ Writing to Files (Redirection) | | RAW | frame |
| \_ Starting Our List | | RAW | fullframe |
| \_ Command Refactoring | | RAW | fullframe |
| \_ Again: Text is a Universal Interface | | RAW | againframe |
| \_ Pipelines | | RAW | fullframe |
| \_ Summary of the Unix Philosophy | | RAW | fullframe |
| \_ Secrets? | 0:01:19 | DRAFT | fullframe |
| \_ Lifting the Curtain | 0:01:00 | DRAFT | frame |
| \_ Web Page Source Code | 0:00:35 | DRAFT | block |
| \_ Text | 0:00:35 | DRAFT | fullframe |
| \_ Text is a Universal Interface | 0:01:19 | DRAFT | fullframe |
| \_ The Shell Command Prompt | 0:00:45 | DRAFT | frame |
| \_ Eliminating the Web Browser | 0:01:00 | DRAFT | frame |
| \_ Browser vs. =wget= Comparison | 0:00:40 | DRAFT | frame |
| \_ Finding Text on the Command Line | 0:01:00 | DRAFT | frame |
| \_ A More Gentle Reply | 0:01:00 | DRAFT | frame |
| \_ Writing to Files (Redirection) | 0:00:55 | DRAFT | frame |
| \_ Starting Our List | 0:01:10 | DRAFT | fullframe |
| \_ Command Refactoring | 0:02:00 | DRAFT | fullframe |
| \_ Again: Text is a Universal Interface | 0:00:20 | DRAFT | againframe |
| \_ Pipelines | 0:00:15 | DRAFT | fullframe |
| \_ Summary of the Unix Philosophy | 0:00:30 | DRAFT | fullframe |
|---------------------------------------------------+----------+--------+-------------|
| \_ Thank You | 00:00:01 | | fullframe |
#+END:
@ -215,7 +215,7 @@ Choreographed Workflows
Practical Freedom
** RAW Practical Example: Web Browser [0/9]
** DRAFT Practical Example: Web Browser [0/9]
*** Browser Topics [3/3] :noexport:
This example is the main segue from GUIs into the utility of keybindings
into shell, so it has to be compelling. I chose something that is
@ -255,11 +255,9 @@ frequently done by users: visiting webpages and searching for text.
text editor.
- [X] But what if I had 10? 100? 1000? This is still tedious and slow.
*** RAW Example: Web Browser :B_frame:
*** DRAFT Example: Web Browser :B_frame:
:PROPERTIES:
:BEAMER_env: frame
:DURATION: 1:00
:END:
[[file:images/web-browser.png]]
@ -267,6 +265,7 @@ frequently done by users: visiting webpages and searching for text.
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:00:40
:END:
One of the only GUIs I use on a day-to-day basis is my web browser.
@ -278,28 +277,15 @@ This is a screenshot of an admittedly staged session,
Perhaps most prominent is Tree-Style Tab,
which displays tabs in a hierarchy off to the left rather than flatly at
the top.
I find this visual enhancement very useful when I have dozens or hundreds of
tabs open.
There are text-mode web browsers,
and I do occasionally use them.
But it provides a very different experience.
I don't want to spend too much time on my rationale,
which as a professional web developer and activist focused on privacy and
security run quite deep.
For the sake of this talk,
let's just recognize that most people who browse the internet use a
graphical web browser;
that's a simple fact.
I chose a web browser as an example because I feel that it's something that
most everyone can relate to using,
I chose a graphical web browser as an example because I feel that it's
something that most everyone can relate to using,
and most everyone can recognize the utility in---most
people using Internet-connected devices use one at least a few
times a week,
if not every day.
*** RAW Finding Text (Mouse-Driven GUI Interaction) :B_frame:
*** DRAFT Finding Text (Mouse-Driven GUI Interaction) :B_frame:
:PROPERTIES:
:BEAMER_env: frame
:END:
@ -330,12 +316,14 @@ I chose a web browser as an example because I feel that it's something that
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:01:40
:END:
The Web is used for many different things today,
but its original purpose is to render documents.
Take Wikipedia for instance.
Or the LibrePlanet conference website.
If you are looking for something specific on a page,
a common operation is to search for a word or phrase,
like shown here.
@ -374,7 +362,7 @@ Further,
what do you call the bar at the bottom of the page?
You have to describe it in a way that reproduces what the user sees.
*** RAW GUIs Change Over Time :B_frame:
*** DRAFT GUIs Change Over Time :B_frame:
:PROPERTIES:
:BEAMER_env: frame
:END:
@ -408,11 +396,12 @@ Ctrl+F
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:00:45
:END:
Another difficult thing is: GUIs change over time.
I'm sure there are people here who remember earlier versions of Firefox that
didn't have the hamburger menu,
I'm sure many people here remember earlier versions of Firefox that didn't
have the hamburger menu,
where the Find menu option was in the Edit menu.
By the way,
those old menus do still exist if you hit Alt.
@ -429,8 +418,7 @@ There's something that /hasn't/ changed over time---something
that has been the same for /decades/!
=Ctrl+F=.
*** RAW Ctrl+F---Just Works :B_frame:
*** DRAFT Ctrl+F---Just Works :B_frame:
:PROPERTIES:
:BEAMER_env: frame
:END:
@ -442,22 +430,22 @@ There's something that /hasn't/ changed over time---something
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:00:25
:END:
When you type =Ctrl+F=,
it immediately opens that search bar and gives focus to the textbox,
so you can just start typing.
Further,
it works /in any browser/.
it works /in all major browsers/.
Not only that,
but =Ctrl+F= is so universal that it works /in nearly every GUI program that
offers some type of search/!
And it's /context-sensitive/!
The program will just Do The Right Thing depending on where you are or what
you're doing.
it is that you're doing.
*** RAW Muscle Memory :B_fullframe:
*** DRAFT Muscle Memory :B_fullframe:
:PROPERTIES:
:BEAMER_env: fullframe
:END:
@ -472,6 +460,7 @@ Visual \Rightarrow Tactile
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:00:40
:END:
But there's something more profound that has happened here,
@ -480,14 +469,15 @@ We have switched our mode of interaction.
With a mouse and a GUI,
interaction is driven by visual indicators.
The position of your hand isn't meaningful,
because your mouse cursor could be anywhere on the screen at any given
time;
your eyes provide the context.
It's hard to use a GUI with your eyes closed.
The position of your hand on the mousepad or your fingers on a touchpad
isn't meaningful,
because your mouse cursor could be anywhere on the screen at any given
time;
your /eyes/ provide the context.
It's hard to use a GUI with your eyes closed while using a mouse.
But by hitting =Ctrl+F=,
we've completely changed how we interact with the system.
we've completely /changed/ how we interact with the system.
It's now /tactile/.
You associate a finger placement;
a motion;
@ -497,12 +487,12 @@ You associate a finger placement;
You develop muscle memory.
You _can_ trigger this feature with your eyes closed.
/(Repeatedly make motion with hand and fingers like a madman during the
above paragraph.)/
/<Repeatedly make motion with hand and fingers like a madman during the
above paragraph.>/
But that's a pretty trivial example.
*** RAW A Research Task :B_fullframe:
*** DRAFT A Research Task :B_fullframe:
:PROPERTIES:
:BEAMER_env: fullframe
:END:
@ -518,6 +508,7 @@ find all that /do not/ contain ``free software''
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:00:25
:END:
Let's explore a fairly simple research task together.
@ -530,8 +521,7 @@ And I want you to come up with a list of the webpages that /do not/ contain
How might we approach this problem as an average user?
*** RAW Executing the Research Task :B_frame:
*** DRAFT Executing the Research Task :B_frame:
:PROPERTIES:
:BEAMER_env: frame
:END:
@ -562,6 +552,7 @@ _Mouse_
******* Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:01:30
:END:
/(Perhaps I should demonstrate this right away rather than reading through
@ -592,9 +583,10 @@ If we /do not/ see a result,
We then go back to the web browser.
If we /do/ see a result,
we skip copying over the URL.
Then we close the tab by clicking on the `X'.
In either case,
we then close the tab by clicking on the `X'.
We repeat this for each tab,
And then we repeat this for each tab,
until they have all been closed.
When we're done,
whatever is in our text editor is the list of URLs of webpages that do not
@ -606,6 +598,8 @@ Simple enough,
But it's a bit of a pain in the ass.
All this clicking around doesn't really /feel/ like we're melding mind and
machine, does it?
I think you'd be pretty disappointed if /this/ is is the crap that you
attended this session for.
What if we used our =Ctrl+F= trick?
That saves us a couple clicks.
@ -634,6 +628,7 @@ _Keyboard_
******* Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:01:30
:END:
Fortunately we have /many/ more keybindings at our disposal!
@ -681,8 +676,7 @@ We don't have to seek out our actions each time in the GUI---the
operations are always at our fingertips,
literally.
*** RAW GUIs of a Feather :B_fullframe:
*** DRAFT GUIs of a Feather :B_fullframe:
:PROPERTIES:
:BEAMER_env: fullframe
:END:
@ -696,11 +690,12 @@ Browser, Editor, Window Manager, OS, \ldots
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:00:40
:END:
Another powerful benefit of this approach is---these
/same exact keybindings work across most GUIs/!
If we switch out Icecat here with nearly any other web browser,
If we switch out Icecat here with nearly any other major web browser,
and switch out gedit with many other text editors or even word processors,
this will work all the same!
There are some notable text editors for which these keybindings won't work,
@ -708,24 +703,18 @@ There are some notable text editors for which these keybindings won't work,
We'll get to that.
If you use Windows instead of GNU/Linux---which
I discourage, but if you do---then
I strongly discourage, but if you do---then
it'll work the same.
This may not seem like a huge deal,
but it has liberating consequences---users
don't have to learn how to use specific programs to do the job.
I can sit down at a completely different system and let that muscle memory
take over and wind up with the same thing.
I can sit down at a completely different system and let that muscle
memory take over and wind up with the same thing.
It's liberating.
We have started to break free from those choreographed workflows.
Let's look at those keybindings a bit more concisely,
since that last slide was a mess,
to put it nicely.
*** RAW Macro-Like Keyboard Instructions :B_fullframe:
*** DRAFT Macro-Like Keyboard Instructions :B_fullframe:
:PROPERTIES:
:BEAMER_env: fullframe
:END:
@ -749,19 +738,19 @@ Ctrl+W
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:01:20
:END:
If we type out the workflow keybindings like this,
If we type out the keybindings like this,
in an isolated format,
it looks a bit more like instructions for the machine,
doesn't it?
Some of you may be familiar with macros---with
the ability to record keypresses and play them back later.
If we could do that,
If we were able to do that,
then we could fully automate this task away!
Unfortunately,
we can't.
But unfortunately...we can't.
At least,
not with the tools we're using right now.
Why is that?
@ -777,7 +766,7 @@ We also need to know how many times to repeat,
We also need to be able to inspect the email for URLs and copy them into the
web browser.
This also scales poorly.
This also scales really poorly.
While using the keyboard is certainly faster than using the mouse,
we're only dealing with a small set of URLs here.
What if I gave you 100 of them?
@ -787,14 +776,13 @@ Suddenly this doesn't feel like a very efficient way to convey our intent to
the machine.
I don't wish that suffering upon anyone.
And to get around that,
To get around that,
we need to change how we think about our computing a bit.
And that's why I've dragged you through this drawn-out example---to
make sure you understand the significance of these progressive
enhancements to our workflow.
** DEVOID A New Perspective [0/16]
** DRAFT A New Perspective [0/16]
*** Perspective Topics [13/13] :noexport:
- [X] What if I could walk away and get a coffee, play with the kids,
come back and have it done for me?
@ -846,7 +834,7 @@ And that's why I've dragged you through this drawn-out example---to
we can maybe let it run for 10--30s while I blabber on. Depends on
the connection speed at MIT with all the participants.
*** RAW Secrets? :B_fullframe:
*** DRAFT Secrets? :B_fullframe:
:PROPERTIES:
:BEAMER_env: fullframe
:END:
@ -856,6 +844,7 @@ And that's why I've dragged you through this drawn-out example---to
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:01:20
:END:
So what if I told you that,
@ -874,7 +863,7 @@ Some of you are sitting in the audience or watching this remotely rolling
because the answer is obvious to you.
But to those of you who are confined to the toolset that I just
demonstrated...it's
not going to be obvious.
/not/ going to be obvious.
You may still be thinking in terms of that toolset---thinking
of how we can continue to use those same tools.
You don't know what you don't know.
@ -889,7 +878,7 @@ It's because modern interfaces have come to completely mask it or provide
But ``good enough'' is only good enough until it's not.
*** RAW Lifting the Curtain :B_frame:
*** DRAFT Lifting the Curtain :B_frame:
:PROPERTIES:
:BEAMER_env: frame
:END:
@ -911,15 +900,17 @@ But ``good enough'' is only good enough until it's not.
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:01:00
:END:
Let's lift the curtain, so to speak, on what's really going on in the web
browser.
Let's lift the curtain,
so to speak,
on what's really going on in the web browser.
Don't worry,
we're only going to give it a little peek;
nothing too complicated.
Take the LP2019 speaker list page for instance.
Take the LibrePlanet 2019 speaker list page for instance.
If you right-click on my name and click on ``Inspect Element'',
you are presented with the developer tools for this browser which shows
what makes up the webpage.
@ -941,16 +932,14 @@ Now,
technically,
this inspector represents something called the DOM,
which represents the current state of the page.
If it were dynamic,
you'd see this updating.
If the webpage were dynamic,
then you'd see this updating.
We could even change it in here and the page would update.
But you don't need to use a specialized tool to view the structure of the
initial webpage;
I just did that for visualization,
since it conveniently highlights the associated elements on the page
which is useful for demonstration purposes.
I just did this for visualization.
*** RAW Web Page Source Code :B_block:
*** DRAFT Web Page Source Code :B_block:
:PROPERTIES:
:BEAMER_env: block
:END:
@ -979,6 +968,7 @@ But you don't need to use a specialized tool to view the structure of the
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:00:35
:END:
If we instead select "View Page Source" from the context menu,
@ -992,12 +982,13 @@ And as you may have noticed,
Structured, but plain, text.
And as you can see,
if we hit =Ctrl+F=,
``free software'' is there all the same.
We don't need to view the webpage with all its fancy formatting.
For the problem we're trying to solve,
it provides little benefit.
the graphical representation provides little benefit.
*** RAW Text :B_fullframe:
*** DRAFT Text :B_fullframe:
:PROPERTIES:
:BEAMER_env: fullframe
:END:
@ -1008,6 +999,7 @@ Text.
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:00:35
:END:
As we're about to see,
@ -1022,14 +1014,14 @@ But we're still within the web browser.
We don't have to be.
We can copy all of that text and paste it into our editor.
=Ctrl+A Ctrl+C Alt-Tab Ctrl+P=.
=Ctrl+A Ctrl+C Alt-Tab Ctrl+V=.
And sure enough,
search works all the same.
=Ctrl+F= and we can still find ``free software''.
Completely different program,
and we can still find the text using the same keybinding.
*** RAW Text is a Universal Interface :B_fullframe:
*** DRAFT Text is a Universal Interface :B_fullframe:
:PROPERTIES:
:BEAMER_env: fullframe
:END:
@ -1040,6 +1032,7 @@ Text is a Universal Interface
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:01:20
:END:
Text is a universal interface.
@ -1053,9 +1046,6 @@ You can write it down on a paper and type it back into your computer.
Text is how we communicate with one-another as human beings.
But the simplicity of text has practical computational benefits, too.
Let me show you.
Let's save this HTML as a file,
=speakers.html=.
@ -1069,10 +1059,10 @@ But this isn't a talk about web development so I'm not going to go deeper
But if again we opened this HTML file in our text editor,
you would see that same plain text HTML as before;
one just chooses to render it differently than another.
one program just chooses to render it differently than another.
Even though we can view the HTML in our text editor,
we haven't eliminated the web browser yet;
we haven't yet eliminated the web browser;
we still need it to navigate to the webpage and view its source.
But if that's all we're using the web browser for,
then it's one hell of an inefficient way of telling the computer that we
@ -1083,7 +1073,7 @@ Up until this point,
an /alternative/ to something.
Now we're going to venture into a world where it is /the/ interface.
*** RAW The Shell Command Prompt :B_frame:
*** DRAFT The Shell Command Prompt :B_frame:
:PROPERTIES:
:BEAMER_env: frame
:END:
@ -1110,6 +1100,7 @@ output line N
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:00:45
:END:
If you open a terminal,
@ -1121,10 +1112,12 @@ The program that is prompting you for a command is called the /shell/.
The GNU shell is =bash=,
which is the default on most GNU/Linux systems.
It's also the default on Mac OSX,
if you happen to be using that.
if you happen to be using that,
though I recommend against it.
And Windows now has something they call
``Bash on Ubuntu on Windows'',
which is GNU/Linux running atop of the Windows kernel.
Of course a fully free GNU/Linux system is better.
Bash isn't required to run any of the commands I'm presenting as part of
this talk,
@ -1132,7 +1125,7 @@ Bash isn't required to run any of the commands I'm presenting as part of
which I'll note when I do in case you happen to be using a different
shell.
*** RAW Eliminating the Web Browser :B_frame:
*** DRAFT Eliminating the Web Browser :B_frame:
:PROPERTIES:
:BEAMER_env: frame
:END:
@ -1141,7 +1134,7 @@ Bash isn't required to run any of the commands I'm presenting as part of
$ wget https://libreplanet.org/2019/speakers/
#+END_SRC
#+BEAMER: \begin{uncoverenv}<2>
#+BEAMER: \begin{uncoverenv}<2->
#+BEGIN_SRC sh
--2019-03-24 00:00:00-- https://libreplanet.org/2019/speakers/
Resolving libreplanet.org (libreplanet.org)... 209.51.188.248
@ -1164,8 +1157,10 @@ $ wget -O speakers.html \
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:01:00
:END:
Alright!
The goal is to retrieve the HTML file at a given URL.
GNU/Linux distributions usually come with GNU =wget=,
which does precisely that.
@ -1178,7 +1173,7 @@ To invoke it,
What follows is quite a bit of text.
The details aren't particularly important as long as it's successful,
but notice that it says it saved to =index.html=.
That's not intuitive to those who don't understand that name was used.
That's not intuitive to those who don't understand why that name was used.
So let's tell =wget= what file we want to output to.
We do this with the =O= option,
@ -1193,9 +1188,9 @@ So remember previously that we manually created =speakers.html= by viewing
If we open this file,
we'll find that it contains /exactly the same text/,
and we never had to open a web browser.
And we can search it all the same as before.
And we can search it all the same as before for ``free software''.
*** RAW Browser vs. =wget= Comparison :B_frame:
*** DRAFT Browser vs. =wget= Comparison :B_frame:
:PROPERTIES:
:BEAMER_env: frame
:END:
@ -1213,6 +1208,7 @@ $ wget https://libreplanet.org/2019/speakers/
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:00:40
:END:
This is a very different means of interacting with the computer,
@ -1224,14 +1220,18 @@ It's hard to imagine a more direct line of communication with the computer
for downloading a webpage,
short of reading your mind.
If we then try to output to a specific file,
then it's even /easier/ on the command line.
It's true that you can save the HTML using Icecat by hitting =Ctrl+S=,
but that saves a lot more than just the HTML page---it
also saves all the images and stylesheets and other resources,
which is much more than we need.
You can do this in =wget= too,
by the way.
You can even archive an entire website for offline viewing by using =-m=.
Just don't do that with this URL,
or it'll also download the entire LibrePlanet wiki too,
which isn't quite what you want.
*** RAW Finding Text on the Command Line :B_frame:
*** DRAFT Finding Text on the Command Line :B_frame:
:PROPERTIES:
:BEAMER_env: frame
:END:
@ -1252,6 +1252,7 @@ exclusively free software. Mike spends most of his free time with his
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:01:00
:END:
Not having to open a web browser is nice,
@ -1277,18 +1278,13 @@ But notice how it happens to include exactly the text we were looking at in
And with that we have replicated =Ctrl+F=.
But did we do a good job conveying our thoughts to the machine?
We just wanted to know whether the page con
And with that we have replicated =Ctrl+F=.
But did we do a good job conveying our thoughts to the machine?
We just wanted to know whether the page /contains/ the phrase;
we don't care to see it!
So while we have efficiently conveyed a search string,
we didn't receive an efficient reply;
it's information overload.
we didn't receive an efficient reply---it's
information overload.
*** RAW A More Gentle Reply :B_frame:
*** DRAFT A More Gentle Reply :B_frame:
:PROPERTIES:
:BEAMER_env: frame
:END:
@ -1320,14 +1316,15 @@ no
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:01:00
:END:
First we tell =grep= to modify its behavior with the =q= flag,
which stands for ``quiet''.
First we tell =grep= to modify its behavior with the =quiet= flag.
You can also use the short form,
which is just =-q=.
Rather than outputting results,
=grep= will exist silently;
it will instead return a status to the shell that says whether or not
the search failed.
=grep= will exit silently and it will instead return a status to the shell
that says whether or not the search failed.
POSIX-like shells,
like Bash,
@ -1352,9 +1349,12 @@ We can do that too,
by using two pipes in place of two ampersands,
which states:
``search for `free software' in =speakers.html= and output `no' if it
is /not/ found''.
fails''.
Alternatively you could also pass =-v= or =--invert-match= which inverts the
exit status,
and continue using the ampersands.
*** RAW Writing to Files (Redirection) :B_frame:
*** DRAFT Writing to Files (Redirection) :B_frame:
:PROPERTIES:
:BEAMER_env: frame
:END:
@ -1380,6 +1380,7 @@ $ echo 'Second line' >> results.txt
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:00:55
:END:
Alright, we're well on our way now!
@ -1397,13 +1398,13 @@ If you place a single greater-than symbol followed by a filename after a
command,
then the output of that command will replace anything already in the
file.
So the result of the first two command will be a =hello.txt= that contains
So the result of the first two commands will be a =hello.txt= that contains
only a single line:
``Hello again, world!''.
The second type,
which uses /two/ greater-than symbols,
appends to the file.
/appends/ to the file.
=echo= by default adds a newline,
so the result of the second two commands is a =results.txt= containing two
lines,
@ -1413,13 +1414,15 @@ If the file doesn't yet exist,
I think maybe you can see where I'm going with this.
*** RAW Starting Our List :B_fullframe:
*** DRAFT Starting Our List :B_fullframe:
:PROPERTIES:
:BEAMER_env: fullframe
:END:
#+BEGIN_SRC sh
$ wget --quiet -O speakers.html \
https://libreplanet.org/2019/speakers/ \
&& grep --quiet 'free software' speakers.html \
@ -1430,6 +1433,7 @@ $ wget --quiet -O speakers.html \
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:01:10
:END:
Take a look at that for a moment.
@ -1453,7 +1457,7 @@ At this point,
But this is a hefty command to have to modify each time we want to try a
different URL.
*** RAW Command Refactoring :B_fullframe:
*** DRAFT Command Refactoring :B_fullframe:
:PROPERTIES:
:BEAMER_env: fullframe
:END:
@ -1462,17 +1466,20 @@ But this is a hefty command to have to modify each time we want to try a
#+BEGIN_SRC sh
$ wget --quiet -O speakers.html \
https://libreplanet.org/2019/speakers/ \
&& grep --quiet 'free software' speakers.html \
|| echo https://libreplanet.org/2019/speakers/ \
>> results.txt
#+END_SRC
\subskip
#+BEAMER: \end{onlyenv}
#+BEAMER: \begin{onlyenv}<1>
#+BEGIN_SRC sh
$ URL=https://libreplanet.org/2019/speakers/
$ wget --quiet -O speakers.html \
"$URL" \
@ -1485,6 +1492,7 @@ $ wget --quiet -O speakers.html \
#+BEAMER: \begin{onlyenv}<2>
#+BEGIN_SRC sh
$ URL=https://libreplanet.org/2019/speakers/
$ wget -qO speakers.html \
"$URL" \
@ -1497,6 +1505,7 @@ $ wget -qO speakers.html \
#+BEAMER: \begin{onlyenv}<3>
#+BEGIN_SRC sh
$ URL=https://libreplanet.org/2019/speakers/
$ wget -qO - \
"$URL" \
@ -1509,6 +1518,7 @@ $ wget -qO - \
#+BEAMER: \begin{onlyenv}<4>
#+BEGIN_SRC sh
$ URL=https://libreplanet.org/2019/speakers/
$ wget -qO - "$URL" \
| grep -q 'free software' || echo "$URL" >> results.txt
@ -1521,8 +1531,9 @@ $ wget -qO - "$URL" \
#+BEAMER: \begin{onlyenv}<5->
#+BEGIN_SRC sh
$ alias fetch-url='wget -qO-'
$ URL=https://libreplanet.org/2019/speakers/ \
fetch-url "$URL" \
$ URL=https://libreplanet.org/2019/speakers/
$ fetch-url "$URL" \
| grep -q 'free software' || echo "$URL" >> results.txt
@ -1533,6 +1544,7 @@ $ URL=https://libreplanet.org/2019/speakers/ \
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:02:00
:END:
We can simplify it by introducing a /variable/.
@ -1541,10 +1553,11 @@ There must be no spaces on either size of the assignment operator,
which is the equal sign.
We then reference its value by prefixing it with a dollar sign everywhere
the URL previously appeared.
You should always put variable references in double quotes for safety---that
ensures that,
if our variable contains a space or other special character,
it isn't interpreted by the shell differently than we intended.
You should always put variable references in double quotes for safety if
they are intended to represent a single argument---that
ensures that,
if our variable contains a space or other special character,
it isn't interpreted by the shell differently than we intended.
We can also make this command line a bit more concise by using the short
name for the =--quiet= flag,
@ -1578,13 +1591,13 @@ We then connect standard out of =wget= to the standard in of =grep= using a
single pipe;
this is called a /pipeline/.
Now that we've freed up some space,
Now that we've freed up some characters,
let's reformat this slightly to be a bit more readable.
Any that =wget= command looks a bit cryptic.
And that =wget= command looks a bit cryptic.
How about we define an alias so that it looks a bit more friendly,
and then we can stop worrying about what it does?
And now here's the original command we started with,
Now here's the original command we started with,
and where we're at now.
This little bit of abstraction has made our intent even more clear.
@ -1596,7 +1609,7 @@ It can now clearly be read that we're defining a URL,
But before we keep going,
I want to go back to a point I mentioned previously.
*** RAW Again: Text is a Universal Interface :B_againframe:
*** DRAFT Again: Text is a Universal Interface :B_againframe:
:PROPERTIES:
:BEAMER_env: againframe
:BEAMER_ref: *Text is a Universal Interface
@ -1606,6 +1619,7 @@ But before we keep going,
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:00:20
:END:
Text is a universal interface.
@ -1619,7 +1633,7 @@ That's because text is something that both humans and computers can work
This is a fundamental design principle in the Unix tools that I have begun
to present to you.
*** RAW Pipelines :B_fullframe:
*** DRAFT Pipelines :B_fullframe:
:PROPERTIES:
:BEAMER_env: fullframe
:END:
@ -1633,6 +1647,7 @@ This is a fundamental design principle in the Unix tools that I have begun
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:00:15
:END:
The invention of the Unix pipe is credited to Doug McIlroy.
@ -1643,9 +1658,10 @@ As part of the Unix philosophy,
More broadly,
the Unix philosophy can be summarized as:
*** RAW Summary of the Unix Philosophy :B_fullframe:
*** DRAFT Summary of the Unix Philosophy :B_fullframe:
:PROPERTIES:
:BEAMER_env: fullframe
:DURATION: 0:00:30
:END:
#+BEAMER: \begingroup\fullslidetext
@ -1663,18 +1679,21 @@ streams, because that is a universal interface.
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:DURATION: 00:00:30
:END:
/<Read it>/
Up to this point,
we have shifted how we communicate with the machine by moving away from a
visual interface driven primarily by movement,
to a textual interface that puts mind and machine on equal footing.
But here we're talking about another profound shift in how we think.
And now here we're talking about another profound shift in how we think.
We start to think of how to decompose problems into small operations that
exist as part of a larger pipeline.
How to chain them together,
transforming the data at each step to make it more suitable for the next.
We think of how to chain small, specialized programs together,
transforming text at each step to make it more suitable for the next.
** Thank You :B_fullframe: