Fun With Fortune in Linux

Fortune provides a random quote or aphorism every time you open a terminal in Linux. I wanted to have a personalized fortune using zuihitsu quotes posted on this site come up whenever I opened a terminal. If you want to do something similar, here’s the procedure.

To check if you have it installed, simply type fortune into the terminal.

$ fortune 

This either returned a fortune or an error message. If you got an error message, then install fortune using the package manager for your system.

$ sudo apt install fortune-mod

Let’s create our own file of fortunes. I want to use my zuihitsu quotes I have posted on this site. This file is a text file that looks like so:

%
quote 1
%
quote 2
%
quote ...

There is a copy of the file available online.

If you have just a file with lines of quotes, this is easy to get into this format using emacs. Simply type: M-%, followed by c-q c-j Enter then c-q c-j % c-q c-j Enter. I like to check the replacements, so just keep hitting y to do the replacement and move on to the next one if it looks good. Save the file to the appropriate directory, which on Debian systems is /usr/share/games/fortunes, but can vary. For explanation purposes, we are going to assume the file was named zuihitsu with no file extension.

Note: If you are using the file above, just save it as a text file in your directory. Then, copy it to the appropriate system directory without a file extension.

Now, create a .dat file for the file you just made.

$ sudo strfile zuihitsu

Set the same permissions on the new files as the others in the directory. This just makes the files readable to groups and others.

$ sudo chmod o+r zuihitsu
$ sudo chmod g+r zuihitsu
$ sudo chmod o+r zuihitsu.dat
$ sudo chmod g+r zuihitsu.dat

Following the rest of the directory. I added a symbolic link.

$ sudo ln -s zuihitsu zuihitsu.u8

You should be able to test it now.

$ fortune zuihitsu

Assuming that worked. The final thing to do is to have your preferred shell call this when it runs. I use bash, so I added the command above to my bash_aliases file. From then on, it will pull a random quote from the zuihitsu file every time you bring up the terminal.

Bonus: Did you know the original fortune-mod fortune collection is available as a EPUB?

Being a Creator, Craig Mod

This is a really interesting discussion of how one man created a business using a subscription model combined with discounts for the finished work for subscribers. There’s much to think about in this discussion. If this is of any interest to you, I’d read the whole thing and the previous year’s as well. He talks about what it takes, how much it costs, the tools he uses, and provides a whole lot of other detail that might provide some food for thought.

Min, The Minimalist Web Browser

See quick definitions and answers with information from DuckDuckGo, including Wikipedia entries and more. Jump to any site quickly with fuzzy search. Or search through the full text of every page you’ve visited, even if you don’t remember the title.

Min

I haven’t tried this browser. I like the idea. But, I think being able to use a SOCKS5 proxy is important, and I don’t see that functionality on a casual scan. Still, I thought it might be worth looking into as a secondary browser.

Build Your Own Text Editor

“This is an instruction booklet that shows you how to build a text editor in C.

The text editor is antirez’s kilo, with some changes. It’s about 1000 lines of C in a single file with no dependencies, and it implements all the basic features you expect in a minimal editor, as well as syntax highlighting and a search feature.

This booklet walks you through building the editor in 184 steps. Each step, you’ll add, change, or remove a few lines of code. Most steps, you’ll be able to observe the changes you made by compiling and running the program immediately afterwards.”

https://viewsourcecode.org/snaptoken/kilo/index.html

Might be interesting to compare to the source code of mg, which is a minimal editor written in C that works like Emacs.

Forecasting in R: Probability Bins for Time-Series Data

This time-series.R script, below, takes a set of historical time series data and does a walk using the forecast period to generate probabilistic outcomes from the data set.

Input file is a csv file with two columns (Date, Value) with dates in reverse chronological order and in ISO-8601 format. Like so:

2019-08-06,1.73                                                                
2019-08-05,1.75                                                                
2019-08-02,1.86

Output is as follows:

0.466: Bin 1 - <1.7
0.328: Bin 2 - 1.7 to <=1.9
0.144: Bin 3 - 1.9+ to <2.1
0.045: Bin 4 - 2.1 to <=2.3
0.017: Bin 5 - 2.3+

Note: Patterns in data sets will skew results. A 20-year upward trend will make higher probabilities more likely. A volatile 5-year period will produce more conservative predictions and may not capture recent trends or a recent change in direction of movement.

R Script

# time-series.R 
# Original: December 4, 2018
# Last revised: December 4, 2018

#################################################
# Description: This script is for running any 
# sequence of historical time-series data to make 
# a forecast for five values by a particular date.
# Assumes a cvs file with two columns (Date, Value) 
# with dates in reverse chronological order and in
# ISO-8601 format. Like so:
#
# 2019-08-06,1.73                                                                
# 2019-08-05,1.75                                                                
# 2019-08-02,1.86

#Clear memory and set string option for reading in data:
rm(list=ls())
gc()

  #################################################
  # Function
  time-series <- function(time_path="./path/file.csv", 
                        closing_date="2020-01-01", trading_days=5, 
                         bin1=1.7, bin2=1.9, 
                         bin3=2.1, bin4=2.3) {

  #################################################
  # Libraries
  #
  # Load libraries. If library X is not installed
  # you can install it with this command at the R prompt:
  # install.packages('X') 

  # Determine how many days until end of question
  todays_date <- Sys.Date()
  closing_date <- as.Date(closing_date)
  remaining_weeks <- as.numeric(difftime(closing_date, todays_date, units = "weeks"))
  remaining_weeks <- round(remaining_weeks, digits=0)
  non_trading_days <- (7 - trading_days) * remaining_weeks
  day_difference <- as.numeric(difftime(closing_date, todays_date))
  remaining_days <- day_difference - non_trading_days 

  #################################################
  # Import & Parse
  # Point to time series data file and import it.
  time_import <- read.csv(time_path, header=FALSE) 
  colnames(time_import) <- c("date", "value")

  # Setting data types
  time_import$date <- as.Date(time_import$date)
  time_import$value <- as.vector(time_import$value)

  # Setting most recent value, assuming descending data
  current_value <- time_import[1,2]

  # Get the length of time_import$value and shorten it by remaining_days
  time_rows = length(time_import$value) - remaining_days

  # Create a dataframe
  time_calc <- NULL

  # Iterate through value and subtract the difference 
  # from the row remaining days away.
  for (i in 1:time_rows) {
    time_calc[i] <- time_import$value[i] - time_import$value[i+remaining_days]
  }

  # Adjusted against current values to match time_calc
  adj_bin1 <- bin1 - current_value
  adj_bin2 <- bin2 - current_value
  adj_bin3 <- bin3 - current_value 
  adj_bin4 <- bin4 - current_value 

  # Determine how many trading days fall in each question bin
  prob1 <- round(sum(time_calc<adj_bin1)/length(time_calc), digits = 3)
  prob2 <- round(sum(time_calc>=adj_bin1 & time_calc<=adj_bin2)/length(time_calc), digits = 3)
  prob3 <- round(sum(time_calc>adj_bin2 & time_calc<adj_bin3)/length(time_calc), digits = 3)
  prob4 <- round(sum(time_calc>=adj_bin3 & time_calc<=adj_bin4)/length(time_calc), digits = 3)
  prob5 <- round(sum(time_calc>adj_bin4)/length(time_calc), digits = 3)
  
  ###############################################
  # Print results
  return(cat(paste0(prob1, ": Bin 1 - ", "<", bin1, "\n",
                  prob2, ": Bin 2 - ", bin1, " to <=", bin2, "\n", 
                  prob3, ": Bin 3 - ", bin2, "+ to <", bin3, "\n", 
                  prob4, ": Bin 4 - ", bin3, " to <=", bin4, "\n", 
                  prob5, ": Bin 5 - ", bin4, "+", "\n")))
}