Archives

Blog index

Blog

  • Relearning D3.js


    I was listening to Data Stories Episode 22: NYT Graphics and D3 with Mike Bostock and Shan Carter today and I realized that while I’ve used D3.js for bar charts and mapping projections, I don’t really understand it. I never took the time to learn the fundamentals, so I’ve always been constrained to cobbling together things from other examples.

    That needs to change.

    Here is a list of resources I plan to go through. I should be able to relearn the basics fairly quickly so that I can spend time making charts of my own. I’ll update completed items with check marks as I go through them.

  • Error Document Handling with .htaccess


    Today I saw that I was getting a bunch of requests for http://cagrimmett.com/blog, which was the landing page for my 2008-2014 blog that I took down last year. That page does not exist now and “blog” is now just a directory on my site generated by Jekyll’s paginator.

    I wanted to take those requests and forward them to the landing page of my new blog. The /blog/ requests were all 403 errors, and any direct link to an old post is a 404 error. So I added these two lines to my main .htaccess file to handle the request:

    ErrorDocument 403 / ErrorDocument 404 /404.html

    This means:

    • “Take any 403 error and show the user the site’s front page (/)”
    • “Take any 404 error and show the user the 404 page
  • Loading scripts in WordPress with wp_enqueue_scripts


    Sometimes you need to put scripts on a specific page in WordPress. Frameworks like Genesis have boxes where you can add header or footer scripts. Most don’t, though. Here is how to load scripts on specific pages in WordPress with the wp_enqueue_scripts hook.

    In functions.php in your theme folder, you’ll need to add an action for the wp_enqueue_scripts hook. This will be a function pointing to the script.

    I’m using get_stylesheet_directory_uri() to link to the script. This means if your theme’s main style.css is in “example.com/wp_content/themes/twentysixteen/style.css”, your script should be in “example.com/wp_content/themes/twentysixteen/js/script.js”.

    Pick one the the scenerios below and add the code to your functions.php file in your theme. Make a backup of it first in case you mess something up.

    This will work for the whole site:

     function hello_script() { wp_register_script( 'hello-script', get_stylesheet_directory_uri() . '/js/hello-script.js' ); wp_enqueue_script( 'hello-script' ); } add_action( 'wp_enqueue_scripts', 'welcome_page_script' ); 

    This will work for just a specific page. Switch “052” with your page ID. Here is how you find the page ID.

     function about_page_script() { if ( is_page('052') ) { wp_register_script( 'about-script', get_stylesheet_directory_uri() . '/js/about-script.js' ); wp_enqueue_script( 'about-script' ); } } add_action( 'wp_enqueue_scripts', 'about_page_script' ); 

    If you have one of those fancy themes that generates a front page that you edit in the Customizer but it doesn’t have a page ID, but you only want it to display on the front page, don’t fret. WordPress has a is_front_page function:

     function front_page_script() { if ( is_front_page() ) { wp_register_script( 'front-page-script', get_stylesheet_directory_uri() . '/js/front-page-script.js' ); wp_enqueue_script( 'front-page-script' ); } } add_action( 'wp_enqueue_scripts', 'front_page_script' ); 
  • jQuery replaceWith


    Let’s say you have a bunch of elements that under certain situations you want to replace with another element. jQuery’s replaceWith() function is perfect for that.

    Here is an example of replacing all links with the class replace with a different link. The use case was finding certain buttons that say “Apply Now” and replacing them with buttons that say “Finish your application”. Since searching for “Apply Now” wasn’t perfect (the text and other links said it, too) I manually put in the replace class so I knew exactly which elements I’d be selecting.

    $( "a.replace" ).replaceWith( '"/application/" class="button arrow-right">Finish your applicationArchived Link' );

    Want to perform this action if a cookie exists? Try using js-cookie:

    $( document ).ready(function() {    if (Cookies.get('cookiename')) {    	$( "a.replace" ).replaceWith( '"/application/" class="button arrow-right">Finish your applicationArchived Link' );    }    else { 	   // do nothing    } });
  • How to Implement Search on a Jekyll Site


    The basic way searching works is that you create an index of all content on a site you want to search, then the search query is checked against that index. On something like a WordPress site, this query is checked against the database, which is a defacto index. Google does its own indexing of your site, so the Google queries are checked against Google’s index (likely also stored in a database).

    Since Jekyll sites are static (meaning that they are only files, no databases included) there is no database to search. That leaves us with two options:

    1. Set up a Google Custom Search Engine. Google will index the site for you and display the results.
    2. Create an index on your own and make sure your search queries check against that index.

    I love Google CSE, but I decided to go with the second route this time. I used Mat Hayward’s Jekyll Search scripts to do the heavy lifting, but I edited them to suit my needs. It is lightning fast!

    These scripts:

    • Generate a JSON file of my site contents when the site is built
    • Compare the search query to the contents of the JSON file
    • Return the results based on a template

    Jekyll Search, image from Mat Hayward

    I modified the way the dates are formatted, how the excerpt gets put into the JSON file, the output styles, and put in a conditional for external link posts.

    See it in action on my search page →Archived Link

  • How to Back Up Your Online Life

    Your stuff in the cloud could disappear at any time. Here is how to download a copy of your data from popular online services.

    Do you use Gmail? WordPress.com? Fitbit? Facebook? How about Twitter? Your account could be shut down and you could lose all of your stuff there at any time.

    This Dennis Cooper situation is a good reminder that you need to be prepared to lose anything and everything stored by online services at any time. Mr. Cooper’s art may not be my cup of tea, but I feel for him. Losing 14 years of work is devastating.

    If you use free services, you have no reasonable expectation of guaranteed access to that service. Read the Terms of Service closely. Unless you are paying for them, the services don’t owe you a thing. The best approach to controlling your data is to back it up regularly.

    Even if you do pay for the service (like Outlook 365 or Dropbox Pro) your safest option is to have a local backup of your data. Again, back it up regularly.

    Relevant XKCD post about online services. https://xkcd.com/1150/

    Below are links to export options for popular online services.

    After you export this data, back it up. Leave a copy on your computer, then buy an external drive (affiliate link // non-affiliate link) and move a copy to it. I’m a big fan of the 3–2–1 backup strategy and this passes it. Three total copies of your data, two are saved locally (your computer and external drive), and one is in the cloud (on the service).

    These services are in alphabetical order. If there is something I didn’t include that I should, leave a comment with a link and I’ll add it to the list! (Last updated July 19, 2016, with suggestions from James WalpoleArchived Link)

    Going Forward

    I suggest you back up your online presence at least once a month. More often if it is business-critical like Slack, Trello, Toggl, Wunderlist, etc. Losing your work means losing money.

    You can also do automated incremental backups of your social media accounts. I set up IFTTT recipes to automatically back up posts to my Day One journal and Google Drive. You can see the recipes I use here.

    https://ifttt.com/p/cagrimmett/favorites

    Back Up Your Devices

    If you don’t do this already, take this as a reminder to back up your computers, phones, and tablets. I make full clones of my hardrives weekly and back up hourly changes with Backblaze (affiliate link // non-affiliate link).

    If you don’t know how to back up your devices, here are instructions on wikiHow:

    https://ifttt.com/p/cagrimmett/favorites


    What did I miss?

    I’m sure there are popular services I missed. If you leave a comment with a link to instructions or export tools for a popular service, I’ll add it to the list!

  • How to Back Up Your Online Life


  • Moving Files to a Mac from Microsoft Remote Desktop


    When moving files between Windows machines via Remote Desktop, you typically go to Local Resources > More and check the box in front of Drives to map your drive on the remote machine. Then you can use xcopy and \\tsclient to move the files.

    This isn’t quite the same on the Microsoft Remote Desktop Mac app. I believe this is because Mac OS X can’t accept SMB connections by default, so you have to map a special folder on your machine to accept transfers.

    When you add or edit a Remote Desktop connection, click “Redirection” on the top of the window.

    Redirection

    Then check “Enable folder redirection” and map a folder on your machine to be mapped to \\tsclient. I like to map a Dropbox folder so I the items are automatically backed up for me.

    Map a folder

    The folder you map will be available at \\tsclient. You can either use xcopy from the command line or find it under the Network drives area in the file browser.

  • Setting and retrieving cookies from form data


    Let’s say you have two forms: One is a basic contact info form and the other is more in-depth. You have them separated because you want to capture contact information as soon as possible to follow up on leads, but you want some information to be carried over to the second form. You also want the user to be greeted with a message to finish the form when they come back to the site (if they leave).

    Here is a sketch of what you’d need to do:

    1. When the first form is filled out and submitted, set a cookie. You could either use vanilla Javascript or a plugin like js-cookie.
    2. The cookies should contain the value of the form fields that were entered. Use something like form.fieldname.value in JavaScript or $("input").val() in jQuery to retrieve them.
    3. Set the cookies for a reasonable amount of time. 2 weeks?
    4. On the landing page, check for cookies. If they are there, change the call to action from “Apply Now” to “Finish your application!”
    5. On the second form page, write a function to check to see if there is are cookies set. If there is, read the cookies and insert their values into the form.
    6. When the form on the second page is submitted, use a function to remove the cookies. They are no longer necessary.

    The implementation is left as an exercise for the reader. This outline should get you well on your way!

  • Powering a Blog Through Medium


    Medium is a wonderful network and editorial platform that allows anyone to share their stories and their ideas. It allows those who don’t want to run a full blog to publish their content easily. If you do want to start a full blog without the overhead of buying hosting or running a WordPress site, it is super easy to power your blog with a custom domainArchived Link through Medium. This means you can buy your own site name (i.e. http://amandagrimmett.com) and the Medium publication will show up there. Here is what you need to do:

    1. Sign up for a Medium account.
    2. Set up a new publicationArchived Link on Medium. Think of this as your blog.
    3. Fill out this form with your publication’s URL and what custom domain you want to point to it.
    4. Medium will respond within 12 hours with a list of A records and a CNAME record that you’ll need to add to your registrar. Here is a cheatsheet for you and Medium’s support pageArchived Link. This is a bit of a pain, but thankfully a good registrar like Hover can do this for you. Hover’s new Connect service presets the 12 A records for you and steps you through setting a CNAME record.
    5. Within a few hours your domain will point to your Medium publication and your blog will be live!

    I just set one up this weekend for my wife’s awesome new blog. I couldn’t believe how simple it was. My only frustration was the wait time between submitting the request and getting a response from Medium. It was a weekend though, so I can’t complain.

    Once it is set up, you log in through Medium and publish to it through the Medium platform. It has the benefit of being tied in to the entire Medium ecosystem, so sharing, commenting, and gaining followers is easy. You are constrained to the limits of their platform, but it does have some customization optionsArchived Link. This is perfect for those of you focusing on your writing.

    Go forth and write!

    Medium gif

  • iOS 10.0 Public Beta Thoughts


    The iOS 10.0 Public Beta came out Thursday, July 7, 2016. I installed it within a few hours of its release and began using it on my main phone. Here are my thoughts so far.

    TL;DR: iOS 10 is going to be a definite improvement, but the beta is buggy. Don’t install it if there are features on your phone that you can’t live without, or if you don’t have patience for glitches. If you do decide to install it, make a full backup via iTunes first. It might save your bacon.

    Installation

    Stop what you are doing and back up your phone if you are considering installing the beta. No, seriously. Do it. There is a serious chance it might not work for you.

    I had a scare and a headache installing it on my iPhone 6s Plus. The first install failed halfway through and my phone would not turn on. It took 4 force restarts before I saw the “Connect to iTunes” screen and I could restore from a backup.

    My second install attempt worked, but you’ve been warned.

    Thoughts on New Features

    Widgets

    • The lock screen widgets are a HUGE improvement. You can force touch on messages, voicemails, and reminders to interact with them if you’ve unlocked via Touch ID. Since my phone is plugged in on my desk most of the day, I love this. I can’t wait to see how third party apps take advantage of this.
    • The widgets make Force Touch (available on the 6s and 6s Plus) less of a novelty and more of a real, useful feature now.
    • Some third-party apps like 2do already have widgets working!

    Messages Apps

    • I’m really “meh” on the Messages apps right now. None of the people I regularly message have installed iOS 10, so most of the features are pretty useless to me right now.
    • If you don’t have iOS 10 and someone who does uses “Tapback”, Messages sends them a message that says something like, Emphasized “message” or Liked “Message”. It looks weird. As my wife responded when I tried a tapback on her,

    “Yeah, you sound dumb if I don’t have iOS 10”

    • There isn’t much in the store right now, either. It will likely improve once more developers get their apps out.
    • That said, the gif picker is pretty nice. I enjoy replying to messages with gifs, so I’ve already used it a ton. People running iOS 9 can see them without an issue.
    • The link preview is pretty great, too. It will make searching through messages for that link some sent last week a lot easier. See below under “Contextual Predictions” for a screenshot.

    George

    Siri

    • None of the cool new Siri features that I remembered from the Keynote worked yet.
    • Siri’s speech recognition hasn’t seemed to improve.
    • Even though I had Uber and Lyft installed, Siri said she couldn’t get me an Uber or Lyft to the nearest airport because no supported apps were installed. Similarly, there are apparently no rider apps available through Maps.

    Contextual Predictions

    • If you type something like, “Amanda’s number is”, anyone named Amanda with a phone number pops up as an option.
    • This is really slick and I’ve been using it. As the engine learns more, it will get even better.
    • I couldn’t get Apple’s “I’m available at” example to work, but maybe it hasn’t had time to index my calendar yet.

    Photos

    • The face recognition is awesome. After a few hours, I saw all of the faces in my photos and just had to assign them to contacts. It didn’t make any mistakes yet that I’ve been able to find.
    • The search is pretty cool. I did a classic search for “mountain” and it returned a bunch of photos with mountains. Then I searched for “fish” and it returned photos from when Amanda and I went fly fishing and were holding our catches. It isn’t perfect, but it will learn more over time.

    Bugs

    This public beta seems to have fewer bugs and glitches than the iOS 9.1 public beta had, but there are still some issues I found within just one day of use:

    • Some apps playing audio intermittently pause.
    • I regularly get phantom notifications. My phone vibrates and the screen wakes up, but nothing is there. No messages, no alerts, no widgets. Just a blank lock screen.
    • When I try to tap apps inside a stack, more often than not a regular tap is translated as a long tap, so all of the app icons wiggle in fear for their lives.
    • About 3 times a day the screen gets stuck in landscape orientation and the only thing that will bring it back is locking and unlocking the phone.
    • The app store sucks on 9.3 as well, but I seemed to get more blank app store screens than ever. I had to try searches multiple times. Even then, after I got one search to work, subsequent searches wouldn’t update the results. See Overcast/Write screenshot below.
    • Multiple apps can’t access the internet connection for some reason. TextExpander and Overcast are the two that I noticed right away.
    • I sent my wife a photo, but what showed up in my Messages stream was a different photo. Turns out that she saw the correct one, but the wrong preview was shown to me.


  • How to Pre-fill Google Forms


    Did you know that you can pre-fill Google Forms based on a URL? Did you also know that if you have a basic example you can automate it with a database and send personalized forms?

    General Instructions

    1. On your form, click the vertical ellipses in the upper right corner to reveal the menu.
    2. Click “Get pre-filled link” Get pre-filled link
    3. This shoots you over to a page where you can fill in the fields you want pre-filled and it will generate a URL for you. Copy this. If you want the link you send out to everyone to have the same pre-filled info, your work is done. Send the link out!

    How you might automate it

    Here is my example form.Once I went through the above steps to get a pre-filled link, here is what I got:

    https://docs.google.com/forms/d/1nuxTbnUGkTaZw1uGIXXgqfx3hYRi3ZaPahdwDNEgy3Q/viewform?entry.2005620554=Chuck&entry.1045781291=cagrimmett@gmail.com&entry.1065046570=308+Negra+Arroyo+Lane,+Albuquerque,+NM+87114&entry.1166974658=281-330-8004&entry.839337160=This+is+so+useful!

    The stuff we are looking for is between the “=” and “&” signs:

    https://docs.google.com/forms/d/1nuxTbnUGkTaZw1uGIXXgqfx3hYRi3ZaPahdwDNEgy3Q/viewform?entry.2005620554=Chuck&entry.1045781291=cagrimmett@gmail.com&entry.1065046570=308+Negra+Arroyo+Lane,+Albuquerque,+NM+87114&entry.1166974658=281-330-8004&entry.839337160=This+is+so+useful!

    As you can see, those are the items I filled in on my own. How might one automate this, then? Here are a few suggestions:

    1. Using handlebars or Liquid, fill them in with the appropriate expressions and use the appropriate objects to fill them in: https://docs.google.com/forms/d/1nuxTbnUGkTaZw1uGIXXgqfx3hYRi3ZaPahdwDNEgy3Q/viewform?entry.2005620554={{name}}&entry.1045781291={{email}}&entry.1065046570={{address}}&entry.1166974658={{phone}}&entry.839337160={{comments}}
    2. Using PHP, you might assign variables for these items and fill them in from your database with a select statement: https://docs.google.com/forms/d/1nuxTbnUGkTaZw1uGIXXgqfx3hYRi3ZaPahdwDNEgy3Q/viewform?entry.2005620554=$name&entry.1045781291=$email&entry.1065046570=$address&entry.1166974658=$phone&entry.839337160=$comments
    3. On Mailchimp, you’d have to use Merge Tags: https://docs.google.com/forms/d/1nuxTbnUGkTaZw1uGIXXgqfx3hYRi3ZaPahdwDNEgy3Q/viewform?entry.2005620554=*|name|*&entry.1045781291=*|email|*&entry.1065046570=*|address|*&entry.1166974658=*|phone|*&entry.839337160=*|comments|*

    Note: Make sure you are URL encoding things with weird characters and spaces like an address. Example: 308+Negra+Arroyo+Lane,+Albuquerque,+NM+87114 vs 308 Negra Arroyo Lane, Albuquerque, NM 87114

    Completion of the code in 1, 2, and 3 is an instruction left to the reader. I’m assuming that if you want to do something like generate thousands of personalized URLs to a form, you probably already have a database and know how to use it. I hope this guides you in the right direction! Email meArchived Link if you want some help.

  • jQuery’s Greater and Less Than Selectors


    Today I learned about jQuery’s greater than selector, :gt().

    The :gt() selector selects elements with an index number higher than a specified number. The index numbers start at 0.

    I’m using this selector to hide more than 10 recent posts on my TIL page. Each of these posts is inside a list item (li) and a child of the unordered list (ul) with a class called “recent”. I then added a toggle function on a button to show them again by using the same selector.

    Example:

    $(document).ready(function(){   $("ul.recent").find("li:gt(9)").hide();   $("ul.recent").has("li:nth-child(10)").after(""showhide button" >Show/Hide all TIL posts");   $("a.showhide").click(function() {     $("ul.recent").find("li:gt(9)").toggle("slow");     $   }); }); 

    There is also a less than selector in jQuery. It works similarly, except that it selects elements with an index number lower than the specified number. Syntax: :lt()

    Note: Since I’m using a Jekyll site and generating that TIL list via Liquid, another solution is to set a counter after which it automatically adds a class directly to the HTML to hide those items that we can then toggle later. I think the jQuery solution is cleaner, though.

  • Take Notes During Your Next Crisis


    The best time to learn how to handle crises is right after you just had one. Analyze what happened, what you did to solve it, and then make a checklist for when it happens next time.

    Then, during your next crisis, take a deep breath and start jotting down notes of what is happening and what you are doing. This makes your post-game analysis easier to complete.

    We had a mini crisis at work today: Some of our sites weren’t connecting to our MySQL servers and we couldn’t figure out why. The problem was intermittent. Our sysadmin is on vacation, so a few of us had to jump in and try to figure it out. When we were in a holding pattern while waiting for our hosting provider to call us back, I made a checklist of what we need to do the next time this happens. This took into account what we had to figure out on the spot, look up, diagnose, and what we learned. Now we have it for the future.

    H/T to Episode 279 of Back to Work with Merlin Mann and Dan Benjamin. I listened to it this morning and their discussion of making checklists while traveling for travel made me think of doing this during the MySQL issues.

  • Scheduling Jobs with Cron


    Cron is a time-based job scheduler in Linux and Unix.

    Basic usage

    Read the manual:

    $ man crontab

    Load your personal crontab (cron table) file:

    $ crontab -e

    View your personal crontab:

    $ crontab -l

    Syntax:

    min hour day of month month day of week command
    * * * * * command
    0 – 59 0 – 23 1 – 31 1 – 12 0 – 6 (0 to 6 are Sunday to Saturday) shell command you want to run at that time

    Intervals:

    • */N is the syntax for an interval
    • You can use commas if the interval is irregular

    Time Syntax Examples

    Example Explanation
    0 9 * * 1-5 Run Monday through Friday at 9am server time
    0 15 * * * Run every day at 3pm server time
    30 */2 * * * Run every 2 hours, on the half hour
    0 0 1 1 * Run once a year at midnight on January 1
    0 3,7,12,18 * * * Run daily at 3am, 7am, noon, and 6pm

    Full example

    Download a JSON file from Quandl and overwrite GOLD.json with it Monday through Friday at 5pm server time:

    0 17 * * 1-5 wget -O "/path/to/quandl_data/GOLD.json" "https://www.quandl.com/api/v3/datasets/LBMA/GOLD.json"

    Things to look out for

    • Surround anything with possible odd characters or spaces with quotes: URLs, local file paths, etc. This will keep you from getting errors.
    • Use a full file path from root instead of ~/ – Tildes aren’t interpreted the same way as on the command line
    • Times are always in server time. If you don’t know what time it is on the server, run: $ date

    Thanks goes out to Eric Davis for helping me out with this!

  • Posts Heatmap Calendar for Jekyll

    Hey, so this post is broken. I moved platforms and some of my old tutorials don’t play nicely with WordPress. I’m working on fixing them, but in the meantime you can view the old version here: https://cagrimmett-jekyll.s3.amazonaws.com/2016/07/04/posts-heatmap-calendar.html

    This posts heatmap calendar gives a visual representation of when you posted on your Jekyll site. It loops through all of your posts, counts how many posts you have each day, creates a JSON string to hold them, then uses moment.js, D3.js and Cal-HeatMap to visualize them.

    It automatically loads the current month on the right and it has responsive breakpoints at 1400px, 730px, and 420px. It will work on Github Pages because it doesn’t need any additional plugins to run. It only uses Liquid to do the counting and build the JSON string.

    For more info and to use it, visit https://github.com/cagrimmett/jekyll-tools

  • DNS Terms Cheatsheet


    There are a lot more domain record terms than this, but these are the ones I most frequently encounter. I’ll add more as I run into them.

    Records

    Record Description Use
    A Address Record Point a domain to a specific IP address
    CNAME Canonical Name Record This is an alias of one name to another. Example: A CNAME of www.cagrimmett.com to cagrimmett.com tells the server to look for the WWW version wherever the non-WWW version’s A record resides. CNAME records must always point to another domain name, never directly to an IP address.
    MX Mail Exchange Record Direct’s a domain’s email to the server hosting the accounts. I most frequently use this for setting up Google Apps.
    NS Name Server Record Determines which servers will communicate DNS info for a domain. You usually have a primary and secondary. This site uses Cloudflare’s name servers.
    DNSKEY DNS Key Record The key record used in DNSSEC.

    Terms

    Term Full Name Description
    DNS Domain Name System Basically a phone book for the web. When you try to go to a domain (e.g. google.com) in your browser, the domain name system tells your browser where to find that domain, usually an IP address.
    TTL Time To Live How long it will take any change you make now to go into effect
    @ Self-referential character You don’t use the actual domain name in your DNS settings. Instead, you use the @ symbol to indicate the domain name.
    DNSSEC Domain Name System Security Extensions A set of protocols that add a layer of security to the DNS lookup and exchange processes.
  • Automating Blog Posts with AppleScript v2


    I decided that my earlier attempt at automating creation of these TIL posts was still too manual. This one is better!

    What it does:

    1. Creates a markdown file with today’s date and my specified string at the title.
    2. Launches Coda in the foreground and goes to my preset Jekyll blog site (cagrimmett.com)
    3. Opens the file it just created in the front window.
    4. Expands the previous TextExpander snippet I created as a template for these TIL posts.

    The Script

    %filltop%  on textexpander(abbreviation)	 do shell script "cd ~/Projects/cagrimmett-com/_posts/til; touch %snippet:fname%"  tell application "Coda 2" 	activate window 	get site 6 of application "Coda 2" 	tell window 1 		connect to site 6 of application "Coda 2" 			open "Macintosh HD:Users:CAG:Projects:cagrimmett-com:_posts:til:%snippet:fname%" 	end tell end tell tell application "TextExpander" 	expand abbreviation ";tem" end tell  end textexpander

    Here are what the other two snippets fill in:

    fname– I had to make this a snippet instead of putting it in directly because in the filename creation string TextExpander didn’t recognize the date string. If you nest it inside another snippet, it works just fine.

    %Y-%m-%d-%filltext:name=title%.md 

    ;tem

    --- layout: post title:  author: Chuck Grimmett date: %Y-%m-%d category: TIL feature-img: "/img/defaults/%snippet:;random-img%" tags:  -  excerpt: 

    --- ### Today I learned:
  • Many-to-Many Relationships in Relational Data Models


    Today I learned about Many-to-Many relationships in relational data models

    • A many-to-many relationship is a type of cardinality that refers to the relationship between two entities A and B in which A may contain a parent instance for which there are many children in B and vice versa.
    • For example, a recipe may have many ingredients and a specific ingredient may be used in many recipes.
    • In SQL, this relationship is handled by an associative table. The primary key for this type of table is composed of two different columns, both of which reference columns in other tables that you are associating together.
    • It is a good convention to name these associative tables by how they reference each other: Table1_Table2
    • A SELECT statement on an associative table usually involves JOINing the main table with the associative table.
    • If you don’t want to run these JOINs every time, create a view first. A view is a virtual table based on the result-set of an SQL statement. You can add SQL functions, WHERE, and JOIN statements to a view and present the data as if the data were coming from one single table.

    Example SQL for creating an associative table:

    CREATE TABLE recipes_ingredients (     RecipeID INT(11) REFERENCES Recipes (RecipeID),     IngredientID INT(11) REFERENCES Ingredients (IngredientID),     PRIMARY KEY (RecipeID, IngredientID) )
  • Trifacta Wrangler


    Trifacta Wrangler

    Trifacta Wrangler is a free program (currently in beta) that helps you clean up data sets and gives you a first cut at basic analysis. It is great for quickly turning messy data into structured, manageable formats.

    Trifacta Wrangler

    In the past few days I’ve used it to analyze huge log files and turn messy JSON in structured CSVs that I could import into SQL.

    Quick tips:

    • splitrows always has to come first. The program usually tries to split by \n (new line) first, but that doesn’t always work for JSON. Try splitting by something like },{, or do a quick find and replace ( },{ for }|||{ ) and do the split by ||| if you want to keep the curly brackets for an unnest.
    • unnest is very powerful for splitting out JSON values out into separate columns titled by their keys.
    • flatten works better than unnest in cases where the JSON does not have keys. It creates new rows and repeats other values in adjacent columns to keep the relation. This works well if you have an ID column and are going to eventually stuff things into a relational database.

    Here is documentation for the Transforms.

  • Linux Webserver Cheat Sheet


    There is obviously a lot more than this, so I’ll add more as I encounter and use them.

    Last updated on: July 6, 2016.

    Connecting

    • Connecting: ssh username@serveraddress
    • Switching to root once you get in, if needed: su root

    Where to find things

    • Logs: /var/log/apache2
    • Site roots: /var/www/ if a single site, /var/www/vhosts if multiple sites on virtual host infrastructure
    • Config files: /etc/apache2/sitesavailable and /etc/apache2/sitesenabled

    Changing directories, creating files and directories, viewing text files

    • Changing directory: cd ~/path/to/folder
    • Going up one directory: cd ..
    • Creating files: touch filename.jpg
    • Creating directories: mkdir directory_name
    • Viewing text files: less filename.txt or cat filename.txt
    • Closing out of less: q

    wget

    Wget retrieves content from web servers.

    Syntax:

    $ wget [option] URL

    Options:

    • -O – Which output file the file you are downloading should get written to.
    • -q – Quiet mode. Doesn’t show the download status and other output.

    Example – Getting a file from the web:

    $ wget -O /path/to/filename.json http://example.com/URL/to/filename.json

    Reading the manual for commands

    $ man <command>

    Examples:

    • man cron
    • man date

    Crontab

    Cron is a time-based job scheduler in Linux and Unix. Here is my full TIL on cron.

    Load your personal crontab (cron table) file:

    $ crontab -e

    View your personal crontab:

    $ crontab -l

    Syntax:

    min hour day of month month day of week command
    * * * * * command
    0 – 59 0 – 23 1 – 31 1 – 12 0 – 6 (0 to 6 are Sunday to Saturday) shell command you want to run at that time

    Examble: Download a JSON file from Quandl and overwrite GOLD.json with it Monday through Friday at 5pm server time

    0 17 * * 1-5 wget -O "/path/to/quandl_data/GOLD.json" "https://www.quandl.com/api/v3/datasets/LBMA/GOLD.json"

    Date

    Display a date and time:

    • $ date spits out the date and time on the server
    • $ TZ=US/Pacific date spits out the server’s date and time adjusted to the Pacific timezone
    • TZ=US/Eastern date -d 'Tue Jul 5 10:43:07 PDT 2016' converts the timestamp in the -d option to the Eastern timezone.
    • date -d @1467740657 converts UNIX timestamps to something you can actually read

    Eric Davis has a Simple CLI date calculator writeup on his site.

  • Cleaning up your Mac with Hazel


    Today I learned how to clean up my Mac with Hazel

    Hazel

    Hazel is a preference pane-based application that helps you automate organization on your Mac.

    Within a few hours of using Hazel, I was able to clean out my 1000+ file Downloads folder, tame my unruly Desktop, get rid of all the trash that accumulated in my home folder, and organize my stashes of client files. I also set up rules for the future that will keep these places neat and orderly.

    The next step is to turn my gaze on my photo library to create one master repository.

    Tools and guides

    The best tools/guides on Hazel right now are:

  • Using Word Frequency Charts for Better Word Clouds


    Word clouds

    Data scientists notoriously hate word clouds. Besides for figuring out what the top 2-3 words are (because they are the biggest), it is difficult to see how much one word is used relative to another. Unfortunately, clients and non-data people love word clouds and sometimes insist on them. What is a self-respecting data nerd to do?

    Pair it a word frequency chart!

    The easiest way to do this is by using Python’s counter:

    Counter(words).most_common()

    Then you can use your favorite charting tool to make a bar chart of the results. I prefer D3.js.

    Results

    Word Frequency Chart

    Word Cloud

    If you see both together, you get a better understanding of the words being used. Of course, a single word doesn’t always capture sentiment. They can be helpful in smaller data sets, but sometimes common phrases are more helpful in larger data sets. For common phrases, use n-gram analysis.

    For more on visualizing text, check out episode 62 of the Data Stories podcast and the Text Visualization Browser.

  • Isaac Morehouse Podcast Episode 75 – How to Learn Anything, with Chuck Grimmett


  • Ember.js Basics


    Resources

    What it is

    • Ember.js is an open-source Javascript framework with the Model–view–viewmodel pattern.
    • Ember is an opinionated framework. This means that most architectural design decisions have been made for you by the developers of the framework. The advantage of this is that anyone who knows Ember can load your code and understand within a few minutes what is going on.

    Core Concepts

    Ember Core Concepts

    1. Ember router maps a URL to a route handler
    2. Route handler renders a template, then a model that is available to the template. Templates use Handlebars syntax.
    3. Models save data in a “persistent state”, which is fancy language for putting it in a database or data store of some kind.
    4. Components control how the UI behaves. They have two parts: A handlebars template and a javascript source file that defines the behavior.

    Installing and running a project

    Install:

    $ npm install -g ember-cli@2.6

    Creating a new app:

    $ ember new 

    Starting the development server. You must be in the project folder (cd to it). It will serve on http://localhost:4200/

    $ ember server

    or ember s for short