If I’ve said it once, I’ve said it a hundred times: principles you can apply to discrete areas of life are worth their weight in gold. Who would think that I could tie together defragmenting a hard drive and work-life balance? I do, that’s who.

I first ran into defragmentation when I noticed my Windows XP machine was running slow. So I decided to open my IE 6 browser, go to Google, and figure out what was wrong with my computer. One of the first result said that defragmentation can cause everything I do on my computer to slow down. So I followed the instructions, defragmented, and like magic everything was faster.

I learned in college the theory behind why fragmentation occurs and how defragmentation ameliorates the performance issues. When you write a file to the disk, it has to find enough free space to fit that file somewhere on it. It writes the data into blocks, which means there can be some leftover space if for instance a file only needs two and a half blocks. If you have a file that only takes up half a block, it would fit perfectly into the remaining space.

Theory in this case is very different than reality. What ends up happening is that there are a lot of left over pieces of blocks that can’t be used. Fragmentation can come into play when the file has to be written to the disk in blocks that are some distance apart. This is bad, slow, and can be mitigated with defragmentation. Some additional time can be taken to move things around on the disk so that contiguous free space is maximized. New files can then take advantage of close spatial locations to increase performance.

Technical talk aside, the idea of defragmentation is a powerful one. I see many people give advise that uses the principle of defragmentation without explicitly mentioning it. Nearly every article I read on how to boost your performance at work suggest becoming more focused by removing distractions like Twitter, Facebook, Reddit, etc. The human brain was built to focus on a single task. Multitaskers are the exception. For the majority of us, myself included, we work best when we attack one problem at a time.

I’ve found huge performance boosts by intentionally taking away distractions while I program. I make myself conscious of when I need to be programming and when I can take a break. By never mixing the two, I’ve noticed my programming is better with my breaks leaving me better refreshed. I perform better at my job by turning my work day into discrete fragments. I can focus on the task at hand without distracting myself.

In keeping with principle ubiquity, I apply defragmentation to nearly every aspect of my life. One of the most obvious is the hours I work. Through some self analysis, I found out that my most productive hours are in the morning. I think it’s because will power is naturally high in the morning, and decreases as the day goes on and more choices need to be made. By maximizing the hours I spend working at my peak time, my work has become noticeably better.

Defragmentation comes into play because of how I spend my time before and after work. If I had it my way, I would start working 10 to 15 minutes after I wake up in the morning. That’s enough time for a quick shower, breakfast, and anything else that comes up. The pre-work fragment is necessary, so there is no way I can cut it out. I normally start working an hour and 20 minutes after I wake up, which I’m still trying to minimize. My optimal work fragment is eight hours with a five minute lunch break.

With around 10 hours spent in the pre-work, work, and commute home phase, that leaves me 14 hours for everything else in my life. If I sleep for seven hours, that leaves a seven hour “Zach” fragment. If I wake up at 5 AM, start work at 6:20 AM, leave work at 2:30 PM, and get home at 3 PM, that means the time between 3 PM and 10 PM is mine. My “Zach” fragment is as large as it can possibly be given the constraints of my system. (i.e. my life)

I noticed a direct correlation between being cranky and starting work late or leaving work late. My body was telling me I needed a larger chunk of time, it just took my mind while to realize my schedule needed defragmentation. Since I switched to this new schedule, I noticed that my work and my overall mood has improved. I have more energy than I did before even while getting slightly less sleep. By allowing myself to move from one fragment to another with as little overlap and mixing as possible, my life has become defragmented and overall better.

IE XML5633 Error when using jQuery.parseXML()

I saw something very interesting today while debugging an issue that a QA reported. They learn as part of their training to always keep Dev Tool open, and create a bug when a console error comes up. The bug I was looking at was created when a QA saw the following:

XML5633: End-tag name does not match the corresponding start-tag name. Line: 1, Column 10

I ran a Fiddler trace, and noticed an AJAX request was throwing a 401 right before this error was shown in the console. I put a console.log() before the request, and in the success callback. My two logs would show, then the XML5633 message would come up.

Uh, what?

My instincts told me that something was doing a setTimeout() and processing the XML outside of a try/catch. I started doing return statements in the methods that were called to isolate the general region this was coming from. I found the error did not show up if I put a return right before the AJAX request, and showed up when I did a return right after the request. This told me something was happening inside of the request that caused the error.

After some additional digging, I found that in the case of a non-200 HTTP status code there are some rules it goes through to determine how to handle the error response. If it is not a 404 or a 500, it tries to parse the response and look for a relevant error message. It uses jQuery.parseXML() to convert it from a string to a document it can use XPath on.

When I did a return right before the parseXML() call, no error showed up. When I did a return right after, the error showed up. This told me it was happening somewhere inside of the jQuery code. What’s strange is that the call to this method was wrapped in a try/catch, the method was throwing an exception, and the browser displayed the exception in the console even though it was explicitly caught.

In that method, jQuery uses the DOMParser object, and it’s method parseFromString(). It’s call to that method is also wrapped in a try catch, so it seems strange the error was still showing up in the console. This method is a version of my Bottom-Up debugging technique.

I created a Fiddle to test this situation:

try {
var dp = new DOMParser();
dp.parseFromString(‘<a><hr></a>’, ‘text/xml’);
alert(‘Parse successful’);
catch (e) {

The HTML returned in the AJAX request was actually invalid XML. The HR tag never closed itself off. All browsers should be able to convert <hr> to <hr/> just like <br> is handled like <br/>. Chrome’s DOMParser was able to figure this out, but IE’s threw an exception.

I’m fine with it throwing an exception. I’m not fine with it showing an error in the console even though it’s coming from a call that’s inside of two try/catch blocks. It’s very difficult to explain to QAs why an error should be logged in one situation but not another. Fixing the HTML to be <hr/> would fix the issue, but I’m sure this will pop up again.

This happened in IE 9, 10, and 11. :(

KCDC 2014 Post-mortem

KCDC 2014 was my first conference. As a complete outsider to the conference world, I found KCDC absolutely fascinating. I have never seen so many developers in one place before. Being able to talk with other people in my field was such an amazing experience.

The diversity of expertise is one of the biggest selling points for me. I got to talk with people who had complete different skill sets and objectives than I do. It is a very humbling feeling to know there are gobs of people smarter and more intelligent than you are. It’s already helped inspire me to become a better developer.

The most rewarding part of KCDC was giving my own presentation:

Advanced JavaScript Debugging for Agile Teams

I went at 3:20 on Friday, May 16th. I got to attend five presentations before mine, so I got a good feel o how other people presented their topics. Although my presentation was later in the day than I would normally like, seeing other people give their presentation really helped me get into the zone and find what worked with this particular crowd.

The best presentations I saw were when the presenters got conversational with the audience. Having a conversation with ~100 people is difficult, but it can be done. Telling anecdotes, funny stories about something shining spectacularly or failing miserably, etc. all contribute to feeling like a true part of the presentation. Moving around and telling stories with their hands also made for a memorable presentation.

When I think back on my presentation, there are some things I definitely want to change for next year. I think including a link to my presentation on the printed presentation description is desperately needed. Having to frantically write down a URL to a person’s presentation is a pain point I saw in multiple presentations. I’m planning on including one when I submit my paper, then right before the presentation making the link live.

The second part of my presentation that needs to be changed is passing out business cards. Passing out business cards to everyone attending the presentation with the date, a link to my presentation, and a personalized thank you message would be an amazing personal touch. Building true relationships start with simple acts that lead to a true appreciation. Doing something that simple will make my presentation even more memorable.

KCDC 2014 was one of the most enjoyable three days I’ve had in a long time. I look forward to it next year, and am glad everyone involved in it spent the time to make my time there as positive as it was.

Dale Carnegie’s How to Win Friends and Influence People: Part 3

This is the third part in my series on Dale Carnegie’s How to Win Friends and Influence People. Part 1 talks about never criticize, condemn, or complain. Part 2 was about finding how a person feels important.

As I’ve been reading this book, I’ve found that there are many things I do subconsciously that Carnegie recommends. It’s good news that I’m already doing them, but bad news that I don’t understand the theory behind why they’re good. The next point Carnegie brought up was one of those I find myself doing all the time:

Lavishly give appreciation and encouragement

There are as many different ways to approach a problem as there are people that have ever lived. No two people are alike, so no two people will fix something in the same way. I’ve had the privilege of watching many different types of personalities attack extremely different problems.

I try to find common threads that help me in a broad range of situations. I must have subconsciously picked up during the process of being exposed to many different problem solvers the one thing they all had in common: a positive attitude.

No one wants to work in a negative environment. If I had to sit at my desk for eight hours a day surrounded by negativity, I would go crazy. Negativity spreads like a disease. People gravitate towards negativity because it is easy to be critical about a situation than try to fix it. Being negative towards something also helps break the ice, and gives people something common to talk about.

Unfocused negativity is a destructive force in the problem solving process. I have never solved a problem just by thinking about how much I didn’t want to solve it. The only way to effectively solve a problem is to believe you can sole it.

People that believe in themselves are infectious. If you had to spend 10 minutes around a miserable, dour fellow or a charismatic chap, the person who makes you feel happiest wins. The same is true for people you work with.

People know when someone is truly happy. A happy person radiates positive feelings to everyone around them. They help people get through the tough parts of problem solving. They let others know they appreciate them. They make sure people get recognized when they do something right. They are focused on the overall positivity of the team, not just their own feelings.

You can’t fake genuine happiness. Being happy comes from within. I am a very happy person, and make sure that everyone knows about it.



Dale Carnegie’s How to Win Friends and Influence People: Part 2

In my blog post yesterday, I talked about one of the first principles Carnegie brings up in his book:

Never criticize, condemn, or complain

My understanding of this principle is to try to understand where the other person is coming from when they made a mistake. Humans try to be rational with their choices. Understanding the context behind a decision allows lasting corrections to be made to a person’s behavior.

The next principle I found is spelled out in a few different ways. The way I think of it is the following:

Identify what makes a person feel important

Dale Carnegie argues that every action a person takes can ultimately be traced back to what makes that person feel important. If a person wants to be admired, they will put themselves out in the open more often than someone who feels important by making silent contributions to society. If a person feels important by pointing out flaws, they will not get along well with someone who finds their importance in perfectionism.

Our zeitgeist of this is the 5 Love Languages. There are so many things that go on in a relationship that it seems to be more of an art than a science. The love languages help characterize the way a person expresses their love to help the other person in the relationship understand their actions.

My love language is Acts of Service. I find myself taking care of chores without being asked, then expect to be thanked. I get frustrated when I am not thanked or recognized when I go above and beyond expectations. Because I know my love language, it helps me realize that my frustration comes from my own beliefs rather than the actions of those around me. Knowing how you feel important is critical to keeping yourself in check.

The same is true for those around you. Every single person is different in some way when it comes to what makes them feel important. Some people feel important when they ask a question and they get an immediate response. Some people’s importance comes from giving feedback, so I let them talk without interrupting them.

Having a legitimate desire to make a person feel important is critical to being successful in the work place. I am constantly in the process of figuring out how a person wants to feel important. By making them feel important, I end up creating a more positive workplace than if I just focused on making myself feel important.

Dale Carnegie’s How to Win Friends and Influence People

During my teenage years, my Dad suggested that I read Dale Carnegie’s How to Win Friends and Influence People. I did not read it because I was a teenager, and thought I knew everything. I recently checked it out from the library, and found out what I was missing.

If you’ve been living under a rock, How to Win Friends and Influence People is Dale Carnegie’s opus on office culture. Carnegie’s advice, even from a 1930′s perspective, is timeless and still extremely relevant today.

So far I’ve only gotten through the first part. Already I’ve started to make sense of the mystical, strange things that happen in the office on a day to day basis. It is truly amazing how much of his perspectives and advice are still extremely relevant in 2014. This post will help me solidify my understanding of his points by forcing me to explain them from my own perspective.

Never criticize, condemn, or complain

This is the very first principle introduced in the book, so I assume it’s pretty important. On the surface I have some pretty big disagreements with this principle. I did some thinking on the context in which Carnegie was writing this, which helped me understand where he was coming from with this piece of advice.

There are several things that happen when you tell someone they’re doing something wrong. The first is that the person immediately feels the need to defend their actions. Even if the person is doing something completely illogical, that initial reaction of defense will make it difficult for them to see they’re doing something wrong in the first place. This happens to me because my fight response is usually activated more often than flight.

The second thing that happens is the focus of the conversation goes down a path that will not produce a positive outcome. Telling someone they did something wrong focuses on the person, which is where the defensiveness comes from, rather than the action. More importantly, it does not try to address the reasons why the person took the action in the first place.

Understanding a person’s context is paramount to being able to fix incorrect behavior. Treating the cause rather than reprimanding the symptoms is the only way to produce lasting, holistic change.

Recently, someone emailed me a file to code review. This is a typical practice for smaller companies that do not have tools like Atlassian’s FishEye to help with the code review process. I was really surprised to get the email because I’ve done code reviews for this person before on FishEye for the past year.

I could have immediately replied back, said something snarky like “please put this on FishEye in the future before sending it to me,” and be done with it. Chances are the person would feel really bad, and not send me code reviews in the future because of my attitude in the hypothetical situation. Although my advice was correct, the end result produced a negative situation for the both of us.

I instead tried to put myself in their shoes. I tried to think through the considerations they must have thought about that prompted them to send an email rather than a link to a FishEye code review. Rather than criticizing, I tried understanding.

When I came at it from their perspective, I realized that they may have not wanted to commit something new that would not pass a code review. If I outright rejected the file, they would have to delete it. The git log would be forever stained with that class, which may cause issues down the road if someone was looking in the history and tried to use it. Commits in git are pretty permanent, so committing something completely new can be frightening until you get comfortable.

I replied back, and told them that committing then creating a formal code review is easier on both our ends. Feedback is much easier to see using a code review tool, and it makes conversations about code easier for the author. I told them it’s fine to push the code as long as it runs and doesn’t affect anything else.

The important part is that the response came from the perspective of the other person to me rather than me to the other person. I tried to figure out what they were thinking, then respond accordingly. I figured out how to make their life easier so in the future they would make my life easier. It is a little selfish, but it is mostly pragmatic. I have a lot that I need to do on any given day, so anything that saves me a few minutes is worth its weight in salt. Moreover, I also focused on increasing the productivity of the other person to give them more time in the day for their important tasks.

This fits Dale Carnegie’s advice and exposition in the book extremely well. What he doesn’t go into, which may be covered in the book, is what to do if the other person continues with the same behavior. My gut reaction would be to criticize them for not remembering, then explain why I thought commit/push/formal code review is preferable. If it happened again, I am not sure what I would do.

I think patterns that can be applied in many different real world situations are extremely valuable. Carnegie’s advice is good, but I am not sure yet how to implement it in every situation. I hope as I read the book I can get further clarification on how to deal with situations like the one mentioned above. It’s been very informative so far, so I look forward to adding to this series.

Adaptive vs Responsive Design

As a HTML5/JavaScript consultant at Keyhole Software, I get a lot of questions about new and bleeding edge technologies. Some of them are just hollow buzz words. Other represent tidal shifts in the way we develop modern web sites.

Responsive Web Design is one of the most important trends in web design since I’ve been doing this crazy work since 2004. It is one of those game changing paradigms like AJAX was when it was first introduced. Ethan Marcotte’s article on A List Apart is what got the whole thing started. It’s still a valuable resource for the fundamental principles behind RWD.

Before RWD, we had Adaptive Design. Many people use the terms interchangeably, but they are fundamentally different. It’s hard though to explain to someone who did not grow up with them why they are different.

This exact discussion came up recently at Keyhole, and I think I have an answer:

When you go to an Adaptive website on an iPhone, it says “hey, you’re using an iPhone, here is” If you go from portrait to landscape, the page stays the same.

When you go to a Responsive website on an iPhone, it says “hey, you’re screen is 460 pixels wide, here is a simplified version of the page.” When you go from portrait to landscape, the page says “hey, you’re screen is now 800 pixels wide, here is some more data.”

Adaptive websites make decisions based on criteria like the type of device you’re using. This is an anti-pattern because the website needs to keep a list of all of the browsers and all the devices that could possibly go to their website. They do not change themselves when the device’s representation of the website displays.

Responsive web design generally cares about one thing: how wide is the browser that the website will be displayed on. That ends up being the most important aspect for most cases. There may be some special things it does for an iPhone, but the display of the website is based on the width of the screen. When the width changes, it moves pieces of the page around accordingly.

Time-Oriented Debugging

Debugging code is traditionally more of an art than a science. Watching a master debugger work is like watching a master chef. There is so much that goes on in their brain that it seems like magic when they finally figure out the issue.

One of my core motivations for this blog was to document my debugging techniques. Being able to isolate and elaborate my techniques has made me a better debugger in general. I’ve found that explaining how I debug has made me consider debugging a science rather than an art.

The motivation for this blog post came about from a real-life issue that I needed to debug. There was a JavaScript error that happened when the user clicked a button. The error was deep into the call stack. It also just started happening recently. I could have quickly fixed the issue by putting in an if-else statement, but the fact that it stated happening recently made me curious.

I looked around in the recent commits for a few hours, but found nothing that pointed me towards the source of the issue. I kept looking and looking without any results. The fact that it happened recently told me there must have been a change somewhere. If I had kept on this path, I would have spent countless hours and eventually found the issue.

Instead of spinning my wheels and burning time, I decided to take a scientific approach to debugging. Traditional debugging involves looking at and comparing code. Profiling, analysis, and breaking on exceptions are all code-oriented debugging techniques. There are several implementations and opinions on how to debug, but they all focus on the code itself.

Time-oriented debugging is a way of debugging that compares snapshots of the same code base at different times. In my case, I was comparing the current version of the code base against the Jan 1st, 2014 version. I chose that date because it is a nice even number, and hopefully that version should be in a working state. When I rolled back my repository to that version, I saw that clicking on the link did not produce that JavaScript error. Yay!

This means that there is a change in the code between Jan 1st, 2014 and today that is causing this issue. If I isolated my search to just those changes, it would be around 2,000 commits. That is still too much for me to look at, so I decided to refine my search again. I checked out my repos to the Feb 1st, 2014 version. If the bug happened in this version, I would know that there was a change sometime during the month of January that caused this bug. If the bug did not happen, then I could ignore the January changes as the source of this bug. The bug did not happen in the Feb version, so I was able to prune my commit set down to 1,500 commits.

I repeated this process until I got to May 1st, 2014. The bug occurred in this version, but not in the April 1st, 2014 version. Using the same principle to my Binary Search JavaScript debugging technique, I tried the April 15th, 2014 version. The bug did not occur, so I know it was somewhere between April 15th and May 1st, 2014. I then tried April 25th, 2014, and the bug did occur. This pruned my commit set down to just 10 commits.

I could have repeated this technique till I identified the exact commit by narrowing my dates even more. The bug did not occur on April 23rd but did on April 24th. It did not occur at noon but did at 3 PM on the 23rd. This narrowed my search down to one commit, which was ultimately the culprit.

The code base I’m using are a set of git repositories. Git is very helpful for this kind of debugging as it offers an easy command to checkout the repository at a specific date. This is the command I use to do the date checkout:

git checkout `git rev-list -n 1 –before=”YYYY-MM-DD HH:SS” BRANCH`

The project I’m working on is composed of a dozen different git repositories all tied together through maven dependencies. Checking out one repository at a specific date may not work as the other repositories contain different expectations and could use newer features not in the old version.

Making sure that I check out each repository at a specific date is the only way to get the project close to a working state. When doing time-oriented debugging, I create a shell script that goes into each repository, stashes the changes, runs the command, then repeats the process for the next repository. I also have a date variable at the top of the script to make the process of binary search just a little bit easier.

Ask n+1 Questions

The process of a manager assigning a task is a process that happens every minute of every hour of every work day. I don’t have any stats on it, but some being assigned a task must have happened multiple times during the writing of this post. Such a ubiquitous process should be refined down to an art. Sadly, I see the process fail, both on the side of the manager and on the side of the asignee.

The biggest miss that happens during a task assignment is missing communication. There is often one important piece that needs just a little more elaboration. When that one small piece is missing, the coder can lead themselves off one way while the manager expects them produce something completely different.

Damage to the product can be minimized if the coder realizes something was missed. A brief conversation to get the coder back on track is all that is often needed, but time and resources were wasted due to the lack of communication. Time one of the most valuable and finite resources in a work place.

Breaks in communication like this are easy ways to suck up resources. If left unchecked, it can become a serious issue in the development of a product. There is fortunately a technique I use every day to help mitigate this problem:

Before I tell someone I can code something, I pause for a few seconds then ask one final question.

Pausing allows my brain to catch up with the conversation. Discussions usually flow many different ways and talk through different possible solutions before one final solution is agreed upon. Ambiguity can easily creep in the longer the discussion takes place. Pausing is a vital step to make sure there is as much comprehension of the final solution as possible.

Asking one final question is also a way to make sure that the coder understands the proposed solution. If their thinking is in a different place than the solution, asking one final question will often show how far off they are. The technique has a very high success rate due to the abstract nature of coding. It is difficult to misunderstand someone yet ask an insightful question that parallels their original thinking.

The technique of one final question also works when the coder is describing the code to a coworker or technical manager. I’ve found that in these types of conversations the first 95% of what the coder says will be in line with the solution, but the last thing they say almost in passing will be way off the mark.

This 5% in passing bits me frequently. I can be describing something flawlessly, then as soon as I’m wrapping up I’ll say something that is totally in left-field. It will sound great in my head, but as soon as I say it I realize that it was different than the proposed solution.

There is a tendency among coders to write off that incorrect 5% as just the coder incorrectly communicating it out. In my experience it is written off because programmers do not like confrontations. The best thing to do in that situation is to ask another clarifying question to the coder.

Leaving that incorrect 5% will always cause issues down the road. Assuming they understand everything is a common pain-point that can be eliminated by simply asking another question.

In both scenarios (manager to coder and coder to manager), asking one more question is paramount to the success of a project. It is an easy technique to implement, and has no cost associated with it.

Failure Analysis

I haven’t posted on here in about two weeks. In my last post, I called myself out on not living up to my own expectations. I tried to blog once a day every day, but I failed and ended up not blogging for a few days. There are several important points that came out of my inability to keep up with the expectations I set for myself.

The first is that true, sustainable growth can only start when an area of weakness identified. Think about the last time someone called you out on something. You probably felt defensive, and gave an immediate response why they are wrong. This is my first instinct to confrontation, and it has inhibited my growth for many years. Inability to take criticism is one of the biggest weaknesses of the current generation.

It is a sign of genuine concern for a person’s growth when someone with more experience alerts a peer to their inefficient behaviors and patterns. It is the duty of those with more experience to mentor those with less, and put them on the right paths.

The most successful people I’ve met are constantly evaluating themselves. They know all of their weaknesses. They tweak and evaluate how well they are working to mitigate their weaknesses. They are their toughest critic. Being able to take feedback from both external and internal sources is paramount.

The second point is that failure should be analyzed and dissected. It is temping to treat failure as an end to a process. People tend to shy away from useful criticism in favor of people-pleasing attitudes. Phrases like “you did your best” and “you’ll do better next time” are encouraging, but are focused on feelings instead of success of the individual.

The best example I know of this is Elizabeth Spiegel. She is the focus of an upcoming documentary on I.S. 318 called Brooklyn Castle. It’s about a lower income middle-school in Brooklyn that has the best chess team in the nation. I first heard about her in an excerpt from How Children Succeed.

My favorite part is when she is talking to a student about the match the student just lost. It begins with cliches like “the other guy was simply better than me” and “he had good skills…good strategies.” Rather than leaving it at that, Spiegel digs deep into why the student didn’t win the match. After some talking, she hits on the issue:

Spiegel stared at Sebastian. “How long did you spend on that move?” she asked. “Two seconds.” Spiegel’s face grew cloudy. “We did not bring you here so that you could spend two seconds on a move,” she said, a steely edge in her voice. Sebastian looked down. “Sebastian!” He looked up. “This is pathetic. If you continue to play like this, I’m going to withdraw you from the tournament, and you can just sit here with your head down for the rest of the weekend. Two seconds is not slow enough.” Her voice softened a little. “Look, if you make a mistake, that’s okay. But you do something without even thinking about it? That’s not okay. I’m very, very, very upset to be seeing such a careless and thoughtless game.”

This kind of feedback seems very blunt and counterproductive, but it is exactly what the student needs to hear to win the next time that situation arises. Real and honest feedback is a central tenet to How to Win Friends and Influence People. When used with grace and care, good feedback can help correct big mistakes and produce positive results.

So, in the spirit of self-analysis, I took a look at why I didn’t meet my goal. Blogging every day is hard. There are some days when I have extremely little motivation to blog. When I kept digging, I found out these days are called “weekends.” I tended to do my best work on work days, so it makes sense that I should focus on what is already working well.

As such, this blog will be posted once a day every week day for as long as I can keep it up. If I fail again, I will look back and figure out why I did not meet my goal.