Author Archives: bill

Dr. Documentation

dctr

Don’t forget to buy Design, Code, Test, Repeat.  It’s a fun, funny, and helpful read.

Recently, I’ve gotten to the point in my release cycle where I’m almost ready for Beta(!) on my IDE for uCLinux uboot, kernel, and application development, Fusion MMX.  Building it has been a lot of fun and very educational as well.  I’ve been able to find so many useful open-source utilities to make development easier.

Of course, that means that some documentation is in order.  I’ve written plenty of documentation in the past, most recently for GTO, a Java application.  For that product, I chose to use JavaHelp, which wasn’t difficult to learn or use, but it was a rather manual process of taking screen shots, trimming them, labeling them, etc.  I couldn’t find a free (we’re a small company, so we like free) environment for creating this and I didn’t want to have to go through the manual process with all of the menus, dialogs, toolbars, and context menus for Fusion.  I also didn’t want to have to learn the ins and outs of Microsoft’s help compiler environment if I didn’t have to.  I just wanted to write the documentation, if possible, and let someone else take care of the busywork.

While I couldn’t find something free, I did find the next best thing: something that was so good and so inexpensive that it paid for itself – Dr. Explain.  What I found there was an application that was simple to use, handled the details of the help environment, and made documentation incredibly easy.  The one feature that literally paid for itself was the UI capture tool.  Start the tool, then focus on a UI element (window, menu, toolbar, dialog) and click.  Dr. Explain takes a screen shot of the element, then labels the individual items to be documented.  Holy cow, what an easy way to do documentation.  The creation of internal and external hyperlinks made cross-referencing a breeze.

Finally, I can export it to html, chm, or rtf for maximum flexibility.  For my next revision of GTO (the java-based application), I’ll be trying to use Dr. Explain for that documentation, too.  I don’t usually write product reviews, but when I run across something that I like this much, I want to share it with my fellow developers.

Eating Your Own Cooking

There’s nothing like eating your own cooking to tell you how the food is.  Unfortunately, the pride we get from doing it ourselves can sometimes cloud our judgment.  The same thing applies to just about any other human endeavor.  People often have an inflated opinion of themselves and what they have or can accomplish (I’m no exception).  If you need any proof, just watch the first few weeks of American Idol.

Those of us in the software business tend to think that our own software is way better than anyone else’s.  Of course it is – you wrote it yourself, didn’t you?  Unfortunately, your competitors are filled with people just like you.  They’re probably just as smart as you and have the same pride in their work and their resultant software.  No one is beyond this kind of thinking – not even Joel Spolsky.  He wrote this a few months ago:

I had to wonder. We do have a large competitor in our market that appears to be growing a lot faster than we are. The company is closing big deals with big, enterprise customers. And the wheels are falling off the donkey cart over there as the company stretches to fulfill its obligations. Meanwhile, our product is miles better, and we’re a well-run company, but it doesn’t seem to matter. Why?

Step One, I think, is to pluck off our biggest competitors. We’re pretty certain that we’ve already built a great product that meets our customers’ needs — but there are still too many cases where we find out that, for some reason, someone went with the other guy. So that’s the development team’s mission for 2010: to eliminate any possible reason that customers might buy our competitors’ junk, just because there is some dinky little feature that they told themselves they absolutely couldn’t live without. I don’t think this is going to be very hard, frankly. Developing great software is something I’m pretty sure we’re good at.

Those are strong words. “Competitor’s junk”?  That’s a very common way of looking at your competition and it clouds your judgment because it’s usually wrong.  “Pluck off our biggest competitors”? If that’s so easy, why hasn’t it happened already?  I love Joel’s blog and admire his goals for his company, but there’s a lot going on and going wrong here.

The responses to his article were interesting. One in particular shows how personal our feelings are about our own software:

JIRA [a competitive product to Joel’s Fogbugz] is a great product. I last used Fogbugz in June 2008, and then moved to a company using JIRA. It’s a real pleasure to use, which is good, because I use it for hours every day. Fogbugz was not a pleasure to use. Maybe Fogbugz is way better now, but if I were in a position to choose for another company, I’m pretty sure it would be JIRA all the way.

So, how do you get past this? One option is to eat your own cooking and the cooking of others. Get a copy of your competitor’s software. Dive into it and really examine its strengths and weaknesses. Find out what their customers like about it. Find out why they didn’t buy yours. Your sales and marketing staff is supposed to do this at your company.

On a more personal level, what can you do to improve your software? Use it yourself. If you can get a copy of your competitors, use it as well. What takes less time to get similar tasks done. How easy is it to do the job? What bugs do you find? Are there dead ends? Are there features missing? Does it take multiple steps to get a simple job done? Is there a method that’s counterintuitive or that requires users to change their way to doing business (this is big roadblock for some people)?

As a solo developer, I have the benefit of being the product designer as well as the coder. If I don’t find something easy to do in my products, I change it. If I can’t do something in the product, I add a new feature. If I run across a bug, I fix it. Note: when you run across a bug in your software, make sure that you either fix it or enter it in the bug database. It’s too easy to ignore bugs you live with every day because we developers are more tolerant of our own bugs – don’t be.  And don’t assume because you and everyone else lives with the bug that it’s in the database unless you check.

Finally, try to be objective. Stop pretending you love your own software so much and pretend you’re an end-user working with it for the first time. Then you’ll get an idea of why it’s so good or why it needs improvement.

Community

Gads, I’ve been writing software for a long time.  I started my professional career in 1986, writing LISP on Symbolics machines.  Back then, there was no web (well, not as we know it today) on which you could look up easy answers to coding problems, share toolkits, or converse with other developers (well, there was usenet, but it wasn’t the same world as it is today).

Today, we have a virtual community of developers.  While our companies may compete, it wouldn’t be unusual for two developers to accidentally help each other by responding to messages on a help board such as Stack Overflow.

Recently I posted a question there that I knew would elicit responses such as, “Why are you trying to do that?”  I know what I’m trying to do might be loony, but it seemed to make sense at the time.  Working alone at home, I don’t have the same personal networking with my colleagues that I used to have at previous jobs.  Sometimes I miss the interpersonal relationships, the banter, and the ability to bounce a nutty idea off another developer.  Instead, I do web searches and ask questions on forums.  At times, it can even be a little embarrassing to ask a question on a forum, but the fact is, everyone’s in pretty much the same boat.  Most developers are just like you and me – nice people, willing to help or give you and hand, and expect the same in return.

It’s a community of software developers, who write toolkits, utilities, sample code, and free applications that help us all get our work done.  I don’t know if Richard Stallman is right about all software being free, but I do know that with the free exchange of ideas we all write better software.  A big thanks to my fellow developers around the world.

Perfect Gift for a Software Engineer/Programmer/Manager

The time of year has rolled around once more where gift-giving is the order of the day.  Sure, this is a shameless plug (have I ever claimed to be shameful?), but I can’t think of a better gift for your friend, spouse, colleague, or manager than my book – Design, Code, Test, Repeat.  It’s probably the funniest book about software you’ll read, but it’s also informative.  I introduce you to my friends’ and my best and worst experiences in over 20 years of software development and management.

Here’s just a sampling of the topics in the book:

  • Interviewing – How to suck and how not to suck at it.  In these times of job-hunting and layoffs, avoiding mistakes and steering interviews are invaluable skills.
  • Handling yourself professionally on the job and dealing with process, projects, and people.
  • Best practices for your projects.
  • Best practices for your career.

Not only is there a wealth of information, but to keep things fun, it’s filled with small cartoons and drawings.  For your perusal, I’m including another small excerpt.  Here’s a story about a friend, Bob, who was interviewing a guy for a software position.

The Philosopher

Bob was interviewing people for a position on his team and found a guy named Ivan who was about to graduate with a Ph.D. in computer science from a nearby university. In the past, they had had some very good luck hiring smart people who were lacking in some software experience and teaching them how to write software. If you have an engineering background, you’ve probably done a bit of programming in school anyway and the problem-solving skills are useful in both fields. This guy even had a background in computer science, so while his practical experience seemed to be lacking, he seemed promising.

They had Ivan come in for a half day of interviewing. He was polite and likeable, but clearly lacking in experience – pretty much what we expected. The problem was that for a guy who had very little practical experience, he had a philosophy about everything. He’d say things like, “My philosophy on starting a new coding project is to sit down and do some rough design work before starting a prototype.” It sounds reasonable enough doesn’t it? But since he’d never had a real job, it was a bit questionable. Additionally, his answers to most of the other questions were just vague philosophies as well. Now this guy had been a teaching assistant for a Java class, so he should have been able to come out with something concrete based on his work on a Ph.D. in computer science, right?

Unfortunately, they didn’t do a great job that day of really testing his Java coding skills. Instead, even though they had doubts, they hired him under the assumption that like our other people fresh from school that the equations:

Education = Brain

Brain + Mentoring = Future Valuable and Productive Employee

would hold true. It didn’t. The guy couldn’t code his way out of a paper bag. They tried to get his feet wet by having him check some code out of our source code repository, copy and paste some changes into the files, compile and test them, then check them back in. Believe it or not, he needed help with the copying and pasting part. Not how to use copy and paste tools, but finding the same code in the other files and putting the right code in there. After giving him several mentors, having him audit another Java course, and giving him 9 months (much too generous) to get up to speed, they had to give up and let him go. He went back into academia and is a Professor somewhere now. He was indeed a smart guy, but just wasn’t made for the kind of work they were doing.

In the end, if you have doubts, you’re better off passing on a candidate or perhaps having a short trial period, if that’s possible, to truly assess whether you have a winner on your hands. Better yet, try some of the suggestions below to remove the doubts and clarify the candidate’s true potential.

Have a great holiday.

Excerpts – Part 1

dctr

Don’t forget to buy Design, Code, Test, Repeat.  It’s a fun, funny, and helpful read.

Some authors are releasing books based on blog entries.  Well, I’m going to go the other way around.  I’m going to publish a few blog entries based on my book,  Design, Code, Test, Repeat.  Here are a couple of sections from Chapter 15:  It Doesn’t Get Any Better Than This – Best Practices.

Dominance and Submission
One of the things a couple of companies did was to use sub-mission documents. When you checked in your code, you filled in a simple form with information about what the code was for, what files and versions were involved, and what bugs you (may have) fixed. This document was checked into the source control system and emailed to your colleagues. Although writing these was somewhat tedious, they were very helpful in seeing what files went together as a bug fix or new code submission. If the build broke or a new bug crept into the system, you might be able to spot what happened by reading through some of these documents. They were also very helpful in tracking who was doing what. Several people would read these after returning from vacation to see what had been going on while they were away. Another benefit was that simply reviewing your sub-mission documents for the week made it easy to write your weekly status report.
These documents were referenced in the bug tracking database and the comments for the files that were checked in. This allowed for easy cross-referencing. If you knew the bug, the file(s), or the submission document, you could trace any desired information from there.

Put Down the Keyboard and Step Away From the Code!
As your release date gets closer, you’ll likely be pushing to fix all of the bugs in the system. If you’re not using a bug tracking system – and you should be – then you’ll probably be using a common spreadsheet or some other method. All of the bugs in your system should be rated according to their severity and desirability to be fixed before release.
It’s unfortunate, but your software is probably going to ship with some known bugs in it, simply because it needs to get out the door on time. However, just because you have a bug doesn’t mean it should be fixed. First of all, bug fixing time shouldn’t just be a free-for-all. Developers are more likely to spend time fixing the “low-hanging fruit.” These are the easy bugs to fix or the ones in the developer’s own code that they find most embarrassing. You may wish to let them have some time to do that, but then you should really concentrate on the most important bugs – the ones that crash the system and block functionality from working. Towards the very end of the release, only specific bugs should even be permitted to have fixes. This will prevent the “fix one bug, create two more” syndrome from keeping your release from shipping.
Managing this time well gives you the opportunity to truly control the quality of the software you send out and when it gets sent.

2D Graphics? What’s that?

dctrDon’t forget to buy Design, Code, Test, Repeat.  It’s a fun, funny, and helpful read.

I don’t see a great need to go into too much background on 2D graphics, because the implementation in hardware frame buffers and display is not of interest to most programmers.  What is interesting when you have to do some programming is your point of view and other things that you can control easily from a software standpoint.

When you’re writing code for 2D graphics, you’re usually starting with a library or graphics environment, C#, Java, OpenGL and C++, DirectX and C++, etc.  I’m going to further limit this discussion to the C#, Java, and other environment where your drawing area starts with y=0 in the upper left hand corner with y increasing as you go down the screen.  I’ve seen too many novice programmers try to get some real graphics code written without even a hint of where to go.  I’m going to keep things somewhat esoteric for this post and start with some basic concepts that might help you if you need to develop some graphics code for a particular application.

Starting with y=0 in the upper left corner is great for text applications when you want to fill the screen and add scroll bars, but for graphs and drawings it stinks.  Wouldn’t it be more convenient to have y going up, like you learned in grade school?  What about having the origin in the middle of the screen rather than a corner, so you could have negative coordinates handled naturally?  The way to do this is NOT by hacking together a bunch of offsets and monkeying with them until the picture looks good (I learned this the hard way a long time ago).  The proper and ultimately easier way is to use simple transformations to do the job.  The main way to do this is by using a window to viewport transformation.  The idea is to take your world (the stuff you want to see), look at some or all of it (like looking out of a window at the world) and putting that onto a screen (or window on your computer), which we call the viewport.  The viewport is normally defined in normalized device coordinates (referred to as NDC, they go from 0 to 1, rather than 0 to 500, or whatever your viewport size really is).  The NDC are then scaled easily to match your actual viewport size.  There’s a simple transformation that accomplishes this and there’s a reasonable explanation here: windows to viewport.  The one thing you’ll need to add is to negate the y coordinate to make y go up instead of down.

To make your entire world visible in the viewport, you simply increase the size of your window (not the computer window, the window into your world) to the size of the stuff that’s in your world.  The transformation, then reduces this to the computer’s viewport and you see everything.  If you want to zoom in, you make the window smaller.  To see other parts of your world when you zoom in, you move the window to the right, left, up, or down.  Graphics programs usually use pan and zoom tools to accomplish these actions.

I’ll add just a couple more handy concepts to help get you started on the right foot.  Most programs are best off having a set of entities stored in memory.  I know, you’re thinking, “duh”, but I’ve seen people read files from disk on every display update and it’s not pretty.  Having a set of entities in memory allows you to quickly loop through them and display them all.  Additionally, you can calculate a bounding box for all of the entities so that you can set the window to zoom to the extents of your world.

There are some other concepts, such as clipping and selection that can come in handy, but that’s for another day and for them most part, clipping is handled automatically by the graphics engine you’re using.  Selection is also handled by some engines, too, and if not, it’s easy to implement.

If there are any concepts that you’d like more detail on, let me know by sending me an email: bill at wandercoding.com.

Comunikashion

I was reading Jeff Atwood’s post yesterday entitled, Email: The Variable Reinforcement Machine.  In it, he suggests that checking email frequently makes you less productive.  He goes on to say that various types of communication are better forums for some information than sending out emails.  As overuse of email has been a pet peeve of mine for a long time, I found it quite a good post.  However, several people misunderstood his points and are so stuck in the “email is how I live” that they closed their minds to the possibility that he had some good points to make.

His initial point was that checking your email basically interrupts your “flow”.  Flow being defined as the state in which you finally manage to boot your brain up with all relevant and necessary information needed to become productive.  This process usually takes about 15 minutes to achieve and once attained, time seems to fly by and the amount of work you accomplish can be quite large.  However, it’s easy to interrupt flow and one sure way is to check your email frequently.  Several people suggested that they don’t do that and that the answer was to turn on email notifications instead – problem solved.  But, not really.  Instead of interrupting your own flow, you now have a little popup in the corner of your screen that interrupts you automatically.

His other point, was that email is just one form of communication and not always the best for the task.  I’m not a fan of having too many venues for information, but there certainly are times where some are better than others.  If you have information that should be accessible about procedures, product/project statuses, etc., perhaps a wiki would be a good place to keep people informed about the latest and greatest.

One major value of email lies in its ability to replace the old hardcopy memo.  Used to be that you’d get a memo in your mailbox telling you about a new company policy or upcoming meeting, you’d put the memo on your desk and a few hours later, it was buried and forgotten.  Email allows for much easier distribution of mass announcements.

One area that email gets dicier is when you want an answer to a complicated question.  I think in this day and age, especially for younger folks, the art of conversation is dying.  Picking up the phone or stopping by is considered an intrusion or something to be dreaded.  It’s so much easier to send an email and simply wait for a response.  Unfortunately, this is now the default behavior, even when it’s not the best option.  I’ve slogged through so many verbose, confusing emails that I’ve had to pick up the phone and ask what was going on.  What then was the point of spending a half hour composing it in the first place.  Some things are just so difficult to describe, they deserve a conversation.

One other time that email is a time-waster is when time is of the essence.  Sending an email and waiting for a response to a time-sensitive question will send you into a tizzy while you twiddle your thumbs waiting for an answer.  Why not just call first?  If you can’t get the person, send an email as a backup to the voicemail you should have left in the first place.

I started working in software before email was used in most office environments.  Back in the day, I’d get dozens of phone calls and office visits interrupting my day.  Over the years this transformed into receiving tens or over a hundred emails a day filled with FYIs, forwarded jokes, chain letters, spam, and actually important emails.  Balancing between the two is a nearly lost art, but if you work on it, it can benefit your productivity greatly.

Run Away From This College (The Worst Salespeople)

I’ve been traveling with my family lately looking at colleges.  In April, we visited several in New England.  Campus visits usually have two main components – an information session and a tour.  They are both opportunities for colleges to show off their campuses and overall educational programs.  Unfortunately, most only do a reasonable job on one end – the tour.  After sitting through many information sessions, we finally gave up on them.  Sitting for an hour listening to an admissions officer blather about SAT scores and what made their college special became intolerable after several schools.  The best sessions used slide shows and had students help with the presentations.  The students were always more enthusiastic than the admissions people and most spoke very convincingly about why they loved the college.  The funny thing is that the professionals usually did a horrible job.  One of them began by saying, “What so special about Blah University?  You will be ripped from your comfort zone.”  Yes, he really said that.  I don’t know about you, but I don’t really look forward to that, so how do you think my high school senior daughter felt?  Next college, please.

One campus “tour” consisted mostly of walking to four places on campus (we only actually entered one building) and talking for 15 minutes at each location.  It was boring as hell and we didn’t get a very good feel for the place at all.

All in all, I still think it’s hard to pick a college and this format doesn’t work that well.  So, why don’t colleges take a hard look at the process and put their brains together to improve?  At the very least, why don’t they take a look at their existing sessions and tours and see if they can be improved?

I honestly don’t know the answer.  I don’t even think the problem is that difficult.  Some places even have feedback forms.  I suppose if you already get more college applications than spots for everyone, then there’s no incentive to improve things, which may be part of the problem.  That just leaves the issue of whether it should be illegal to bore potential customers to death.

I have been involved for software for a long time and one thing that always fascinates me is sales and marketing.  It’s not easy and I’m afraid that many companies do a poor job of it.  At one interview I had years ago, I asked what the return on investment was for their product.  They didn’t know.  I suppose they didn’t do any studies or calculations on it.  For a product that I recently developed, we knew going in that it would be easy to justify purchasing it.  It will pay for itself the first time you use it.  Who wouldn’t consider buying a product that does that?

Take a look at the marketing materials you have – paper, web sites, etc.  And take a look at the sales presentations you do?  As yourself – “If I were a customer, would I want to buy this?  Does it justify itself in terms of savings?  What about any other factors?”  If not, you’d better take a look at the product or the sales/marketing.

Morphing

I’ve been writing code for a long time – professionally, since 1986.  In that time, I’ve learned tricks and strategies for making it more robust, more flexible, faster, etc.  I’ve planned software to the nth degree and I’ve written it off the cuff.

I’m a firm believer in prototyping.  I like to get something up and running as quickly as possible so that I can grow it, play with it, see what design changes make it better, etc.  It’s very difficult to keep a lot of variables in your head at once and having thing written down, even code snippets, makes it easier to juggle thoughts.

One of my personal strategies is to keep a notebook.  I outlined this as a personal best practice in my book.  I’ve been doing this since my days as an engineering student.  Although I don’t do this as a legal document, I do find it useful for many things.  I jot down ideas and alternatives, I track to-do lists, I diagram code, and doodle icons.  Since one of my friends introduced me to engineering paper (it has a faint grid on it), I’ve preferred using quadrille ruled (like graph paper) notebooks.  This is partly because of my previous life in solid modeling and computer graphics, as graph paper makes drawing things a bit easier for me.

When I work on a new project, I try to keep in mind the big picture, but I’ve found that having a prototype makes it easy to play with ideas as long as you don’t go too deep.  I’ve tried many time to plan code solely on paper (or an electronic document), but found that, especially with an existing code-base, I’m usually wrong.  It’s irritating to find that once you’ve carefully planned your code, that as soon as you try to implement it, you find out immediately that you were planning to modify the wrong classes.  Also, the amount of planning should depend on the size of the project.

I’m also a firm believer in phased development.  Being able to give the customer (even if it’s the marketing department) something to look at and comment on, is invaluable.  People have an easier time understanding what you’re talking about when they can see it, rather than imagine it.  In my current project, I’m trying to replace an existing application that was developed as a prototype (by someone else).  Now I’m able to start over with a good idea of what my customer is looking for.  This is happening with staged development, too.  My customer currently has an application that he can play with and comment on.  Since it was developed in phases, he hasn’t had to wait for a year before there was something to work with.

On the other hand, the requirements are now growing.  This is requiring some code enhancements that I hadn’t expected and is challenging some assumptions that I’ve built in.  Fortunately, code is morphable and as long as it’s not written completely horribly, can be changed without starting over.  Constant refactoring is key to this process.  I’m continually taking code snippets and creating new methods, making all of my methods smaller.  Being happy with refactoring and not beating yourself up about prior decisions is important.  When I morph new features into my code-base, I prefer to do it piecemeal, testing along the way, rather than making giant changes and fixing dozens of bugs at the end.  In the long run, I think it produces more robust code and provides the instant gratification feedback along the way.

For example, the latest change I’m making is to allow for sub-directories in a set of C files to be compiled in my application.  I had assumed that there would be no need to have sub-directories (there weren’t any examples in the old code-base).  To accommodate this, I needed to add new menu items, new file save and load routines, and ensure that they new files would compile properly.  The easiest way to get started was to go to the end first.  I added the information to my saved files and enhanced the loading code.  I only took an hour or so to make the necessary changes and I knew that things would work.  I proceeded to work on the UI and that’s when the fun really started.  But, with refactoring and a lot more notes in my notebook, it will get done soon enough.

As Jeff Atwood points out, What’s the worst code you’ve seen recently?  My own.  Does this thrill me?  No, but I’ve learned over the years to cut myself some slack.  My code is no worse than anyone else’s, I know how to make it better, and I can morph it into a beauty.

An Itch = A Niche

In my book, Design, Code, Test, Repeat, I talk a lot about the things that make you a better and more valuable software developer (or other related software person). Many of these things are the intangibles of what makes one developer better than another. It’s hard to quantify software development. Joel Spolsky notes in his post on measurement that people usually work towards what’s being measured, making the original goal of improving overall performance using measurement, useless. This is one reason why I always hated performance reviews – you were always supposed to have measurable goals included for the year. If you were able to add a few, they were usually either bad goals that had little to do with what your job was really about or they weren’t measurable, which was more likely.

So, getting back to the intangibles. On numerous jobs, I have found myself drawn to niches. It’s not uncommon to find that one aspect of programming or your product seems to beckon. Maybe you like fussing with the UI to make it more beautiful or usable. Maybe you like the API layer because that’s what other programmers (or even your fellow programmers, plus you) will see of your product. Maybe you enjoy working more on the internals – providing core functionality, improving speed, finding new ways to solve the fundamental problems that your software is supposed to address.

These itches that pique your curiosity and passion become your niches. They become part of what make you valuable not only to your current company, but also your next potential company. When you advertise yourself on your next performance review or on your resume, be sure to include things that make you unique. They will become talking points for you in your interactions that relate to your career.

It’s important to keep your niche(s) current and flexible. Being the renowned expert in writing FORTRAN on punch cards isn’t really all that useful anymore (yeah, that’s an extreme example). Try this one – how about being an expert on a now defunct database engine? Hitching your niche to a particular technology isn’t the way to go either. It is a way to develop in-depth knowledge of an area, but it’s important to advertise the field as opposed to the specific brand. So, you’re an expert in database customization, not an expert on Debacle DataKing 5.0. The latter is something you mention later when you’re providing proof that you are a master of databases.

The final word here is to keep your niches vital. It doesn’t do any good to be the last surviving employee who remembers a particular product or technology. OK, maybe it will keep you in the company and deliver you a paycheck, but it’s unlikely to benefit you in the long-term. Keeping your niches current, finding out where your company or the industry is going, and adding them to your repertoire is what makes you valuable in the future.