Search

Monday, May 27, 2013

Java file organization - part 1

Location: Salt Lake City, UT, USA
In my car I keep all my music on a collection of, currently 8, 64GB USB thumb drives.  It's great!  I can fit years worth of music into a case that would only hold 5-10 CD's or DVD's.  I have a directory for each artist which contains a separate folder for each album.  I can print out this list of artists/albums very easily, print and laminate it, and keep it in my car to easily find what I am looking for.

This arrangement only really has two drawbacks: I have to split my music library into chunks less than 59.6GB (since disk manufacturers define a GB as 10^9, and your computer defines it as 2^30), and my car stereo will only support files of the type mp3, wma, m4a, and wav.  Files like video's, album covers, and playlist (.m3u) files are useless to transfer for my car.  Splitting my collection, efficiently, and weeding out the unneeded files would take me ages.  And my collection continues to expand.  I would be fumbling through menus, drag & drop, and shortcut keys forever doing it all by hand.


What are computers but the most versatile tools created by man?  Why spend my days doing something that a computer can do so much faster?  To my rescue comes Java, a handy little language with a short development time for small widgets like I would need, but the power and speed to efficiently manage a task as massive as I demanded.

The other day I took about five hours and wrote up a set of utilities to manage the vast majority of my music file management tasks, including building and copying my disk lists.  I like little utilities like this, they help me keep my skills limber.

I figured this might be a good topic to write a little how-to on some of the stuff I did.  I will assume you know some basic java as well as the LinkedList class.

The heart to any file organization is being able to find all the children of a given directory.  So to this end I wrote a helper method and two basic filters to do just that:

 public static String validExtRegex = "^.*?(\\.mp3|\\.wma|\\.m4a|\\.wav)$";

 public static LinkedList<File> getImmediateChildren(File root,
   boolean getDirs, boolean getFiles, boolean onlyValidFiles,
   boolean skipEmptyDirs) {

  LinkedList<File> list = new LinkedList<File>();

  if (!root.isDirectory())
   return list;

  if (getDirs) {
   File[] children = root.listFiles(isDirectory);
   for (int i = 0; i < children.length; i++) {
    if (skipEmptyDirs) {
     if (children[i].listFiles().length < 1)
      continue;
     boolean skip = true;
     for (File f : children)
      if (f.isDirectory()
        || (onlyValidFiles && f.isFile() && f.getName()
          .toLowerCase().matches(validExtRegex))) {
       skip = false;
       break;
     }
     if (skip)
      continue;
    }
    list.add(children[i]);
   }
  }

  if (getFiles) {
   File[] children = root.listFiles(isFile);
   for (int i = 0; i < children.length; i++) {
    if (onlyValidFiles
      && !children[i].getName().toLowerCase()
        .matches(validExtRegex))
     continue;
    list.add(children[i]);
   }
  }

  return list;
 }

 public static FileFilter isDirectory = new FileFilter() {
  @Override
  public boolean accept(File pathname) {
   return pathname.isDirectory();
  }
 };

 public static FileFilter isFile = new FileFilter() {
  @Override
  public boolean accept(File pathname) {
   return pathname.isFile();
  }
 };

We start by defining a regular expression (regex) to match known good file types.  A discussion of regex is beyond this post, but this basically says to match anything which ends in .mp3, .wma, .m4a, or .wav.
The method takes a File object which should be a directory which we want to retrieve the children for, the rest of the parameters are booleans for whether we should get files, directories, and if we should only include valid files or skip empty directories.
The real meat of this method is the root.listFiles(isDirectory) and root.listFiles(isFile) calls, which use the FileFilter objects we create below the method, which are called Anonymous Inner Classes.  This returns only files or directories from the listFiles() method of File.  If you are unfamiliar with the syntax I use to create these objects, search google for anonymous inner class.  The only real complexit in this method is in handling the exclusion of empty directories, and filtering out unmatched file types, but the logic involved should be self-evident if you have done much coding.

This method is great, but what we really need is the ability to list files/directories to any depth.  There are two ways to go about this sort of task, recursive, and iterative.  Though many people are tempted to go for the elegance of a recursive solution, for arbitrarily large data sets the stack overhead makes this less than an ideal candidate, so I have instead written an iterative solution:

 public static LinkedList<File> getAllChildren(File root, boolean getDirs,
   boolean getFiles, boolean onlyValidFiles, boolean skipEmptyDirs) {

  LinkedList<File> list = new LinkedList<File>(), dirsToCheck = new LinkedList<File>();

  if (root.isDirectory())
   dirsToCheck.add(root);

  while (!dirsToCheck.isEmpty()) {
   File file = dirsToCheck.pop();
   LinkedList<File> childDirs = getImmediateChildren(file, true,
     false, onlyValidFiles, skipEmptyDirs);
   LinkedList<File> childFiles = getImmediateChildren(file, false,
     true, onlyValidFiles, skipEmptyDirs);
   if (getFiles)
    list.addAll(childFiles);
   if (getDirs)
    list.addAll(childDirs);
   dirsToCheck.addAll(childDirs);
  }

  return list;
 }

This method should be fairly straightforward.  We are simply using a list named dirsToCheck to collect each directory we find, and we continue to remove and check each directory till the list is empty.  This is known as a breadth first search (as opposed to a depth first search) because it examines each complete level in the hierarchy before moving to the next.  This is a fairly simple method, most of the real work is being done in the first method we created.

In my next post I will show how I build my file lists to be written to thumb drives.  This will include deleting and copying files!

Friday, May 24, 2013

How I quit smoking

Location: Salt Lake City, UT, USA

April of 2011 I quit smoking.  I had quit before around 2004, with the help of Zyban (also known as Wellbutrin), but after going through a period of my life with a lot of stress, I had started again in 2006.  I can proudly say that since April '11 I have tried one cigarette, and the taste was so disgusting that I put it out after a few drags.  I haven't had the slightest inkling to try one since.


I loved smoking.  I certainly was addicted, immensely so, but beyond that I was in love with the act of smoking.  At any point in my day when I was bored I could have a cigarette, and ten minutes would be filled with addictive pleasure.  It provided an oral fixation as well as something to do with my hands.  I also love old fashioned things, trinkets; my zippos and cigarette cases were things I proudly carried and used regularly, long ago having become part of my personal style.  On the psychological front, smoking is a way to instantly differentiate myself from the average straight laced Mormon, and growing up and living in Utah, there is value in such a display.


The key to me quitting was being able to do so without giving up the things I loved about smoking.  I started using an E-Cigarette.  I hadn't planned on quitting smoking entirely.  I had an idea in my head that I would use the e-cigarette most of the time, but still enjoy a real cigarette once a week or so.  But once I had become accustom to the e-cigarette I just lost my desire to smoke.  There was simply no need when the e-cigarette took care of all the things I loved about smoking, and contained none of the drawbacks.


To those who are not aware of e-cigarettes, or those who have been caught up in all of the misinformation which surrounded them when they first became available, I will give you a quick rundown.  An e-cigarette consists of two primary components, a battery, and something which is called an atomizer.  An atomizer is a fancy word to describe a group of devices which break a liquid into a fine mist (atom in the classical sense).  Inhalers are a type of atomizer.  They work in many different ways, but in an e-cigarette the atomizer contains a small heating coil which literally works to make steam.  There are two styles of atomizers.  The more popular ones are built into a cartridge which holds the e-juice, the other style uses an atomizer that is surrounded by a mesh, designed to drip e-juice on directly.

The key to an e-cigarette, of course, is the e-juice, which is a mixture of nicotine with a base and sometimes flavoring.  E-cigarettes work by vaporizing e-juice, or more accurately, by steaming it with the heat coming from the atomizer.  The base used in e-juice is typically propylene glycol, a substance commonly used as a base for medicine and food (it's used in nebulizing inhalers).  Some people are allergic to propylene glycol, so sometimes vegetable glycol will be used instead.  Nicotine is a poison, produced by the tobacco plant to deter insects.  It is the active ingredient in cigarettes, the substance you become addicted to.  In small doses, with a built up tolerance (addiction), it is a relatively safe substance.  It causes an increase in heart rate similar to the effects of caffeine.  Usually a flavoring agent is added to the mixture.  My go-to flavor is Chocolate-Vanilla-Hazelnut, but there are literally thousands of flavors made by different companies.

The choice between different types and brands of e-cigarettes is such a personal thing, but I will tell my own experience and hope that it is enlightening.

I started out buying an e-cigarette package from a local smoke shop.  The brand was Smoke 51, designed to work with cartridges.   They advertised a cartridge as being equivalent to a pack of cigarettes, with 5 cartridges costing about $12.  I used this for two to three months, and was satisfied, but I did have two complaints, the cartridges would leak e-juice on my lips and it tasted disgusting, and I also found them to be imprecise, the way they wick the juice to the atomizer meant that toward the end of their life the cartridges started to give off wispy draws that were unsatisfying, even though the cartridge still contained a lot of juice.  Also the batteries tended to last me 6-8 hours.

To deal with the short battery life I bought a much cheaper unit from the corner store as a backup (I don't recall the brand).  This brand had a different design, using a separate atomizer and cartridge.  The atomizer was a drip atomizer with a wire mesh, and the cartridge was designed to fit on it and wick to the mesh.  After a few days of using the cartridges I got tired of the same issues with juice leaking into my mouth and started using this e-cigarette as a drip atomizer instead of using the cartridges.  It worked very well, and I was much much more satisfied with this setup.  I put away my Smoke 51 unit and never picked it back up.


I liked dripping onto my new e-cig, but the one I had gotten was as cheap as they get.  It only held a charge for 4-6 hours, and the thing was crooked when you screwed the atty on the battery.  Armed with the experience I had gained from vaping for nearly six months, I went online to find solutions to my previous complaints about my e-cigarette experience.  I found a company called Volcano E-Cigarettes, which seemed highly recommended, and had a very active forums where their customers had built quite a neat little community.  The product which drew me was a well crafted version of the typical e-cig you find, but came with two of them, along with a handy carrying case which also acted as a charger, holding enough juice to recharge both batteries a few times.  I went with a cartridge like option, a clear tube which held a large volume of e-juice but I switched back to using a drip atomizer when I had issues with the tanks leaking.

After using this portable charging case which they called the Magma, I was sold, and began trying their different flavors, eventually hitting on the Choconilla-haze, which I have used exclusively for over a year now.  I also became intrigued with a more high end e-cig which Volcano was selling, more appropriately referred to as a cigar due to its oversized battery, called Inferno.  The inferno came in two styles, a larger battery, and a smaller battery that can charge via USB while in use, both styles came in the starter kit.  I quickly gave away the larger battery as I found that the USB pass-through battery was enough to last through a long day, and was convenient to keep plugged in while at my desk using it.  After using the Inferno for a few months I gave away all my other e-cigs and got a second Inferno battery as a backup.  I continue to use the Inferno to this day.


Volcano recently came out with a new e-cigarette named LavaTube.  It is much larger than the inferno, and much much larger than a typical e-cigarette.  It uses a removable battery and has variable voltage, along with improvements under the hood.  The variable voltage means that you can adjust how dense or 'hot' the draw will be.  I tend to run mine at 3.8 volts.  The removable batteries means that I can buy a number of them (I have 4) and charge two at a time in a separate charger.  I can go backpacking for 4-7 days without needing to recharge this way.  I use my LavaTube mostly at my desk, as it is a little large to carry in my shirt pocket, and I carry the Inferno out and about with me.


There are lots of different companies out there making cool e-cigarettes.  So Volcano is not the only game in town, and I encourage you to go see what's available.  I can say that with the few problems I have had (one unit that failed after a few months, and one shipment of the wrong flavor of juice), they were quick to correct the issues and very easy to deal with.  I have placed maybe thirty or so orders with them in the past 2 years.

And last, if you made it this far, you are likely committed to quitting smoking.  I want to explain a difference between the nicotine you get in a cigarette, and what you get with pure nicotine, like that found in e-juice.  Cigarette manufacturers use a chemical process to change nicotine in cigarettes so that it is absorbed into your blood stream much faster than it would naturally.  Because of this, cigarette smokers are trained to the immediate response (the fix) that smoking gives.  Pure nicotine can take 5-10 minutes to fully absorb into the bloodstream, and as such, transitioning from cigarettes to e-juice can be less satisfying than people may expect.  Cigarettes are a game of rewarding a desire, e-cigarettes are more about establishing a constant level of nicotine in your system.  By the time you crave a cigarette, it is too late to get a quick cure with an e-cigarette.  Instead, you will need to get used to using the e-cigarette maintenance, regularly using it to maintain the level which you are accustomed to.

In closing, I know a lot has been brought up about the health risks of e-cigarettes, so I thought I should address this, as I have done extensive research on the subject.  The medical science on nicotine and propylene glycol is fairly extensive and both substances are safe as they are intended to be used in e-cigarettes.  The flavoring used is typically USDA grade and food-safe.  However there is one big warning here.  KNOW WHERE YOU GET YOUR E-JUICE FROM.  Buy from a non-name/fly-by-night operation and you have no idea what they put in there.  Buy from a reputable source where you can confirm the ingredients and methods used in preparation, this is very important.  This is another reason I went with Volcano, who have a large brick-and-mortar business located in the US, employing food-safe laboratories and methods.  The same can be said for hardware, such as batteries and atomizers.  Batteries can malfunction, and parts can be made with toxic substances.  Again, ensure you are purchasing from a reputable manufacturer who care about what goes into their products.

Since quitting smoking, and taking up the e-cigarette I feel great, I don't stink all the time, and I expect to be around a lot longer!  If you have any questions for me leave them in the comments!