Feed fetched in 285 ms.
Warning Content type is application/rss+xml
, not text/xml
.
Feed is 88,485 characters long.
Feed has an ETag of "eaf7c093a2c731be709db3568a1929b1"
.
Feed has a last modified date of Tue, 21 Jul 2020 18:20:17 GMT
.
Warning This feed does not have a stylesheet.
This appears to be an RSS feed.
Feed title: Dan Nguyen's Blog | Thoughts, Data and Computational Journalism
Feed self link matches feed URL.
Feed has 10 items.
First item published on 2020-07-21T17:14:00.000Z
Last item published on 2017-03-06T06:00:00.000Z
Home page URL: http://blog.danwin.com/
Home page has feed discovery link in <head>.
Home page has a link to the feed in the <body>
<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> <channel> <title>Dan Nguyen's Blog | Thoughts, Data and Computational Journalism</title> <description>Dan Nguyen is a programmer and computational journalist</description> <link>http://blog.danwin.com/</link> <atom:link href="http://blog.danwin.com/feed.xml" rel="self" type="application/rss+xml"/> <pubDate>Tue, 21 Jul 2020 13:20:11 -0500</pubDate> <lastBuildDate>Tue, 21 Jul 2020 13:20:11 -0500</lastBuildDate> <generator>Jekyll v3.8.6</generator> <item> <title>How to automatically timestamp a new row in Google Sheets using Apps Script</title> <description><p>One of my most frequent everyday usecases for spreadsheets is casual tracking of personal activity, like daily exercise, or my progress in Duolingo; here’s what the spreadsheets for those two examples look like, respectively:</p> <p><img src="/files/images/posts/screenshots/daily-spreadsheets.png" alt="image daily-spreadsheets.png" /></p> <p>You’ll notice that both have a <strong>datetime</strong> field – I include this not because I’m particularly anal about when exactly I did something, but because maybe down the road I want to do a quickie pivot table analysis, like how often I did things in the morning versus evening, or weekday versus weekend, etc.</p> <p>More data is <em>generally</em> better than less, since if I don’t capture this info, I can’t go back in time to redo the spreadsheet. However, the mundane work of data entry for an extra field, especially added up over months, risks creating enough friction that I might eventually abandon my “casual tracking”.</p> <p>Google Sheets does provide <a href="https://webapps.stackexchange.com/a/24692/53055">handy keyboard shortcuts</a> for adding date and time to a field:</p> <ul> <li><code class="highlighter-rouge">Ctrl</code>/<code class="highlighter-rouge">Cmd</code>+<code class="highlighter-rouge">:</code> to insert date: <code class="highlighter-rouge">7/21/2020</code></li> <li><code class="highlighter-rouge">Ctrl</code>/<code class="highlighter-rouge">Cmd</code>+<code class="highlighter-rouge">Shift</code> + <code class="highlighter-rouge">:</code> to insert time: <code class="highlighter-rouge">3:25:24 PM</code></li> <li><code class="highlighter-rouge">Ctrl</code>/<code class="highlighter-rouge">Cmd</code>+ <code class="highlighter-rouge">Alt</code> + <code class="highlighter-rouge">Shift</code> + <code class="highlighter-rouge">:</code> to insert the full timestamp: <code class="highlighter-rouge">7/21/2020 12:05:46</code></li> </ul> <p>However, doing that per row is still <em>work</em>; more importantly, I wanted to be able to use the iOS version of Google Sheets to enter exercises as soon as I did them (e.g. random sets of pushups or pullups), and these time/date shortcuts are non-existent.</p> <p>What I needed was for the <strong>datetime</strong> field to be automatically be filled <em>each time I started a new row</em>, i.e. as soon as I filled out the first field of a new row, e.g. Duolingo <strong>word</strong> or exercise <strong>type</strong>.</p> <h2 id="the-solution">The solution</h2> <p>What I wanted can be done by using the <strong>Script Editor</strong> and writing a <a href="https://developers.google.com/apps-script/guides/sheets">Google Apps Script snippet</a>. Here are the steps:</p> <p>First, create a Google Sheet that has at least 2 columns, and with one of the non-first columns titled <strong>datetime</strong>:</p> <p><img src="/files/images/posts/screenshots/google-sheets-blank-datetime-template.png" alt="image google-sheets-blank-datetime-template.png" /></p> <p>Then, from the menubar, open <strong>Tools » Script Editor</strong>:</p> <p><img src="/files/images/posts/screenshots/google-sheets-menu-script-editor.png" alt="image google-sheets-menu-script-editor.png" /></p> <p>This will take you to a blank template for a new Google App Script project/file:</p> <p><img src="/files/images/posts/screenshots/google-sheets-app-script-editor-new.png" alt="image google-sheets-app-script-editor-new.png" /></p> <p>One of the features of Google Apps Script for Google Sheets is <a href="https://developers.google.com/apps-script/guides/triggers">simple triggers</a>, i.e. functions with reserved names like <code class="highlighter-rouge">onOpen(e)</code>, <code class="highlighter-rouge">onEdit(e)</code>, and <code class="highlighter-rouge">onSelectionChange(e)</code> that execute on common document events. What we want is to change a row (i.e. insert a timestamp) when it is edited, so we want <code class="highlighter-rouge">onEdit(e)</code>:</p> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code><span class="kd">function</span> <span class="nx">onEdit</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span> </code></pre></div></div> <p>But before we get into <code class="highlighter-rouge">onEdit</code>, we want a helper function that, given a fieldname like <code class="highlighter-rouge">"datetime"</code>, it returns the column index as Google Sheets understands it, e.g. <code class="highlighter-rouge">2</code>, in the given screenshot examples. Here’s one way to write that function, which we’ll call <code class="highlighter-rouge">getDatetimeCol()</code>:</p> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code><span class="kd">var</span> <span class="nx">SHEET_NAME</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Sheet1</span><span class="dl">'</span><span class="p">;</span> <span class="kd">var</span> <span class="nx">DATETIME_HEADER</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">datetime</span><span class="dl">'</span><span class="p">;</span> <span class="kd">function</span> <span class="nx">getDatetimeCol</span><span class="p">(){</span> <span class="kd">var</span> <span class="nx">headers</span> <span class="o">=</span> <span class="nx">SpreadsheetApp</span><span class="p">.</span><span class="nx">getActiveSpreadsheet</span><span class="p">().</span><span class="nx">getSheetByName</span><span class="p">(</span><span class="nx">SHEET_NAME</span><span class="p">).</span><span class="nx">getDataRange</span><span class="p">().</span><span class="nx">getValues</span><span class="p">().</span><span class="nx">shift</span><span class="p">();</span> <span class="kd">var</span> <span class="nx">colindex</span> <span class="o">=</span> <span class="nx">headers</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">DATETIME_HEADER</span><span class="p">);</span> <span class="k">return</span> <span class="nx">colindex</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <p>The <code class="highlighter-rouge">onEdit()</code> function can be described like this:</p> <ul> <li>get the currently edited cell (which requires getting the currently active sheet)</li> <li><strong>if</strong> the edited cell (i.e. active cell) is in the first column <ul> <li><strong>and</strong> it is <strong>not</strong> blank</li> <li><strong>and</strong> the corresponding datetime field <strong>is</strong> blank</li> </ul> </li> <li><strong>then</strong> set the value of the datetime field to the current timestamp – in this example, I use the <a href="https://en.wikipedia.org/wiki/ISO_8601">ISO 8601</a> standard of <code class="highlighter-rouge">2020-07-20 14:03</code></li> </ul> <p>Here’s the entire code snippet with both functions:</p> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code><span class="kd">var</span> <span class="nx">SHEET_NAME</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Sheet1</span><span class="dl">'</span><span class="p">;</span> <span class="kd">var</span> <span class="nx">DATETIME_HEADER</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">datetime</span><span class="dl">'</span><span class="p">;</span> <span class="kd">function</span> <span class="nx">getDatetimeCol</span><span class="p">(){</span> <span class="kd">var</span> <span class="nx">headers</span> <span class="o">=</span> <span class="nx">SpreadsheetApp</span><span class="p">.</span><span class="nx">getActiveSpreadsheet</span><span class="p">().</span><span class="nx">getSheetByName</span><span class="p">(</span><span class="nx">SHEET_NAME</span><span class="p">).</span><span class="nx">getDataRange</span><span class="p">().</span><span class="nx">getValues</span><span class="p">().</span><span class="nx">shift</span><span class="p">();</span> <span class="kd">var</span> <span class="nx">colindex</span> <span class="o">=</span> <span class="nx">headers</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">DATETIME_HEADER</span><span class="p">);</span> <span class="k">return</span> <span class="nx">colindex</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="p">}</span> <span class="kd">function</span> <span class="nx">onEdit</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">ss</span> <span class="o">=</span> <span class="nx">SpreadsheetApp</span><span class="p">.</span><span class="nx">getActiveSheet</span><span class="p">();</span> <span class="kd">var</span> <span class="nx">cell</span> <span class="o">=</span> <span class="nx">ss</span><span class="p">.</span><span class="nx">getActiveCell</span><span class="p">();</span> <span class="kd">var</span> <span class="nx">datecell</span> <span class="o">=</span> <span class="nx">ss</span><span class="p">.</span><span class="nx">getRange</span><span class="p">(</span><span class="nx">cell</span><span class="p">.</span><span class="nx">getRowIndex</span><span class="p">(),</span> <span class="nx">getDatetimeCol</span><span class="p">());</span> <span class="k">if</span> <span class="p">(</span><span class="nx">ss</span><span class="p">.</span><span class="nx">getName</span><span class="p">()</span> <span class="o">==</span> <span class="nx">SHEET_NAME</span> <span class="o">&amp;&amp;</span> <span class="nx">cell</span><span class="p">.</span><span class="nx">getColumn</span><span class="p">()</span> <span class="o">==</span> <span class="mi">1</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nx">cell</span><span class="p">.</span><span class="nx">isBlank</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="nx">datecell</span><span class="p">.</span><span class="nx">isBlank</span><span class="p">())</span> <span class="p">{</span> <span class="nx">datecell</span><span class="p">.</span><span class="nx">setValue</span><span class="p">(</span><span class="k">new</span> <span class="nb">Date</span><span class="p">()).</span><span class="nx">setNumberFormat</span><span class="p">(</span><span class="dl">"</span><span class="s2">yyyy-MM-dd hh:mm</span><span class="dl">"</span><span class="p">);</span> <span class="p">}</span> <span class="p">};</span> </code></pre></div></div> <p>Now, select <strong>File » Save</strong> and give your project a name (it can be anything):</p> <p><img src="/files/images/posts/screenshots/google-sheets-app-script-editor-save-project.png" alt="image google-sheets-app-script-editor-save-project.png" /></p> <p>And your sheet should have the power of auto-inserted timestamps:</p> <p><img src="/files/images/gifs/google-sheets-autotimestamp.gif" alt="gif animation of google sheet auto updating" /></p> <p>Big thanks to the following resources, from which I adapted my solution:</p> <ul> <li><a href="https://support.google.com/docs/thread/12320385?hl=en&amp;msgid=12326611">Abbas Abdulla’s response to the post “Automatic Timestamp when a Cell on the same row gets Updated”, on Google Docs Editors Help forum</a></li> <li><a href="https://stackoverflow.com/questions/31214352/how-to-use-a-column-header-to-reference-a-cell-in-google-apps-script-spreadsheet">StackOverflow: How to use a column header to reference a cell in Google Apps Script Spreadsheet</a></li> </ul></description> <pubDate>Tue, 21 Jul 2020 12:14:00 -0500</pubDate> <link>http://blog.danwin.com/how-to-automatically-timestamp-a-new-row-in-google-sheets-using-apps-script/</link> <guid isPermaLink="true">http://blog.danwin.com/how-to-automatically-timestamp-a-new-row-in-google-sheets-using-apps-script/</guid> </item> <item> <title>NYPD Stop, Question, and Frisk Worksheet (UF-250); My attempt at getting the latest version as 'just a researcher'</title> <description><p><strong>June 26, 2020 update:</strong> I hadn’t received a response to this and let it fall by the wayside, but a few people have emailed asking for an update, so I will try again. Note that the Bloomberg era of NYPD Stop and Frisk <a href="https://www.nytimes.com/2020/03/02/upshot/stop-and-frisk-bloomberg.html">made the news</a> during his 2020 presidential candidacy.</p> <p>I’m writing a book about using SQL for data journalism, and one of the sections will be about the <a href="https://danwin.com/2010/07/the-nyts-cop-stop-and-frisk-graphic/">NYPD’s Stop and Frisk data</a>, which has a long history as both data and policy. In my book, I frequently assert that researching the data is much more important than any programming and database skill. And this includes finding the actual forms – paper or electronic – used for collecting the data.</p> <p>For a stop-and-frisk encounter by the NYPD, police officers have to fill out a <strong>Stop, Question, and Frisk Worksheet (PD 344-151A)</strong>, also known as a Unified Form 250, aka UF-250. The <a href="https://ccrjustice.org/sites/default/files/assets/files/11%2025%2013%20Opp%20to%20Mot%20to%20Intervene%20Decl%20of%20D%20Charney%20Ex%20H.pdf">2011 version</a> has two sides.</p> <p>This is the first:</p> <p><img src="/files/images/uf250-2011-side-1.png" alt="uf250-2011-side-1.png" /></p> <p>And the second side:</p> <p><img src="/files/images/uf250-2011-side-2.png" alt="uf250-2011-side-2.png" /></p> <p>However, after <a href="https://www.nytimes.com/2013/08/13/nyregion/stop-and-frisk-practice-violated-rights-judge-rules.html">a federal judge ruled in 2013</a> that the NYPD’s stop-and-frisk practices violated the constitutional rights of New York’s minorities, the NYPD agreed in 2015 to revise the form, which included requiring officers <a href="https://www.nydailynews.com/new-york/stop-and-frisk-forms-require-details-nypd-article-1.2574886">to write a detailed explanation</a> for why they made a stop.</p> <p>From a <a href="https://www1.nyc.gov/assets/ccrb/downloads/pdf/investigations_pdf/20150302_finest-message-stop-frisk-pursuant-to-floyd.pdf">March 2, 2015 NYPD memo titled “COURT-ORDERED CHANGES TO NYPD PRACTICES AND POLICES RELATED TO STOPS AND FRISKS”</a>:</p> <blockquote> <p>(2) THE DEPARTMENT FORM ENTITLED STOP, QUESTION AND FRISK REPORT WORKSHEET (PD 344-151A), COMMONLY REFERRED TO AS A UF 250 FORM, MUST BE REVISED TO INCLUDE A NARRATIVE SECTION WHERE AN OFFICER MUST RECORD, IN HIS OR HER OWN WORDS, THE BASIS FOR THE STOP. THE NEW FORM MUST ALSO INCLUDE A SEPARATE EXPLANATION OF WHY A FRISK WAS CONDUCTED. THE CHECKBOX SYSTEM CURRENTLY IN USE MUST BE SIMPLIFIED AND IMPROVED.</p> </blockquote> <p>Previously, NYPD officers could simply check a box labeled with “Furtive Movements”, which was apparently <a href="https://www.nytimes.com/2011/12/18/opinion/sunday/young-black-and-frisked-by-the-nypd.html">the sole and vague reason for half of the 600,000 stops conducted in 2010</a>, and which led to the lawsuit in the first place.</p> <p>Anyway, I need this new version of UF-250 for my book. But I could not find it via my Google-fu, including searches for <a href="https://www.google.com/search?q=stop+frisk+site%3Anyc.gov+filetype%3Apdf"><code class="highlighter-rouge">stop frisk site:nyc.gov filetype:pdf</code></a> and <a href="https://www.google.com/search?q=344-151A+filetype%3Apdf&amp;oq=344-151A+filetype%3Apdf"><code class="highlighter-rouge">344-151A filetype:pdf</code></a>, so I guess it’s time to contact the <a href="https://www1.nyc.gov/site/nypd/bureaus/administrative/public-information.page">NYPD’s Public Information office</a>.</p> <p>It’s just a form, so I wouldn’t think it requires the formality of a <a href="https://www1.nyc.gov/site/cchr/about/submit-a-foil-request.page">FOIL request</a> (right?) and the boilerplate language. So I’ll try a friendly email. For the first time in awhile, I’m making this kind of request as someone not currently working for a journalism organization, so here’s how I worded the email, sent from my personal GMail account:</p> <hr /> <p>Hello,</p> <p>My name is Dan Nguyen and I am researching law enforcement policy. I’ve been able to find past revisions of the UF-250 form used in Stop and Frisks, such as from 2000 [1] and 2007 [2], but I haven’t found any since the 2015 Floyd v. City of New York decision [3], which required these revisions:</p> <blockquote> <p>… THE DEPARTMENT FORM ENTITLED STOP, QUESTION AND FRISK REPORT WORKSHEET (PD 344-151A), COMMONLY REFERRED TO AS A UF 250 FORM, MUST BE REVISED TO INCLUDE A NARRATIVE SECTION WHERE AN OFFICER MUST RECORD, IN HIS OR HER OWN WORDS, THE BASIS FOR THE STOP. THE NEW FORM MUST ALSO INCLUDE A SEPARATE EXPLANATION OF WHY A FRISK WAS CONDUCTED. THE CHECKBOX SYSTEM CURRENTLY IN USE MUST BE SIMPLIFIED AND IMPROVED.</p> </blockquote> <p>Could you direct me to where the latest revision of UF-250 exists on the NYPD’s website? Or send to my email ([email protected]).</p> <p>Thank you, Dan Nguyen</p> <p>References:</p> <p>[1] <a href="https://www1.nyc.gov/assets/ccrb/downloads/pdf/policy_pdf/issue_based/20010601_sqf.pdf">https://www1.nyc.gov/assets/ccrb/downloads/pdf/policy_pdf/issue_based/20010601_sqf.pdf</a></p> <p>[2] <a href="https://www1.nyc.gov/assets/nypd/downloads/pdf/public_information/TR534_FINALCompiled.pdf">https://www1.nyc.gov/assets/nypd/downloads/pdf/public_information/TR534_FINALCompiled.pdf</a></p> <p>[3] <a href="https://www1.nyc.gov/assets/ccrb/downloads/pdf/investigations_pdf/20150302_finest-message-stop-frisk-pursuant-to-floyd.pdf">https://www1.nyc.gov/assets/ccrb/downloads/pdf/investigations_pdf/20150302_finest-message-stop-frisk-pursuant-to-floyd.pdf</a></p> <hr /> <p>Note: So I sent this email <em>before</em> I blogged about it, which is why there this error in the text: the Floyd v. City of New York decision was in <em>2013</em>; <a href="https://www1.nyc.gov/assets/ccrb/downloads/pdf/investigations_pdf/20150302_finest-message-stop-frisk-pursuant-to-floyd.pdf">2015 is the date of the NYPD memo</a> asserting the new revisions. Oops.</p> <p>As for why I’m blogging this: just for funsies. If I get a response, I’ll update and link to the new form for the benefit of fewer researchers. And if not, I’ll update and append my ongoing FOIL adventure.</p> <hr /> <p>Other useful reading and links (updated June 2020):</p> <ul> <li><a href="https://www.courtlistener.com/docket/4347389/davis-v-the-city-of-new-york/?filed_after=&amp;filed_before=&amp;entry_gte=&amp;entry_lte=&amp;order_by=desc">CourtListener/PACER: Davis v. The City of New York (1:10-cv-00699) Docket</a></li> <li><a href="https://www.courtlistener.com/recap/gov.uscourts.nysd.357782/gov.uscourts.nysd.357782.355.0.pdf">MEMO ENDORSEMENT on re: (246 in 1:12-cv-02274-AT-HBP) Status Report filed by Peter L Zimroth, (354 in 1:10-cv-00699-AT-HBP) Status Report filed by Peter L. Zimroth, (526 in 1:08-cv-01034-AT-HBP) Status Report filed by Peter A. Zimroth, re: Recommendation Regarding Stop Report Form. ENDORSEMENT: APPROVED. SO ORDERED. (Signed by Judge Analisa Torres on 3/25/2016) (kko) (Entered: 03/25/2016)</a></li> <li><a href="https://www.nyclu.org/sites/default/files/field_documents/20190314_nyclu_stopfrisk_singles.pdf">NYCLU March 2019 Report: Stop-and-Frisk in the de Blasio Era </a></li> <li><a href="https://www.nydailynews.com/new-york/nyc-crime/ny-stop-question-and-frisk-numbers-jump-20200210-vamjtzdfcvdorot57ajtrhnghu-story.html">NY Daily News: NYPD stop-and-frisk numbers jumped by 22% in 2019 from prior year: report</a></li> <li><a href="https://gothamist.com/news/nyc-ending-illegal-stop-and-frisk-era">Gothamist: NYC Has “A Long Way To Go” To End The Illegal Stop-And-Frisk Era</a></li> <li> <p><a href="https://www.nytimes.com/2020/03/02/upshot/stop-and-frisk-bloomberg.html">NYT: The Lasting Effects of Stop-and-Frisk in Bloomberg’s New York</a></p> </li> <li><a href="http://www.nyc.gov/html/nypd/downloads/pdf/analysis_and_planning/212-11.pdf">NYPD Patrol Guide: Procedure No. 212-11: INVESTIGATIVE ENCOUNTERS: REQUESTS FOR INFORMATION, COMMON LAW RIGHT OF INQUIRY AND LEVEL 3 STOPS</a></li> <li><a href="http://www.nyc.gov/html/ccrb/downloads/pdf/2016pg/pg221-02-use-of-force.pdf">NYPD Patrol Guide: Procedure No. 221-02: USE OF FORCE </a></li> <li><a href="http://directives.chicagopolice.org/forms/CPD-11.910.pdf">Chicago Police Investigatory Stop Report</a></li> </ul></description> <pubDate>Thu, 28 Nov 2019 00:00:00 -0600</pubDate> <link>http://blog.danwin.com/request-nypd-form-uf250/</link> <guid isPermaLink="true">http://blog.danwin.com/request-nypd-form-uf250/</guid> </item> <item> <title>The scammers of Harvard Law's Bruce Hay and the "Nigerian Prince" filter</title> <description><p>There’s too much to process in <a href="https://www.thecut.com/2019/07/bruce-hay-paternity-trap-maria-pia-shuman-mischa-haider.html">“The Most Gullible Man in Cambridge “</a>, the Kera Bolonik longform piece that dropped yesterday on the <em>New York Magazine/The Cut</em> website. For starters, just how <a href="https://twitter.com/BrandyLJensen/status/1153727879215235073">completely bananas</a> it is from top to bottom. And then, whether the main character and victim, <a href="https://hls.harvard.edu/faculty/directory/10374/Hay">Professor Bruce Hay of Harvard Law</a>, is a reliable and trustworthy narrator. And of course, the absolute marvel of long suffering patience and wisdom that is his ex-wife (more on that later) and mother of his young children.</p> <p>Because of its many bizarre elements and threads, Bolonik’s article feels much longer than its 7,000-word count and is hard to summarize. But to do it in one convoluted sentence: Professor Hay is the victim of an alleged paternity scam, one so elaborate it nearly cost him and his family their home, and one that includes sexual misconduct allegations leading to <a href="https://babe.net/2018/10/02/bruce-hay-harvard-80495">an ongoing Title IX investigation</a>.</p> <p>The story’s most notable feature is just how gullible and <em>how dumb</em> Professor Hay – who is the on-record source of 90-95% of the narrative – makes himself sound. In this case, a sentence (or several) can’t do Bolonik’s article justice. But one particularly interesting aspect is how seemingly obvious the ploy seems to be, and yet, how it managed to fool several highly intelligent men, including Professor Hay and – as far as we know – three Harvard-area men.</p> <p>From the story’s first graf, this is how Hay describes his first encounter with the scammer; I’ve added emphasis to the pickup line:</p> <blockquote> <p>It was just supposed to have been a quick Saturday-morning errand to buy picture hooks. On March 7, 2015, Harvard Law professor Bruce Hay, then 52, was in Tags Hardware in Cambridge, Massachusetts, near his home, when a young woman with long reddish-brown hair approached him to ask where she could find batteries. It was still very much winter, and, once the woman got his attention, he saw that underneath her dark woolen coat and perfectly tied scarf she was wearing a dress and a chic pair of boots — hardly typical weekend-errand attire in the New England college town. When he directed her to another part of the store, she changed the subject. <strong>“By the way, you’re very attractive,” he remembers her saying.</strong></p> </blockquote> <p>In the latter-third of the story, Bolonik writes that Hay and his lawyer uncovered 3 other men who previously filed suit against his scammer. Bolonik met with one of them, who is referred to in court papers as “John Doe”. Here’s how Doe describes meeting the scammer (again, emphasis mine)</p> <blockquote> <p>This past fall, I met Doe, who told me Shuman appeared out of nowhere at an intersection where he was standing with two colleagues and started chatting him up in what he described as hushed tones. He recalled her saying, <strong>“Excuse me, but I couldn’t help but notice that you’re attractive. I’m in town from New York, visiting a friend, and I was hoping you’d be willing to show me around.”</strong> He gave her his cell number.</p> </blockquote> <p>Everything is obvious in retrospect, but here the pickup line, and its contrived circumstances – how many late-20s/early-30s adults show up in Boston or New York without a smartphone to serve as a guide? – seem <em>especially</em> so. How could Doe, described by Bolonik as a “young, lanky, blue-eyed CPA”, or Hay, a tenured professor with nearly 30 years at Harvard Law, fall for something so comically transparent?</p> <p>Those questions about the depths of human trust and gullibility aren’t readily answered. But I do wonder if the flimsiness of the pickup tactic itself is itself inspired by the trope of the <a href="https://en.wikipedia.org/wiki/Advance-fee_scam">Nigerian Prince email scam</a>, an ostensibly obvious and universally-known scam, <a href="https://www.cnbc.com/2019/04/18/nigerian-prince-scams-still-rake-in-over-700000-dollars-a-year.html">yet one that still brings in fortunes for its perpetrators</a>?.</p> <p>But couldn’t scammers attract even more victims and their money by being more sophisticated? e.g. pretending to be a prince from a country less notorious than Nigeria? In 2012, Microsoft Research’s Cormac Herley studied this question in one of my favorite white papers, <a href="https://www.microsoft.com/en-us/research/publication/why-do-nigerian-scammers-say-they-are-from-nigeria/">Why Do Nigerian Scammers Say They are From Nigeria?</a> (link to <a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/WhyFromNigeria.pdf">PDF</a>).</p> <p>Here’s an excerpt from the Discussion section (Section 4):</p> <blockquote> <p>An examination of a web-site that catalogs scam emails shows that 51% mention Nigeria as the source of funds…Why so little imagination? Why don’t Nigerian scammers claim to be from Turkey, or Portugal or Switzerland or New Jersey? Stupidity is an unsatisfactory answer.</p> </blockquote> <p>It’s a very accessible paper and worth reading, but in summary, Herley argues that the use of “Nigeria” (or “Nigerian Prince”) acts as a very effective filter for the scammer, whose has nearly unlimited bandwidth in the amount of emails sent, but very limited time to deal with “false positives” – i.e. potential victims who ultimately wise up. The percentage of targets who would even open an unsolicited email subject line of “Nigeria” is vanishingly and staggeringly tiny. But the ones who do, Herley argues, are extremely profitable to the scammer:</p> <blockquote> <p>If we assume that the scammer enters into email conversation (i.e., attacks) almost everyone who responds, his main opportunity to separate viable from non-viable users is the wording of the original email…Who are the most likely targets for a Nigerian scammer? Since the scam is entirely one of manipulation he would like to attack (i.e., enter into correspondence with) only those who are most gullible…</p> <p>Since gullibility is unobservable, the best strategy is to get those who possess this quality to self-identify. An email with tales of fabulous amounts of money and West African corruption will strike all but the most gullible as bizarre. It will be recognized and ignored by anyone who has been using the Internet long enough to have seen it several times.</p> </blockquote> <blockquote> <p>It will be figured out by anyone savvy enough to use a search engine and follow up on the auto-complete suggestions such as shown in Figure 8. It won’t be pursued by anyone who consults sensible family or friends, or who reads any of the advice banks and money transfer agencies make available. Those who remain are the scammers ideal targets. They represent a tiny subset of the overall population.</p> </blockquote> <p>Reading through the <a href="https://twitter.com/KeraBolonik/status/1153611968193933312">Twitter replies to NYMag’s Bolonik</a>, there’s at least <a href="https://twitter.com/jordanharap/status/1153774824810078209">one more guy who has a story about the scammer</a> – though apparently, he appears to have avoided the trap:</p> <p><a href="https://twitter.com/jordanharap/status/1153774824810078209"><img src="/files/images/tweet-jharap-bolonik-thecut-hay-scammer.png" alt="This was crazy to read. I was approached by this woman on Mass Ave (directly across from Harvard Law School) in April 2015. I was a third year law student at the time - may be able to provide further corroboration in light of the ongoing proceedings." /> </a></p> <p>Hay’s alleged scammer seems to have some of the same constraints as a Nigerian scammer – it’s a huge amount of time and risk to initiate a relationship with a mark who is likely to wise up. So the exceedingly cringe pickup line of <em>“Excuse me, sir, I’mbut I noticed you’re very handsome. Could you show me around New York?”</em> likely had any rejections before finding success in Professor Hay, “John Doe”, and other victims. And this works beautifully for the paternity-test-scammer.</p> <p>(<strong>Note:</strong> Except for this aside, I’ve deliberately avoid mentioning or speculating about the motives of Hay’s scammers, which would require an entirely separate wordy blog post. Bolonik’s article offers little revelation. But it’s worth noting that in Hay’s case, unlike with Nigerian scammers, the scammers don’t seem to be primarily motivated by money)</p> <p>But as with everything else in Bolonik’s necessarily convoluted article, there are only more questions. Herley, the Microsoft researcher, points out that Nigerian scammers depend on victims lacking a support network of “sensible family or friends”. Professor Hay does not seem to be in this situation; he says he and his scammer, before they first had sex, had coffee dates and long talks about their respective lives. She would have learned from him that his ex-wife – who he has 2 children with and who he was still living with, amicably – is <em>an assistant U.S. Attorney</em>. At that point, the ostensibly savvy scammer must have realized that no matter how gullible Hay seemed, or how estranged he might be from the rest of Harvard’s elite, Hay’s ex-wife was <em>definitely</em> going to step in and pursue any scammers who threatened Hay’s (i.e. <em>her</em>) home and children.</p> <p>And yet here we are. The depths and speed at which Professor Hay fell for the scam is shocking. But it doesn’t explain why (again, assuming that money is not an issue) the scammers would entangle themselves with him, when there are so many other marks. This incongruity (among the <em>many</em> others), added to the fact Hay – against the advice of Harvard and other lawyers – shopped his story around to several other journalists before finding Bolonik, is enough to raise serious doubt that we’ve heard all the relevant and significant facts of this bizarre story.</p></description> <pubDate>Wed, 24 Jul 2019 08:11:00 -0500</pubDate> <link>http://blog.danwin.com/the-scammers-of-harvard-law-s-bruce-hay-and-the-nigerian-prince-filter/</link> <guid isPermaLink="true">http://blog.danwin.com/the-scammers-of-harvard-law-s-bruce-hay-and-the-nigerian-prince-filter/</guid> </item> <item> <title>How to install and use schemacrawler on MacOS to generate nifty SQL database schemas</title> <description><p>The following post is a <a href="https://gist.github.com/dannguyen/f056d05bb7fec408bb7c14ea1552c349">copy of this Gist</a>, an instruction recipe I wrote on how to get the superhandy schemacrawler program working on MacOS. It’s a command-line tool that allows you to easily generate SQL schemas as image files, like so:</p> <p><em>This was tested on MacOS 10.14.5 on 2019-07-16</em></p> <p><a href="http://www.schemacrawler.com/">schemacrawler is a free and open-source database schema discovery and comprehension tool</a>. It can be invoked from the command-line to produce, using <a href="http://www.graphviz.org/">GraphViz</a>, images/pdfs from a SQLite (or other database type) file. It can be used from the command-line to generate schema diagrams like these:</p> <p><img src="https://user-images.githubusercontent.com/121520/41448959-de545a74-7012-11e8-99f9-520d76a683b8.png" alt="image" /></p> <p>To see more examples of commands and diagrams, visit scheacrawler’s docs: http://www.schemacrawler.com/diagramming.html</p> <h2 id="install-graphviz-dependency">Install graphviz dependency</h2> <p>For schema drawing, <code class="highlighter-rouge">schemacrawler</code> uses graphviz, which can be installed via the <a href="https://brew.sh/">Homebrew</a> package manager:</p> <div class="language-sh highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code>brew <span class="nb">install </span>graphviz </code></pre></div></div> <h2 id="installing-schemacrawler-as-a-command-line-tool">Installing <code class="highlighter-rouge">schemacrawler</code> as a command-line tool</h2> <p>This section gives an example of how to install <code class="highlighter-rouge">schemacrawler</code> so that you can invoke it with your shell. There isn’t a Homebrew recipe, so the shell commands basically:</p> <ul> <li>Download a release zip from <a href="https://github.com/schemacrawler/SchemaCrawler/releases">schemacrawler/releases</a></li> <li>Copies the relevant subdir from the release into a local directory, e.g. <code class="highlighter-rouge">/usr/local/opt/schemacrawler</code></li> <li>Creates a simple shell script that saves you from having to run <code class="highlighter-rouge">schemacrawler</code> via the <code class="highlighter-rouge">java</code> executable</li> <li>symlinks this shell script into an executable path, e.g. <code class="highlighter-rouge">/usr/local/bin</code></li> </ul> <h2 id="downloading-and-installing-schemacrawler">Downloading and installing schemacrawler</h2> <p>The latest releases can be found on the Github page:</p> <p>https://github.com/schemacrawler/SchemaCrawler/releases/</p> <h3 id="setting-up-schemacrawler-to-run-on-your-system-via--schemacrawler">Setting up schemacrawler to run on your system via <code class="highlighter-rouge">$ schemacrawler</code></h3> <p>In this gist, I’ve attached a shell script <a href="https://gist.github.com/dannguyen/f056d05bb7fec408bb7c14ea1552c349#file-script-schemacrawler-on-macos-sh">script-schemacrawler-on-macos.sh</a> that automates the downloading of the schemacrawler ZIP file from its Github repo, installs it, creates a helper script, and creates a symlink to that helper script so you can invoke it via:</p> <div class="language-sh highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code><span class="nv">$ </span>schemacrawler ... </code></pre></div></div> <p>You can copy the script into a file and invoke it, or copy-paste it directly into Bash. Obviously, as with anything you copy-paste, read it for yourself to make sure I’m not attempting to do something malicious.</p> <p>(An older version of this script can be found <a href="https://gist.github.com/dannguyen/f056d05bb7fec408bb7c14ea1552c349#file-OLDscript-schemacrawler-on-macos-sh">here</a>)</p> <h4 id="a-couple-of-notes-about">A couple of notes about</h4> <p>The script <a href="https://gist.github.com/dannguyen/f056d05bb7fec408bb7c14ea1552c349#file-script-schemacrawler-on-macos-sh">script-schemacrawler-on-macos.sh</a> has a few defaults – e.g. <code class="highlighter-rouge">/usr/local/opt/</code> and <code class="highlighter-rouge">/usr/local/bin/</code> – which are assumed to be writeable, but you can change those default vars for yourself.</p> <p>One of the effects of is that it creates a Bash script named something like</p> <p>Its contents are:</p> <p>This script is a derivation of schemacrawler’s <a href="https://github.com/schemacrawler/SchemaCrawler/blob/a3fea8be74ae28d6e8318c14f2c3f4be314efe2a/schemacrawler-distrib/src/assembly/schemacrawler.sh">schemacrawler-distrib/src/assembly/schemacrawler.sh</a>, the contents of which are:</p> <h2 id="general-usage">General usage</h2> <p>Now that <code class="highlighter-rouge">schemacrawler</code> is installed as an executable shell command, here’s an example of how to invoke it – change <code class="highlighter-rouge">DBNAME.sqlite</code> and <code class="highlighter-rouge">OUTPUT_IMAGE_FILE.png</code> to something appropriate for your usecase:</p> <div class="language-sh highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code> schemacrawler <span class="nt">-server</span> sqlite <span class="se">\</span> <span class="nt">-database</span> DBNAME.sqlite <span class="se">\</span> <span class="nt">-user</span> <span class="nt">-password</span> <span class="se">\</span> <span class="nt">-infolevel</span> standard <span class="se">\</span> <span class="nt">-command</span> schema <span class="se">\</span> <span class="nt">-outputformat</span> png <span class="se">\</span> <span class="nt">-outputfile</span> OUTPUT_IMAGE_FILE.png </code></pre></div></div> <h3 id="bootload-a-sample-sqlite-database-and-test-out-schemacrawler">Bootload a sample SQLite database and test out schemacrawler</h3> <p>Just in case you don’t have a database to play around with, you can copy paste this sequence of SQLite commands into your <strong>Bash</strong> shell, which will create the following empty database file at <code class="highlighter-rouge">/tmp/tmpdb.sqlite</code></p> <div class="language-sh highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code><span class="nb">echo</span> <span class="s1">''' DROP TABLE IF EXISTS business; DROP TABLE IF EXISTS inspection; DROP TABLE IF EXISTS violation; CREATE TABLE business ( business_id TEXT, name TEXT, address TEXT, city TEXT, postal_code TEXT, latitude DECIMAL, longitude DECIMAL, phone_number TEXT, application_date TEXT, owner_name TEXT ); CREATE TABLE inspection ( business_id TEXT, "Score" NUMERIC, date TEXT NOT NULL, type TEXT NOT NULL, FOREIGN KEY(business_id) REFERENCES business(business_id) ); CREATE TABLE violation ( business_id TEXT, date TEXT, "ViolationTypeID" TEXT, risk_category TEXT, description TEXT, FOREIGN KEY(business_id, date) REFERENCES inspection(business_id, date) );'''</span> <span class="se">\</span> | sqlite3 /tmp/tmpdb.sqlite </code></pre></div></div> <p>Invoke <code class="highlighter-rouge">schemacrawler</code> like so:</p> <div class="highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code>schemacrawler -server sqlite \ -user -password \ -infolevel standard \ -command schema \ -outputformat png \ -database /tmp/tmpdb.sqlite \ -outputfile /tmp/mytmpdb.png </code></pre></div></div> <p>The output of that Bash command will be a file <code class="highlighter-rouge">/tmp/tmpdb.sqlite</code>, which looks like this:</p> <p><img src="https://user-images.githubusercontent.com/121520/61403484-ede86e80-a8c4-11e9-8bda-f9ceb63b6101.png" alt="/tmp/tmpdb.sqlite" /></p> <h2 id="graphviz-properties">graphviz properties</h2> <p>You can edit <code class="highlighter-rouge">schemacrawler.config.properties</code>, which is found wherever you installed the schemacrawler distribution – e.g. if you ran my installer script, it would be in <code class="highlighter-rouge">/usr/local/opt/schemacrawler/config/schemacrawler.config.properties</code></p> <p>Some example settings:</p> <div class="highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code>schemacrawler.format.no_schemacrawler_info=true schemacrawler.format.show_database_info=true schemacrawler.format.show_row_counts=true schemacrawler.format.identifier_quoting_strategy=quote_if_special_characters schemacrawler.graph.graphviz.nodes.ranksep=circo schemacrawler.graph.graphviz.graph.layout=circo schemacrawler.graph.graphviz.graph.splines=ortho schemacrawler.graph.graphviz.node.shape=folder schemacrawler.graph.graphviz.node.style=rounded,filled schemacrawler.graph.graphviz.node.fillcolor=#fcfdfc #schemacrawler.graph.graphviz.node.color=red schemacrawler.graph.graphviz.graph.fontname=Helvetica Neue schemacrawler.graph.graphviz.node.fontname=Consolas schemacrawler.graph.graphviz.edge.fontname=Consolas schemacrawler.graph.graphviz.edge.arrowsize=1.5 </code></pre></div></div> <p>If you append the previous snippet to the default <code class="highlighter-rouge">schemacrawler.config.properties</code>, you’ll get output that looks like this:</p> <p><img src="https://user-images.githubusercontent.com/121520/61417204-f00ef500-a8e5-11e9-9e97-e690b23e31aa.png" alt="image" /></p> <p>More info about GraphViz in this StackOverflow Q:</p> <p><a href="https://stackoverflow.com/questions/11588667/how-to-influence-layout-of-graph-items">How to influence layout of graph items?</a></p></description> <pubDate>Tue, 16 Jul 2019 00:00:00 -0500</pubDate> <link>http://blog.danwin.com/installing-schemacrawler-for-macos-to-map-out-sqlite-schemas/</link> <guid isPermaLink="true">http://blog.danwin.com/installing-schemacrawler-for-macos-to-map-out-sqlite-schemas/</guid> </item> <item> <title>A submemberist?</title> <description><p>It’s a given that Google has pages for every valid English word in existence as well as most fantastical words. It’s very rare that Google comes up with <em>nothing</em>, even for nonsense or terribly misspelled words.</p> <p>However, I stumbled upon a non-result for the word “submemberist”:</p> <p><a href="https://www.google.com/search?q=submemberist">https://www.google.com/search?q=submemberist</a></p> <p>Of course, by the time you click on the above query, Google will have crawled at least a few pages mentioning the word.</p> <p>I guess it’s probably not a big deal to come up with arbitrary combinations of letters for which Google has no results. What was interesting about “submemberist” is that it <em>looks</em> like it could be a word. Though to be fair, the <a href="https://en.oxforddictionaries.com/definition/us/sub-member">Oxford “Living” Dictionary only has it listed with a hyphen: “sub-member”</a>.</p> <p>I didn’t even know “submember” or “sub-member” was a word before I saw Parker Higgins (<a href="https://twitter.com/xor">@xor</a>) tweet some <a href="https://twitter.com/xor/status/978793975590150144">fun trivia about airport codes</a> last night:</p> <blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">As far as I can tell, the longest words you can spell entirely out of airport codes are each 9 letters long. It&#39;s quite an evocative list of words, too. <a href="https://t.co/ssNMRz3s5O">pic.twitter.com/ssNMRz3s5O</a></p>&mdash; Parker Higgins (@xor) <a href="https://twitter.com/xor/status/978793975590150144?ref_src=twsrc%5Etfw">March 28, 2018</a></blockquote> <script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>Of all the 3-character codes, “IST” seems the most flexible when it comes to creating a legit combination with a 9-character word. Of course, “memberist” isn’t a word either, though Google at least has plenty of attempted results:</p> <p><img src="/files/images/posts/google-memberist.png" alt="google-memberist.png" /></p> <p>I wish I could say this blog post had a more important point about language or even search-engine optimization, but I just wanted to spoil the results for anyone else who ever searches for “submemberist” :p.</p> <blockquote> <p><strong>Update 2019-07-16:</strong> More than a year later, this blog is the only result for a <a href="https://www.google.com/search?q=submemberist">google search of “submemberist”</a>, which means my blog apparently isn’t notable enough to get content-scraped by SEO-spammers!</p> <p><img src="/files/images/submemberist-google-search.png" alt="image submemberist-google-search.png" /></p> </blockquote></description> <pubDate>Wed, 28 Mar 2018 00:00:00 -0500</pubDate> <link>http://blog.danwin.com/a-submemberist/</link> <guid isPermaLink="true">http://blog.danwin.com/a-submemberist/</guid> </item> <item> <title>How James Bamford exposed the NSA using the NSA's own company newsletter</title> <description><p>MuckRock <a href="https://www.muckrock.com/news/archives/2017/mar/27/cia-employee-activity-association/">recently posted a fun FOIA-related item about a declassified CIA memo on “Cover and Security Considerations”</a> for employees who want to have an after-work bowling league or glee club:</p> <blockquote> <p>In most professions, all it takes to form an after-work bowling league is an overly long email chain and some beer money. As a declassified memo recently unearthed in CREST shows, in the CIA, it’s a lot more complicated.</p> </blockquote> <blockquote> <p>…To cope with these rather unique challenges, the Agency formed the Employee Activity Association (EAA), which, in exchange for membership dues, would ensure that next weekend’s fishing trip would have a plausible cover story.</p> </blockquote> <blockquote> <p>…members were expected to keep the existence or non-existence of the ping-pong team a secret and to attend security briefings.</p> </blockquote> <p>This bureaucratic anal-retentiveness regarding mundane company functions immediately reminded me of <a href="https://en.wikipedia.org/wiki/James_Bamford">James Bamford</a>, the first journalist to bring mainstream attention to the National Security Agency when he published <a href="https://en.wikipedia.org/wiki/The_Puzzle_Palace">“The Puzzle Palace” in 1982</a>.</p> <p>There is a great profile of Bamford in Baltimore’s City Paper in which he describes finding an internal NSA newsletter that contained chatty and useful details about the agency and, like your typical chatty company newsletter, was meant for employees <em>and their families</em>. And since family members didn’t have special security clearances, that meant that all the NSA internal newsletters were eligible to be released by FOIA. Bamford was able to get thousands of pages of newsletters about the NSA, and that allowed him to greatly expand his knowledge and access to NSA officials.</p> <p>Unfortunately, City Paper seems to have undertaken one of those news site redesigns/content-management system overhauls <a href="https://www.theatlantic.com/technology/archive/2015/11/the-irony-of-writing-about-digital-preservation/416184/">in which the archives are eradicated from Internet history</a>. Luckily, the Internet Archive still has a copy of the original 2008 article by Lee Gardner: <em><a href="https://web-beta.archive.org/web/20111020180602/http://www.citypaper.com/news/story.asp?id=17031">Secrets and Lies: An Interview With National Security Agency Expert James Bamford</a></em></p> <p>Here’s the key excerpt, though the entire interview is a great read:</p> <blockquote> <p><strong>[City Pages]</strong>: Did you get any push-back from the agency when you started writing about it? After all, it’s supposed to be top secret.</p> </blockquote> <blockquote> <p><strong>[Bamford]</strong>: I had a difficult time. My advance was fairly small, I was living in Massachusetts, I didn’t really know anyone in intelligence, and I hadn’t written anything before. And I was going up against NSA.</p> </blockquote> <blockquote> <p>One of the things I was good at in law school was research, so I thought maybe I’d try using the Freedom of Information Act. The problem with that was, NSA is really the only agency excluded from the act. If you sent them a [FOIA] request, they would just send you a letter back saying [under Section 6 of the National Security Agency Act] we don’t have to give you anything, even if it’s unclassified.</p> </blockquote> <blockquote> <p>But I found this place, the George C. Marshall Research Library in Lexington, Virginia, and William F. Friedman, one of the founders of the NSA, had left all his papers there. When I got down there, I found the NSA had gotten there just before me and gone through all of his papers and taken a lot of his papers out and put them in a vault down there and ordered the archivist to keep them under lock and key. And I convinced the archivist that that wasn’t what Friedman wanted, and he took the documents out and let me take a look at them.</p> </blockquote> <blockquote> <p>Among the documents was an NSA newsletter. These are things the NSA puts out once a month. They’re fairly chatty, but if you read them closely enough you can pick up some pretty good information about the agency. . . . When I was reading one of the newsletters, there was a paragraph that said, “The contents of this newsletter must be kept within the small circle of NSA employees and their families.” And I thought about it for a little bit, and I thought, hmm, they just waived their protections on that newsletter–if that’s on every single newsletter then I’ve got a pretty good case against them. If you’re going to open it up to family members, with no clearance, who don’t work for the agency, then I have every right to it. That was a long battle, but I won it, and they gave me over 5,000 pages’ worth of NSA newsletters going back to the very beginning. That was the first time anyone ever got a lot of information out of NSA.</p> </blockquote> <blockquote> <p>We made this agreement where I could come down and spend a week at NSA, and they gave me a little room where I could go over the newsletters and pick the ones I wanted. So I got all that information, and spent about a week at NSA. And finally they really wanted to delete some names and faces, and I said you can do that, but there ought to be some kind of quid pro quo. The quid pro quo was that I get to interview senior officials and take a tour of the agency. And that was what really opened it up.</p> </blockquote> <blockquote> <p>It wasn’t the NSA you see today–it was much different. They just thought no one would ever try to write about NSA, and they didn’t think I would have any luck, because who am I? I’m just some guy up in Massachusetts with no track record.</p> </blockquote></description> <pubDate>Thu, 30 Mar 2017 00:00:00 -0500</pubDate> <link>http://blog.danwin.com/how-james-bamford-exposed-the-nsa-using-its-own-internal-newsletter/</link> <guid isPermaLink="true">http://blog.danwin.com/how-james-bamford-exposed-the-nsa-using-its-own-internal-newsletter/</guid> </item> <item> <title>Rabbit holes and writing.</title> <description><p>It’s about 1:50 A.M. and I’m reading a <a href="https://news.ycombinator.com/item?id=13823881">HN thread about a BBC article, titled “Rabbit hole leads to 700-year-old Knights Templar cave”</a>.</p> <p>Several users point out that the title is a bit of nonsense – “The reference to a rabbit hole makes no sense unless it’s symbolic, since rabbits holes are about the size of a rabbit”. That gets me thinking about the rabbit holes that led into the seemingly huge warrens described in <a href="https://en.wikipedia.org/wiki/Watership_Down">“Watership Down”</a>.</p> <p>Googling, “watership down rabbit facts” led me to this <a href="https://www.theguardian.com/books/2015/jan/04/richard-adams-watership-down-interview">2015 Guardian interview with author Richard Adams</a>; I knew the book originated from a whimsical story Adams made up to keep his daughters entertained on a car trip. I didn’t realize that he had never written fiction before, or that he was so late in his life when he started:</p> <blockquote> <p>Watership Down was one of the first of these stories. Adams was 52 and working for the civil service when his daughters began pleading with him to tell them a story on the drive to school. “I had been put on the spot and I started off, ‘Once there were two rabbits called Hazel and Fiver.’ And I just took it on from there.” <strong>Extraordinarily, he had never written a word of fiction before, but once he’d seen the story through to the end, his daughters said it was “too good to waste, Daddy, you ought to write that down”</strong>.</p> </blockquote> <blockquote> <p>He began writing in the evenings, and the result, an exquisitely written story about a group of young rabbits escaping from their doomed warren, won him both the Carnegie medal and the Guardian children’s prize. “It was rather difficult to start with,” he says. <strong>“I was 52 when I discovered I could write. I wish I’d known a bit earlier. I never thought of myself as a writer until I became one.”</strong></p> </blockquote></description> <pubDate>Thu, 09 Mar 2017 00:00:00 -0600</pubDate> <link>http://blog.danwin.com/never-too-late-to-start-writing/</link> <guid isPermaLink="true">http://blog.danwin.com/never-too-late-to-start-writing/</guid> </item> <item> <title>On automated journalism: Don't automate the good stuff</title> <description><p>I love and frequently recommend Al Weigart’s, <a href="https://automatetheboringstuff.com/">“Automate the Boring Stuff with Python”</a>, because it so perfectly captures how I feel about programming: programming is how we tell computers what to do. And computers, like all of the best mechanical inventions in existence, are best at doing mechanical, i.e. <em>boring</em> work.</p> <p>The inverse of that mentality – that computers should/can be used to automate the interesting work of our lives – can be found in this blog post (h/t <a href="https://twitter.com/ndiakopoulos/status/839668650181283840">@ndiakopoulos</a>) from the research blog <strong>Immersive Automation</strong>:</p> <div class="highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code>[Can computers quote like human journalists, and should they?](http://immersiveautomation.com/2017/03/can-computers-quote-like-human-journalists/) (emphasis added) When a reader enjoys a story in a magazine, they have no way of knowing how an interview between a journalist and a source was conducted. Even quotations – which are widely considered being verbatim repetitions of what has been said in the interview – might be very accurate, but they might as well be heavily modified, or even partially trumped-up. “For journalists, and their editors, **the most important thing is of course to produce a good piece of writing**. This means they might be forced to make compromises, since the citations must serve a purpose for the story,” Lauri Haapanen explains. </code></pre></div></div> <p>The rest of the post goes on to describe “nine essential quoting strategies used by journalists when writing articles”, which is an interesting discussion in itself. But I wanted to point out how fuzzy (or misguided) the statement bolded above is:</p> <div class="highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code>For journalists, and their editors, **the most important thing is of course to produce a good piece of writing**. </code></pre></div></div> <p>No.</p> <p>The most important thing to a journalist is to <strong>produce interesting reporting</strong>.</p> <p>Let’s look at the ledes – often considered the part of a story where good writing has (and needs) the most impact – of some published journalism:</p> <p>Those are the ledes for the winners of what is often considered journalism’s most important prize: the Pulitzer Prizer for Public Service</p> <p>The</p> <p><a href="http://www.pulitzer.org/winners/news-observer-raleigh-nc-work-melanie-sill-pat-stith-and-joby-warrick">News &amp; Observer in 1996</a></p> <p><a href="http://www.pulitzer.org/winners/boston-globe-1">Boston Globe</a> in <a href="http://www.pulitzer.org/winners/sun-sentinel">Sun Sentinel in 2013</a>,</p> <div class="highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code>North Carolina, hundreds of miles from America's traditional Midwest hog belt, has become the nation's No. 2 hog producer. Last year, hogs generated more than $1 billion in revenue -- more than tobacco. This year, hogs are expected to pass broiler chickens as the No. 1 agricultural commodity. One of the five men arrested early Saturday in the attempt to bug the Democratic National Committee headquarters is the salaried security coordinator for President Nixon’s reelection committee. The District of Columbia's Metropolitan Police Department has shot and killed more people per resident in the 1990s than any other large American city police force. Bell, one of the poorest cities in Los Angeles County, pays its top officials some of the highest salaries in the nation, including nearly $800,000 annually for its city manager, according to documents reviewed by The Times. Since the mid-1990s, more than 130 people have come forward with horrific childhood tales about how former priest John J. Geoghan allegedly fondled or raped them during a three-decade spree through a half-dozen Greater Boston parishes. </code></pre></div></div> <p>Here’s a clickbait version:</p> <div class="highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code> We've all seen it, and now there's proof: Police officers sworn to uphold our traffic laws are among the worst speeders on South Florida roads. </code></pre></div></div> <p>https://www.washingtonpost.com/politics/gop-security-aide-among-five-arrested-in-bugging-affair/2012/06/07/gJQAYTdzKV_story.html</p> <p>And here are a couple of ledes from the la times, which, when read in isolation, falls into the “OK is Dunia and why should I give a shit?”</p> <p>http://www.pulitzer.org/winners/los-angeles-times-3</p> <p>But “just the facts” isn’t the sole mark of a good</p> <p>On a warm July afternoon, an impish second-grader named Dunia Tasejo was running home after buying ice cream on her South Los Angeles street when a car sideswiped her. Knocked to the pavement, she screamed for help, blood pouring from her mouth.</p> <hr /> <p>I’m being unfair, maybe, because “good” can encompass all of those examples. But that’s my point – “good writing” has no obvious meaning when it comes to journalism or any other form of writing. It is up to the discretion and style of the writers.</p> <p>But important journalism – journalism that is important to publish. It’s facts.</p> <hr /> <p>I went into journalism because I liked writing and am old enough that, when I worked for my college paper, it had enough paper to print 10,000 words, in actual pieces of paper with real ink.</p> <hr /> <p>But I don’t think that computers can’t replace a lot of what humans do. They already do – page layout, copy-editing (of the spell-check variety), and research (of the Google-variety) – have all been replaced. Because much of it was mechanical. But the biggest outlets still hire copy editors (also known as fact checkers) and researchers for the bespoke work.</p> <p>How much of quoting is bespoke work? Depends. I contend that of all the parts of writing that can be automated, it’s one of the least in terms of return on investment.</p> <p>To describe writing like this:</p> <blockquote> <p>The Immersive Automation-project focuses on news automation and algorithmically produced news. Since human-written journalistic texts often contain quotations, automated content should also include them to meet the traditional expectations of readers.</p> </blockquote> <p>No it shouldn’t. That’s one of the things I learned in journalism school: don’t quote parts just repeat someone.</p> <blockquote> <p>In the development process of news automation, it is realistic to expect human journalists and machines to collaborate.</p> <p>“A text generator could write a story and a journalist could interview sources and add quotations in suitable places,” says Haapanen.</p> </blockquote> <p>Also the headline annoys me. It’s not about <strong>can</strong>. Nor is it about <strong>should</strong>.</p></description> <pubDate>Wed, 08 Mar 2017 00:00:00 -0600</pubDate> <link>http://blog.danwin.com/on-automated-journalism-don-t-automate-the-good-stuff/</link> <guid isPermaLink="true">http://blog.danwin.com/on-automated-journalism-don-t-automate-the-good-stuff/</guid> </item> <item> <title>Jekyll websites, open-source and in the real-world</title> <description><p>A student hoping to build a project in Jekyll asked me for examples of well-known, well-designed Jekyll sites.</p> <p>Of course, a site’s visual appearance technically has nothing to do with its framework – e.g. Jekyll vs. Hugo vs. WordPress vs. Drupal, etc. But for folks starting out, important conventions and best practices – such as how to write the template files, which folders to put CSS and other asset files, how to incorporate Bootstrap/SASS/etc., and overall site configuration – are much easier to learn when having source code from sites built with the same framework.</p> <p>So I’ve compiled a short list (and am happy to take suggestions) of Jekyll sites that:</p> <ol> <li>Have their source code available to clone and learn from.</li> <li>Aren’t just blogs.</li> <li>Are attractive.</li> <li>Are popular.</li> </ol> <p>Most of these sites have lots of data, content, and words. So they won’t be the most <em>beautiful</em>, in the sense of content-lite sites that feature of chasms of white space and <a href="https://unsplash.com/">beautiful Unsplash-worthy hero images</a>. But I rate their attractiveness in relation to their <em>function</em>. Most of them are aimed at a general audience (especially the government sites). And many of them have to relay a large array of data and content.</p> <p>If the official documentation on Jekyll’s <a href="https://jekyllrb.com/docs/datafiles/">data files</a>, <a href="https://jekyllrb.com/docs/collections/">collections</a>, and <a href="https://jekyllrb.com/docs/variables/">site variables</a> don’t make immediate sense to you, then take a look at these examples’ repos to see how the professionals organize their Jekyll projects.</p> <h6 id="templates-showcase-from-jekyll-tips">Templates showcase from Jekyll Tips</h6> <p><a href="http://jekyll.tips/templates/"><img src="/files/images/jekyll-examples-jekyll-tips.png" alt="jekyll-examples-jekyll-tips.png" /></a></p> <p><a href="http://jekyll.tips/templates/">http://jekyll.tips/templates/</a></p> <p>OK, most of these templates are geared toward Jekyll’s original use-case: blogs. But front-end assets for Jekyll blogs can be implemented in the same fashion for Jekyll sites that aren’t straightforward blogs. Each of the templates in this showcase have an associated Github repo.</p> <h6 id="github-on-demand-training">Github On-Demand Training</h6> <p>Since <a href="https://jekyllrb.com/">Jekyll itself came out of Github</a> and is used to power Github’s extremely popular <a href="https://help.github.com/articles/what-is-github-pages/">Github Pages feature</a>, pretty much all of Github’s static content is done in Jekyll. I’ve tried to list the more notable examples that have their source code available.</p> <p>Here’s their On-Demand Training page, which is a homepage for their “How-to Use Github/Git” guides, cheat-sheets, and curricula:</p> <p><a href="https://services.github.com/on-demand/">https://services.github.com/on-demand/</a></p> <p>The repo: <a href="https://github.com/github/training-kit">https://github.com/github/training-kit</a></p> <p><a href="https://services.github.com/on-demand/"> <img src="/files/images/jekyll-examples-github-ondemand-training.jpg" alt="jekyll-examples-github-ondemand-training.jpg" /> </a></p> <p><a href="https://services.github.com/on-demand/intro-to-github/"> <img src="/files/images/jekyll-examples-github-ondemand-training-intro.jpg" alt="jekyll-examples-github-ondemand-training-intro.jpg" /> </a></p> <h6 id="githubs-open-source-guide">Github’s Open Source Guide</h6> <p><a href="https://opensource.guide/"> <img src="/files/images/jekyll-examples-github-open-source.png" alt="jekyll-examples-github-open-source.png" /> </a></p> <p><a href="https://opensource.guide/">https://opensource.guide/</a></p> <p>Repo: <a href="https://github.com/github/open-source-guide">https://github.com/github/open-source-guide</a></p> <p>This isn’t a “complex” site, per se, but it’s a nice non-blog site if you need an example of how to structure a page-based site in Jekyll.</p> <h6 id="marksheet">MarkSheet</h6> <p><a href="http://marksheet.io/"> <img src="/files/images/jekyll-examples-marksheet-index.png" alt="jekyll-examples-marksheet-index.png" /> </a></p> <p><a href="http://marksheet.io/html-images.html"> <img src="/files/images/jekyll-examples-marksheet-images-lesson.png" alt="jekyll-examples-marksheet-images-lesson.png" /> </a></p> <p><a href="http://marksheet.io/">http://marksheet.io/</a></p> <p>Repo: <a href="https://github.com/jgthms/marksheet">https://github.com/jgthms/marksheet</a></p> <p>MarkSheet is a free HTML and CSS tutorial site. Nice example of how to structure a Jekyll site to accommodate book-reference-like content.</p> <h6 id="consumer-financial-protection-bureaus-developer-homepage">Consumer Financial Protection Bureau’s Developer Homepage</h6> <p><a href="https://cfpb.github.io/">https://cfpb.github.io/</a></p> <p>Repo: <a href="https://github.com/cfpb/cfpb.github.io">https://github.com/cfpb/cfpb.github.io</a></p> <p>If you want great examples of how to build data-intensive services and sites, there are few better organizations than the CFPB, which, since it’s a government agency, means their work is in the public domain.</p> <p>Not all of their excellent sites use Jekyll as their front-end (such as <a href="https://github.com/cfpb/hmda-explorer">the HDMA explorer</a>), but the CFPB’s dev/tech homepage uses it as both a landing page and a blog.</p> <p><a href="https://cfpb.github.io/"> <img src="/files/images/jekyll-examples-cfpb-homepage.png" alt="jekyll-examples-cfpb-homepage.png" /> </a></p> <h6 id="the-presidential-innovation-fellows">The Presidential Innovation Fellows</h6> <p><a href="https://presidentialinnovationfellows.gov/"> <img src="/files/images/jekyll-examples-presidential-fellows-homepage.jpg" alt="jekyll-examples-presidential-fellows-homepage.jpg" /> </a></p> <p><a href="https://presidentialinnovationfellows.gov/fellows/"> <img src="/files/images/jekyll-examples-presidential-fellows.jpg" alt="jekyll-examples-presidential-fellows.jpg" /> </a></p> <p><a href="https://www.presidentialinnovation.org/">https://www.presidentialinnovation.org/</a></p> <p>Repo: <a href="https://github.com/18F/presidential-innovation-foundation.github.io">https://github.com/18F/presidential-innovation-foundation.github.io</a></p> <hr /> <p>The Analytics page for the federal government uses Jekyll to tie together Javascript code for reading from APIs and making charts: https://analytics.usa.gov/</p> <p>repo: https://github.com/18F/analytics.usa.gov</p> <hr /> <hr /> <p>Our own Stanford Computational Journalism Lab homepage is in Jekyll:</p> <p>http://cjlab.stanford.edu/</p> <p>repo: https://github.com/compjolab/cjlab-homepage</p> <hr /> <p>Believe it or not, but healthcare.gov – the front-facing static parts, were built in Jekyll: https://www.healthcare.gov/</p> <p>They took down their source code but here is an old version of it: https://github.com/dannguyen/healthcare.gov</p> <p>And here’s what that old code produced: http://healthcaregov-jekyll.s3.amazonaws.com/index.html</p> <p>Here’s a piece in the Atlantic by an open-gov advocate, which is about why healthcare.gov is open source (or was, before the non-Jekyll parts of the site failed to live up to the traffic):</p> <p>https://www.theatlantic.com/technology/archive/2013/06/healthcaregov-code-developed-by-the-people-and-for-the-people-released-back-to-the-people/277295/</p> <hr /> <p>18F is the digital agency for the federal government. Much of the modern and best webdev of the U.S. gov is through their shop:</p> <p>18F’s homepage: https://18f.gsa.gov/ repo: https://github.com/18F/18f.gsa.gov</p> <p>Their handbook: https://handbook.18f.gov/ repo: https://github.com/18F/handbook</p> <p>Here’s a post by them about why they switched to Jekyll.</p> <p>https://18f.gsa.gov/2014/11/17/taking-control-of-our-website-with-jekyll-and-webhooks/</p> <hr /> <p>https://stackoverflow.blog/</p> <p>https://github.com/StackExchange/stack-blog</p> <p>https://stackoverflow.blog/2015/07/01/the-new-stack-exchange-blog/</p> <p>https://stackoverflow.blog/2015/07/02/how-we-built-our-blog/</p></description> <pubDate>Wed, 08 Mar 2017 00:00:00 -0600</pubDate> <link>http://blog.danwin.com/complex-open-source-jekyll-websites-in-the-wild/</link> <guid isPermaLink="true">http://blog.danwin.com/complex-open-source-jekyll-websites-in-the-wild/</guid> </item> <item> <title>Finding Stories in Data: A presentation to college journalists</title> <description><p>This past weekend, I did a quick session at the <a href="http://acpsanfran.org/">Associated Collegiate Press Midwinter National College Journalism Convention</a> on how to find stories in data.</p> <p>You can find a repo with links to my slides and my big list of links here:</p> <p><a href="https://github.com/dannguyen/acp-2017-finding-stories-in-data">https://github.com/dannguyen/acp-2017-finding-stories-in-data</a></p> <p>The slides:</p> <iframe src="https://docs.google.com/presentation/d/11wmCbXJ8CjUAnt8k7A_j3-v2vybphhvh5NHISbA-EM8/embed?start=false&amp;loop=false&amp;delayms=3000" frameborder="0" width="960" height="569" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe> <p>It’s not a great or finished presentation, but I’ve been meaning to put together a reusable deck/source list so I can do more of these presentations, so it’s a start. Since this session was for college journalists, most of whom I assume fit the “unknowledgable-of-statistics” mold, I tried to talk about projects that were relevant and feasible for their newsrooms.</p> <p>In terms of how to get started, my best advice was to join crowdsourcing efforts put on by organizations like ProPublica. Data entry/collection is always a dry affair, but it is always necessary. So it’s all the better if you can find data entry that works towards a good cause. Here’s a few examples:</p> <ul> <li><a href="http://www.fatalencounters.org/">Fatal Encounters</a> - Well before Ferguson, this project – started by a single, curious journalist – recognized the severe deficiency of data on police shootings.</li> <li><a href="https://projects.propublica.org/graphics/hatecrimes">Documenting Hate</a> - ProPublica’s initiative to count hate crimes and bias incidents and create a national dataset.</li> <li><a href="https://www.buzzfeed.com/johntemplon/help-us-map-trumpworld?utm_term=.syzw4LwmP#.eyzXdmXB7">TrumpWorld</a> - BuzzFeed has logged more than 1,500 of the Trump Administration’s business and personal connections. Use their spreadsheet and help them find more connections.</li> </ul> <p>The best insight I found while gathering material was this GQ interview with Fatal Encounters founder D. Brian Burghart: <a href="http://www.gq.com/story/fatal-encounters-police-statistics-interview">Meet the Man Who Spends 10 Hours a Day Tracking Police Shootings</a>.</p> <p>Here’s how I documented it in slides:</p> <p><img src="/files/images/fatal-encounters-burghart-slide-01.png" alt="image fatal-encounters-burghart-slide-01.png" /></p> <p><img src="/files/images/fatal-encounters-burghart-slide-02.png" alt="image fatal-encounters-burghart-slide-02.png" /></p> <p><img src="/files/images/fatal-encounters-burghart-slide-03.png" alt="image fatal-encounters-burghart-slide-03.png" /></p> <p><img src="/files/images/fatal-encounters-burghart-slide-04.png" alt="image fatal-encounters-burghart-slide-04.png" /></p> <p><img src="/files/images/fatal-encounters-burghart-slide-05.png" alt="image fatal-encounters-burghart-slide-05.png" /></p> <p><img src="/files/images/fatal-encounters-burghart-slide-06.png" alt="image fatal-encounters-burghart-slide-06.png" /></p> <p>The main technical advice I gave to students was: Use a spreadsheet for <strong>everything</strong>. Burghart’s vital contribution to journalism is proof of this method.</p></description> <pubDate>Mon, 06 Mar 2017 00:00:00 -0600</pubDate> <link>http://blog.danwin.com/finding-stories-in-data-a-presentation-to-college-journalists/</link> <guid isPermaLink="true">http://blog.danwin.com/finding-stories-in-data-a-presentation-to-college-journalists/</guid> </item> </channel> </rss>
<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> <channel> <title>Dan Nguyen's Blog | Thoughts, Data and Computational Journalism</title> <description>Dan Nguyen is a programmer and computational journalist</description> <link>http://blog.danwin.com/</link> <atom:link href="http://blog.danwin.com/feed.xml" rel="self" type="application/rss+xml"/> <pubDate>Tue, 21 Jul 2020 13:20:11 -0500</pubDate> <lastBuildDate>Tue, 21 Jul 2020 13:20:11 -0500</lastBuildDate> <generator>Jekyll v3.8.6</generator> <item> <title>How to automatically timestamp a new row in Google Sheets using Apps Script</title> <description><p>One of my most frequent everyday usecases for spreadsheets is casual tracking of personal activity, like daily exercise, or my progress in Duolingo; here’s what the spreadsheets for those two examples look like, respectively:</p> <p><img src="/files/images/posts/screenshots/daily-spreadsheets.png" alt="image daily-spreadsheets.png" /></p> <p>You’ll notice that both have a <strong>datetime</strong> field – I include this not because I’m particularly anal about when exactly I did something, but because maybe down the road I want to do a quickie pivot table analysis, like how often I did things in the morning versus evening, or weekday versus weekend, etc.</p> <p>More data is <em>generally</em> better than less, since if I don’t capture this info, I can’t go back in time to redo the spreadsheet. However, the mundane work of data entry for an extra field, especially added up over months, risks creating enough friction that I might eventually abandon my “casual tracking”.</p> <p>Google Sheets does provide <a href="https://webapps.stackexchange.com/a/24692/53055">handy keyboard shortcuts</a> for adding date and time to a field:</p> <ul> <li><code class="highlighter-rouge">Ctrl</code>/<code class="highlighter-rouge">Cmd</code>+<code class="highlighter-rouge">:</code> to insert date: <code class="highlighter-rouge">7/21/2020</code></li> <li><code class="highlighter-rouge">Ctrl</code>/<code class="highlighter-rouge">Cmd</code>+<code class="highlighter-rouge">Shift</code> + <code class="highlighter-rouge">:</code> to insert time: <code class="highlighter-rouge">3:25:24 PM</code></li> <li><code class="highlighter-rouge">Ctrl</code>/<code class="highlighter-rouge">Cmd</code>+ <code class="highlighter-rouge">Alt</code> + <code class="highlighter-rouge">Shift</code> + <code class="highlighter-rouge">:</code> to insert the full timestamp: <code class="highlighter-rouge">7/21/2020 12:05:46</code></li> </ul> <p>However, doing that per row is still <em>work</em>; more importantly, I wanted to be able to use the iOS version of Google Sheets to enter exercises as soon as I did them (e.g. random sets of pushups or pullups), and these time/date shortcuts are non-existent.</p> <p>What I needed was for the <strong>datetime</strong> field to be automatically be filled <em>each time I started a new row</em>, i.e. as soon as I filled out the first field of a new row, e.g. Duolingo <strong>word</strong> or exercise <strong>type</strong>.</p> <h2 id="the-solution">The solution</h2> <p>What I wanted can be done by using the <strong>Script Editor</strong> and writing a <a href="https://developers.google.com/apps-script/guides/sheets">Google Apps Script snippet</a>. Here are the steps:</p> <p>First, create a Google Sheet that has at least 2 columns, and with one of the non-first columns titled <strong>datetime</strong>:</p> <p><img src="/files/images/posts/screenshots/google-sheets-blank-datetime-template.png" alt="image google-sheets-blank-datetime-template.png" /></p> <p>Then, from the menubar, open <strong>Tools » Script Editor</strong>:</p> <p><img src="/files/images/posts/screenshots/google-sheets-menu-script-editor.png" alt="image google-sheets-menu-script-editor.png" /></p> <p>This will take you to a blank template for a new Google App Script project/file:</p> <p><img src="/files/images/posts/screenshots/google-sheets-app-script-editor-new.png" alt="image google-sheets-app-script-editor-new.png" /></p> <p>One of the features of Google Apps Script for Google Sheets is <a href="https://developers.google.com/apps-script/guides/triggers">simple triggers</a>, i.e. functions with reserved names like <code class="highlighter-rouge">onOpen(e)</code>, <code class="highlighter-rouge">onEdit(e)</code>, and <code class="highlighter-rouge">onSelectionChange(e)</code> that execute on common document events. What we want is to change a row (i.e. insert a timestamp) when it is edited, so we want <code class="highlighter-rouge">onEdit(e)</code>:</p> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code><span class="kd">function</span> <span class="nx">onEdit</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span> </code></pre></div></div> <p>But before we get into <code class="highlighter-rouge">onEdit</code>, we want a helper function that, given a fieldname like <code class="highlighter-rouge">"datetime"</code>, it returns the column index as Google Sheets understands it, e.g. <code class="highlighter-rouge">2</code>, in the given screenshot examples. Here’s one way to write that function, which we’ll call <code class="highlighter-rouge">getDatetimeCol()</code>:</p> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code><span class="kd">var</span> <span class="nx">SHEET_NAME</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Sheet1</span><span class="dl">'</span><span class="p">;</span> <span class="kd">var</span> <span class="nx">DATETIME_HEADER</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">datetime</span><span class="dl">'</span><span class="p">;</span> <span class="kd">function</span> <span class="nx">getDatetimeCol</span><span class="p">(){</span> <span class="kd">var</span> <span class="nx">headers</span> <span class="o">=</span> <span class="nx">SpreadsheetApp</span><span class="p">.</span><span class="nx">getActiveSpreadsheet</span><span class="p">().</span><span class="nx">getSheetByName</span><span class="p">(</span><span class="nx">SHEET_NAME</span><span class="p">).</span><span class="nx">getDataRange</span><span class="p">().</span><span class="nx">getValues</span><span class="p">().</span><span class="nx">shift</span><span class="p">();</span> <span class="kd">var</span> <span class="nx">colindex</span> <span class="o">=</span> <span class="nx">headers</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">DATETIME_HEADER</span><span class="p">);</span> <span class="k">return</span> <span class="nx">colindex</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <p>The <code class="highlighter-rouge">onEdit()</code> function can be described like this:</p> <ul> <li>get the currently edited cell (which requires getting the currently active sheet)</li> <li><strong>if</strong> the edited cell (i.e. active cell) is in the first column <ul> <li><strong>and</strong> it is <strong>not</strong> blank</li> <li><strong>and</strong> the corresponding datetime field <strong>is</strong> blank</li> </ul> </li> <li><strong>then</strong> set the value of the datetime field to the current timestamp – in this example, I use the <a href="https://en.wikipedia.org/wiki/ISO_8601">ISO 8601</a> standard of <code class="highlighter-rouge">2020-07-20 14:03</code></li> </ul> <p>Here’s the entire code snippet with both functions:</p> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code><span class="kd">var</span> <span class="nx">SHEET_NAME</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Sheet1</span><span class="dl">'</span><span class="p">;</span> <span class="kd">var</span> <span class="nx">DATETIME_HEADER</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">datetime</span><span class="dl">'</span><span class="p">;</span> <span class="kd">function</span> <span class="nx">getDatetimeCol</span><span class="p">(){</span> <span class="kd">var</span> <span class="nx">headers</span> <span class="o">=</span> <span class="nx">SpreadsheetApp</span><span class="p">.</span><span class="nx">getActiveSpreadsheet</span><span class="p">().</span><span class="nx">getSheetByName</span><span class="p">(</span><span class="nx">SHEET_NAME</span><span class="p">).</span><span class="nx">getDataRange</span><span class="p">().</span><span class="nx">getValues</span><span class="p">().</span><span class="nx">shift</span><span class="p">();</span> <span class="kd">var</span> <span class="nx">colindex</span> <span class="o">=</span> <span class="nx">headers</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">DATETIME_HEADER</span><span class="p">);</span> <span class="k">return</span> <span class="nx">colindex</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="p">}</span> <span class="kd">function</span> <span class="nx">onEdit</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">ss</span> <span class="o">=</span> <span class="nx">SpreadsheetApp</span><span class="p">.</span><span class="nx">getActiveSheet</span><span class="p">();</span> <span class="kd">var</span> <span class="nx">cell</span> <span class="o">=</span> <span class="nx">ss</span><span class="p">.</span><span class="nx">getActiveCell</span><span class="p">();</span> <span class="kd">var</span> <span class="nx">datecell</span> <span class="o">=</span> <span class="nx">ss</span><span class="p">.</span><span class="nx">getRange</span><span class="p">(</span><span class="nx">cell</span><span class="p">.</span><span class="nx">getRowIndex</span><span class="p">(),</span> <span class="nx">getDatetimeCol</span><span class="p">());</span> <span class="k">if</span> <span class="p">(</span><span class="nx">ss</span><span class="p">.</span><span class="nx">getName</span><span class="p">()</span> <span class="o">==</span> <span class="nx">SHEET_NAME</span> <span class="o">&amp;&amp;</span> <span class="nx">cell</span><span class="p">.</span><span class="nx">getColumn</span><span class="p">()</span> <span class="o">==</span> <span class="mi">1</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nx">cell</span><span class="p">.</span><span class="nx">isBlank</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="nx">datecell</span><span class="p">.</span><span class="nx">isBlank</span><span class="p">())</span> <span class="p">{</span> <span class="nx">datecell</span><span class="p">.</span><span class="nx">setValue</span><span class="p">(</span><span class="k">new</span> <span class="nb">Date</span><span class="p">()).</span><span class="nx">setNumberFormat</span><span class="p">(</span><span class="dl">"</span><span class="s2">yyyy-MM-dd hh:mm</span><span class="dl">"</span><span class="p">);</span> <span class="p">}</span> <span class="p">};</span> </code></pre></div></div> <p>Now, select <strong>File » Save</strong> and give your project a name (it can be anything):</p> <p><img src="/files/images/posts/screenshots/google-sheets-app-script-editor-save-project.png" alt="image google-sheets-app-script-editor-save-project.png" /></p> <p>And your sheet should have the power of auto-inserted timestamps:</p> <p><img src="/files/images/gifs/google-sheets-autotimestamp.gif" alt="gif animation of google sheet auto updating" /></p> <p>Big thanks to the following resources, from which I adapted my solution:</p> <ul> <li><a href="https://support.google.com/docs/thread/12320385?hl=en&amp;msgid=12326611">Abbas Abdulla’s response to the post “Automatic Timestamp when a Cell on the same row gets Updated”, on Google Docs Editors Help forum</a></li> <li><a href="https://stackoverflow.com/questions/31214352/how-to-use-a-column-header-to-reference-a-cell-in-google-apps-script-spreadsheet">StackOverflow: How to use a column header to reference a cell in Google Apps Script Spreadsheet</a></li> </ul> </description> <pubDate>Tue, 21 Jul 2020 12:14:00 -0500</pubDate> <link>http://blog.danwin.com/how-to-automatically-timestamp-a-new-row-in-google-sheets-using-apps-script/</link> <guid isPermaLink="true">http://blog.danwin.com/how-to-automatically-timestamp-a-new-row-in-google-sheets-using-apps-script/</guid> </item> <item> <title>NYPD Stop, Question, and Frisk Worksheet (UF-250); My attempt at getting the latest version as 'just a researcher'</title> <description><p><strong>June 26, 2020 update:</strong> I hadn’t received a response to this and let it fall by the wayside, but a few people have emailed asking for an update, so I will try again. Note that the Bloomberg era of NYPD Stop and Frisk <a href="https://www.nytimes.com/2020/03/02/upshot/stop-and-frisk-bloomberg.html">made the news</a> during his 2020 presidential candidacy.</p> <p>I’m writing a book about using SQL for data journalism, and one of the sections will be about the <a href="https://danwin.com/2010/07/the-nyts-cop-stop-and-frisk-graphic/">NYPD’s Stop and Frisk data</a>, which has a long history as both data and policy. In my book, I frequently assert that researching the data is much more important than any programming and database skill. And this includes finding the actual forms – paper or electronic – used for collecting the data.</p> <p>For a stop-and-frisk encounter by the NYPD, police officers have to fill out a <strong>Stop, Question, and Frisk Worksheet (PD 344-151A)</strong>, also known as a Unified Form 250, aka UF-250. The <a href="https://ccrjustice.org/sites/default/files/assets/files/11%2025%2013%20Opp%20to%20Mot%20to%20Intervene%20Decl%20of%20D%20Charney%20Ex%20H.pdf">2011 version</a> has two sides.</p> <p>This is the first:</p> <p><img src="/files/images/uf250-2011-side-1.png" alt="uf250-2011-side-1.png" /></p> <p>And the second side:</p> <p><img src="/files/images/uf250-2011-side-2.png" alt="uf250-2011-side-2.png" /></p> <p>However, after <a href="https://www.nytimes.com/2013/08/13/nyregion/stop-and-frisk-practice-violated-rights-judge-rules.html">a federal judge ruled in 2013</a> that the NYPD’s stop-and-frisk practices violated the constitutional rights of New York’s minorities, the NYPD agreed in 2015 to revise the form, which included requiring officers <a href="https://www.nydailynews.com/new-york/stop-and-frisk-forms-require-details-nypd-article-1.2574886">to write a detailed explanation</a> for why they made a stop.</p> <p>From a <a href="https://www1.nyc.gov/assets/ccrb/downloads/pdf/investigations_pdf/20150302_finest-message-stop-frisk-pursuant-to-floyd.pdf">March 2, 2015 NYPD memo titled “COURT-ORDERED CHANGES TO NYPD PRACTICES AND POLICES RELATED TO STOPS AND FRISKS”</a>:</p> <blockquote> <p>(2) THE DEPARTMENT FORM ENTITLED STOP, QUESTION AND FRISK REPORT WORKSHEET (PD 344-151A), COMMONLY REFERRED TO AS A UF 250 FORM, MUST BE REVISED TO INCLUDE A NARRATIVE SECTION WHERE AN OFFICER MUST RECORD, IN HIS OR HER OWN WORDS, THE BASIS FOR THE STOP. THE NEW FORM MUST ALSO INCLUDE A SEPARATE EXPLANATION OF WHY A FRISK WAS CONDUCTED. THE CHECKBOX SYSTEM CURRENTLY IN USE MUST BE SIMPLIFIED AND IMPROVED.</p> </blockquote> <p>Previously, NYPD officers could simply check a box labeled with “Furtive Movements”, which was apparently <a href="https://www.nytimes.com/2011/12/18/opinion/sunday/young-black-and-frisked-by-the-nypd.html">the sole and vague reason for half of the 600,000 stops conducted in 2010</a>, and which led to the lawsuit in the first place.</p> <p>Anyway, I need this new version of UF-250 for my book. But I could not find it via my Google-fu, including searches for <a href="https://www.google.com/search?q=stop+frisk+site%3Anyc.gov+filetype%3Apdf"><code class="highlighter-rouge">stop frisk site:nyc.gov filetype:pdf</code></a> and <a href="https://www.google.com/search?q=344-151A+filetype%3Apdf&amp;oq=344-151A+filetype%3Apdf"><code class="highlighter-rouge">344-151A filetype:pdf</code></a>, so I guess it’s time to contact the <a href="https://www1.nyc.gov/site/nypd/bureaus/administrative/public-information.page">NYPD’s Public Information office</a>.</p> <p>It’s just a form, so I wouldn’t think it requires the formality of a <a href="https://www1.nyc.gov/site/cchr/about/submit-a-foil-request.page">FOIL request</a> (right?) and the boilerplate language. So I’ll try a friendly email. For the first time in awhile, I’m making this kind of request as someone not currently working for a journalism organization, so here’s how I worded the email, sent from my personal GMail account:</p> <hr /> <p>Hello,</p> <p>My name is Dan Nguyen and I am researching law enforcement policy. I’ve been able to find past revisions of the UF-250 form used in Stop and Frisks, such as from 2000 [1] and 2007 [2], but I haven’t found any since the 2015 Floyd v. City of New York decision [3], which required these revisions:</p> <blockquote> <p>… THE DEPARTMENT FORM ENTITLED STOP, QUESTION AND FRISK REPORT WORKSHEET (PD 344-151A), COMMONLY REFERRED TO AS A UF 250 FORM, MUST BE REVISED TO INCLUDE A NARRATIVE SECTION WHERE AN OFFICER MUST RECORD, IN HIS OR HER OWN WORDS, THE BASIS FOR THE STOP. THE NEW FORM MUST ALSO INCLUDE A SEPARATE EXPLANATION OF WHY A FRISK WAS CONDUCTED. THE CHECKBOX SYSTEM CURRENTLY IN USE MUST BE SIMPLIFIED AND IMPROVED.</p> </blockquote> <p>Could you direct me to where the latest revision of UF-250 exists on the NYPD’s website? Or send to my email ([email protected]).</p> <p>Thank you, Dan Nguyen</p> <p>References:</p> <p>[1] <a href="https://www1.nyc.gov/assets/ccrb/downloads/pdf/policy_pdf/issue_based/20010601_sqf.pdf">https://www1.nyc.gov/assets/ccrb/downloads/pdf/policy_pdf/issue_based/20010601_sqf.pdf</a></p> <p>[2] <a href="https://www1.nyc.gov/assets/nypd/downloads/pdf/public_information/TR534_FINALCompiled.pdf">https://www1.nyc.gov/assets/nypd/downloads/pdf/public_information/TR534_FINALCompiled.pdf</a></p> <p>[3] <a href="https://www1.nyc.gov/assets/ccrb/downloads/pdf/investigations_pdf/20150302_finest-message-stop-frisk-pursuant-to-floyd.pdf">https://www1.nyc.gov/assets/ccrb/downloads/pdf/investigations_pdf/20150302_finest-message-stop-frisk-pursuant-to-floyd.pdf</a></p> <hr /> <p>Note: So I sent this email <em>before</em> I blogged about it, which is why there this error in the text: the Floyd v. City of New York decision was in <em>2013</em>; <a href="https://www1.nyc.gov/assets/ccrb/downloads/pdf/investigations_pdf/20150302_finest-message-stop-frisk-pursuant-to-floyd.pdf">2015 is the date of the NYPD memo</a> asserting the new revisions. Oops.</p> <p>As for why I’m blogging this: just for funsies. If I get a response, I’ll update and link to the new form for the benefit of fewer researchers. And if not, I’ll update and append my ongoing FOIL adventure.</p> <hr /> <p>Other useful reading and links (updated June 2020):</p> <ul> <li><a href="https://www.courtlistener.com/docket/4347389/davis-v-the-city-of-new-york/?filed_after=&amp;filed_before=&amp;entry_gte=&amp;entry_lte=&amp;order_by=desc">CourtListener/PACER: Davis v. The City of New York (1:10-cv-00699) Docket</a></li> <li><a href="https://www.courtlistener.com/recap/gov.uscourts.nysd.357782/gov.uscourts.nysd.357782.355.0.pdf">MEMO ENDORSEMENT on re: (246 in 1:12-cv-02274-AT-HBP) Status Report filed by Peter L Zimroth, (354 in 1:10-cv-00699-AT-HBP) Status Report filed by Peter L. Zimroth, (526 in 1:08-cv-01034-AT-HBP) Status Report filed by Peter A. Zimroth, re: Recommendation Regarding Stop Report Form. ENDORSEMENT: APPROVED. SO ORDERED. (Signed by Judge Analisa Torres on 3/25/2016) (kko) (Entered: 03/25/2016)</a></li> <li><a href="https://www.nyclu.org/sites/default/files/field_documents/20190314_nyclu_stopfrisk_singles.pdf">NYCLU March 2019 Report: Stop-and-Frisk in the de Blasio Era </a></li> <li><a href="https://www.nydailynews.com/new-york/nyc-crime/ny-stop-question-and-frisk-numbers-jump-20200210-vamjtzdfcvdorot57ajtrhnghu-story.html">NY Daily News: NYPD stop-and-frisk numbers jumped by 22% in 2019 from prior year: report</a></li> <li><a href="https://gothamist.com/news/nyc-ending-illegal-stop-and-frisk-era">Gothamist: NYC Has “A Long Way To Go” To End The Illegal Stop-And-Frisk Era</a></li> <li> <p><a href="https://www.nytimes.com/2020/03/02/upshot/stop-and-frisk-bloomberg.html">NYT: The Lasting Effects of Stop-and-Frisk in Bloomberg’s New York</a></p> </li> <li><a href="http://www.nyc.gov/html/nypd/downloads/pdf/analysis_and_planning/212-11.pdf">NYPD Patrol Guide: Procedure No. 212-11: INVESTIGATIVE ENCOUNTERS: REQUESTS FOR INFORMATION, COMMON LAW RIGHT OF INQUIRY AND LEVEL 3 STOPS</a></li> <li><a href="http://www.nyc.gov/html/ccrb/downloads/pdf/2016pg/pg221-02-use-of-force.pdf">NYPD Patrol Guide: Procedure No. 221-02: USE OF FORCE </a></li> <li><a href="http://directives.chicagopolice.org/forms/CPD-11.910.pdf">Chicago Police Investigatory Stop Report</a></li> </ul> </description> <pubDate>Thu, 28 Nov 2019 00:00:00 -0600</pubDate> <link>http://blog.danwin.com/request-nypd-form-uf250/</link> <guid isPermaLink="true">http://blog.danwin.com/request-nypd-form-uf250/</guid> </item> <item> <title>The scammers of Harvard Law's Bruce Hay and the "Nigerian Prince" filter</title> <description><p>There’s too much to process in <a href="https://www.thecut.com/2019/07/bruce-hay-paternity-trap-maria-pia-shuman-mischa-haider.html">“The Most Gullible Man in Cambridge “</a>, the Kera Bolonik longform piece that dropped yesterday on the <em>New York Magazine/The Cut</em> website. For starters, just how <a href="https://twitter.com/BrandyLJensen/status/1153727879215235073">completely bananas</a> it is from top to bottom. And then, whether the main character and victim, <a href="https://hls.harvard.edu/faculty/directory/10374/Hay">Professor Bruce Hay of Harvard Law</a>, is a reliable and trustworthy narrator. And of course, the absolute marvel of long suffering patience and wisdom that is his ex-wife (more on that later) and mother of his young children.</p> <p>Because of its many bizarre elements and threads, Bolonik’s article feels much longer than its 7,000-word count and is hard to summarize. But to do it in one convoluted sentence: Professor Hay is the victim of an alleged paternity scam, one so elaborate it nearly cost him and his family their home, and one that includes sexual misconduct allegations leading to <a href="https://babe.net/2018/10/02/bruce-hay-harvard-80495">an ongoing Title IX investigation</a>.</p> <p>The story’s most notable feature is just how gullible and <em>how dumb</em> Professor Hay – who is the on-record source of 90-95% of the narrative – makes himself sound. In this case, a sentence (or several) can’t do Bolonik’s article justice. But one particularly interesting aspect is how seemingly obvious the ploy seems to be, and yet, how it managed to fool several highly intelligent men, including Professor Hay and – as far as we know – three Harvard-area men.</p> <p>From the story’s first graf, this is how Hay describes his first encounter with the scammer; I’ve added emphasis to the pickup line:</p> <blockquote> <p>It was just supposed to have been a quick Saturday-morning errand to buy picture hooks. On March 7, 2015, Harvard Law professor Bruce Hay, then 52, was in Tags Hardware in Cambridge, Massachusetts, near his home, when a young woman with long reddish-brown hair approached him to ask where she could find batteries. It was still very much winter, and, once the woman got his attention, he saw that underneath her dark woolen coat and perfectly tied scarf she was wearing a dress and a chic pair of boots — hardly typical weekend-errand attire in the New England college town. When he directed her to another part of the store, she changed the subject. <strong>“By the way, you’re very attractive,” he remembers her saying.</strong></p> </blockquote> <p>In the latter-third of the story, Bolonik writes that Hay and his lawyer uncovered 3 other men who previously filed suit against his scammer. Bolonik met with one of them, who is referred to in court papers as “John Doe”. Here’s how Doe describes meeting the scammer (again, emphasis mine)</p> <blockquote> <p>This past fall, I met Doe, who told me Shuman appeared out of nowhere at an intersection where he was standing with two colleagues and started chatting him up in what he described as hushed tones. He recalled her saying, <strong>“Excuse me, but I couldn’t help but notice that you’re attractive. I’m in town from New York, visiting a friend, and I was hoping you’d be willing to show me around.”</strong> He gave her his cell number.</p> </blockquote> <p>Everything is obvious in retrospect, but here the pickup line, and its contrived circumstances – how many late-20s/early-30s adults show up in Boston or New York without a smartphone to serve as a guide? – seem <em>especially</em> so. How could Doe, described by Bolonik as a “young, lanky, blue-eyed CPA”, or Hay, a tenured professor with nearly 30 years at Harvard Law, fall for something so comically transparent?</p> <p>Those questions about the depths of human trust and gullibility aren’t readily answered. But I do wonder if the flimsiness of the pickup tactic itself is itself inspired by the trope of the <a href="https://en.wikipedia.org/wiki/Advance-fee_scam">Nigerian Prince email scam</a>, an ostensibly obvious and universally-known scam, <a href="https://www.cnbc.com/2019/04/18/nigerian-prince-scams-still-rake-in-over-700000-dollars-a-year.html">yet one that still brings in fortunes for its perpetrators</a>?.</p> <p>But couldn’t scammers attract even more victims and their money by being more sophisticated? e.g. pretending to be a prince from a country less notorious than Nigeria? In 2012, Microsoft Research’s Cormac Herley studied this question in one of my favorite white papers, <a href="https://www.microsoft.com/en-us/research/publication/why-do-nigerian-scammers-say-they-are-from-nigeria/">Why Do Nigerian Scammers Say They are From Nigeria?</a> (link to <a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/WhyFromNigeria.pdf">PDF</a>).</p> <p>Here’s an excerpt from the Discussion section (Section 4):</p> <blockquote> <p>An examination of a web-site that catalogs scam emails shows that 51% mention Nigeria as the source of funds…Why so little imagination? Why don’t Nigerian scammers claim to be from Turkey, or Portugal or Switzerland or New Jersey? Stupidity is an unsatisfactory answer.</p> </blockquote> <p>It’s a very accessible paper and worth reading, but in summary, Herley argues that the use of “Nigeria” (or “Nigerian Prince”) acts as a very effective filter for the scammer, whose has nearly unlimited bandwidth in the amount of emails sent, but very limited time to deal with “false positives” – i.e. potential victims who ultimately wise up. The percentage of targets who would even open an unsolicited email subject line of “Nigeria” is vanishingly and staggeringly tiny. But the ones who do, Herley argues, are extremely profitable to the scammer:</p> <blockquote> <p>If we assume that the scammer enters into email conversation (i.e., attacks) almost everyone who responds, his main opportunity to separate viable from non-viable users is the wording of the original email…Who are the most likely targets for a Nigerian scammer? Since the scam is entirely one of manipulation he would like to attack (i.e., enter into correspondence with) only those who are most gullible…</p> <p>Since gullibility is unobservable, the best strategy is to get those who possess this quality to self-identify. An email with tales of fabulous amounts of money and West African corruption will strike all but the most gullible as bizarre. It will be recognized and ignored by anyone who has been using the Internet long enough to have seen it several times.</p> </blockquote> <blockquote> <p>It will be figured out by anyone savvy enough to use a search engine and follow up on the auto-complete suggestions such as shown in Figure 8. It won’t be pursued by anyone who consults sensible family or friends, or who reads any of the advice banks and money transfer agencies make available. Those who remain are the scammers ideal targets. They represent a tiny subset of the overall population.</p> </blockquote> <p>Reading through the <a href="https://twitter.com/KeraBolonik/status/1153611968193933312">Twitter replies to NYMag’s Bolonik</a>, there’s at least <a href="https://twitter.com/jordanharap/status/1153774824810078209">one more guy who has a story about the scammer</a> – though apparently, he appears to have avoided the trap:</p> <p><a href="https://twitter.com/jordanharap/status/1153774824810078209"><img src="/files/images/tweet-jharap-bolonik-thecut-hay-scammer.png" alt="This was crazy to read. I was approached by this woman on Mass Ave (directly across from Harvard Law School) in April 2015. I was a third year law student at the time - may be able to provide further corroboration in light of the ongoing proceedings." /> </a></p> <p>Hay’s alleged scammer seems to have some of the same constraints as a Nigerian scammer – it’s a huge amount of time and risk to initiate a relationship with a mark who is likely to wise up. So the exceedingly cringe pickup line of <em>“Excuse me, sir, I’mbut I noticed you’re very handsome. Could you show me around New York?”</em> likely had any rejections before finding success in Professor Hay, “John Doe”, and other victims. And this works beautifully for the paternity-test-scammer.</p> <p>(<strong>Note:</strong> Except for this aside, I’ve deliberately avoid mentioning or speculating about the motives of Hay’s scammers, which would require an entirely separate wordy blog post. Bolonik’s article offers little revelation. But it’s worth noting that in Hay’s case, unlike with Nigerian scammers, the scammers don’t seem to be primarily motivated by money)</p> <p>But as with everything else in Bolonik’s necessarily convoluted article, there are only more questions. Herley, the Microsoft researcher, points out that Nigerian scammers depend on victims lacking a support network of “sensible family or friends”. Professor Hay does not seem to be in this situation; he says he and his scammer, before they first had sex, had coffee dates and long talks about their respective lives. She would have learned from him that his ex-wife – who he has 2 children with and who he was still living with, amicably – is <em>an assistant U.S. Attorney</em>. At that point, the ostensibly savvy scammer must have realized that no matter how gullible Hay seemed, or how estranged he might be from the rest of Harvard’s elite, Hay’s ex-wife was <em>definitely</em> going to step in and pursue any scammers who threatened Hay’s (i.e. <em>her</em>) home and children.</p> <p>And yet here we are. The depths and speed at which Professor Hay fell for the scam is shocking. But it doesn’t explain why (again, assuming that money is not an issue) the scammers would entangle themselves with him, when there are so many other marks. This incongruity (among the <em>many</em> others), added to the fact Hay – against the advice of Harvard and other lawyers – shopped his story around to several other journalists before finding Bolonik, is enough to raise serious doubt that we’ve heard all the relevant and significant facts of this bizarre story.</p> </description> <pubDate>Wed, 24 Jul 2019 08:11:00 -0500</pubDate> <link>http://blog.danwin.com/the-scammers-of-harvard-law-s-bruce-hay-and-the-nigerian-prince-filter/</link> <guid isPermaLink="true">http://blog.danwin.com/the-scammers-of-harvard-law-s-bruce-hay-and-the-nigerian-prince-filter/</guid> </item> <item> <title>How to install and use schemacrawler on MacOS to generate nifty SQL database schemas</title> <description><p>The following post is a <a href="https://gist.github.com/dannguyen/f056d05bb7fec408bb7c14ea1552c349">copy of this Gist</a>, an instruction recipe I wrote on how to get the superhandy schemacrawler program working on MacOS. It’s a command-line tool that allows you to easily generate SQL schemas as image files, like so:</p> <p><em>This was tested on MacOS 10.14.5 on 2019-07-16</em></p> <p><a href="http://www.schemacrawler.com/">schemacrawler is a free and open-source database schema discovery and comprehension tool</a>. It can be invoked from the command-line to produce, using <a href="http://www.graphviz.org/">GraphViz</a>, images/pdfs from a SQLite (or other database type) file. It can be used from the command-line to generate schema diagrams like these:</p> <p><img src="https://user-images.githubusercontent.com/121520/41448959-de545a74-7012-11e8-99f9-520d76a683b8.png" alt="image" /></p> <p>To see more examples of commands and diagrams, visit scheacrawler’s docs: http://www.schemacrawler.com/diagramming.html</p> <h2 id="install-graphviz-dependency">Install graphviz dependency</h2> <p>For schema drawing, <code class="highlighter-rouge">schemacrawler</code> uses graphviz, which can be installed via the <a href="https://brew.sh/">Homebrew</a> package manager:</p> <div class="language-sh highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code>brew <span class="nb">install </span>graphviz </code></pre></div></div> <h2 id="installing-schemacrawler-as-a-command-line-tool">Installing <code class="highlighter-rouge">schemacrawler</code> as a command-line tool</h2> <p>This section gives an example of how to install <code class="highlighter-rouge">schemacrawler</code> so that you can invoke it with your shell. There isn’t a Homebrew recipe, so the shell commands basically:</p> <ul> <li>Download a release zip from <a href="https://github.com/schemacrawler/SchemaCrawler/releases">schemacrawler/releases</a></li> <li>Copies the relevant subdir from the release into a local directory, e.g. <code class="highlighter-rouge">/usr/local/opt/schemacrawler</code></li> <li>Creates a simple shell script that saves you from having to run <code class="highlighter-rouge">schemacrawler</code> via the <code class="highlighter-rouge">java</code> executable</li> <li>symlinks this shell script into an executable path, e.g. <code class="highlighter-rouge">/usr/local/bin</code></li> </ul> <h2 id="downloading-and-installing-schemacrawler">Downloading and installing schemacrawler</h2> <p>The latest releases can be found on the Github page:</p> <p>https://github.com/schemacrawler/SchemaCrawler/releases/</p> <h3 id="setting-up-schemacrawler-to-run-on-your-system-via--schemacrawler">Setting up schemacrawler to run on your system via <code class="highlighter-rouge">$ schemacrawler</code></h3> <p>In this gist, I’ve attached a shell script <a href="https://gist.github.com/dannguyen/f056d05bb7fec408bb7c14ea1552c349#file-script-schemacrawler-on-macos-sh">script-schemacrawler-on-macos.sh</a> that automates the downloading of the schemacrawler ZIP file from its Github repo, installs it, creates a helper script, and creates a symlink to that helper script so you can invoke it via:</p> <div class="language-sh highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code><span class="nv">$ </span>schemacrawler ... </code></pre></div></div> <p>You can copy the script into a file and invoke it, or copy-paste it directly into Bash. Obviously, as with anything you copy-paste, read it for yourself to make sure I’m not attempting to do something malicious.</p> <p>(An older version of this script can be found <a href="https://gist.github.com/dannguyen/f056d05bb7fec408bb7c14ea1552c349#file-OLDscript-schemacrawler-on-macos-sh">here</a>)</p> <h4 id="a-couple-of-notes-about">A couple of notes about</h4> <p>The script <a href="https://gist.github.com/dannguyen/f056d05bb7fec408bb7c14ea1552c349#file-script-schemacrawler-on-macos-sh">script-schemacrawler-on-macos.sh</a> has a few defaults – e.g. <code class="highlighter-rouge">/usr/local/opt/</code> and <code class="highlighter-rouge">/usr/local/bin/</code> – which are assumed to be writeable, but you can change those default vars for yourself.</p> <p>One of the effects of is that it creates a Bash script named something like</p> <p>Its contents are:</p> <p>This script is a derivation of schemacrawler’s <a href="https://github.com/schemacrawler/SchemaCrawler/blob/a3fea8be74ae28d6e8318c14f2c3f4be314efe2a/schemacrawler-distrib/src/assembly/schemacrawler.sh">schemacrawler-distrib/src/assembly/schemacrawler.sh</a>, the contents of which are:</p> <h2 id="general-usage">General usage</h2> <p>Now that <code class="highlighter-rouge">schemacrawler</code> is installed as an executable shell command, here’s an example of how to invoke it – change <code class="highlighter-rouge">DBNAME.sqlite</code> and <code class="highlighter-rouge">OUTPUT_IMAGE_FILE.png</code> to something appropriate for your usecase:</p> <div class="language-sh highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code> schemacrawler <span class="nt">-server</span> sqlite <span class="se">\</span> <span class="nt">-database</span> DBNAME.sqlite <span class="se">\</span> <span class="nt">-user</span> <span class="nt">-password</span> <span class="se">\</span> <span class="nt">-infolevel</span> standard <span class="se">\</span> <span class="nt">-command</span> schema <span class="se">\</span> <span class="nt">-outputformat</span> png <span class="se">\</span> <span class="nt">-outputfile</span> OUTPUT_IMAGE_FILE.png </code></pre></div></div> <h3 id="bootload-a-sample-sqlite-database-and-test-out-schemacrawler">Bootload a sample SQLite database and test out schemacrawler</h3> <p>Just in case you don’t have a database to play around with, you can copy paste this sequence of SQLite commands into your <strong>Bash</strong> shell, which will create the following empty database file at <code class="highlighter-rouge">/tmp/tmpdb.sqlite</code></p> <div class="language-sh highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code><span class="nb">echo</span> <span class="s1">''' DROP TABLE IF EXISTS business; DROP TABLE IF EXISTS inspection; DROP TABLE IF EXISTS violation; CREATE TABLE business ( business_id TEXT, name TEXT, address TEXT, city TEXT, postal_code TEXT, latitude DECIMAL, longitude DECIMAL, phone_number TEXT, application_date TEXT, owner_name TEXT ); CREATE TABLE inspection ( business_id TEXT, "Score" NUMERIC, date TEXT NOT NULL, type TEXT NOT NULL, FOREIGN KEY(business_id) REFERENCES business(business_id) ); CREATE TABLE violation ( business_id TEXT, date TEXT, "ViolationTypeID" TEXT, risk_category TEXT, description TEXT, FOREIGN KEY(business_id, date) REFERENCES inspection(business_id, date) );'''</span> <span class="se">\</span> | sqlite3 /tmp/tmpdb.sqlite </code></pre></div></div> <p>Invoke <code class="highlighter-rouge">schemacrawler</code> like so:</p> <div class="highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code>schemacrawler -server sqlite \ -user -password \ -infolevel standard \ -command schema \ -outputformat png \ -database /tmp/tmpdb.sqlite \ -outputfile /tmp/mytmpdb.png </code></pre></div></div> <p>The output of that Bash command will be a file <code class="highlighter-rouge">/tmp/tmpdb.sqlite</code>, which looks like this:</p> <p><img src="https://user-images.githubusercontent.com/121520/61403484-ede86e80-a8c4-11e9-8bda-f9ceb63b6101.png" alt="/tmp/tmpdb.sqlite" /></p> <h2 id="graphviz-properties">graphviz properties</h2> <p>You can edit <code class="highlighter-rouge">schemacrawler.config.properties</code>, which is found wherever you installed the schemacrawler distribution – e.g. if you ran my installer script, it would be in <code class="highlighter-rouge">/usr/local/opt/schemacrawler/config/schemacrawler.config.properties</code></p> <p>Some example settings:</p> <div class="highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code>schemacrawler.format.no_schemacrawler_info=true schemacrawler.format.show_database_info=true schemacrawler.format.show_row_counts=true schemacrawler.format.identifier_quoting_strategy=quote_if_special_characters schemacrawler.graph.graphviz.nodes.ranksep=circo schemacrawler.graph.graphviz.graph.layout=circo schemacrawler.graph.graphviz.graph.splines=ortho schemacrawler.graph.graphviz.node.shape=folder schemacrawler.graph.graphviz.node.style=rounded,filled schemacrawler.graph.graphviz.node.fillcolor=#fcfdfc #schemacrawler.graph.graphviz.node.color=red schemacrawler.graph.graphviz.graph.fontname=Helvetica Neue schemacrawler.graph.graphviz.node.fontname=Consolas schemacrawler.graph.graphviz.edge.fontname=Consolas schemacrawler.graph.graphviz.edge.arrowsize=1.5 </code></pre></div></div> <p>If you append the previous snippet to the default <code class="highlighter-rouge">schemacrawler.config.properties</code>, you’ll get output that looks like this:</p> <p><img src="https://user-images.githubusercontent.com/121520/61417204-f00ef500-a8e5-11e9-9e97-e690b23e31aa.png" alt="image" /></p> <p>More info about GraphViz in this StackOverflow Q:</p> <p><a href="https://stackoverflow.com/questions/11588667/how-to-influence-layout-of-graph-items">How to influence layout of graph items?</a></p> </description> <pubDate>Tue, 16 Jul 2019 00:00:00 -0500</pubDate> <link>http://blog.danwin.com/installing-schemacrawler-for-macos-to-map-out-sqlite-schemas/</link> <guid isPermaLink="true">http://blog.danwin.com/installing-schemacrawler-for-macos-to-map-out-sqlite-schemas/</guid> </item> <item> <title>A submemberist?</title> <description><p>It’s a given that Google has pages for every valid English word in existence as well as most fantastical words. It’s very rare that Google comes up with <em>nothing</em>, even for nonsense or terribly misspelled words.</p> <p>However, I stumbled upon a non-result for the word “submemberist”:</p> <p><a href="https://www.google.com/search?q=submemberist">https://www.google.com/search?q=submemberist</a></p> <p>Of course, by the time you click on the above query, Google will have crawled at least a few pages mentioning the word.</p> <p>I guess it’s probably not a big deal to come up with arbitrary combinations of letters for which Google has no results. What was interesting about “submemberist” is that it <em>looks</em> like it could be a word. Though to be fair, the <a href="https://en.oxforddictionaries.com/definition/us/sub-member">Oxford “Living” Dictionary only has it listed with a hyphen: “sub-member”</a>.</p> <p>I didn’t even know “submember” or “sub-member” was a word before I saw Parker Higgins (<a href="https://twitter.com/xor">@xor</a>) tweet some <a href="https://twitter.com/xor/status/978793975590150144">fun trivia about airport codes</a> last night:</p> <blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">As far as I can tell, the longest words you can spell entirely out of airport codes are each 9 letters long. It&#39;s quite an evocative list of words, too. <a href="https://t.co/ssNMRz3s5O">pic.twitter.com/ssNMRz3s5O</a></p>&mdash; Parker Higgins (@xor) <a href="https://twitter.com/xor/status/978793975590150144?ref_src=twsrc%5Etfw">March 28, 2018</a></blockquote> <script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>Of all the 3-character codes, “IST” seems the most flexible when it comes to creating a legit combination with a 9-character word. Of course, “memberist” isn’t a word either, though Google at least has plenty of attempted results:</p> <p><img src="/files/images/posts/google-memberist.png" alt="google-memberist.png" /></p> <p>I wish I could say this blog post had a more important point about language or even search-engine optimization, but I just wanted to spoil the results for anyone else who ever searches for “submemberist” :p.</p> <blockquote> <p><strong>Update 2019-07-16:</strong> More than a year later, this blog is the only result for a <a href="https://www.google.com/search?q=submemberist">google search of “submemberist”</a>, which means my blog apparently isn’t notable enough to get content-scraped by SEO-spammers!</p> <p><img src="/files/images/submemberist-google-search.png" alt="image submemberist-google-search.png" /></p> </blockquote> </description> <pubDate>Wed, 28 Mar 2018 00:00:00 -0500</pubDate> <link>http://blog.danwin.com/a-submemberist/</link> <guid isPermaLink="true">http://blog.danwin.com/a-submemberist/</guid> </item> <item> <title>How James Bamford exposed the NSA using the NSA's own company newsletter</title> <description><p>MuckRock <a href="https://www.muckrock.com/news/archives/2017/mar/27/cia-employee-activity-association/">recently posted a fun FOIA-related item about a declassified CIA memo on “Cover and Security Considerations”</a> for employees who want to have an after-work bowling league or glee club:</p> <blockquote> <p>In most professions, all it takes to form an after-work bowling league is an overly long email chain and some beer money. As a declassified memo recently unearthed in CREST shows, in the CIA, it’s a lot more complicated.</p> </blockquote> <blockquote> <p>…To cope with these rather unique challenges, the Agency formed the Employee Activity Association (EAA), which, in exchange for membership dues, would ensure that next weekend’s fishing trip would have a plausible cover story.</p> </blockquote> <blockquote> <p>…members were expected to keep the existence or non-existence of the ping-pong team a secret and to attend security briefings.</p> </blockquote> <p>This bureaucratic anal-retentiveness regarding mundane company functions immediately reminded me of <a href="https://en.wikipedia.org/wiki/James_Bamford">James Bamford</a>, the first journalist to bring mainstream attention to the National Security Agency when he published <a href="https://en.wikipedia.org/wiki/The_Puzzle_Palace">“The Puzzle Palace” in 1982</a>.</p> <p>There is a great profile of Bamford in Baltimore’s City Paper in which he describes finding an internal NSA newsletter that contained chatty and useful details about the agency and, like your typical chatty company newsletter, was meant for employees <em>and their families</em>. And since family members didn’t have special security clearances, that meant that all the NSA internal newsletters were eligible to be released by FOIA. Bamford was able to get thousands of pages of newsletters about the NSA, and that allowed him to greatly expand his knowledge and access to NSA officials.</p> <p>Unfortunately, City Paper seems to have undertaken one of those news site redesigns/content-management system overhauls <a href="https://www.theatlantic.com/technology/archive/2015/11/the-irony-of-writing-about-digital-preservation/416184/">in which the archives are eradicated from Internet history</a>. Luckily, the Internet Archive still has a copy of the original 2008 article by Lee Gardner: <em><a href="https://web-beta.archive.org/web/20111020180602/http://www.citypaper.com/news/story.asp?id=17031">Secrets and Lies: An Interview With National Security Agency Expert James Bamford</a></em></p> <p>Here’s the key excerpt, though the entire interview is a great read:</p> <blockquote> <p><strong>[City Pages]</strong>: Did you get any push-back from the agency when you started writing about it? After all, it’s supposed to be top secret.</p> </blockquote> <blockquote> <p><strong>[Bamford]</strong>: I had a difficult time. My advance was fairly small, I was living in Massachusetts, I didn’t really know anyone in intelligence, and I hadn’t written anything before. And I was going up against NSA.</p> </blockquote> <blockquote> <p>One of the things I was good at in law school was research, so I thought maybe I’d try using the Freedom of Information Act. The problem with that was, NSA is really the only agency excluded from the act. If you sent them a [FOIA] request, they would just send you a letter back saying [under Section 6 of the National Security Agency Act] we don’t have to give you anything, even if it’s unclassified.</p> </blockquote> <blockquote> <p>But I found this place, the George C. Marshall Research Library in Lexington, Virginia, and William F. Friedman, one of the founders of the NSA, had left all his papers there. When I got down there, I found the NSA had gotten there just before me and gone through all of his papers and taken a lot of his papers out and put them in a vault down there and ordered the archivist to keep them under lock and key. And I convinced the archivist that that wasn’t what Friedman wanted, and he took the documents out and let me take a look at them.</p> </blockquote> <blockquote> <p>Among the documents was an NSA newsletter. These are things the NSA puts out once a month. They’re fairly chatty, but if you read them closely enough you can pick up some pretty good information about the agency. . . . When I was reading one of the newsletters, there was a paragraph that said, “The contents of this newsletter must be kept within the small circle of NSA employees and their families.” And I thought about it for a little bit, and I thought, hmm, they just waived their protections on that newsletter–if that’s on every single newsletter then I’ve got a pretty good case against them. If you’re going to open it up to family members, with no clearance, who don’t work for the agency, then I have every right to it. That was a long battle, but I won it, and they gave me over 5,000 pages’ worth of NSA newsletters going back to the very beginning. That was the first time anyone ever got a lot of information out of NSA.</p> </blockquote> <blockquote> <p>We made this agreement where I could come down and spend a week at NSA, and they gave me a little room where I could go over the newsletters and pick the ones I wanted. So I got all that information, and spent about a week at NSA. And finally they really wanted to delete some names and faces, and I said you can do that, but there ought to be some kind of quid pro quo. The quid pro quo was that I get to interview senior officials and take a tour of the agency. And that was what really opened it up.</p> </blockquote> <blockquote> <p>It wasn’t the NSA you see today–it was much different. They just thought no one would ever try to write about NSA, and they didn’t think I would have any luck, because who am I? I’m just some guy up in Massachusetts with no track record.</p> </blockquote> </description> <pubDate>Thu, 30 Mar 2017 00:00:00 -0500</pubDate> <link>http://blog.danwin.com/how-james-bamford-exposed-the-nsa-using-its-own-internal-newsletter/</link> <guid isPermaLink="true">http://blog.danwin.com/how-james-bamford-exposed-the-nsa-using-its-own-internal-newsletter/</guid> </item> <item> <title>Rabbit holes and writing.</title> <description><p>It’s about 1:50 A.M. and I’m reading a <a href="https://news.ycombinator.com/item?id=13823881">HN thread about a BBC article, titled “Rabbit hole leads to 700-year-old Knights Templar cave”</a>.</p> <p>Several users point out that the title is a bit of nonsense – “The reference to a rabbit hole makes no sense unless it’s symbolic, since rabbits holes are about the size of a rabbit”. That gets me thinking about the rabbit holes that led into the seemingly huge warrens described in <a href="https://en.wikipedia.org/wiki/Watership_Down">“Watership Down”</a>.</p> <p>Googling, “watership down rabbit facts” led me to this <a href="https://www.theguardian.com/books/2015/jan/04/richard-adams-watership-down-interview">2015 Guardian interview with author Richard Adams</a>; I knew the book originated from a whimsical story Adams made up to keep his daughters entertained on a car trip. I didn’t realize that he had never written fiction before, or that he was so late in his life when he started:</p> <blockquote> <p>Watership Down was one of the first of these stories. Adams was 52 and working for the civil service when his daughters began pleading with him to tell them a story on the drive to school. “I had been put on the spot and I started off, ‘Once there were two rabbits called Hazel and Fiver.’ And I just took it on from there.” <strong>Extraordinarily, he had never written a word of fiction before, but once he’d seen the story through to the end, his daughters said it was “too good to waste, Daddy, you ought to write that down”</strong>.</p> </blockquote> <blockquote> <p>He began writing in the evenings, and the result, an exquisitely written story about a group of young rabbits escaping from their doomed warren, won him both the Carnegie medal and the Guardian children’s prize. “It was rather difficult to start with,” he says. <strong>“I was 52 when I discovered I could write. I wish I’d known a bit earlier. I never thought of myself as a writer until I became one.”</strong></p> </blockquote> </description> <pubDate>Thu, 09 Mar 2017 00:00:00 -0600</pubDate> <link>http://blog.danwin.com/never-too-late-to-start-writing/</link> <guid isPermaLink="true">http://blog.danwin.com/never-too-late-to-start-writing/</guid> </item> <item> <title>On automated journalism: Don't automate the good stuff</title> <description><p>I love and frequently recommend Al Weigart’s, <a href="https://automatetheboringstuff.com/">“Automate the Boring Stuff with Python”</a>, because it so perfectly captures how I feel about programming: programming is how we tell computers what to do. And computers, like all of the best mechanical inventions in existence, are best at doing mechanical, i.e. <em>boring</em> work.</p> <p>The inverse of that mentality – that computers should/can be used to automate the interesting work of our lives – can be found in this blog post (h/t <a href="https://twitter.com/ndiakopoulos/status/839668650181283840">@ndiakopoulos</a>) from the research blog <strong>Immersive Automation</strong>:</p> <div class="highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code>[Can computers quote like human journalists, and should they?](http://immersiveautomation.com/2017/03/can-computers-quote-like-human-journalists/) (emphasis added) When a reader enjoys a story in a magazine, they have no way of knowing how an interview between a journalist and a source was conducted. Even quotations – which are widely considered being verbatim repetitions of what has been said in the interview – might be very accurate, but they might as well be heavily modified, or even partially trumped-up. “For journalists, and their editors, **the most important thing is of course to produce a good piece of writing**. This means they might be forced to make compromises, since the citations must serve a purpose for the story,” Lauri Haapanen explains. </code></pre></div></div> <p>The rest of the post goes on to describe “nine essential quoting strategies used by journalists when writing articles”, which is an interesting discussion in itself. But I wanted to point out how fuzzy (or misguided) the statement bolded above is:</p> <div class="highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code>For journalists, and their editors, **the most important thing is of course to produce a good piece of writing**. </code></pre></div></div> <p>No.</p> <p>The most important thing to a journalist is to <strong>produce interesting reporting</strong>.</p> <p>Let’s look at the ledes – often considered the part of a story where good writing has (and needs) the most impact – of some published journalism:</p> <p>Those are the ledes for the winners of what is often considered journalism’s most important prize: the Pulitzer Prizer for Public Service</p> <p>The</p> <p><a href="http://www.pulitzer.org/winners/news-observer-raleigh-nc-work-melanie-sill-pat-stith-and-joby-warrick">News &amp; Observer in 1996</a></p> <p><a href="http://www.pulitzer.org/winners/boston-globe-1">Boston Globe</a> in <a href="http://www.pulitzer.org/winners/sun-sentinel">Sun Sentinel in 2013</a>,</p> <div class="highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code>North Carolina, hundreds of miles from America's traditional Midwest hog belt, has become the nation's No. 2 hog producer. Last year, hogs generated more than $1 billion in revenue -- more than tobacco. This year, hogs are expected to pass broiler chickens as the No. 1 agricultural commodity. One of the five men arrested early Saturday in the attempt to bug the Democratic National Committee headquarters is the salaried security coordinator for President Nixon’s reelection committee. The District of Columbia's Metropolitan Police Department has shot and killed more people per resident in the 1990s than any other large American city police force. Bell, one of the poorest cities in Los Angeles County, pays its top officials some of the highest salaries in the nation, including nearly $800,000 annually for its city manager, according to documents reviewed by The Times. Since the mid-1990s, more than 130 people have come forward with horrific childhood tales about how former priest John J. Geoghan allegedly fondled or raped them during a three-decade spree through a half-dozen Greater Boston parishes. </code></pre></div></div> <p>Here’s a clickbait version:</p> <div class="highlighter-rouge"><div class="highlight"><pre class="code-highlight"><code> We've all seen it, and now there's proof: Police officers sworn to uphold our traffic laws are among the worst speeders on South Florida roads. </code></pre></div></div> <p>https://www.washingtonpost.com/politics/gop-security-aide-among-five-arrested-in-bugging-affair/2012/06/07/gJQAYTdzKV_story.html</p> <p>And here are a couple of ledes from the la times, which, when read in isolation, falls into the “OK is Dunia and why should I give a shit?”</p> <p>http://www.pulitzer.org/winners/los-angeles-times-3</p> <p>But “just the facts” isn’t the sole mark of a good</p> <p>On a warm July afternoon, an impish second-grader named Dunia Tasejo was running home after buying ice cream on her South Los Angeles street when a car sideswiped her. Knocked to the pavement, she screamed for help, blood pouring from her mouth.</p> <hr /> <p>I’m being unfair, maybe, because “good” can encompass all of those examples. But that’s my point – “good writing” has no obvious meaning when it comes to journalism or any other form of writing. It is up to the discretion and style of the writers.</p> <p>But important journalism – journalism that is important to publish. It’s facts.</p> <hr /> <p>I went into journalism because I liked writing and am old enough that, when I worked for my college paper, it had enough paper to print 10,000 words, in actual pieces of paper with real ink.</p> <hr /> <p>But I don’t think that computers can’t replace a lot of what humans do. They already do – page layout, copy-editing (of the spell-check variety), and research (of the Google-variety) – have all been replaced. Because much of it was mechanical. But the biggest outlets still hire copy editors (also known as fact checkers) and researchers for the bespoke work.</p> <p>How much of quoting is bespoke work? Depends. I contend that of all the parts of writing that can be automated, it’s one of the least in terms of return on investment.</p> <p>To describe writing like this:</p> <blockquote> <p>The Immersive Automation-project focuses on news automation and algorithmically produced news. Since human-written journalistic texts often contain quotations, automated content should also include them to meet the traditional expectations of readers.</p> </blockquote> <p>No it shouldn’t. That’s one of the things I learned in journalism school: don’t quote parts just repeat someone.</p> <blockquote> <p>In the development process of news automation, it is realistic to expect human journalists and machines to collaborate.</p> <p>“A text generator could write a story and a journalist could interview sources and add quotations in suitable places,” says Haapanen.</p> </blockquote> <p>Also the headline annoys me. It’s not about <strong>can</strong>. Nor is it about <strong>should</strong>.</p> </description> <pubDate>Wed, 08 Mar 2017 00:00:00 -0600</pubDate> <link>http://blog.danwin.com/on-automated-journalism-don-t-automate-the-good-stuff/</link> <guid isPermaLink="true">http://blog.danwin.com/on-automated-journalism-don-t-automate-the-good-stuff/</guid> </item> <item> <title>Jekyll websites, open-source and in the real-world</title> <description><p>A student hoping to build a project in Jekyll asked me for examples of well-known, well-designed Jekyll sites.</p> <p>Of course, a site’s visual appearance technically has nothing to do with its framework – e.g. Jekyll vs. Hugo vs. WordPress vs. Drupal, etc. But for folks starting out, important conventions and best practices – such as how to write the template files, which folders to put CSS and other asset files, how to incorporate Bootstrap/SASS/etc., and overall site configuration – are much easier to learn when having source code from sites built with the same framework.</p> <p>So I’ve compiled a short list (and am happy to take suggestions) of Jekyll sites that:</p> <ol> <li>Have their source code available to clone and learn from.</li> <li>Aren’t just blogs.</li> <li>Are attractive.</li> <li>Are popular.</li> </ol> <p>Most of these sites have lots of data, content, and words. So they won’t be the most <em>beautiful</em>, in the sense of content-lite sites that feature of chasms of white space and <a href="https://unsplash.com/">beautiful Unsplash-worthy hero images</a>. But I rate their attractiveness in relation to their <em>function</em>. Most of them are aimed at a general audience (especially the government sites). And many of them have to relay a large array of data and content.</p> <p>If the official documentation on Jekyll’s <a href="https://jekyllrb.com/docs/datafiles/">data files</a>, <a href="https://jekyllrb.com/docs/collections/">collections</a>, and <a href="https://jekyllrb.com/docs/variables/">site variables</a> don’t make immediate sense to you, then take a look at these examples’ repos to see how the professionals organize their Jekyll projects.</p> <h6 id="templates-showcase-from-jekyll-tips">Templates showcase from Jekyll Tips</h6> <p><a href="http://jekyll.tips/templates/"><img src="/files/images/jekyll-examples-jekyll-tips.png" alt="jekyll-examples-jekyll-tips.png" /></a></p> <p><a href="http://jekyll.tips/templates/">http://jekyll.tips/templates/</a></p> <p>OK, most of these templates are geared toward Jekyll’s original use-case: blogs. But front-end assets for Jekyll blogs can be implemented in the same fashion for Jekyll sites that aren’t straightforward blogs. Each of the templates in this showcase have an associated Github repo.</p> <h6 id="github-on-demand-training">Github On-Demand Training</h6> <p>Since <a href="https://jekyllrb.com/">Jekyll itself came out of Github</a> and is used to power Github’s extremely popular <a href="https://help.github.com/articles/what-is-github-pages/">Github Pages feature</a>, pretty much all of Github’s static content is done in Jekyll. I’ve tried to list the more notable examples that have their source code available.</p> <p>Here’s their On-Demand Training page, which is a homepage for their “How-to Use Github/Git” guides, cheat-sheets, and curricula:</p> <p><a href="https://services.github.com/on-demand/">https://services.github.com/on-demand/</a></p> <p>The repo: <a href="https://github.com/github/training-kit">https://github.com/github/training-kit</a></p> <p><a href="https://services.github.com/on-demand/"> <img src="/files/images/jekyll-examples-github-ondemand-training.jpg" alt="jekyll-examples-github-ondemand-training.jpg" /> </a></p> <p><a href="https://services.github.com/on-demand/intro-to-github/"> <img src="/files/images/jekyll-examples-github-ondemand-training-intro.jpg" alt="jekyll-examples-github-ondemand-training-intro.jpg" /> </a></p> <h6 id="githubs-open-source-guide">Github’s Open Source Guide</h6> <p><a href="https://opensource.guide/"> <img src="/files/images/jekyll-examples-github-open-source.png" alt="jekyll-examples-github-open-source.png" /> </a></p> <p><a href="https://opensource.guide/">https://opensource.guide/</a></p> <p>Repo: <a href="https://github.com/github/open-source-guide">https://github.com/github/open-source-guide</a></p> <p>This isn’t a “complex” site, per se, but it’s a nice non-blog site if you need an example of how to structure a page-based site in Jekyll.</p> <h6 id="marksheet">MarkSheet</h6> <p><a href="http://marksheet.io/"> <img src="/files/images/jekyll-examples-marksheet-index.png" alt="jekyll-examples-marksheet-index.png" /> </a></p> <p><a href="http://marksheet.io/html-images.html"> <img src="/files/images/jekyll-examples-marksheet-images-lesson.png" alt="jekyll-examples-marksheet-images-lesson.png" /> </a></p> <p><a href="http://marksheet.io/">http://marksheet.io/</a></p> <p>Repo: <a href="https://github.com/jgthms/marksheet">https://github.com/jgthms/marksheet</a></p> <p>MarkSheet is a free HTML and CSS tutorial site. Nice example of how to structure a Jekyll site to accommodate book-reference-like content.</p> <h6 id="consumer-financial-protection-bureaus-developer-homepage">Consumer Financial Protection Bureau’s Developer Homepage</h6> <p><a href="https://cfpb.github.io/">https://cfpb.github.io/</a></p> <p>Repo: <a href="https://github.com/cfpb/cfpb.github.io">https://github.com/cfpb/cfpb.github.io</a></p> <p>If you want great examples of how to build data-intensive services and sites, there are few better organizations than the CFPB, which, since it’s a government agency, means their work is in the public domain.</p> <p>Not all of their excellent sites use Jekyll as their front-end (such as <a href="https://github.com/cfpb/hmda-explorer">the HDMA explorer</a>), but the CFPB’s dev/tech homepage uses it as both a landing page and a blog.</p> <p><a href="https://cfpb.github.io/"> <img src="/files/images/jekyll-examples-cfpb-homepage.png" alt="jekyll-examples-cfpb-homepage.png" /> </a></p> <h6 id="the-presidential-innovation-fellows">The Presidential Innovation Fellows</h6> <p><a href="https://presidentialinnovationfellows.gov/"> <img src="/files/images/jekyll-examples-presidential-fellows-homepage.jpg" alt="jekyll-examples-presidential-fellows-homepage.jpg" /> </a></p> <p><a href="https://presidentialinnovationfellows.gov/fellows/"> <img src="/files/images/jekyll-examples-presidential-fellows.jpg" alt="jekyll-examples-presidential-fellows.jpg" /> </a></p> <p><a href="https://www.presidentialinnovation.org/">https://www.presidentialinnovation.org/</a></p> <p>Repo: <a href="https://github.com/18F/presidential-innovation-foundation.github.io">https://github.com/18F/presidential-innovation-foundation.github.io</a></p> <hr /> <p>The Analytics page for the federal government uses Jekyll to tie together Javascript code for reading from APIs and making charts: https://analytics.usa.gov/</p> <p>repo: https://github.com/18F/analytics.usa.gov</p> <hr /> <hr /> <p>Our own Stanford Computational Journalism Lab homepage is in Jekyll:</p> <p>http://cjlab.stanford.edu/</p> <p>repo: https://github.com/compjolab/cjlab-homepage</p> <hr /> <p>Believe it or not, but healthcare.gov – the front-facing static parts, were built in Jekyll: https://www.healthcare.gov/</p> <p>They took down their source code but here is an old version of it: https://github.com/dannguyen/healthcare.gov</p> <p>And here’s what that old code produced: http://healthcaregov-jekyll.s3.amazonaws.com/index.html</p> <p>Here’s a piece in the Atlantic by an open-gov advocate, which is about why healthcare.gov is open source (or was, before the non-Jekyll parts of the site failed to live up to the traffic):</p> <p>https://www.theatlantic.com/technology/archive/2013/06/healthcaregov-code-developed-by-the-people-and-for-the-people-released-back-to-the-people/277295/</p> <hr /> <p>18F is the digital agency for the federal government. Much of the modern and best webdev of the U.S. gov is through their shop:</p> <p>18F’s homepage: https://18f.gsa.gov/ repo: https://github.com/18F/18f.gsa.gov</p> <p>Their handbook: https://handbook.18f.gov/ repo: https://github.com/18F/handbook</p> <p>Here’s a post by them about why they switched to Jekyll.</p> <p>https://18f.gsa.gov/2014/11/17/taking-control-of-our-website-with-jekyll-and-webhooks/</p> <hr /> <p>https://stackoverflow.blog/</p> <p>https://github.com/StackExchange/stack-blog</p> <p>https://stackoverflow.blog/2015/07/01/the-new-stack-exchange-blog/</p> <p>https://stackoverflow.blog/2015/07/02/how-we-built-our-blog/</p> </description> <pubDate>Wed, 08 Mar 2017 00:00:00 -0600</pubDate> <link>http://blog.danwin.com/complex-open-source-jekyll-websites-in-the-wild/</link> <guid isPermaLink="true">http://blog.danwin.com/complex-open-source-jekyll-websites-in-the-wild/</guid> </item> <item> <title>Finding Stories in Data: A presentation to college journalists</title> <description><p>This past weekend, I did a quick session at the <a href="http://acpsanfran.org/">Associated Collegiate Press Midwinter National College Journalism Convention</a> on how to find stories in data.</p> <p>You can find a repo with links to my slides and my big list of links here:</p> <p><a href="https://github.com/dannguyen/acp-2017-finding-stories-in-data">https://github.com/dannguyen/acp-2017-finding-stories-in-data</a></p> <p>The slides:</p> <iframe src="https://docs.google.com/presentation/d/11wmCbXJ8CjUAnt8k7A_j3-v2vybphhvh5NHISbA-EM8/embed?start=false&amp;loop=false&amp;delayms=3000" frameborder="0" width="960" height="569" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe> <p>It’s not a great or finished presentation, but I’ve been meaning to put together a reusable deck/source list so I can do more of these presentations, so it’s a start. Since this session was for college journalists, most of whom I assume fit the “unknowledgable-of-statistics” mold, I tried to talk about projects that were relevant and feasible for their newsrooms.</p> <p>In terms of how to get started, my best advice was to join crowdsourcing efforts put on by organizations like ProPublica. Data entry/collection is always a dry affair, but it is always necessary. So it’s all the better if you can find data entry that works towards a good cause. Here’s a few examples:</p> <ul> <li><a href="http://www.fatalencounters.org/">Fatal Encounters</a> - Well before Ferguson, this project – started by a single, curious journalist – recognized the severe deficiency of data on police shootings.</li> <li><a href="https://projects.propublica.org/graphics/hatecrimes">Documenting Hate</a> - ProPublica’s initiative to count hate crimes and bias incidents and create a national dataset.</li> <li><a href="https://www.buzzfeed.com/johntemplon/help-us-map-trumpworld?utm_term=.syzw4LwmP#.eyzXdmXB7">TrumpWorld</a> - BuzzFeed has logged more than 1,500 of the Trump Administration’s business and personal connections. Use their spreadsheet and help them find more connections.</li> </ul> <p>The best insight I found while gathering material was this GQ interview with Fatal Encounters founder D. Brian Burghart: <a href="http://www.gq.com/story/fatal-encounters-police-statistics-interview">Meet the Man Who Spends 10 Hours a Day Tracking Police Shootings</a>.</p> <p>Here’s how I documented it in slides:</p> <p><img src="/files/images/fatal-encounters-burghart-slide-01.png" alt="image fatal-encounters-burghart-slide-01.png" /></p> <p><img src="/files/images/fatal-encounters-burghart-slide-02.png" alt="image fatal-encounters-burghart-slide-02.png" /></p> <p><img src="/files/images/fatal-encounters-burghart-slide-03.png" alt="image fatal-encounters-burghart-slide-03.png" /></p> <p><img src="/files/images/fatal-encounters-burghart-slide-04.png" alt="image fatal-encounters-burghart-slide-04.png" /></p> <p><img src="/files/images/fatal-encounters-burghart-slide-05.png" alt="image fatal-encounters-burghart-slide-05.png" /></p> <p><img src="/files/images/fatal-encounters-burghart-slide-06.png" alt="image fatal-encounters-burghart-slide-06.png" /></p> <p>The main technical advice I gave to students was: Use a spreadsheet for <strong>everything</strong>. Burghart’s vital contribution to journalism is proof of this method.</p> </description> <pubDate>Mon, 06 Mar 2017 00:00:00 -0600</pubDate> <link>http://blog.danwin.com/finding-stories-in-data-a-presentation-to-college-journalists/</link> <guid isPermaLink="true">http://blog.danwin.com/finding-stories-in-data-a-presentation-to-college-journalists/</guid> </item> </channel> </rss>
{ "cf-cache-status": "DYNAMIC", "cf-ray": "929b4c9db606105c-ORD", "connection": "keep-alive", "content-length": "89095", "content-type": "application/rss+xml", "date": "Tue, 01 Apr 2025 21:49:57 GMT", "etag": "\"eaf7c093a2c731be709db3568a1929b1\"", "last-modified": "Tue, 21 Jul 2020 18:20:17 GMT", "server": "cloudflare", "x-amz-id-2": "o2+a/i54jY5OI4+gkxIZfcRVU9oiLrtFvolLd9BHTx3EYU0QiqoLFJ/uz/v4bkJwbVe3D+DfO5zksvsVtW+8X1/h79XWRj0R", "x-amz-request-id": "ZSSWM36SVDP3YSFK" }
{ "meta": { "type": "rss", "version": "2.0" }, "language": null, "title": "Dan Nguyen's Blog | Thoughts, Data and Computational Journalism", "description": "Dan Nguyen is a programmer and computational journalist", "copyright": null, "url": "http://blog.danwin.com/", "self": "http://blog.danwin.com/feed.xml", "published": "2020-07-21T18:20:11.000Z", "updated": "2020-07-21T18:20:11.000Z", "generator": { "label": "Jekyll v3.8.6", "version": null, "url": null }, "image": null, "authors": [], "categories": [], "items": [ { "id": "http://blog.danwin.com/how-to-automatically-timestamp-a-new-row-in-google-sheets-using-apps-script/", "title": "How to automatically timestamp a new row in Google Sheets using Apps Script", "description": "<p>One of my most frequent everyday usecases for spreadsheets is casual tracking of personal activity, like daily exercise, or my progress in Duolingo; here’s what the spreadsheets for those two examples look like, respectively:</p>\n\n<p><img src=\"/files/images/posts/screenshots/daily-spreadsheets.png\" alt=\"image daily-spreadsheets.png\" /></p>\n\n<p>You’ll notice that both have a <strong>datetime</strong> field – I include this not because I’m particularly anal about when exactly I did something, but because maybe down the road I want to do a quickie pivot table analysis, like how often I did things in the morning versus evening, or weekday versus weekend, etc.</p>\n\n<p>More data is <em>generally</em> better than less, since if I don’t capture this info, I can’t go back in time to redo the spreadsheet. However, the mundane work of data entry for an extra field, especially added up over months, risks creating enough friction that I might eventually abandon my “casual tracking”.</p>\n\n<p>Google Sheets does provide <a href=\"https://webapps.stackexchange.com/a/24692/53055\">handy keyboard shortcuts</a> for adding date and time to a field:</p>\n\n<ul>\n <li><code class=\"highlighter-rouge\">Ctrl</code>/<code class=\"highlighter-rouge\">Cmd</code>+<code class=\"highlighter-rouge\">:</code> to insert date: <code class=\"highlighter-rouge\">7/21/2020</code></li>\n <li><code class=\"highlighter-rouge\">Ctrl</code>/<code class=\"highlighter-rouge\">Cmd</code>+<code class=\"highlighter-rouge\">Shift</code> + <code class=\"highlighter-rouge\">:</code> to insert time: <code class=\"highlighter-rouge\">3:25:24 PM</code></li>\n <li><code class=\"highlighter-rouge\">Ctrl</code>/<code class=\"highlighter-rouge\">Cmd</code>+ <code class=\"highlighter-rouge\">Alt</code> + <code class=\"highlighter-rouge\">Shift</code> + <code class=\"highlighter-rouge\">:</code> to insert the full timestamp: <code class=\"highlighter-rouge\">7/21/2020 12:05:46</code></li>\n</ul>\n\n<p>However, doing that per row is still <em>work</em>; more importantly, I wanted to be able to use the iOS version of Google Sheets to enter exercises as soon as I did them (e.g. random sets of pushups or pullups), and these time/date shortcuts are non-existent.</p>\n\n<p>What I needed was for the <strong>datetime</strong> field to be automatically be filled <em>each time I started a new row</em>, i.e. as soon as I filled out the first field of a new row, e.g. Duolingo <strong>word</strong> or exercise <strong>type</strong>.</p>\n\n<h2 id=\"the-solution\">The solution</h2>\n\n<p>What I wanted can be done by using the <strong>Script Editor</strong> and writing a <a href=\"https://developers.google.com/apps-script/guides/sheets\">Google Apps Script snippet</a>. Here are the steps:</p>\n\n<p>First, create a Google Sheet that has at least 2 columns, and with one of the non-first columns titled <strong>datetime</strong>:</p>\n\n<p><img src=\"/files/images/posts/screenshots/google-sheets-blank-datetime-template.png\" alt=\"image google-sheets-blank-datetime-template.png\" /></p>\n\n<p>Then, from the menubar, open <strong>Tools » Script Editor</strong>:</p>\n\n<p><img src=\"/files/images/posts/screenshots/google-sheets-menu-script-editor.png\" alt=\"image google-sheets-menu-script-editor.png\" /></p>\n\n<p>This will take you to a blank template for a new Google App Script project/file:</p>\n\n<p><img src=\"/files/images/posts/screenshots/google-sheets-app-script-editor-new.png\" alt=\"image google-sheets-app-script-editor-new.png\" /></p>\n\n<p>One of the features of Google Apps Script for Google Sheets is <a href=\"https://developers.google.com/apps-script/guides/triggers\">simple triggers</a>, i.e. functions with reserved names like <code class=\"highlighter-rouge\">onOpen(e)</code>, <code class=\"highlighter-rouge\">onEdit(e)</code>, and <code class=\"highlighter-rouge\">onSelectionChange(e)</code> that execute on common document events. What we want is to change a row (i.e. insert a timestamp) when it is edited, so we want <code class=\"highlighter-rouge\">onEdit(e)</code>:</p>\n\n<div class=\"language-js highlighter-rouge\"><div class=\"highlight\"><pre class=\"code-highlight\"><code><span class=\"kd\">function</span> <span class=\"nx\">onEdit</span><span class=\"p\">(</span><span class=\"nx\">e</span><span class=\"p\">)</span> <span class=\"p\">{</span> \n\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>But before we get into <code class=\"highlighter-rouge\">onEdit</code>, we want a helper function that, given a fieldname like <code class=\"highlighter-rouge\">\"datetime\"</code>, it returns the column index as Google Sheets understands it, e.g. <code class=\"highlighter-rouge\">2</code>, in the given screenshot examples. Here’s one way to write that function, which we’ll call <code class=\"highlighter-rouge\">getDatetimeCol()</code>:</p>\n\n<div class=\"language-js highlighter-rouge\"><div class=\"highlight\"><pre class=\"code-highlight\"><code><span class=\"kd\">var</span> <span class=\"nx\">SHEET_NAME</span> <span class=\"o\">=</span> <span class=\"dl\">'</span><span class=\"s1\">Sheet1</span><span class=\"dl\">'</span><span class=\"p\">;</span>\n<span class=\"kd\">var</span> <span class=\"nx\">DATETIME_HEADER</span> <span class=\"o\">=</span> <span class=\"dl\">'</span><span class=\"s1\">datetime</span><span class=\"dl\">'</span><span class=\"p\">;</span>\n\n<span class=\"kd\">function</span> <span class=\"nx\">getDatetimeCol</span><span class=\"p\">(){</span>\n <span class=\"kd\">var</span> <span class=\"nx\">headers</span> <span class=\"o\">=</span> <span class=\"nx\">SpreadsheetApp</span><span class=\"p\">.</span><span class=\"nx\">getActiveSpreadsheet</span><span class=\"p\">().</span><span class=\"nx\">getSheetByName</span><span class=\"p\">(</span><span class=\"nx\">SHEET_NAME</span><span class=\"p\">).</span><span class=\"nx\">getDataRange</span><span class=\"p\">().</span><span class=\"nx\">getValues</span><span class=\"p\">().</span><span class=\"nx\">shift</span><span class=\"p\">();</span>\n <span class=\"kd\">var</span> <span class=\"nx\">colindex</span> <span class=\"o\">=</span> <span class=\"nx\">headers</span><span class=\"p\">.</span><span class=\"nx\">indexOf</span><span class=\"p\">(</span><span class=\"nx\">DATETIME_HEADER</span><span class=\"p\">);</span>\n <span class=\"k\">return</span> <span class=\"nx\">colindex</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>The <code class=\"highlighter-rouge\">onEdit()</code> function can be described like this:</p>\n\n<ul>\n <li>get the currently edited cell (which requires getting the currently active sheet)</li>\n <li><strong>if</strong> the edited cell (i.e. active cell) is in the first column\n <ul>\n <li><strong>and</strong> it is <strong>not</strong> blank</li>\n <li><strong>and</strong> the corresponding datetime field <strong>is</strong> blank</li>\n </ul>\n </li>\n <li><strong>then</strong> set the value of the datetime field to the current timestamp – in this example, I use the <a href=\"https://en.wikipedia.org/wiki/ISO_8601\">ISO 8601</a> standard of <code class=\"highlighter-rouge\">2020-07-20 14:03</code></li>\n</ul>\n\n<p>Here’s the entire code snippet with both functions:</p>\n\n<div class=\"language-js highlighter-rouge\"><div class=\"highlight\"><pre class=\"code-highlight\"><code><span class=\"kd\">var</span> <span class=\"nx\">SHEET_NAME</span> <span class=\"o\">=</span> <span class=\"dl\">'</span><span class=\"s1\">Sheet1</span><span class=\"dl\">'</span><span class=\"p\">;</span>\n<span class=\"kd\">var</span> <span class=\"nx\">DATETIME_HEADER</span> <span class=\"o\">=</span> <span class=\"dl\">'</span><span class=\"s1\">datetime</span><span class=\"dl\">'</span><span class=\"p\">;</span>\n\n<span class=\"kd\">function</span> <span class=\"nx\">getDatetimeCol</span><span class=\"p\">(){</span>\n <span class=\"kd\">var</span> <span class=\"nx\">headers</span> <span class=\"o\">=</span> <span class=\"nx\">SpreadsheetApp</span><span class=\"p\">.</span><span class=\"nx\">getActiveSpreadsheet</span><span class=\"p\">().</span><span class=\"nx\">getSheetByName</span><span class=\"p\">(</span><span class=\"nx\">SHEET_NAME</span><span class=\"p\">).</span><span class=\"nx\">getDataRange</span><span class=\"p\">().</span><span class=\"nx\">getValues</span><span class=\"p\">().</span><span class=\"nx\">shift</span><span class=\"p\">();</span>\n <span class=\"kd\">var</span> <span class=\"nx\">colindex</span> <span class=\"o\">=</span> <span class=\"nx\">headers</span><span class=\"p\">.</span><span class=\"nx\">indexOf</span><span class=\"p\">(</span><span class=\"nx\">DATETIME_HEADER</span><span class=\"p\">);</span>\n <span class=\"k\">return</span> <span class=\"nx\">colindex</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"kd\">function</span> <span class=\"nx\">onEdit</span><span class=\"p\">(</span><span class=\"nx\">e</span><span class=\"p\">)</span> <span class=\"p\">{</span> \n <span class=\"kd\">var</span> <span class=\"nx\">ss</span> <span class=\"o\">=</span> <span class=\"nx\">SpreadsheetApp</span><span class=\"p\">.</span><span class=\"nx\">getActiveSheet</span><span class=\"p\">();</span>\n <span class=\"kd\">var</span> <span class=\"nx\">cell</span> <span class=\"o\">=</span> <span class=\"nx\">ss</span><span class=\"p\">.</span><span class=\"nx\">getActiveCell</span><span class=\"p\">();</span>\n <span class=\"kd\">var</span> <span class=\"nx\">datecell</span> <span class=\"o\">=</span> <span class=\"nx\">ss</span><span class=\"p\">.</span><span class=\"nx\">getRange</span><span class=\"p\">(</span><span class=\"nx\">cell</span><span class=\"p\">.</span><span class=\"nx\">getRowIndex</span><span class=\"p\">(),</span> <span class=\"nx\">getDatetimeCol</span><span class=\"p\">());</span>\n <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">ss</span><span class=\"p\">.</span><span class=\"nx\">getName</span><span class=\"p\">()</span> <span class=\"o\">==</span> <span class=\"nx\">SHEET_NAME</span> <span class=\"o\">&&</span> <span class=\"nx\">cell</span><span class=\"p\">.</span><span class=\"nx\">getColumn</span><span class=\"p\">()</span> <span class=\"o\">==</span> <span class=\"mi\">1</span> <span class=\"o\">&&</span> <span class=\"o\">!</span><span class=\"nx\">cell</span><span class=\"p\">.</span><span class=\"nx\">isBlank</span><span class=\"p\">()</span> <span class=\"o\">&&</span> <span class=\"nx\">datecell</span><span class=\"p\">.</span><span class=\"nx\">isBlank</span><span class=\"p\">())</span> <span class=\"p\">{</span> \n <span class=\"nx\">datecell</span><span class=\"p\">.</span><span class=\"nx\">setValue</span><span class=\"p\">(</span><span class=\"k\">new</span> <span class=\"nb\">Date</span><span class=\"p\">()).</span><span class=\"nx\">setNumberFormat</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">yyyy-MM-dd hh:mm</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n <span class=\"p\">}</span>\n<span class=\"p\">};</span>\n</code></pre></div></div>\n\n<p>Now, select <strong>File » Save</strong> and give your project a name (it can be anything):</p>\n\n<p><img src=\"/files/images/posts/screenshots/google-sheets-app-script-editor-save-project.png\" alt=\"image google-sheets-app-script-editor-save-project.png\" /></p>\n\n<p>And your sheet should have the power of auto-inserted timestamps:</p>\n\n<p><img src=\"/files/images/gifs/google-sheets-autotimestamp.gif\" alt=\"gif animation of google sheet auto updating\" /></p>\n\n<p>Big thanks to the following resources, from which I adapted my solution:</p>\n\n<ul>\n <li><a href=\"https://support.google.com/docs/thread/12320385?hl=en&msgid=12326611\">Abbas Abdulla’s response to the post “Automatic Timestamp when a Cell on the same row gets Updated”, on Google Docs Editors Help forum</a></li>\n <li><a href=\"https://stackoverflow.com/questions/31214352/how-to-use-a-column-header-to-reference-a-cell-in-google-apps-script-spreadsheet\">StackOverflow: How to use a column header to reference a cell in Google Apps Script Spreadsheet</a></li>\n</ul>", "url": "http://blog.danwin.com/how-to-automatically-timestamp-a-new-row-in-google-sheets-using-apps-script/", "published": "2020-07-21T17:14:00.000Z", "updated": "2020-07-21T17:14:00.000Z", "content": null, "image": null, "media": [], "authors": [], "categories": [] }, { "id": "http://blog.danwin.com/request-nypd-form-uf250/", "title": "NYPD Stop, Question, and Frisk Worksheet (UF-250); My attempt at getting the latest version as 'just a researcher'", "description": "<p><strong>June 26, 2020 update:</strong> I hadn’t received a response to this and let it fall by the wayside, but a few people have emailed asking for an update, so I will try again. Note that the Bloomberg era of NYPD Stop and Frisk <a href=\"https://www.nytimes.com/2020/03/02/upshot/stop-and-frisk-bloomberg.html\">made the news</a> during his 2020 presidential candidacy.</p>\n\n<p>I’m writing a book about using SQL for data journalism, and one of the sections will be about the <a href=\"https://danwin.com/2010/07/the-nyts-cop-stop-and-frisk-graphic/\">NYPD’s Stop and Frisk data</a>, which has a long history as both data and policy. In my book, I frequently assert that researching the data is much more important than any programming and database skill. And this includes finding the actual forms – paper or electronic – used for collecting the data.</p>\n\n<p>For a stop-and-frisk encounter by the NYPD, police officers have to fill out a <strong>Stop, Question, and Frisk Worksheet (PD 344-151A)</strong>, also known as a Unified Form 250, aka UF-250. The <a href=\"https://ccrjustice.org/sites/default/files/assets/files/11%2025%2013%20Opp%20to%20Mot%20to%20Intervene%20Decl%20of%20D%20Charney%20Ex%20H.pdf\">2011 version</a> has two sides.</p>\n\n<p>This is the first:</p>\n\n<p><img src=\"/files/images/uf250-2011-side-1.png\" alt=\"uf250-2011-side-1.png\" /></p>\n\n<p>And the second side:</p>\n\n<p><img src=\"/files/images/uf250-2011-side-2.png\" alt=\"uf250-2011-side-2.png\" /></p>\n\n<p>However, after <a href=\"https://www.nytimes.com/2013/08/13/nyregion/stop-and-frisk-practice-violated-rights-judge-rules.html\">a federal judge ruled in 2013</a> that the NYPD’s stop-and-frisk practices violated the constitutional rights of New York’s minorities, the NYPD agreed in 2015 to revise the form, which included requiring officers <a href=\"https://www.nydailynews.com/new-york/stop-and-frisk-forms-require-details-nypd-article-1.2574886\">to write a detailed explanation</a> for why they made a stop.</p>\n\n<p>From a <a href=\"https://www1.nyc.gov/assets/ccrb/downloads/pdf/investigations_pdf/20150302_finest-message-stop-frisk-pursuant-to-floyd.pdf\">March 2, 2015 NYPD memo titled “COURT-ORDERED CHANGES TO NYPD PRACTICES AND POLICES RELATED TO STOPS AND FRISKS”</a>:</p>\n\n<blockquote>\n <p>(2) THE DEPARTMENT FORM ENTITLED STOP, QUESTION AND FRISK REPORT WORKSHEET (PD 344-151A), COMMONLY REFERRED TO AS A UF 250 FORM, MUST BE REVISED TO INCLUDE A NARRATIVE SECTION WHERE AN OFFICER MUST RECORD, IN HIS OR HER OWN WORDS, THE BASIS FOR THE STOP. THE NEW FORM MUST ALSO INCLUDE A SEPARATE EXPLANATION OF WHY A FRISK WAS CONDUCTED. THE CHECKBOX SYSTEM CURRENTLY IN USE MUST BE SIMPLIFIED AND IMPROVED.</p>\n</blockquote>\n\n<p>Previously, NYPD officers could simply check a box labeled with “Furtive Movements”, which was apparently <a href=\"https://www.nytimes.com/2011/12/18/opinion/sunday/young-black-and-frisked-by-the-nypd.html\">the sole and vague reason for half of the 600,000 stops conducted in 2010</a>, and which led to the lawsuit in the first place.</p>\n\n<p>Anyway, I need this new version of UF-250 for my book. But I could not find it via my Google-fu, including searches for <a href=\"https://www.google.com/search?q=stop+frisk+site%3Anyc.gov+filetype%3Apdf\"><code class=\"highlighter-rouge\">stop frisk site:nyc.gov filetype:pdf</code></a> and <a href=\"https://www.google.com/search?q=344-151A+filetype%3Apdf&oq=344-151A+filetype%3Apdf\"><code class=\"highlighter-rouge\">344-151A filetype:pdf</code></a>, so I guess it’s time to contact the <a href=\"https://www1.nyc.gov/site/nypd/bureaus/administrative/public-information.page\">NYPD’s Public Information office</a>.</p>\n\n<p>It’s just a form, so I wouldn’t think it requires the formality of a <a href=\"https://www1.nyc.gov/site/cchr/about/submit-a-foil-request.page\">FOIL request</a> (right?) and the boilerplate language. So I’ll try a friendly email. For the first time in awhile, I’m making this kind of request as someone not currently working for a journalism organization, so here’s how I worded the email, sent from my personal GMail account:</p>\n\n<hr />\n\n<p>Hello,</p>\n\n<p>My name is Dan Nguyen and I am researching law enforcement policy. I’ve been able to find past revisions of the UF-250 form used in Stop and Frisks, such as from 2000 [1] and 2007 [2], but I haven’t found any since the 2015 Floyd v. City of New York decision [3], which required these revisions:</p>\n\n<blockquote>\n <p>… THE DEPARTMENT FORM ENTITLED STOP, QUESTION AND FRISK REPORT WORKSHEET (PD 344-151A), COMMONLY REFERRED TO AS A UF 250 FORM, MUST BE REVISED TO INCLUDE A NARRATIVE SECTION WHERE AN OFFICER MUST RECORD, IN HIS OR HER OWN WORDS, THE BASIS FOR THE STOP. THE NEW FORM MUST ALSO INCLUDE A SEPARATE EXPLANATION OF WHY A FRISK WAS CONDUCTED. THE CHECKBOX SYSTEM CURRENTLY IN USE MUST BE SIMPLIFIED AND IMPROVED.</p>\n</blockquote>\n\n<p>Could you direct me to where the latest revision of UF-250 exists on the NYPD’s website? Or send to my email ([email protected]).</p>\n\n<p>Thank you,\nDan Nguyen</p>\n\n<p>References:</p>\n\n<p>[1] <a href=\"https://www1.nyc.gov/assets/ccrb/downloads/pdf/policy_pdf/issue_based/20010601_sqf.pdf\">https://www1.nyc.gov/assets/ccrb/downloads/pdf/policy_pdf/issue_based/20010601_sqf.pdf</a></p>\n\n<p>[2] <a href=\"https://www1.nyc.gov/assets/nypd/downloads/pdf/public_information/TR534_FINALCompiled.pdf\">https://www1.nyc.gov/assets/nypd/downloads/pdf/public_information/TR534_FINALCompiled.pdf</a></p>\n\n<p>[3] <a href=\"https://www1.nyc.gov/assets/ccrb/downloads/pdf/investigations_pdf/20150302_finest-message-stop-frisk-pursuant-to-floyd.pdf\">https://www1.nyc.gov/assets/ccrb/downloads/pdf/investigations_pdf/20150302_finest-message-stop-frisk-pursuant-to-floyd.pdf</a></p>\n\n<hr />\n\n<p>Note: So I sent this email <em>before</em> I blogged about it, which is why there this error in the text: the Floyd v. City of New York decision was in <em>2013</em>; <a href=\"https://www1.nyc.gov/assets/ccrb/downloads/pdf/investigations_pdf/20150302_finest-message-stop-frisk-pursuant-to-floyd.pdf\">2015 is the date of the NYPD memo</a> asserting the new revisions. Oops.</p>\n\n<p>As for why I’m blogging this: just for funsies. If I get a response, I’ll update and link to the new form for the benefit of fewer researchers. And if not, I’ll update and append my ongoing FOIL adventure.</p>\n\n<hr />\n\n<p>Other useful reading and links (updated June 2020):</p>\n\n<ul>\n <li><a href=\"https://www.courtlistener.com/docket/4347389/davis-v-the-city-of-new-york/?filed_after=&filed_before=&entry_gte=&entry_lte=&order_by=desc\">CourtListener/PACER: Davis v. The City of New York (1:10-cv-00699) Docket</a></li>\n <li><a href=\"https://www.courtlistener.com/recap/gov.uscourts.nysd.357782/gov.uscourts.nysd.357782.355.0.pdf\">MEMO ENDORSEMENT on re: (246 in 1:12-cv-02274-AT-HBP) Status Report filed by Peter L Zimroth, (354 in 1:10-cv-00699-AT-HBP) Status Report filed by Peter L. Zimroth, (526 in 1:08-cv-01034-AT-HBP) Status Report filed by Peter A. Zimroth, re: Recommendation Regarding Stop Report Form. ENDORSEMENT: APPROVED. SO ORDERED. (Signed by Judge Analisa Torres on 3/25/2016) (kko) (Entered: 03/25/2016)</a></li>\n <li><a href=\"https://www.nyclu.org/sites/default/files/field_documents/20190314_nyclu_stopfrisk_singles.pdf\">NYCLU March 2019 Report: Stop-and-Frisk in the de Blasio Era </a></li>\n <li><a href=\"https://www.nydailynews.com/new-york/nyc-crime/ny-stop-question-and-frisk-numbers-jump-20200210-vamjtzdfcvdorot57ajtrhnghu-story.html\">NY Daily News: NYPD stop-and-frisk numbers jumped by 22% in 2019 from prior year: report</a></li>\n <li><a href=\"https://gothamist.com/news/nyc-ending-illegal-stop-and-frisk-era\">Gothamist: NYC Has “A Long Way To Go” To End The Illegal Stop-And-Frisk Era</a></li>\n <li>\n <p><a href=\"https://www.nytimes.com/2020/03/02/upshot/stop-and-frisk-bloomberg.html\">NYT: The Lasting Effects of Stop-and-Frisk in Bloomberg’s New York</a></p>\n </li>\n <li><a href=\"http://www.nyc.gov/html/nypd/downloads/pdf/analysis_and_planning/212-11.pdf\">NYPD Patrol Guide: Procedure No. 212-11: INVESTIGATIVE ENCOUNTERS: REQUESTS FOR INFORMATION, COMMON LAW RIGHT OF INQUIRY AND LEVEL 3 STOPS</a></li>\n <li><a href=\"http://www.nyc.gov/html/ccrb/downloads/pdf/2016pg/pg221-02-use-of-force.pdf\">NYPD Patrol Guide: Procedure No. 221-02: USE OF FORCE </a></li>\n <li><a href=\"http://directives.chicagopolice.org/forms/CPD-11.910.pdf\">Chicago Police Investigatory Stop Report</a></li>\n</ul>", "url": "http://blog.danwin.com/request-nypd-form-uf250/", "published": "2019-11-28T06:00:00.000Z", "updated": "2019-11-28T06:00:00.000Z", "content": null, "image": null, "media": [], "authors": [], "categories": [] }, { "id": "http://blog.danwin.com/the-scammers-of-harvard-law-s-bruce-hay-and-the-nigerian-prince-filter/", "title": "The scammers of Harvard Law's Bruce Hay and the \"Nigerian Prince\" filter", "description": "<p>There’s too much to process in <a href=\"https://www.thecut.com/2019/07/bruce-hay-paternity-trap-maria-pia-shuman-mischa-haider.html\">“The Most Gullible Man in Cambridge\n“</a>, the Kera Bolonik longform piece that dropped yesterday on the <em>New York Magazine/The Cut</em> website. For starters, just how <a href=\"https://twitter.com/BrandyLJensen/status/1153727879215235073\">completely bananas</a> it is from top to bottom. And then, whether the main character and victim, <a href=\"https://hls.harvard.edu/faculty/directory/10374/Hay\">Professor Bruce Hay of Harvard Law</a>, is a reliable and trustworthy narrator. And of course, the absolute marvel of long suffering patience and wisdom that is his ex-wife (more on that later) and mother of his young children.</p>\n\n<p>Because of its many bizarre elements and threads, Bolonik’s article feels much longer than its 7,000-word count and is hard to summarize. But to do it in one convoluted sentence: Professor Hay is the victim of an alleged paternity scam, one so elaborate it nearly cost him and his family their home, and one that includes sexual misconduct allegations leading to <a href=\"https://babe.net/2018/10/02/bruce-hay-harvard-80495\">an ongoing Title IX investigation</a>.</p>\n\n<p>The story’s most notable feature is just how gullible and <em>how dumb</em> Professor Hay – who is the on-record source of 90-95% of the narrative – makes himself sound. In this case, a sentence (or several) can’t do Bolonik’s article justice. But one particularly interesting aspect is how seemingly obvious the ploy seems to be, and yet, how it managed to fool several highly intelligent men, including Professor Hay and – as far as we know – three Harvard-area men.</p>\n\n<p>From the story’s first graf, this is how Hay describes his first encounter with the scammer; I’ve added emphasis to the pickup line:</p>\n\n<blockquote>\n <p>It was just supposed to have been a quick Saturday-morning errand to buy picture hooks. On March 7, 2015, Harvard Law professor Bruce Hay, then 52, was in Tags Hardware in Cambridge, Massachusetts, near his home, when a young woman with long reddish-brown hair approached him to ask where she could find batteries. It was still very much winter, and, once the woman got his attention, he saw that underneath her dark woolen coat and perfectly tied scarf she was wearing a dress and a chic pair of boots — hardly typical weekend-errand attire in the New England college town. When he directed her to another part of the store, she changed the subject. <strong>“By the way, you’re very attractive,” he remembers her saying.</strong></p>\n</blockquote>\n\n<p>In the latter-third of the story, Bolonik writes that Hay and his lawyer uncovered 3 other men who previously filed suit against his scammer. Bolonik met with one of them, who is referred to in court papers as “John Doe”. Here’s how Doe describes meeting the scammer (again, emphasis mine)</p>\n\n<blockquote>\n <p>This past fall, I met Doe, who told me Shuman appeared out of nowhere at an intersection where he was standing with two colleagues and started chatting him up in what he described as hushed tones. He recalled her saying, <strong>“Excuse me, but I couldn’t help but notice that you’re attractive. I’m in town from New York, visiting a friend, and I was hoping you’d be willing to show me around.”</strong> He gave her his cell number.</p>\n</blockquote>\n\n<p>Everything is obvious in retrospect, but here the pickup line, and its contrived circumstances – how many late-20s/early-30s adults show up in Boston or New York without a smartphone to serve as a guide? – seem <em>especially</em> so. How could Doe, described by Bolonik as a “young, lanky, blue-eyed CPA”, or Hay, a tenured professor with nearly 30 years at Harvard Law, fall for something so comically transparent?</p>\n\n<p>Those questions about the depths of human trust and gullibility aren’t readily answered. But I do wonder if the flimsiness of the pickup tactic itself is itself inspired by the trope of the <a href=\"https://en.wikipedia.org/wiki/Advance-fee_scam\">Nigerian Prince email scam</a>, an ostensibly obvious and universally-known scam, <a href=\"https://www.cnbc.com/2019/04/18/nigerian-prince-scams-still-rake-in-over-700000-dollars-a-year.html\">yet one that still brings in fortunes for its perpetrators</a>?.</p>\n\n<p>But couldn’t scammers attract even more victims and their money by being more sophisticated? e.g. pretending to be a prince from a country less notorious than Nigeria? In 2012, Microsoft Research’s Cormac Herley studied this question in one of my favorite white papers, <a href=\"https://www.microsoft.com/en-us/research/publication/why-do-nigerian-scammers-say-they-are-from-nigeria/\">Why Do Nigerian Scammers Say They are From Nigeria?</a> (link to <a href=\"https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/WhyFromNigeria.pdf\">PDF</a>).</p>\n\n<p>Here’s an excerpt from the Discussion section (Section 4):</p>\n\n<blockquote>\n <p>An examination of a web-site that catalogs scam emails shows that 51% mention Nigeria as the source of funds…Why so little imagination? Why don’t Nigerian scammers claim to be from Turkey, or Portugal or Switzerland or New Jersey? Stupidity is an unsatisfactory answer.</p>\n</blockquote>\n\n<p>It’s a very accessible paper and worth reading, but in summary, Herley argues that the use of “Nigeria” (or “Nigerian Prince”) acts as a very effective filter for the scammer, whose has nearly unlimited bandwidth in the amount of emails sent, but very limited time to deal with “false positives” – i.e. potential victims who ultimately wise up. The percentage of targets who would even open an unsolicited email subject line of “Nigeria” is vanishingly and staggeringly tiny. But the ones who do, Herley argues, are extremely profitable to the scammer:</p>\n\n<blockquote>\n <p>If we assume that the scammer enters into email conversation (i.e., attacks) almost everyone who responds, his main opportunity to separate viable from non-viable users is the wording of the original email…Who are the most likely targets for a Nigerian scammer? Since the scam is entirely one of manipulation he would like to attack (i.e., enter into correspondence with) only those who are most gullible…</p>\n\n <p>Since gullibility is unobservable, the best strategy is to get those who possess this quality to self-identify. An email with tales of fabulous amounts of money and West African corruption will strike all but the most gullible\nas bizarre. It will be recognized and ignored by anyone who has been using the Internet long enough to have seen it several times.</p>\n</blockquote>\n\n<blockquote>\n <p>It will be figured out by anyone savvy enough to use a search engine and follow up on the auto-complete suggestions such as shown in Figure 8. It won’t be pursued by anyone who consults sensible family or friends, or who reads any of the advice banks and money transfer agencies make available. Those who remain are the scammers ideal targets. They represent a tiny subset of the overall population.</p>\n</blockquote>\n\n<p>Reading through the <a href=\"https://twitter.com/KeraBolonik/status/1153611968193933312\">Twitter replies to NYMag’s Bolonik</a>, there’s at least <a href=\"https://twitter.com/jordanharap/status/1153774824810078209\">one more guy who has a story about the scammer</a> – though apparently, he appears to have avoided the trap:</p>\n\n<p><a href=\"https://twitter.com/jordanharap/status/1153774824810078209\"><img src=\"/files/images/tweet-jharap-bolonik-thecut-hay-scammer.png\" alt=\"This was crazy to read. I was approached by this woman on Mass Ave (directly across from Harvard Law School) in April 2015. I was a third year law student at the time - may be able to provide further corroboration in light of the ongoing proceedings.\" />\n</a></p>\n\n<p>Hay’s alleged scammer seems to have some of the same constraints as a Nigerian scammer – it’s a huge amount of time and risk to initiate a relationship with a mark who is likely to wise up. So the exceedingly cringe pickup line of <em>“Excuse me, sir, I’mbut I noticed you’re very handsome. Could you show me around New York?”</em> likely had any rejections before finding success in Professor Hay, “John Doe”, and other victims. And this works beautifully for the paternity-test-scammer.</p>\n\n<p>(<strong>Note:</strong> Except for this aside, I’ve deliberately avoid mentioning or speculating about the motives of Hay’s scammers, which would require an entirely separate wordy blog post. Bolonik’s article offers little revelation. But it’s worth noting that in Hay’s case, unlike with Nigerian scammers, the scammers don’t seem to be primarily motivated by money)</p>\n\n<p>But as with everything else in Bolonik’s necessarily convoluted article, there are only more questions. Herley, the Microsoft researcher, points out that Nigerian scammers depend on victims lacking a support network of “sensible family or friends”. Professor Hay does not seem to be in this situation; he says he and his scammer, before they first had sex, had coffee dates and long talks about their respective lives. She would have learned from him that his ex-wife – who he has 2 children with and who he was still living with, amicably – is <em>an assistant U.S. Attorney</em>. At that point, the ostensibly savvy scammer must have realized that no matter how gullible Hay seemed, or how estranged he might be from the rest of Harvard’s elite, Hay’s ex-wife was <em>definitely</em> going to step in and pursue any scammers who threatened Hay’s (i.e. <em>her</em>) home and children.</p>\n\n<p>And yet here we are. The depths and speed at which Professor Hay fell for the scam is shocking. But it doesn’t explain why (again, assuming that money is not an issue) the scammers would entangle themselves with him, when there are so many other marks. This incongruity (among the <em>many</em> others), added to the fact Hay – against the advice of Harvard and other lawyers – shopped his story around to several other journalists before finding Bolonik, is enough to raise serious doubt that we’ve heard all the relevant and significant facts of this bizarre story.</p>", "url": "http://blog.danwin.com/the-scammers-of-harvard-law-s-bruce-hay-and-the-nigerian-prince-filter/", "published": "2019-07-24T13:11:00.000Z", "updated": "2019-07-24T13:11:00.000Z", "content": null, "image": null, "media": [], "authors": [], "categories": [] }, { "id": "http://blog.danwin.com/installing-schemacrawler-for-macos-to-map-out-sqlite-schemas/", "title": "How to install and use schemacrawler on MacOS to generate nifty SQL database schemas", "description": "<p>The following post is a <a href=\"https://gist.github.com/dannguyen/f056d05bb7fec408bb7c14ea1552c349\">copy of this Gist</a>, an instruction recipe I wrote on how to get the superhandy schemacrawler program working on MacOS. It’s a command-line tool that allows you to easily generate SQL schemas as image files, like so:</p>\n\n<p><em>This was tested on MacOS 10.14.5 on 2019-07-16</em></p>\n\n<p><a href=\"http://www.schemacrawler.com/\">schemacrawler is a free and open-source database schema discovery and comprehension tool</a>. It can be invoked from the command-line to produce, using <a href=\"http://www.graphviz.org/\">GraphViz</a>, images/pdfs from a SQLite (or other database type) file. \nIt can be used from the command-line to generate schema diagrams like these:</p>\n\n<p><img src=\"https://user-images.githubusercontent.com/121520/41448959-de545a74-7012-11e8-99f9-520d76a683b8.png\" alt=\"image\" /></p>\n\n<p>To see more examples of commands and diagrams, visit scheacrawler’s docs: http://www.schemacrawler.com/diagramming.html</p>\n\n<h2 id=\"install-graphviz-dependency\">Install graphviz dependency</h2>\n\n<p>For schema drawing, <code class=\"highlighter-rouge\">schemacrawler</code> uses graphviz, which can be installed via the <a href=\"https://brew.sh/\">Homebrew</a> package manager:</p>\n\n<div class=\"language-sh highlighter-rouge\"><div class=\"highlight\"><pre class=\"code-highlight\"><code>brew <span class=\"nb\">install </span>graphviz\n</code></pre></div></div>\n\n<h2 id=\"installing-schemacrawler-as-a-command-line-tool\">Installing <code class=\"highlighter-rouge\">schemacrawler</code> as a command-line tool</h2>\n\n<p>This section gives an example of how to install <code class=\"highlighter-rouge\">schemacrawler</code> so that you can invoke it with your shell. There isn’t a Homebrew recipe, so the shell commands basically:</p>\n\n<ul>\n <li>Download a release zip from <a href=\"https://github.com/schemacrawler/SchemaCrawler/releases\">schemacrawler/releases</a></li>\n <li>Copies the relevant subdir from the release into a local directory, e.g. <code class=\"highlighter-rouge\">/usr/local/opt/schemacrawler</code></li>\n <li>Creates a simple shell script that saves you from having to run <code class=\"highlighter-rouge\">schemacrawler</code> via the <code class=\"highlighter-rouge\">java</code> executable</li>\n <li>symlinks this shell script into an executable path, e.g. <code class=\"highlighter-rouge\">/usr/local/bin</code></li>\n</ul>\n\n<h2 id=\"downloading-and-installing-schemacrawler\">Downloading and installing schemacrawler</h2>\n\n<p>The latest releases can be found on the Github page:</p>\n\n<p>https://github.com/schemacrawler/SchemaCrawler/releases/</p>\n\n<h3 id=\"setting-up-schemacrawler-to-run-on-your-system-via--schemacrawler\">Setting up schemacrawler to run on your system via <code class=\"highlighter-rouge\">$ schemacrawler</code></h3>\n\n<p>In this gist, I’ve attached a shell script <a href=\"https://gist.github.com/dannguyen/f056d05bb7fec408bb7c14ea1552c349#file-script-schemacrawler-on-macos-sh\">script-schemacrawler-on-macos.sh</a> that automates the downloading of the schemacrawler ZIP file from its Github repo, installs it, creates a helper script, and creates a symlink to that helper script so you can invoke it via:</p>\n\n<div class=\"language-sh highlighter-rouge\"><div class=\"highlight\"><pre class=\"code-highlight\"><code><span class=\"nv\">$ </span>schemacrawler ...\n</code></pre></div></div>\n<p>You can copy the script into a file and invoke it, or copy-paste it directly into Bash. Obviously, as with anything you copy-paste, read it for yourself to make sure I’m not attempting to do something malicious.</p>\n\n<p>(An older version of this script can be found <a href=\"https://gist.github.com/dannguyen/f056d05bb7fec408bb7c14ea1552c349#file-OLDscript-schemacrawler-on-macos-sh\">here</a>)</p>\n\n<h4 id=\"a-couple-of-notes-about\">A couple of notes about</h4>\n\n<p>The script <a href=\"https://gist.github.com/dannguyen/f056d05bb7fec408bb7c14ea1552c349#file-script-schemacrawler-on-macos-sh\">script-schemacrawler-on-macos.sh</a> has a few defaults – e.g. <code class=\"highlighter-rouge\">/usr/local/opt/</code> and <code class=\"highlighter-rouge\">/usr/local/bin/</code> – which are assumed to be writeable, but you can change those default vars for yourself.</p>\n\n<p>One of the effects of is that it creates a Bash script named something like</p>\n\n<p>Its contents are:</p>\n\n<p>This script is a derivation of schemacrawler’s <a href=\"https://github.com/schemacrawler/SchemaCrawler/blob/a3fea8be74ae28d6e8318c14f2c3f4be314efe2a/schemacrawler-distrib/src/assembly/schemacrawler.sh\">schemacrawler-distrib/src/assembly/schemacrawler.sh</a>, the contents of which are:</p>\n\n<h2 id=\"general-usage\">General usage</h2>\n\n<p>Now that <code class=\"highlighter-rouge\">schemacrawler</code> is installed as an executable shell command, here’s an example of how to invoke it – change <code class=\"highlighter-rouge\">DBNAME.sqlite</code> and <code class=\"highlighter-rouge\">OUTPUT_IMAGE_FILE.png</code> to something appropriate for your usecase:</p>\n\n<div class=\"language-sh highlighter-rouge\"><div class=\"highlight\"><pre class=\"code-highlight\"><code> schemacrawler <span class=\"nt\">-server</span> sqlite <span class=\"se\">\\</span>\n <span class=\"nt\">-database</span> DBNAME.sqlite <span class=\"se\">\\</span>\n <span class=\"nt\">-user</span> <span class=\"nt\">-password</span> <span class=\"se\">\\</span>\n <span class=\"nt\">-infolevel</span> standard <span class=\"se\">\\</span>\n <span class=\"nt\">-command</span> schema <span class=\"se\">\\</span>\n <span class=\"nt\">-outputformat</span> png <span class=\"se\">\\</span>\n <span class=\"nt\">-outputfile</span> OUTPUT_IMAGE_FILE.png\n</code></pre></div></div>\n\n<h3 id=\"bootload-a-sample-sqlite-database-and-test-out-schemacrawler\">Bootload a sample SQLite database and test out schemacrawler</h3>\n\n<p>Just in case you don’t have a database to play around with, you can copy paste this sequence of SQLite commands into your <strong>Bash</strong> shell, which will create the following empty database file at <code class=\"highlighter-rouge\">/tmp/tmpdb.sqlite</code></p>\n\n<div class=\"language-sh highlighter-rouge\"><div class=\"highlight\"><pre class=\"code-highlight\"><code><span class=\"nb\">echo</span> <span class=\"s1\">'''\nDROP TABLE IF EXISTS business;\nDROP TABLE IF EXISTS inspection;\nDROP TABLE IF EXISTS violation;\n\nCREATE TABLE business (\n business_id TEXT,\n name TEXT,\n address TEXT,\n city TEXT,\n postal_code TEXT,\n latitude DECIMAL,\n longitude DECIMAL,\n phone_number TEXT,\n application_date TEXT,\n owner_name TEXT\n);\n\nCREATE TABLE inspection (\n business_id TEXT,\n \"Score\" NUMERIC,\n date TEXT NOT NULL,\n type TEXT NOT NULL,\n FOREIGN KEY(business_id) REFERENCES business(business_id)\n);\n\nCREATE TABLE violation (\n business_id TEXT,\n date TEXT,\n \"ViolationTypeID\" TEXT,\n risk_category TEXT,\n description TEXT,\n FOREIGN KEY(business_id, date) REFERENCES inspection(business_id, date)\n);'''</span> <span class=\"se\">\\</span>\n | sqlite3 /tmp/tmpdb.sqlite\n</code></pre></div></div>\n\n<p>Invoke <code class=\"highlighter-rouge\">schemacrawler</code> like so:</p>\n\n<div class=\"highlighter-rouge\"><div class=\"highlight\"><pre class=\"code-highlight\"><code>schemacrawler -server sqlite \\\n -user -password \\\n -infolevel standard \\\n -command schema \\\n -outputformat png \\\n -database /tmp/tmpdb.sqlite \\\n -outputfile /tmp/mytmpdb.png\n</code></pre></div></div>\n\n<p>The output of that Bash command will be a file <code class=\"highlighter-rouge\">/tmp/tmpdb.sqlite</code>, which looks like this:</p>\n\n<p><img src=\"https://user-images.githubusercontent.com/121520/61403484-ede86e80-a8c4-11e9-8bda-f9ceb63b6101.png\" alt=\"/tmp/tmpdb.sqlite\" /></p>\n\n<h2 id=\"graphviz-properties\">graphviz properties</h2>\n\n<p>You can edit <code class=\"highlighter-rouge\">schemacrawler.config.properties</code>, which is found wherever you installed the schemacrawler distribution – e.g. if you ran my installer script, it would be in <code class=\"highlighter-rouge\">/usr/local/opt/schemacrawler/config/schemacrawler.config.properties</code></p>\n\n<p>Some example settings:</p>\n\n<div class=\"highlighter-rouge\"><div class=\"highlight\"><pre class=\"code-highlight\"><code>schemacrawler.format.no_schemacrawler_info=true\nschemacrawler.format.show_database_info=true\nschemacrawler.format.show_row_counts=true\nschemacrawler.format.identifier_quoting_strategy=quote_if_special_characters\n\nschemacrawler.graph.graphviz.nodes.ranksep=circo\nschemacrawler.graph.graphviz.graph.layout=circo\nschemacrawler.graph.graphviz.graph.splines=ortho\n\n\nschemacrawler.graph.graphviz.node.shape=folder\nschemacrawler.graph.graphviz.node.style=rounded,filled\nschemacrawler.graph.graphviz.node.fillcolor=#fcfdfc\n#schemacrawler.graph.graphviz.node.color=red\n\nschemacrawler.graph.graphviz.graph.fontname=Helvetica Neue\nschemacrawler.graph.graphviz.node.fontname=Consolas\nschemacrawler.graph.graphviz.edge.fontname=Consolas\nschemacrawler.graph.graphviz.edge.arrowsize=1.5\n</code></pre></div></div>\n\n<p>If you append the previous snippet to the default <code class=\"highlighter-rouge\">schemacrawler.config.properties</code>, you’ll get output that looks like this:</p>\n\n<p><img src=\"https://user-images.githubusercontent.com/121520/61417204-f00ef500-a8e5-11e9-9e97-e690b23e31aa.png\" alt=\"image\" /></p>\n\n<p>More info about GraphViz in this StackOverflow Q:</p>\n\n<p><a href=\"https://stackoverflow.com/questions/11588667/how-to-influence-layout-of-graph-items\">How to influence layout of graph items?</a></p>", "url": "http://blog.danwin.com/installing-schemacrawler-for-macos-to-map-out-sqlite-schemas/", "published": "2019-07-16T05:00:00.000Z", "updated": "2019-07-16T05:00:00.000Z", "content": null, "image": null, "media": [], "authors": [], "categories": [] }, { "id": "http://blog.danwin.com/a-submemberist/", "title": "A submemberist?", "description": "<p>It’s a given that Google has pages for every valid English word in existence as well as most fantastical words. It’s very rare that Google comes up with <em>nothing</em>, even for nonsense or terribly misspelled words.</p>\n\n<p>However, I stumbled upon a non-result for the word “submemberist”:</p>\n\n<p><a href=\"https://www.google.com/search?q=submemberist\">https://www.google.com/search?q=submemberist</a></p>\n\n<p>Of course, by the time you click on the above query, Google will have crawled at least a few pages mentioning the word.</p>\n\n<p>I guess it’s probably not a big deal to come up with arbitrary combinations of letters for which Google has no results. What was interesting about “submemberist” is that it <em>looks</em> like it could be a word. Though to be fair, the <a href=\"https://en.oxforddictionaries.com/definition/us/sub-member\">Oxford “Living” Dictionary only has it listed with a hyphen: “sub-member”</a>.</p>\n\n<p>I didn’t even know “submember” or “sub-member” was a word before I saw Parker Higgins (<a href=\"https://twitter.com/xor\">@xor</a>) tweet some <a href=\"https://twitter.com/xor/status/978793975590150144\">fun trivia about airport codes</a> last night:</p>\n\n<blockquote class=\"twitter-tweet\" data-lang=\"en\"><p lang=\"en\" dir=\"ltr\">As far as I can tell, the longest words you can spell entirely out of airport codes are each 9 letters long. It's quite an evocative list of words, too. <a href=\"https://t.co/ssNMRz3s5O\">pic.twitter.com/ssNMRz3s5O</a></p>— Parker Higgins (@xor) <a href=\"https://twitter.com/xor/status/978793975590150144?ref_src=twsrc%5Etfw\">March 28, 2018</a></blockquote>\n<script async=\"\" src=\"https://platform.twitter.com/widgets.js\" charset=\"utf-8\"></script>\n\n<p>Of all the 3-character codes, “IST” seems the most flexible when it comes to creating a legit combination with a 9-character word. Of course, “memberist” isn’t a word either, though Google at least has plenty of attempted results:</p>\n\n<p><img src=\"/files/images/posts/google-memberist.png\" alt=\"google-memberist.png\" /></p>\n\n<p>I wish I could say this blog post had a more important point about language or even search-engine optimization, but I just wanted to spoil the results for anyone else who ever searches for “submemberist” :p.</p>\n\n<blockquote>\n <p><strong>Update 2019-07-16:</strong> More than a year later, this blog is the only result for a <a href=\"https://www.google.com/search?q=submemberist\">google search of “submemberist”</a>, which means my blog apparently isn’t notable enough to get content-scraped by SEO-spammers!</p>\n\n <p><img src=\"/files/images/submemberist-google-search.png\" alt=\"image submemberist-google-search.png\" /></p>\n</blockquote>", "url": "http://blog.danwin.com/a-submemberist/", "published": "2018-03-28T05:00:00.000Z", "updated": "2018-03-28T05:00:00.000Z", "content": null, "image": null, "media": [], "authors": [], "categories": [] }, { "id": "http://blog.danwin.com/how-james-bamford-exposed-the-nsa-using-its-own-internal-newsletter/", "title": "How James Bamford exposed the NSA using the NSA's own company newsletter", "description": "<p>MuckRock <a href=\"https://www.muckrock.com/news/archives/2017/mar/27/cia-employee-activity-association/\">recently posted a fun FOIA-related item about a declassified CIA memo on “Cover and Security Considerations”</a> for employees who want to have an after-work bowling league or glee club:</p>\n\n<blockquote>\n <p>In most professions, all it takes to form an after-work bowling league is an overly long email chain and some beer money. As a declassified memo recently unearthed in CREST shows, in the CIA, it’s a lot more complicated.</p>\n</blockquote>\n\n<blockquote>\n <p>…To cope with these rather unique challenges, the Agency formed the Employee Activity Association (EAA), which, in exchange for membership dues, would ensure that next weekend’s fishing trip would have a plausible cover story.</p>\n</blockquote>\n\n<blockquote>\n <p>…members were expected to keep the existence or non-existence of the ping-pong team a secret and to attend security briefings.</p>\n</blockquote>\n\n<p>This bureaucratic anal-retentiveness regarding mundane company functions immediately reminded me of <a href=\"https://en.wikipedia.org/wiki/James_Bamford\">James Bamford</a>, the first journalist to bring mainstream attention to the National Security Agency when he published <a href=\"https://en.wikipedia.org/wiki/The_Puzzle_Palace\">“The Puzzle Palace” in 1982</a>.</p>\n\n<p>There is a great profile of Bamford in Baltimore’s City Paper in which he describes finding an internal NSA newsletter that contained chatty and useful details about the agency and, like your typical chatty company newsletter, was meant for employees <em>and their families</em>. And since family members didn’t have special security clearances, that meant that all the NSA internal newsletters were eligible to be released by FOIA. Bamford was able to get thousands of pages of newsletters about the NSA, and that allowed him to greatly expand his knowledge and access to NSA officials.</p>\n\n<p>Unfortunately, City Paper seems to have undertaken one of those news site redesigns/content-management system overhauls <a href=\"https://www.theatlantic.com/technology/archive/2015/11/the-irony-of-writing-about-digital-preservation/416184/\">in which the archives are eradicated from Internet history</a>. Luckily, the Internet Archive still has a copy of the original 2008 article by Lee Gardner: <em><a href=\"https://web-beta.archive.org/web/20111020180602/http://www.citypaper.com/news/story.asp?id=17031\">Secrets and Lies: An Interview With National Security Agency Expert James Bamford</a></em></p>\n\n<p>Here’s the key excerpt, though the entire interview is a great read:</p>\n\n<blockquote>\n <p><strong>[City Pages]</strong>: Did you get any push-back from the agency when you started writing about it? After all, it’s supposed to be top secret.</p>\n</blockquote>\n\n<blockquote>\n <p><strong>[Bamford]</strong>: I had a difficult time. My advance was fairly small, I was living in Massachusetts, I didn’t really know anyone in intelligence, and I hadn’t written anything before. And I was going up against NSA.</p>\n</blockquote>\n\n<blockquote>\n <p>One of the things I was good at in law school was research, so I thought maybe I’d try using the Freedom of Information Act. The problem with that was, NSA is really the only agency excluded from the act. If you sent them a [FOIA] request, they would just send you a letter back saying [under Section 6 of the National Security Agency Act] we don’t have to give you anything, even if it’s unclassified.</p>\n</blockquote>\n\n<blockquote>\n <p>But I found this place, the George C. Marshall Research Library in Lexington, Virginia, and William F. Friedman, one of the founders of the NSA, had left all his papers there. When I got down there, I found the NSA had gotten there just before me and gone through all of his papers and taken a lot of his papers out and put them in a vault down there and ordered the archivist to keep them under lock and key. And I convinced the archivist that that wasn’t what Friedman wanted, and he took the documents out and let me take a look at them.</p>\n</blockquote>\n\n<blockquote>\n <p>Among the documents was an NSA newsletter. These are things the NSA puts out once a month. They’re fairly chatty, but if you read them closely enough you can pick up some pretty good information about the agency. . . . When I was reading one of the newsletters, there was a paragraph that said, “The contents of this newsletter must be kept within the small circle of NSA employees and their families.” And I thought about it for a little bit, and I thought, hmm, they just waived their protections on that newsletter–if that’s on every single newsletter then I’ve got a pretty good case against them. If you’re going to open it up to family members, with no clearance, who don’t work for the agency, then I have every right to it. That was a long battle, but I won it, and they gave me over 5,000 pages’ worth of NSA newsletters going back to the very beginning. That was the first time anyone ever got a lot of information out of NSA.</p>\n</blockquote>\n\n<blockquote>\n <p>We made this agreement where I could come down and spend a week at NSA, and they gave me a little room where I could go over the newsletters and pick the ones I wanted. So I got all that information, and spent about a week at NSA. And finally they really wanted to delete some names and faces, and I said you can do that, but there ought to be some kind of quid pro quo. The quid pro quo was that I get to interview senior officials and take a tour of the agency. And that was what really opened it up.</p>\n</blockquote>\n\n<blockquote>\n <p>It wasn’t the NSA you see today–it was much different. They just thought no one would ever try to write about NSA, and they didn’t think I would have any luck, because who am I? I’m just some guy up in Massachusetts with no track record.</p>\n</blockquote>", "url": "http://blog.danwin.com/how-james-bamford-exposed-the-nsa-using-its-own-internal-newsletter/", "published": "2017-03-30T05:00:00.000Z", "updated": "2017-03-30T05:00:00.000Z", "content": null, "image": null, "media": [], "authors": [], "categories": [] }, { "id": "http://blog.danwin.com/never-too-late-to-start-writing/", "title": "Rabbit holes and writing.", "description": "<p>It’s about 1:50 A.M. and I’m reading a <a href=\"https://news.ycombinator.com/item?id=13823881\">HN thread about a BBC article, titled “Rabbit hole leads to 700-year-old Knights Templar cave”</a>.</p>\n\n<p>Several users point out that the title is a bit of nonsense – “The reference to a rabbit hole makes no sense unless it’s symbolic, since rabbits holes are about the size of a rabbit”. That gets me thinking about the rabbit holes that led into the seemingly huge warrens described in <a href=\"https://en.wikipedia.org/wiki/Watership_Down\">“Watership Down”</a>.</p>\n\n<p>Googling, “watership down rabbit facts” led me to this <a href=\"https://www.theguardian.com/books/2015/jan/04/richard-adams-watership-down-interview\">2015 Guardian interview with author Richard Adams</a>; I knew the book originated from a whimsical story Adams made up to keep his daughters entertained on a car trip. I didn’t realize that he had never written fiction before, or that he was so late in his life when he started:</p>\n\n<blockquote>\n <p>Watership Down was one of the first of these stories. Adams was 52 and working for the civil service when his daughters began pleading with him to tell them a story on the drive to school. “I had been put on the spot and I started off, ‘Once there were two rabbits called Hazel and Fiver.’ And I just took it on from there.” <strong>Extraordinarily, he had never written a word of fiction before, but once he’d seen the story through to the end, his daughters said it was “too good to waste, Daddy, you ought to write that down”</strong>.</p>\n</blockquote>\n\n<blockquote>\n <p>He began writing in the evenings, and the result, an exquisitely written story about a group of young rabbits escaping from their doomed warren, won him both the Carnegie medal and the Guardian children’s prize. “It was rather difficult to start with,” he says. <strong>“I was 52 when I discovered I could write. I wish I’d known a bit earlier. I never thought of myself as a writer until I became one.”</strong></p>\n</blockquote>", "url": "http://blog.danwin.com/never-too-late-to-start-writing/", "published": "2017-03-09T06:00:00.000Z", "updated": "2017-03-09T06:00:00.000Z", "content": null, "image": null, "media": [], "authors": [], "categories": [] }, { "id": "http://blog.danwin.com/on-automated-journalism-don-t-automate-the-good-stuff/", "title": "On automated journalism: Don't automate the good stuff", "description": "<p>I love and frequently recommend Al Weigart’s, <a href=\"https://automatetheboringstuff.com/\">“Automate the Boring Stuff with Python”</a>, because it so perfectly captures how I feel about programming: programming is how we tell computers what to do. And computers, like all of the best mechanical inventions in existence, are best at doing mechanical, i.e. <em>boring</em> work.</p>\n\n<p>The inverse of that mentality – that computers should/can be used to automate the interesting work of our lives – can be found in this blog post (h/t <a href=\"https://twitter.com/ndiakopoulos/status/839668650181283840\">@ndiakopoulos</a>) from the research blog <strong>Immersive Automation</strong>:</p>\n\n<div class=\"highlighter-rouge\"><div class=\"highlight\"><pre class=\"code-highlight\"><code>[Can computers quote like human journalists, and should they?](http://immersiveautomation.com/2017/03/can-computers-quote-like-human-journalists/)\n\n(emphasis added)\n\nWhen a reader enjoys a story in a magazine, they have no way of knowing how an interview between a journalist and a source was conducted. Even quotations – which are widely considered being verbatim repetitions of what has been said in the interview – might be very accurate, but they might as well be heavily modified, or even partially trumped-up.\n\n“For journalists, and their editors, **the most important thing is of course to produce a good piece of writing**. This means they might be forced to make compromises, since the citations must serve a purpose for the story,” Lauri Haapanen explains.\n</code></pre></div></div>\n\n<p>The rest of the post goes on to describe “nine essential quoting strategies used by journalists when writing articles”, which is an interesting discussion in itself. But I wanted to point out how fuzzy (or misguided) the statement bolded above is:</p>\n\n<div class=\"highlighter-rouge\"><div class=\"highlight\"><pre class=\"code-highlight\"><code>For journalists, and their editors, **the most important thing is of course to produce a good piece of writing**.\n</code></pre></div></div>\n\n<p>No.</p>\n\n<p>The most important thing to a journalist is to <strong>produce interesting reporting</strong>.</p>\n\n<p>Let’s look at the ledes – often considered the part of a story where good writing has (and needs) the most impact – of some published journalism:</p>\n\n<p>Those are the ledes for the winners of what is often considered journalism’s most important prize: the Pulitzer Prizer for Public Service</p>\n\n<p>The</p>\n\n<p><a href=\"http://www.pulitzer.org/winners/news-observer-raleigh-nc-work-melanie-sill-pat-stith-and-joby-warrick\">News & Observer in 1996</a></p>\n\n<p><a href=\"http://www.pulitzer.org/winners/boston-globe-1\">Boston Globe</a> in <a href=\"http://www.pulitzer.org/winners/sun-sentinel\">Sun Sentinel in 2013</a>,</p>\n\n<div class=\"highlighter-rouge\"><div class=\"highlight\"><pre class=\"code-highlight\"><code>North Carolina, hundreds of miles from America's traditional Midwest hog belt, has become the nation's No. 2 hog producer. Last year, hogs generated more than $1 billion in revenue -- more than tobacco. This year, hogs are expected to pass broiler chickens as the No. 1 agricultural commodity.\n\n\nOne of the five men arrested early Saturday in the attempt to bug the Democratic National Committee headquarters is the salaried security coordinator for President Nixon’s reelection committee.\n\n\n\nThe District of Columbia's Metropolitan Police Department has shot and killed more people per resident in the 1990s than any other large American city police force.\n\n\n\nBell, one of the poorest cities in Los Angeles County, pays its top officials some of the highest salaries in the nation, including nearly $800,000 annually for its city manager, according to documents reviewed by The Times.\n\n\nSince the mid-1990s, more than 130 people have come forward with horrific childhood tales about how former priest John J. Geoghan allegedly fondled or raped them during a three-decade spree through a half-dozen Greater Boston parishes.\n</code></pre></div></div>\n\n<p>Here’s a clickbait version:</p>\n\n<div class=\"highlighter-rouge\"><div class=\"highlight\"><pre class=\"code-highlight\"><code> We've all seen it, and now there's proof: Police officers sworn to uphold our traffic laws are among the worst speeders on South Florida roads.\n</code></pre></div></div>\n\n<p>https://www.washingtonpost.com/politics/gop-security-aide-among-five-arrested-in-bugging-affair/2012/06/07/gJQAYTdzKV_story.html</p>\n\n<p>And here are a couple of ledes from the la times, which, when read in isolation, falls into the “OK is Dunia and why should I give a shit?”</p>\n\n<p>http://www.pulitzer.org/winners/los-angeles-times-3</p>\n\n<p>But “just the facts” isn’t the sole mark of a good</p>\n\n<p>On a warm July afternoon, an impish second-grader named Dunia Tasejo was running home after buying ice cream on her South Los Angeles street when a car sideswiped her. Knocked to the pavement, she screamed for help, blood pouring from her mouth.</p>\n\n<hr />\n\n<p>I’m being unfair, maybe, because “good” can encompass all of those examples. But that’s my point – “good writing” has no obvious meaning when it comes to journalism or any other form of writing. It is up to the discretion and style of the writers.</p>\n\n<p>But important journalism – journalism that is important to publish. It’s facts.</p>\n\n<hr />\n\n<p>I went into journalism because I liked writing and am old enough that, when I worked for my college paper, it had enough paper to print 10,000 words, in actual pieces of paper with real ink.</p>\n\n<hr />\n\n<p>But I don’t think that computers can’t replace a lot of what humans do. They already do – page layout, copy-editing (of the spell-check variety), and research (of the Google-variety) – have all been replaced. Because much of it was mechanical. But the biggest outlets still hire copy editors (also known as fact checkers) and researchers for the bespoke work.</p>\n\n<p>How much of quoting is bespoke work? Depends. I contend that of all the parts of writing that can be automated, it’s one of the least in terms of return on investment.</p>\n\n<p>To describe writing like this:</p>\n\n<blockquote>\n <p>The Immersive Automation-project focuses on news automation and algorithmically produced news. Since human-written journalistic texts often contain quotations, automated content should also include them to meet the traditional expectations of readers.</p>\n</blockquote>\n\n<p>No it shouldn’t. That’s one of the things I learned in journalism school: don’t quote parts just repeat someone.</p>\n\n<blockquote>\n <p>In the development process of news automation, it is realistic to expect human journalists and machines to collaborate.</p>\n\n <p>“A text generator could write a story and a journalist could interview sources and add quotations in suitable places,” says Haapanen.</p>\n</blockquote>\n\n<p>Also the headline annoys me. It’s not about <strong>can</strong>. Nor is it about <strong>should</strong>.</p>", "url": "http://blog.danwin.com/on-automated-journalism-don-t-automate-the-good-stuff/", "published": "2017-03-08T06:00:00.000Z", "updated": "2017-03-08T06:00:00.000Z", "content": null, "image": null, "media": [], "authors": [], "categories": [] }, { "id": "http://blog.danwin.com/complex-open-source-jekyll-websites-in-the-wild/", "title": "Jekyll websites, open-source and in the real-world", "description": "<p>A student hoping to build a project in Jekyll asked me for examples of well-known, well-designed Jekyll sites.</p>\n\n<p>Of course, a site’s visual appearance technically has nothing to do with its framework – e.g. Jekyll vs. Hugo vs. WordPress vs. Drupal, etc. But for folks starting out, important conventions and best practices – such as how to write the template files, which folders to put CSS and other asset files, how to incorporate Bootstrap/SASS/etc., and overall site configuration – are much easier to learn when having source code from sites built with the same framework.</p>\n\n<p>So I’ve compiled a short list (and am happy to take suggestions) of Jekyll sites that:</p>\n\n<ol>\n <li>Have their source code available to clone and learn from.</li>\n <li>Aren’t just blogs.</li>\n <li>Are attractive.</li>\n <li>Are popular.</li>\n</ol>\n\n<p>Most of these sites have lots of data, content, and words. So they won’t be the most <em>beautiful</em>, in the sense of content-lite sites that feature of chasms of white space and <a href=\"https://unsplash.com/\">beautiful Unsplash-worthy hero images</a>. But I rate their attractiveness in relation to their <em>function</em>. Most of them are aimed at a general audience (especially the government sites). And many of them have to relay a large array of data and content.</p>\n\n<p>If the official documentation on Jekyll’s <a href=\"https://jekyllrb.com/docs/datafiles/\">data files</a>, <a href=\"https://jekyllrb.com/docs/collections/\">collections</a>, and <a href=\"https://jekyllrb.com/docs/variables/\">site variables</a> don’t make immediate sense to you, then take a look at these examples’ repos to see how the professionals organize their Jekyll projects.</p>\n\n<h6 id=\"templates-showcase-from-jekyll-tips\">Templates showcase from Jekyll Tips</h6>\n\n<p><a href=\"http://jekyll.tips/templates/\"><img src=\"/files/images/jekyll-examples-jekyll-tips.png\" alt=\"jekyll-examples-jekyll-tips.png\" /></a></p>\n\n<p><a href=\"http://jekyll.tips/templates/\">http://jekyll.tips/templates/</a></p>\n\n<p>OK, most of these templates are geared toward Jekyll’s original use-case: blogs. But front-end assets for Jekyll blogs can be implemented in the same fashion for Jekyll sites that aren’t straightforward blogs. Each of the templates in this showcase have an associated Github repo.</p>\n\n<h6 id=\"github-on-demand-training\">Github On-Demand Training</h6>\n\n<p>Since <a href=\"https://jekyllrb.com/\">Jekyll itself came out of Github</a> and is used to power Github’s extremely popular <a href=\"https://help.github.com/articles/what-is-github-pages/\">Github Pages feature</a>, pretty much all of Github’s static content is done in Jekyll. I’ve tried to list the more notable examples that have their source code available.</p>\n\n<p>Here’s their On-Demand Training page, which is a homepage for their “How-to Use Github/Git” guides, cheat-sheets, and curricula:</p>\n\n<p><a href=\"https://services.github.com/on-demand/\">https://services.github.com/on-demand/</a></p>\n\n<p>The repo: <a href=\"https://github.com/github/training-kit\">https://github.com/github/training-kit</a></p>\n\n<p><a href=\"https://services.github.com/on-demand/\">\n <img src=\"/files/images/jekyll-examples-github-ondemand-training.jpg\" alt=\"jekyll-examples-github-ondemand-training.jpg\" />\n</a></p>\n\n<p><a href=\"https://services.github.com/on-demand/intro-to-github/\">\n<img src=\"/files/images/jekyll-examples-github-ondemand-training-intro.jpg\" alt=\"jekyll-examples-github-ondemand-training-intro.jpg\" />\n</a></p>\n\n<h6 id=\"githubs-open-source-guide\">Github’s Open Source Guide</h6>\n\n<p><a href=\"https://opensource.guide/\">\n<img src=\"/files/images/jekyll-examples-github-open-source.png\" alt=\"jekyll-examples-github-open-source.png\" />\n</a></p>\n\n<p><a href=\"https://opensource.guide/\">https://opensource.guide/</a></p>\n\n<p>Repo: <a href=\"https://github.com/github/open-source-guide\">https://github.com/github/open-source-guide</a></p>\n\n<p>This isn’t a “complex” site, per se, but it’s a nice non-blog site if you need an example of how to structure a page-based site in Jekyll.</p>\n\n<h6 id=\"marksheet\">MarkSheet</h6>\n\n<p><a href=\"http://marksheet.io/\">\n <img src=\"/files/images/jekyll-examples-marksheet-index.png\" alt=\"jekyll-examples-marksheet-index.png\" />\n</a></p>\n\n<p><a href=\"http://marksheet.io/html-images.html\">\n <img src=\"/files/images/jekyll-examples-marksheet-images-lesson.png\" alt=\"jekyll-examples-marksheet-images-lesson.png\" />\n</a></p>\n\n<p><a href=\"http://marksheet.io/\">http://marksheet.io/</a></p>\n\n<p>Repo: <a href=\"https://github.com/jgthms/marksheet\">https://github.com/jgthms/marksheet</a></p>\n\n<p>MarkSheet is a free HTML and CSS tutorial site. Nice example of how to structure a Jekyll site to accommodate book-reference-like content.</p>\n\n<h6 id=\"consumer-financial-protection-bureaus-developer-homepage\">Consumer Financial Protection Bureau’s Developer Homepage</h6>\n\n<p><a href=\"https://cfpb.github.io/\">https://cfpb.github.io/</a></p>\n\n<p>Repo: <a href=\"https://github.com/cfpb/cfpb.github.io\">https://github.com/cfpb/cfpb.github.io</a></p>\n\n<p>If you want great examples of how to build data-intensive services and sites, there are few better organizations than the CFPB, which, since it’s a government agency, means their work is in the public domain.</p>\n\n<p>Not all of their excellent sites use Jekyll as their front-end (such as <a href=\"https://github.com/cfpb/hmda-explorer\">the HDMA explorer</a>), but the CFPB’s dev/tech homepage uses it as both a landing page and a blog.</p>\n\n<p><a href=\"https://cfpb.github.io/\">\n <img src=\"/files/images/jekyll-examples-cfpb-homepage.png\" alt=\"jekyll-examples-cfpb-homepage.png\" />\n</a></p>\n\n<h6 id=\"the-presidential-innovation-fellows\">The Presidential Innovation Fellows</h6>\n\n<p><a href=\"https://presidentialinnovationfellows.gov/\">\n <img src=\"/files/images/jekyll-examples-presidential-fellows-homepage.jpg\" alt=\"jekyll-examples-presidential-fellows-homepage.jpg\" />\n</a></p>\n\n<p><a href=\"https://presidentialinnovationfellows.gov/fellows/\">\n <img src=\"/files/images/jekyll-examples-presidential-fellows.jpg\" alt=\"jekyll-examples-presidential-fellows.jpg\" />\n</a></p>\n\n<p><a href=\"https://www.presidentialinnovation.org/\">https://www.presidentialinnovation.org/</a></p>\n\n<p>Repo: <a href=\"https://github.com/18F/presidential-innovation-foundation.github.io\">https://github.com/18F/presidential-innovation-foundation.github.io</a></p>\n\n<hr />\n\n<p>The Analytics page for the federal government uses Jekyll to tie together Javascript code for reading from APIs and making charts:\nhttps://analytics.usa.gov/</p>\n\n<p>repo: https://github.com/18F/analytics.usa.gov</p>\n\n<hr />\n\n<hr />\n\n<p>Our own Stanford Computational Journalism Lab homepage is in Jekyll:</p>\n\n<p>http://cjlab.stanford.edu/</p>\n\n<p>repo: https://github.com/compjolab/cjlab-homepage</p>\n\n<hr />\n\n<p>Believe it or not, but healthcare.gov – the front-facing static parts, were built in Jekyll: https://www.healthcare.gov/</p>\n\n<p>They took down their source code but here is an old version of it: \nhttps://github.com/dannguyen/healthcare.gov</p>\n\n<p>And here’s what that old code produced:\nhttp://healthcaregov-jekyll.s3.amazonaws.com/index.html</p>\n\n<p>Here’s a piece in the Atlantic by an open-gov advocate, which is about why healthcare.gov is open source (or was, before the non-Jekyll parts of the site failed to live up to the traffic):</p>\n\n<p>https://www.theatlantic.com/technology/archive/2013/06/healthcaregov-code-developed-by-the-people-and-for-the-people-released-back-to-the-people/277295/</p>\n\n<hr />\n\n<p>18F is the digital agency for the federal government. Much of the modern and best webdev of the U.S. gov is through their shop:</p>\n\n<p>18F’s homepage: https://18f.gsa.gov/\n repo: https://github.com/18F/18f.gsa.gov</p>\n\n<p>Their handbook: https://handbook.18f.gov/\nrepo: https://github.com/18F/handbook</p>\n\n<p>Here’s a post by them about why they switched to Jekyll.</p>\n\n<p>https://18f.gsa.gov/2014/11/17/taking-control-of-our-website-with-jekyll-and-webhooks/</p>\n\n<hr />\n\n<p>https://stackoverflow.blog/</p>\n\n<p>https://github.com/StackExchange/stack-blog</p>\n\n<p>https://stackoverflow.blog/2015/07/01/the-new-stack-exchange-blog/</p>\n\n<p>https://stackoverflow.blog/2015/07/02/how-we-built-our-blog/</p>", "url": "http://blog.danwin.com/complex-open-source-jekyll-websites-in-the-wild/", "published": "2017-03-08T06:00:00.000Z", "updated": "2017-03-08T06:00:00.000Z", "content": null, "image": null, "media": [], "authors": [], "categories": [] }, { "id": "http://blog.danwin.com/finding-stories-in-data-a-presentation-to-college-journalists/", "title": "Finding Stories in Data: A presentation to college journalists", "description": "<p>This past weekend, I did a quick session at the <a href=\"http://acpsanfran.org/\">Associated Collegiate Press Midwinter National College Journalism Convention</a> on how to find stories in data.</p>\n\n<p>You can find a repo with links to my slides and my big list of links here:</p>\n\n<p><a href=\"https://github.com/dannguyen/acp-2017-finding-stories-in-data\">https://github.com/dannguyen/acp-2017-finding-stories-in-data</a></p>\n\n<p>The slides:</p>\n\n<iframe src=\"https://docs.google.com/presentation/d/11wmCbXJ8CjUAnt8k7A_j3-v2vybphhvh5NHISbA-EM8/embed?start=false&loop=false&delayms=3000\" frameborder=\"0\" width=\"960\" height=\"569\" allowfullscreen=\"true\" mozallowfullscreen=\"true\" webkitallowfullscreen=\"true\"></iframe>\n\n<p>It’s not a great or finished presentation, but I’ve been meaning to put together a reusable deck/source list so I can do more of these presentations, so it’s a start. Since this session was for college journalists, most of whom I assume fit the “unknowledgable-of-statistics” mold, I tried to talk about projects that were relevant and feasible for their newsrooms.</p>\n\n<p>In terms of how to get started, my best advice was to join crowdsourcing efforts put on by organizations like ProPublica. Data entry/collection is always a dry affair, but it is always necessary. So it’s all the better if you can find data entry that works towards a good cause. Here’s a few examples:</p>\n\n<ul>\n <li><a href=\"http://www.fatalencounters.org/\">Fatal Encounters</a> - Well before Ferguson, this project – started by a single, curious journalist – recognized the severe deficiency of data on police shootings.</li>\n <li><a href=\"https://projects.propublica.org/graphics/hatecrimes\">Documenting Hate</a> - ProPublica’s initiative to count hate crimes and bias incidents and create a national dataset.</li>\n <li><a href=\"https://www.buzzfeed.com/johntemplon/help-us-map-trumpworld?utm_term=.syzw4LwmP#.eyzXdmXB7\">TrumpWorld</a> - BuzzFeed has logged more than 1,500 of the Trump Administration’s business and personal connections. Use their spreadsheet and help them find more connections.</li>\n</ul>\n\n<p>The best insight I found while gathering material was this GQ interview with Fatal Encounters founder D. Brian Burghart: <a href=\"http://www.gq.com/story/fatal-encounters-police-statistics-interview\">Meet the Man Who Spends 10 Hours a Day Tracking Police Shootings</a>.</p>\n\n<p>Here’s how I documented it in slides:</p>\n\n<p><img src=\"/files/images/fatal-encounters-burghart-slide-01.png\" alt=\"image fatal-encounters-burghart-slide-01.png\" /></p>\n\n<p><img src=\"/files/images/fatal-encounters-burghart-slide-02.png\" alt=\"image fatal-encounters-burghart-slide-02.png\" /></p>\n\n<p><img src=\"/files/images/fatal-encounters-burghart-slide-03.png\" alt=\"image fatal-encounters-burghart-slide-03.png\" /></p>\n\n<p><img src=\"/files/images/fatal-encounters-burghart-slide-04.png\" alt=\"image fatal-encounters-burghart-slide-04.png\" /></p>\n\n<p><img src=\"/files/images/fatal-encounters-burghart-slide-05.png\" alt=\"image fatal-encounters-burghart-slide-05.png\" /></p>\n\n<p><img src=\"/files/images/fatal-encounters-burghart-slide-06.png\" alt=\"image fatal-encounters-burghart-slide-06.png\" /></p>\n\n<p>The main technical advice I gave to students was: Use a spreadsheet for <strong>everything</strong>. Burghart’s vital contribution to journalism is proof of this method.</p>", "url": "http://blog.danwin.com/finding-stories-in-data-a-presentation-to-college-journalists/", "published": "2017-03-06T06:00:00.000Z", "updated": "2017-03-06T06:00:00.000Z", "content": null, "image": null, "media": [], "authors": [], "categories": [] } ] }