Program Composition: Slides of new section
This is likely sufficient to get me through my entire talk time, but I have a number of other interesting things I want to get to. Let's see what the timing looks like in a couple of commits.master
parent
5abc22bae0
commit
b40e289f35
675
slides.org
675
slides.org
|
@ -21,14 +21,19 @@
|
|||
- GUIs /are/ sometimes the most efficient means of melding mind and machine.
|
||||
- De-emphasize doing everything on a terminal just because its "cool".
|
||||
|
||||
** Concepts [7/28]
|
||||
** Concepts [8/27]
|
||||
- [ ] =/sys= and such
|
||||
- [ ] Automating multi-step workflows with GNU Make
|
||||
- [ ] Concurrency
|
||||
- [ ] Connecting graphical and command line (X11 integration) [0/3]
|
||||
- [-] Connecting graphical and command line (X11 integration) [1/4]
|
||||
- [ ] Clipboard (image)
|
||||
- [ ] Clipboard (text)
|
||||
- [X] Clipboard (text) ([[*Program Composition]])
|
||||
- [ ] X11 commands
|
||||
- [ ] Interesting example idea: =import=, =tesseract ss.png - | xsel -ib=
|
||||
so that you can select an area of text on the screen and perform
|
||||
OCR, then have the result on your clipboard
|
||||
- I've never done this, but it goes to show how trivial it is to
|
||||
create something that is seemingly novel.
|
||||
- [ ] Discoverability
|
||||
- Example: I used GIMP for editing some images for this talk because I
|
||||
thought it'd be faster to discover how to that way vs. ImageMagick docs.
|
||||
|
@ -44,17 +49,13 @@
|
|||
- Symbiosis is not only with machine, but community
|
||||
- [ ] Globbing
|
||||
- [ ] GnuPG and smart cards
|
||||
- [ ] Incremental development [0/3]
|
||||
- [ ] Develop as you go, perhaps just referencing history early on
|
||||
- [ ] Evolve by making portions of command dynamic (variables, subshells)
|
||||
- [ ] Transfer commands from history into scripts and aliases for re-use
|
||||
- [ ] Interactive prototyping
|
||||
- [ ] Incremental, iterative, interactive development ([[*Program Composition]])
|
||||
- [X] Looping ([[*Perspective Topics][Perspective Topics]])
|
||||
- [ ] McIlroy and Knuth
|
||||
- [X] Mouse has dependency on positioning of UI elements ([[*Browser Topics][Browser Topics]])
|
||||
- Changes over time, subject to user/system preferences, etc
|
||||
- [ ] Multiplexing with GNU Screen
|
||||
- [ ] Output redirection
|
||||
- [X] Output redirection ([[*A New Perspective]])
|
||||
- [ ] Phone as an example of a device that best works with touch and GUIs
|
||||
and sacrifices practical freedom.
|
||||
- Requires specialized knowledge and is inconvenient to work with.
|
||||
|
@ -77,91 +78,106 @@
|
|||
- [ ] Version control
|
||||
|
||||
** Programs [0/4]
|
||||
- [-] Coreutils / Common [3/12]
|
||||
- [-] Coreutils / Common [7/14]
|
||||
- [X] =cut=
|
||||
- [ ] =column=
|
||||
- [ ] =diff=
|
||||
- [X] =echo= ([[*Browser Topics][Browser Topics]]).
|
||||
- [X] =echo=
|
||||
- [ ] =find=
|
||||
- [ ] =gpg=
|
||||
- [X] =grep= ([[*Browser Topics][Browser Topics]])
|
||||
- [X] =grep=
|
||||
- [ ] =make= / Makefiles
|
||||
- [ ] =sort=
|
||||
- [ ] =man=
|
||||
- [X] =sort=
|
||||
- [ ] =ssh=
|
||||
- [ ] =uniq=
|
||||
- [ ] =wc=
|
||||
- [X] =wget= / =curl= ([[*Browser Topics][Browser Topics]])
|
||||
- [ ] Miscellaneous [0/8]
|
||||
- [X] =uniq=
|
||||
- [X] =wc=
|
||||
- [X] =wget= / =curl=
|
||||
- [-] Miscellaneous [4/8]
|
||||
- [ ] =awk=
|
||||
- [ ] =cowsay=
|
||||
- [ ] =dict=
|
||||
- [ ] =espeak=
|
||||
- [X] =espeak=
|
||||
- [ ] =git=
|
||||
- [ ] =mpv= (e.g. my =pronounce=)
|
||||
- [ ] =torify=
|
||||
- [ ] =sed=
|
||||
- [ ] X11 / Graphical [0/5]
|
||||
- [X] =mail=
|
||||
- [X] =torify=
|
||||
- [X] =sed=
|
||||
- [-] X11 / Graphical [1/5]
|
||||
- [ ] =convert=
|
||||
- [ ] =i3= / =xmonad= / etc
|
||||
- [ ] =import=
|
||||
- [ ] =setxkbmap=
|
||||
- [ ] =xclip= / =xsel=
|
||||
- [X] =xclip= / =xsel=
|
||||
- [ ] Editors / Multiplexing [0/4]
|
||||
- [ ] =emacs=
|
||||
- [ ] =nano=
|
||||
- [ ] =vim=
|
||||
- [ ] =screen=
|
||||
|
||||
* DEVOID Slides [0/5]
|
||||
* DEVOID Slides [0/6]
|
||||
:PROPERTIES:
|
||||
:ID: slides
|
||||
:END:
|
||||
|
||||
** Summary :noexport:
|
||||
#+BEGIN: columnview :hlines 2 :maxlevel 3 :indent t :id slides
|
||||
| ITEM | DURATION | TODO | ENVIRONMENT |
|
||||
|---------------------------------------------------+----------+--------+-------------|
|
||||
| Slides | 0:23:54 | DEVOID | |
|
||||
|---------------------------------------------------+----------+--------+-------------|
|
||||
| \_ Summary | | | |
|
||||
|---------------------------------------------------+----------+--------+-------------|
|
||||
| \_ Introduction | | RAW | note |
|
||||
|---------------------------------------------------+----------+--------+-------------|
|
||||
| \_ Choreographed Workflows | | DEVOID | fullframe |
|
||||
|---------------------------------------------------+----------+--------+-------------|
|
||||
| \_ Practical Freedom | | DEVOID | fullframe |
|
||||
|---------------------------------------------------+----------+--------+-------------|
|
||||
| \_ Practical Example: Web Browser | 0:09:32 | DRAFT | |
|
||||
| \_ Browser Topics | | | |
|
||||
| \_ 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 | 0:14:22 | DRAFT | |
|
||||
| \_ Perspective Topics | | | |
|
||||
| \_ 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 |
|
||||
| ITEM | DURATION | TODO | ENVIRONMENT |
|
||||
|-------------------------------------------------------+----------+---------+-------------|
|
||||
| Slides | 0:23:54 | DEVOID | |
|
||||
|-------------------------------------------------------+----------+---------+-------------|
|
||||
| \_ Summary | | | |
|
||||
|-------------------------------------------------------+----------+---------+-------------|
|
||||
| \_ Introduction | | RAW | note |
|
||||
|-------------------------------------------------------+----------+---------+-------------|
|
||||
| \_ Choreographed Workflows | | DEVOID | fullframe |
|
||||
|-------------------------------------------------------+----------+---------+-------------|
|
||||
| \_ Practical Freedom | | DEVOID | fullframe |
|
||||
|-------------------------------------------------------+----------+---------+-------------|
|
||||
| \_ Practical Example: Web Browser | 0:09:32 | DRAFT | |
|
||||
| \_ Browser Topics | | | |
|
||||
| \_ 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 | 0:14:22 | DRAFT | |
|
||||
| \_ Perspective Topics | | | |
|
||||
| \_ 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 |
|
||||
|-------------------------------------------------------+----------+---------+-------------|
|
||||
| \_ Program Composition | | LACKING | |
|
||||
| \_ Composition Topics | | | |
|
||||
| \_ Clarifying Pipelines | | RAW | fullframe |
|
||||
| \_ Tor | | LACKING | fullframe |
|
||||
| \_ LP Sessions | | LACKING | fullframe |
|
||||
| \_ Interactive, Incremental, Iterative Development | | LACKING | fullframe |
|
||||
| \_ Discovering URLs | | LACKING | fullframe |
|
||||
| \_ Go Grab a Coffee | | LACKING | fullframe |
|
||||
| \_ Async Processes | | | fullframe |
|
||||
| \_ Executable Shell Script and Concurrency | | LACKING | fullframe |
|
||||
| \_ Again: A Research Task | | LACKING | againframe |
|
||||
| \_ A Quick-n-Dirty Solution | | LACKING | frame |
|
||||
|-------------------------------------------------------+----------+---------+-------------|
|
||||
| \_ Thank You | 00:00:01 | | fullframe |
|
||||
#+END:
|
||||
|
||||
** RAW Introduction :B_note:
|
||||
|
@ -818,21 +834,6 @@ And that's why I've dragged you through this drawn-out example---to
|
|||
- [X] Eliminate the temporary file entirely using a pipe
|
||||
- [X] Alias =fetch-url= for =wget -qO-=.
|
||||
- [X] Introduce the Unix philosophy
|
||||
- [ ] Now script discovering what pages contain a certain word [0/4]
|
||||
- [ ] Mention previous example of being emailed a list of URLs. Rather
|
||||
than pasting them into a file, let's discover them using the same
|
||||
tool: =grep=. Save email to a file.
|
||||
- [ ] =grep -o 'https\?://[^ ]\+'=, show how it gets a list of URLs.
|
||||
- Mention how powerful regexes are, e.g. "find all the phone numbers on
|
||||
a page".
|
||||
- g/re/p
|
||||
- [ ] Introduce =while= and =read=, showing how we can iteratively run
|
||||
commands, maybe =... | while read url; do echo "URL: $url"; done=.
|
||||
- [ ] Introduce =-q= flag for grep, and use it to conditionally output
|
||||
only the URLs at which the word can be found.
|
||||
- Not enough talk time to walk away and get a coffee, but let's see if
|
||||
we can maybe let it run for 10--30s while I blabber on. Depends on
|
||||
the connection speed at MIT with all the participants.
|
||||
|
||||
*** DRAFT Secrets? :B_fullframe:
|
||||
:PROPERTIES:
|
||||
|
@ -1695,6 +1696,514 @@ We start to think of how to decompose problems into small operations that
|
|||
We think of how to chain small, specialized programs together,
|
||||
transforming text at each step to make it more suitable for the next.
|
||||
|
||||
** LACKING Program Composition [0/9]
|
||||
*** Composition Topics [5/6] :noexport:
|
||||
- [X] Clarify how pipelines work with existing =wget | grep=.
|
||||
- [X] More involved pipeline with more than two programs.
|
||||
- [ ] Emphasize iterative development and how the shell is a REPL. [0/3]
|
||||
- Useful for programmers for prototyping and debugging, but also essential
|
||||
to average users for discovery.
|
||||
- [ ] Develop as you go, perhaps just referencing history early on
|
||||
- [ ] Evolve by making portions of command dynamic (variables, subshells)
|
||||
- [ ] Transfer commands from history into scripts and aliases for re-use
|
||||
- [X] Now script discovering what pages contain a certain word [3/3]
|
||||
- [X] Mention previous example of being emailed a list of URLs. Rather
|
||||
than pasting them into a file, let's discover them using the same
|
||||
tool: =grep=. Save email to a file.
|
||||
- [X] =grep -o 'https\?://[^ ]\+'=, show how it gets a list of URLs.
|
||||
- [X] Introduce =while= and =read=, showing how we can iteratively run
|
||||
commands, maybe =... | while read url; do echo "URL: $url"; done=.
|
||||
- Not enough talk time to walk away and get a coffee, but let's see if
|
||||
we can maybe let it run for 10--30s while I blabber on. Depends on
|
||||
the connection speed at MIT with all the participants.
|
||||
- [X] Extract =url-grep= into script.
|
||||
- [X] Demonstrate running jobs in parallel with =xargs=.
|
||||
|
||||
*** RAW Clarifying Pipelines :B_fullframe:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: fullframe
|
||||
:END:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
$ fetch-url https://libreplanet.org/2019/speakers/ \
|
||||
| head -n3
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
#+END_SRC
|
||||
|
||||
#+BEAMER: \begin{uncoverenv}<2->
|
||||
#+BEGIN_SRC sh
|
||||
$ fetch-url https://libreplanet.org/2019/speakers/ \
|
||||
| wc -l
|
||||
1422
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{uncoverenv}
|
||||
|
||||
#+BEAMER: \begin{uncoverenv}<3->
|
||||
#+BEGIN_SRC sh
|
||||
$ fetch-url https://libreplanet.org/2019/speakers/ \
|
||||
| grep 'free software' \
|
||||
| wc -l
|
||||
38
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{uncoverenv}
|
||||
|
||||
#+BEAMER: \begin{uncoverenv}<4->
|
||||
#+BEGIN_SRC sh
|
||||
$ fetch-url https://libreplanet.org/2019/speakers/ \
|
||||
| grep 'free software' \
|
||||
| tail -n1
|
||||
Expat</a>. The JavaScript is free software with
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{uncoverenv}
|
||||
|
||||
**** Notes :B_noteNH:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: noteNH
|
||||
:END:
|
||||
|
||||
Let's observe the profound consequences of these design decisions.
|
||||
First,
|
||||
let's make sure you understand what outputting to standard out is doing
|
||||
with our existing =wget= command.
|
||||
Remember that standard out is displayed to us on the terminal by default.
|
||||
If we were to just run that =wget= command and nothing else,
|
||||
we'd be spammed with output.
|
||||
But I just want to prove to you that HTML is being output to standard out;
|
||||
I don't want a ton of spam.
|
||||
So we can pipe it to =head= to show only the first few lines.
|
||||
|
||||
But how many lines did we save ourselves?
|
||||
We can pipe it to =wc= instead,
|
||||
which stands for ``word count'',
|
||||
and tell it to count the number of newlines with =-l=.
|
||||
|
||||
What about the number of lines that contain the string ``free software''?
|
||||
|
||||
Or how about the last such line?
|
||||
|
||||
*** LACKING Tor :B_fullframe:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: fullframe
|
||||
:END:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
$ alias fetch-url='torify wget -qO-'
|
||||
#+END_SRC
|
||||
|
||||
|
||||
*** LACKING LP Sessions :B_fullframe:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: fullframe
|
||||
:END:
|
||||
|
||||
#+BEAMER: \begin{onlyenv}<+>
|
||||
#+BEGIN_SRC sh
|
||||
$ fetch-url https://libreplanet.org/2019/speakers/ \
|
||||
| grep -A5 speaker-header \
|
||||
| head -n14
|
||||
<header class="keynote-speaker-header" id="garbee">
|
||||
<hgroup>
|
||||
<h2>Bdale Garbee</h2>
|
||||
</hgroup>
|
||||
</header>
|
||||
<p><em>Closing keynote</em></p>
|
||||
--
|
||||
<header class="keynote-speaker-header" id="loubani">
|
||||
<hgroup>
|
||||
<h2>Tarek Loubani</h2>
|
||||
</hgroup>
|
||||
</header>
|
||||
<p><em>Opening keynote (Day 1)</em></p>
|
||||
--
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{onlyenv}
|
||||
|
||||
#+BEAMER: \begin{onlyenv}<+>
|
||||
#+BEGIN_SRC sh
|
||||
$ fetch-url https://libreplanet.org/2019/speakers/ \
|
||||
| grep -A5 speaker-header \
|
||||
| grep '<em>'
|
||||
<p><em>Closing keynote</em></p>
|
||||
<p><em>Opening keynote (Day 1)</em></p>
|
||||
<p><em>Opening keynote (Day 2)</em></p>
|
||||
[...]
|
||||
<p><em>The Tor Project: State of the Onion</em> and <em>Library Freedom Institute: A new hope</em></p>
|
||||
<p><em>The Tor Project: State of the Onion</em></p>
|
||||
[...]
|
||||
<p><em>Large-scale collaboration with free software</em></p>
|
||||
<p><em>Large-scale collaboration with free software</em></p>
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{onlyenv}
|
||||
|
||||
#+BEAMER: \begin{onlyenv}<+>
|
||||
#+BEGIN_SRC sh
|
||||
$ fetch-url https://libreplanet.org/2019/speakers/ \
|
||||
| grep -A5 speaker-header \
|
||||
| grep -o '<em>[^<]\+</em>'
|
||||
<em>Closing keynote</em>
|
||||
<em>Opening keynote (Day 1)</em>
|
||||
<em>Opening keynote (Day 2)</em>
|
||||
[...]
|
||||
<em>The Tor Project: State of the Onion</em>
|
||||
<em>Library Freedom Institute: A new hope</em>
|
||||
<em>The Tor Project: State of the Onion</em>
|
||||
[...]
|
||||
<em>Large-scale collaboration with free software</em>
|
||||
<em>Large-scale collaboration with free software</em>
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{onlyenv}
|
||||
|
||||
#+BEAMER: \begin{onlyenv}<+>
|
||||
#+BEGIN_SRC sh
|
||||
$ fetch-url https://libreplanet.org/2019/speakers/ \
|
||||
| grep -A5 speaker-header \
|
||||
| grep -o '<em>[^<]\+</em>' \
|
||||
| sort \
|
||||
| uniq -cd
|
||||
2 <em>Hackerspace Rancho Electrónico</em>
|
||||
4 <em>Large-scale collaboration with free software</em>
|
||||
2 <em>Library Freedom Institute: A new hope</em>
|
||||
2 <em>Right to Repair and the DMCA</em>
|
||||
2 <em>Teaching privacy and security via free software</em>
|
||||
2 <em>The joy of bug reporting</em>
|
||||
5 <em>The Tor Project: State of the Onion</em>
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{onlyenv}
|
||||
|
||||
#+BEAMER: \begin{onlyenv}<+>
|
||||
#+BEGIN_SRC sh
|
||||
$ fetch-url https://libreplanet.org/2019/speakers/ \
|
||||
| grep -A5 speaker-header \
|
||||
| grep -o '<em>[^<]\+</em>' \
|
||||
| sort \
|
||||
| uniq -cd \
|
||||
| sort -nr \
|
||||
| head -n5
|
||||
5 <em>The Tor Project: State of the Onion</em>
|
||||
4 <em>Large-scale collaboration with free software</em>
|
||||
2 <em>The joy of bug reporting</em>
|
||||
2 <em>Teaching privacy and security via free software</em>
|
||||
2 <em>Right to Repair and the DMCA</em>
|
||||
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{onlyenv}
|
||||
|
||||
#+BEAMER: \begin{onlyenv}<+>
|
||||
#+BEGIN_SRC sh
|
||||
$ fetch-url https://libreplanet.org/2019/speakers/ \
|
||||
| grep -A5 speaker-header \
|
||||
| grep -o '<em>[^<]\+</em>' \
|
||||
| sort \
|
||||
| uniq -cd \
|
||||
| sort -nr \
|
||||
| head -n5 \
|
||||
| sed 's#^ *\(.\+\) <em>\(.*\)</em>#\2 has \1 speakers#g'
|
||||
The Tor Project: State of the Onion has 5 speakers
|
||||
Large-scale collaboration with free software has 4 speakers
|
||||
The joy of bug reporting has 2 speakers
|
||||
Teaching privacy and security via free software has 2 speakers
|
||||
Right to Repair and the DMCA has 2 speakers
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{onlyenv}
|
||||
|
||||
#+BEAMER: \begin{onlyenv}<+>
|
||||
#+BEGIN_SRC sh
|
||||
$ fetch-url https://libreplanet.org/2019/speakers/ \
|
||||
| grep -A5 speaker-header \
|
||||
| grep -o '<em>[^<]\+</em>' \
|
||||
| sort \
|
||||
| uniq -cd \
|
||||
| sort -nr \
|
||||
| head -n5 \
|
||||
| sed 's#^ *\(.\+\) <em>\(.*\)</em>#\2 has \1 speakers#g'
|
||||
| espeak
|
||||
|
||||
|
||||
|
||||
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{onlyenv}
|
||||
|
||||
*** LACKING Interactive, Incremental, Iterative Development :B_fullframe:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: fullframe
|
||||
:END:
|
||||
|
||||
#+BEAMER: \fullslidetext
|
||||
Incremental Development
|
||||
|
||||
#+BEAMER: \fullsubtext
|
||||
Interactive REPL, Iterative Decomposition
|
||||
|
||||
*** LACKING Discovering URLs :B_fullframe:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: fullframe
|
||||
:END:
|
||||
|
||||
#+BEAMER: \begin{onlyenv}<+>
|
||||
#+BEGIN_SRC sh
|
||||
|
||||
$ grep -o 'https\?://[^ ]\+' email-of-links.msg
|
||||
https://en.wikipedia.org/wiki/Free_software
|
||||
https://en.wikipedia.org/wiki/Open_source
|
||||
https://en.wikipedia.org/wiki/Microsoft
|
||||
https://opensource.org/about
|
||||
|
||||
|
||||
|
||||
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{onlyenv}
|
||||
|
||||
#+BEAMER: \begin{onlyenv}<+>
|
||||
#+BEGIN_SRC sh
|
||||
|
||||
$ grep -o 'https\?://[^ ]\+' email-of-links.msg \
|
||||
| while read URL; do
|
||||
echo "URL is $URL"
|
||||
done
|
||||
URL is https://en.wikipedia.org/wiki/Free_software
|
||||
URL is https://en.wikipedia.org/wiki/Open_source
|
||||
URL is https://en.wikipedia.org/wiki/Microsoft
|
||||
URL is https://opensource.org/about
|
||||
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{onlyenv}
|
||||
|
||||
#+BEAMER: \begin{onlyenv}<+>
|
||||
#+BEGIN_SRC sh
|
||||
|
||||
$ grep -o 'https\?://[^ ]\+' email-of-links.msg \
|
||||
| while read URL; do
|
||||
fetch-url "$URL" | grep -q 'free software' \
|
||||
|| echo "$URL" >> results.txt
|
||||
done
|
||||
|
||||
|
||||
|
||||
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{onlyenv}
|
||||
|
||||
#+BEAMER: \begin{onlyenv}<+>
|
||||
#+BEGIN_SRC sh
|
||||
|
||||
$ grep -o 'https\?://[^ ]\+' email-of-links.msg \
|
||||
| while read URL; do
|
||||
fetch-url "$URL" | grep -q 'free software' \
|
||||
|| echo "$URL" | tee -a results.txt
|
||||
done
|
||||
https://en.wikipedia.org/wiki/Microsoft
|
||||
https://opensource.org/about
|
||||
|
||||
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{onlyenv}
|
||||
|
||||
#+BEAMER: \begin{onlyenv}<+>
|
||||
#+BEGIN_SRC sh
|
||||
|
||||
$ grep -o 'https\?://[^ ]\+' email-of-links.msg \
|
||||
| while read URL; do
|
||||
fetch-url "$URL" | grep -q 'free software' \
|
||||
|| echo "$URL" | tee -a results.txt
|
||||
done \
|
||||
| xclip -i -selection clipboard
|
||||
|
||||
|
||||
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{onlyenv}
|
||||
|
||||
#+BEAMER: \begin{onlyenv}<+>
|
||||
#+BEGIN_SRC sh
|
||||
|
||||
$ grep -o 'https\?://[^ ]\+' email-of-links.msg \
|
||||
| while read URL; do
|
||||
fetch-url "$URL" | grep -q 'free software' \
|
||||
|| echo "$URL" | tee -a results.txt
|
||||
done \
|
||||
| tee >( xclip -i -selection clipboard )
|
||||
https://en.wikipedia.org/wiki/Microsoft
|
||||
https://opensource.org/about
|
||||
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{onlyenv}
|
||||
|
||||
#+BEAMER: \begin{onlyenv}<+>
|
||||
#+BEGIN_SRC sh
|
||||
$ xclip -o -selection clipboard \
|
||||
| grep -o 'https\?://[^ ]\+' \
|
||||
| while read URL; do
|
||||
fetch-url "$URL" | grep -q 'free software' \
|
||||
|| echo "$URL" | tee -a results.txt
|
||||
done \
|
||||
| tee >( xclip -i -selection clipboard )
|
||||
https://en.wikipedia.org/wiki/Microsoft
|
||||
https://opensource.org/about
|
||||
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{onlyenv}
|
||||
|
||||
#+BEAMER: \begin{onlyenv}<+>
|
||||
#+BEGIN_SRC sh
|
||||
$ xclip -o -selection clipboard \
|
||||
| grep -o 'https\?://[^ ]\+' \
|
||||
| while read URL; do
|
||||
fetch-url "$URL" | grep -q 'free software' \
|
||||
|| echo "$URL" | tee -a results.txt
|
||||
done
|
||||
https://en.wikipedia.org/wiki/Microsoft
|
||||
https://opensource.org/about
|
||||
|
||||
$ xclip -i -selection clipboard < results.txt
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{onlyenv}
|
||||
|
||||
#+BEAMER: \begin{onlyenv}<+>
|
||||
#+BEGIN_SRC sh
|
||||
$ xclip -o -selection clipboard \
|
||||
| grep -o 'https\?://[^ ]\+' \
|
||||
| while read URL; do
|
||||
fetch-url "$URL" | grep -q 'free software' \
|
||||
|| tee -a results.txt <<< "$URL"
|
||||
done
|
||||
https://en.wikipedia.org/wiki/Microsoft
|
||||
https://opensource.org/about
|
||||
|
||||
$ xclip -i -selection clipboard < results.txt
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{onlyenv}
|
||||
|
||||
*** LACKING Go Grab a Coffee :B_fullframe:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: fullframe
|
||||
:END:
|
||||
|
||||
#+BEAMER: \fullslidetext
|
||||
Go Grab a Coffee
|
||||
|
||||
**** Notes :B_noteNH:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: noteNH
|
||||
:END:
|
||||
|
||||
...
|
||||
|
||||
But grabbing a coffee means that this system is a bottleneck.
|
||||
Ideally,
|
||||
we wouldn't have to wait long.
|
||||
Can we do better?
|
||||
|
||||
*** Async Processes :B_fullframe:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: fullframe
|
||||
:END:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
$ sleep 1 && echo done & echo start
|
||||
start
|
||||
done
|
||||
#+END_SRC
|
||||
|
||||
#+BEAMER: \begin{uncoverenv}<2>\subskip
|
||||
/(Don't do this for large numbers of URLs!)/
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
$ while read URL; do
|
||||
fetch-url "$URL" | grep -q 'free software' \
|
||||
|| tee -a results.txt <<< "$URL" &
|
||||
done
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{uncoverenv}
|
||||
|
||||
*** LACKING Executable Shell Script and Concurrency :B_fullframe:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: fullframe
|
||||
:END:
|
||||
|
||||
**** =url-grep= :B_block:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: block
|
||||
:END:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
#!/bin/bash
|
||||
#+END_SRC
|
||||
|
||||
#+BEAMER: \begin{onlyenv}<+>
|
||||
#+BEGIN_SRC sh
|
||||
search="$1"
|
||||
url="$2"
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{onlyenv}
|
||||
|
||||
#+BEAMER: \begin{onlyenv}<+->
|
||||
#+BEGIN_SRC sh
|
||||
search="${1?Missing search string}"
|
||||
url="${2?Missing URL}"
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{onlyenv}
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
wget -qO- "$url" \
|
||||
| grep -q "$search" || echo "$url"
|
||||
#+END_SRC
|
||||
|
||||
**** Execute :B_ignoreheading:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: ignoreheading
|
||||
:END:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
$ chmod +x url-grep
|
||||
#+END_SRC
|
||||
|
||||
#+BEAMER: \begin{onlyenv}<1-2>
|
||||
#+BEGIN_SRC sh
|
||||
$ while read URL; do
|
||||
./url-grep 'free software' "$URL" >> results.txt
|
||||
done
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{onlyenv}
|
||||
|
||||
#+BEAMER: \begin{onlyenv}<3>
|
||||
#+BEGIN_SRC sh
|
||||
$ xargs -n1 ./url-grep 'free software' > results.txt
|
||||
|
||||
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{onlyenv}
|
||||
|
||||
#+BEAMER: \begin{onlyenv}<4>
|
||||
#+BEGIN_SRC sh
|
||||
$ xargs -n1 -P5 ./url-grep 'free software' > results.txt
|
||||
# ^ 5 concurrent processes
|
||||
|
||||
#+END_SRC
|
||||
#+BEAMER: \end{onlyenv}
|
||||
|
||||
*** LACKING Again: A Research Task :B_againframe:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: againframe
|
||||
:BEAMER_ref: *A Research Task
|
||||
:BEAMER_act:
|
||||
:END:
|
||||
|
||||
*** LACKING A Quick-n-Dirty Solution :B_frame:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: frame
|
||||
:END:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
echo 'wget -qO- "$2" | grep -q "$1" || echo "$2"' > url-grep
|
||||
$ grep -o 'https\?://[^ ]\+' mail \
|
||||
| xargs -n1 -P10 bash url-grep 'free software' \
|
||||
| mail -s 'URLs not mentioning free software' mtg@gnu.org
|
||||
#+END_SRC
|
||||
|
||||
|
||||
** Thank You :B_fullframe:
|
||||
:PROPERTIES:
|
||||
|
|
Loading…
Reference in New Issue