Give five questions that a programmer should ask about errors in the problem definition phase. (5)
1) Writing Code Without Planning
High-quality written content, in general, cannot be created easily.
It requires careful thinking and research. High-quality programs
are no exception.
Writing quality programs is a process with a flow:
Think. Research. Plan. Write. Validate. Modify.
Unfortunately, there is no good acronym for this. You need to
create a habit to always go through the right amount of these
activities.
One of the biggest mistakes I have made as a beginner programmer
was to start writing code right away without much thinking and
researching. While this might work for a small stand-alone
application, it has a big, negative effect on larger
applications.
Just like you need to think before saying anything you might
regret, you need to think before you code anything you might
regret. Coding is also a way to communicate your thoughts.
Programming is mostly about reading previous code, researching
what is needed and how it fits within the current system, and
planning the writing of features with small, testable increments.
The actual writing of lines of code is probably only 10% of the
whole process.
Do not think about programming as writing lines of code.
Programming is a logic-based creativity that needs nurturing.
2) Planning Too Much Before Writing Code
Yes. Planning before jumping into writing code is a good thing, but
even good things can hurt you when you do too much of them. Too
much water might poison you.
Do not look for a perfect plan. That does not exist in the world of
programming. Look for a good-enough plan, something that you can
use to get started. The truth is, your plan will change, but what
it was good for is to force you into some structure that leads to
more clarity in your code. Too much planning is simply a waste of
your time.
I am only talking about planning small features. Planning all the
features at once should simply be outlawed! It is what we call the
Waterfall Approach, which is a system linear plan with distinct
steps that are to be finished one by one. You can imagine how much
planning that approach needs. This is not the kind of planning I am
talking about here. The waterfall approach does not work for most
software projects. Anything complicated can only be implemented
with agile adaptations to reality.
Writing programs has to be a responsive activity. You will add
features you would never have thought of in a waterfall plan. You
will remove features because of reasons you would never have
considered in a waterfall plan. You need to fix bugs and adapt to
changes. You need to be agile.
However, always plan your next few features. Do that very carefully
because too little planning and too much planning can both hurt the
quality of your code, and the quality of your code is not something
you can risk.
3) Underestimating the Importance of Code Quality
If you can only focus on one aspect of the code that you write, it
should be its readability. Unclear code is trash. It is not even
recyclable.
Never underestimate the importance of code quality. Look at coding
as a way to communicate implementations. Your main job as a coder
is to clearly communicate the implementations of any solutions that
you are working on.
One of my favorite quotes about programming is:
Always code as if the guy who ends up maintaining your code will be
a violent psychopath who knows where you live.
Even the small things matter. For example, if you are not
consistent with your indentation and capitalization, you should
simply lose your license to code.
tHIS is
WAY MORE important
than
you think
Another simple thing is the use of long lines. Anything beyond 80
characters is much harder to read. You might be tempted to place
some long condition on the same line to keep an if-statement block
more visible. Do not do that. Just never go beyond the 80 character
limit, ever.
Many of the simple problems like these can be easily fixed with
linting and formatting tools. In JavaScript, we have two excellent
tools that work perfectly together: ESLint and Prettier. Do
yourself a favor and always use them.
Here are a few more mistakes related to code quality:
— Using many lines in a function or a file. You should always break
long code into smaller chunks that can be tested and managed
separately. I personally think that any function that has more than
10 lines is just too long, but this is just a rule of thumb.
— Using double negatives. Please do not not not do that.
Using double negatives is just very not not wrong
— Using short, generic, or type-based variable names. Give your
variables descriptive and non-ambiguous names.
There are only two hard things in Computer Science: cache
invalidation and naming things.
— Hard-coding primitive strings and numbers without descriptions.
If you want to write logic that depends on a fixed primitive string
or number value, put that value in a constant and give it a good
name.
const answerToLifeTheUniverseAndEverything = 42;
— Using sloppy shortcuts and workarounds to avoid spending more
time around simple problems. Do not dance around problems. Face
your realities.
— Thinking that longer code is better. Shorter code is better in
most cases. Only write longer versions if they make the code more
readable. For example, do not use clever one-liners and nested
ternary expressions just to keep the code shorter, but also do not
intentionally make the code longer when it does not need to be.
Deleting unnecessary code is the best thing you can do in any
program.
Measuring programming progress by lines of code is like measuring
aircraft building progress by weight.
— The excessive use of conditional logic. Most of what you think
needs conditional logic can be accomplished without it. Consider
all the alternatives and pick exclusively based on readability. Do
not optimize for performance unless you can measure. Related: avoid
Yoda conditions and assignments within conditionals.
4) Picking the First Solution
When I was starting to program, I remember that when I got
presented with a problem, I would find a solution and just
immediately run with it. I would rush the implementation right away
before thinking about the complexities and potential failures of my
first identified solution.
While the first solution might be tempting, the good solutions are
usually discovered once you start questioning all the solutions
that you find. If you cannot think of multiple solutions to a
problem, that is probably a sign that you do not completely
understand the problem.
Your job as a professional programmer is not to find a solution to
the problem. It is to find the simplest solution to the problem. By
“simple” I mean the solution has to work correctly and perform
adequately but still be simple enough to read, understand, and
maintain.
There are two ways of constructing a software design. One way is to
make it so simple that there are obviously no deficiencies, and the
other way is to make it so complicated that there are no obvious
deficiencies.
5) Not Quitting
Another mistake that I have made more often than I cared to admit
is sticking with the first solution even after I identify that it
might not be the simplest approach. This is probably
psychologically related to the “not-quitting” mentality. This is a
good mentality to have in most activities, but it should not apply
to programming. In fact, when it comes to writing programs, the
right mentality is fail early and fail often.
The minute you begin doubting a solution, you should consider
throwing it away and re-thinking the problem. This is true no
matter how much you were invested in that solution. Source control
tools like GIT can help you branch off and experiment with many
different solutions. Leverage that.
Do not be attached to code because of how much effort you put into
it. Bad code needs to be discarded.
6) Not Using the Right Data Structures
When preparing for interviews, beginner programmers usually put too
much focus on algorithms. It is good to identify good algorithms
and use them when needed, but memorizing them will probably never
attribute to your programming genius.
However, memorizing the strengths and weaknesses of the various
data structures that you can use in your language will certainly
make you a better developer.
Using the wrong data structure is a big and strongly-lit billboard
sign that screams newbie code here.
This article is not meant to teach you about data structures but
let me mention a couple of quick examples:
— Using lists (arrays) instead of maps (objects) to manage
records
The most common data structure mistake is probably the use of lists
instead of maps to manage a list of records. Yes, to manage a LIST
of records you should use a MAP.
Note that I am talking about a list of records here where each
record has an identifier that’s to be used to lookup that record.
Using lists for scalar values is okay and often the better choice
specially if the focus of the usage is “pushing” values to the
list.
In JavaScript, the most common list structure is an array and the
most common map structure is an object (there is also a map
structure in modern JavaScript).
Using lists over maps for managing records is often wrong. While
this point is really only true for large collections, I would say
just stick with it all the time. The main reason this is important
is because when looking up records using their identifiers, maps
are a lot faster than lists.
— Not Using Stacks
When writing any code that requires some form of recursion, it is
always tempting to use simple recursive functions. However, it is
usually hard to optimize recursive code, especially in
single-threaded environments.
Optimizing recursive code depends on what recursive functions
return. For example, optimizing a recursive function that returns
two or more calls to itself is a lot harder than optimizing a
recursive function that simply returns a single call to
itself.
What we tend to overlook as beginners is that there is an
alternative to using recursive functions. You can just use a Stack
structure. Push function calls to a Stack yourself and start
popping them out when you are ready to traverse the calls
back.
7) Making Existing Code Worse
Imagine that you were given a messy room like this:
You were then asked to add an item to that room. Since it is a
big mess already, you might be tempted to put that item anywhere.
You can be done with your task in a few seconds.
Do not do that with messy code. Do not make it worse! Always leave
the code a bit cleaner than when you started to work with it.
The right thing to do to the room above is to clean what is needed
in order to place the new item in the right place. For example, if
the item is a piece of clothing that needs to be placed in a
closet, you need to clear a path to that closet. That is part of
doing your task correctly.
Here are a few wrong practices that usually make the code a bigger
mess than what it was (not a complete list):
Duplicating code. If you copy/paste a code section to only change a
line after that, you are simply duplicating code and making a
bigger mess. In the context of the messy room example above, this
would be like introducing another chair with a lower base instead
of investing in a new chair that is height-adjustable. Always keep
the concept of abstraction in your mind and use it when you
can.
Not using configuration files. If you need to use a value that
could potentially be different in different environments or at
different times, that value belongs in a configuration file. If you
need to use a value in multiple places in your code, that value
belongs in a configuration file. Just ask yourself this question
all the time when you introduce a new value to the code: does this
value belong in a configuration file? The answer will most likely
be yes.
Using unnecessary conditional statements and temporary variables.
Every if-statement is a logic branch that needs to be at-least
double tested. When you can avoid conditionals without sacrificing
readability, you should. The major problem with this is extending a
function with a branch logic instead of introducing another
function. Every time you think you need an if-statement or a new
function variable you should ask yourself: am I changing the code
at the right level or should I go think about the problem at a
higher level?
On the topic of unnecessary if-statements, think about this
code:
function isOdd(number) {
if (number % 2 === 1) {
return true;
} else {
return false;
}
}
The isOdd function above has a few problems but can you see the
most obvious one?
It uses an unnecessary if-statement. Here is an equivalent
code:
function isOdd(number) {
return (number % 2 === 1);
};
8) Writing Comments About the Obvious Things
I have learned the hard way to avoid writing comments when I can.
Most comments can be replaced with better-named elements in your
code.
For example, instead of the following code:
// This function sums only odd numbers in an array
const sum = (val) => {
return val.reduce((a, b) => {
if (b % 2 === 1) { // If the current number is odd
a+=b; // Add current number to accumulator
}
return a; // The accumulator
}, 0);
};
The same code can be written without comments like this:
const sumOddValues = (array) => {
return array.reduce((accumulator, currentNumber) => {
if (isOdd(currentNumber)) {
return accumulator + currentNumber;
}
return accumulator;
}, 0);
};
Just using better names for functions and arguments simply makes
most comments unnecessary. Keep that in mind before writing any
comment.
However, sometimes you are forced into situations where the only
clarity you can add to the code is via comments. This is when you
should structure your comments to answer the question of WHY this
code rather than the question of WHAT is this code doing.
If you are strongly tempted to write a WHAT comment to clarify the
code, please do not point out the obvious. Here is an example of
some useless comments that only add noise to the code:
// create a variable and initialize it to 0
let sum = 0;
// Loop over array
array.forEach(
// For each number in the array
(number) => {
// Add the current number to the sum variable
sum += number;
}
);
Do not be that programmer. Do not accept that code. Remove comments
like these if you have to deal with them. Most importantly, educate
programmers who write comments like these of how bad they are. If
you happen to be employing programmers who write comments like the
above, let them know that they might actually lose their job over
this. Yep… That’s how bad it is.
9) Not Writing Tests
I am going to keep this point simple. If you think you are an
expert programmer and that thinking gives you the confidence to
write code without tests, you are a newbie in my book.
If you are not writing tests in code, you are most likely testing
your program some other way, manually. If you are building a web
application, you will be refreshing and interacting with the
application after every few lines of code. I do that too. There is
nothing wrong with manually testing your code. However, you should
manually test your code to figure out how to automatically test it.
If you successfully test an interaction with your application, you
should go back to your code editor and write code to automatically
perform the exact same interaction the next time you add more code
to the project.
You are a human being. You are going to forget to test all
previously successful validations after each code change. Make the
computer do that for you!
If you can, start by guessing or designing your validations even
before you write the code to satisfy them. Testing-driven
development (TDD) is not just some fancy hype. It positively
affects the way you think about your features and how to come up
with a better design for them.
TDD is not for everyone and it does not work well for every
project, but if you can utilize it (even in part) you should
totally do so.
10) Assuming That If Things are Working then Things are Right
Take a look at this function that implements the sumOddValues
feature. Is there anything wrong with it?
const sumOddValues = (array) => {
return array.reduce((accumulator, currentNumber) => {
if (currentNumber % 2 === 1) {
return accumulator + currentNumber;
}
return accumulator;
});
};
console.assert(
sumOddValues([1, 2, 3, 4, 5]) === 9
);
The assertion passes. Life is good. Right, RIGHT?
The problem with the code above is that it not complete. It
correctly handles a few cases (and the assertion used happens to be
one of these cases) but it has many problems beyond that. Let me go
through a few of them:
— Problem #1: There is no handling for empty input. What should
happen when the function is called without any arguments? Right now
you get an error revealing the function’s implementation when that
happens:
TypeError: Cannot read property 'reduce' of undefined.
That is usually a sign of bad code for two main reasons.
Users of your function should not encounter implementation details
about it.
The error is not helpful for the user. Your function just did not
work for them. However, if the error was more clear about the usage
problem, they would know that they used the function incorrectly.
For example, you can opt to have the function throw a user-defined
exception like this:
TypeError: Cannot execute function for empty list.
Maybe instead of throwing an error, you need to design your
function to just ignore empty input and return a sum of 0.
Regardless, something has to be done for this case.
— Problem #2: There is no handling of invalid input. What should
happen if the function is called with a string, an integer, or an
object value instead of an array?
Here is what the function would throw now:
sumOddValues(42);
TypeError: array.reduce is not a function
Well, that is unfortunate because array.reduce is definitely a
function!
Since we named the function’s argument array, anything you call the
function with (42 in the example above) is labeled as array within
the function. The error is basically saying that 42.reduce is not a
function.
You see how that error is confusing, right? Maybe a more helpful
error would have been:
TypeError: 42 is not an array, dude.
Problems #1 and #2 are sometimes referred to as edge-cases. These
are some common edge-cases to plan for, but there are usually less
obvious edge-cases that you need to think about as well. For
example, what happens if we use negative numbers?
sumOddValues([1, 2, 3, 4, 5, -13]) // => still 9
Well, -13 is an odd number. Is this the behavior that you want this
function to have? Should it throw an error? Should it include the
negative numbers in the sum? Or should it simply just ignore
negative numbers like it is doing now? Maybe you will realize that
the function should have been named sumPositiveOddNumbers.
Making a decision on this case is easy. The more important point
is, if you do not write a test case to document your decision,
future maintainers of your function will have no clue if your
ignoring of negative numbers was intentional or buggy.
It’s not a bug. It’s a feature.
— Someone who forgot a test case
— Problem #3: Not all valid cases are tested. Forget edge-cases,
this function has a legitimate and very simple case that it does
not handle correctly:
sumOddValues([2, 1, 3, 4, 5]) // => 11
The 2 above was included in sum when it should not have been.
The solution is simple, reduce accepts a second argument to be used
as the initial value for the accumulator. If that argument is not
provided (like in the code above), reduce will just use the first
value in the collection as the initial value for the accumulator.
This is why the first even value in the test case above was
included in the sum.
While you might have spotted this problem right away or when the
code was written, this test case that revealed it should have been
included in the tests, in the first place, along with many other
test cases, like all-even numbers, a list that has 0 in it, and an
empty list.
If you see minimal tests that do not handle many cases or ignore
edge-cases, that is another sign of newbie code.
Give five questions that a programmer should ask about errors in the problem definition phase. (5)
Please list 5 brief points for the below question 2 Give five questions that a programmer should ask about errors in the problem definition phase. (5)
Part 1: Give the definition for each word: 1. Active Listening: 2. Anxiety: 3. Body Language: 4. Closed Questions: 5. Empathy 6. Paraphrasing: 7. Projection: 8. Reflecting: 9. Terminal Phase:
By reading a misleading graph, what types of questions should you ask about the data you are reviewing? What type of basic information, formatting should be present on a graph to make it clear and unambiguous?
in chromatopraphy, Give an example of stationary phase in your Bu HSSSSS The following questions are for Exp. Microfluidics (Chromatography). 1 Briefly explain about stationary phase in chromatography. Give a chromatography experiment. (1 pt) Statinca a dop Phese is when you but a anor and does not spread as easily ore epauple wall Nac. 2. Briefly explain about mobile phase in chromatography. Give an example o chromatography experiment. (1 pt) mobile Phase is when dos spreads over water was mophe...
Make up at least ten open-ended questions and ask them of a minimum of 5 individuals over the age of 65. Among the questions that you should ask them are, "What would you do differently if you had your life to live over again?" and "What advice would you give a person of my age on how to live a meaningful life?" Write your questions and the answers received in your paper and include any conclusions you would make about...
Questions a nurse should ask themselves to determine if they are a patient centered nurse or not include: Select all that apply "Do I explain why I decided to become a nurse when introduced to a new patient?" "Do I really listen when patients and family members attept to express a problem or concern?" "Do I give prompt attention to all of my patients, even those who are "difficutl"?" O "Do I take every opportunity to learn, grow, and enhance...
What questions should the nurse ask when evaluating the effectiveness of nursing interventions? Select all that apply. What is the best nursing diagnosis to cover this cluster of signs and symptoms? What are the signs and symptoms that can be used to diagnose the patient's condition? Did the patient meet the goals established during the planning phase? Should the plan of care be discontinued? Next . Previous
Kindly answer all five questions and give me short answer .
Question 2 give 5 present and 5 missing
Unique NGO was founded 10 years ago as a community-based organization. It enjoys a good reputation with both the community it serves as well as with its donors. Most of the staff have been with Unique for at least 5 years and feel a strong commitment to the organization. This year, Unique's founder announced that he would retire. A new executive...
What information should the nurse include about the possible side effects of Go-LYTELY? What questions should the nurse ask the patient to see if he is properly prepared for the colostomy
1) What is the thermodynamic definition of state and how many properties are needed to fix a state in simple compressible system? Comment on independent properties on system consisting of single phase and two phase mixture cases. 2)Explain the problem associated with evaluation of an expansion or compression work for processes where quasi-equilibrium assumption is not valid 3)Explain possible energy storage mechanism and give examples to them 4)Define ideal gas model and assumptions used in this model 5)Explain enthalpy and...