Friday, December 30, 2011

Sous-vide gyros

I tried to make gyros today - 1 lbs ground lamb and .75 lbs ground pork, small onion plus basic spices in the mortar (marojam powder, rosemary, garlic powder, tiny piece of clove, a hint of paprika, oregano, greek seasoning (oregano, msg, etc.), juice from one lemon - I forgot the ground black pepper...). Processed quite a bit in my food processor to change the texture.

The first use was just to fry some of the mixture in the frying pan - it came out OK. I didn't have a wrap to put it in so I just ate it with store made tzatziki (which was actually pretty good). The texture was OK but lacking in flavor (not enough fat in the meat is at least part of the problem).

Since I was already sous-vide'ing a Jamacian skirt steak at 131F (trying for a much longer cooking time to see if it will help break down the tasty skirt steak), I came up with a plan to sous-vide some of the mixture for my second course. This turned out pretty interesting. If you put a scoop of the mixture in a plastic bag, and then make a .25" flat "patty" about the thickness of gyros meat but filling up the entire bad. After cooking for 45 minutes, it retained it's shape and I cut it into 2x5" strips. I finished those strips on a really hot grill for a minute a side.

Flavor wise, no improvement but it was pretty interesting that I was able to get the shape to be like a sub-shop gyro.

I put a couple of bags of the mixture into bags as before and threw them into the freezer - figure I'll have gyros later in the week (they just need a little more time in the water bath to defrost).

Next time I will try a 80/20 beef plus lamb mixture and more spices (especially garlic and maybe allspice and other ingredients I saw in some of the recipes).

Sous-vide eggs

I tried my first sous-vide eggs yesterday - 144F for 45 minutes - crumbled seasoned seaweed and a little soy sauce. The whites were a little under-cooked, but the yolks seemed about right. I think next time I'll try 146 for 35 minutes and then cheese and a buttered English muffin.

Wednesday, October 19, 2011

How Lisp Programmers View the World




I couldn't help but improve the graph from someone's Haskell post. http://neugierig.org/software/blog/2011/10/why-not-haskell.html

Sunday, September 25, 2011

Easy Pasta Meta Recipe

I'm not an expert cook, but here is a meta-recipe for tasty pasta (for when
simple marinara sauce is not enough).

Start by sautéing olive oil (or butter), onion, and garlic. Add a little red
pepper flakes if you like a little heat.

You can optionally deglaze this with white wine, dry vermouth, or even Vodka.

You can add any Italian herbs like basil, oregano, thyme, etc. that you have on
hand. Rosemary seems like it might be too perfumey - I think it is supposed to
be used with red-meats and grilling.

You can add any Mediterranean ingrediants pretty much - green/black olives,
artichoke hearts, sun-dried tomatoes, diced tomatoes, chicken, suasage, capers, pine-nuts, anchoives, etc. You probably want to cook the meats first and then add them unless they are really small pieces (and even then).

I almost forgot about other vegetables. Sweet peas and snap-peas seem to go well with creamy Italian pasta. I'd probably stay away from green/red peppers and most leafy greens (except perhaps spinach). You can always pair the pasta with a nice fresh salad in which case green and red peppers and all of the leafy greens can be put to good use.

You can also add near the end cheese (Parmesan, goat cheese and possbily just
cream cheese). I'm not skilled enough to make a good alfredo sauce and all the
ones I've tried in from a jar have not be very pleasant tasting.

And of course finish with salt and pepper (always freshly ground) to taste and
then put over pasta (which you can throw right into the pan if you want).

Saturday, September 24, 2011

Roles versus Capabilities

Fine grained capabilities are the right code-level abstraction for writing any security checks but most people do it wrong by testing for "roles" instead of the underlying capabilities that should be assigned to roles which a user may or may not have.

In Java pseudo-code roughly what I'm talking about is:

WRONG!

enum Role { CUSTOMER, DIRECTOR, CEO, PEON, ADMIN, CEO_ADMIN}

if (user.hasRole(Role.DIRECTOR) || user.hasRole(Role.CEO)) {
createNewEmployee();
} else {
// Leaving this bogus error message in because I only caught it after the fact.
throw new AuthorizationException("Only directors can create new employees");
}

versus:

GOOD!

enum Capability { CREATE_NEW_EMPLOYEE, CREATE_STACK_OF_PAPER, .... }

if (user.can(Capability.CREATE_NEW_EMPLOYEE)) {
createNewEmployee();
} else {
throw new AuthorizationException("User not authorized to create a new employee");
}

The second one is way easier to write, reason about locally, and is ultimately way more flexible. Pushing the decision into the user abstraction isolates the "what can this user do" into the user object instead of all over your code based on what the code is trying to do rather than by roles which you will find need to be fluid over time. For example, in a capability based system, it becomes possible to create brand new roles without changing code anywhere except perhaps in your user object.

Actually, it is deeper than that. Most capabilities should be "read-capability" versus "change-capability". In the capability model, you should automatically create at least two different capabilities and protect the read versus write capabilities. (Generally the write capability should also require the read capability though I'm sure there are strange cases when this is actually OK). The full CRUD model would require 4 bits per fundamental operation though if I allow you to write something, I pretty much give you most of the abilities to create and delete it. (Auditing is a good thing to have in place of course. Separate blog post.)

Roles are OK as symbolic names to represent a set of fine-grained capabilities and allowing a user to have one or more roles is a fine concept (and you just need to union the underlying capabilities to produce a denser in memory storage for a single users capabilities - binary is nice!). In many systems that span a single company, you may only need a single definition for each role but if you are writing software that is supposed to meet the needs of different companies (or different subsidiaries), each company can allow fine grained control over the symbolic roles. In some companies, a CEO_ADMIN role can create new employees and in some others they can't. The capability based approach allows these distinctions quite naturally, the role based approach with global roles doesn't. With the capability approach, your software may eventually provide the ability for a particular person like Steve Jobs to "lend" capabilities to someone else (perhaps with a timeout). Again, you won't have to change 1000 places in your code to create the lend concept, only enhance the user object.

I think I know why I see the WRONG! version of the code so often. When the product designer creates the stories for developers, they create different roles as an abstraction to think about what types of users are using the system. Designers may have to think about security as a matter of law (HIPPA) or as more of a practical customer desire. Developers latch on to this and then code to those roles and then balk later when the implementation team talking to particular customers ask for something different.

It's just so obvious that a capability based approach plus per use capabilities (which can be based on the union of symbolic roles the user has) is the right strategy, that it makes me cry when I see role checks in code.

(BTW, of course you can make both the WRONG! version and the GOOD! version of the code tighter by having a method on either the user or the Role called ensureXXX() which would do the test and throw an exception if it fails.)

Is there a cost to the capability approach the role based approach doesn't have? I don't really think so. In Java on a 32 bit machine, a single role represented by an enum will typically be implemented by a 32 bit field. That itself is 16 read/write capabilities. If you have a user object kicking around, you've probably also read in their username (at least 8 * 8 bits plus 32 bits for string length), real-name (at least 10 * 8 bits plus 32 bits for the string length), userid (64 bits), phone-number (10 * 8 bits plus 32 bits for string length), and maybe even more stuff like their birthday (32 bits), start-date (32 bits), etc. That's already something like 416 bits or 208 capabilities if you just double the amount of storage you use for this structure you've never worried about passing around before). So you went from maybe 52 bytes to 104 bytes. So what? You can almost afford to assign every form-field in your system its own read/write capability and it still won't clog up your memory however you don't want to do that because then managing the sheer number of capabilities becomes harder (it's better when each one has a sharp name and precise meaning). Do your own math. Packed bits are cheap.

(Capabilities becomes even more interesting in distributed systems when you can sign them and pass them around. Andrew S. Tanenbaum after creating the progenitor of Linux and there's lot of other great research on this topic.)

Thursday, September 22, 2011

How much RAM do you need?

My rule of thumb on how much memory to have could be num-cores * num-gighertz Gb. So a typical four-core workstation should have 12Mb. My two core smart-phone should have 2Gb but only has 512Mb.


Wednesday, July 13, 2011

Rusted Closet / Toilet Flange Fixit Tip

Mine looked basically like this:


But this thread is so wrong in the advice that they give. Since it was so rusted, it was relatively easy to cut the old one out with a dremel tool and remove it. This leaves the unrusted PVC drain pipe about 7mm off the floor. Then, if you go through the aisles of Home Depot (I couldn't find it on their online store - strange), you can find a two piece closet flange which you can just slip underneath the PVC pipe. The two pieces are joined together using the same uprights that you attach the toilet to. The only downside for my repair is that only two of the six holes in the replacement flange were in spots that the old one wasn't - and the other ones were basically unable to tigthen to the screw. I bet some kind of compound could be added to the holes where the screws were and give some bite to the screws.