Shared posts

15 Aug 01:51

Raising the Shields – Part 15b – Email Privacy!

by Martin

Back in 2013 I set out to decentralize and to end-to-end encrypt as much of my private communication as possible (see here how it all began and here for the overall history). It’s been the year of the Snowden revelations and I was (and still am) more than just a bit concerned. Since then I’ve come a long way. It started with installing the Off-The-Record (OTR) plugin in my XMPP desktop messenger, checking certificates with Certificate Patrol, making sure an encrypted connection is always used when I send emails, using TOR for especially sensitive web sessions, automatically deleting cookies when the browser closes, using Nextcloud (Owncloud back then) for file sharing and synchronizing contacts and calendars between my devices, installing my own XMPP messaging server at home, encrypting my frequent remote screen sharing sessions and I started using my own VPN server at home. Lately, Nextcloud talk has become available for voice and video communication, so I’ve also regained a secure and end-to-end encrypted voice and video channel. There are a lot of other small things I have also implemented over the years but one major service has so far only been inadequately protected: eMail! Well, I’ve finally got a fix for that as well.

Some might argue that email is a lost cause because end-to-end encryption is a mess and mail service providers store a copy of all incoming emails before they are retrieved by their clients. In addition, email providers are obliged by law to store metadata and provide it on request. The only way to escape all of this is to run an email server at home. And even then, it’s still a lost cause because pretty much everyone else is using a public email server, so there is still a weak link on the other side.

But be that as it may, we are using email in my family for a number of reasons to exchange documents. So far, that always had to go via a public service and this was really bothering me. Setting up an email sever at home is no trivial thing so this was pretty much the last piece of the puzzle I hadn’t put in place yet. But with all other things in place I consider important, it was time to tackle this as well.

After looking at a lot of different solutions I decided to set up a simple email sever just consisting of Postfix and Dovecot. As I only need the server for internal communication, I made sure that emails could not be sent from an internal account to external email addresses and also, that the server is not reachable from external domains. In practice that means that I haven’t set an MX record and other things required on the DNS server for external communication and I’ve moved the TCP ports I use for SMTP and POP3 away from their standard places. It’s a perfect setup for internal communication that is reachable from the Internet as it prevents accidental email exchange to and from our public email addresses with an error message the moment a wrong email address is used as sender or receiver address.

Most of the complexity of setting up an email server is to ensure the server is classified as a source of spam and to protect against spam and viruses. Fortunately I don’t have to worry about that at all and so the setup was straight forward. Here’s a great blog post that describes how this is done (in German, unfortunately).

On the email client side, I use Thunderbird and have ensured that SMTP and POP3 are only done over encrypted sessions protected by a Letsencrypt SSL certificate. You might wonder why I use POP3 instead of IMAP!? The reason for this is that I want that data off my server as soon as possible. Yes, my server is at home and all data is on an encrypted partition but still, it shouldn’t be there.

No more metadata about our private internal communication stored externally anymore and no private files stored in the clear on a server somewhere on the Internet until they are picked up. It feels really good!

So it’s been a 5 year voyage to get where I wanted to be with my privacy online. No time to become complacent, however, as security and privacy are not a feature, they are a process! But the main takeaway is that over the last 5 years a lot of tools have become available to better protect oneself from prying eyes and overreaching surveillance on the net!

15 Aug 01:51

7 Benefits of Recumbent Trikes

by Guest Author

7 tips for Recumbent Trike Riders.In this post we highlight 7 benefits of recumbent trikes, including fun, stability, safety, social interaction, exercise, and comfort!

The post 7 Benefits of Recumbent Trikes appeared first on Average Joe Cyclist.

15 Aug 01:51

July #OnABlix Winner!

by Blix PR

We love seeing where your Blix takes you. When Blix riders tag us in their photos using the #OnABlix they are automatically entered for a chance to win the monthly prize in the month they posted! We received a lot of great photos and it was hard to choose a winner.

Congrats to @owenbiddle — our July winner!

Owen was "Blix'n around Nashville", posted on Instagram, tagged us and now will receive a $50 Tango Gift Card to spend wherever he'd like! Thanks so much for sharing your pic! Keep 'em coming!

 

For a chance to be entered into our August photo competition, next time you are out and about with your Blix bike take a picture, tag us and use the #OnABlix for your chance to win the monthly prize! 

 We love to see our Blix Community in action!

Tag us and use the #OnABlix

Blix Bike Facebook   Blix Bike Instagram

15 Aug 01:50

Looking for Your Next Cycling Adventure? The Lake District of England is Calling …

by Average Joe Cyclist

Looking for Your Next Cycling Adventure? The Lake District of England is Calling …Check out this great infographic about cycling opportunities in the Lake District of England.

The post Looking for Your Next Cycling Adventure? The Lake District of England is Calling … appeared first on Average Joe Cyclist.

15 Aug 01:50

How to Save Money in the City

image

Vancouver has a bad reputation as one of the world’s most expensive cities. This has lead to a significant exodus of young professionals, but many have chosen to stay. They’ve chosen to embrace the city’s livability and maintain a high quality of life while also budgeting for its exorbitant housing costs.

A few months ago, I wrapped up the series, My Affordable City, which profiled six people living in big urban centres to learn more about their living situation, how they budget for city life, and their cost-saving tips.

Through this series, the participants profiled offered great advice on how to save money while living in some of Canada’s most expensive cities (Vancouver and Toronto). Many common themes emerged that focus on enjoying everything  cities have to offer, such as attending free events, taking advantage of the sharing economy, and most importantly, getting rid of your car.

Here are their tips on how to save money in the city: 

image

Ditch your car - When I asked participants, “what are your money-saving tips for living in the city?“ The number one response was to get rid of your car. City life means close proximity to shops, parks, amenities and public transit. Most people I spoke to did not own a car, which freed up what for many is the second or third largest expense in their household budget. In the city, people often have access to car sharing, bike sharing, taking public transit and walking, so they no longer need a car. According to Torontonian architect, Craig Race, “car-share programs are an easy way to avoid owning a second car - or having a car at all. We actually find a mixture of transit and car-share programs to be significantly less expensive and more convenient than owning a car.”

Don’t spend more than 30 percent of your income on housing - On average, Canadians spend 45.9% of their income on housing. This is far above the Canada Mortgage and Housing Corporation’s benchmark, which considers housing “affordable” when no more than 30% of pre-tax income is spent on home ownership expenses. Anything more than this means a tighter budget for other essentials, like food, transportation and energy costs. It also means less money for savings and discretionary spending on things like vacations. The participants I profiled spent between 30-45% of their monthly budget on housing.

Apply for community grants or supported housing - The demand for subsidized co-op housing is growing in expensive cities like Vancouver, and recently, the federal government has announced new funding to support more co-op housing. If the wait-list for co-op housing is long or unavailable in your city, you can also look into your eligibility for grants to support things like education or recreation costs, especially if you have kids. According to Vancouver community worker and single mother, Andrea, “Families who meet the eligibility requirements can apply for the following subsidy programs in BC: Vancouver Parks and Recreation Access Card, BC Housing Rental Assistance Program and Province of BC Sports Funding.”

image

Take advantage of community centres, nature and public spaces - Instead of spending $150 a month on fancy fitness studios or expensive hobbies like skiing, get a membership to your local community centre and enjoy affordable access to libraries, pools, gyms, ice rinks, fitness and art classes, and more. According to Vancouver urbanist, Mitchell Reardon, “We tend to meet friends at each other’s places, in the mountains or at the beach – free spaces. The beaches and North Shore are treasures. An early bird season pass at Mount Seymour is $340. We spend a lot of winter nights up there!”

Enjoy free/low-cost events, or volunteer for the expensive ones - Any great city has it’s share of free festivals where you can enjoy concerts, arts, culture, and recreation. If you still are dying to attend an expensive music festival, register as a volunteer and get free access. According to Vancouver graphic artist, Jada Stevens, “Vancouver hosts numerous free events and festivals, which I take advantage of, like the Vancouver Mural Festival, the Pride Festival, and Car Free Days. And, instead of paying for a ticket to a festival, I will volunteer. It’s a fantastic way to give back to my community, meet new people, and enjoy events without buying a ticket.“

Share with friends - If you enjoy spending time with your friends, it shouldn’t matter where you get together. Expensive dinners can be easily replaced with potluck dinners or picnics at the beach. You can even organize fun, money-saving events where you exchange clothes or baby items. According to Jada, “My girlfriends and I organize clothing swaps where we get together for a night of trading our gently-used clothes. It’s easy to walk away with a wardrobe of new-to-me clothes and accessories. It’s also a fantastic way to socialize and we donate the leftover clothing to a woman’s shelter.”

image

Share with strangers…join the sharing economy! - Car shares, bike shares, ride shares, home shares, tool shares. City dwellers love to share instead of own, especially when it comes to transportation. When my husband and I renovated our backyard, we needed a truck and a lot of tools. So, instead of buying these costly items, we used our Modo membership every time we needed a truck and got tools from the Vancouver Tool Library.

Make your meals (and coffee) at home - I confess that I get a fancy coffee from a local cafe every weekday morning. It’s an expensive, difficult habit to break that has become part of my morning ritual. Most of the people I profiled stressed the importance of making their own coffee and meals as a significant source of savings. According to LGBTQ activist Brandon Yan, “I used to buy my lunches at work, but now I make big dinners and bring leftovers. I used to buy my coffee and breakfast on the way to work, and now I brew it all at home and usually have toast or granola. Those expenses cost me $20 a day.”

Have a budget, but don’t let it rule your life -  It is easy to let your spending get out of control if you are not tracking it. There are plenty of online budget or banking apps that allow you to do this easily (this is how I found out I was spending $100 a month at Starbucks!). Once you have this info, you can re-evaluate whether your spending habits reflect what you really value. According to Brandon, “I budget, budget, budget - but I don’t let my budget control my life. “

15 Aug 01:50

Things you don't need when you are about to have a baby

by Alison Mazurek
Using this excuse to post a pic of Mae a couple months old with the one soft baby blanket we used and the portable change mat.

Using this excuse to post a pic of Mae a couple months old with the one soft baby blanket we used and the portable change mat.

It can be so overwhelming being pregnant, especially in a small apartment (or any space) where everyone is telling you the many many things you NEED in order to have a baby. There is truly so little you need to have a baby. Somewhere for baby to sleep, a good stroller and a few options to give your arms a rest. Here is an older post of my most loved items that made having a baby in a small space easier. But you could probably even do with half of that with a little ingenuity.  Below are some things you may think you need when expecting but you don't.....

Change Table (a portable mat and a canvas bin to hold diapers and wipes is all you need)

Diaper Bag ( a backpack with some zippered pouches like these works fine)

More than 2 carriers ( 1 Ergo, 1 Sling or Wrap)

More than 1 baby chair ( I recommend the Nuna Leaf or Baby Bjorn Bouncer)

More than 2 Bottles (wash them by hand quickly or put them in the dishwasher)

Wipe Warmer (rub a wipe in your hands to warm it up, or just use it cold)

Bottle Warmer (warm up in warm water, or again just cold)

Bottle Sterilizer 

More than 4 blankets (1 cozy, 3 swaddles)

Baby Jeans (I know so cute but so hard to get on and not comfortable!)

Baby Shoes! (one pair that stays on for each size is all you need. I loved Mini Mocs.)

Large Plastic Toys ( babies don't need much to be entertained, wait until they need entertainment then choose carefully and swap out regularly)

I'm sure there is even more you can do without! What did I miss? Also I'm considering switching over to Disqus for the comments section. Would you all be up for that? Then you can actually know if i wrote back or if you want to follow a thread. Currently the Squarespace comments don't have that function.

 

 

15 Aug 01:50

Librem 5 general development report – Updated August 6, 2018

by Heather Ellsworth

The Librem 5 team has been a busy group with GUADEC along with lots of exciting development changes. Here’s a summary of what has been going on with the Librem 5 team the last few weeks.

GUADEC

Recently most of the Librem 5 team members attended GUADEC. Some of the Librem 5 attendees gave talks as well. Since many of the talks are still being edited, here are a few of them for your viewing pleasure:

There were also talks given on security items and implementing phone UIs with GTK+. We’ll link to those talks when the editing is complete.

Design

The Librem 5 will look beautiful but that doesn’t come without effort. Lately, our design team has been hard at work on a new icon style for GNOME 3.30 that will be used by the phone. They have also been working on expanding the mockups for the cellular settings panel with more advanced features as well as more detailed work on the shell.

 

Software Work

Images

The images were taking a long time to build so we were able to cut down the total build time by making a few tweaks. This makes development and testing a little nicer. There was also the first prototype aarch64 build with PureOS wich worked well. The images haven’t completely shifted over to PureOS as a base (instead of Debian buster) but that is coming real soon. If you’ve been running the x86_64 VM, then you’ll be happy to know that recent images allow you to resize your rootfs to fill a larger (31GB) space. This will make development much easier since previously the image was only 3.6GB. There is still work to be done on resizing the rootfs but it’s in a usable state now.

Phosh

Phosh has seen many under-the-hood improvements in the form of bug fixes, like several potential crashers and missing initializations. Also the brightness slider was fixed to behave properly when moved.

Wayland global handling was moved into a separate GObject. A lockscreen-manager object was introduced to unclutter things (it also picks up the timeout form GSettings now) and all remaining Layersurfaces were converted into PhoshLayerSurfaces.

It’s these code clean ups that really pave the way for community contributions because the more organized code is, the easier it is to understand and contribute.

The integrity of phosh is critical since it is the phone shell so a gitlab smoketest has been added to run phosh under Valgrind. Also it’s just a start to our eventual language support, but Spanish and German translations have been added.

And there were some odds and ends fixed up in phosh too. As we mentioned in the last progress report blog post, there was some ongoing redshift work. This code was merged to master including a fix for race conditions when listing video modes. Phosh/wlroots now starts via gnome-session and a (software) home button was added to the bottom of the screen.

Wlroots

In the land of wlroots there were also plenty of under-the-hood changes. Some custom video mode patches were merged upstream to allow any custom video mode to be defined. Since the Librem 5 will ultimately not include X support, we needed to remove the dependency on xwayland. So now wlroots is built both with and without xwayland support. A wlroots freeze has also been found to be caused by one logging out of the ssh session that started wlroots and there it is awaiting some upstream discussion on how to handle this.

Keyboard

The keyboard (virtboard) will ultimately benefit from the great text-input protocol work that has been recently worked on. The text-input-v3 patch has also been updated and sent upstream to Wayland for review. An implementation of the text-input protocol for GTK3 was submitted upstream and is a work in progress. For wlroots support, a recreated implementation has been drafted, soon to be submitted for review.

Calls

In order to integrate Calls with the gnome-settings-daemon and gnome-control-center, it became clear from discussions at GUADEC that the best path forward was to switch to using ModemManager instead of ofono. So even though the testing thus far has been with an ofono implementation, this was an unavoidable necessary change. The initial implementation of ModemManager backend of Calls was completed and has started undergoing tests.

The UI of Calls has made some strides to look like the mockups from the design team. Below you can see the implementation (left) next to the mockup (right).

Libhandy

Some more bugs were fixed in libhandy too as well as more preparation for GTK+4. One of the issues found and fixed was memory leak was found and fixed. Also there was a bug found and fixed in HdyColumn where the wrong width was being used for column height calculation.

If you are following the librem-5-dev email list, then you may have seen that libhandy v0.0.2 has been released too!

Epiphany/GNOME Web

Nobody likes unsolicited ads so Better ad blocking was suggested to upstream to be used with epiphany and is undergoing discussion.

Messaging

The phone will ship with an SMS app which also has E2EE messaging. We are working with the Fractal project upstream to get encryption implemented, but it’s not clear whether the Fractal 1-1 successor app (GNOME Messages) will have all the things we need by launch. For a more detailed analysis of Fractal’s role on the Librem 5 read the Banquets and Barbecues blog post.

This is why “Chatty”  (code name) is being developed by Purism, a new chat application using a libpurple backend, which will contain E2EE of XMPP messages via OMEMO from day 1 (when Librem 5 phones are shipped in January), as well as non-encrypted SMS. Since the revelation that ModemManager is needed instead of ofono for the Calls application, a D-BUS handler was created for the ModemManager backend of the messaging app. With this ModemManager setup, sending and receiving SMS is working so far!

Security

Security is one of our favorite things (maybe you’ve noticed) so some research was done on TrustZone, TPM and other related topics. There have also been some internal discussions about tamper-resistant boot, Heads, and alternate USB modes for video output. So we’re really starting to think hard about implementing security measures for the Librem 5.

Kernel

It is no small feat to get a working kernel and drivers ready for the i.MX8M board. With lots of hard work, we now have ethernet working. As a requirement for DRM and graphics support, the PCIe has been forward ported. The second SD port is now working but not SDIO yet (the SDIO board is powered by USB so need to get USB working first) so working on getting the designware USB core working. More i2c devices have been enabled. The board will also need some sort of battery charger and the one being tested now is the BQ25896 from TI, but a power supply driver had to be added and submitted upstream.

There is still a long road ahead towards getting the kernel and all of the drivers in working order, especially on the graphics front. If there are any graphics driver experts out there willing to lend a hand, please reach out to us in the Matrix chat rooms.

Hardware Work

We’re still working with our potential manufacturer of the development boards to review the schematic developed by the Librem 5 hardware engineers and make suggested changes. However, many things are set in stone for the development boards and many parts have been ordered so here are some components you can count on being on your development board:

Community Outreach

There is a new FAQ up on the developer documentation site, just based on some repeat questions we’ve seen in the community/librem-5 matrix channel. We are not aiming to answer ALL questions here that you can think of because that would require too much time but rather we’re adding questions that are just commonly asked.

A big Thanks goes out to all of the external teams that have helped review and merge changes into upstream projects. Everyone’s time and contribution is much appreciated!

That’s all for now folks. Stay tuned for more exciting updates to come!

15 Aug 01:50

Capitalism Killed Our Climate Momentum, Not “Human Nature” | Naomi Klein

Capitalism Killed Our Climate Momentum, Not “Human Nature” | Naomi Klein: Naomi Klein pulls the...
15 Aug 01:49

Zeit Here, Zeit Now: Watching the WWW Wake Up to Container Hosting

by Reverend

It was a pretty busy week at Reclaim Hosting, and I am up early on a Saturday morning working on the final migrations of our shared hosting infrastructure to Digital Ocean. Bye, bye ReliableSite! It has been a very productive summer when it comes to infrastructure, and folks are still reclaiming and domaining so no complaints from the bava. We also continue to make headway on Reclaim Today, our live video show highlighting stuff we’re interested in, working  on, dreaming about, etc. Yesterday’s episode was a 25 minute discussion about Now (which I keep calling Zeit Now because the domain is zeit.co/now) which is a hosting environment that makes it dead simple to host Docker containers on the web. We used the episode as an occasion to work through Now, and talk about our own dreams for container-based hosting at Reclaim. I discovered Now thanks to the following Tweet from ed-tech’s mole from the future, Tony Hirst:

I then played with it briefly, but was fumbling around with Docker on my desktop and ran into issues get a Shiny server running. I abandoned the project, but this episode allowed me to get a clearer understanding of what Now can do, how it differs from Cloudron, and what it could mean from faculty, researchers, edtech, and students who want to spin up container -based apps on the quick.  I also liked this episode a lot because I think it encapsulates pretty well how Tim and I have been working together these last 7 or 8 years. It’s been such a fun and funny relationship in so many ways, and capturing some of that on Reclaim Today seems to be just one of many reasons it feels so good.

15 Aug 01:49

Digging into mbox details: A tale of tm & reticulate

by hrbrmstr
✨

I had to processes a bunch of emails for a $DAYJOB task this week and my “default setting” is to use R for pretty much everything (this should come as no surprise). Treating mail as data is not an uncommon task and many R packages exist that can reach out and grab mail from servers or work directly with local mail archives.

Mbox’in off the rails on a crazy tm1

This particular mail corpus is in mbox🔗 format since it was saved via Apple Mail. It’s one big text file with each message appearing one after the other. The format has been around for decades, and R’s tm package — via the tm.plugin.mail plugin package — can process these mbox files.

To demonstrate, we’ll use an Apple Mail archive excerpt from a set of R mailing list messages as they are not private/sensitive:

library(tm)
library(tm.plugin.mail)

# point the tm corpus machinery to the mbox file and let it know the timestamp format since it varies
VCorpus(
  MBoxSource("~/Data/test.mbox/mbox"),
  readerControl = list(
    reader = readMail(DateFormat = "%a, %e %b %Y %H:%M:%S %z")
  )
) -> mbox

str(unclass(mbox), 1)
## List of 3
##  $ content:List of 198
##  $ meta   : list()
##   ..- attr(*, "class")= chr "CorpusMeta"
##  $ dmeta  :'data.frame': 198 obs. of  0 variables

str(unclass(mbox[[1]]), 1)
## List of 2
##  $ content: chr [1:476] "Try this:" "" "> library(lubridate)" "> library(tidyverse)" ...
##  $ meta   :List of 9
##   ..- attr(*, "class")= chr "TextDocumentMeta"

str(unclass(mbox[[1]]$meta), 1)
## List of 9
##  $ author       : chr "jim holtman "
##  $ datetimestamp: POSIXlt[1:1], format: "2018-08-01 15:01:17"
##  $ description  : chr(0) 
##  $ heading      : chr "Re: [R] read txt file - date - no space"
##  $ id           : chr ""
##  $ language     : chr "en"
##  $ origin       : chr(0) 
##  $ header       : chr [1:145] "Delivered-To: bob@rud.is" "Received: by 2002:ac0:e681:0:0:0:0:0 with SMTP id b1-v6csp950182imq;" "        Wed, 1 Aug 2018 08:02:23 -0700 (PDT)" "X-Google-Smtp-Source: AAOMgpcdgBD4sDApBiF2DpKRfFZ9zi/4Ao32Igz9n8vT7EgE6InRoa7VZelMIik7OVmrFCRPDBde" ...
##  $              : NULL

We’re using unclass() since the str() output gets a bit crowded with all of the tm class attributes stuck in the output display.

The tm suite is designed for text mining. My task had nothing to do with text mining and I really just needed some header fields and body content in a data frame. If you’ve been working with R for a while, some things in the str() output will no doubt cause a bit of angst. For instance:

  • datetimestamp: POSIXlt[1:1], : POSIXlt 😒 and data frames really don’t mix well
  • description : chr(0) / origin : chr(0): zero-length character vectors ☹
  • $ : NULL : Blank element name with a NULL value…I Don’t Even 🤦🏽‍♀️2

The tm suite is also super opinionated and “helpfully” left out a ton of headers (though it did keep the source for the complete headers around). Still, we can roll up our sleeves and turn that into a data frame:

# helper function for cleaner/shorter code
`%|0|%` %
  glimpse()
## Observations: 198
## Variables: 9
## $ author         "jim holtman ", "PIKAL Petr ...
## $ datetimestamp  2018-08-01 15:01:17, 2018-08-01 13:09:18, 2018-...
## $ description    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
## $ heading        "Re: [R] read txt file - date - no space", "Re: ...
## $ id             " "en", "en", "en", "en", "en", "en", "en", "en", ...
## $ origin         NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
## $ header         Delivere...., Delivere...., Delivere...., De...
## $ body           Try this...., SGkNCg0K...., Dear Pik...., De... 

That wasn’t a huge effort, but we would now have to re-process the headers and/or write a custom version of tm.plugin.mail::readMail() (the function source is very readable and extendable) to get any extra data out. Here’s what that might look like:

# Custom msg reader
read_mail  mbox

str(unclass(mbox[[1]]$meta), 1)
## List of 9
##  $ author       : chr "jim holtman "
##  $ datetimestamp: POSIXct[1:1], format: "2018-08-01 15:01:17"
##  $ description  : chr NA
##  $ heading      : chr "Re: [R] read txt file - date - no space"
##  $ id           : chr ""
##  $ language     : chr "en"
##  $ origin       : chr NA
##  $ spam_score   : chr "-3.631"
##  $ header       : chr [1:145] "Delivered-To: bob@rud.is" "Received: by 2002:ac0:e681:0:0:0:0:0 with SMTP id b1-v6csp950182imq;" "        Wed, 1 Aug 2018 08:02:23 -0700 (PDT)" "X-Google-Smtp-Source: AAOMgpcdgBD4sDApBiF2DpKRfFZ9zi/4Ao32Igz9n8vT7EgE6InRoa7VZelMIik7OVmrFCRPDBde" ...

If we wanted all the headers, there are even more succinct ways to solve for that use case.

Packaging up emails with a reticulated message.mbox

Since the default functionality of tm.plugin.mail::readMail() forced us to work a bit to get what we needed there’s some justification in seeking out an alternative path. I’ve written about reticulate before and am including it in this post as the Python standard library module mailbox🔗 can also make quick work of mbox files.

Two pieces of advice I generally reiterate when I talk about reticulate is that I highly recommend using Python 3 (remember, it’s a fragmented ecosystem) and that I prefer specifying the specific target Python to use via the RETICULATE_PYTHON environment variable that I have in ~/.Renviron as RETICULATE_PYTHON=/usr/local/bin/python3.

Let’s bring the mailbox module into R:

library(reticulate)
library(tidyverse)

mailbox 

If you're unfamiliar with a Python module or object, you can get help right in R via reticulate::py_help(). Et sequitur3: py_help(mailbox) will bring up the text help for that module and py_help(mailbox$mbox) (remember, we swap out dots for dollars when referencing Python object components in R) will do the same for the mailbox.mbox class.

Text help is great and all, but we can also render it to HTML with this helper function:

py_doc 

Here's what the text and HTML help for mailbox.mbox look like side-by-side:

We can also use a helper function to view the online documentation:

readthedocs 

Et sequitur: readthedocs(mailbox$mbox) will take us to this results page

Going back to the task at hand, we need to cycle through the messages and make a data frame for the bits we (well, I) care about). The reticulate package does an amazing job making Python objects first-class citizens in R, but Python objects may feel "opaque" to R users since we have to use the $ syntax to get to methods and values and — very often — familiar helpers such as str() are less than helpful on these objects. Let's try to look at the first message (remember, Python is 0-indexed):

msg1 

The output for those last two calls is not shown because they both are just a large text dump of the message source. #unhelpful

We can get more details, and we'll wrap some punctuation-filled calls in two, small helper functions that have names that will sound familiar:

pstr 

Lets see them in action:

pstr(msg1, 1) # we can pass any params str() will take
## List of 10
##  $ _from        : chr "jholtman@gmail.com Wed Aug 01 15:02:23 2018"
##  $ policy       :Compat32()
##  $ _headers     :List of 56
##  $ _unixfrom    : NULL
##  $ _payload     : chr "Try this:\n\n> library(lubridate)\n> library(tidyverse)\n> input 

Using just names() excludes the "hidden" builtins for Python objects, but knowing they are there and what they are can be helpful, depending on the program context.

Let's continue on the path to our messaging goal and see what headers are available. We'll use some domain knowledge about the _headers component, though we won't end up going that route to build a data frame:

map_chr(msg1$`_headers`, ~.x[[1]])
##  [1] "Delivered-To"               "Received"                  
##  [3] "X-Google-Smtp-Source"       "X-Received"                
##  [5] "ARC-Seal"                   "ARC-Message-Signature"     
##  [7] "ARC-Authentication-Results" "Return-Path"               
##  [9] "Received"                   "Received-SPF"              
## [11] "Authentication-Results"     "Received"                  
## [13] "X-Virus-Scanned"            "Received"                  
## [15] "Received"                   "Received"                  
## [17] "X-Virus-Scanned"            "X-Spam-Flag"               
## [19] "X-Spam-Score"               "X-Spam-Level"              
## [21] "X-Spam-Status"              "Received"                  
## [23] "Received"                   "Received"                  
## [25] "Received"                   "DKIM-Signature"            
## [27] "X-Google-DKIM-Signature"    "X-Gm-Message-State"        
## [29] "X-Received"                 "MIME-Version"              
## [31] "References"                 "In-Reply-To"               
## [33] "From"                       "Date"                      
## [35] "Message-ID"                 "To"                        
## [37] "X-Tag-Only"                 "X-Filter-Node"             
## [39] "X-Spam-Level"               "X-Spam-Status"             
## [41] "X-Spam-Flag"                "Content-Disposition"       
## [43] "Subject"                    "X-BeenThere"               
## [45] "X-Mailman-Version"          "Precedence"                
## [47] "List-Id"                    "List-Unsubscribe"          
## [49] "List-Archive"               "List-Post"                 
## [51] "List-Help"                  "List-Subscribe"            
## [53] "Content-Type"               "Content-Transfer-Encoding" 
## [55] "Errors-To"                  "Sender"

The mbox object does provide a get() method to retrieve header values so we'll go that route to build our data frame but we'll make yet-another helper since doing something like msg1$get("this header does not exist") will return NULL just like list(a=1)$b would. We'll actually make two new helpers since we want to be able to safely work with the payload content and that means ensuring it's in UTF-8 encoding (mail systems are horribly diverse beasts and the R community is international and, remember, we're using R mailing list messages):

# execute an object's get() method and return a character string or NA if no value was present for the key
get_chr 

We're also doing this because I get really tired of using the $ syntax.

We also want the message content or payload. Modern mail messages can be really complex structures with many multiple part entities. To put it a different way, there may be HTML, RTF and plaintext versions of a message all in the same envelope. We want the plaintext ones so we'll have to iterate through any multipart messages to (hopefully) get to a plaintext version. Since this post is already pretty long and we ignored errors in the tm portion, I'll refrain from including any error handling code here as well.

map_df(1:py_len(mbox), ~{

  m  mdf

  content_type  mbox_df

glimpse(mbox_df)
## Observations: 198
## Variables: 7
## $ date          2018-08-01 11:01:17, 2018-08-01 09:09:18, 20...
## $ from          "jim holtman ", "PIKAL Pe...
## $ to            "diego.avesani@gmail.com, R mailing list  "Re: [R] read txt file - date - no space", "R...
## $ spam_score    "-3.631", "-3.533", "-3.631", "-3.631", "-3.5...
## $ content_type  "text", "text", "text", "text", "text", "text...
## $ body          "Try this:\n\n library(lubridate)\n library...

FIN

By now, you've likely figured out this post really had nothing to do with reading mbox files. I mean, it did — and this was a task I had to do this week — but the real goal was to use a fairly basic task to help R folks edge a bit closer to becoming more friendly with Python in R. There hundreds of thousands of Python packages out there and, while I'm one to wax poetic about having R or C[++]-backed R-native packages — and am wont to point out Python's egregiously prolific flaws — sometimes you just need to get something done quickly and wish to avoid reinventing the wheel. The reticulate package makes that eminently possible.

I'll be wrapping up some of the reticulate helper functions into a small package soon, so keep your eyes on RSS.


✨: You might want to read this even if you're not interested in mbox files. FIN (right above this note) might have some clues as to why.
1: yes, the section title was a stretch
2: am I doing this right, Mara? ;-)
3: Make Latin Great Again

15 Aug 01:49

Bye-bye Haida Gwaii

I’m down to my last few pictures and stories from our July vacation in Haida Gwaii and Gwaii Haanas.

Two eagles in Gwaii Haanas

Fuji X-T2, XF55-200mmF3.5-4.8, 200mm, 1/680 sec at f/5.6, ISO 200

Most of our stops were at old Haida village sites. One of the highlights, aside from the totem poles, were the sites of the large houses; here’s a sample:

Site of large house at an old Haida Village

Pixel 2, 1/350 sec at f/1.8, ISO 50

The idea was, they dug down into the earth, then they put up a fair-size house on top. The steps down to the floor would provide living and sleeping space; the fire would be in the middle. The interior space was really impressive; there are cool old photos at the Canadian Museum of History.

Skedans and the Hot Springs

Our first Haida-village-site stop was at Skedans; a couple of the locals told us it should be called Q’una, but the local Watchman (who was a woman) Carol Duck, called it “Skedans”, so I guess either works. Carol was absolutely great, and here’s a story. While we were there, the weekly supply boat pulled up, and there was a lot of chaos while they were unloading their stuff. Carol climbed on the boat to visit with someone; when it was pulling out, I noticed she hadn’t come back and mentioned that to one of the locals. He laughed and yelled at them and the boat turned around and brought her back. I guess one of the guys was her partner, because another man hollered out “he’s trying to take your woman away, just like one of those old Haida stories!” and there was a general outburst of hilarity; Carol (everyone called her “Duck”) wasn’t totally amused.

Another stop worth mentioning is Hotspring Island, a totally ordinary little place except for the geothermal hot spring, downstream of which they’ve built a bunch of hot tubs, just above a sandy beach, so you can do the “chill your ass in the North Pacific, then bake it in the hot sulphurous water” thing. A totally relaxing place to stop for lunch.

While we were there, an RCMP police boat pulled up, with a couple of personable young officers; they’d been on a training patrol up and down the remote, stormblown west coast of Haida Gwaii, and broken their boat in a couple of places. In distant communities like Haida Gwaii, the RCMP usually sends in ignorant junior white boys for four-year postings, then rotates them out as they begin to grow a clue or two.

After they left, I was shooting the shit with two Haida tour-guide guys, and it was a little tense until we discovered that we all mostly hold the RCMP in contempt. There’s the part where too many of their arestees die in captivity, the part where they systematically harass their female employees, the part where the leadership was embezzling the retirement funds, the part where they taser ignorant confused immigrants to death in Vancouver airport, and — particularly relevant in that context — the part where our indigenous people have come to regard them, generally, as the enemy.

Back to our vacation. One thing I want to highlight is the general wonderfulness of cruising from island to island in a small boat, every moment a feast for the eyes; I’m talking about the quality of light, and the textures of the trees and the stones and the water. Here are a few random snaps from in the boat.

Little water cave in Haida Gwaii

Pixel 2, 1/750 sec at f/1.8, ISO 51

Water and cave in Haida Gwaii

Pixel 2, 1/530 sec at f/1.8, ISO 51

Gwaii Haanas waterfront

Fuji X-T2, XF55-200mmF3.5-4.8, 55mm, 1/680 sec at f/5.6, ISO 200;
processed with Silver Efex

Gwaii Haanas seawater, very clear

Pixel 2, 1/1900 sec at f/1.8, ISO 51

Trees at the edge of an island, Gwaii Haanas

Fuji X-T2, XF55-200mmF3.5-4.8, 55mm, 1/200 sec at f/4.5, ISO 200

Marine life in Gwaii Haanas

Fuji X-T2, XF55-200mmF3.5-4.8, 67mm, 1/200 sec at f/7.1, ISO 2500

It’s worth noting that those last two pictures are from the exact same spot, beside a random tiny island, looking up at the trees then down at the urchins and anemones. It helps that a Zodiac can float right up to the edge of a rocky island, that this is basically a fjord so there’s lots of water right up to the edge, and that our guide Marilyn was an awesome boat pilot.

Windy Bay

It’s another old Haida village site, but here’s the view coming in; there’s a new big house and totem pole.

Windy Bay on Lyell Island

Fuji X-T2, XF55-200mmF3.5-4.8, 67mm, 1/210 sec at f/5.6, ISO 200

This is on Lyell Island, Athlii Gwaii, a special place. It’s beautiful, like many islands on Gwaii Haanas, but it was the site, starting in 1985, of a pitched battle between the Haida and some supporting greens on one side, and the logging industry, which was hell-bent on monetizing every old-growth tree in the hemisphere. 72 citizens were arrested but they won, and launched the process that led to the creation of Gwaii Haanas. I’m in awe, full of gratitude for those people and their work, and you should be too.

Here are a couple of shots of the totem pole.

Totem pole at Windy Bay on Lyell Island

Pixel 2, 1/3900 sec at f/1.8, ISO 55

Totem pole at Windy Bay at Lyell Island

Fuji X-T2, XF55-200mmF3.5-4.8, 78mm, 1/750 sec at f/5.6, ISO 200

The Haida Watchman there at Windy bay was Henry Tyler (everyone calls him “Tyler”) and when we went into the big house, he told us stories of the Athlii Gwaii protest action (they sent in Haida RCMP officers to arrest their own elders, thinking that would help) and then took out a drum and sang the Athlii Gwaii song which, he said, is becoming the Haida national anthem. It was a moment of wrenching beauty. Thank you Tyler, and good luck to you and your people.

Time moves on, and the old totems that haven’t fallen yet will, but as you can see, the world has new totems too. And then, this is happening.

Tree on fallen totem pole, Haida Gwaii

Pixel 2, 1/1500 sec at f/1.8, ISO 50

15 Aug 01:49

Can you make a mistake around here

by Jim

I wrote my first book with Larry Prusak 25 years ago, while we were both working for Ernst & Young. In the intervening years he turned out another 8 or 10 books while I’ve only managed one more so far. I think he’s done writing books for now, so there’s some chance I may yet catch up.

When I was teaching knowledge management at Kellogg, I invited Larry as a guest speaker. He’s an excellent storyteller, so my students benefitted that afternoon. He opened with a wonderful diagnostic question for organizations: “Can you make a mistake around here?”

Organizations spend a great deal of energy designing systems and processes to be reliable and not make mistakes. This is as it should be. No one wants to fly in a plane that you can’t trust to be reliable.

But what can we learn about organizations from how they respond to mistakes? Do they recognize and acknowledge the fundamental unreliability of people? Or, do they lie to themselves and pretend that they can staff themselves with people who won’t make mistakes?

If you can’t make a mistake, you can’t learn. If you can’t learn, you can’t innovate. You can extend the logic from there.

The post Can you make a mistake around here appeared first on McGee's Musings.

15 Aug 01:49

Recently

by Tom MacWright

Reading

Cool gray city of love

Cool Gray City of Love: 49 views of San Francisco. This very ‘local’ book has been really fun. I realize that many of my reading picks are simply downers, things that I strongly feel I should know about but that are guaranteed to strip away a little more faith in people. And there are elements of that in practically everything I read about San Francisco: the city’s habit of patting itself on the back for superficial ethics at the same time as it becomes the purest expression of America’s race and class-based stratification is grating. But, there are respites from that storyline and this book has a great way of pulling me into positive cycles. For example, I’ve been reading about the hills of SF, which inspires me to go and see or climb those hills. And I’ve been taking more photos from those hills, posting them on Flickr, and having a fun time trying to identify all the features I can see from the vistas and tagging those with notes. It’s altogether a pretty nice, positive loop. If you’re interested in it, there’s a chapter posted on Found SF: Western Addition: A Basic History that was my introduction.

In shorter reads, ‘How an Offer to Sell Wistia Inspired Us to Take On $17M in Debt’ was worthwhile: there are plenty of think-pieces in the same vein, but this one was particularly interesting because it’s specific about how they compensate employees without the possibility of a sellout: which means, profit-sharing and a stock buy-back. And, on the topic of buy-backs, Are Stock Buybacks Starving the Economy? is a bracing read.

How much might workers have benefited if companies had devoted their financial resources to them rather than to shareholders? Lowe’s, CVS, and Home Depot could have provided each of their workers a raise of $18,000 a year, the report found. Starbucks could have given each of its employees $7,000 a year, and McDonald’s could have given $4,000 to each of its nearly 2 million employees.

Watching

I watched Sorry to Bother You and it was excellent, as expected. As was Fruitvale Station. Before watching the former, I read ‘Black Issues in Philosophy: A Conversation on Sorry to Bother You’, which was interesting but could be a lot tighter.

Listening

I’ve still been listening to a lot of Sen Morimoto:

And also Nnamdi Ogbonnaya:

And been feeling some DC nostalgia with Bad Moves, DC’s new successful punk band:

15 Aug 01:49

Book Review – The Unix Haters Handbook

by Martin

The Unix Haters Handbook - CoverBack in 1994, a book was published that I read at the time and up to this day, I am not sure how serious the people who wrote it were about it. Its title: ‘The Unix Haters Handbook‘. Having been in my bookshelf for the better part of the last 20 years, I recently stumbled over it again because quite some time ago, the authors have made an online version available to download for free.

Reading some parts of it again these days brings back fond memories and the realization that computers might be faster and more colorful today, but the problems frustrating people are still the same. Two examples to make my point: The Unix ‘rm’ command still deletes permanently and is probably one of the most dangerous commands at the disposal to shell novices. Or how about ‘inappropriate online behavior’? At the time it was flame wars on Usenet, today it’s flame wars and hate comments on your preferred ‘social media’ website. Nothing has changed except the number of people now involved.

It’s great fun to read! Learn about the past, present and future of problems of interactive computing, all in one volume that will keep you in its ban from before the anti-forward by Dennis Richie right to the bibliography!

15 Aug 01:49

kenyatta: The fish trap exists because of the fish. Once you’ve gotten the fish you can forget the...

kenyatta: The fish trap exists because of the fish. Once you’ve gotten the fish you can forget the...
15 Aug 01:49

datarep: Reddit is Changing its Mind about Elon Musk Time to ...



datarep:

Reddit is Changing its Mind about Elon Musk

Time to short Tesla?

15 Aug 01:48

Quick Geo Queries Using Datasette – Fact Checking a Conversation About Local Building Works on the Isle of Wight

by Tony Hirst

A few weeks ago, chatting with neighbours, comment was made about some earthworks appearing along the roadside a couple of miles away, out towards an area that has been licensed for fracking exploration. Concerns were raised as to whether this new earth embankment might be associated with that.

It is possible to run queries over historical planning applications on the Isle of Wight council website but the results are provided in tabular form:

However, I’ve also been running a scraper over Isle of Wight planning applications for some time, with the data stored in a simple SQLite database. A couple of the columns give latitude and longitude information associated with each application (oftentimes, quite crudely…), and multiple other columns are also available that can be queried over:

It only took a single command line command to fire up a datasette server that meant I could look for planning applications made in recent times in the area:

datasette data.sqlite

A simple query turns up applications in the appropriate parish – the map is automatically created by the datasette server when latitude and longitude columns are returned from a query:

Zooming in gives a possible candidate for the application behind the recent works- a better choice of selected columns would give a more useful tooltip:

A slightly refined query turns up the application in more detail:

And from there it’s easy enough to go to the application  – the one with ID 32578:

Handy…

See also this previous encounter with IW planning applications: All I Did Was Take the Dog Out For a Walk….

PS And also see also: Running Spatial Queries on Food Standards Agency Data Using Ordnance Survey Shapefiles in SpatiaLite via Datasette.

PPS Here’s a handy side effect of running the datasette command from inside a Jupyter notebook – a copy of the query log.

iwplanning

PPS the scraper actually feeds a WordPress plugin I started trying to develop that displays currently open applications in a standing test blog page. I really should tidy that plugin code up and blog it one day…

15 Aug 01:48

A helpful approach to personal data protection regulation

by Doc Searls

Enforcing Data Protection: A Model for Risk-Based Supervision Using Responsive Regulatory Tools, a post by Dvara Research, summarizes Effective Enforcement of a Data Protection Regime, a deeply thought and researched paper by Beni Chugh (@BeniChugh), Malavika Raghavan (@teninthemorning), Nishanth Kumar (@beamboybeamboy) and Sansiddha Pani (@julupani). While it addresses proximal concerns in India, it provides useful guidance for data regulators everywhere.

An excerpt:

Any data protection regulator faces certain unique challenges. The ubiquitous collection and use of personal data by service providers in the modern economy creates a vast space for a regulator to oversee. Contraventions of a data protection regime may not immediately manifest and when they do, may not have a clear monetary or quantifiable harm. The enforcement perimeter is market-wide, so a future data protection authority will necessarily interface with other sectoral institutions.  In light of these challenges, we present a model for enforcement of a data protection regime based on risk-based supervision and the use of a range of responsive enforcement tools.

This forward-looking approach considers the potential for regulators to employ a range of softer tools before a breach to prevent it and after a breach to mitigate the effects. Depending on the seriousness of contraventions, the regulator can escalate up to harder enforcement actions. The departure from the focus on post-data breach sanctions (that currently dominate data protection regimes worldwide) is an attempt to consider how the regulatory community might act in coordination with entities processing data to minimise contraventions of the regime.

I hope European regulators are looking at this. Because, as I said in a headline to a post last month, without enforcement, the GDPR is a fail.

Bonus link from the IAPP (International Association of Privacy Professionals): When will we start seeing GDPR enforcement actions? We guess Feb. 22, 2019.

15 Aug 01:48

"The weak overcomes its menace, the strong over-comes itself."

“The weak overcomes its menace, the strong over-comes itself.” - | Marianne Moore,...
15 Aug 01:48

Three Uses of the Knife

by Eugene Wallingford

I just finished David Mamet's Three Uses of the Knife, a wide-ranging short book with the subtitle: "on the nature and purpose of drama". It is an extended essay on how we create and experience drama -- and how these are, in the case of great drama, the same journey.

Even though the book is only eighty or so pages, Mamet characterizes drama in so many ways that you'll have to either assemble a definition yourself or accept the ambiguity. Among them, he says that the job of drama and art is to "delight" us and that "the cleansing lesson of the drama is, at its highest, the worthlessness of reason."

Mamet clearly believes that drama is central to other parts of life. Here's a cynical example, about politics:

The vote is our ticket to the drama, and the politician's quest to eradicate "fill in the blank", is no different from the promise of the superstar of the summer movie to subdue the villain -- both promise us diversion for the price of a ticket and a suspension of disbelief.

As reader, I found myself using the book's points to ruminate about other parts of life, too. Consider the first line of the second essay:

The problems of the second half are not the problems of the first half.

Mamet uses this to launch into a consideration of the second act of a drama, which he holds equally to be a consideration of writing the second act of a drama. But with fall semester almost upon us, my thoughts jumped immediately to teaching a class. The problems of teaching the second half of a class are quite different from the problems of teaching the first half. The start of a course requires the instructor to lay the foundation of a topic while often convincing students that they are capable of learning it. By midterm, the problems include maintaining the students' interest as their energy flags and the work of the semester begins to overwhelm them. The instructor's energy -- my energy -- begins to flag, too, which echoes Mamet's claim that the journey of the creator and the audience are often substantially the same.

A theme throughout the book is how people immerse themselves in story, suspending their disbelief, even creating story when they need it to soothe their unease. Late in the book, he connects this theme to religious experience as well. Here's one example:

In suspending their disbelief -- in suspending their reason, if you will -- for a moment, the viewers [of a magic show] were rewarded. They committed an act of faith, or of submission. And like those who rise refreshed from prayers, their prayers were answered. For the purpose of the prayer was not, finally, to bring about intercession in the material world, but to lay down, for the time of the prayer, one's confusion and rage and sorrow at one's own powerlessness.

This all makes the book sound pretty serious. It's a quick read, though, and Mamet writes with humor, too. It feels light even as it seems to be a philosophical work.

The following paragraph wasn't intended as humorous but made me, a computer scientist, chuckle:

The human mind cannot create a progression of random numbers. Years ago computer programs were created to do so; recently it has been discovered that they were flawed -- the numbers were not truly random. Our intelligence was incapable of creating a random progression and therefore of programming a computer to do so.

This reminded me of a comment that my cognitive psychology prof left on the back of an essay I wrote in class. He wrote something to the effect, "This paper gets several of the particulars incorrect, but then that wasn't the point. It tells the right story well." That's how I felt about this paragraph: it is wrong on a couple of important facts, but it advances the important story Mamet is telling ... about the human propensity to tell stories, and especially to create order out of our experiences.

Oh, and thanks to Anna Gát for bringing the book to my attention, in a tweet to Michael Nielsen. Gát has been one of my favorite new follows on Twitter in the last few months. She seems to read a variety of cool stuff and tweet about it. I like that.

15 Aug 01:48

Repeat yourself, do more than one thing, and rewrite everything

If you ask a programmer for advice—a terrible idea—they might tell you something like the following: Don’t repeat yourself. Programs should do one thing and one thing well. Never rewrite your code from scratch, ever!.

Following “Don’t Repeat Yourself” might lead you to a function with four boolean flags, and a matrix of behaviours to carefully navigate when changing the code. Splitting things up into simple units can lead to awkward composition and struggling to coordinate cross cutting changes. Avoiding rewrites means they’re often left so late that they have no chance of succeeding.

The advice isn’t inherently bad—although there is good intent, following it to the letter can create more problems than it promises to solve.

Sometimes the best way to follow an adage is to do the exact opposite: embrace feature switches and constantly rewrite your code, pull things together to make coordination between them easier to manage, and repeat yourself to avoid implementing everything in one function..

This advice is much harder to follow, unfortunately.

Repeat yourself to find abstractions.

“Don’t Repeat Yourself” is almost a truism—if anything, the point of programming is to avoid work.

No-one enjoys writing boilerplate. The more straightforward it is to write, the duller it is to summon into a text editor. People are already tired of writing eight exact copies of the same code before even having to do so. You don’t need to convince programmers not to repeat themselves, but you do need to teach them how and when to avoid it.

“Don’t Repeat Yourself” often gets interpreted as “Don’t Copy Paste” or to avoid repeating code within the codebase, but the best form of avoiding repetition is in avoiding reimplementing what exists elsewhere—and thankfully most of us already do!

Almost every web application leans heavily on an operating system, a database, and a variety of other lumps of code to get the job done. A modern website reuses millions of lines of code without even trying. Unfortunately, programmers love to avoid repetition, and “Don’t Repeat Yourself” turns into “Always Use an Abstraction”.

By an abstraction, I mean two interlinked things: a idea we can think and reason about, and the way in which we model it inside our programming languages. Abstractions are way of repeating yourself, so that you can change multiple parts of your program in one place. Abstractions allow you to manage cross-cutting changes across your system, or sharing behaviors within it.

The problem with always using an abstraction is that you’re preemptively guessing which parts of the codebase need to change together. “Don’t Repeat Yourself” will lead to a rigid, tightly coupled mess of code. Repeating yourself is the best way to discover which abstractions, if any, you actually need.

As Sandi Metz put it, “duplication is far cheaper than the wrong abstraction”.

You can’t really write a re-usable abstraction up front. Most successful libraries or frameworks are extracted from a larger working system, rather than being created from scratch. If you haven’t built something useful with your library yet, it is unlikely anyone else will. Code reuse isn’t a good excuse to avoid duplicating code, and writing reusable code inside your project is often a form of preemptive optimization.

When it comes to repeating yourself inside your own project, the point isn’t to be able to reuse code, but rather to make coordinated changes. Use abstractions when you’re sure about coupling things together, rather than for opportunistic or accidental code reuse—it’s ok to repeat yourself to find out when.

Repeat yourself, but don’t repeat other people’s hard work. Repeat yourself: duplicate to find the right abstraction first, then deduplicate to implement it.

With “Don’t Repeat Yourself”, some insist that it isn’t about avoiding duplication of code, but about avoiding duplication of functionality or duplication of responsibility. This is more popularly known as the “Single Responsibility Principle”, and it’s just as easily mishandled.

Gather responsibilities to simplify interactions between them

When it comes to breaking a larger service into smaller pieces, one idea is that each piece should only do one thing within the system—do one thing, and do it well—and the hope is that by following this rule, changes and maintenance become easier.

It works out well in the small: reusing variables for different purposes is an ever-present source of bugs. It’s less successful elsewhere: although one class might do two things in a rather nasty way, disentangling it isn’t of much benefit when you end up with two nasty classes with a far more complex mess of wiring between them.

The only real difference between pushing something together and pulling something apart is that some changes become easier to perform than others.

The choice between a monolith and microservices is another example of this—the choice between developing and deploying a single service, or composing things out of smaller, independently developed services.

The big difference between them is that cross-cutting change is easier in one, and local changes are easier in the other. Which one works best for a team often depends more on environmental factors than on the specific changes being made.

Although a monolith can be painful when new features need to be added and microservices can be painful when co-ordination is required, a monolith can run smoothly with feature flags and short lived branches and microservices work well when deployment is easy and heavily automated.

Even a monolith can be decomposed internally into microservices, albeit in a single repository and deployed as a whole. Everything can be broken into smaller parts—the trick is knowing when it’s an advantage to do so.

Modularity is more than reducing things to their smallest parts.

Invoking the ‘single responsibility principle’, programmers have been known to brutally decompose software into a terrifyingly large number of small interlocking pieces—a craft rarely seen outside of obscenely expensive watches, or bash.

The traditional UNIX command line is a showcase of small components that do exactly one function, and it can be a challenge to discover which one you need and in which way to hold it to get the job done. Piping things into awk '{print $2}' is almost a rite of passage.

Another example of the single responsibility principle is git. Although you can use git checkout to do six different things to the repository, they all use similar operations internally. Despite having singular functionality, components can be used in very different ways.

A layer of small components with no shared features creates a need for a layer above where these features overlap, and if absent, the user will create one, with bash aliases, scripts, or even spreadsheets to copy-paste from.

Even adding this layer might not help you: git already has a notion of user-facing and automation-facing commands, and the UI is still a mess. It’s always easier to add a new flag to an existing command than to it is to duplicate it and maintain it in parallel.

Similarly, functions gain boolean flags and classes gain new methods as the needs of the codebase change. In trying to avoid duplication and keep code together, we end up entangling things.

Although components can be created with a single responsibility, over time their responsibilities will change and interact in new and unexpected ways. What a module is currently responsible for within a system does not necessarily correlate to how it will grow.

Modularity is about limiting the options for growth

A given module often gets changed because it is the easiest module to change, rather than the best place for the change to be made. In the end, what defines a module is what pieces of the system it will never responsible for, rather what it is currently responsible for.

When a unit has no rules about what code cannot be included, it will eventually contain larger and larger amounts of the system. This is eternally true of every module named ‘util’, and why almost everything in a Model-View-Controller system ends up in the controller.

In theory, Model-View-Controller is about three interlocking units of code. One for the database, another for the UI, and one for the glue between them. In practice, Model-View-Controller resembles a monolith with two distinct subsystems—one for the database code, another for the UI, both nestled inside the controller.

The purpose of MVC isn’t to just keep all the database code in one place, but also to keep it away from frontend code. The data we have and how we want to view it will change over time independent of the frontend code.

Although code reuse is good and smaller components are good, they should be the result of other desired changes. Both are tradeoffs, introducing coupling through a lack of redundancy, or complexity in how things are composed. Decomposing things into smaller parts or unifying them is neither universally good nor bad for the codebase, and largely depends on what changes come afterwards.

In the same way abstraction isn’t about code reuse, but coupling things for change, modularity isn’t about grouping similar things together by function, but working out how to keep things apart and limiting co-ordination across the codebase.

This means recognizing which bits are slightly more entangled than others, knowing which pieces need to talk to each other, which need to share resources, what shares responsibilities, and most importantly, what external constraints are in place and which way they are moving.

In the end, it’s about optimizing for those changes—and this is rarely achieved by aiming for reusable code, as sometimes handling changes means rewriting everything.

Rewrite Everything

Usually, a rewrite is only a practical option when it’s the only option left. Technical debt, or code the seniors wrote that we can’t be rude about, accrues until all change becomes hazardous. It is only when the system is at breaking point that a rewrite is even considered an option.

Sometimes the reasons can be less dramatic: an API is being switched off, a startup has taken a beautiful journey, or there’s a new fashion in town and orders from the top to chase it. Rewrites can happen to appease a programmer too—rewarding good teamwork with a solo project.

The reason rewrites are so risky in practice is that replacing one working system with another is rarely an overnight change. We rarely understand what the previous system did—many of its properties are accidental in nature. Documentation is scarce, tests are ornamental, and interfaces are organic in nature, stubbornly locking behaviors in place.

If migrating to the replacement depends on switching over everything at once, make sure you’ve booked a holiday during the transition, well in advance.

Successful rewrites plan for migration to and from the old system, plan to ease in the existing load, and plan to handle things being in one or both places at once. Both systems are continuously maintained until one of them can be decommissioned. A slow, careful migration is the only option that reliably works on larger systems.

To succeed, you have to start with the hard problems first—often performance related—but it can involve dealing with the most difficult customer, or biggest customer or user of the system too. Rewrites must be driven by triage, reducing the problem in scope into something that can be effectively improved while being guided by the larger problems at hand.

If a replacement isn’t doing something useful after three months, odds are it will never do anything useful.

The longer it takes to run a replacement system in production, the longer it takes to find bugs. Unfortunately, migrations get pushed back in the name of feature development. A new project has the most room for feature bloat—this is known as the second-system effect.

The second system effect is the name of the canonical doomed rewrite, one where numerous features are planned, not enough are implemented, and what has been written rarely works reliably. It’s a similar to writing a game engine without a game to implement to guide decisions, or a framework without a product inside. The resulting code is an unconstrained mess that is barely fit for its purpose.

The reason we say “Never Rewrite Code” is that we leave rewrites too late, demand too much, and expect them to work immediately. It’s more important to never rewrite in a hurry than to never rewrite at all.

null is true, everything is permitted

The problem with following advice to the letter is that it rarely works in practice. The problem with following it at all costs is that eventually we cannot afford to do so.

It isn’t “Don’t Repeat Yourself”, but “Some redundancy is healthy, some isn’t”, and using abstractions when you’re sure you want to couple things together.

It isn’t “Each thing has a unique component”, or other variants of the single responsibility principle, but “Decoupling parts into smaller pieces is often worth it if the interfaces are simple between them, and try to keep the fast changing and tricky to implement bits away from each other”.

It’s never “Don’t Rewrite!”, but “Don’t abandon what works”. Build a plan for migration, maintain in parallel, then decommission, eventually. In high-growth situations you can probably put off decommissioning, and possibly even migrations.

When you hear a piece of advice, you need to understand the structure and environment in place that made it true, because they can just as often make it false. Things like “Don’t Repeat Yourself” are about making a tradeoff, usually one that’s good in the small or for beginners to copy at first, but hazardous to invoke without question on larger systems.

In a larger system, it’s much harder to understand the consequences of our design choices—in many cases the consequences are only discovered far, far too late in the process and it is only by throwing more engineers into the pit that there is any hope of completion.

In the end, we call our good decisions ‘clean code’ and our bad decisions ‘technical debt’, despite following the same rules and practices to get there.

15 Aug 01:45

Ghost post from 7 years ago

by Liz

Someone just “liked” a 7 year old post that I made on Diaspora. Shades of the past! Here is the post. Why don’t I write more here and less on FB? Too burned out? Anyway, enjoy…

>>>

Flavia at Tigerbeatdown has linked to this digital paper from the UK that describes low female participation in political discussions online:

http://hansardsociety.org.uk/blogs/edemocracy/archive/2011/07/07/digital-paper-gender-and-digital-politics.aspx

The summary is:

80% of MPs’ blogs are by men
85% of political media blogs are by men
93% of councillors’ blogs are by men
85% of individual blogs in Total Politics Political Blog Awards 2010 were written by men
79% of blog posts and 90% of comments on Lib Dem Voice blog (to November 2010) were written by men

I skimmed through the actual PDF and noticed something… peculiar.

Now, before I get there, Flavia’s post outlines one reason why many women may choose not to participate in public discussion on the internet. She discusses the amount of gendered abuse and scorn that women experience when they get too uppity online. (Flavia’s post: http://tigerbeatdown.com/2011/09/05/politics-and-gender-imbalance-online-women-are-not-participating/) I’ve certainly received my share of that, as have my former co-bloggers, including the now obligatory rape threats and death threats. Some of them I still get, and I haven’t blogged much in public since December.

However, I find at least some of this results of this study questionable. On page 1-2 of the document, you’ll find this quote:

“There is also evidence to suggest that women are discussing politics online in places that would traditionally have been perceived as non-political. Mumsnet, which is dedicated to sharing information and tips on parenting, has a campaigning focus, lobbying government and private companies on a variety of issues. This site has blogs from female contributors, and features a talk section, where users are able to discuss issues such as childcare, children’s food and education, lifestyle issues, health and politics. As of July 2011, Mumsnet has a number of active discussions around the public sector pensions, the NHS, EU and Margaret Thatcher’s refusal to meet Sarah Palin, all political issues.”

I read this as dividing what Mumsnet discusses into two groups. One is non-political. It includes childcare, children’s food and education, lifestyle issues, and health. It also has “politics”, which includes pensions, NHS, EU, and Margaret Thatcher.

I don’t live in a world that shares that divide.

Some of you have probably been around the block on the “where are all the women bloggers!” discussions that come up periodically when male bloggers suddenly realise they don’t read a single blog written by a woman, and thus decide there aren’t any. A particularly “fun” example of this is at Hoyden about Town back in 2009, that devolved into a very lengthy comment thread while a very nice man explained that he had no idea why disability, childcare, gender equality or midwifery would be considered a political issue.

http://hoydenabouttown.com/20090819.6278/quickhit-invisible-women-invisible-politics/

To quote the blogger in question (comment 7):

“I’m guilty of defining politics very narrowly in that post – but to the audience of my blog that’s what politics means to them – party and electoral politics and legislation. It’s from that perspective I was asking where the female political bloggers are.”

This was my response (Comment 9):

“A bucket of what Lauredhel & Tigtog blog about is about legislation. It includes legislation about breast feeding, midwifery, and disability.”

These things are politics too. When you put childcare on one side of a divide and politics on another, you’re depoliticizing the issues because it’s convenient to do so. Regardless of how you feel about state-run childcare facilities, _discussing that is discussing politics. Discussing the so called work-family balance is discussing politics. Discussing the use of midwifery and home births is discussing politics, because these things have legislation.

Women’s lives are not hobbies. They, too, are politics.

Where are all the women writing online about politics? Right here. You don’t even have to lift up a rock to find them, they’re out in the open, right where you aren’t looking.

14 Aug 20:35

Seveneves

by peter@rukavina.net (Peter Rukavina)

Being a longtime member of the congregation of Stewart Brand, I have been following the Long Now Foundation and its tentacles in recent years; one of these is The Interval at Long Now, the coffee shop cum bar cum thinkers lounge cum library in San Francisco (where I’m pretty certain I could set up a cot and never leave).

Long Now has a speaker series called The Conversations at The Interval that has included as interesting a collection of great minds as you’ll find anywhere; back in 2015, or 02015 as the Long Nowistas style their years, Neal Stephenson spoke about his then-recently-released book Seveneves (which, oddly but somehow appropriately, you can read here in its entirety). I’d known of Stephenson for a long time, but had never read anything he’d written. His talk was so compelling, however, that I put Seveneves on reserve at the public library.

In an uncharacteristic marathon of reading–more analog pages than I’ve read in years–I finished the last page this morning, over breakfast at Receiver Coffee.

I loved it.

Maybe you will too?

Here’s how it starts:

The Moon blew up without warning and for no apparent reason. It was waxing, only one day short of full. The time was 05:03:12 UTC. Later it would be designated A+0.0.0, or simply Zero.

An amateur astronomer in Utah was the first person on Earth to realize that something unusual was happening. Moments earlier, he had noticed a blur flourishing in the vicinity of the Reiner Gamma formation, near the moon’s equator. He assumed it was a dust cloud thrown up by a meteor strike. He pulled out his phone and blogged the event, moving his stiff thumbs (for he was high on a mountain and the air was as cold as it was clear) as fast as he could to secure the claim to himself. Other astronomers would soon be pointing their telescopes at the same dust cloud—might be doing it already! But—supposing he could move his thumbs fast enough—he would be the first to point it out. The fame would be his; if the meteorite left behind a visible crater, perhaps it would even bear his name.

His name was forgotten. By the time he had gotten his phone out of his pocket, his crater no longer existed. Nor did the moon.

When he pocketed his phone and put his eye back to the eyepiece of his telescope, he let out a curse, since all he saw was a tawny blur. He must have knocked the telescope out of focus. He began to twiddle the focus knob. This didn’t help.

Finally he pulled back from the telescope and looked with his naked eyes at the place where the moon was supposed to be. In that moment he ceased to be a scientist, with privileged information, and became no different from millions of other people around the Americas, gaping in awe and astonishment at the most extraordinary thing that humans had ever seen in the sky.

In movies, when a planet blows up, it turns into a fireball and ceases to exist. This is not what happened to the moon. The Agent (as people came to call the mysterious force that did it) released a very large amount of energy, to be sure, but not nearly enough to turn all the moon’s substance into fire.

14 Aug 18:21

Stuff that works :: CleanMyMac

by Volker Weber

ZZ6A4CC339

I love this program. It helps me keep my Macs lean by removing old junk. Highly recommended.

More >

14 Aug 18:21

Literary Clock Made From An Old Kindle

by Volker Weber

F6M7J9DJK4UKQIU
Photo Jaap Meiyers

My girlfriend is a *very* avid reader. As a teacher and scholar of English literature, she reads eighty books per year on average. On her wishlist was a clock for our living room. I could have bought a wall clock from the store, but where is the fun in that? Instead, I made her a clock that tells the time by quoting time indications from literary works, using an e-reader as display, because it's so incredibly appropriate :-)

That sounds like a fun project.

More >

14 Aug 18:21

Sonos as a platform

by Volker Weber

IMG 4071

I have a small frustration: the Sonos developer program is still invite only. If you could only see what is going on behind the curtain, you would understand so many things that are happening. For instance you would not complain about the ID that Sonos wants its customers to register. You have to be ready for what is coming.

Anyway, there is a developer program coming. It revolves around new APIs. Some of them are already being used by integration partners. All the third party controllers you see today, all the code on Github, that is all old stuff revolving around UPnP. If you seriously want to build something, you have to talk to Sonos so you can use a robust API instead of a reverse-engineered protocol.

What you see above is TunesMap, an Apple TV app that visualizes what is going on in a selected Sonos player of your household. It's built with the Sonos API. And I wish Sonos would unleash this to everybody so that you could start building crazy good stuff.

14 Aug 18:21

HomePod as conference speakerphone

by Volker Weber

IMG 20180806 135615

This wasn't obvious to me, but using your HomePod as a speakerphone is a really cool usecase. When in a call, hit the Audio button and select your nearest HomePod to transfer the audio to instead of using the iPhone speaker. I still need to try this out on longer calls, but there is a lot going on in HomePod to make this work really well. For now, you can't ask Siri to place calls for you or to answer your iPhone, but that is an obvious next stept.

IMG 4080

HomePod just got a lot more useful. And it's pretty unique. Sonos can't do that, neither can Amazon Echo. It's very much like a Polycom Soundstation.

Update: This is working really well. Much better than a Polycom.

09 Aug 14:02

advertisingpics: SCM -‘The End of The Silent Letter’ (late...



advertisingpics:

SCM -‘The End of The Silent Letter’ (late 1960’s)

09 Aug 14:02

Rogers has both the fifth and sixth generation iPads on sale for $359

by Brad Bennett
new apple iPad 2017

Rogers is currently offering a sale on 32GB and 128GB model iPads and they’re a bit cheaper than Apple’s price.

There are two separate generations of iPads on sale. There are the fifth-generation models that came out in 2017 and the sixth-gen models from earlier this year.

The fifth-gen iPad is slightly slower than Apple’s newest model, but not enough to notice right away. The older iPad also lacks support for the Apple Pencil, so if you’re looking to use it with Apple’s stylus, you’re out of luck. Rogers has in stock three colour options for the 32GB model, Space Grey, Silver and Gold. The tablet starts at $359 CAD, while the larger storage variant only comes in Silver and costs $489 CAD.

The sixth-generation iPad also comes in 32GB and 128GB, but both storage options only come in black. This model starts at $359 too, while the larger option starts at $479. The newer iPads are a better deal as long as you don’t mind black, but Rogers has hidden them off-screen. To find the deal just click on the left arrow three times and the newest iPad will filter onto the screen.

A brand new sixth generation iPad starts at $429 for a 32GB model and $549 for the 128GB.

If you’re willing to buy a refurbished iPad, Apple sells 2017 models online starting at $319, which is a bit less than Rogers, but it’s refurbished, not brand new.

Source: Rogers, Apple

The post Rogers has both the fifth and sixth generation iPads on sale for $359 appeared first on MobileSyrup.

09 Aug 14:02

Are you interested in the Microsoft Surface Go?

by Dean Daley
Microsoft's diminutive new Surface Go 2-in-1

Microsoft has recently released the Surface Go, a low-cost 2-in-1 laptop-tablet hybrid. The U.S.-based company has positioned the new 2-in-1 as the perfect device for children and teens, or anyone who wants a smaller second computer.

The Surface Go features a 10-inch PixelSense Display with a 1,800 x 1,200 pixel resolution. Further, the tablet features up to 8GB of RAM, up to 128GB of storage,  and includes a 7th-gen Intel Pentium Gold Processor 4415Y and an Intel HD Graphics 615 graphics card.

The Surface Go is available in two models, the base one with 4GB of RAM and 64GB of internal storage costs $529 CAD. Meanwhile, the more expensive variant, with 8GB of RAM and 128GB of internal storage, retails for $699.

The Surface Go is an interesting tablet-laptop hybrid but is it worth it the cost? Microsoft sells the Type Cover separately at $169.99, making the lower model cost $699.98 with keyboard and the more expensive model $869.99.

And while some tablet-laptop hybrid come with styluses, Microsoft sells that separately as well for $129.99.

So adding that all together, the laptop starts at $829.99 for the base model.

There are a variety of other Windows and Chromebook options that retail around the price. So the question remains, is the Surface Go worth the cost? And are you even interested in a laptop-tablet hybrid like the Surface Go?

Let us know in the poll and the comments below.

Take Our Poll

The post Are you interested in the Microsoft Surface Go? appeared first on MobileSyrup.