iHeinrich

just trying to find the answer…

Page 2 of 2

Thinking about making a mobile web app? Think again.

There is an excellent and LONG article on why mobile web apps are dogtastically slow.

Why Mobile Web Apps are slow.

The article is well written and well documented.

I have looked at platforms like RhoMobile by Motorola which seem to promise effortless mobile web app development, but a look at the apps that actually USE this platform is not very impressive.

 

How to make the Ultimate Cup of Coffee


When I wake up in the morning, the first thing I need to do is make myself a cup of coffee.

I am not a coffee snob, but the coffee from Starbucks and Dunkin Donuts just doesn’t do it for me.

My journey to the find the perfect cup of coffee was completely accidental. In fact, when I was in the Navy as a young man, I never drank coffee.

Even today, I only drink ONE cup of coffee in the morning.

First Discovery: The Bean

CremaI worked with a guy who was an espresso fanatic. He bought broken espresso machines on eBay, fixed them up, and sold them. He knew the price of every bag of espresso beans and when he got a good price on a bag, he usually bought a case of  12 bags.

One day, he offered me a bag of Lavazza Super Crema Espresso Whole Bean Coffee.

I promptly ground it up using a cheap bladed coffee grinder, put the grounds in a paper filter, and put it into a Mr Coffee machine.

It tasted better than the Folgers or whatever I was drinking.

My concern with the Mr Coffee machine was getting the AMOUNT of GROUND to WATER RATIO correct. I can’t do precise measurement in the morning when I am bleary eyed and sleepy.

Second Discovery: The Mokka Pot

machinetta-thumbnail2I was introduced to the Mokka Pot by way of a Polish girl who lived in Italy (long story). I was immediately  impressed by the simplicity of the device. My espresso fanatic friend often spent $500 or MORE on espresso machines, and here was an aluminum pot for $25 to 35 which had no moving parts.

The operation was simple.

  1. Put grounds into the cup. Warning: DO NOT PACK IN or TAMP THE GROUNDS!! 
  2. Fill water chamber up to the pressure nipple.
  3. Assemble (takes all of 5 seconds).
  4. Apply heat.
  5. Wait 5 minutes. When the espresso is ready, it will make a distinctive “rumbling” noise. When it starts rumbling, turn off the heat.
  6. When the rumbling noise stops, the coffee is ready.

Other things to consider

  • Do not open the lid and look in and see how the coffee is progressing. The water is under pressure coming up thru the grounds, and opening the lid releases the pressure and slows down the process, or so I was told. It’s not exactly a perfect seal.
  • Do not WASH the Mokka pot! In the first few uses, the coffee will form a “stain” on the inside of the aluminum, this stain is GOOD! It keeps out that “aluminum” taste and acts as a natural barrier. Bachelors of the World, this is the perfect kitchen appliance!
  • There is only ONE item that requires annual replacing: the rubber seal. There is a rubber seal under the top chamber. When it fails after about a year, coffee will come shooting out of the middle of the pot.
  • Most people in Europe have one of these pots at home.

Third Discovery: Conical Burr Grinder

saeco-titan-burr-grinderI was pretty happy with my coffee at this point. I had my mokka pot and my Lavazza beans and I thought I was set.

I was wrong.

Speaking again with my espresso fanatic friend, he said, “You really need a conical burr grinder”

He went on to explain that the conical burr grinder SQUEEZES the oils out of the bean, creates a more uniform grind, and the coffee will taste richer and smoother.

I discovered that a GOOD conical burr grinder is not cheap. I paid $120 for mine, and prices have come down. The good news is they last quite a while. I’ve had my current one for 5 years, without any issue.

This is my current conical burr grinder, a Saeco Titan. I highly recommend it.

Amazon doesn’t carry this model anymore, but the updated version of this grinder is quite cool looking as well and half the price that I paid.

A conical burr grinder is worth every penny you pay for it. The difference in taste is dramatic and immediately noticeable.

Final Notes

  • I no longer drink Lavazza Blue as I am totally addicted to Lavazza Crema e Aroma. I have a subscription thru Amazon, so it comes out to $22 a bag, every 2 months. I try different beans every now and again, but I always come back to Crema e Aroma.
  • I was travelling overseas and I met a pair of Italian ladies. Immediately, we began to discuss coffee and I asked them “How do YOU make your coffee?”I thought we would be coffee compagni, but I was mistaken.They told me they use Lavazza one-time use pods in a Nespresso Machine. When I told them my process they said they would do that but it takes too long. (Ridiculous: takes 5 minutes). Then they added, “You make coffee like a REAL ITALIAN”.

I’ve been duped!


dupedIn testing my Photo Organizing Script, I noticed something scary.

If I move an image into a folder where another DIFFERENT image has the SAME name, the move function overwrites previous image.

No warning.

This is a pretty serious issue, since it will result in data loss.

It’s time to write a function to detect for this and rename the file.



	def move_safely (file, folderName)

	  if File.exists?(folderName+"/"+file)
	    puts "the file exists and should not be overwritten!"

	    #rename the file
	    #generate an 8 char random string to append to the file name.
	    random8 = (0...8).map{(65+rand(26)).chr}.join

	    #break up the file into file and file type. The result of this is an array
	    breakUp = file.split(".")

	    #add the fixin's to the random8 string
	    randomize = "_"+random8+"."

	    #insert it into the array
	    breakUp.insert(1,randomize)

	    #convert the array into a file string
	    newFileName = breakUp.join

	    File.rename(file,newFileName)

	    file = newFileName

	  else
	    puts "the file doesn't exist"
	  end

	FileUtils.move file, folderName

	end

NEF images with Sorting Script


logo-NEF
I was pretty happy with my scanning and sorting script.

I shoot with a Nikon camera, so many of my images are NEF/RAW images.

Unfortunately, the exifr method JPEG.new doesn’t like NEF images, because they aren’t JPEGS.

Maybe they are TIFFs? Let’s give it a try!



if file.end_with?(".NEF")
     dateShot = EXIFR::TIFF.new("#{file}").date_time
     puts "it's a NEF"
else
     dateShot = EXIFR::JPEG.new("#{file}").date_time
end

so we replace the one line that extracts date with this “NEF checker” and it works!

Drowning in a sea of pictures…..


Great_Wave_off_Kanagawa2If you are like me, you take a gazillion pictures and they are all over the place.

Recently, I decided to the consolidate all my data from all my hard drives onto one massive NAS Drive (Synology 412+).

Synology DOES offer a tool that let’s you sort all your images using “Smart Folders” or something, but that didn’t appeal to me.

I wanted a ruby script to that I could drop into a sea of pictures and I would get all the images sorted by month and year into named folders.

I am sure there are tools that do this, but I wanted to write my own.

I’m stubborn that way.

Step 1: Install exifr reader gem.

One of the great things about ruby is that there usually is a “gem for that”.


Heinrichs-iMac:~ hbeck$ sudo gem install exifr

WARNING: Improper use of the sudo command could lead to data loss
or the deletion of important system files. Please double-check your
typing when using sudo. Type "man sudo" for more information.

To proceed, enter your password, or type Ctrl-C to abort.

Password: StevePontEsMuyMacho
Successfully installed exifr-1.1.3
1 gem installed
Installing ri documentation for exifr-1.1.3...
Installing RDoc documentation for exifr-1.1.3...
Heinrichs-iMac:~ hbeck$ 

Step 2: Write some code!

We are going to require

  • rubygems since we are using a gem.
  • exifr, to read the exif data.
  • date, to read the date.
  • fileutils, to move the files.

#! /usr/bin/env ruby

require 'rubygems'
require 'exifr'
require 'date'
require 'fileutils'


# I want to just drop this in a folder of images. This gets the working directory
wd = Dir.getwd

# files is an array of file name strings in the working folder.
files = Dir.entries("#{wd}")

#I'm going to go thru each file and read it's date.
files.each do |file|  
        # the meat of what I want to do will go here....
end

Step 3: There’s trouble right here in Directory City

One of the pain in the keister issues in MacOS is that hidden files called “.” or “..” will be picked up in the directory scan. But since they do not have exif data we need to sniff for them and NOT run the exifr method on them. Also, the ruby file will be in the directory so I need to exclude that as well.


if file.start_with?(".") || file.end_with?(".rb") 
    puts "(hand wave) this is not the file you are looking for..."
  else
       # the meat of what I want to do will go here.
  end 

Time to get some shooting data!


dateShot = EXIFR::JPEG.new("#{file}").date_time

returns a date that looks like this: Sat Jun 22 22:09:22 -0400 2013

I know it’s a date class since I double checked thusly:


puts dateShot.class

and got ‘Date’.
If ever you are unsure what a variable actually is ‘variable.class‘ is your best friend.

Step 4: There’s MORE trouble right here in Directory City

The idea is to make directories with Month_Year, but what if there is ALREADY a directory in the folder? What if I dump a sea of images into a directory, run my magic ruby script, and then find MORE images after I have sorted all the images into directories? I can’t run the exifr method on a directory, so I need to sniff for that as well.


if file.start_with?(".") || file.end_with?(".rb")
    puts "(hand wave) this is not the file you are looking for..."
  elsif file.include? "."
     # I know that all my jpeg files will have a DOT in the name and my directories do NOT have dots in their name.
     # So I will put the methods here....
  else
    puts "it's a directory"
  end 

Step 4: How about a date, baby?

I want the date formatted like this: Mon_Year. The Date class offers a method to format our date pretty much any way we like.


     dateShot = EXIFR::JPEG.new("#{file}").date_time
     folderName = dateShot.strftime("%b_%Y")

This will return Jun_2013.

I want to make the directory, but of course, if the directory ALREADY EXISTS, I want to leave it alone.


 if File.exists?("#{folderName}") # I thought Dir.exists would work, but it doesn't. If you know WHY, please let me know.
          puts "the directory exists"
     else
          Dir.mkdir("#{folderName}")
          puts "make the directory"
     end

The directory has been created, let’s move the files in there…


FileUtils.move file, folderName

Yes, it really is that easy.

Step 5: It’s ALWAYS SOMETHING ALICE!! 

Ok, you are thrilled that everything is working fine and images are getting sorted out but then exifr finds that SOME images have no shooting data.

It happens. Maybe you downloaded the image from a website that stripped out the exif data.

When this occurs, the exifr method returns nil.

We need to catch that, so let’s make a NO_Date directory and drop the undated images in there.


   if dateShot.nil?
         folderName = 'No_Date'
         puts "there is no date"
 else
         folderName = dateShot.strftime("%b_%Y")
 end

Step 6: Let’s test it! 

I suggest you start with a small folder of images, drop the ruby file in there, and see your results. I wrote this on my MacOS, but it should work on any OS. If you have Windows, it goes without saying that you need to install Ruby to make this work (but I said it anyway).

Step 7: What happens if I have a NEF/RAW image? 

Good question! I’ll investigate this another time. I have a lot of images to clean up!

Here is the final script. Enjoy.


	#! /usr/bin/env ruby

	require 'rubygems'
	require 'exifr'
	require 'date'
	require 'fileutils'

	# I want to just drop this in a folder of images. 
	wd = Dir.getwd

	# files is a list of a files in the working folder
	files = Dir.entries("#{wd}")

	#I'm going to go thru each file and read it's date.
	files.each do |file|  

	  if file.start_with?(".") || file.end_with?(".rb") 
		#ignore ruby scrip and hidden files.
	    puts "(hand wave) this is not the file you are looking for..." 
	  elsif file.include? "."
	     dateShot = EXIFR::JPEG.new("#{file}").date_time

	     if dateShot.nil?
	       folderName = 'No_Date'
	       puts "there is no date"
	     else
	       folderName = dateShot.strftime("%b_%Y")
	     end

	     if File.exists?("#{folderName}") 
	     	puts "the directory exists"
	     else
	     	Dir.mkdir("#{folderName}")
	     end

	     FileUtils.move file, folderName

	  else
	    puts "it's a directory"
	  end

Final thoughts

Happy Ticket


While on the bus in Russia, they give you a ticket with a 6 digit number.

The Russian I was with closely read the numbers, and I asked “Why do you care about the number?”

She said, “If the first three numbers equal the last three numbers, it’s a ‘Happy Ticket’ and I keep it.”

I tried to figure the odds on getting a “Happy Ticket” and just gave up.

I’m a programmer, not a mathematician.

So I wrote a Ruby script to iterate thru the numbers and do a comparison of the first three and the last three.


#!/usr/bin/env ruby
i = 0
happy = 0
theCount = Array.new
while i < 999999
i += 1
f = sprintf '%06d', i # f is a six digit number

theCount = f.chars.to_a

first = theCount.fetch(0).to_i + theCount.fetch(1).to_i + theCount.fetch(2).to_i
last = theCount.fetch(3).to_i + theCount.fetch(4).to_i + theCount.fetch(5).to_i

     if first == last
          happy += 1
          print("Happy Number ", happy," is ", theCount[0..2], theCount[3..5], "\n") 
      end

end

The end result is that there are 55,252 'Happy Numbers', meaning your odds of getting one is about 5.5%

New blog, different approach

If you are reading this, there is a chance you remember my long running blog, “The Heinrich Show”.

While “The Heinrich Show” was a fun blog (I laughed), it really was more geared for my circle of friends.

In retrospect, I think Facebook killed the Heinrich Show. But that’s ok. Not everything is supposed to last forever.

iHeinrich is really about solving technical problems, how I solved the problem, and gripes about how long it took me to solve a problem.

 

 

Page 2 of 2

Powered by WordPress & Theme by Anders Norén