Thursday, April 11, 2019

Cardamom rice

I am in a Indian cooking mode right now, doing a ton of chana (chickpea) dishes.

This is my current favorite "base", just a simple rice.

Full vegan (but still, no crossfit).


  1. Throw a small dollap of coconut oil in a saucepan, medium heat
  2. 1 cup Jasmine rice in said saucepan. It's a whole new world
  3. 1 tablespoon garlic in there as well.
  4. 1 teaspoon ginger. My local schmaldi sold ginger-in-a-tube and I bought all of them. This has been transformative to my cooking, as cutting ginger into appropriate sizes is a PITA to me (but I still do it. Ginger, I can't quit you).
  5. Healthy shake of ground cardamom. Maybe someday I use real cardamom pods. One can dream...
  6. Some season salt.
  7. Stir a bit, Let cook for 2-3 minutes. Burn rice, BURN! (I kind of like the blackened bits when all is said and done).
  8. Put in 1.5 cups of water. Stir, so the blackened bits at the bottom are not fully stuck to the pan.
  9. Jack up the heat to boil
  10. When full rolling boil, turn down the heat to simmer, 1 final stir & cover.
  11. Ask Amanda to set a 20 minute rice timer.
  12. When done, uncover, stir, enjoy!
This worked really well with my lunch chana masala yesterday. The kinder devoured it as well, with fake Doritos.

Tuesday, April 9, 2019

Vegan avocado cream sauce

Old joke: If you were a vegan who did crossfit, what would you talk about first?
I'm neither, but found this recipe delicious. The kinder devoured it as well.
  1. 1 large avocado
  2. tablespoon of garlic
  3. tablespoon of basil pesto
  4. small handful of cherry tomatoes
  5. healthy squirt of lemon juice
  6. salt, pepper, Italian seasoning
  7. glug of olive oil
Throw in a food processor & puree. Chunks of tomato will be left over. Admire their redness.

Toss over some pasta. Throw some Parmesan cheese on top. 

I haven't tried it yet, but I bet this would be lovely with some toasted pine nuts

or (better yet) saute some asparagus in butter just enough so that it's still crispy, toss pasta over the asparagus and then throw on the creme sauce.

Totally vegan, so +100 points from those who are keeping score.

Friday, April 5, 2019

The quest for the perfect hard egg

I love hard eggs. I'm a 49 year old man, and I love hard eggs. I have one for breakfast every damn morning. Along with French press coffee. So much French press coffee...

Notice, that I said hard eggs. Not hard boiled. I take great delight in annoying those around me (especially my wife) in my quest for precise language. I was going through a period where my hard eggs were done in my bamboo steamer, after I breakfast on a trip to Guangzhou. Thus, hard eggs, with no unnecessary information about how the hardness is achieved.

Sadly, I burned the hell out of my steamer (I need to pick another one up, loved that thing). No amount of staples could bring it back to life, so into the garbage it went.

Anyway, I'm still on a quest for the perfect hard egg. My current quest has me at

https://food-hacks.wonderhowto.com/how-to/make-amazing-hard-boiled-eggs-are-easy-peel-0154519/

where I'm picking and choosing what parts I of the recipe I want to follow based on just how lazy I am.

Trying

  1. Splash of baking soda. Not a teaspoon like mentioned. I'm seriously too lazy to measure that, or anything else, to be honest. In my mind, this is "half a glug". 
  2. I didn't warm my eggs. I can see future Kevin doing that, as he is informed by historical Kevin.
  3. Now that we have a functioning refrigerator with an ice maker, I don't feel like I'm wasting valuable resources making an ice bath (like a frickin' Rockefeller). So we do that too.
I'm not shaking an egg or otherwise centering a yolk. I'm not doing any pinprick crap. Ain't nobody got time for that.

Here's hoping for the perfect egg.

Thursday, April 4, 2019

Tidying up a project - safe refactoring rules

With 6 kids (!) that I love with every fiber of my being, I'm used to rooms being a bit of a mess when I enter. Therefore, I try to lead by example and:
"Make the space better for me having been there"
Which means, depending on where I am, I wipe down the sink in the bathroom, put a dish or two in the dishwasher, etc. Of course, any child within earshot, when appropriate, gets a "everything on pause, come help me with this..."

And, like all rules, there is nuance. When we're out the door for a thing in 2 minutes, I don't do this. Everybody needs to stay on task. I'm not going to distract from the shoe tying & coat buttoning to get "the dang toys off of Bruce (our table, don't ask) and into a bin!"

Likewise, when I open up a C# programming project - .sln in Visual Studio - to do a thing, I will accompany that thing with some refactorings that feel generally safe.

Nuance: I calculate the days to when this code will hit my production environment (the bake time). If we're below my comfort zone, I do not do any of these steps. I don't have a hard cutoff for comfort zone, and much of it depends on the project. When we're talking hours to prod and not days or weeks, my comfort zone is a little on edge, so I say skip these. From one of my favorite writings
"vi. Break any of these rules sooner than say anything outright barbarous." - George Orwell
Ok, enough with the boring. Onto my rules
NOTE: I'm nowhere near as good of a C# developer as I am C++. These rules are going to change for me over time. Also, the point of this is to not proscribe a set of rules for the reader, but to get you thinking in terms of what are YOUR safe refactoring rules.

My Safe Refactoring Rules


Definitions

  • TEST projects are C# projects (.csproj) that contain the unit tests, integration tests, smoke tests, whatever tests. The build artifacts produced do NOT run on production. The build artifacts produced by a TEST project are used to exercise the artifacts that DO run on production. 
  • PRODUCTION projects are the C# projects that produce build artifacts that DO run on production.

Rules

  1. Validate that all TEST projects are on the latest department accepted version of the .NET Framework
  2. Make sure that all projects are configured so that StyleCop style violations are errors, not warnings.
  3. Update all NuGet packages in TEST projects, except for the department documented "don't update" packages.
  4. For each .cs file that is modified, make sure that unnecessary using statements are removed.
    • Visual Studio has a function under Edit / IntelliSense / Organize Usings / Remove Unnecessary Usings. I have muscle memory around alt e i o r.
  5. For each .cs file that is modified, sort your using statements.
    • Visual Studio has a function under Edit / IntelliSense / Organize Usings / Sort Usings. I have muscle memory around alt e i o s.
  6. If your PRODUCTION projects are developing NuGet packages, avoid updating dependent NuGet packages unless absolutely necessary.
    • Final choice of the proper version consumed should be up to the application, not the NuGet package.
    • NuGet package dependencies here are an expression of "what interface do I expect."

Deets

I want to go into a bit of detail about each of the choices.

1. Update .NET Framework

Developers should be familiar with how to update the target .NET Framework and not allow code to languish on an old framework version, like some kind of an animal. Tools like the Target Framework Migrator can help tremendously. 

2. StyleCop

While I can be annoyed at StyleCop, it's an "eat your broccoli" to me, as I think projects are generally better with StyleCop than without. 

I like StyleCop.Error.MSBuild to turn StyleCop warnings into errors, although it needs a hand modification to your packages.config file to turn it into a development dependency

<package id="StyleCop.MSBuild" version="5.0.0" targetFramework="net461" developmentDependency="true" />
lest a build choice on a package be injected into a downstream consumer that is not quite ready for it.

Sometimes this choice can cause me to have to fix more warnings-turned-errors than I'm comfortable with, so it may turn into scheduled work for the future.

3. Update all NuGet packages in TEST projects

Developers should be "watching the skies" for updates to NuGet packages, as stale packages can cause bugs (been there, done that). 

By doing this in a safe manner, where the only thing you may break are your tests (which would reject your build because you gate, right, RIGHT?) gets you in a good mindset.

If your department does not have a documented list of "don't update these" packages, then demand one. Better yet, create & champion one.

4. & 5. Fix yer usings

Using statements are happier when they are organized this way; I've spoken to them.

6. Be careful with package to package dependencies

While this feels like a weird one, as it's not a "do this" rule, but an "avoid this", I thought it was important to call out the difference between what a package dependency represents when developing a NuGet package and what a package dependency represents when developing an application.

While developing a NuGet package, you're selecting an expected interface by the version choices of your package dependencies.

If you find bugs with particular releases of your dependencies, then by all means, express that in your dependency ("Anybody that uses package FOOBAR version 3.1.5 or below is a FOOL and will get the BAZ race condition bug - Minimum expected version is 3.1.6").

Other than bugs, you should let the application be the final arbiter of what version of package they are dependent upon. When wearing the NuGet package developer hat, you can't determine the full context in which your package will be used, and the application may be combining your package with other packages written by other developers in interesting ways that require more control over dependencies.

Being as flexible as possible over dependent versions helps here.

Conclusion

Again, these are my rules, not yours. My rules will change over time as I get more seasoned in C#. The purpose of this is to get you thinking about what your "tidying up" rules might be so your projects stay fresh and moving forward.

Wednesday, April 3, 2019

FILE_FLAG_DELETE_ON_CLOSE, temporary files and tidying up your room

I'm sure most of you have a favorite CreateFile flag (I kid, I kid). Mine is FILE_FLAG_DELETE_ON_CLOSE and I've been using it in my software development career for many years, to great effect, IMHO.

I'd like to write a few articles to describe what it does, why it's awesome, and to present some frustrations with its usage as a challenge to library writers.

OVERVIEW

At the lowest API level, when opening up a file for reading or writing in a Windows process, your call will wind up in the CreateFile function. Actually, CreateFile does a ton more than just reading and writing - check out that MSDN link above - but for this article, let's just focus on regular disk files.

NOTE: The above link takes you to CreateFileW, which is different from CreateFileA. The W and A are Microsoft's way of distinguishing Wide (2 byte) characters from nArrow (1 byte) characters. Macros hide this from you in your C++ code, so your calls are all done using CreateFile without the W or A suffix.

Resolving to CreateFile is done whether the call originates from a higher level API like C++'s std::fstream, .Net's File.Open, whatever.

CreateFile has a number of flags that tweak behavior that can be bitwise OR'ed together in the 6th paramter called dwFlagsAndAttributes.

When you use the flag FILE_FLAG_DELETE_ON_CLOSE, this tells the Windows operating system to delete the file when all handles to it are closed.

In case you don't see it yet, this is super effective for temporary files that are created during process execution, where data has to live outside of the process and on disk for whatever reason (too big for process memory, needs to be accessed by an external process, library requires filesystem access to do it's thang, ...).

When you're all done with the temporary file, you need to tidy up your room, by getting rid of the junk piles on the floor.  To delete those files after usage (Mom says "clean your room... NOW!") instead of executing DeleteFile, you can just CloseHandle and let the operating system take care of it.

Now, here's the awesomeness: Think about what happens if your process is torn down by an exception, taskkill, whatever. You've never reached the line of code that calls DeleteFile, so you've left a mess.

<IMPORTANT>
If you use FILE_FLAG_DELETE_ON_CLOSE, the operating system will delete the file for you as it tears down the process.
</IMPORTANT>

As the operating system tears down a process for whatever reason, it iterates through all open handles and, effectively, calls CloseHandle one by one. Side effects of the CloseHandle, like honoring FILE_FLAG_DELETE_ON_CLOSE, are done.

Combining this with RAII semantics in code can make the resource of the temporary file automatically go away as soon as it is no longer needed, where the destructor of your temporary file management class closes the handle before the object dies, with the added safeguard that if something bad happens during your process execution, your file will still be removed.

NOTE: FILE_FLAG_DELETE_ON_CLOSE can't protect you against all events: a power outage or a well placed hammer strike on the CPU will not go through the operating system's process teardown routine. YMMV.

Next up, FILE_FLAG_DELETE_ON_CLOSE all the things! Where using this flag doesn't work well. Soon.