April 2009 Entries

v3 tech on a v1 body

imageNew Database, relay boards, Linq To Sql backend now work with the old user interface.  Right now there are 2 things not hooked up, the images as you can see and the progress bars for pouring.  With Expression Blend 3’s support for Illustrator, I realized I could port the PSD’s which are vector based into Illustrator.  The gradients won’t port 100% nicely but I can redo those in Illustrator.  The glasses also were made by Ian Hall if I haven’t mentioned that before.

I did a decent chunk of axe sharpening building this new version.  It has some pretty nice admin tools now which are done in Win32 currently as I’m not 100% comfortable with WPF yet.  Doing the last bits of logic today, I know there are still chances are some bugs as when I was writing the code, I didn’t expect LINQ to act in certain ways.

var listOfDrinks = from d in GetPossibleDrinkListByPartialName("")
					   select d.DrinkId;

var returnVal = (from uh in user.UserHistories
				 where listOfDrinks.Contains(uh.DrinkId)
				 orderby uh.UserHistoryId descending
				 select uh).Take(1);

return (returnVal == null) ? null : returnVal.SingleOrDefault().Drink;

Now if I didn’t have the Take(1) and just used SingleOrDefault(), LINQ would throw an exception if more than one object was returned.  I would have thought it would have just returned the top result.  Another thing that acted weird in my opinion is when I would use just Single().  If it didn’t have an object to return, I would expect a null returned.  Not the case.  It returned a nice exception instead.  I’m not sure yet about the SingleOrDefault() return as well.  I think my object IDs will have an ID of 0.  If this is the case, it is very easy to tell.

Now to make this application actually be WPF instead of just looking like it is WPF.  I have to get with the times and figure out how to do a proper Model-View-ViewModel application first.  I did find a sweet WPF library by Kevin Moore (http://j832.com/bagotricks/) called The WPF Bag-O-Tricks.  I’m thinking I’m going to use his Grid since the animation style I want is already built into his.

Also a nice gentleman from across the pond, Ross Dargan (http://blog.the-dargans.co.uk) came up with a different way of doing the SQL call to return all items the system can currently make.  I did learn a few things about SQL which could make my query a bit cleaner but I think the two queries are about the same.

What drinks can you make?

Hardware is fun but can’t do anything without the software to power it.  But getting important data can be hard.  Why is the query for getting all the drinks the system can make with what it has on hand hard?  Because you can have drinks that are possible based on substitutes.  An example of this would be if my drink requires Grey Goose Vodka but I only have Smirnoff, I still should be able to get the drink.  This requires a logic that seems normal for us but it a bit hard to express in SQL.

First, here is my database layout that is prevalent to this post.  I will be renaming AlcoholType to IngredientType also.

image

 

Lets take this in multiple parts.  First we need all the ingredient IDs of what the system has on the hookup table or is a valid substitute.  Once again, an example of this is if the system has Vodka, I should be able to make any drink that has a vodka ingredient type.

SELECT * FROM
	ingredients i
	INNER JOIN AlcoholTypes a ON i.AlcoholTypeID = a.AlcoholTypeID
	LEFT JOIN hookups h ON i.IngredientID = h.IngredientID
	where
	(
		h.hookupid IS NULL AND i.AlcoholTypeID IN
		(
			select a.AlcoholTypeID from 
				ingredients i
				INNER JOIN AlcoholTypes a ON i.AlcoholTypeID = a.AlcoholTypeID
				INNER JOIN hookups h ON i.IngredientID = h.IngredientID
		)
	)
	OR
	(
		h.hookupid IS NOT NULL
	)

The left join on the hook up table will let me know which ingredients aren’t actually in the system.  By seeing which don’t have a hookup ID, I can then do another query where the ingredients are not in the hook up table but are valid substitutes based off the ingredient type.

Here is a sample output from this query with these items in the hookup table:

The system thinks it has Jim Bean, Cola, Orange Juice, and Smirnoff in it.  As you can see, I get back Grey Goose and Costco vodka as well since I have Smirnoff too even though they aren’t hooked into the system.

image 

This then leads to this monster.  There is a small tweak from the query above to get this to execute.  I couldn’t use all the IN’s and had to switch to EXISTS in SQL so this lead to a small tweak in how the query looks.

SELECT * FROM drinks
WHERE drinkid NOT IN
(
	SELECT dr.drinkid FROM
	DrinkRecipes dr
	WHERE NOT EXISTS
	(
		SELECT * FROM
		ingredients i
		INNER JOIN AlcoholTypes a ON i.AlcoholTypeID = a.AlcoholTypeID
		LEFT JOIN hookups h ON i.IngredientID = h.IngredientID
		WHERE
		(( h.hookupid IS NULL AND EXISTS
			(
				select a.AlcoholTypeID from 
				ingredients ii
				INNER JOIN AlcoholTypes a ON ii.AlcoholTypeID = a.AlcoholTypeID
				INNER JOIN hookups h ON ii.IngredientID = h.IngredientID
				where i.AlcoholTypeID = a.AlcoholTypeID
			)
		) OR ( h.hookupid IS NOT NULL ))
		AND dr.IngredientID = i.IngredientID
	)
	GROUP BY dr.drinkid
)

And with the same items above, here is what I can make with the limited test data I have.

image

Now that I do have this logic, I bet I could make this query into a LINQ statement …  And yes, I’m betting there is a better way to do this in SQL.  If there is, please do tell.

I did my querying in Microsoft SQL Server Management Studio which you can get with the Express SKU and the database map was done with Visual Studio which you still should be able to do in Express

New style bottle mount

SDC10155I came up with this style actually on the way home from an event last week.  It helps solve a few major issues.  It will allow gravity to drain the liquid in it, it is small and compact, and is an all-in-one design.

Doesn’t it look nice?  Parts from 3 separate vendors but it seems to work.

And now on a Jameson bottle.  To make this function, cut a cord to length and attach it to the bottom.  Then attach an airline to the right, and the out tube to the top.

SDC10153

LINQ to SQL, taking the pain out of SQL

I’m not a SQL man.  I never liked it in the slightest.  It always seemed like a ton of work having to create the c# then the SQL duplicating the failure logic.  Just seems like a lot of extra work.

So after you’ve created your database, you can then do all your heavy lifting in LINQ and c#.  Why is this nice?  You’d have to create all the code anyways to get to SQL.  You can still have your stored procedures and views within LINQ to SQL as well.

Here is some sample code for getting a single item back.

public static User Get(string Name)
{
	var user = Context.Users.Single(u => u.Name == Name);

	if(null == user)
		throw new KeyNotFoundException("No user found");

	return user;
}

And for updating / inserting:

public static bool Upsert(string Name, string RfId, string BluetoothId, int Id)
{
	using (var db = new DrunktenderDataContext())
	{
		if (Id > 0)
		{
			var user = db.Users.Single(u => u.UserId == Id);
			user.Name = Name;
			user.RfId = RfId;
			user.BluetoothId = BluetoothId;
		}
		else
		{
			db.Users.InsertOnSubmit(
				new User
					{
						Name = Name,
						RfId = RfId,
						BluetoothId = BluetoothId
					}
				);
		}

		db.SubmitChanges();
	}

	return true;
}

Challenge and new parts

I semi got a kick in the butt when I found out that Nick Pegg (twitter: nickpegg) at Missouri University of Science and Technology was building a bartender as well.  Looks like we’ll be doing a little challenge for who’s is better designed from hardware to software.  From the video, sounds like his runs on pumps, mine is pressure based.

His bartender prototype:

 

My bartender prototype:

Due to this challenge, I’ve decided it was in my best interest to order some more parts to get this puppy built 100% again.  So I ordered 3 more valves from McMaster Carr (part # 5489T633) (Polycarbonate Solenoid Valve W/ Tube Conn EPR Seat, for 1/4" Tube OD, 80 Max PSI, 24 VDC) so now I’ll have 10 food grade valves and I also ordered more stoppers and connectors from US Plastics and Home Science Tools.  I’m seeing if I can’t come up with a better way of doing the liquid containers also.  I bought some test parts for testing out a new way of doing this.

Mounting a hard drive on my laptop

I got a portable hard drive and ran into an issue of being afraid to move my laptop while it was running.  I also almost had it drop while giving a presentation which would have been a very bad thing as it was running 2 virtual machines at the time.  This had to be fixed ASAP.

With about $4 worth of 3M removable poster mounting Velcro, I was able to mount it and remove it if I chose to.  Here are some pictures.

Laptop Hacking Laptop Hacking Laptop Hacking