Related
Here's a somewhat general computer question. I've always been able to follow the LOGIC of programming, but when I go to code something, I always find that I don't know some method or another to get what I need to get done. When I see it, I always think, "OF COURSE!".
How do you go about finding relevant methods for your programming needs that are "built-in?" I don't enjoy re-inventing the wheel, but I find it difficult to find what I need to do what I want to do.
First try Google:
You can use google to search your required method. For example If I want to search a value in array in PHP then I go to Google and type "Search values in array in PHP". I find my required function at first place.
Then try Standard Documentation:
Try standard documentation to search for your required method. For example if my problem is related to strings in PHP then I go to String Functions documentation and find the required function.
Finally try Stackoverflow:
Otherwise you can ask your problem at Stackoverflow for your required methods and libraries. You will always get a shortest way.
What you are asking here is for the best way to do research. Well, that's hard skill to explain, even more so to teach.
Nevertheless here are some tips:
Go to a search engine. It makes no
sense to start in a place like MSDN,
since all of its content is indexed
by the search engines anyway.
Phrase your question several
different ways.
As you learn more
about the issue you will learn new
vocabulary about it. Use that new
vocabulary to do even more searches.
If the searches turn out empty,
switch to browsing a specific
section of the official
documentation that you think is the
most related to what you are doing. If nothing else, it will expand your horizons around the issue and give you more vocabulary to do more searches.
Finally, if all else fails ask a question on StackOverflow explaining what you want to do as clearly as possible.
Note that if there's a simple API that does what you need, you will rarely reach step 4.
You say:
It's very frustrating to suddenly find
an "easy" button mid-way through.
Try to see it differently. Think of these moments as blessings. You've just learned something. You invested a lot of effort - and instead of seeing that effort as wasted, see it as critical to proper learning. You - better than the guy who just happened across the magic method - really understand what it's for and something about how it works. And you really, really, understand why you need it, and you properly appreciate its value. You're never going to forget that method.
So it was costly, but you learned something important. Celebrate, and move on.
It is usually included in some form of documentation. Most IDEs support the documentation format and gives you auto-complete functionality.
if you are using MVS so MSDN is really good for it
In addition to this and this answer above, google's basic and advanced searching tips prove very helpful.
In addition to above, changing the order of keywords in search criteria also sorts the list in different orders.
In essence I believe that searching is still an art rather than a science, and is best learnt - quoting from David Reis' answer above: "2. As you learn more about the issue you will learn new vocabulary about it. Use that new vocabulary to do even more searches."
Search in the API documentation. But the best way to (I found so) is to search on the internet for multiple solutions and then choose the one that you think is best. Make your search as narrow as possible. For example you want to implement random number generation function, then search like this, "How to generate random numbers in Java?".
Namespaces, namingconventions, Autocomplete/Intellisence
I assume that you are trying to find some kind of Object-Oriented-apis . I use .net in my example.
First try to find a class that might be responsable for the method you are looking for.
Example: If you want to "Make a new Directory in the Filesystem" you must know (or learn) that (in dotnet) these classes are in the namespace System.IO:
This namespace contains subnamespaces like Compresseion and Classes like File, Path, Directory, ...
Second you sould know NamingConventions. There are common Naming-Prefixes for methods like Get, Set, Insert, Create. In the documentation for class Directory you will find a CreateDirectory-Method.
If you have an intelligent editor that knows your programming language and the classes and namespaces learning is much easier. In the dotnet-world this feature is called Autocomplete/Intellisence
I hate writing error condition code. I guess I don't have a good approach to doing it:
Do you write all of your 'functional'
code first then go back in and add
error handling or vice versa?
How stupid do you assume your users
are?
How granular do you make your
exception throws?
Does anyone have sage advice to pass on to make this easier?
A lot of great answers guys, thank you. I had actually gotten more answers about dealing with the user than I thought. I'm actually more interested in error handling on the back end, dealing with database connection failures and potential effects on the front end, etc. Keep them coming!
I can answer one question: You don't need to assume your users are "stupid", you need to help them to use your application. Show nice prompts for things, validate data and explain why, so it's obvious to them, don't crash in their face if you can't handle what they've done (or more specifically, what you've let them do), show a nice page explaining what they can do instead, and so on.
Treat them with respect, and don't assume they know everything about your system, you are here to help them.
In respect to the first part; I generally write most error-handling at the time, and add a little bit back in later.
I generally don't throw that many exceptions.
Assume your users don't know anything and will break your system any way that it can possibly be broken.
Then write your error handling code accordingly.
First, and foremost, be clear to the user on what you expect. Second, test the input to verify it contains data within the boundaries you expect.
Prime example, I had a form with an email field. We weren't immediately using that data so we didn't put any checking on it. Result: about 1% of the users put in their home address. The field was labeled "Email Address" Apparently the users were just reading the second word and ignoring the first.
The fix was to change the label to simply say "Email" and then test the input. For kicks we went ahead and logged what the users were initially typing in that field just to see if the label change helped. It did.
Also, as a general practice, your functions should test the inputs to verify they contain the data you expect. Use asserts or their equivalent in your language of choice.
When i code, there will be some exceptions which i will expect, i.e. a file may be missing, or some xml serialisation may fail. Those exceptions i know will happen ahead of time, and i can put in handling for them.
There is a lot you cannot anticipate though, and nor should you try to. Put in a global error handler and logger, so that ultimately everything gets caught and logged. Then as your testers and/or users find situations that cause exceptions (i.e. bad input) then you can decide whether you want to put further handling in specifically for it, or maybe leave it as it was.
Summary: validate your input, but don't try to gaze into the crystal ball too much, as you will never anticipate every issue that the user may come up with. Have a global handler and logger, and then refine as necessary.
I have two words for you: Defensive Coding
You have to assume your users are incredibly stupid. Someone will always find a way to give you input that you thought would never happen.
I try to make my exception throws as granular as possible to provide the best feedback when something goes wrong. If you lump everything together, you can't tell which error case caused the problem.
I usually try to handle error cases first (before getting functional code), but that's not necessarily a best practice.
Someone has already mentioned defensive programming. A few thoughts from a user experience perspective, though.
If the user's input is invalid, either (a) correct it if you're reasonably sure you knew what they meant or (b) display a message in line that tells them what corrective action they should take.
Avoid messages like, "FATAL SYSTEM ERROR CODE 02382981." Users (a) don't know what this means, even if you do, and (b) are intimidated and put off by seeing things like this.
Avoid pop-up messages for every—freaking—possible—error you can come up with. You shouldn't disrupt user flow unless you absolutely need them to resolve a problem before they can do anything else.
Log, log, log. When you show an error message to the user, put relevant information that might help you debug in either (a) a log file or (b) a database, depending on the type of application you're creating. This will ease the effort of hunting down information about the error without making the user cry.
Once you identify what your users should and should not be able to do, you'll be able to effectively write error handling code. You can make this easier on yourself with helper methods/classes.
In terms of your question about writing handling before/after/during business logic, think about it this way: if you're making 400,000 sandwiches, it might be faster to add all the mustard at the same time, but it's probably also a lot more boring than making each sandwich individually. Who knows, though, maybe you really like the smell of mustard...
G'day,
This is related to my question on star developers and to this question regarding telling someone that they're writing bad code but I'm looking at a situation that is more specific.
That is, how do I tell a "star" that their changes to a program that I'd written are poorly made and inconsistently implemented without just sounding like I'm annoyed at someone "playing with my stuff"?
The new functionality added was deliberatly left out of the original version of this shell script to keep the it as simple as possible until we got an idea of the errors we were going to see with the system under load.
Basically, I'd argued that to try and second guess all error situations was impossible and in fact could leave us heading down a completely wrong path after having done a lot of work.
After seeing what needed to be added, someone dived in and made the additions but unfortunately:
the logic is not consistent
the variable names no longer describe the data they contain
there are almost no comments at all
the way in which the variables are used is not easy to follow and massively decreases readability and hence maintainability.
I always try and approach coding from the Damien Conway point of view "Always code as if your system is going to be maintained by a psychopath who knows where you live." That is, I try to make it easy for follow and not as an advertisement for my own brilliance. "What does this piece of code do?" exercises are fun and are best left to obfuscation contests IMHO.
Any suggestions greatly received.
cheers,
I would just be honest about it. You don't necessarily need to point every little detail that's wrong, but it's worth having a couple of examples of any general points you're going to make. You might want to make notes about other examples that you don't call out in the first brief feedback, in case they challenge your reasoning.
Try to make sure that the feedback is entirely about the code rather than the person. For example:
Good: The argument validation in foo() seems inconsistent with that in bar(). In foo(), a NullPointerException is thrown if the caller passes in null, whereas bar() throws IllegalArgumentException.
Bad: Your argument validation is all over the place. You throw NullPointerException in foo() but IllegalArgumentException in bar(). Please try to be consistent.
Even with a "please," the second form is talking about the developer rather than the code.
Of course in many cases you don't need to worry about being so careful, but if you think they're going to be very sensitive about it, it's worth making the effort. (Read what you've written carefully, if it's written feedback: I accidentally included a "you" in the first version to start with :)
I've found that most developers (superstar or not) are pretty reasonable about accepting, "No, I didn't implement that feature because it has problem X." It's possible that I've been lucky though.
Coming from the other perspective, I would encourage you to think about it in their shoes. I will describe a "hypothetical" experience.
Some things to keep in mind:
The guy was trying to do something
good.
Programmers are terrible at
mind reading. They tend to only know
what they read.
He may have not been given complete guidance as what needs to be done(or what doesn't need to be done)
He is likely doing the best he knows how to.
Just keep that in mind and talk to them. Teach them. No need for yelling or pissing contests. Just remember that they are not intentionally trying to make your life difficult.
I see that you've asked a lot of questions about how to deal with certain kinds of developers. It seems to be a common thread for you. You keep asking about how to change people around you. If this is a constant problem for you, then perhaps you are the problem.
Now I know you are asking questions to learn how to deal with people you find difficult, and that's good, however, you keep asking (and getting answers) about how to change people.
It seems to me that you need to change. Work with these people to change the code to what you want it to be. With them. Don't try to get them to do it. Just do it, and tell them what you did and why, and ask suggestions for further improvement, and learn from each other. Play off of each other's experience and strengths. Just my 2 cents.
If you have clearly defined coding standards for the project, point out that the code needs to be changed to meet those standards. The list you have there seems like quite reasonable feedback (though #3 is much argued-over; I would only push to document the really confusing parts as fixing the other three points, hopefully, makes the code less confusing).
If there are any other examples you have in your repository from this developer that are several months old, show one to him and ask him what it is doing. (Show him this one in a few months). When he has to zip around to find out what is actually in his variables, and deconstructing every line of code to figure out what it is doing. Break into a code review / pair programming session right there. Refactor and rename together so that he hopefully begins to see for himself exactly why these things are important.
Frankly, I think this is a political problem, not a coding problem. Specifically...
WHO SAID THIS PERSON WAS A "STAR"? If this is the same person you described in your other question, then you already have your answer there: THIS PERSON IS NO "STAR".
So then you get into the other effects of politics...
Who is claiming this person to be a star? Why can you not just tell the person "this is crap code"? Who is protecting them / defending them were you to do that? Can you do that or would you get blasted / demoted / put on the "to be laid off" pile?
You are asking questions that cannot really be answered in isolation. IF the code is crap, then throw it away and do it correctly yourself. IF there are reasons that you cannot do that, then you need to ask yourself if the benefits of this place outweigh the negatives.
Cheers,
-R
Creating a program and then releasing it to be worked on by other developers is tough. You are throwing your code to the mercy of others' development styles, coding conventions, etc.
Telling those developers that they are doing coding poorly, after the code is in, is one of the hardest things that you can do. It is best to address your concerns before they ever start working with your code. This can be done in two ways: Maintaining a detailed coding standard, requiring that submitted code adheres to this and maintaining a development road map, not to just outline when new features will be in, but to create dependencies to avoid such mishaps.
More to your situation, it is important not to criticize or it could cause hostility and worse code coming in. Maybe you can work with that developer to create standards documentation. You will be able to express your ideas about what the standards should be, and you will get their input, without causing any hard feelings.
Always point out the good things in their code, and be sure when discussing the weaknesses that you frame them pointing out the reasons that it will benefit everyone (the developer included), never criticize.
Good luck.
I would do the following:
Make sure he knows that his hard work is appreciated (preferably, this should be the truth)
Ask him if he would mind making a few changes, making it sound like no big deal and easy to fix
Explain the issues, including why they are issues, and suggest specific changes to set him on the right path.
Hopefully, the exercise will help him integrate into the culture project better.
We try to solve these potential 'issues' proactively:
Every 'bigger' project where people work together gets assigned a project 'codelead' (one of the developers). This rotates every project (based on preferences, experience with the particular task ...) so everyone gets to be in the 'contributing' and 'code-project-lead' roles once in a while.
We explicitely made an agreement that
these project 'leads' can decide
whatever they want to with the code
contributions of the others (sort of
like a temporary dictatorship: change
it, make suggestions, ask people to
redo stuff etc.). The projectcode
'lead' bears the complete
responsibility for the aggregated
code to work.
With these formalised 'leads' (and the changing roles) I think people have less problems with (constructive) criticism of the parts they contribute.
Yes, keep the feedback as appreciative, professional and technical as possible, back up your concerns with possible "worst case" scenarios so that the disadvantages of those features and/or this particular implementation, become blatantly obvious.
Also, if this is about features/code that are very specific and are not of any use to most users, express your concerns about the code/use ratio - indicating concerns about increased code base complexity etc.
Ideally, present your concerns as open-ended questions - in the sense of: "Though, I am wondering if this way of doing it may work in the long term, due to ...". So that you actually encourage an active dialogue between contributors.
Invite your fellow contributors and user to provide their opinions on these concerns, in fact ask other people/contributors what they are thinking about this addition (in terms of pros & cons, requirements, code quality), do make the statement that you are willing to reconsider your current position if other contributors/users can provide corresponding insight.
You are basically encouraging an informal review that way, asking your community to also look into the proposed additions, so that the advantages and disadvantages can be discussed.
So, whatever the decision will be, it will be one that is community-backed, and not just simply made by you.
You being the architect of the original design, are also in an excellent position to provide architectural reasons why something is not (yet) suitable for inclusion/deployment.
If stability, complexity or code quality are a real concern, do illustrate how other contributions also had to go through a certain review process in order to be acceptable.
You can also mention how specific code doesn't really align with your current design, or how it may not scale too well with future extension to your current design, similarly you can highlight why certain stuff was left out explicitly.
If you actually like the features or the core idea, be sure to highlight the excellent addition these features would make if properly implemented and integrated, but do also highlight that the existing implementation isn't really appropriate due to a number of reasons.
If you can, do make specific suggestions for improvements, provide examples of how to do things better, and what to avoid and do express that you hope, this can be reworked to be added with the help of your project's community.
Ideally, present your requirements for actually accepting this contribution and do mention the background for your requirements, you may in fact say that you hate some of these requirements yourself.
Preferably, present and discuss instances where you yourself contributed similar code (or even worse code) and that you ended up facing huge issues due to your own code, so that these policies are now in place to prevent such issues. By actually talking about your own bad code, you can actually be very subjective.
Emphasize that you generally appreciate the effort itself, and that you are willing to provide the necessary help and pointers to bring the code in question into a better shape and form. Also, encourage that similar contributions in the future should be properly coordinated within your community, in order to avoid similar issues.
Always think in terms of features and functionality (and remind your contributor to do the same), not code - imagine it like a thorough code review process, where the final code that ends up being committed/accepted, may have hardly anything in common with the original implementation.
This is again a good possibility, to present examples where you yourself developed code that ended up largely reworked, so that much of it is now replaced by a much better implementation.
Similarly, there's always the issue with code that has no active maintainers, so you can just as easily suggest that you feel concerned about code that may end up being unmaintained, you could even ask if the corresponding developer would be willing to help maintain that code, possibly in a separate branch.
In the same sense, always require new code to be accompanied with proper comments, documentation and other updates. In other words, code that adds new or changes existing functionality, should always be accompanied with updates to all relevant documentation.
Ultimately, if you know right away that you cannot and will not accept any of that code in the near future, you can at least invite the developer to branch or even fork your project, possibly in you repository and with your help and guidance, so that you still express your gratitude for working with your project.
And if so, where do you draw the line? My coworkers and I disagree on this subject. I have seen such things as
// fixes bug # 22
to
// fixed bug: shouldnt be decrementing
i++;
Is it ok if the change is fairly significant, and radically changes what the method was written to do? Or do you simply change the summary text of the method to reflect what it is now meant to do?
My opinion is that this information should be put into source control. Some state that this is bad because then it will be lost outside of the context of source control (say you switch systems and want to keep historical data).
Comments should explain how the methods work.
Source control explains why changes were made.
Adding a comment about bug fixing is a good idea, if you write the right thing.
For example,
/* I know this looks wrong, but originally foo was being decremented here, and
it caused the baz to sproing. Remember, the logic is negated by blort! */
Stuff like Fixes bug #22 is better kept in source control. Comments in your code should be signposts to help future sojourners on their way, not satisfy process and tracking.
No. You should keep information on bugs and the change set that fixes the bug external to the source code. Any comments in the code itself should only relate to what the code is doing. Anything else is just clutter.
I personally feel that comments should be about the code itself, not about a bug fix.
My reason for this is maintainability - 2 (or 10) years later, this comment will no longer be meaningful. In your example above, I would prefer something like:
// Increment i to counteract extra decrement
++i;
The difference is that it's not tied to a bug, but rather what the code is doing. Comments should be commenting on the code, not meta info, IMO.
This opinion is partially because I maintain a very old codebase - and we have lots of comments that are no longer meaningful related to bug fixes or feature enhancement requests, etc....
We had a few comments like this, but then our Bugzilla server died and we restarted at bug #1 so they're all meaningless. A short explanation of the bug is my preferred method now.
Something like // fixes bug # 22
is quite meaningless on its own, and requires supplementary steps to even get an idea about what it means and what role it fulfills. A short description is in my opinion more appropriate, regardless of the bug tracking or source control software you might be using.
If the algorithm needs to be coded in a certain way - to workaround a bug in a 3rd party API for example, then that should be commented in the code so that the next person that comes along doesn't try to "optimise" the code (or whatever) and reintroduce a problem.
If this involves adding a comment when you fix the original bug then do it.
It will also serve as a marker so you can find the code you need to check if ever you upgrade to the next version of the API.
Assuming comments aren't superfluous (the classic i++; //increment i example comes to mind), there is almost never a reason to argue against adding a comment, regardless of what it's related to. Information is useful. However, it's best to be descriptive and concise - don't say "fixes bug #YY", but instead add something like "this used to fail for x=0, the extra logic here prevents that". That way someone who looks at the code later can understand why a particular section is critical to proper function.
I rely on FogBugz and check-in comments in svn. Works great, though as jeffamaphone said case numbers don't make a lot of sense if you lose your bug database.
A problem with putting comments in the code is that, over time, your code will become littered with comments about problems that haven't existed for awhile. By placing such comments in the source control check-in comments you're effectively tying information about the fix to the specific version where it was corrected, which can be helpful later on.
My view is that comments should be relevant to the developer's intention, or highlights of 'why' surrounding the algorithm/method.
Comments shouldn't surround a fix-in-time.
I agree that such data should be placed in source control or another part Configuration Management. Having worked in codebases that place information about bug fixes in comments, I can say it leads to very cluttered comments and code later. Six months after the fix is in place, do you really want to know that about a line fixing some long-past bug? What do you do with comments when you need to refactor the code?
We use Team Foundation Server for source control here at my company and it lets you tie a check-in to a bug report, so I wouldn't put a comment directly in code to server the same purpose.
However, in situations where I'm implementing code as a workaround for a bug in the .NET framework or a third-party library I like to put a the URL to the Microsoft TechNet log or website that describes the bug and its status.
So obviously
// fix bug #22
i++;
is not effective communication.
Good communication is mostly common sense. Say what you mean.
// Compensate for removeFrob() decrementing i.
i++;
Include the bug number if it seems likely to help future readers.
// Skipping the next flange is necessary to maintain the loop
// invariant if the lookup fails (bug #22).
i++;
Sometimes important conversations are recorded in your bug tracking system. Sometimes a bug leads to a key insight that changes the shape of the code.
// Treat this as a bleet. Misnomed grotzjammers and particle
// bleets are actually both special cases of the same
// situation; see Anna's analysis in bug #22.
i++;
In the Perl5 source repository it is common to refer to bugs, with their associated Trac number in Test files.
This makes more sense to me, because adding a test for a bug will prevent that bug from ever going unnoticed again.
I'm currently working on my Bachelors dissertation. This involves developing a software product and a 12000 word write-up, mainly covering research, design and development. Now where I am quoting other peoples written work, I am obviously referencing this, but what about code? There have been plenty of times where I've looked for a solution to a problem I was unsure of and found someone who had solved the problem. Most of the time I took their code, worked to understand what they were doing, and then wrote my own version in my application, so should it be referenced somehow?
What would you guys do, put a comment in the code referencing the original author, add a reference in the write up or my bibliography, or nothing at all?
Where its a significant or interesting piece of code used, I will probably refer to it in my write-up, but for solutions that don't warrant this, I’m trying to come up with a good solution.
If you were the author of some code I had either used, or been inspired by, what would make you happy that I wasn't plagiarizing you?
To take this a bit further, there's really 2 different things here. If I go to MSDN to lookup how to use a particular part of the .net framework, is that something that should be referenced, or is it fair use of the framework.
Where as if I've used an algorithm that someone clearly developed and put a lot of time into, that's something I would definitely reference.
It all depends on context. Many algorithms are so well known that they are generally considered public domain and as long as you reference a well known source on the subject then you shouldn't have any worries (Sorting, Searching)
When dealing with specific problems, especially in other people code, you have to read really carefully. If its published (book, journal, web, etc..) then you must always reference the original, at some point in your dissertation (technically once in then write up and then a comment in the source)
If it's other peoples work they deserve proper credit. Anything else is plagiarism
There's two aspects to this:
The citation requirements of your academic institution. You should make sure you comply with this because if you're found to have plagiarised another's work you can be guilty of academic misconduct and you don't want that; and
The ethics of using another's work. Barring "fair use" provisions (meaning there's only so much of someone's work you can reproduce before what you're doing is no longer "fair use") and the like, if you reproduce someone else's code, that you should credit. If you simply take the idea, that's possibly a bit different and is a judgement call. It depends on the significance of that idea and it's contribution to your work.
Outside of academic work, I make it a habit to leave a comment in my source code if I reference someone else to solve a particular problem. It's for my benefit as well, I might want to go back and take another look at their code months later and have forgotten where I originally found it. Of course, take a look at the included license when you reference someone's code, it should be pretty clear what you can't do with it.
There's no shame in borrowing working code if it's the best tool for the job, provided the author's licence conditions allow it - real programmers do it all the time. But for academic purposes there is a problem if you could be percieved as being at all secretive or deceptive about it. To avoid that, I'd reference it both in the code with a big, clear comment, and in the report. Full disclosure means you can't be accused of doing anything wrong.
I have the same issue for my dissertation as well:
I opt for referencing without overdoing it. Adding a reference to the referenced section, means that you've searched, found something, thought of using it and accepted it, while having nothing means that you made it up. This increases the value of your work in academical context (the more you base on previous work, the better).
Also your supervisor will be able to trace license and algorithmic issues on the referenced site.
At last you do not know where your work will get to. Suppose in 3 years after today someone tries to use it, and jumps into a patent violation? How can you help him - by a reference...