Bitwise Operators

This started off as a post about using bitmasks with SceneKit for collision detection/notification but the explanation of bitwise operators became so extensive I’ll have to talk about how this ties to SceneKit in another posting.

To understand bitmasks and bitwise operations I think it’s essential to understand how binary numbers work, don’t worry it’s pretty simple.  As you know a computer is a digital device which means it basically is on or off and at its lowest level that is how all data is stored, a one or a zero.  This unit of data (a single one or zero) is called a bit.  Obviously there’s not much you can do with just one bit when it comes to representing numbers but when you combine 8 bits you get a byte and now you can start representing things, such as any number from 0-255.

Here’s how that works – when you have a byte with a series of 8 bits that are one or zero imagine it like this: (Think of these as 8 ‘lanes’ of bits.)

bitwise_zero

That is a zero, nothing is going on here.  Now what if we change the bit on the right to a 1? (you will need to learn to read these right to left)

bitwise_one

This is now representing the number 1.  So if we turn on the next bit what do we have?

bitwise_three

You know what that is? It’s a 3.  But why?  You remember how I mentioned thinking of these a ‘lanes’, well imagine each lane has a number assigned to it, starting at the right and working to the left:

bit_lanes

Notice we numbered the lanes by doubling the previous value, also notice if you add the lanes at are ‘on’ (lanes 1 and 2) you get 3.  Using this you can also represent a two like so:

bitwise_two

Using this we can see the largest number we can represent with 8 bits is 255:

bitwise_255

That is an 8-bit, unsigned (all positive, no negative) integer value.  You can see where increasing the number of bits can improve the representation, for example a 16-bit integer would be able to represent numbers up to 65,535 – yeah that escalated quickly.

Lane #:                 32768  16384  8192  4096  2048  1024  512  256  128  64  32  16  8  4  2  1
What cool stuff can you do with this knowledge? Well as you noticed, the lane numbers double each time so by ‘shifting’ right or left you get quick multiplication and division, for example if you have 2:

bitwise_two

Now, if we move all those bits to the left by one, you get 4:

left_shift

Note that any numbers shifted beyond the bounds of this variable (in this case an 8-bit unsigned integer) will be discarded in Swift.  So shifting 128 left by one makes it zero.

Inversely, you can also right shift.  For example, if you have 16 and shift to the right by 2 you end up with 4:

right_shift_2

In Swift you can do something like this:

var a = 8 //a is 8

var b = a >> 1 //b is 4 (8 shifted to the right by 1)

var c = a << 2 //c is 32 (8 shifted to the left by 2)

You can also create a number with its binary representation:

var w = 0b00000010 //w is 2
Now, for more fun you can use bitwise operators like a bitwise OR which combines two numbers into a new one:

bitwise_or

As you can see, if a lane has a 1 in the first number OR the second, that gets put in the new number.

In Swift, it might look like this – notice the type of ‘UInt8’ and bask in your knowledge of what that means:

var y:UInt8 = 0b10000110 //y is 134

var w:UInt8 = 0b00000101  //w is 5

var a:UInt8 = y | w //a is 135

In addition to OR, you can use a bitwise AND operator, in which only lanes that have a 1 in both inputs will be carried over:

bitwise_and

Which in Swift could look like:

var y:UInt8 = 0b10000110 //y is 134

var w:UInt8 = 0b00000101  //w is 5

var a:UInt8 = y & w //a is 4

There is also an XOR operator and more things you can do with this  knowledge in Swift, and for that I will refer you to Apple’s documentation on Advanced Operators.  Now we have covered a low-level topic to work with a high level framework (SceneKit) I hope to post about how bitmasks come into play soon!

Advertisements
Bitwise Operators

Polymorphism in Protocols

I don’t remember exactly how I stumbled across this but thought it would be useful and maybe save someone else a few minutes of debugging.  It’s also great to know how this bit of polymorphism is handled in Swift.  If you create an object that conforms to a protocol method that is overridden you can still access the overridden behavior by specifying the protocol.  That sounds more complicated than it is, just take a look at this trivial and contrived code:

ext

Considering the push toward protocol oriented design I can only imagine this will be cropping up over time.

Polymorphism in Protocols

Automating Exports from PowerSchool

Recently we found ourselves needing to do an export from PowerSchool into Hapara.  There are two files to get up and going actually, a classes file with the usual information like teacher name, class name, etc. and a student file which is actually just their Google username (e-mail address) and the course name that matches the classes file.  Sure, you could just export course number, section number and termid but that’s just not very friendly to look at.  So I decided that with a little SQL we could export the course name and a term name (S1, S2, Year, etc).  Using the very excellent sqlreports4 plugin I put together a select with a few joins (and a pyramid of doom style term naming piece that removes spaces and slashes from course names):

 SELECT
replace(replace(replace(replace(Courses.course_name || decode(Sections.TermID,2501,’S1′,decode(Sections.TermID,2502,’S2′,’Year’)), ‘-‘,”) || ‘-‘ || Sections.section_number || ‘-1516’, ‘ ‘, ” ), ‘/’,”), ‘,’,”) as mailbox, replace(replace(replace(replace(Courses.course_name || decode(Sections.TermID,2501,’S1′,decode(Sections.TermID,2502,’S2′,’Year’)), ‘-‘,”) || ‘-‘ || Sections.section_number || ‘-1516’, ‘ ‘, ” ), ‘/’,”), ‘,’,”) as calendar, Teachers.email_addr, Courses.course_name, ‘any’, replace(replace(replace(replace(Courses.course_name || decode(Sections.TermID,2501,’S1′,decode(Sections.TermID,2502,’S2′,’Year’)), ‘-‘,”) || ‘-‘ || Sections.section_number || ‘-1516’, ‘ ‘, ” ), ‘/’,”), ‘,’,”) as calendar,  ‘any’, Sections.SchoolID
FROM
 Sections
JOIN
 Courses
ON
 Sections.course_number = courses.course_number
JOIN
 Teachers
ON
 Teachers.id = Sections.teacher
WHERE
 Sections.termid >= 2500
AND
 Sections.termid < 2599
AND
 LENGTH(TRIM (Teachers.email_addr)) > 0
AND
 Sections.SchoolID = 100

 

We have some vo-tech classes that are taught at the local community college and the teacher for that course varies by semester and content so the TRIMing is in there to make sure those courses don’t get imported (or any course with a teacher without a valid e-mail address).  Removing this AND section is good for debugging just to make sure a class doesn’t get excluded because the teacher info is missing their e-mail address.

This worked fine for the high school (SchoolID=100) but then came the problem of what about adding a class or two at a different school?  Well, we could just manually include those but that seems like a hack.  A more elegant solution would be having a checkbox on the sections page that you can simply choose to include or exclude that section from the upload.  In this vein I created a boolean database extension with a one-to-one relationship to the sections table.  Then with a few lines of HTML added the checkbox to the edit sections page.

Screen Shot 2015-08-30 at 4.51.02 PM

Of course I had to pre-populate that field for all the high school courses, I just used the data export manager and took all sections at the high school in the current year, exported the SectionsDCID field to a text file, added a column for the include flag (1) in Excel and imported that back into PS into the new DB Extension table.

Now we can use this SQL statement:

 SELECT
replace(replace(replace(replace(Courses.course_name || decode(Sections.TermID,2501,’S1′,decode(Sections.TermID,2502,’S2′,’Year’)), ‘-‘,”) || ‘-‘ || Sections.section_number || ‘-1516’, ‘ ‘, ” ), ‘/’,”), ‘,’,”) as mailbox, replace(replace(replace(replace(Courses.course_name || decode(Sections.TermID,2501,’S1′,decode(Sections.TermID,2502,’S2′,’Year’)), ‘-‘,”) || ‘-‘ || Sections.section_number || ‘-1516’, ‘ ‘, ” ), ‘/’,”), ‘,’,”) as calendar, Teachers.email_addr, Courses.course_name, ‘any’, replace(replace(replace(replace(Courses.course_name || decode(Sections.TermID,2501,’S1′,decode(Sections.TermID,2502,’S2′,’Year’)), ‘-‘,”) || ‘-‘ || Sections.section_number || ‘-1516’, ‘ ‘, ” ), ‘/’,”), ‘,’,”) as calendar,  ‘any’, Sections.SchoolID
FROM
 Sections
JOIN
 Courses
ON
 Sections.course_number = courses.course_number
JOIN
 Teachers
ON
 Teachers.id = Sections.teacher
LEFT JOIN 
 U_DEF_EXT_SECTIONS s2 
ON 
 Sections.DCID = s2.SectionsDCID
WHERE
 Sections.termid >= 2500
AND
 Sections.termid < 2599
AND
 LENGTH(TRIM (Teachers.email_addr)) > 0
AND
 s2.upload = 1
Screen Shot 2015-08-30 at 4.48.50 PM
The report nicely exports as a CSV file in the required format! The real beauty of sqlReports though is the ability to use sqlExports to automate a query to run at a set time each day and upload to an FTP server.  Which is exactly what is done with the student data:
SELECT
ps_customfields.getstudentscf(Students.id,’student_email’),
replace(replace(replace(replace(Courses.course_name || decode(cc.TermID,2501,’S1′,decode(cc.TermID,2502,’S2′,decode(cc.TermID,2503,’Q1AS’,decode(cc.TermID,2504,’Q2AS’,decode(cc.TermID,2505,’Q3AS’,decode(cc.TermID,2506,’Q4AS’,’Year’)))))), ‘-‘,”) || ‘-‘ || cc.section_number || ‘-1516’, ‘ ‘, ” ), ‘/’,”), ‘,’,”) as Class
FROM
CC
JOIN
Students
ON
CC.Studentid = Students.id
JOIN
Courses
ON
cc.course_number = courses.course_number
JOIN
Sections
ON
Sections.id = cc.SectionID
LEFT JOIN
U_DEF_EXT_SECTIONS s2
ON
Sections.DCID = s2.SectionsDCID
WHERE
CC.TermID >= 2500
AND
CC.TermID < 2599
AND
s2.upload = 1
You get a nice two column export that looks like this:
Screen Shot 2015-08-30 at 4.46.24 PM
This file is now ready to be picked up by a cURL script and uploaded to Hapara.  The best part is all you have to do is change a few termID’s in the SQL code from year to year to maintain it.  And you can always add a course and students later by simply checking a box.
Automating Exports from PowerSchool

Love the Auto Layout

Every year after WWDC I spend way too much time trying to catch as many session videos as I can.  This year the graphics stuff, SceneKit, Core Image, and Metal are the top of my watch list.  And of course there is this year’s breakout star of Old Crusty showing us all the ways of protocol oriented programming, which I’ve admittedly watched more than once and still continues to impress.  There’s so much good info out there that I sometimes miss the little things that really make life easier.  This is one of those things I missed at first, probably a ‘duh’ to most people and if that’s the case for you then hello back button!

To preview your auto layout constraints right in Xcode/IB/Storyboards, (yes I use IB and I know you may or may not like that):

While in your storyboard on a view controller click the two circles to switch to assistant editor, aka the thing you use to drag outlets and actions from you IB objects to your view controller code:

Screen Shot 2015-08-03 at 8.37.25 PM

Now, instead of using the view controller, change to ‘Preview’ and select your storyboard to get a real preview of what your layout will look like:

Screen Shot 2015-08-03 at 8.37.40 PM

Now, click the little + sign at the bottom of the preview window and add another device (or all of them if you want) and get previews of those all at the same time:

Screen Shot 2015-08-03 at 8.37.47 PM

This is fantastic especailly now that we live in a 5 screen size world and makes moving old apps to Auto Layout kinda fun.

Screen Shot 2015-08-03 at 8.38.23 PM

Love the Auto Layout

Wheat Brew Redux

A few months back I brewed a wheat ale, using DME, Wilamette and Cascade hops, and US-05 yeast.  It fermented for just over two weeks, was kegged and started pouring a week later.  The general consensus seems to be that it is okay; not awesome, not awful, but okay.  By beer snob standards it was definitely weak but palatable.  The ironic thing is that I brewed this to ease people used to the usual into trying homebrew but those people remarked that it “had a lot of flavor”.  I was disappointed of course, the brew I hoped would have cross-palette appeal seemed to have none.

With that in mind, I decided to do what any homebrewer does and add more hops! Approximately two weeks ago (May 14th) was brew day but this time with 0.5oz more of Cascade hops in the last 15 minutes of the boil and then another 0.5oz of Cascade pellets in the primary fermenter after a week.  Yep, it’s a dry hopped American Wheat.  

After researching dry hopping, I came to the conclusion that it seems best to add the hops after high krausen.  During high krausen there is a lot of CO2 escaping which could carry away that fantastic aroma we are trying to keep in.  The obvious concern is risk of infection when putting anything in the brew post-boil.  At least I thought, turns out everyone pretty much says not to sweat it because after a week or more of fermentation the alcohol will keep the nasties at bay.

Here’s the recipe, it’s changed up just a tad on the pale malt/wheat malt ratio and had a fresh pitch of US-05:

  • 4.2lb Bavarian Wheat DME
  • 0.75lb Pale DME
  • 1oz Wilamette for 60 min
  • 1.5oz Cascade for 15 min
  • 0.5oz Cascade dry hop addition after 10 days
  • US-05 (not rehydrated)

The fermenter was put in the basement on the concrete floor, I’ve never fermented in this part of the basement before and it’s a little cooler than the previous spot.  In addition, this wort was chilled prior to pitching much more than the previous batch.  Those factors meant that fermentation did not take off like a rocket that night, but it did blow out the airlock after 4 days and there’s quite a sediment layer on the bottom of the carboy, maybe the most I’ve had on any brew so far.  The dry hops were added after 10 days, directly to the primary fermenter.

The brew was kegged after 16 days in the fermenter, and then put in the fridge on CO2.  After about three days I poured a sample which was of course very lightly carbonated, the smell was very citrusy and the brew was a little cloudy but overall pretty clear.  That first taste and whoa, I think I could have told someone I squeezed a grapefruit in that glass!  To be honest, that was something I expected, apparently lots of Cascade hops added dry leave their mark in the form of a grapefruit experience.  After a few weeks the flavor has mellowed to a much more manageable amount, the IBUs are low and the body is light but the citrus-ness of the brew is still there and the finish is pretty clean, which I’m attributing to the US-05 yeast.  

Overall, this is a nice brew to have on hand now that the temperatures have hit 90.  I did not harvest the yeast this time as I’m not sure that I will be using this strain again for a long while, I think I much prefer the hefeweizen yeast strains or maybe even a saison yeast with the bit of funkiness they bring to the brew.

Wheat Brew Redux

First Recipe

I wrote this post right before the brew day but it was late so I did not publish it, the actual brewing was completed on February 13, 2014.

There comes a time when the home brewer has made enough kits and read enough that we decide (for better or worse) it’s time to try our hand at creating a recipe.  After all, what fun is having total control over the process if you’re just following directions?  After recently stepping up to 5 gallon batches and partial mash I decided the time had come to attempt it.  After tossing around a few thoughts on what would be a good first recipe I settled on an extract based wheat with 2 classic hops.  Sound boring? Well, I wanted something I could offer to everyone, something that would have mass appeal and I stuck with all-extract to keep it simple.

For the most part all I could find in the DME variety was Bavarian Wheat, but I wanted to make an American Wheat, not a hefeweizen.  So after reading I discovered that the Bavarian Wheat DME has a ratio of 65% wheat to 35% barley.  Most of the American Wheat recipes I saw used a ratio around 55% wheat to 45% barley.  In order to bring the ratio where I wanted it, I also picked up some Pilsen Light DME which is 100% barley.  After some calculations I arrived at 4.2lbs of Bavarian Wheat and 0.6lbs of Pilsen Light which brought the ratio to around 57% wheat and 43% barley.  As a side note, if you look up American Wheat recipes you will find it can be pretty broad but it’s generally agreed that there is less wheat than a hefeweizen and they generally lack that ester flavor of the German yeast; but like anything else there are plenty of delicious sounding hybrid recipes.

As for hops, I am going to stick with some classic American styles: Cascade and Willamette.  As a bonus, these hops are easy to find and not expensive.  According to Qbrew: Willamette has an earthy, spicy character and Cascade has a grapefruit aroma and flavor.  Playing with Qbrew, I decided that boiling 1oz of Willamette for 60 minutes and 1oz of Cascade for the last 15 put the IBU’s at 23 and will hopefully give me the citrus aroma without an overwhelming citrus taste.  Since I probably won’t be doing a full 5 gallon boil the actual IBU’s will likely be lower (see below) but I haven’t decided if I want to increase the hop amount or stick with the easy to remember 1oz. of each measurement. 

For yeast, I’ll be utilizing the Safale US-05 I harvested from a recently kegged brown ale.  As stated earlier, another key difference between a hefeweizen and American Wheat is the yeast, while I like the banana, clovey flavors of a hefe this will be a bit tamer.

Some things I learned which might be useful to others include converting from LME to DME.  Many recipes, especially those aimed at a beginner use LME instead of DME, to convert just multiply the LME amount by 0.8.  For example if you see a recipe that calls for 6lbs of LME, that equates to 4.8lbs of DME (6 * 0.8 = 4.8).  Another thing to consider is boil size, many ‘easy’ recipes tell you to boil only 1.5 gallons and while this does let you get the wort chilled very rapidly when you pour it on 3.5 gallons of cold water, you will lose bitterness and your wort will be darker due to the smaller boil size.  Honestly, I’ve not attempted a full boil because I don’t have a wort chiller but I will boil 3 gallons and have the other 2 very cold to get the temps down.  If all you have is a 2 gallon pot you can still make quality brew, just watch for boil overs.  Another tip, a spray bottle works great for taming boil-overs.

First Recipe

Adventures in Yeast Harvesting

Something I’ve read about but never had the courage to venture into with my home brewing is yeast harvesting.  The intricacies of yeast bring to mind visions of a lab coat, flasks, and warming plates.  I’m lucky enough my wife lets me brew in the kitchen so I though I shouldn’t push my luck.  After reading enough about it I decided to round up a couple of mason jars and give it a shot.

ImageI use a glass carboy as my primary fermenter, I know glass has downsides but I like glass (that’s another blog post).  Anyhow, the nut brown ale was ready to be transferred out and lucky for me it used the always versatile Safale US-05.  The night before I took two mason jars and boiled them to sterilize them and their lids.  Then they were filled with boiled water and let it fall to room temperature overnight.  The next day, after racking, I left just a bit of liquid to slosh the yeast cake into a muddy looking mess.  I sprayed the neck of the carboy with sanitizer and poured the clean water from the jar into the carboy.  That liquified the whole thing and I poured it into the now empty jar.

ImageI then placed this muddy looking mess in the refrigerator for a couple of hours.  I did not take a picture of it but it looked similar to those classic cutaways of the Earth, with the striations.  I then opened the jar and poured off the liquid layer at the top.  After that, I opened the other jar and poured the middle layer (yeast in suspension) into it and tried to leave most of the trub at the bottom behind.  Then it was back to the fridge for a couple of hours.

ImageThis is the resulting jar, you can see it’s pretty much just liquid and yeast.  I may try to rinse it but my fear of contamination makes me think I may just pour off most of the top liquid and dump the yeast into the American Wheat batch on deck.

I realize most people harvest/rinse saison, liquid, and generally something more exotic than a US-05.  While the idea of saving $4-5 per batch is appealing the main reason for me is that the nearest home brew supply store is better than an hour away.

Adventures in Yeast Harvesting