Piping fun in shell with fortune and cowsay

Somebody mentioned seashells.io to me. A nifty little service that let’s you pipe output from your shell’s command line directly to the web.

What better use for this than to pipe random funny quotes?

TL;DR

If you want to check out the output – just go here https://seashells.io/v/FCPsK8Sh. It’s running from my shell – so may die any moment.

Show me how!

First, you need to install a couple of packages.

  • cowsay prints an ascii image to the screen, that looks like a cow ( or one of the specified animals).
  • fortune prints a random quote or a “fortune-cookie” type message from a collection of quotes
  • fortune-min is needed on some systems (like Ubuntu), as fortune only comes with the engine, not the db of quotes. Not needed on mac.
  • seashell is a client for seashells.io website. You don’t have to install it, you can just use netstat. It’s up to you. But you do need python & pip available.
sudo apt-get install -y cowsay fortune fortunes-min

# If you are on macOSX, brew is your friend
brew install cowsay fortune 

# if you want seashells client instead of nc
pip install seashells

Now that we have prerequisites, let’s actually use the magic of pipe to combine all the tool togeather!

Note: The choice of animals available to cowsay varies by distribution . For instance, macOSx has blowfish but ubunutu‘s package, doesn’t

If you use fish shell

# Let's wrap some functionality into a handy function
function random_quote
  set animal (random choice {default,dragon,dragon-and-cow,elephant,moose,stegosaurus,tux,vader})
  fortune -s | cowsay -f $animal
end

# a trick to pipe from loop to another process. Fish only.  
fish -c 'while true; sleep 15; random_quote; end' | nc seashells.io 1337

If you use bash shell

random_quote() {
  choices=("dragon" "dragon-and-cow" "elephant" "moose" "stegosaurus" "tux" "vader")
  animal=${choices[$RANDOM % ${#choices[@]} ]}
  fortune -s | cowsay -f $animal
}

while true; do sleep 15; random_quote; done | nc seashells.io 1337

Ruby Hash[key] Showdown :symbol vs “string”

Who cares?

There was recently a discussion on Trailblazer Gitter channel about Hashes as params, how to pass them around, and as customary a flame-war war ~~ensued~~ never happened, and it came down to a measuring contest: ~~whose~~ which key is better and faster.

For the impatient: for small Hashes it doesn’t really matter, for larger ones :symbol is 2x faster than string’ keys. Frozen string’ keys are almost as fast as :symbol keys.

The best way to argue is to present facts. So I coded a couple of benchmarks and submitted a pull request to fast-ruby (Github). Here are the details.

Round 1: Hash[:symbol] vs Hash[“string”]

First, lets measure allocating Hash in various ways that Ruby gives us

require "benchmark/ips"

def symbol_key
  {symbol: 42}
end

def symbol_key_arrow
  {:symbol => 42}
end

def symbol_key_in_string_form
  {'sym_str': 42}
end

def string_key_arrow_double_quotes
  {"string" => 42}
end

def string_key_arrow_single_quotes
  {'string' => 42}
end

Full code for the benchmark is here on Github and the results on rig with 8 cores and 16 GB of RAM, running on Ruby 2.4.2

Comparison:
        {symbol: 42}:  1731221.3 i/s
     {:symbol => 42}:  1714113.4 i/s - same-ish
     {'sym_str': 42}:  1711084.8 i/s - same-ish
    {"string" => 42}:  1508413.1 i/s - 1.15x  slower
    {'string' => 42}:  1452896.9 i/s - 1.19x  slower

So while 19% slower may be a fairly big difference, keep in mind that this is for 1.5 million iterations per second. Who in their right mind creates 1,500,000 single pair hashes per seconds? Right?

string keys are not going to be the speed bottleneck in your app.

Round 2: But what about large hashes?

Don’t worry I got you covered. You can check out specific benchmark right here on Github. Let’s try it out for a 1000 key-value pairs.

require "benchmark/ips"


STRING_KEYS = (1..1000).map{|x| "key_#{x}"}.shuffle
FROZEN_KEYS = STRING_KEYS.map{|x| "fr_#{x}".freeze}
SYMBOL_KEYS = STRING_KEYS.map(&:to_sym)

# If we use static values for Hash, speed improves even more.
def symbol_hash
  SYMBOL_KEYS.collect { |k| [ k, rand(1..100)]}.to_h
end

def string_hash
  STRING_KEYS.collect { |k| [ k, rand(1..100)]}.to_h
end

# See this article for the discussion of using frozen strings instead of symbols
# http://blog.arkency.com/could-we-drop-symbols-from-ruby/
def frozen_hash
  FROZEN_KEYS.collect { |k| [ k, rand(1..100)]}.to_h
end


SYMBOL_HASH = symbol_hash
STRING_HASH = string_hash
FROZEN_HASH = frozen_hash


def reading_symbol_hash
  SYMBOL_HASH[SYMBOL_KEYS.sample]
end

def reading_string_hash
  STRING_HASH[STRING_KEYS.sample]
end

def reading_frozen_hash
  FROZEN_HASH[FROZEN_KEYS.sample]
end

Full benchmark code . Let’s see the results:

Creating large Hash

Comparison:
         Symbol Keys:     3262.0 i/s
         Frozen Keys:     3023.2 i/s - same-ish
         String Keys:     2476.7 i/s - 1.32x  slower

Reading large Hash

Comparison:
         Symbol Keys:  5280882.7 i/s
         Frozen Keys:  4791128.0 i/s - same-ish
         String Keys:  4275730.5 i/s - 1.24x  slower

So as we can see on a larger Hashes with 1000’s of keys, the difference becomes more apparent and being mindful of it can help improve speed, if you are using a lot of large hashes. Otherwise, my recommendation, keep using what works better for you app. If string keys make it easier, let’s say you are importing them from an external file, don’t go through the trouble of converting them to symbols, it’s probably not worth it.

But don’t take my word for it. Just measure it.

Why do people like Elixir?

What is there not to like? I recently started learning Elixir, and so far I haven’t found any downsides.

It’s functional, concurrent, highly scalable, super stable, offers gazillion 9’s of reliability, has many built-in features like key/value store, pleasant Ruby-inspired syntax, a fast-growing number of libraries, awesomely welcoming community, great docs.

While Elixir may not be the best fit for every type of application, and I’m not abandoning Ruby anytime soon, it is a great language – that has a great market/audience fit.

Here are some of my favorite aspects of programming in Elixir coming from OOP programming in Ruby, that is winning me over. In fact, I like them so much, that I’ve started writing similar functional code in Ruby.

  • Let is crash
    • The whole language is built around an idea, that it is cheap to let a process crash and restart using a supervisor process. If you had to ever deal with silently crashing code before, you will appreciate this immensely.
  • Functional
    • You deal with functions, not objects. Some people find to wrap their heads around it. But it’s not. Have you ever written something with a pipe operator in Linux shell? Where you passed the output of one command straight into another? Well, that’s pretty much it.
  • Immutable
    • This is a big deal if you ever head to handle state in your program. It simplifies reasoning about your program. You don’t have to worry anymore if your data structure got changed. Because you never change it in the first place. You make a copy and deal with a copy, in your next step.
  • Familiar Ruby syntax
    • Sometimes that can work against me as I’m reaching for some things, that are not in Elixir, but overall I found it very user-friendly.

Originally posted on Quora: Nick Gorbikoff’s answer to Why do people like Elixir

Read / write to DBF files from Ruby

A little history.

I worked on a project, where a system was written in house for a period of almost 20 years and it’s done in dBase. Once cool and almighty, it’s not longer, dare we say, a system that is at the forefront of computer technology. It has numerous problems: multiple users locking tables, AD based security for each individual file/table, slow, etc.

Long story short, we decided to convert our system to a web based one, with a Debian / Nginx / Passenger / MariaDB / Ruby back-end – and whatever at the front-end. Obviously we had a problem of converting old data to mysql format, with ruby only supporting reading of dbf file via ruby dbf gem – which is great if you only need to read files.

Unfortunately, we couldn’t just abandon our system, since too much depended on it – we needed to have a slow transition – where some sections are being phased out as it’s being replaced by web based app. We needed to be able to write back to dbf files. Let me save you some time – I search long and hard, and there is no way to do it. Or so I and most of the comments on the Internet thought at the time of this writing (Jan, 09).

Until I had an epiphany – ODBC!!! I was actually reading an article about PHP, and thought about one of my first experiences – when I had to pull data from MS Access (back in ’99) into MySQL using ODBC. So below is the solution and explanation of the process. Let me tell you right now – I haven’t tried this will work on Linux. This was deployed on Win2k3 (and tested on WinXP). Please leave a comment if you got it working on Linux.

Setup a DSN for your connection.

  1. Go to Control Panel > Administrative Tools > ODBC
  2. Select System DSN tab and add a new connection
  3. Select Driver do Microsoft dBase (*.dbf) – if you are missing that – you might need to install db2k running time, that you should have if you working with dBase files.
  4. Select Version 5
  5. Give it a name – i.e. rubydbf – something unique and descriptive – this analogous to your db name in your MySQL connections
  6. Select the directory where your dbf files sit – in my case – C:\Projects\dbf
  7. Select appropriate indexes for your dbf files – either *.ndx or *.mdx files.

Lets try to access our data

Fire up shell – we are going to test our connection.

We need to make sure we have all the gems:

  gem install dbi gem install dbd-odbc

Let’s test if it worked:

irb 
require 'dbi' 
require 'odbc' 
conn = DBI.connect('DBI:ODBC:rubydbf','','')

If you didn’t get any error messages – that means that you are fine. You can try to run for a list of tables available to you through this connection.

conn.tables

Read data

Let me warn you right away – and I think it’s a dBase driver issue ( there are a couple of other driver’s I haven’t tried, that might be better) – some of the standard DBI ODBC commands just don’t work. I’ll give the list of the ones I found working and most useful at the end of the post.

rs = conn.select_all('select * from product')

This spits back all the data sitting in the product table, rs being your reqular ruby array. So you can do all the nice things such as rs.size or rs[3], etc. Obviously you are limited by your RAM and pc – but most modern pc’s should handle your older dbf files. The reason I’m saying this is that I found most sql statement unexecutable – for example select * from product limit 2 – won’t work.

Of course you can use things like select_many() – but I think it’s just easier to do all of your magic in ruby, simply because ruby is going to be faster and easier in this case, thou I don’t not advocate that in general – DBs are good at manipulating data – leave it to them.

Another way to query your data it is to use DBI’s prepare and execute statements:

q = conn.prepare('select * from product where partid = 14')
q.execute()
rs = q.fetch_all()

This approach lets you use band variables – which might be useful – if you are not just converting data, but need to pull dynamic result sets – i.e. dated reports or something.

Insert Records

Now that we can read data, let try to insert data – which is the main point of this exercise:

q = conn.prepare("insert into product (description) values('cool widget')")
q.execute()

If you run select statement now you should see a new record in your table. As – I said unfortunatly you can’t do limits and so on, so you can dump all you data in an array rs = conn.select_all('select * from product') and then do rs.last to see your new and shiny row

That is it. Should be enough to get you started, let me know if you run into problems – someone else mgiht think of something or sometimes

Have fun! or what amounts to it in dBase world 🙂

Если бы языки программирования были бы машинами

Below is my literary translation ( with some small changes and additions ) of a post on Mike Vanier’s website – If programming languages were cars. Translated and posted with author’s permission.

Ниже – мой литературный перевод заметки на сайте Майкла Ваниера, с небольшими добавлениями и немного отсебятины. Переведено и напечатано с разрешения автора.

  • Ada – это аццкий танк. Большой и толстый, времён 2-ой мировой, чем-то напоминает русский T-34 или американский Шерман М-4. Люди смеются над тобой когда ты им говоришь, что ты в танке. Но ты, блин, ещё посмеёшся над ними, когда наступит война, и они будут ездить на своих спортивных машинах по полю битвы. Хорошо смееётся тот, кто смеётся последний. Особенно если у него есть план, и он в танке.

  • Assembly – чисто двигатель. Машину надо построить самому, вручню подвести нефть из трубы, нефть переработать на месте, и всё это не выключая двигателя. Зато если ты аккуратен – попрёт, что твой запорожец, из анекдота, с авиационным двигателем.

  • ASP.NET – машина класса ехтра-люкс, которая хочет попасть в гараж каждего автолюбителя, как это удалось сделать главному её конкуренту. Правда ездит она только по дорогам построенным специально для неё, в случае поломки вам надо выписивать специалного механика из дорогой мастерской и запасные части, а также спойлера, диски, и трубо, стоят сумашедших денег.

  • Basic – простая машинка, для поездок в ближайший овощной магазин. Однажды популярная среди начинающих машин, была переделана крупным ПО производителем. Новая машина пригодна для поездок на более дальние расстояния, лишь издалека напоминая предыдущую модель. А-ля Toyota Corolla – 1984 и 2000.

  • C – спортивная машина, которая может ехать очень быстро, но ломается каждые 100 км.

  • Cobol – поговаривают что была такая машина, но ни один уважающий себя водитель не признается, что ездил на такой. Прячется в подвалах очень крупных гаражей. Типа инвалидки с зиловским двигателем.

  • C# – конкурентная модель симейных седанов. Однажды проехавшись на таком, вы уже не сможете пересесть на другую машину. Ваш седан просто не разрешит вам.

  • C++ – затюнингованая Си, обладает кучей всяких крутых новых кнопочек и фишечек, может проехать 500км, прежде чем поломается, но когда уж поломоается, никто не знает почему. И без-политра тут не обойдёшся.

  • dBase – это Deloarean языков програмирования. Одно время – это была самая модная тачка на районе. Так должны были виглядеть машины будушего. Когда вы садитесь за руль этой машины, вы чувствуете себя немного как тот сумашедший профессор из “Назад В Будущее”.

  • Eiffel – машина, в которую встроен инструктор по-вождению, разговаривающий с сильным французским акцентом. Он поможет вам быстро понять и исправить ваши ошибки, но не смейте прирекаться – или вас обматерят и выкинут из машины.

  • Erlang – это автопарк машин, которые едут вместе, чтобы доставить вас по месту назначения. Требуется опыт, чтобы научится управлять этим табуном, но уже если научитесь, то не не захотите учиться ездить по-другому. К тому же не важно если одна из лошадей выпадет из табуна – упряжка всё равно дотянет вас до места назначения.

  • Forth – машина которую вы собираете сами из конструктора. Она не выглядет как машина и даже не ведёт себя как ни одна другая. Зато очень эксклюзивно – ведь машина марки Forth – ездит только задом наперёд.

  • Fortran – достаточно примитивная машина, которая может ездить, только по очень прямым дорогам. Владельцы – этой машины будут до посининения доказывать вам, что это не правда, и просто у всех остальнх слишком неправильный прямой взгляд на дороги.

  • Java – это семейный вагон. Им относительно легко управлять, он не слишком быстр, но и в меру безопасен.

  • Haskell – не совсем машина. На самом деле вовсе не машина – а абстракция машина, которой вы должны описать как бы вы себя вели если бы были машиной. После чего, вам нужно будет абстракцию воплатить в реалном мире. При этом как работает прототип вы знать не имеете права. Вы так же можете сделать множество копий вашей абстрактной машины, после чего вы сможете сделать много одинкаовых поездок на этих копиях.

  • Lisp – похож на машину, но если у вас есть смекалка и лобзик, вы можете из него сделать и самолёт и атомную подводную лодки. Вы лишь ограничены своей фантазией и лобзиком. К сожелению никто вам не верит – все думают, что это всего лишь старый советский анекдот.

  • Mathematica – продукт попыток сделать из Лиспа – навигационый спутник. Может расчитать оиптимальный маршрут до места назначения, но и стоит эта машина как спутник.

  • Matlab – дешовый вариант Математики, на подобе, распечатаных карт. Очень удобна для передвижения по знакомой местности, но стоит вам попаст в чащёбу, и вы быстрее выберетесь пешком.

  • Ocaml – европейские автопроизводители постарались над её сексуальным дезайном. Она не такая быстрая как Си, но почти никогда не ломается, в отличии от своих амерканских скоростных аналогов. Правда из-за того, что делали её во Франции, приборная доска, комьютерный чип и руль находятся в совершенно неожиданных местах.

  • Perl – говорят, что это очень классная точила, но книга по эксплуатации, написана по-олбански, а логика управления – отчасти напоминает женскую. Оданко если вы научитесь управлять этой машиной, вам уже не захочется пересаживаться на другю.

  • PHP – это как Экарус. В него набито куча народу, в него иногда не заедешь легко в маленкий дворик, но всем хочется такой поводить и желательно оранжего цвета.

  • Prolog – делает за вас всё автоматически, после того как вы дадите эй инструкции – но усилий которые вам на это потребуются, с лихвой хватило бы чтобы уже сбегать туда и обратно два раза.

  • Python – это замечательная машина для начинающих. Если вы никогда не поедете на болото, не заберётесь на вершину вулкана или не полетите в космос, другое средство передвижения вам и не потрбуется.

  • Ruby – машина, которя пострил один японский автостроитель в подсобке, из останков того что осталось после аварии между Пёрлом, Питоном и Смолтоком. Правда некоторые водители жалуются: ” На хера в машине три руля?”, но не задумиваются они над тем, что первый руль может отказать, а второй просто не захочет с вами разговаривать. Правда поговоривают , что её скоро перестроют с одним рулём, но с 6-ю колёсами для увеличения проходимости и скорости.

  • Smalltalk – очень маленкая машина, придуманая для начинаюших водителей и конструкторов. Она не быстра, но зато вы можете сделать из неё трех-колёсный мопед или веложабу. Единстевенное маааааленкое отличие: вы ей не управляете, вы посилаете смс-ки что бы она сделала, то что вы хотите.

  • Visual Basic – машина которая ездит на вас!