Gordon Ramsay Home-made Fish Fingers with a Chip Butty Application…Just because

There was no need for this post to exist or for these four hundred and thirty-eight (with brackets and other nonsense) random lines of C# code to even see the light of day. For some unknown reason, I woke up over the weekend and spent an hour watching Gordon Ramsay YouTube videos when I came across this amazing looking take on fish fingers with a chip butty:

The video somehow leads me to write the following code. I wasn’t trying to write anything particularly good (i.e. a gaming engine or anything reusable, per say), it’s just an hour or two of me sitting on my tod mindlessly coding to no exacting standards (i.e. it’s all in one file, doesn’t conform to my usual commenting/ordering standards, is horrendously formed and pretty damn awful). Essentially, just enjoy the ‘random factor’ of all of this; you’ll notice I throw in a tonne of exceptions because, in my head, Gordon Ramsay wouldn’t use simple boolean logic to denote if your choice was correct or not, he would throw massive exceptions all over the place (pretty sure this is how he would write his code).

Here it is, very much un-sanitised and untested:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Media;

namespace GordonRamseyCookingSimulator
{
    class Program
    {
        private static List<string> gordonSoundBites = new List<string>()
        {
            "gordon-clip-one.wav",
            "gordon-clip-two.wav",
            "gordon-clip-three.wav"
        };

        private const string WELL_DONE_SOUND_BITE = "well-done.wav";

        private static SoundPlayer player = new SoundPlayer();

        private const string GOOD_JOB_TEXT = "Good job, moving on...";
        private const string GORDON_DEMANDS_TEXT = "Gordon demands that you choose a {0}";

        private static Dictionary<string, string> complexOptions = new Dictionary<string, string>();

        static void Main(string[] args)
        {
            Console.WindowHeight = 60;
            Console.WindowWidth = 185;
            Console.ForegroundColor = ConsoleColor.Green;
            bool playFailSound = false, continuePlaying = true;

            WriteToConsole($"Let's make Home-made Fish Fingers and a Chip Butty with Gordon Ramsay{ Environment.NewLine }================================================================================");

            do
            {
                try
                {
                    MakeFishFingersWithAChipButty();
                }
                catch (Exception ex)
                {
                    Console.ForegroundColor = ConsoleColor.Red;

                    Console.WriteLine();
                    playFailSound = true;
                    Console.WriteLine("Gordon Ramsay looks upon you with shame. You have failed because: ({0}) - {1}", ex.GetType().Name, ex.Message);
                }

                if (playFailSound)
                {
                    player.SoundLocation = gordonSoundBites[new Random().Next(0, 3)];
                    player.Play();

                    playFailSound = false;
                }

                WriteToConsole("Play again (Y/N followed by enter)");

                continuePlaying = RetrieveTerifiedCooksChoice().Equals("y", StringComparison.InvariantCultureIgnoreCase);

            } while (continuePlaying);
        }

        private static void MakeFishFingersWithAChipButty()
        {
            Console.WriteLine();

            // Cook with the big man
            NavigateThroughThePotatoSelectionForTheButtyTest();
            NavigateThroughThePeelingInstrumentTest();                  // This one should be easy ahem (peeling...peeler!)
            NavigateThroughTheChipPreparationTest();
            NavigateThroughTheChipCookingChoiceTest();
            NavigateThroughTheFishSelectionTest();
            NavigateThroughTheFishPreparationTest();
            NavigateThroughTheHerbSelectionTest();
            NavigateThroughTheCookingInstrumentForFishFingersTest();
            NavigateThroughTheFishFinalCookingStepTest();
            NavigateThroughTheBreadSelectionTest();

            // Freebie from Gordon - He takes pity, and dishes out an awesome nugget of knowledge
            Console.ForegroundColor = ConsoleColor.DarkMagenta;
            WriteToConsole("HEY IDIOT! This one is for free; remember to rub the bread in the chip oil on the tray (do a 'mop' up) and get all of those awesome flavours!");
            Console.ForegroundColor = ConsoleColor.Green;

            // The FINAL TEST!
            NavigateThroughTheFinalServingTest();

            // SUCCESS (woop woop)!!!
            GodJob();

            Console.ForegroundColor = ConsoleColor.DarkMagenta;
            WriteToConsole("You have survived the Home-made Fish Fingers and a Chip Butty challenge! Well done! Press enter to exit...");
            Console.ForegroundColor = ConsoleColor.Green;
        }

        private static void NavigateThroughTheFinalServingTest()
        {
            // Final choice, how does this thing get served?
            complexOptions.Clear();
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "sauce to serve this with and decide if you should share this with others or not:"));
            complexOptions = CreateDictionaryWithOptions("Serve with ketchup and devour everything yourself.",
                "Serve with brown sauce and share (there is enough for two).", "Serve with ketchup and hand the whole dish over to a loved one, you've already eaten.");

            WriteDictionaryValuesToConsole(complexOptions);
            GordonRamsayInspectsYourComplexChoice(RetrieveTerifiedCooksChoice(), "A");
        }

        private static void NavigateThroughTheBreadSelectionTest()
        {
            // What type of bread should you use!!!
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "bread type for the chip butty (buttered, of course!):"));
            WriteEnumValuesToConsole<BreadType>();
            GordonRamsayProcessesYourIngredientChoiceForFoolishMistakes<BreadType>(RetrieveTerifiedCooksChoice(), "thickcrustybread");

            // SUCCESS (so far anyway, you're nearly there)!!!
            GodJob();
        }

        private static void NavigateThroughTheFishFinalCookingStepTest()
        {
            // How long should they be cooked and what do you add near the end (when the heat is turned up)?
            complexOptions.Clear();
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "time for how long the fish fingers should be cooked on each side and what secret ingredient should be added near the end of this process:"));
            complexOptions = CreateDictionaryWithOptions("Cook for 3 minutes on each side adding some butter near the end.",
                "Cook for 2 minutes on each side adding some margarine near the end.", "cook for 5 minutes on each side adding some butter near the end.");

            WriteDictionaryValuesToConsole(complexOptions);
            GordonRamsayInspectsYourComplexChoice(RetrieveTerifiedCooksChoice(), "A");

            // SUCCESS (so far anyway, getting there)!!!
            GodJob();
        }

        private static void NavigateThroughTheCookingInstrumentForFishFingersTest()
        {
            // What cooking instrument should be used to cook said fish fingers
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "cooking instrument with which to cook your fish:"));
            WriteEnumValuesToConsole<ChefToolsForTheJob>();
            GordonRamsayProcessesYourToolChoiceForFoolishMistakes(RetrieveTerifiedCooksChoice(), ChefToolsForTheJob.Pan);

            // SUCCESS (so far anyway, getting there)!!!
            GodJob();
        }

        private static void NavigateThroughTheHerbSelectionTest()
        {
            // What herb should be used with the fish???
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "herb to chop and use with your breadcrumb mixture for the fish:"));
            WriteEnumValuesToConsole<HerbType>();
            GordonRamsayProcessesYourIngredientChoiceForFoolishMistakes<HerbType>(RetrieveTerifiedCooksChoice(), "dill");

            // SUCCESS (so far anyway, there is a long way to go)!!!
            GodJob();
        }

        private static void NavigateThroughTheFishPreparationTest()
        {
            // Ok, how should the fish be prepared...
            complexOptions.Clear();
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "method for preparing the fish:"));
            complexOptions = CreateDictionaryWithOptions("Cut into squares, pepper and cover in a little chill powder before coating in seasoned flour, then use egg-wash.",
                "Cut into battons, lightly salt before coating in seasoned flour and rolling, then use egg-wash.", "Cut at an angle, lightly salt and don't flour (just use egg-wash).");

            WriteDictionaryValuesToConsole(complexOptions);
            GordonRamsayInspectsYourComplexChoice(RetrieveTerifiedCooksChoice(), "B");

            // SUCCESS (so far anyway, there is a long way to go)!!!
            GodJob();
        }

        private static void NavigateThroughTheFishSelectionTest()
        {
            // Choose the correct fish type
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "fish type for your fish fingers:"));
            WriteEnumValuesToConsole<FishType>();
            GordonRamsayProcessesYourIngredientChoiceForFoolishMistakes<FishType>(RetrieveTerifiedCooksChoice(), "pollock");

            // SUCCESS (so far anyway, there is a long way to go)!!!
            GodJob();
        }

        private static void NavigateThroughTheChipCookingChoiceTest()
        {
            // Ok, what do we 'bang' the chips into in order to cook them
            complexOptions.Clear();
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "method for cooking the chips:"));
            complexOptions = CreateDictionaryWithOptions("Chuck the chips in a roasting hot pan with oil and cook for 10 minutes.",
                "Chuck the chips in the deep fat fryer until done.", "Chuck the chips on an oiled baking tray and cook in a pre-heated oven.");

            WriteDictionaryValuesToConsole(complexOptions);
            GordonRamsayInspectsYourComplexChoice(RetrieveTerifiedCooksChoice(), "C");

            // SUCCESS (so far anyway, there is a long way to go)!!!
            GodJob();
        }

        private static void NavigateThroughTheChipPreparationTest()
        {
            // How do you choose to make the chips???
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "method for making preparing the chips for cooking:"));
            complexOptions = CreateDictionaryWithOptions("Chop, add oil, don't season and add chilli. Then shake.",
                "Chop, blanch, season and add paprika. Then shake.", "Chop, add oil, don't season and add pesto. Then shake.");

            WriteDictionaryValuesToConsole(complexOptions);
            GordonRamsayInspectsYourComplexChoice(RetrieveTerifiedCooksChoice(), "B");

            // SUCCESS (so far anyway, there is a long way to go)!!!
            GodJob();
        }

        private static void NavigateThroughThePeelingInstrumentTest()
        {
            // Choose the correct peeling method, or you'll become a cropper
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "peeling instrument for your potatoes:"));
            WriteEnumValuesToConsole<ChefToolsForTheJob>();
            GordonRamsayProcessesYourToolChoiceForFoolishMistakes(RetrieveTerifiedCooksChoice(), ChefToolsForTheJob.Peeler);

            // SUCCESS (so far anyway, there is a long way to go)!!!
            GodJob();
        }

        private static void NavigateThroughThePotatoSelectionForTheButtyTest()
        {
            player.SoundLocation = WELL_DONE_SOUND_BITE;

            // Choose the correct potato type for the chips
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "potato type for your chips:"));
            WriteEnumValuesToConsole<PotatoType>();
            GordonRamsayProcessesYourIngredientChoiceForFoolishMistakes<PotatoType>(RetrieveTerifiedCooksChoice(), "desiree");

            // SUCCESS (so far anyway, there is a long way to go)!!!
            GodJob();
        }

        private static Dictionary<string, string> CreateDictionaryWithOptions(params string[] items)
        {
            Dictionary<string, string> complexItems = new Dictionary<string, string>();

            if (items == null || items.Count() == 0)
            {
                throw new GordonRamsayEnragedAtTheDeveloperException();
            }

            List<string> keys = new List<string>() { "A", "B", "C" };

            if (items.Count() > keys.Count())
            {
                throw new GordonRamsayEnragedAtTheDeveloperException();
            }

            for (int i = 0; i < items.Count(); i++)
            {
                complexItems.Add(keys[i], items[i]);
            }

            return complexItems;
        }

        private static void GodJob()
        {
            player.Play();
            WriteToConsole(Environment.NewLine + GOOD_JOB_TEXT);
        }

        private static void WriteDictionaryValuesToConsole(Dictionary<string, string> complexOptions)
        {
            if (complexOptions == null || complexOptions.Count == 0)
            {
                throw new GordonRamsayEnragedAtTheDeveloperException();
            }

            complexOptions.ToList().ForEach(item =>
            {
                WriteToConsole($"{ item.Value }: type = { item.Key }", false);
            });

            Console.WriteLine();
        }

        private static void GordonRamsayInspectsYourComplexChoice(string choiceString, string gordonsDesiredOutcome)
        {
            if (complexOptions == null || complexOptions.Count == 0)
            {
                throw new GordonRamsayEnragedAtTheDeveloperException();
            }

            if (!choiceString.Trim().Equals(gordonsDesiredOutcome, StringComparison.InvariantCultureIgnoreCase))
            {
                throw new GordonRamsayPoorChefSkillException("GOD DAMN IT, WHY DID YOU DO IT LIKE THAT. USELESS, SIMPLY USELESS - EPIC FAIL!");
            }
        }

        private static void GordonRamsayProcessesYourToolChoiceForFoolishMistakes(string choiceString, ChefToolsForTheJob gordonsDesiredOutcome)
        {
            if ((ChefToolsForTheJob)CheckForAStupidChoiceInGeneral(choiceString) != gordonsDesiredOutcome)
            {
                throw new GordonRamsayPoorChefSkillException("GOD DAMN IT, WHY DID YOU CHOOSE THAT BLOOMING (imagine swearing here) TOOL FOR THE JOB - EPIC FAIL!");
            }
        }

        private static void GordonRamsayProcessesYourIngredientChoiceForFoolishMistakes<T>(string choiceString, string gordonsDesiredOutcome) where T : struct, IConvertible
        {
            if (!typeof(T).IsEnum)
            {
                throw new GordonRamsayEnragedAtTheDeveloperException();
            }

            string choiceFromEnum = Enum.GetName(typeof(T), CheckForAStupidChoiceInGeneral(choiceString));
            if (string.IsNullOrWhiteSpace(choiceFromEnum) || !choiceFromEnum.Equals(gordonsDesiredOutcome, StringComparison.InvariantCultureIgnoreCase))
            {
                throw new GordonRamsayWrongIngredientException("WRONG, WRONG, WRONG INGREDIENT!!! - EPIC FAIL");
            }
        }

        private static int CheckForAStupidChoiceInGeneral(string choiceString)
        {
            int choiceValue;
            if (!int.TryParse(choiceString, out choiceValue))
            {
                throw new GordonRamsayInvalidChoiceException("YOU DIDN'T GIVE ME A BLOOMING (imagine swearing here) NUMBER - EPIC FAIL!");
            }

            return choiceValue;
        }

        private static string RetrieveTerifiedCooksChoice()
        {
            Console.ForegroundColor = ConsoleColor.Blue;

            Console.Write("MAKE YOUR CHOICE: ");
            string choice = Console.ReadLine();
    
            Console.ForegroundColor = ConsoleColor.Green;

            return choice;
        }

        private static void WriteToConsole(string text, bool addAdditionalNewLine = true)
        {
            Console.WriteLine(text + (addAdditionalNewLine ? Environment.NewLine : string.Empty));
        }

        private static void WriteEnumValuesToConsole<T>() where T : struct, IConvertible 
        {
            Type typePassedIn = typeof(T);

            if (typePassedIn.IsEnum)
            {
                Enum.GetValues(typePassedIn).Cast<T>().ToList().ForEach(item =>
                {
                    Enum enumValue = Enum.Parse(typeof(T), item.ToString()) as Enum;
                    WriteToConsole($"{ item }: type = { Convert.ToUInt32(enumValue) }", false);
                });
            }

            Console.WriteLine();
        }
    }

    public enum BreadType
    {
        MediumSlicedGranary = 0,
        HovisHalfAndHalf = 1,
        Baguette = 2,
        ThickCrustyBread = 3
    }

    public enum HerbType
    {
        Basil = 0,
        Chives = 1,
        Dill = 3,
        Sage = 4,
        Tarragon = 5
    }

    public enum FishType
    {
        Haddock = 0,
        Pollock = 1,
        Tuna = 2,
        Salmon = 3
    }

    public enum PotatoType
    {
        Desiree = 0,
        KingEdward = 1,
        Laura = 2,
        MelodyPotato = 3
    }

    public enum ChefToolsForTheJob
    {
        RustySpoon = 0,
        Peeler = 1,
        Screwdriver = 2,
        Pan = 3,
        Griddle = 4
    }

    public class GordonRamsayInvalidChoiceException : Exception
    {
        public GordonRamsayInvalidChoiceException(string message)
            : base(message)
        {

        }
    }

    public class GordonRamsayWrongIngredientException : Exception
    {
        public GordonRamsayWrongIngredientException(string message)
            : base(message)
        {

        }
    }
    
    public class GordonRamsayPoorChefSkillException : Exception
    {
        public GordonRamsayPoorChefSkillException(string message)
            : base(message)
        {

        }
    }

    public class GordonRamsayEnragedAtTheDeveloperException : Exception
    {
        public GordonRamsayEnragedAtTheDeveloperException()
            : base("OMG, YOU ARE SO INCOMPETENT. THIS SOFTWARE DEVELOPER DOESN'T KNOW HOW HIS OWN CODE SHOULD WORK. SHOCKING!")
        {

        }
    }
}

It takes the form of a beautiful console application; here it is in full swing:

Gordon Ramsay Cooking Challenge.

Gordon Ramsay Cooking Challenge.

For extra kicks, I forced my wife to play it to…adding annoying sound bites (for success and failure, in each case, to cover all of my bases):

Claire Epic Failing.

Claire Epic Failing.

Claire Nailing It.

Claire Nailing It.

It felt pretty darn good to just rattle out a piece of random, not that well thought out code. I think I just needed to write ‘something’, so this is what we have ended up with for better or for worse. I urge you to write something awful (just for yourself, not for your day job, unless you quite like the idea of being tossed out onto the street that is!) and get liberated, just for once! There is quite a bit of pressure sometimes to conform to standards, practice patterns, etc. This is all good and well, but just remember that you can always just hammer out something ill-thought for yourself and enjoy doing so; sometimes it can be just the ticket! ūüėČ

I seem to be, as it was pointed out to me today, late to the Gordon Ramsay game-based party anyway:

Gordon Ramsay Dash

There will be more golden, crispy, fish finger like coding posts coming soon; in the meantime have a great morning/afternoon (or evening/night) depending on when you read this, bye for now!

SEO – Gouging Eyes out with Rusty Spoons

A very short piece on my current, off-the-wall, opinions on my little SEO journey so far and the shenanigans we’ve faced up to this point.

Ok, so it hasn’t been¬†that bad! Plus it’s interesting I have opted to use ‘spoons’, and not just a singular spoon. It looks like I plan to¬†gouge¬†out both my eyes at once based on the post title!

I have certainly had moments of scratching my head as to what the hell is going on and SEO often brings up questions like ‘is¬†option¬†a, b, c, z or a combination of some or all, the best way to approach it?’; which quickly leads to the questioning of every blooming decision you plan to make to the nth degree!

With the website ‚Äėfundamentally‚Äô finished (ok, I‚Äôm completely and utterly lying, I want to rewrite massive chunks in the usual ‚Äėunhappy with the code as soon as you‚Äôve finished writing it‚Äô, developer condition, or sickness if you will!), we have desperately been trying to hike our way up the rankings. This has, after a painstaking process, happened; to some degree at least.

I picked this book up for starters, as all good things start with a good read; don’t be put off by the whopping great name:

SEO 2016: Learn search engine optimization with smart internet marketing strategies

After reading this and (thanks for this by the way) picking a few brains of SEO boffins and asking friends to pick additional boffin brains for me, I was ready to start making some of the larger, more critical changes.

So, in no particular order, here were the ideas and concepts that I feel have made the most impact in the short time we have been climbing the SEO mountain…

Page Titles and Page Descriptions

This, without a shadow of a doubt, had the largest impact. We, quite literally, just added unique metadata to each page and ensured our titles and descriptions were informative, without skipping out on the correct keyword combinations we were targeting.

Up until this point the web applications that I have produced, out in the wild, have been linked to from other sites (i.e. local authorities, for example); these other sites took on the burden of SEO and it most cases were sought out for the services they provide (i.e. it was non-commercial in a sense and the traffic was not being fought over).

Now I find myself competing for these precious nuggets of traffic, this takes the biggest bite of the biscuit for me. We went from completely impossible to find, for a small subset of keywords we were targeting, to being on page 3 of the search results (a little variance across Google and Bing, but just a rough approximation). Not perfect, but a very good start!

Keyword Optimisation

This took a couple of days to do in the end. This boiled down to, in essence, looking for keyword combinations with good levels of traffic but lower degrees of difficulty when it came to competition. We ended up spreading our eggs amongst a few baskets here and did target a few competitive keywords; only in an effort to make our content as natural and accurate as possible (clarity/quality of content is also a ranking factor, after all).

We used the Moz tools for this job; this was to check out keyword densities of comparable sites and then plan some alternatives. These references can be found here (you get a month’s free trial by the way):

Moz Keyword Explorer

Moz Open Site Explorer

This has had some impact, once our site was re-crawled and re-indexed. Just from a content quality perspective, it was well worth running everything through Grammarly. I have the Chrome Plugin but, in this instance, I used a Word Plugin to get the job done (you can get a free account, with additional paid for options being available):

Grammarly for Word

Grammarly for Chrome

Keywords in Content, Image Titles/Alt Attributes and Anchor Text

A simple one but one that, after a few hours of looking around the site and post-building up a new keyword strategy using Moz tools, we knew we could improve on.

We now have a much better spread of keywords across our pages, including LSI keywords (Latent Semantic Indexing); essentially just related phrases.

As for image titles and title/alt attributes, we went on a massive, night long, rampage to improve these; based on our new found keyword knowledge (using hyphens to separate words in resource names).

Lastly, a great deal of effort was placed upon using natural and informative text within anchor tags which, to be honest, we were a little weak on. This appears to have had a positive impact.

Sitemaps.xml

This one got me! I generated a sitemap that, on the face of it, looked prim and proper. However, after checking it in the Google Search Console I had been sucker punched by dodgy encoding (UTF-8 BOM, to be exact). There, at the start of my file, sat a Byte Order Mark (otherwise invisible in Notepad/Visual Studio, as these things often are). This equalled an instant red flag and is something worth not getting caught out on.

I found a reasonable looking Sitemaps.xml validator which flagged the issue:

Robots.txt Checker

Recreating the file in Notepad and checking it in fixed the issue (and doing the resubmit via Google Search Console).

One last thing (luckily I didn’t do this!), make sure to double check that in the robots.txt file you aren’t disallowing access to your entire site when it comes to¬†legitimate¬†bots. Thankfully, I was dead careful in this regard!

So, what has raised eyebrows (in the ‘why does this matter’ stakes)? One thing that has really got my goat is the¬†Flesch-Kincaid Reading Ease¬†score. I have spent a fair bit of time wracking my brains as to whether content really needs to be targeted at a¬†thirteen to the fifteen-year-old¬†student (when it comes to reading ability that is). In honesty, I’m not sure on this…

The content outlined in SEO 2016 references Searchmetrics findings show sites appearing in the top ten results, on average, have a Flesch reading score of 76.00; which puts a stake in the ground at the aforementioned thirteen to fifteen-year-old reading level ability.

This doesn’t sound all that bad to me; but, after some initial testing I was finding that our content was ranking below this bar on all¬†occasions. Not by too much, but enough to concern me. Upon testing some other comparable, higher ranking sites, I wasn’t able¬†to determine that any other site had much better¬†scores, to be honest.

We reread the content, multiple times, before coming to the conclusion that it was easy enough to read. I personally felt that certain sentences and words were being penalised too harshly for being ‘too complex’ or as having ‘too many¬†syllables’ when I’m sure that it could be easily read by children (far below the thirteen to fifteen-year-old mark).

It felt as though we had to dumb down our content to a point where it felt very unnatural; as if we couldn’t compose a sentence of more than five words. Possibly borderline insulting to most people; so we’ll be sticking to our guns for the time being.

What’s Next?

Claire and I have a few other strategies going on, such as getting some strong backlinks in play; this is the next port of call. We also need to focus more on the all-important social media. I have additional tasks to perform, such as adjusting how JavaScript is loaded (looking at async/defer options for all of my resources; without busting pages!), looking at resource bundling and caching including resource optimisation (i.e. a little bit more image compression work). I’ll be a busy bee for a fair while yet!

We’ll see how the first batch of alterations plays out first; it is incredibly difficult to shake the feeling that a good chunk of this is highly experimental!

If any SEO experts come across and can offer any further advice or would like to comment please do! I’d love to hear from you.

Until the next time, toodles!

The Bears Whereabouts

Where have I been you may ask! Apologies for the lack of content, we’ve (included my wife in the equation here) hit a sizeable brick wall of work.

I think this has been mentioned previously, but I’ve recently started a new position and this has involved me spending a good dollop of time getting acclimatised; in particular finding my way around Amazon Web Services (which I’m having a super time with by the way!).

Coupled with this, I’m incredibly busy ploughing through work items for my wife’s business website, frogandpencil, using the magic of a (beastly) Trello board.

What does this mean for bearandhammer posts? Well, I’m kind of hoping that as I work my way through website tasks for frogandpencil and keep chewing AWS related subjects at work that a handful of small posts will come out in the wash, before normal service is resumed (i.e. the larger post on Web API).

So, with any luck, I’ll have something new plastered up on here soon enough. In the meantime, happy coding!

All the best from the Bear!