Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
I'm a computer science student finishing up my second semester of programming classes. I've enjoyed them quite a bit, and learned a lot, but it seems other students are struggling with the concepts and assignments more than I am. When an assignment is due, the inevitable group email comes out the day or two before with people needing some help either with a specific part of the problem, or sometimes people just seem to have a hard time knowing where to start.
I'd really like to be able to help out, but I have a hard time thinking of the right way to give them help without giving them the answer. When I'm having trouble understanding a concept, a code snippet can go along way to helping me, but at the same time if it makes a lot of sense, it can be difficult to think of another way to go about it. Plus the Academic Integrity section of each assignment is always looming overhead warning against sharing code with others. I've tried using pseudo code to help give others an idea on program flow, leaving them to figure out how to implement certain aspects of it, but I didn't get too much feedback and don't know how much it actually helped them out, or if it just confused them further.
So I'm basically looking to see if anyone has experience with this, or good ways that I can help out other students to nudge them in the right direction or help them think about the problem in the right way.
Have them explain their code to you.
This accomplishes several things:
First, it demonstrates that they actually have code to show you. How can they not understand something if they haven't even opened up a text editor yet?
Next, it demonstrates that they understand the code at a basic level. They could have copied it from somewhere. If they don't know the first thing about the code they have, that's a flag. (If they did copy the code, but still took the time to understand the code, then that's still academically dishonest but it's a valuable skill to use after college.)
Finally, now we're at the place where they might actually get it, with your help (or possibly even without!) If they get to the place where the hole in their understanding is (as they're explaining their code to you) and it jumps out at them, then they've solved their own problem. If they don't recognize the hole, then this is where you can give them targeted hints.
I've worked as a TA and at a CS department help desk (and helped buddies). This is what I do...
Abstract out the issue, find a related problem, then work through the related problem with them. If they can't make the connection, you can't really help them.
Edit: and refuse to help with more than the bare basic syntax if they are looking for help the day of or day before. Things should have been dealt with long before deadline. Crutching people on the day-of is not a good practice for you.
Some thoughts:
Do pair programming
Have the student (the person you are helping) sit in the chair and code something. Could be a code snippet, could be a portion of a project, anything, as long as it represents something they have trouble on. As they go, point out (not rudely) places where they may have done something incorrectly, or something that could be improved upon.
Review work done
One of the things that helped me the most was to have a peer (as opposed to a teacher or student aide) review my code. Most of the time the peer could point out places where they might have done something differently.
Make them repeat you.
I often make people I'm helping learn repeat what I just said to see if they understand it or have any questions. You would be surprised how often people don't speak up when they don't understand something.
Offer help before the project is due.
Trying to get the project done the night before it is due is a surefire way to, at the very least, not learn the concepts as thoroughly as you might have otherwise.
Don't code it yourself
Your peers will learn nothing if you do it for them.
Find other resources
An aide, a friendly professor, another one of your peers can be invaluable resources. If you find that your style of teaching doesn't mesh well with one of your peers' style of learning, point them toward someone else who might be able to help them more.
Hope for the best
You can only go so far when teaching someone; they have to want to learn.
One thing that might be helpful to your fellow students is to point to similar code in the lecture notes (or if you don't get lecture notes handed out, in your own notes). That way you're only showing them what the professor said, but doing it in a helpful way.
If another student is open to it, asking them questions about everything they've tried and why would be helpful.
Finally, consider going to your professor and asking for his or her input on what you are allowed to do and how they might suggest you help others. After all, professors have years of experience in teaching students. Even more, will you have an opportunity as an undergraduate to be a TA in future years? I got to TA as an undergraduate, and that helped me to productively use my impulses to assist others without breaking any honor codes. If you have such undergraduate employment opportunities, letting professors see you now as the helpful type will help you acquire them.
I don't think you should be helping them. I think it's academically dishonest. Also, it does them no help to have you give them answers, or even to have you be around to answer questions, since once they get to the exam (or the real world), you won't be there for them. They need to not only learn how to program on their own (which presumably you're helping them do), but also get their questions answered on their own. That means posting on places like StackOverflow. You might want to recommend that they formulate a specific question (always a good exercise) and post it on here with the "homework" tag.
When I was taking CS classes in college, there were a number of students who just couldn't code or design at all (and I'm thinking of a senior level software engineering class in particular). They also had no idea how to go about solving problems, or where to look things up, where to get questions answered, or what questions to ask. They were totally helpless because they had spent most of their undergraduate time working on their homework/projects in groups and having the more talented group members hand-hold them. Don't perpetuate this. The last thing the industry needs is more incompetent programmers who graduate with good grades to put on their resume.
Whenever I tried to teach my girlfriend how to program I did almost nothing but ask questions. (she got to the .each statement before getting bored)
Ask them question how their code works and how they think they could accomplish the task. Give them small nudges in the right direction. And never EVER type something for them. If you have another computer and type code on it to show them and show them the results, that is fine but don't over do that.
Here's the advice I give my student teachers: avoid giving answers to students. Instead, ask them questions. And make sure to ask questions that they can ask themselves in the future. For the material I teach, here are some of the questions I want all students asking themselves:
What is your abstraction?
What is an example of how your abstraction is supposed to behave? Can you show me another example?
Are there any examples of where you abstraction is allowed to fail? How should it fail on that example?
Have you tested these examples?
What is the representation of your abstraction?
How does the representation relate to the abstraction? Can you show me a picture? Can you show me in math?
What functions are allowed to see the representation? What is the contract of each function? Does the representation satisfy an invariant that the function can assume? Does each function make sure the invariant is preserved?
What does valgrind say?
One of the most common problems in teaching is determining whether the student understood you. An easy and effective way to determine if you should continue or rephrase is to have the student demonstrate their understanding by doing something closely related but not identical.
Also, since programming is essentially word problems, it's important that the student break things down into steps. I'd be asking to see their highlevel step-through before I showed them anything. Too many people get hung up in syntax and never really nail down what they're trying to do before diving in.
A general experience in explaining stuff to others is to find out where they stand first. Try to refrain from giving them solutions to problems they don't even have yet (even if you are sure that they will come across them later). In other words, don't go two steps ahead of them. If they have problems understanding call-by-value, don't explain them recursion.
As far as helping fellow students in general, I generally use the "play stupid" approach. I pretend that I know nothing about their particular assignment, and I ask them to get me up to speed on what they are supposed to be doing. I also ask them to give me a quick run-down of what they learned in class about whatever concept the assignment is about. This usually takes about 5 minutes and about 95% of the time, the other student has answered their own question by the time they finish explaining it to me. If they haven't solved it by this point, I ask them to walk me through their solution to the assignment. In doing this, they usually catch where their solution deviates from what they just said they learned in class.
As far as programming-specific help goes, I sometimes ask the other student to send me their code and I run it through a simple shell script I wrote. That script blanks out everything in the code file that is not a comment, and I give the result to the other student to read. The resulting file usually reads like an outline of their code, and a lot of times they can see where their code went wrong simply by getting the code out of the way. If their approach is completely wrong, I tell them to write an outline of what the code is supposed to do (in high-level terms) using comments; after completing this, they fill in each section of the outline with code that implements that outline step (testing each "chunk" as they go). This helps a lot of people separate the code from the algorithm (many common problems I see stem from the lack of a systematic or disciplined approach to problem solving, and this exercise helps get them on the right path).
Another method is to answer questions using a different programming language. For example, I helped several of my fellow students on Matlab projects by explaining the concepts using C, Ruby, or even pseudo-code (that read more like plain English than code). I knew that they had far more experience with other languages, so I used what they knew best to illustrate the concepts and encouraged them to try solving the problem in their "native language" first. Once they were confident that they understood the concepts, they could work on figuring out how to implement them in the target language. Having to learn new concepts while you are still learning a language makes both more difficult. This approach also helps determine whether they are having trouble understanding how to solve the problem or how to code the solution.
PSYCHOLOGICAL APPROACH
show them some popular real world APPLICATIONS (as an example) which they use day to day...written in same programming language you are trying to teach.....
explain every thing with background
give every student, considerable importance
alwaysss use colour coded syntax
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I've been attempting to learn programming (in C#) for a few years now. The problem I've had is that I'd know what I want to do (or what I want the program to do), but no idea on how to actually implement it. So I often wonder what it is I'm lacking. Is the mindset of a programmer somehow different, and I've yet to condition myself to that type of thinking, or do I just need to know more about syntax and what they do?
Of course, it's compounded by the fact that I have no means of taking classes at the moment.
So is trial and error the way to being a better programmer, or are there essential pieces that I presently lack?
Also, my goal is to eventually get into the Gaming Industry, and I don't know if that affects anything at this point.
By far the best way to improve your skills is to practice, practice, practice, and then practice some more. Just like an athlete gets better and hones his skills and natural abilities, the more you code the better you will get. Your best resources are going to be books and the internet--blogs, articles, websites such as SO are incredible sources of information. Google is your friend, learn how to use it effectively.
Find a problem you want to solve, and then find two or three ways to solve it. Being able to approach a problem from different angles can be an invaluable skill.
I would also recommend finding an open source project you can participate in. There are plenty of 'em out there.
Yeah, it's pretty much trial and error.
Or more accurately, research, trial, error, cry, fix, error, research, success!
Anything I want to do (that is new) I typically find by doing various searches, or I accidentally learn by participating in forums like this, and then am lucky enough to remember when it becomes neccessary.
Just dedicate yourself to research and trying "various things", and then you'll become better at it. You just need to accept that it will be difficult at first, and that that is quite acceptable and appropriate.
You'll get the hang of it. As long as you're motivated, you'll achieve what you wish.
I think the most valuable thing at this point is seeing working code in action. Get your hands on lots of working sample apps with full source that interest you. Look at the source, figure out what does what, and start to modify it!
Then try to write your own apps using similar constructs, and you'll find it much easier.
I like silky's second sentence. I agree. Just hang in there.
Find a project (small project) that you want to do, and then learn how to do it. Any project...like build a calculator or something. If you have a goal in mind, it makes it a lot easier...and it will make it easier to people to help you when you post questions so they can have a frame of reference.
Lots of google searches...and stackoverflow searches ;)
One other way that can get you started is to look at standard examples (and I'm sure you can find lots of those for C#) try and run them, understand what they do, and then start modifying them and play around.
Get your questions from such tinkering answered by reseaching the net etc.
Increase complexity and you'd be on your way in a while.
Search around for an C# Open Source project that interests you. Most projects will take any help you can give. This will allow you to practice your skills in a controlled environment.
You do have means to take courses at the moment. There are entire courses, complete with free textbooks, available online. And that's just one quick example.
I recommend you work your way through a couple of coding and design books while learning the syntax of a language or 2. Code Complete is a great place to start. As far as what you should start programming, aim for simple things that will solve a problem you have. While picking up a language I have done things like write a program that will auto-organize my media library, kick off processes based on things I tweet from my cell phone, quickly add shortcuts to my favorite launcher app, or organize and archive all of my saved school work at the end of a semester. Also, look at a LOT of other people's code. It's can be hard to code better until you've looked at better code.
With this approach you'll build your abstract skills like design and upfront preparation, practical skills like file access and network communication, and general programmer toolbox items like regular expressions and reflection.
Another interesting thing to try is Code Kata. How do you become a great musician or learn to ski or speak a foreign language? Practice. Practice. Practice.
Google for Bruce Eckel's "Thinking in ..." books, they're free and very good
Take a look at functional programming languages - This will broaden your mind and therefore change (and probably enhance) the way you look at code and problems.
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.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
While solving any programming problem, what is your modus operandi? How do you fix a problem?
Do you write everything you can about the observable behaviors of the bug or problem?
Take me through the mental checklist of actions you take.
(As they say - First, solve the problem. Then, write the code)
Step away from the computer and grab some paper and a pen or pencil if you prefer.
If I'm around the computer then I try to program a solution right then and there and it normally doesn't work right or it's just crap. Pen and paper force me to think a little more.
First, I go to one bicycle shop; or another.
Once I figure nobody invented that particular bicycle,
Figure out appropriate data structures for the domain and the problem, and then map needed algorithms for dealing with those data structures in ways you need.
Divide and conquer. Solve subsets of the problem
This algorithm has never failed me:
Take Action. Often just sitting there and being terrified or miffed by the problem will not help solve it. Also, often, no amounting of thinking will solve the problem. So you have to get your hands dirty and grapple with the problem head on.
Test. Under exactly what conditions, input values or states, does the problem occur? Make a mental model of why these particular conditions might cause the problem. Check similar conditions that don't cause the problem. Test enough so that you have a clear understanding of the problem.
Visualise. Put debug code in, dump variable contents, single step code whatever. Do anything that clarifies exactly what is going on where - within the problem conditions.
Simplify. Remove or comment code, poke values into variables, run particular functions with certain values. Try your hardest to get to the nub of the problem by cutting away the chaff or stuff that doesn't have a relevance to the problem at hand. Copy code into a separate project and run it, if you have to, to remove dependencies.
Accept. A great man said: "whatever remains, however improbable, must be the truth". In other words, after simplifying as much as you can, whatever is left must be the problem, no matter how bizarre it may seem at first.
Logic. Double, triple check the logic of the problem. Does it make sense? What would have to be true for it to make sense? Is there something you're missing? Is your understanding of the algorithm wrong? If all else fails, re-engineer the problem away.
As an adjunct to step 3, as a last resort, I often employ the binary search method of finding wayward code. Simply comment half the code and see if the problem disappears. If it does then it must be in that half (and vice versa). Half the remaining code and continue.
Google is great for searching for
error messages and common problems. Somewhere, someone has usually encountered your problem before and found a solution.
Pencil and paper. Pseudo Code and
workflow diagrams.
Talk to other developers about it. It
really helps when you have to force
yourself to simplify the problem for
someone else to understand. They may also have another angle. Sometimes it's hard to see the forest through the trees.
Go for a walk. Take your head out of
the problem. Take a step back and try
to see the bigger picture of what you
want to achieve. Make sure the problem you are 'trying' to solve is the one your 'need' to solve.
A big whiteboard is great to work on. Use it to write out workflows and relationships. Talk through what is happening with another team member
Move on. Do something else. Let your subconscious work on the problem. Allow the solution to come to you.
write down the problem
think very hard
write down the answer
I can't believe no one posted this already:
Write up your problem on StackOverflow, and let a bunch of other people solve it for you.
My method, something analytic-sinthetic:
Calm down. Take a deep breath. Focus your attention in what you're going to solve. This may include going for a walk, cleaning the whiteboard, getting scratch paper and pencils ordered, some snacks, etc. Avoid stress.
High level understanding of the problem. In case it is a bug, when does it happened? in what circumstances? If it is a new task, try to diverge of what results are needed. Recollect data, evidence, get acceptance descriptions, maybe documentation or a talk with someone that knows about the issue.
Setup the test playground. Try to feel happy with the tools needed. Use the data collected in the previous step to automate something, hopefully the bug if that's the case, some failing tests otherwise.
Start sinthesizing, summarizing what you know, reflecting that on code. Executing once and once more. If you are not happy with the results, return to step two with renewed ideas, diverge more: maybe apply tools (in order of cost) that helped before, i.e. divide and conquer, debug, multithread, dissassemble, profile, static analysis tools, metrics, etc. Get in this loop until you can isolate the problem and pass the over the phone test.
Now it's time to fix it but you have all the tools set up. It won't be so much trouble. Start writing code, apply refactoring, enjoy describing your solution in the docs.
Get someone to try your solution. She can eventually get you to step 2 but that's ok. Refine your solution and redeploy.
I'm interpreting this as fixing a bug, not a design problem.
Isolate the problem. Does it always occur? Does it occur only the first time run on a set of new data? Does it occur with specific values, but not with others?
Is the system generating any error message that appear related to the problem? Verify that the error messages are not generated when the problem does not occur.
Has anything been changed recently? Those are likely places to start looking.
Identify the gap between what I know is working (e.g. I can start up the app and attempt to do a query) and what I know is not working (e.g. it gives me an error instead of the expected results). Find an intermediate point in the code where it seems possible to look for a problem (does this contain valid data at this point?). This allows me to isolate the problem on one side or the other of the point I looked.
Read the stack traces. If you have a stack trace, find the first line that mentions in-house code. The problem is not in your libraries. Maybe it will turn out to be, but just forget about that possibly first. The error is in your code. It's not a bug in java, it's not a bug in apache commons HTTP client, it's in code written in your organization.
Think. Come up with something the system could be doing that can cause the symptoms you see. Find a way to validate whether that is what the system is doing.
No possibility the bug is in your code? Google for anything you can think of related. Maybe it is a bug in the library, or poor documentation leading you to use it wrong.
Logic.
Break the problem down, use your own brain and knowledge of each component of the system to determine exactly what is happening and why; then on the basis of this you will discover where the problem isn't, and hence determine where it must be.
I stop working on it until tomorrow. I usually solve my problem in the shower the next day. I find stepping away from the issue, and allowing my brain to clear, allows a fresh perspective on the issue.
Answer these three questions in this order:
Q1: What is the desired output?
I don't care if this is a napkin with scribble on it. I want something tangible that shows me what the end result is supposed to look like. If I don't get at least this far then I stop.
Q2: What is the input?
I find out what data I have coming in. Where this data is coming from from. What formulas I may need. What dependencies there might be on A happening before B. What permissions if any are necessary to get this data. I then ask Question 3.
Q3: Is there enough input to create the output?
If the answer is No then I go back to Q2 and get more input from whoever can give it to me.
For very large problems I break them down in Phases and apply Q1 Q2 and Q3 to each phase.
To paraphrase Douglas Adams, programming is easy. You only need to stare at a blank screen until your forehead bleeds. For people who are squeamish about their foreheads, my ideal architect-and-build for the bigger problems would go something like this. (For smaller problems, like George Jempty I can only recommend Feynman's Algorithm.)
What I write is couched in an on-site business setting but there are analogues in open-source or distributed teams. And I can't pretend that every, or even most, projects pan out this way. This is just the series of events that I dream about, and occasionally come to pass.
Get advanced, concise warning of what the problem is likely to look like. This is not the full, final meeting, but an informal discussion. Uncertainty in certain specification details is fine, as long as the client (or manager) is honest. Then take a piece of paper or text editor, and try to condense what you've learned down to five essential points, and then try to condense those to a single sentence. Be happy you can picture the core problem(s) to be solved without referencing any of your documentation.
Think about it for maybe a couple of hours, maybe playing with code and prototyping, but not with a view to the full architecture: you should even do other stuff, if you've time, or go for a walk. It's great if you can learn about a job an hour before home time in order to deliver a decision around midday the next day, so you get to sleep on it. Spend your time looking at potential libraries, frameworks, data standards. Try to tie together at least two languages or resources (say, Javascript on PHP-generated HTML; or get a Python stub talking RPC to a web service). Flesh out the core problems; zoom in on the details; zoom out to make sure the whole shape is still distinct and makes sense.
Send any questions to the client or manager well in advance of a meeting to discuss both the problem and your proposed solution. Invite as many stakeholders and your programming peers along as is convenient (and as your manager is happy with.) Explain the problem back to them, as you see it, then propose your solution. Explain as much as you can; pitch the technical details at your audience, but also let your explanations fill in more details in your own mental model.
Iterate on 2 and 3 until everyone is happy. Happiness is domain-specific. Your industry might require UML diagrams and line-item quotations, or it might be happy with something jotted on a whiteboard with an almost invisible drywipe marker. Make sure everyone has the same expectations of what you're about to build.
When your client or manager is happy for you to start, clear everything. Close Twitter, instant messenger, IRC and email for an hour or two. Start with the overall structure as you see it. Drop some of your prototype code in and see if it feels right. If it doesn't, change the structure as early as possible. But most of all make sure your colleagues give you a couple of hours of space. Try not to fight fires in this time. Begin with a good heart and cheer, and interest in the project. When you're bogged down later on you'll be glad of the clarity that came out of those first few hours.
How your programming proceeds from there depends on what it actually is, and what tasks the finished code needs to perform. And how you ultimately architect your code, and what external resources you use, will always be dictated by your experience, preference and domain knowledge. But give your project and its stakeholder team the most hopeful, most exciting and most engaged start you can.
Pencil, paper and a whiteboard. If you need more organization, use a tool like MindManager.
Andy Hunt's Pragmatic Thinking and Learning has a lot to say on this question.
Question: How do you eat an elephant?
Answer: One bite at a time.
One technique I like using for really big projects is to get into a room with a whiteboard and a pile of square Post-it Notes.
Write your tasks on the Post-it Notes then start sticking them on the whiteboard.
As you go, you can replace tasks that are too big with multiple notes.
You can shift notes around to change the order that the tasks happen in.
Use different colours to indicate different information; I sometimes use a different colour to indicate stuff that we need to do more research on.
This is a great technique for working with a team. Everybody can see the big picture and can contribute in a highly interactive way.
I think about it. I take anywhere from a couple minutes to a few weeks to mull over the problem and develop a general plan of attack.
Hammer out an initial solution. This solution is probably half-baked and one or more aspects may not work.
Refine that solution. Keep working on the problem till i have something that solves the problem.
(and this may be done at any step in the process) Ask questions on stack overflow to clear up any difficulties i'm having at the moment.
One of my ex-colleagues had a unique Modus Operandi. Whenever faced with a hard programming problem (e.g. Knapsack problem or some kind of non-standard optimization problem) he would get stoned on weed, claiming his ability to visualize complex state (such as that of recursive function doing operations on set passed on the stack) was greatly improved. The only difficulty, the next day he could not understand his own code. So eventually I showed him TDD and he has quit smoking...
I write it on a piece of paper and start with my horrible class diagram or flowchart. Then I write it on sticky notes to break it down to "TO DO's".
1 sticky note = 1 task. 1 dumped sticky note = 1 finished task. This works really well for me so far.
Add the problem to StackOverflow, wait about 5-10 minutes and you usually have a brilliant solution! :)
The following applies to a bug rather than building a project from scratch (but even then it could do both if reworded a bit):
Context: What is the problem at hand? What is it preventing, doing wrong, or not doing?
Control: What variables (in the wide sense of the word) are involved? Can the problem be reproduced?
Hypothesise: With enough data on what is occurring or required, it is possible to hypothesise, that is, to draw a mental image of the problem in question.
Evaluate: How much effort, cost, etc, will the correction require? Determine if it's a show stopper or a minor irritant. At this point, it may be too early to tell, but even that is a form of evaluation. This will allow prioritisation.
Plan: How will the problem be approached? Does it require specifications? If so, do them first.
Execute: A.K.A. The fun part.
Test: A.K.A. The not-so-fun-part.
Repeat to satisfaction. Finally:
Feedback: how did it come to be this way? What lead us here? Could this have been prevented, and if so, how?
EDIT:
Really summarised, stop, analyse, act.
Probably a gross oversimplification:
But really, this holds 100% true.
CONCEIVE
What are you without an idea? You may have a problem, but first you must define it more explicitly. You have a frozen pizza that you want to eat. You need to cook that pizza! In programming, this is usually your brainstorming session for coming up with a solution from the hip. Here you decide what your approach is.
PLAN
Well, of course you need to cook that pizza! But HOW! Will you use the oven? No. Too easy. You want to build a solar cooker, so you can eat that frozen pizza anywhere that the sun grants you power to do so. This is your design phase. This is your pencil and paper phase. This is where you start to form a cohesive, step-by-step method to implementation.
EXECUTE
Well, you are going to build a solar oven to cook your frozen pizza; you've decided. NOW DO IT. Write code. Test. Commit. Refactor. Commit.
Related question that may be useful:
Helpful points of view, concepts or ways to think about problems every newbie should know
Every problem I've ever had to solve on a computer has had something to do with solving a task in the real world. Therefore, I've learned to look at how I would accomplish something in the real world and map that to the computer problem.
Example:
I need to keep track of my student's grades and come up with a final grade that is an average of all the grades throughout the year?
Well, I'd save the grades in a log (database) and I'd have a page for every student (Field StudentID) and so on...
I always take a problem to a blog first. Stackoverflow would be a good place to start. Why waste your time re-inventing the wheel when someone else may have already solved a similar problem in the past? If anything you will get some good ideas to solve it yourself.
I use the scientific method:
Based on the available information about the programming problem I come up with a hypothesis about what the reason could be.
Then I design / think up an experiment that will reject or confirm the hypothesis. This could be observing something in a debugger or screen/file output. Or changing the program slightly.
If the hypothesis is rejected then repeat 1. The information gathered in 2. may help in coming up with a new hypothesis.
If the hypothesis is confirmed then the hypothesis may be refined/become more specific (repeat 1.). Or it may already be clear what the problem is.
This directed way of find the problem is much more effective than changing things at random, observe what happens and try to (inappropriately) use statistics.
No one has mentioned truth tables! But that's probably because they're usually only mildly helpful ;) (although your mileage may vary) I used one for the first time yesterday in my 8 years of programming.
Diagramming on whiteboards or paper have always been very helpful for me.
When faced with very weird bugs. Like this: JPA stops working after redeploy in glassfish
I start from scratch. Make a new project. Does it work? Yes. Start to recreate the components of my app one piece of a time. DB. Check. Deploy. Check. Until it breaks. Continue until it breaks. If it never breaks. Ok. You just recreated your entire app. Discard of the old one. When it breaks. You pinpointed the exact problem.
I think - what am i looking for?
What method best solves this problem?
Implement it with solid logic - no code
Pseudo code
code a rough cut
execute
These is my prioritized methods
Analyse
a. Try to find the source of your problem
b. Define desired outcome
c. Brainstorm about solutions
Try on error (If I dont want to analyse)
Google a bit around
a. Of course, look around on stackoverflow
When you get mad, walk away from pc for a cup of coffee
When you still mad after 10 cups of coffee, Go sleep a night to think about the problem
GOLDEN TIP
Never give up. Persistence will always win
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
Question
My question is how can you teach the methods and importance of tidying-up and refactoring code?
Background
I was recently working on a code review for a colleague. They had made some modifications to a long-gone colleagues work. During the new changes, my colleague had tried to refactor items but gave up as soon as they hit a crash or some other problem (rather than chasing the rabbit down the hole to find the root of the issue) and so reimplemented the problem code and built more on top of that. This left the code in a tangle of workarounds and magic numbers, so I sat down with them to go through refactoring it.
I tried to explain how I was identifying the places we could refactor and how each refactoring can often highlight new areas. For example, there were two variables that stored the same information - why? I guessed it was a workaround for a bigger issue so I took out one variable and chased the rabbit down the hole, discovering other problems as we went. This eventually led to finding a problem where we were looping over the same things several times. This was due in no small part to the use of arrays of magic number sizes that obfuscated what was being done - fixing the initial "double-variable" problem led to this discovery (and others).
As I went on this refactoring journey with my colleague, it was evident that she wasn't always able to grasp why we made certain changes and how we could be sure the new functionality matched the original, so I took the time to explain and prove each change by comparing with earlier versions and stepping through the changes on paper. I also explained, through examples, how to tell if a refactoring choice was a bad idea, when to choose comments instead of code changes, and how to select good variable names.
I felt that the process of sitting together to do this was worthwhile for both myself (I got to learn a bit more about how best to explain things to others) and my colleague (they got to understand more of our code and our coding practices) but, the experience led me to wonder if there was a better way to teach the refactoring process.
...and finally...
I understand that what does or does not need refactoring, and how to refactor it are very subjective so I want to steer clear of that discussion, but I am interested to learn how others would tackle the challenge of teaching this important skill, and if others here have had similar experiences and what they learned from them (either as the teacher or the student).
Like most programming, refactoring skill comes with practice and experience. It would be nice to think it can be taught, but it has to be learned - and there is a significant difference in the amount of learning that can be accomplished in different environments.
To answer your question, you can teach refactoring methods and good design in a pedagogical fashion, and that's fine. But, ultimately, you and I both know attaining a certain level is only through long hard experience.
I am not 100% to understand your question but I think you can refer yourself to Code Smell that need to be refactored.It contain a lot of example that you could show to other.
Here is a list of when refactoring should be used (list of code smell)
If you haven't read it, Martin Fowler has an excellent book on the subject called Refactoring: Improving the Design of Existing Code. He goes into substantial detail about how and why a specific piece of code should be refactored.
I hesitated to even mention it for fear that knowledge of this book is assumed by someone asking about refactoring, and that you would think, "Duh, I meant besides the Fowler book." But what the hey, there you go. :-)
You don't mention tests. To 'prove' that a refactoring does not break the existing functionality you need to either have existing tests or write tests before doing the refactoring.
Pair Programming seems to be the best way for me to get this across. This way, as we're working on real, production code, and we both encounter some code that doesn't smell right, we tackle a code refactoring together. The pair acts as the driver's conscience saying to do the right thing instead of the quick fix, and in turn, they both learn what good code looks like in the process.
Refactoring can be an art, and just takes practice. The more you do it, the better you get at it. Keep studying the methods described in Martin Fowler's Ractoring book, and use your tools (Resharper for Visual Studio folk)
One simple way to conceive of refactoring is right there in the name -- it's just like when you factor a common variable out of an equation:
xy + xz
becomes
x(y + z)
The x has been factored out. Refactoring code is the same thing, in that you're finding duplicate code or logic and factoring it out.
It sounds like your approach is a very good one. At the end of the process, you showed how you were able to uncover and fix a lot of problems. For educational purposes, it could then be interesting to invent a new change/enhancement/fix. You could then ask your mentoree how they would enact that change with the old a new codebase. Hopefully they'll see that it's much easier to make the new change with the refactored code (or how doing more refactoring would be the easiest way to prepare for the hypothetical change).
I see a couple of different ways you could try to teach refactoring:
Given textbook-like examples. A downside here is that you may have contrived or simplistic examples where why refactoring is useful doesn't necessarily shine through as well as in other cases.
Refactoring existing code. In this case you could take existing legacy code that you'd clean up, or your own code in development and show the before and after doing various bits to see how much better the after is, in terms of readability and ease of maintanence. This may be a better exercise to do as this is live code being improved and enhanced to some extent.
It isn't something that someone can pick up instantly, it takes time, practice, effort and patience as some refactorings may be done for personal preference rather than because the code runs optimally one way or another.
Teaching someone to refactor when they aren't a natural is a tough job. In my experience your best bet is to sit down with them in an office and refactor some code. While you are doing this keep up a "stream of consciousness" dialog. Talk about what you see, why the code doesn't smell right, options to refactor to, etc. Also you should make sure they're doing the same thing. The most important thing is to impart why, not how, to change the code. Any decent programmer can make a change and have it work, but it takes skill and experience to be able to state why the new solution is better than the previous.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Does anyone have any suggestions on how to mentor a junior programmer ? If you have mentored someone did you follow any process or was it quite informal ?
If you've been mentored in the past what kind of things did you find most helpful ?
Try to set aside between 30-60 minutes a day to review their code together. If you can't do this, then try to get together to review their code whenever they make a code commit, unless it was very basic. Have them explain why they chose the approach they took in lieu of others. A process like this helps to establish a great relationship, as well as really stimulate the student to think on their own and be able to defend their decisions. Not only does the student end up with someone approachable whom they can trust, but you'll notice an improvement in their quality of code and logic almost immediately.
Edit: Also, If you are unable to commit this much time to co-review with your junior, then you probably shouldn't be mentoring them and instead see if anyone else has a schedule that would allow it. The whole point of mentoring is to actively aid in the professional development of the student, and they're not going to learn much if proper attention and guidance is not given to them.
I had the chance to work as an intern (one of two) in a small software company and had the opportunity to work on an "almost new" project they had. They had me set up with everything needed and gave me an introduction into what the project actually was (basic stuff like what the requirements were etc).
At first we got to do minor tasks like researching things that mattered to the project (they had given us a list of topics). This was, I think, to see how much we could handle ourselves, as the things we needed to look up and research were not that trivial and it took a good 2 weeks or so (counting the basic demos we had to create for it). That testing phase was actually done really without much 'coaching'.
However, after that period we could work on the actual project itself. This was also the moment we began to be coached together, in a similar style to pair programming, except there were three of us (2 interns and 1 'coach').
We learned a lot from him, but it was in an informal manner, and he didn't act like the 'all-knowing-listen-to-me' guy. When we had suggestions he would listen and think through with us whether they were any good. or give his view on why an idea should not be done in that way... Now that I think of it, he actively encouraged us to make suggestions, and to think about better ways to do things, instead of just sitting there 'taking orders' from someone who probably knows what to do better then you.
So in short:
Let the junior programmer work (mostly) on his own to study the materials at hand, give him a list of minor TODO things like looking up information, or building small demos.
Check the work he has done regularly and advise him if there are better ways to do things. Also point out the items he actually did well, that way he'll remember those for later.
Let him work on a real project, and mentor him by working together at the same project, giving him advice when he has questions.
The effort has to come from both directions: encourage him to ask questions, to challenge 'the way it is currently done'. Ask him questions on how he thinks it should be done and give him your opinion as well.
Make it 'enjoyable' - don't let it look like you are giving orders.
During an internship w/ a large company that had a lot of in house IT, I was paired w/ a mentor. The practice definitely aided my career development, both in terms of technical skills and business skills. Here are some of the reasons the mentoring worked out so well:
Credible: The mentor had 8+ years of experience and an accomplished background to draw upon in leading and training. He'd been through different challenges, worked in different environments, so he had a great perspective.
Genuine: The mentorship was encouraged by the supervisor, but not so formal as to make it an exercise in going through the motions. The mentor wanted to mentor, and I wanted someone to learn from.
Passion: The mentor loved the field he was in, the problems he was solving, and the technologies he was using. When I came under his wing, I found this to be infectious.
Sharp and Articulate: The mentor approached issues critically and framed them concisely. There wasn't a lot of fuzziness in our discussions; we got to the root of the matter and he directed me on wise courses of problem solving and action.
Meaningful: The work I was doing w/ the mentor was meaningful work, not just an exercise to keep busy or ramp up in a skill set. By jointly working on a task that tangibly aided the organization, that helped focus my interest and legitimize the mentoring process.
At my first place of employment there was this really patient dude that would always help me solve my immediate problem, and then teach me some important underlying principle. I loved this because he would help me stay productive while teaching me how to become a better programmer.
I'd be the junior, I guess :) I think I'd value an informal approach. It probably depends a lot on your and your mentee's characters, but I'd say that you learn best if you don't have egos in the way. Break the ice, make sure there's feedback in both directions. Things like code reviewing (both ways?) and occasional pair programming may work, and if there's a good match, it may be a lot of fun, as well!
Because I had to explain why I wanted to co-op (besides needing the money) during my interview, my manager made sure my first project allowed me to work on what I had identified as weak areas: very little Linux experience (I chose a Linux-only R&D team so I would be forced to learn), not knowing a useful text editor (I really wanted to learn Vim), and how to learn another programming language (very different approach than learning a language as you learn to program). He told me I was being paid to study for a while.
I learn best by reading books, so after chuckling over Unix for Dummies (yay! I wasn't the only one who thought this was obscure and knuckleheaded sometimes) I started with Unix in a Nutshell and Sobell's Practical Guide to Linux Commands. After that I printed out the Vim documentation and started going through it. Then I looked through a couple books on Python, the language of my first project. I was given all the time I needed to feel comfortable about these things (which was the real problem, as I now understand) and then began adding functionality to a previous co-op's project.
I realize now it would have been terrific to meet with someone every day or two for code review, as Kamikaze Mercenary said.
In my experience, when mentoring someone, it is very important for the mentee to really WANT to learn more.
Never ever spoon feed them. Instead point them towards things of value and have them utilize the new information they are learning in projects that they are using. Knowledge is useless if not put into practice. So encourage your mentee to code, code, code.
Here would be my short list:
Pair programming - This is helpful for many things, like reinforcing various ideas and practices. Getting used to Resharper is much easier when you pair with someone that uses it often.
Informal chats - This is where we would go get a drink, go outside for someone to have a smoke break, go for lunch together, etc. While away from the desks, the discussion may be related to work immediately being done or it may be abstract philosophical stuff that can help bring someone's game up a notch or two. Talking about various upcoming technologies or changes in what coming can be exciting and help form bonds as well.
Feedback and suggestions - This is what occured in both above cases. Books like "How to Win Friends and Influence People" by Dale Carnegie can help in understanding various human relationship dynamics, which while that sounds quite technical is really just about how to motivate someone else in various ways. A key point here is to know how to leave a trail of breadcrumbs to pick up some practices, like giving hint after hint about something rather than just give the answer. I have had various Math teachers that had a gift for this for how I developed some of this skill.
So part of this is merely motivating the other person and trying to guide them as when someone figures something out for themself it can be an empowering and enlightening experience. The, "I did it! That's right, moi, yours truly!" kind of self-talk is quite nice when it happens.
Ask them what would they try next to complete the task. This can give an idea of where from the "I don't know what to do" to "Well, I would try this but..." category are they in terms of having their own idea that may be useful for a starting point.
Take a quick look at what they want to do and offer hints so that they figure out the problem. This is rather than give the answer of, "Just take out this line of code," suggest they look at what is there and is it all necessary
I would recommend start giving parts of real assignments you have and make everything to be able to use his code. In other words train him as replacement for yourself.
This way you will commit yourself to allocating time to work with junior and he will be able to see "real life". By working on real assignments and hearing lively feedback he will be able to get p to speed rather quickly.
Drawback of this approach is that it is possible that it will have too narrow focus on you particular project. So be sure to show the trainee possible alternatives and encourage trade-offs analysis to widen his professional horizon.
Couple of years ago I worked for a small company, where on the first day I was given a list of small task to complete - do some little changes in code, find and fix a small bug in the project. It really helped me to ask the right questions from my mentor and familiarize myself with the environment, the code base. These tasks were easy to complete, so I had a little bit of self confidence, before turning to the bigger tasks.
This way of mentoring really worked with me very well, so I am planning to do the same with our new colleague.
I have mentored several junior people under me before. My approach varied slightly based on the person a bit based on how they learned.
In short, I gave the junior people small, self-contained projects when I could and gave them a relatively fixed time to complete the task. Once the task was complete I would review their approach, code and solution and made suggestions for improvements or a better way to handle the problem. I think this way they don't feel overwhelmed being part of a much larger project.
Hope this helps a bit.