Category Archives: Dean

Stuff Dean writes

Hey, my first rails plugin

Ruby on Rails allows for plugins to extend its functionality. My first attempt at one is nothing special but I am going to blog about it anyway 😀

I needed a way to check if a number is within a range before saving a record to the database. Rails has a number of good validations built in, but not one that does that. In two or three hours, I was able to piece together a simple plugin that adds “validates_range_of” to my AR models. The code is a little ugly until I can get Greg to install a syntax highlighting plugin for this blog.

module ActiveRecord
module Validations
module ClassMethods
def validates_range_of(*attrs)
options = {  :on => :save  }
options.update(attrs.pop) if attrs.last.is_a?(Hash)
attrs.flatten!
unless options[:message]
if options[:maximum] && options[:minimum]
options[:message] = 'must be betweeen ' + options[:minimum].to_s + ' and ' + options[:maximum].to_s
elsif options[:maximum]
options[:message] = 'must be less than or equal to ' + options[:maximum].to_s
elsif options[:minimum]
options[:message] = 'must be greater than or equal to ' + options[:minimum].to_s
else
raise ArgumentError, 'Range unspecified.  Specify the :maximum and/or :minimum.'
end
end
 
validates_numericality_of( attrs, options )
 
validates_each(attrs, options) do |record, attr_name, value|
if ((!options[:maximum].nil?) && (!options[:minimum].nil?)) &&
(value > options[:maximum] || value < options[:minimum])
record.errors.add( attr_name, options[:message] )
elsif (!options[:maximum].nil?) && value > options[:maximum]
record.errors.add( attr_name, options[:message] )
elsif (!options[:minimum].nil?) && value < options[:minimum]
record.errors.add( attr_name, options[:message] )
end
end
end
end
end
end

As you can see this plugin extends AR::Validations. So my models can use validates_range_of to check minimum and maximum values. Let’s look at the BJCP Scoresheet I needed it for:

class BjcpScoresheet < ActiveRecord::Base
belongs_to :brew_session
validates_associated :brew_session
validates_range_of :brew_session_id, { :minimum => 1, :message => 'does not belong to a brew session' }
validates_range_of :aroma_score, { :minimum => 1, :maximum => 12, :only_integer => true }
validates_range_of :appearance_score, { :minimum => 1, :maximum => 3, :only_integer => true }
validates_range_of :flavor_score, { :minimum => 1, :maximum => 20, :only_integer => true }
validates_range_of :mouthfeel_score, { :minimum => 1, :maximum => 10, :only_integer => true }
validates_range_of :impression_score, { :minimum => 1, :maximum => 10, :only_integer => true }

How nice – reusable user input validation.

–Dean

Obligatory new blogger post

I'm not a blogger, I just like looking under-sexedI’m happy to see we’re getting some traffic and, being a new blogger, I want to just crow a little about it.

(9:43:00 AM) Greg: we suddenly have 89 unique visitors to the blog. At the beginning of the month we had 0.
(9:43:28 AM) Uh, me: very nice
(9:43:57 AM) Greg: and for our home page we had 42 visitors for Jan two days ago, now we have 64
(9:44:19 AM) Uh, me: yay – more traffic

Thanks to the HBD post I made for bringing us traffic. Greg is also driving people here from the Northern Brewer forums.

About Our Infertility

I originally published this on MySpace in January of 2007.

Thanks for taking the time

Thank you for taking the time to read this. I realize the post is quite lengthy, but it is important to us that you have an idea of what we are going through. These are mostly not my words – I found this in an alt.infertility.primary post, but everything here applies to us. I have added emphasis where I thought appropriate. –Dean

About Our Infertility

Adrienne knows that you love her and want her to be happy, to be her “old self” again. Maybe lately, she seems isolated, depressed or obsessed with the idea of having a baby.

You probably have difficulty understanding why getting pregnant has colored virtually every aspect of her daily life. Adie hopes that by reading this , written by psychologists with both personal and professional experience with infertility, you will better understand the pain she is feeling. This letter also will tell you how you can help her.

SOME FACTS ABOUT INFERTILITY

It may surprise you to know that one out of six women who wants to have a baby cannot conceive. There are many possible reasons for this dismal statistic: blocked fallopian tubes, ovarian failure, hormonal imbalances, toxic exposure, husband’s low sperm count, to name just a few. Moreover, after a woman turns 35, it becomes difficult to have a baby primarily because many of the eggs she has left are defective.

All these barriers to pregnancy are physical or physiological, not psychological. Tubes don’t become blocked because a woman is “trying too hard” to get pregnant. Antibodies that kill sperm will not disappear if a woman simply relaxes. And a man cannot make his sperm swim faster by developing a more optimistic outlook.

WELL-MEANING ADVICE

When someone we care about has a problem, it is natural to try to help. If there’s nothing specific that we can do, we try to give helpful advice. Often, we draw on our personal experiences or on anecdotes involving other people we know. Perhaps you recall a friend who had trouble getting pregnant until she and her husband went to a tropical island. So you suggest that she and I take a vacation, too.

We appreciate your advice, but cannot use it because of the physical nature of our problems. Not only can we not use your advice, the sound of it upsets Adie greatly. Indeed, she is inundated with this sort of advice at every turn. Imagine how frustrating it must be for her to hear about other couples who “magically” become pregnant during a vacation simply by making love. To us, undergoing infertility treatment, making love and conceiving a child have very little to do with one another, now. You can’t imagine how hard we have been trying to have this baby and how crushed Adie and I feel every month we learn that we failed again. Your well-meaning advice is an attempt to transform an extremely complicated predicament into a simplistic little problem. By simplifying our problems in this manner, you’ve diminished the validity of our emotions, making us feel psychologically undervalued. Naturally, both of us will feel angry and upset with you under these circumstances.

The truth is: There’s practically nothing concrete you can do to help Adrienne. The best help you can provide is to be understanding and supportive. It’s easier to be supportive if you can appreciate how being unable to have a baby can be such a devastating blow.

WHY NOT HAVING A BABY IS SO UPSETTING

Women are reared with the expectation that they will have a baby someday. They’ve thought about themselves in a motherhood role ever since they played with dolls. A woman may not even consider herself part of the adult world unless she is a parent. When Adrienne thinks she cannot have a baby, she feels “broken.”

Worse, we are not even certain that we will never have a baby. One of the cruellest things you can do to a person is give them hope and then not come through. Modern medicine has created this double-edged sword. It offers hope where there previously was none — but at the price of slim odds.

WHAT MODERN MEDICINE HAS TO OFFER THE INFERTILE COUPLE

In the past decade, reproductive medicine has made major breakthroughs that enable women, who in the past were unable to have children, to now conceive. The use of drugs such as Pergonal can increase the number and size of eggs that a woman produces thereby increasing her chances of fertilization. In-vitro fertilization (IVF) techniques extract a woman’s eggs and mix them with sperm in a “test tube” and allow them to fertilize in a laboratory. The embryo can then be transferred back to the woman’s uterus. There are many other options, as well.

Despite the hope these technologies offer, they are a hard row to hoe. Adrienne has endured repeated doctor’s visits, taken daily injections, shuffled work, school and social schedules to accommodate various procedures, and laid out considerable sums of money — money that may or may not be reimbursed by insurance. All of this is preceded by a battery of diagnostic tests that can be both embarrassing and extremely painful.

Infertility is a highly personal medical condition, one that we may feel uncomfortable discussing with our employers. So, Adie is faced with coming up with excuses whenever her treatment interferes with her job. Meanwhile, we are devoting considerable time and energy to managing a mountain of claims forms and other paperwork required by insurers.

After every medical attempt at making her pregnant, she and I must play a waiting game that is peppered with spurts of optimism and pessimism. It is an emotional roller coaster. She doesn’t know if her swollen breasts are a sign of pregnancy or a side effect of the fertility drugs. If she sees a spot of blood on her underwear, she doesn’t know if an embryo is trying to implant or her period is about to begin. If she is not pregnant after a procedure, we may feel as though our baby died. How can a person grieve for a life that existed only in our mind?

While trying to cope with this emotional turmoil, she gets invited to a baby shower or Christening, learns that a friend or colleague is pregnant, or she reads about a one-day-old infant found abandoned in a Dumpster. Can you try to imagine her envy, her rage over the inequities in life? Given that infertility permeates practically every facet of our existence, is it any wonder why she is obsessed with her quest?

Every month, we wonder whether this will finally be our month. If is is not, we wonder if we can muster the energy to try again. Will we be able to afford another procedure?

So when you speak with Adirenne, try to empathize with the burdens on her mind and in her heart. She knows you care about her, and she may need to talk with you about her ordeal. But she knows that there is nothing you can say or do to make her pregnant, and she fears that you will offer a suggestion that will trigger even more despair.

WHAT CAN YOU DO FOR US?

You can give us support, and don’t criticize Adie or I for any steps we may be taking — such as not attending a nephew’s birthday — to protect ourselves from emotional trauma. You can say something like this:

I care about you. After reading this letter, I have a better idea about how hard this must be for you. I wish I could help. I’m here to listen to you and cry with you, if you feel like crying. I’m here to cheer you on when you feel as though there is no hope. You can talk to me. I care.

The most important thing to remember is that Adie and I are distraught and worried. Listen to what we have to say, but do not judge. Do not belittle her feelings. Don’t try to pretend that everything will be OK. Don’t sell her on fatalism with statements like, “What will be will be.” If that were truly the case, what’s the point of using medical technology to try to accomplish what nature cannot?

Your willingness to listen can be of great help. Infertile women feel cut off from other people. Your ability to listen and support her will help her handle the stress she’s experiencing. Our infertility is one of the most difficult situations we will ever have to deal with.

PROBLEM SITUATIONS

Just as an ordinary room can be an obstacle course to a blind person, so can the everyday world be full of hazards for an infertile woman — hazards which do not exist for women with children.

She goes to her cousin’s house for Christmas. Her cousin is breast-feeding. The men are watching the football game while the women talk about the problems with their kids. She feels left out, to say the least. Christmas is an example of the many holidays that are particularly difficult for her. They mark the passage of time. She remembers what came to mind last Christmas — that the next year, she would have a new son or daughter to show off to her family.

Mundane activities like a walk down the street or going to the shopping mall are packed with land mines. Seeing women pushing baby carriages and strollers strikes a raw nerve. While watching TV, Adirenne is bombarded by commercials for diapers, baby food, and early pregnancy tests.

At a party, someone asks how long she’s been married and whether she has any kids. She feels like running out of the room, but she can’t. If she talks about being infertile, she’s likely to get well-intentioned advice — just the thing she doesn’t need: “Just relax. Don’t worry. It will happen soon,” or “You’re lucky. I’ve had it with my kids. I wish I had your freedom.” These are the kinds of comments that make her want to crawl under the nearest sofa and die.

Escape into work and career can be impossible. Watching our dream shatter on a monthly basis, we can have difficulty investing energy in advancing our careers. All around, her co-workers are getting pregnant. Going to a baby shower is painful — but so is distancing herself from social occasions celebrated by her colleagues.

THE BOTTOM LINE

Because we are infertile, life is extremely stressful for us. We are doing our best to cope. Please be understanding. Sometimes she will be depressed. Often times she will be angry. Sometimes she will be physically and emotionally exhausted. She’s not going to be “the same old sweetie” she used to be. She might not want to do many of the things she used to do.

We have no idea when, or if, our problem will be solved. We are engaged in an emotionally and financially taxing venture with a low probability of success. Overall, only about 11 percent of those people using special fertility treatments succeed in having a baby. The odds are even lower for women over 40. The longer we persevere, however, the greater her chances of pregnancy become.

Maybe someday we will be successful. Maybe someday we will give up and turn to adoption, or come to terms with living a childfree life. At present, though, we have no idea what will happen. It’s all we can do to keep going from one day to the next. We do not know why this is our lot. Nobody does. All we know is the horrible anguish that we live with every day.

Please care about her. Please be sensitive to her situation. Give her your support, she needs it and wants it.

Of all the things I miss….

Before the death of my drives I had a flexible Measurement class written up. As most of you know brewing involves all kinds of measurement – hop weights, boil volume, bitterness, etc. The class served as a base that more specific classes would inherit and provided the framework for converting between different measurement systems. For example, the SpecificGravity class would inherit Measurement and provide the conversion code to switch between SG and Plato.

The database would save the scalar and units and instantiate an aggregation of these two pieces. When the units changed, back into the database it went with the new values. It was very easy to work with, but took me quite a bit of time to write.

“Why not use one of the libraries already available?” you might ask. The short answer is that they do not fit my needs. Firstly, none of them produced objects that I could stuff in the database as a aggregation – most are intended as great extensions to various number classes. Secondly, and most importantly, none of them dealt with Bitterness, Color or Specific Gravity, which is really why I need a measurement class. Lastly, most of them only handled linear transformations:

m2 = a * m1 + b

To convert from SG to Plato you need to use a cubic polynomial, ugh.

So I wrote my own, then re-wrote it, and it was beautiful. Now I am re-engineering the whole thing. In addition, I’ll have to figure out where I got the Plato to SG reverse conversion. I remember trying to solve the cubic equation, then finding something that actually worked.

It is a little faster-going because I wrote it all before, but I had some tr1cky 31337 code in there that I will have to figure out again.

Always make sure your backups are working and current.

–Dean

Progress report

‘Been working hard on BrewSession for a few days and I’d like to tell my readers (or is it reader?) about it. I got the hop data Greg compiled and the BJCP style guidelines back into the database. It feels like an accomplishment because this data is critical to meaningful brewing software. Next up is to move my spreadsheet of yeast information into the database and re-compile the data I had about extras. Today is a holiday in the US so I will be hard at work on that. Our biggest data hurdle is finding malt information and putting it into a consistent format. Greg is working hard on that. Once all our data is loaded and backed up I believe BrewSession will be around one quarter complete.

–Dean

It doesn’t have to start out so advanced

Merry Christmas. Here’s a little javascript brewsession present.

http://ror.deanandadie.net/table.html

I was thinking about the ingredients table Greg designed. While it is good looking and we’ll definitely use it, I would rather see a very simple list to start with and give the option to have an “advanced view”. It occurred to me to let the user choose which columns they want to see. So I restarted work on BrewSession again with this prototype. It’s a work in progress, but a solid start.

–Dean

Disaster Recovery

BrewSession is not off the ground in a professional capacity, therefore all the code is housed on a machine I have running on my home network. A week and a half ago that machine’s disk controller corrupted my data. Then I screwed up the backup copy of that data in the restore process. The data is almost surely still there, but it’s just beyond my knowledge system administration. I have acquaintances in the data-recovery business, so there is hope for a full restore.

I am upset about losing 4 months worth of hard work because we were planing to have a private alpha test next month. However, now that I have sixteen weeks of ruby programming experience recreating the project will not be difficult. With luck we will be able to roll out our alpha in early spring, 2007.

The lesson here is to test your restores before you need to.

–Dean

Hop bitterness calculations

Since there has to be a first post some time, I thought I’d start. I need a break from coding, too.

All hop utilization formulas are “best fit” calculations to enpirical data – researchers look at results from their expirements and try to find an equation that best fits the data. This reality produces a few different ways to estimate the final bitterness in your beer. For BrewSession Greg and I decided to offer three bittering calculation methods.

Many brewers regard Tinseth’s method to be well suited when doing full boils using whole or plug hops. There are quite a few parts to it, all of which we will post to the FAQ or User’s Guide or Glossary when we get it up.

Partial-mashers and extract brewers are better served by Rager’s method which is more accurate when doing partial boils with pellet hops loose in the boil. We’ll make this formula available too.

Daniels-Mosher is a somewhat new formula. In fact, I can’t find the formula referenced on the Internet (speak up, Greg). We will be sure to include it with the others.

Because we want to use the right tool for the right job, I devised some programatic logic to select a utilization calculation that best fits the hop as used in individual recipe bitterness calculations. Currently there is no regard for full v. partial boils, only hop form – all the information is there, so the code may change if there is a need. The code first checks to see if the user has a preferred calculation method and uses that if present. Failing that, BrewSession decides which method is better – Tinseth for whole and plug hops and Rager for pellets. If BrewSession can not figure out the hop’s form, it uses Daniels-Mosher. Unsure of where to best use D-M, I threw it as the “unknown” case. If you have ideas, hit the comments or drop me an email.

–Dean

Stealing A Buffer

Jumpy, jittery, convoluted video and audio

For a long time, Myth did well. It did everything we expected it to and even a little more. Then shows began to degrade. It may have been a driver or software upgrade or a settings change – these things don’t “just happen” – but I could not trace the cause. Random shows would end up with jumpy audio and video skips. I found a similar description on the web: It is like the first 200ms of each second is missing. Try watching that. Ben came up with a three-level rating system for the severity of unwatchability. Level One was annoying, but watchable and often went away. Level Two neared pure noise and at Level Three you lost all hope.

I turned debugging on, collecting volumes of log files. At one point, I filled up my /var filesystem (how did I forget to turn cron on? Oh yeah, on most other operating systems it’s running by default!) which does not make Myth happy when it’s trying to write logs there.

I tweaked settings, trolled for clues in the detritus, searched for and requested help from the Internet. No improvement. No message in the data. No suggestion availed me.

Recordings are big files

1.3G Apr 4 00:00 1047_20060403230000.mpg
1.3G Apr 5 00:00 1047_20060404230000.mpg
1.3G Apr 6 00:00 1047_20060405230000.mpg
627M Mar 30 23:30 1063_20060330230000.mpg
1.3G Mar 23 02:00 1048_20060323010000.mpg

Behind the scenes the operating system breaks up each file into manageable blocks and writes the chunks to the disk. It tries very hard to put all the blocks in a row so it can read the whole file much like you are reading this text – word by word. When the OS deletes a file it makes the file’s blocks available for other files that may come along. This creates a “space” between two files on disk. Often, new files are bigger than the space created so the OS fills the space with part of the file and then uses new space for the remainder. This is called file fragementation. Fragmentation is bad because it slows down file reads as the OS has to look all over the disk to get each piece of a file. UFS, a widely-used filesystem for unix machines, somehow keeps fragementation from becoming a problem. However, I was using XFS to store recordings.

That made me wonder

I wondered if XFS was as good as keeping fragments out of the filesystem and if fragmentation could cause my A/V problems. I fired up the xfs_db utility to check the situation.

mythical # xfs_db -f /dev/mapper/myth_vg-myth_lv
xfs_db> frag
actual 14468, ideal 402, fragmentation factor 97.22%

This seemed bad to me. The XFS defrag’er only works for two hours at a time, so I set up a little script in screen to do the defrag’ing while I slept.

mythical # while true
while> do
while> clear
while> date
while> xfs_fsr
while> echo done!
while> sleep 300
while> done

When the work was done several hours later, new recordings improved in quality. I was happy with myself and posted the fix to the mailing list.

I hoped recordings would return to normal

I Don’t Watch Commercials

I do not miss the advertisements

Previously, I blogged about how I got to be a MythTV user. Possibly the best thing about Myth is automatic commercial skipping! It is not perfect, but when it works, you barely know your’re watching broadcast television. It works by marking suspected commercials and jumping over those marks during playback. There are some very clever developers that wrote the code to go back over a recording looking for station logos, special video frames, closed-captioning breaks, among other things. This operation takes (on my machines) about 20 minutes per hour of real video and can (currently) happen only after a show is finished recorded. Each flagging job queues up so depending on how many recordings just completed it could be hours before the show is really ready to watch. You can always watch a show immediately after it begins recording. I have become so accustomed to time-shifting all my television that the wait between live broadcast and prepared recording is unnoticable. Watching a well-flagged television show is quite cool and even if the flagger misses, it is an easy thing to rewind then skip ahead in 30 second jumps. We do miss the TiVo sounds just a little, so someone makes them when necessary; ba-doop ba-doop ba-doop.

In addition to the volume of bad adverts, we miss out on the occasional not-so-bad commercial. The benefits and detriments of a comsumer culture is left as an exercise for the reader, but it feels nice to be free of stupid, stupid commercials. Adrienne felt that she was missing out on too much new TV, so she went out and subscribed to a television magazine. I guess people are willing to pay for targeted advertisements.