“C wears well with experience” ~ a quote from the classic book, The C Programming Language.
(I like to think that well-written Scala code wears well with experience.)
“C wears well with experience” ~ a quote from the classic book, The C Programming Language.
(I like to think that well-written Scala code wears well with experience.)
Seibel: What do you enjoy about programming?
Peyton Jones: For me, part of what makes programming fun is trying to write programs that have an intellectual integrity to them ... so I think a good attribute of a good programmer is they try to find a beautiful solution.
(A quote from the book, Coders at Work)
“As soon as you start programming with side effects, evaluation order becomes important.”
From the book, Masterminds of Programming: Conversations with the Creators of Major Programming Languages
From the python.org website: “Long time Pythoneer Tim Peters succinctly channels the BDFL's guiding principles for Python's design into 20 aphorisms, only 19 of which have been written down.”
1995: [at blockbuster] yes, please call me when the movie I want is returned
2016: [netflix won’t load] I've never endured such suffering
(from this twitter page)
The first seven chapters of my new book, Functional Programming, Simplified, are now available online. More coming soon.
As a “note to self,” I just updated this Drupal 8 website in less than three minutes. Actually, what I did was (a) test the Drupal update on a Test server, and then (b) did the update here in less than three minutes.
The following block shows my Cliffnotes on performing the update. If you’re familiar with Drupal, these notes may make sense, and help you when you need to perform an update of your own.
UPDATE: Once you get to a certain level of Drupal — I don’t remember the exact version but somewhere around 8.43 or 8.5 — you shouldn’t use Drush to update your website any more, you should use Composer. I write about this in my article, A Drush 9 list of commands for Drupal 8.
Update Drupal 8.1.3 to 8.1.8 (on the test server)
=================================================
# create a new database on my test server
mysql -u root -p
create database aad8prod;
use aad8prod;
# create a mysql user and grant permissions
GRANT ALL PRIVILEGES
ON aad8prod.*
TO 'prod_user'@'localhost'
IDENTIFIED BY 'prod_password'
WITH GRANT OPTION;
# restore the production database to my test server
source aa.com.sql.20160814;
# update the drupal8 config with the new username and password
# sites/default/settings.php
$databases['default']['default'] = array (
'database' => 'aad8prod',
'username' => 'prod_user',
'password' => 'prod_password',
'prefix' => '',
'host' => 'localhost',
'port' => '3306',
'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
'driver' => 'mysql',
);
# Test server notes
- had to disable the 'trusted_host_patterns' in settings.php
- drupal error message was:
The provided host name is not valid for this server.
- made sure everything is working on the test server
- i turn off my wifi to make sure i don't accidentally do
something on the prod server
Performing the Drupal Update (Test server)
------------------------------------------
# download latest drupal version (8.1.8)
- unpack it
- follow the instructions in /core/UPDATE.txt:
- MINOR AND PATCH VERSION UPDATES
- if needed, make a backup copy of your settings.php file
- backup .htaccess and robots.txt
- cp settings.php settings.php.pre20160814 (sites/default)
- cp .htaccess .htaccess.pre20160814
- cp robots.txt robots.txt.pre20160814
- unpack drupal update files somewhere so you can quickly and easily
copy them after you remove the old files
- in this case i put mine in:
- ../drupal-8.1.8
- take the website offline
- admin/config/development/maintenance
- cd to the drupal8 root directory
- `drush cr`
- my cache database tables are several GB; flush them
- rm -rf core vendor
- rm *php
- rm composer*
- rm web.config
- unpack new files
- cp -R ../drupal-8.1.8/* ../drupal-8.1.8/.htaccess .
- run update.php via browser
- http://aad8:8888/update.php
- this shows an update page with no css
- 'tmp' directory on Test server was messed up
- check that everything is working
- go back online
- admin/config/development/maintenance
"Couldn't write file" error message (Test server)
-------------------------------------------------
- looked in reports
- may have to do with:
- couldn't write .htaccess file
- couldn't use temporary directory b/c it was looking for
the temp directory i use in production
- change the temporary directory at this uri:
- admin/config/media/file-system
- change to: /Applications/MAMP/htdocs/aad8-drupal-tmp
- the css/html is screwed up on this page:
- admin/reports/dblog
- `drush cr` fixes this
Production Server
=================
- after i confirmed that the update didn't clobber my website,
i followed the same steps on the Production server
- investigate the differences between these files:
- .htaccess
- robots.txt
Those notes are cryptic, but if you need an example of the steps needed to update a Drupal 8 website from one minor version to another (in just a few minutes on the Production server), I hope they are helpful.
I hear a lot of people say they want to be successful. For me this always comes down to, “What are you willing to do to make that happen?”
In my own case I had to overcome a fear of public speaking, learn how to write software, learn how to build and manage a company, learn some sales techniques, make sacrifices on how I spend my time, etc.
“Adam is just special. He has that kind of makeup that is always trying to invest in other people.”
~ Cardinals’ manager Mike Matheny talking about Adam Wainwright
As a quick note to self, this source code from the online version of Learn You a Haskell shows how to read command line arguments in Haskell:
-- from "Learn You a Haskell"
-- http://learnyouahaskell.com/input-and-output
import System.Environment
import Data.List
main = do
args <- getArgs -- IO [String]
progName <- getProgName -- IO String
putStrLn "The arguments are:"
mapM putStrLn args
putStrLn "The program name is:"
putStrLn progName
If you save that source code in a file named args.hs, and then compile it with ghc like this:
ghc args.sh
you can test it with no command line args like this:
$ ./args The arguments are: The program name is: CommandLineArgs
and then give it a few test command line args like this:
$ ./args foo bar The arguments are: foo bar The program name is: CommandLineArgs
As I show in the comments that I added, getArgs has the type IO [String], and progName has the type IO String.
I want to try writing a few simple scripts/programs in Haskell, so hopefully over time I’ll add more information on how to process command line arguments in Haskell. Until then, the Learn You a Haskell link I shared at the beginning has good information on handling I/O in Haskell.
Parinfer is a tool that is currently in development, and it’s intended to help with the management of all those parentheses in languages like Lisp and Clojure. It looks like it is written in JavaScript, and intended to work with editors like Atom and Sublime Text.
This image is from this New Yorker article on modern day mindfulness. This is a “poem” about mindfulness at the workplace.
Many Olympic athletes are using the ancient Chinese practice of cupping to promote healing, but the Greek team has their own technique.
(Half of my DNA comes form the Middle East, so, you know.)
In this post I share the contents of a custom TextMate command I just created that uses pandoc and sed to convert markdown content in the TextMate editor to a “pretty printer” version of HTML:
#!/bin/sh PATH=$PATH:/usr/local/bin # note: 'sed -E' gives you the advanced regex's # use pandoc to convert from markdown to html, # then use sed to clean up the resulting html pandoc -f markdown -t html |\ sed -Ee "/<p|<h2|<h3|<h4|<aside|<div|<ul|<ol/i\\ \\"
You can try to use a command like tidy to clean the HTML, but the version of tidy I have does not know about HTML5 tags. The TextMate Markdown plugin also doesn’t work the way I want it. Besides that, I’m trying to learn more about writing TextMate commands anyway.
As an important note, when you set this up as a TextMate command and then run it, it will convert the TextMate editor contents from markdown to HTML.
(In a related note, serenity.de is also a good resource for TextMate command and bundle documentation.)
In summary, this code shows:
* How to execute a Unix shell command from TextMate
* Specifically, how to execute a sed command from TextMate
* How to use modern regular expressions with sed (the -E option)
* How to search for multiple regex search patterns with sed
As a little tip today, here’s a short Java/JDBC example program where I show how to perform SQL SELECT, INSERT, UPDATE, and DELETE statements with JDBC:
package com.devdaily.sqlprocessortests;
import java.sql.*;
public class BasicJDBCDemo
{
Connection conn;
public static void main(String[] args)
{
new BasicJDBCDemo();
}
public BasicJDBCDemo()
{
try
{
Class.forName("com.mysql.jdbc.Driver").newInstance();
String url = "jdbc:mysql://localhost/coffeebreak";
conn = DriverManager.getConnection(url, "username", "password");
doTests();
conn.close();
}
catch (ClassNotFoundException ex) {System.err.println(ex.getMessage());}
catch (IllegalAccessException ex) {System.err.println(ex.getMessage());}
catch (InstantiationException ex) {System.err.println(ex.getMessage());}
catch (SQLException ex) {System.err.println(ex.getMessage());}
}
private void doTests()
{
doSelectTest();
doInsertTest(); doSelectTest();
doUpdateTest(); doSelectTest();
doDeleteTest(); doSelectTest();
}
private void doSelectTest()
{
System.out.println("[OUTPUT FROM SELECT]");
String query = "SELECT COF_NAME, PRICE FROM COFFEES";
try
{
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(query);
while (rs.next())
{
String s = rs.getString("COF_NAME");
float n = rs.getFloat("PRICE");
System.out.println(s + " " + n);
}
}
catch (SQLException ex)
{
System.err.println(ex.getMessage());
}
}
private void doInsertTest()
{
System.out.print("\n[Performing INSERT] ... ");
try
{
Statement st = conn.createStatement();
st.executeUpdate("INSERT INTO COFFEES " +
"VALUES ('BREAKFAST BLEND', 200, 7.99, 0, 0)");
}
catch (SQLException ex)
{
System.err.println(ex.getMessage());
}
}
private void doUpdateTest()
{
System.out.print("\n[Performing UPDATE] ... ");
try
{
Statement st = conn.createStatement();
st.executeUpdate("UPDATE COFFEES SET PRICE=4.99 WHERE COF_NAME='BREAKFAST BLEND'");
}
catch (SQLException ex)
{
System.err.println(ex.getMessage());
}
}
private void doDeleteTest()
{
System.out.print("\n[Performing DELETE] ... ");
try
{
Statement st = conn.createStatement();
st.executeUpdate("DELETE FROM COFFEES WHERE COF_NAME='BREAKFAST BLEND'");
}
catch (SQLException ex)
{
System.err.println(ex.getMessage());
}
}
}
This code is taken from this Simple JDBC Example on an older version of my website. I’m including it here so I can search for it more easily.
The database that this code uses is the Coffee Break database from Sun’s original JDBC tutorial.
A Bloomberg report says that Apple is planning to release a new MacBook Pro that has a narrow OLED screen at the top of the keyboard, which may replace the function keys. In that same article they share this chart, which shows iPad sales compared to Mac sales (which presumably includes all MacBook, MacBook Pro, and Mac Pro models).
“In Erlang it’s OK to mutate state within an individual process but not for one process to tinker with the state of another process ... processes interact by one method, and one method only, by exchanging messages. Processes share no data with other processes. This is the reason why we can easily distribute Erlang programs over multicores or networks.”
Joe Armstrong, in the book Programming Erlang
Note: This is an excerpt from my book, Functional Programming, Simplified. (No one has reviewed this text yet. All mistakes are definitely my own.)
It’s surprisingly hard to find a consistent definition of functional programming. As just one example, some people say that functional programming (FP) is about writing pure functions — which is a good start — but then they add something else like, “The programming language must be lazy.” Really? Does a programming language really have to be lazy (non-strict) to be FP? (The correct answer is “no.”)
I share links to many definitions at the end of this lesson, but I think you can define FP with just two statements:
Note: I originally wrote this article in 2012.
For a long time I’ve thought the Netflix UI/UX sucks. Their designers don’t seem to understand how I want to use their service, they just seem interested in promoting their “You might like this tv show or movie” algorithm. I keep thinking about buying their stock (which just tanked again to $60), but then the thought comes into my mind, “They’re enamored with their algorithm and architecture, but they don’t understand UX or social.”
After thinking this again last night, I thought about the simple question, “What would Netflix look like if Facebook owned them?” In less than five minutes I came up with the following ideas.
1) Friends make suggestions: First, friends could make movie and tv series suggestions. The Netflix “You might like this” algorithm is okay, but what I’d rather see is suggestions from friends and family who know me.
2) Similar people: I’ve been using Netflix for about two years now, and it would be interesting to see other people who have similar tastes to mine. Again, I could get suggestions from these people, so maybe we have a “Suggestion list from similar users.” I could “follow” these people like I follow people on Twitter. I know I’m getting suggestions from these people already from the Netflix algorithm, but I have no idea who they are.
3) Movie annotations: I’d like to see movie and tv show annotations from my friends, like AMC does with their movies, but from my friends. Imagine my nieces writing, “Uncle Al, make sure you watch X in the next scene,” or friends who really know a lot about movies making notes about how a scene is related to a scene from another movie, or by the same director, etc.
4) Promo clips: Let me make promo clips of movies I like so I can share those with friends. I already do this on Facebook, but I have to copy the movie with one app, then edit the clips down to what I like with iMovie. That’s okay for me, but make this easy so others can do it. (Movie directors and producers: This will help more people see your movie.)
5) My favorites: Let me make a list of my favorite movies and tv series, and share those with other people. I might not recommend that people watch Rashomon or Wild Strawberries, but they would be on this list, where other people could discover them.
6) Movies that inspired directors/producers: Let me see a list of movies that inspired directors and producers of tv shows. I love the old tv show, Northern Exposure, and if the creators of this series told me what inspired them, I’d certainly watch those shows. (And oh by the way, they could tell me about their music inspirations, too.)
As you can see, there isn’t anything magic here — I came up with these ideas in less than five minutes — but I think they’re good ideas. Imagine what a group of people could come up with if they spent time on this? Just look at YouTube and IMDB, and you’ll quickly get many more ideas about what people want to do with video, and know about video.
Besides making for a better experience, they also help tie me into the Netflix service. Right now, I have about ten episodes of Supernatural left to watch on Netflix, and then I’m out of there, unless they have some other content I want to watch. But if they had these social tie-ins, I’d think twice before leaving.
Besides making Netflix a better social website, how about adding in the obvious features:
Basically Netflix has created an on-demand tv station, and if there’s nothing interesting to watch, you just change the channel. But if they had some social aspects to their service, a) it would be a much more interesting concept, and b) I'd think more than twice before leaving.