How do you address being fired when asked in an interview? Turn it into a growth story. https://discoverpraxis.com/turn-defeat-growth-story/Archived Link

How do you address being fired when asked in an interview? Turn it into a growth story. https://discoverpraxis.com/turn-defeat-growth-story/Archived Link

Up until last week, Sass breakpoints were a bit of a mystery to me. I finally figured out how they work.
First, they are programmatically generated. Define the breakpoints as a map. I use the list here.
$breakpoints: ( xs: 512px, sm: 768px, md: 896px, lg: 1152px, xl: 1280px );
Next, use a mixin and expressions to build the media queries. I use min-width. I leave it as an exercise for the reader if you wish to reverse this to use max-width instead.
@mixin breakpoint( $breakpoint ) { @if map-has-key( $breakpoints, $breakpoint ) { @media ( min-width: #{ map-get( $breakpoints, $breakpoint ) } ) { @content; } } @else if type_of( $breakpoint ) == number and unit( $breakpoint ) == px or unit( $breakpoint ) == em or unit( $breakpoint ) == rem { @media (min-width: $breakpoint ) { @content; } } @else { @warn "No value could be retrieved from `#{$breakpoint}`. " + "It is either not defined in the `$breakpoints` map, or it is an invalid number of px, em, or rem."; } }
To use, define your breakpoint styles using @import. Here is an example defining H1 font sizes at three different breakpoints:
h1 { text-transform: capitalize; @include breakpoint(xs) { font-size: 2.2em; } @include breakpoint(sm) { font-size: 2.7em; } @include breakpoint(xl) { font-size: 3em; } }

I saw this question on Reddit: I recently graduated with a degree in business management, but Iâm having a hard time finding a management job. Iâm not getting any interviews because I have no experience. What can I do? Here is my answer: https://discoverpraxis.com/10-steps-becoming-manager/Archived Link

Yesterday I threw down a challenge to the Praxis community: 12 Days of Christmas Blogging. Blog every day from the 13th until Christmas. Flex that shipping muscle in the face of holiday obligations and time constraints. Stay on that grind when it is easy to let it slip.
Iâm playing with fire here because I have to ship, too. Like all good challenges, the blade has to cut both ways in order for it to be any fun.
Here is yesterdayâs post: How can I come up with more ideas?Archived Link
This reminds me of my favorite Christmas story: Sir Gawain and the Green Knight.

The story opens with at King Arthurâs court where he and his men are exchanging gifts and getting ready to feast. A gigantic green figure atop a green horse rides into the court with an axe and a piece of holly. He challenges the court to âa Crystemas Gomanâ – someone can strike him with his axe and he will return the stroke in a year and a day. Sir Gawain rises to the challenge and promptly lops off the knightâs head with his own axe. Not missing a beat, the knight picks his head up off of the floor, reminds Sir Gawain that they have date at the Green Chapel in a year and a day, then rides off as abruptly as he arrived.
I wonât ruin the rest for you. Give it a read this Christmas! The story teems with vivid, meaningful descriptions, double meanings, alliteration, imagery, and symmetry. It is a wonderful read.
To mark the occasion of my own Crystemas Goman, here is a translation I did of my favorite passage. I used Casey Finchâs Complete Works of the Pearl Poet for the text and the Oxford English Dictionary for reference of word meanings.
'Nay, frayst I no fyÈt, in fayth I þe telle; 279 Hit arn aboute on þis bench bot berdlez chylder. If I were hasped in armes on a heÈe stede, Here is no mon me to mach, for myÈtez so wayke. Forþy I craue in þis court a Crystemas gomen, For hit is Èol and Nwe Èer, and here ar Èep mony: If any so hardy in þis hous holdez hymseluen, Be so bolde in his blod, brayn in hys hede, Ãat dar stifly strike a strok for an oþer, I schal gif hym of my gyft þys giserne ryche, Ãis ax, þat is heué innogh, to hondele as hym lykes, And I schal bide þe fyrst bur as bare as I sitte. 290
âNay, on my word, I seek no fight; 279 There are about these benches but beardless children. If I were fastened in armor on a noble steed, There is no man here to match me, for their strength is weak. And so I ask in this court for a Christmas game, For it is Yule and the New Year, and here are many agile fellows. If any in this hall holds himself hardy enough, Be so bold in his blood, mad in his mind, That dare swiftly strike one stroke for another, And I shall give him as my gift this well-wrought guisarme, This axe, that is plenty heavy, to handle as he likes, And I shall endure the first blow as bare as I sit. 290

The old saying, âYou are what you eatâ, applies to the creative process. If you want to be creative and come up with ideas, the best thing you can do is engage the creative ideas that are already out there. Not because you want to copy or emulate them, but because creative ideas catalyze other creative ideas. https://discoverpraxis.com/more-ideas/Archived Link

The past few days have been quite a ride in the crypto world! This rollercoaster is reminiscent of late 2013, except now there is much more skin in the game. My latest piece on Yours.org covers my history with BTC, BCH, and Ripple, and my investment and use strategies for the currencies. Read this piece over at https://www.yours.org/content/my-btc–bch–and-ripple-strategies-cb2b3d401e30.

I’m not sure that we have a bitcoin-caused environmental energy crisis on our hands. This piece on Yours.org points out some of the issues with the articles going arount about bitcoin and the environment. Read this piece over at https://www.yours.org/content/does-the-environmental-case-against-bitcoin-have-merit–656fd7d75c0f.

This afternoon I decided to try Yours.org, a site where you can write articles, decide what to charge for them, and get paid in bitcoin cash. I had an idea: If you pay and then a section is revealed to you, that doesn’t have to be just for articles. It can be used for anything digital!
A few ideas:
So, I decided to test it out. I packaged up four sets of national parks photos, put a thumbnail grid in the preview, and put a download link in the paid section:
I’m testing three different price points: $15, $10, and $5.
I also wrote a piece on how to use Yours.org for selling digital products. I priced it at $2.
In just a few hours I made over $40 in bitcoin cash! It is super exciting seeing the notifications come in while you are reading other articles. I think that the notifications are tied to transaction verifications because they come in waves. That must be when blocks get processed and transactions verified.


At Praxis we use Restrict Content Pro as the membership system for our curriculum portal. We decided that all grads get access for life, not just during the program. So, I needed a way to clear over 200 member expiration dates. The only bulk method available through the WordPress interface is to set the expiration dates to another date in the future, which would just kick my problem further down the road. So I needed to dust off my SQL knowledge and directly edit the database.
Don’t be a fool. Back up your database and test the queries on a local development version first. Never run queries for the first time on production. The backup is also a failsafe that you can restore if something goes wrong despite your testing.
I saw that all data related to Restrict Content Pro usually had rcp somewhere in the table, column, or key. So I started with the rcp tables. They had nothing to do with expiration dates, so I checked the wp_usermeta table since RCP extends the WordPress users with more functionality. Bingo. There was a column called meta_key with rcp_expiration in it with corresponding date values.
Sure, you could run your UPDATE statement first, but I like to make sure I am editing the correct data by running a SELECT statement first and then using the same WHERE clause for my UPDATE statement.
After a few stupid syntax errors, here is the SELECT statement that got exactly what I wanted. This shows the user ID so I can spot check, restricts searching to the rcp_expiration meta key, and looks for values that are not none.
SELECT user_id, meta_key, meta_value FROM wp_usermeta WHERE meta_key = 'rcp_expiration' AND meta_value != 'none';
This returned 176 results. When I changed it to show only meta values that were none, I got 31 values. 31+176=207, which is the total number of users. Looking good.
Now that we know we selected the correct data with our previous statement, it is time to craft our UPDATE statement.
Here I’m updating the wp_usermeta table and setting the meta_value to none where the meta_key is rcp_expiration and the corresponding meta_value is not none.
UPDATE wp_usermeta SET meta_value = 'none' WHERE meta_key = 'rcp_expiration' AND meta_value != 'none';
I tested this on my local machine and it updated 176 rows. Just like we wanted.
Now that we’ve tested the query in our development environment and verified that we got the results we wanted, we can run the query on the production database. If you use phpmyadmin and want to triple check that you aren’t messing anything up, you can click the “Simulate Query” button first. (I did.)
Log in to WordPress and check the RCP membership area. Verify that all expiration dates are now set to none. Also verify that your users can still log in. You should have a few user test logins specifically for this purpose. You can also check your site logs throughout the day to make sure people are still logging in. You can’t count on them always letting you know when something doesn’t work. More often than not they will just stop using it. It is up to you to verify everything works as it should!

Adding dates is tricky. Months have different numbers of days, so you can’t rely on just adding 30 days to get an extra month. You also can’t just add a certain number of months because formulas in Salesforce don’t auto increment the year. The solution is modular arithmetic and conditionals.
The goal here was to make a set of fields to send out emails on the first day of each month for 6 months, given a specific month to start with.
What I’m doing here is:
DATE( YEAR( date ) + FLOOR( ( MONTH ( date ) + number_of_months - 1 ) / 12 ), IF( MONTH ( date ) + number_of_months = 12, 12, MOD( MONTH ( date ) + number_of_months, 12 )), 01 )
How to use this: the date variable should be the date field you are starting with. You should replace number_of_months with the number of months you want to add to the original date. If the date is 07/01/2017 I want this to go out on 08/01/2017, I’d set number_of_months to 1. If 09/01/2017, I’d set it to 2, etc.
Note: This only works for the first of each month. If you need it to work on any day of the month, use this more complicated solution to account for months having different lengths.

As I mentioned a few days ago, I’m using Gulp on a new WordPress project. I like to back up my work every night, and since a lot of WordPress config and customization happens in the WordPress editor and widgets, that means backing up the mysql database as well as the code.
Why not use this newfound tool? Let’s do it.
I did some searching and found Gulp WordPress Backup, but it was overkill for what I wanted. But I saw that it used an npm package named mysqldump, for the export, so I grabbed that and started setting up a new task in gulpfile.js:
// add mysqldump as a dependency var mysqlDump = require('mysqldump'); // dumpDatabase gulp.task('dumpDatabase', () => { return new Promise((resolve, reject) => { mysqlDump({ host: 'localhost', user: 'user', password: 'pass', database: 'wp_database', dest: 'backup.sql' }, (err) => { if (err !== null) return reject(err); }); }) .catch((err) => { console.log(err); }); });
Next step: Defining the filename. I just wanted to use today’s date because I intend on running this at the end of each work day. Since gulp is all javascript, this is easy:
var today = new Date(), dd = today.getDate(), mm = today.getMonth()+1 //January is 0! yyyy = today.getFullYear(); if(dd<10) { dd = '0'+dd } if(mm<10) { mm = '0'+mm } today = mm + '-' + dd + '-' + yyyy;
Add this to the gulp task and you are good to go!
gulp.task('dumpDatabase', () => { var today = new Date(), dd = today.getDate(), mm = today.getMonth()+1 //January is 0! yyyy = today.getFullYear(); if(dd<10) { dd = '0'+dd } if(mm<10) { mm = '0'+mm } today = mm + '-' + dd + '-' + yyyy; return new Promise((resolve, reject) => { mysqlDump({ host: 'localhost', user: 'user', password: 'pass', database: 'wp_database', dest: 'SQLBackups/' + today + '.sql' // Outputs to the folder named SQLBackups and uses today's date as the filename. }, (err) => { if (err !== null) return reject(err); }); }) .catch((err) => { console.log(err); }); });
Make sure you add mysqldump to your project’s package.json, or at least run npm install mysqldump before using!

When I updated to macOS High Sierra, a bunch of necessary stuff broke: Jekyll, Homebrew, Node.js, and a bunch of gems. s3_website, the tool I use to deploy my Jekyll site to S3, was one of the gems that just completely disappeared. When I went to reinstall it, I got an error that I didn’t have Java installed. Against my better judgment, I went to the URL listed and installed it. Then I ran s3_website push.
After about 30 seconds, I got an error saying that s3_website doesn’t work with Java 9, which was the most recent version at the link. And also the version you get with brew cask install java. Well, shit.
Exception in thread "main" java.lang.ExceptionInInitializerError at org.jruby.Ruby.newInstance(Ruby.java:266) at s3.website.Ruby$.rubyRuntime$lzycompute(Ruby.scala:4) at s3.website.Ruby$.rubyRuntime(Ruby.scala:4) at s3.website.model.Config$$anonfun$15.apply(Config.scala:229) at s3.website.model.Config$$anonfun$15.apply(Config.scala:227) at scala.util.Try$.apply(Try.scala:192) at s3.website.model.Config$.erbEval(Config.scala:227) at s3.website.model.Site$$anonfun$2.apply(Site.scala:28) at s3.website.model.Site$$anonfun$2.apply(Site.scala:27) at scala.util.Success.flatMap(Try.scala:231) at s3.website.model.Site$.parseConfig(Site.scala:27) at s3.website.model.Site$.loadSite(Site.scala:100) at s3.website.Push$.push(Push.scala:62) at s3.website.Push$.main(Push.scala:40) at s3.website.Push.main(Push.scala) Caused by: java.lang.RuntimeException: unsupported Java version: 9 at org.jruby.RubyInstanceConfig.initGlobalJavaVersion(RubyInstanceConfig.java:1878) at org.jruby.RubyInstanceConfig.(RubyInstanceConfig.java:1585) ... 15 more
After lots of searching, I came across a kind soul on Github suggesting that we use jEnv to define which java environment to use in the directory.
When I first installed jenv, I couldn’t add versions to the tool. I kept getting this error:
ln: /usr/local/opt/jenv/versions/oracle64-9.0.1: No such file or directory
The fix is described here: https://github.com/gcuisinier/jenv/wiki/Trouble-Shooting. Once I added version 8 as well, I switched to version 8 locally with this:
jenv local oracle64-1.8.0.151
Then I opened a fresh Terminal window and ran s3_website again and everything pushed up to s3 without an issue.

The line-height attribute doesn’t work on span by default. If you need to use line-height on a span, you’ll need to set display:block; on the span element to make it display as a block element (like
).

While working on the 51 Line Charts for my Opioid Crisis data visualization, I ran into an issue with generating all 51 charts at the same time: The data was either in 51 rows stacked and I couldn’t access the dates effectively, or 306 rows unstacked and I had 6x as many objects as I needed when I did a join.
The solution was to use D3.nest. Nesting allows elements in an array to be grouped into a hierarchical tree structure; think of it like the GROUP BY operator in SQL, except you can have multiple levels of grouping, and the resulting output is a tree rather than a flat table. The levels in the tree are specified by key functions.
When I used the state as a key, it grouped each state’s data together in a tree.
Input:
state,code,year,deaths,adjrate Alabama,1,2010,547,11.8 Alabama,1,2011,552,11.8 Alabama,1,2012,562,12.1 Alabama,1,2013,598,12.7 Alabama,1,2014,723,15.2 Alabama,1,2015,736,15.7 Alaska,2,2010,83,11.6 Alaska,2,2011,107,14.2 Alaska,2,2012,129,17.4 Alaska,2,2013,105,14.4 Alaska,2,2014,124,16.8 Alaska,2,2015,122,16 Arizona,4,2010,1098,17.5 Arizona,4,2011,1071,16.9 Arizona,4,2012,1134,17.7 Arizona,4,2013,1222,18.7 Arizona,4,2014,1211,18.2 Arizona,4,2015,1274,19 Arkansas,5,2010,350,12.5 Arkansas,5,2011,355,12.6 Arkansas,5,2012,373,13.1 Arkansas,5,2013,319,11.1 Arkansas,5,2014,356,12.6 Arkansas,5,2015,392,13.8
D3 code:
d3.nest() .key(function(d) { return d.state; }) .entries(data);
Output:
[ { "key": "Alabama", "values": [ { "state": "Alabama", "code": "1", "year": "2010", "deaths": "547", "adjrate": "11.8" }, { "state": "Alabama", "code": "1", "year": "2011", "deaths": "552", "adjrate": "11.8" }, { "state": "Alabama", "code": "1", "year": "2012", "deaths": "562", "adjrate": "12.1" }, { "state": "Alabama", "code": "1", "year": "2013", "deaths": "598", "adjrate": "12.7" }, { "state": "Alabama", "code": "1", "year": "2014", "deaths": "723", "adjrate": "15.2" }, { "state": "Alabama", "code": "1", "year": "2015", "deaths": "736", "adjrate": "15.7" } ] }, { "key": "Alaska", "values": [ { "state": "Alaska", "code": "2", "year": "2010", "deaths": "83", "adjrate": "11.6" }, { "state": "Alaska", "code": "2", "year": "2011", "deaths": "107", "adjrate": "14.2" }, { "state": "Alaska", "code": "2", "year": "2012", "deaths": "129", "adjrate": "17.4" }, { "state": "Alaska", "code": "2", "year": "2013", "deaths": "105", "adjrate": "14.4" }, { "state": "Alaska", "code": "2", "year": "2014", "deaths": "124", "adjrate": "16.8" }, { "state": "Alaska", "code": "2", "year": "2015", "deaths": "122", "adjrate": "16" } ] }, { "key": "Arizona", "values": [ { "state": "Arizona", "code": "4", "year": "2010", "deaths": "1098", "adjrate": "17.5" }, { "state": "Arizona", "code": "4", "year": "2011", "deaths": "1071", "adjrate": "16.9" }, { "state": "Arizona", "code": "4", "year": "2012", "deaths": "1134", "adjrate": "17.7" }, { "state": "Arizona", "code": "4", "year": "2013", "deaths": "1222", "adjrate": "18.7" }, { "state": "Arizona", "code": "4", "year": "2014", "deaths": "1211", "adjrate": "18.2" }, { "state": "Arizona", "code": "4", "year": "2015", "deaths": "1274", "adjrate": "19" } ] } ]
A few useful tools and resources for understanding d3.nest:

I’ve used Coda by Panic as my IDE of choice for 10 years now, but I think it is starting to fall behind other tools. It isn’t updated often and there aren’t nearly as many community-built packages as other tools have. So I’m giving both Atom and Sublime a try. I’m trying Atom first.
In my first few days of use, here are some things I love:

I’m working on a new WordPress theme development project and using Gulp and Sketch for the first time. Here are my first use notes:
gulpfile.js
Here are the tasks I’m using:
gulp styles — Compile, autoprefix and minify Sass files.gulp scripts — Minify javascript files.gulp images — Compress and optimize images.gulp watch — Compile assets when file changes are made, start BrowserSyncgulp — Default task – runs all of the above tasks.gulp zip — Package theme into zip file for distribution, ignoring node_modules.TLDR pages – Simplified man pages with practical examples. Probably covers 80% of your daily use cases. Looks super cool.
Great email from Paul Jarvis’s Sunday Dispatches this week. The relationship doesn’t end once you make the sale. That is just the beginning. Don’t be the hot tub guy.
I got this error today when trying to partition a Western Digital My Passport 4TB:
Volume erase failed: Media kit reports not enough space on device
Nothing I could do inside Disk Utility worked. Thanks to some kind soul on Reddit, here is how I solved the issue from the command line:
$ diskutil list
$ diskutil unmountDisk force disk2 #replace disk2 with your disk number
and then write zeros to the boot sector:
$ sudo dd if=/dev/zero of=/dev/disk2 bs=1024 count=1024
Attempt to partition it again:
$ diskutil partitionDisk disk2 GPT JHFS+ "My External HD" 0g
Sometimes I get off track. This is what I need to do to get back on track:
Venkatesh Rao had a good take on the big data/machine learning/blockchain mania in Breaking Smart a few weeks ago:
Many people, database experts among them, dismiss Big Data as a fad that’s already come and gone, and argue that it was a meaningless term, and that relational databases can do everything NoSQL databases can. That’s not the point! The point of Big Data, pointed out by George Dyson, is that computing undergoes a fundamental phase shift when it crosses the Big Data threshold: when it is cheaper to store data than to decide what to do with it. The point of Big Data technologies is not to perversely use less powerful database paradigms, but to defer decision-making about data — how to model, structure, process, and analyze it — to when (and if) you need to, using the simplest storage technology that will do the job.A organization that chooses to store all its raw data, developing an eidetic corporate historical memory so to speak, creates informational potential and invests in its own future wisdom.
Next, there is machine learning. Here the connection is obvious. The more you have access to massive amounts of stored data, the more you can apply deep learning techniques to it (they really only work at sufficiently massive data scales) to extract more of the possible value represented by the information. I’m not quite sure what a literal Maxwell’s Historian might do with its history of stored molecule velocities, but I can think of plenty of ways to use more practical historical data.
And finally, there are blockchains. Again, database curmudgeons (what is it about these guys??) complain that distributed databases can do everything blockchains can, more cheaply, and that blockchains are just really awful, low-capacity, expensive distributed databases (pro-tip, anytime a curmudgeon makes an “X is just Y” statement, you should assume by default that the(X-Y) differences they are ignoring are the whole point of X). As with Big Data, they are missing the point. The essential feature of blockchains is not that they can poorly and expensively mimic the capabilities of distributed databases, but do so in a near-trustless decentralized way, with strong irreversibility and immutability properties.
Sometimes you have to stop what you are doing and climb out on the roof to take a #ManhattanSkyline photo because the sunset is so beautiful. #nofilter

Studio Neat put together a cool video showing how the Panobook is made. I preordered three Panobooks and can’t wait for them to arrive.
Studio Neat makes some of my favorite products: Neat Ice KitArchived Link, Highball, and the Glif. I love the way they document their work through videos like this, their weekly newsletter, and their podcast, Thoroughly Considered.
A lot of email services track you by putting a tiny transparent image in your email and logging when you load it. You can prevent this by turning off autoloading of remote images in your favorite email app’s settings. If your app doesn’t have that setting, consider switching. I’m currently using Airmail across all of my devices and the setting is under Settings > Advanced.
One evening last week I had the idea to draw some quick sketches to illustrate some concepts in the Praxis curriculum. I used my iPad, Apple Pencil, Procreate, Paper by 53Archived Link, and Pixelmator.




