Poly-Repo vs Mono-Repo

Poly-Repo vs Mono-Repo

So I’ve been doing a lot of DevOps work recently, and one of the bigger topic of discussions I’ve been a part of recently is this idea of Mono-Repo vs Poly-Repo. And I thought I would way in with some of my thoughts on this.

So first and foremost, let’s talk about what the difference is. Mono-Repo vs Poly-Repo, actually refers to how you store your source control. Now I don’t care if you are using Azure Dev Ops, GitHub, BitBucket, or any other solution. The idea here is whether you put the entirety of your source code in a single repo, or if you split it up into multiple repositories.

Now this doesn’t sound like a big deal, or might not make sense depending on the type of development code, but this also ties into the idea of Microservices. If you think about a micro-services, and the nature of them, then the debate about repos becomes apparent.

This can be a hot-debated statement, but most modern application development involves distributed solutions and architectures with Micro-services, whether you are deploying to a server-less environment, or even to Kubernetes, most modern applications involve a lot of completely separate micro-services that provide the total functionality.

And this is where the debate comes into play, the idea that let’s say your application is actually made of a series of smaller micro service containers that are being used to completely overall functionality. Then how do you store them in source control. Does each service get it’s own repository or do you have one repository with all your services in folders.

When we look at Mono-Repo, it’s not without benefits:

  • Easier to interact with
  • Easier to handle changes that cut across multiple services
  • Pull Requests are all localized

But it isn’t without it’s downsides:

  • Harder to control from a security perspective
  • Makes it easier to inject bad practices
  • Can make versioning much more difficult

And really in a lot of ways Poly-Repo can really read like the opposite of what’s above.

For me, I prefer poly-repo, and I’ll tell you why. Ultimately it can create some more overhead, but I find it leads to better isolation and enforcement of good development practices. But making each repo responsible for containing a single service and all of it’s components it makes for a much cleaner development experience and makes it much easier to maintain that isolation and avoid letting bad practices slip in.

Now I do believe is making repos for single purposes, and that includes things like a templates repo for deployment components and GitOps pieces. But I like the idea that to make a change to a service the workflow is:

  • Clone the Services Repo
  • Make changes
  • Test changes
  • PR changes
  • PR kicks off automated deployment

It helps to keep each of these services as independently deplorable in this model which is ultimately where you want to be as opposed to building multiple services at once.

How to start a New Job in a Pandemic

How to start a New Job in a Pandemic

So if you find me on LinkedIn, you know that I recently changed job at my current company. And changing roles is something that many of us have had to deal with several times in our careers. Even if you’ve been able to work at the same place for most of your career, it’s more than likely that you’ve had to change roles, or even teams at one point.

Now this time was a little different, mainly because it was in a pandemic. In previous roles, I would say I was a “mobile worker” and then a mix of “remote and mobile” (probably a blog post on the differences coming). But in all cases, I would go to an office for the initial transition, and at least meet people face to face. But thanks to COVID-19, that became impossible.

So this was the first time I’ve had to transition jobs in a completely remote position. And more than that I’ve noticed I’m not alone, having friends who are going through the exact same thing. Now through this experience, there were somethings I was able to do to help myself, and other things I learned for next time. And in this post I hope to capture both. So here are some tips and tricks to starting a new job in a 100% remote capacity.

Tip #1 – Make sure you fully transitioned

This is the first thing I will point out, and may not apply to everyone. If you are changing roles at your current company though, this can definitely be important. As you gear up to transition from one role to another, it’s especially important that you make sure you are able to close out your current responsibilities to prepare for your new roles responsibilities. This sounds like common sense, but I have seen in the past how this can go horribly wrong.

Because you are a remote worker, its easy for some manager or team mates to think that because you aren’t physically moving, or are still working for the same organization that you can be available after your start date at your new position. This is a slippery slope in my experience that should be avoided. The simple fact is this, its not fair to you, your previous team, or your new team for your attention to be divided. Now I’m not saying you should be a jerk about this, and it’s a scorched earth policy when you leave your old team. But I am seeing be cautious about taking on responsibilities after you start your new position.

Like it’s one thing, for some one your old team to reach out with questions or asking you for context on something. It’s another entirely for you to be working on key deliverables or attending meetings for your old team after you start date at the new position. Remember to be respectful of all sides, and I will say that for this to work, you need to respect this tip as well.

More than likely you gave a certain amount of notice, and I’ve seen way too many people take those 2 weeks as a “I’m just going to coast out and then pick up my new position.” This is absolutely the wrong behavior. You have a responsibility to your old team to do as much as you can in the two weeks to set them up for success in the transition. For example, doing the following actions:

  • Document everything you can about your current projects, things like:
    • State they are in
    • Why certain decisions were made
    • Key team members who were part of the conversations
    • where to find certain things
    • key concepts and processes
  • Setup meetings with your backfills early, and make sure they have time to consume everything and understand what is going on.
  • Communicate with team members and others as much as you can to make sure nothing gets dropped.
  • Document any processes you do to help them pick them up.

Tip #2 – Make sure you have a meeting with your new manager day 1

This one feels kind of obvious, but again, some people miss it. You really need to make sure you have a meeting with your new manager as soon as possible. This is going to be to set the foundation of your relationship with them.

You need to make sure you have this meeting as this is the time to make sure you focus on the following key areas:

  • Expectations on communication
  • Expectations on delivery and focus
  • Key objectives and things you can help with
  • How to engage with the team
  • What is their preference means of communication?
  • What are their working hours?
  • What is a reasonable response time?
  • What kind of regular cadence should you set up? And who defines the agenda?

Tip #3 – Make sure you talk about team culture

The above meeting with your manager is a great time to have this conversation. And this is one of those things everyone over looks, but is probably the most important. In a pre-COVID world, you would discover the nature of the team naturally. You would talk to your team mates, and find out how they work. And let’s be honest, some of these things could be taken for granted. But with the advent of remote work, all of the old assumptions are out of the window. So you need to take the time to figure out what the culture of Thea team is, and by that I. Mean things like this:

  • Are there regular cadence calls?
  • Do people prefer phone or face to face?
  • Is there a preference for camera use?

Tip #4 – Ask for an “onboarding buddy”

This is extremely important, Onboarding in a vacuum is completely impossible. And even the best manager in the world isn’t going to be able to talk about everything. And to be honest, even if they want to, team dynamics are always going to be different.

Let’s face it, people behave differently for their managers than they do for their other team members. Plus, most managers I’ve known are very busy people, and the demands of onboarding someone can be problematic.

So a good solution is to ask your manager for an “onboarding buddy,” and the idea is this is someone who you can check in with on a daily basis. The goal being that you can check in with on a daily basis to make sure things are going well and that you are aligning properly.

Tip #5 – Make sure you have explicit direction

I find too often, and I’m including myself in this, I am afraid to step back and say, I’m not entirely clear on what you are looking for. You don’t want to find yourself in a situation where you don’t have an understanding of your direction and next steps. Make sure you get explicit instructions from your new manager on what you’re priorities should be and what you are going to be working on.

Tip #6 – Make sure you are able to contribute early

Look for ways to dive in, I hate to say this, but most onboarding is fairly generic, and the best way to get to know the team is to roll up your sleeves and get to work. Find ways that you can help them with what they are working on right now.

Don’t be pushy about it but just ask “How can I help?” Or look for things you feel comfortable taking on early. The best way to get to know a team is by getting in a foxhole with them and showing value.

Tip #7 – Start in listening mode

One of the biggest mistakes, I see over and over again is that people show up to a team and start saying “we should do this differently?” It is pretty presumptuous to walk in to a team that has been working together and start with a “You’re doing it wrong.” It also causes you to miss out on a lot of learning and would recommend you take the time to really make sure you understand how the team works, and the “Why?” before you start throwing out ideas for changes.

So there are some of my initial thoughts on how to join a team remotely.

Passing Values to a Orchestrator function in durable functions

Passing Values to a Orchestrator function in durable functions

So I wanted to get a short post out here on a handy little trick that I actually had a pretty hard time finding the answer to. So I’ve been doing work with Durable functions lately in Python, and really enjoy the possible options this opens up for longer running or complex server-less operations.

That being said, I did run into a headache early on in the form of how do I pass values from the initial request to the other parts of the function. So here’s a short post on how to do that so that hopefully the next person doesn’t have as hard of a time finding the answer.

So when you have a durable function, you essentially get 3+ pieces, but at the minimum its 3 pieces.

  • HttpStart: This is the code that receives all Http requests for durable functions and then acts as a router, to push them to the correct Orchestrator.
  • Orchestrator: This is the function that will be longer running and used to manage state ongoing.
  • Activity: These are the smaller functions that are called upon by the orchestrator to do the work being asked for.

Now the problem is that normally I would pull from an http request in a function in the following way:

async def main(req: func.HttpRequest, starter: str) -> func.HttpResponse:
    payload = json.loads(req.get_body().decode())
    logging.info(f"Trigger payload = {payload}")

See though the problem with this is that the actual request that kicked off the function is only accessible to the HttpStart. So now, you need to figure out a way to pass this to the orchestrator, and if I’m being honest, the best way to do that isn’t clear.

Part of the reason it isn’t clear, is that Durable functions do a lot of work to encapsulate the inner workings of how they manage state. Which I’m thankful for, but it made this harder.

But after much head-scratching, if I figured it out, and here it is:

async def main(req: func.HttpRequest, starter: str) -> func.HttpResponse:
    client = df.DurableOrchestrationClient(starter)

    function_name = req.route_params["functionName"]
    requestBody = json.loads(req.get_body().decode())
    instance_id = await client.start_new(function_name, client_input=requestBody)

Now when you use core tools, all the wiring is pre-built for you. Strongly recommend that. But if you leverage the “client_input” parameter off the DurableOrchestrationClient, you can pass a json serialized paylod over to the orchestrator.

From the orchestrator’s side, the code looks like the following:

requestBody : str = context.get_input()

Now one of the limitations I found was that you could only pass one parameter this way, so the easy workaround was to implement a complex object that I would then serialize containing all relevant data.

Building modules in Python

Building modules in Python

So recently I’ve been involved in a lot more development work as a result of changing direction in my career. And honestly it’s been really interesting. Most recently I’ve been doing a lot of work with Python, which up until now was a language that I was familiar with but hadn’t done much with.

And I have to tell you, I’ve really been enjoying it. Python really is a powerful language in it’s flexibility, and I’ve been doing a lot of work with building out scripts to do a variety of tasks.

As mentioned in previous blog posts, I’m a big fan of DevOps and one of the things I try to embrace quickly is the idea of packaging code to maximize re-use. And to that end, I recently took a step back and went through how to build python modules, and how to package them up for using a pip install.

How to structure your Python Modules?

The first thing I’ve learned about Python is that it very much focused on the idea of convention. And what I mean by that is that Python focuses on the idea of using convention to define how things are done over have a rigid structure that requires configuration. And putting together these kinds of modules is no different.

So when you go through the setting up of the configuration, you would use the following structure:

  • {Project Folder}
    • {Module Folder}
    • __init__.py
    • {Module Code}
  • setup.py
  • requirements.txt

From there the next important part of the setup is to create a setup.py. As you start to flush this out, you are going to be identifying all the details of your package here along with dependencies that you want pip to resolve. A great post on project structure is here.

import setuptools 
with open("README.md", "r") as fh: 
    long_description = fh.read() 
    python_requires = '>=3.7',
    packages = setuptools.find_packages(),

And next is the requirement for a readme.md, which will outline the specifics of your package. This where you are going to put the documentation.

Next the important part is how to implement the __init__.py, this is important and is basically a manifest for the namespace of the library. Below is the sample.

from .{python code file} import {class}

From there you can actually use a utility called twine to bundle the package, and information on twine can be found here. Below is the command to create the bundle. There is a great post on that found here.

Threading in Python

Threading in Python

Just another quick tip and trick for Python, and that is how you implement threading. This is surprisingly simple in Python, but basically it involves installing the threading library using pip

pip install threading

From there the process is the following:

numThreads = 10
threadList = []

def RunTest(self, name):
	print(f"Hello {name}")

for x in range(numThreads):
	t = threading.Thread(target=RunTest, args=(x))

This will then kick off each thread and let them run in the background, now the next logical question being how do I wait for a thread to complete, and that would be the following:

for t in threadList:

That’s really it, overall pretty easy.

Quickly Deserializing in Python

Quickly Deserializing in Python

Just a quick “Tip and Trick” post right now, but I’ve been doing a lot of work with python lately. And I have to tell you, I’m really enjoying it. Python provides a lot of easy ways to do the kind of work that we have to do so often. The “Free form” nature of python gives the ability to build a lot of things very quickly, and one of the common problems I wanted to solve is pulling in configuration information into your python scripts.

One of the habits I’ve built over my time as a developer is that I HATE to build magic strings, and prefer to build configuration settings as I build my code. And rely upon this configuration almost immediately. And as I’ve been working with python, I found an easy way to handle this type of pattern.

The first benefit, is how Python handles json, when Python reads in a json script, it will treat it as a type “dict” which is great because it makes it really easy to read as a key / value pair. So for example, the following code works:

Below is the test.json:

	"value1":"value 2",
	"object1": {

The following python script can read that:

filePath = "./test.json"
f = open(filePath)
config = json.load(f)

value1 = config["value1"]

Honestly pretty easy, but one of the fun tricks of python I recently discovered is how to map those values to a class. Take the following file for “test.json”

	"value1":"value 2",
	"object1": {

And if I create the following class:

class Object1(object):
	def __init__(self, objectvalue1, objectvalue2):
		self.objectvalue1 = objectvalue1
		self.objectvalue2 = objectvalue2

I can load that class with the following:

filePath = "./test.json"
f = open(filePath)
config = json.load(f)

object1 = Object1(**config["object1"])

That one line at the end will take the json object from the “object1” property and will match it to the constructor to load the object, and do it based on name mapping, so as long as the constructor parameters match the names of the json file it will take care of the mapping.

So just a fun little trick for python for anyone who’s new to python.

Being your own enemy….Perfectionism

Being your own enemy….Perfectionism

So this is something I’ve been thinking a lot about lately, and I figured it might be worth doing a blog post about, and that’s the topic of Perfectionism, and the idea of being your own worst enemy.

In my new role, I’m doing a lot more coding, and software development and I find myself in a position that I’ve been in before, where I have sort of a “blank slate” to build out something and have a degree of latitude to figure out the “how” I want to do things. And it can be great, but also stressful.

We’ve all heard the stories of Steve Jobs, Elon Musk, Thomas Edison, and others. Who demanded nothing less than perfection from themselves and those who they worked with. And we’ve all had that manager who’s standards were too high, or even been that person who tries to make every detail of your work perfect.

I have lots of times where I catch myself doing the later, and being the one who holds myself to a higher standard, and there can be a lot of reasons for that. Some of those reasons include:

  • Perfectionism
  • Ego
  • Fear of Failure
  • Imposter Syndrome
  • Lack of self confidence

In my experience, due to the positive nature of the word “Perfectionist” because of people like Elon Musk, or Steve Jobs, there is now this “convention” where people say “I’m just a perfectionist” to really help mask one of the other truths above.

And at the end of the day that’s telling yourself a lie, which can create this vicious circle. For example, it took me a long time to realize that my perfectionist tendencies were really imposter syndrome.

And this ultimately created a vicious cycle, as follows:

  • I would be over critical of my work, and put in more hours thinking that it “Needs to be better” or people are going to “realize I not as good at this as I think I should be.”
  • When people would identify the extra hours and work, I would hide it by saying “I’m a perfectionist, and just need to really deliver the best work possible.”
  • I would then feel increased pressure to deliver perfect every time, and repeat the cycle with more intensity.

And it should surprise no one, that the above cycle is about the furthest thing from sustainable that you can get to, and because I would take on too much and put too much pressure on myself, I would then set myself up for failure, which made my imposter syndrome a self-fulfilling prophecy.

Now after talking to friends and colleagues, I find that this type of issue is pretty common, subtle differences might be involved (Remove imposter syndrome, and replace with “Fear of Failure”). And the first thing to know, is you are not alone, there are a ton of people now starting to talk more about this. Personally I like Scott Hanselman’s discussion on this topic, found here.

But here are some tricks I’ve found to help myself avoid this, and increase the amount of work I deliver and getting to a quality I am satisfied with, and avoid the downward spiral.

Tip 1 – Keep objectives Small

This is the biggest thing I find that helps me, so let’s do it first. And I did this recently with a coding project that I needed to work on. I take every coding project and break it into small tasks, things that can be done in like 20-30 minutes. And then I break that list into two categories Essential and Nice to have.

The idea here being that I am forcing myself to take 2 minutes and define what is absolutely essential and what would be nice to have. And then as I work on this I will focus on the Essentials, while roping in as many nice to haves as I can.

Now what I did find is that this alone is not enough, as you will find ways to push to make sure both groups get done, but Tip #2, helps with that.

Tip 2 – TimeBox

The next part is that I will timebox everything I do, maybe not with tight like “I have 30 minutes to do this.” But more of a “I’m going to get X done before lunch.” And I find that by doing so, I ensure that I don’t lose focus on the larger picture.

This forces me to keep the essential at the front of my mind, and only let’s me go so far down the “rabbit hole” that is the “Nice to have” list.

At the end of the timebox, I then adopt the Scrum mentality and either add the “Nice to have” items to the backlog, or throw them out all together. This helps me feel like I’m being productive and delivering on what I need to, and can lead to a confidence boost, when I see how many “Nice to haves” I knocked out.

Tip 3 – Be clear about the desired outcome

This is the other critical one, I’m clear for myself and when I communicate with team members about this. Avoid words like “need to…” and be clear about “trying things”.

For example, I had a scenario where I wanted to implement threading in python to resolve an issue and making something more performant. At the time I hadn’t even researched threading, so I was very clear with my team members that I was going to “try” and make this work, and made sure that I went into it with the expectation of trying, not that I 100% committed which reminded myself that getting this working was not essentially.

Now as it turns out threading in python is really easy, and was pretty thrilled with the results (2 hour process down to 17 minutes). But it helps to understand that you need to make sure that you are clear about what you are “trying to do” or “experimenting with” and what the expected outcome is.

Updating version numbers for Python Packages in Azure DevOps

Updating version numbers for Python Packages in Azure DevOps

So I did a previous post on how to create package libraries in Python, and I wanted to put in a post here on how to solve a problem I immediately identified.

If you look at the setup.py, you will see that the version number, and other details are very much hard coded into the file. This is concerning as it requires a manual step to go and update this before you can do a build / publish activity. And honestly, nowadays CI/CD is the way of the word.

So to resolve this, I built a script to have the automated build agent inject the version number created by the CI/CD tool. And that code is the following:

import fileinput
import sys

filename = sys.argv[1]
text_to_search = sys.argv[2]
replacement_text = sys.argv[3]
with fileinput.FileInput(filename, inplace=True, backup='.bak') as file:
    for line in file:
        print(line.replace(text_to_search, replacement_text), end='')

I then updated my setup.py with the following:

    python_requires = '>=3.7',

And that’s it, from their you just trigger this tile and inject the new build number into the file.

Tips for Job Interviews

Tips for Job Interviews

So I wanted to take a second to talk about interviewing, and how to go about interviewing for a position. I recently changed job at my current employer, and have actually had this conversation with quite a few friends, and I did want to put out a post of some quick tips for interviewing:

Tip 1 – Your Resume should really be comprehensive.

One of the number one mistakes I see people make with their resume is they get too beholden to this idea that a resume can only be 1 page, and I honestly don’t know why people believe that.

I know part of that comes from the fact that people want to keep it brief. I totally get that, but if I’m being honest if you are approaching ten years in your field, you more than likely have quite a breadth of skills and relevant experience, that should be documented. And to be honest you don’t know what specific skills they are most looking for, so it’s important to make sure you make your resume comprehensive to ensure that you check the appropriate box they are looking for.

Additionally, and I see this mistake a lot, people leave off skills because they don’t think they matter but do. For example, if you’ve ever had to work with an end customer, done a sales pitch, managed an escalation or expectations. These are valuable skills that many people just don’t have and should be documented in your resume.

Tip 2 – Build a brand deck, it’s the trailer

I have to be honest, in my experience the practice of a Cover Letter is really out of date. Most people I’ve ever known don’t put a lot of stock in them. I would argue a better medium in my experience is a “Brand Deck”, which really enables the ability to showcase your skills.

If the resume is a comprehensive view of your career and skills, the Brand Deck is the “Trailer”, the goal being that it allows you to shape the narrative around your skills and strengths and present that to a potential employer for their review. This can be a powerful tool for helping to show your skills ahead of the conversation in an interview. And ultimately help setup a more productive conversations for both potential employers and you. Instead of having the “What kind of experience do you have in Scrum?” They can see in your brand deck, “Lead team with Scrum Master role, and coordinated activities for Sprint Planning and Retrospective.

Tip 3 – Be on time, and very professional

This one I shouldn’t have to say, but I will. You need to be on the spot, and even potentially early for every interview. Also, treat this with a professional approach. And if you have a scheduled time slot be respectful of that. Don’t try to go over the allotted time, and be respectful. I have a whole blog post on how to run a meeting, and you should treat your interview in the same manner.

Tip 4 – Never use the word “Expert”. I don’t care how good you are.

This is a good rule that a friend of mine gave me. Never…EVER say you are an expert in anything. There is always “a bigger fish”, and there will always be someone who knows more than you on any topic. So I find the term “Expert” is just inviting people to play “stump the chump.” And honestly that’s a waste of your time and theirs.

Tip 5 – Be humble, hungry, and smart

A great book, that I’m going to do a post on is the Ideal Team Player, And the book really is a fascinating read, with some amazing insights into how someone can be a true team player by embodying these values. And at it’s core, the simplistic explanation of these values are:

  • Humble: Don’t have an ego, or a chip on your shoulder. Be the kind of person who isn’t in it for personal glory, but rather has a passion for the work they are doing.
  • Hungry: Be someone who has a passion for the work, and finds ways to do better and accomplish the goals set out for the team. Be someone who wants to find ways to contribute, and doesn’t need to know how to move forward.
  • Smart: Be someone who knows how to communicate with people. That you treat everyone with the same respect and know how to talk to people. You are smart enough to know what’s appropriate.

Tip 6 – Do your homework

Another key point I’ve seen people not do enough of is, do your homework up front. Research the company you are applying to, and make sure there’s a way to ensure that you make that part of the conversation. One of the most important aspects of the interview is that you are “selling yourself”, to a potential employer.

Tip 7 – Always ask questions

Another key piece of wisdom I’ve learned over the years is that you must always ask questions. ALWAYS. And don’t be afraid to ask about the culture or the team, some of the questions I’ve asked are the following:

  • What is the best part of working with this team?
  • What is the worst part of working with this team?
  • How do you feel about the leadership of the team?
  • What about the culture?
  • Do you find people are willing to discuss new ideas?

Tip 8 – Stick the landing

I got this advice from a very good friend, and honestly it is the best thing I’ve ever done in an interview. I now end every interview with the following two questions.

  • Do you have any reservations about me for this position? And if so can we address those now?
  • Can I count of you for a “Yes” vote when it comes time to hire?

What I love about these questions, is it gives you a very specific conversation that is focused on the reason you are all there. Let’s face it they are looking to see if you are a good fit, and you are looking to see the same. What I love about this question is that it gives them a chance to talk to you about anything they might have reservations about.

The biggest thing here is if they say “Well you don’t have a lot of experience in _______.” You can possibly clear up that misconception by talking about something adjacent.

The final question really helps you to show them how committed and interested you are in the position. It solidifies that you want this, and are ultimately looking for that to happen.

Tip 9 – Remember this is a sales conversation

Remember, interviewing is a sales motion, where you are selling yourself. You are selling them on why you would be an excellent addition to their team. So approach this as such, and it will always help to orient you in the right direction.

Final thoughts

Remember at the end of this process, you are interviewing them as much as they are interviewing you. You want to make sure you are going to enjoy and want to work with these people. So make sure you pay attention and ask questions during the interview.

2021…to Infinity and Beyond

2021…to Infinity and Beyond

Well all, I know I’ve been silent for a while and that was not intentional, but life just got in the way of me posting. Which I am going to endeavor to change, and get back on track with regular updates again.

So things went nuts for the month of December because of all the normal craziness of the holidays but in addition I actually changed jobs at Microsoft and was lucky enough to be able to move over to the engineering side of Microsoft. Which marked the achievement of a dream of mine, and with that came a lot of things, but I am now working on many excited new projects.

But I wanted to make sure to talk about the approach I have with regard to 2021 and moving forward. As I took some time over the past month, to reflect on 2020, the year was definitely one for the books. 2020 can be summarized as a bit chaotic of a year, and above all it marks a pretty radical change in the world, as things I’m not convinced will ever go back 100% to the way they were before.

And how I know there is no shortage of posts, blogs, memes, videos, and etc that talked about the dumpster fire that 2020 was. I prefer to use this as a time to look back at good things that have happened.

2020 in a lot of ways I think showed the strength and resiliency of the human spirit and the fact that when we pull together we can accomplish quite a lot. And also this year marked the realization for me of what it takes to enjoy life and what values drive me and define success for my life. And also how much I learned and continue to learn moving forward.

So while 2020 was a year of sacrifice, I want to focus on the positive and those were the following:

  • More time spent with my family.
  • Built a strong core group of friends around a game I really enjoy.
  • Learned and grew more as a creative this year, and really boosted the belief in my ability to create things in this world.
  • I got to work with some truly amazing people who are building solutions that are changing the world and making the world a better place.
  • I learned a new programming language (Python)
  • I’ve learned more about the values that define success for me.
  • I’ve watch my kids grow, and their minds grow in ways, and I am convinced in the future they will be WAY smarter than I ever was.
  • I reconnected with old friends, and found myself becoming part of a community that I had moved out of long ago.
  • I made new professional friends who are amazing.
  • I read a lot of really amazing books that opened my eyes to what is possible (Infinite Game, absolutely amazing).

So for 2021, I really look forward to the opportunity to grow and learn further, to find new ways to push the envelope and innovate, and to embrace the amazing life with a family I am lucky to have. For those who read this blog regularly, I hope 2021 turns out to be an amazing year for you of learning and growth, and “May the force be with you.”, and ultimately I look back on all of this, and I think it was said best on the best new show of 2020.

See the source image