How do you write code that is easily read by other people who have had no hand in writing any part of it? - readability

How do you write code that is easily read by other people and who have had no hand in writing any part of it?

The best way to ensure that others can read your code is to make sure that it is clear and concise. Namely,
Use self documenting names for variables, functions, and classes.
Comment complex algorithms so that the reader doesn't have to spend to long figuring out what it does.
Ensure that tabbing and line breaks are constant throughout the code.
Beyond that you start to get in to the areas that might be a bit subjective, most people should agree on these items.

You may want to take a look at Clean Code by Robert C. Martin. It offers up a lot of useful practices for ensuring your code is readable.
Additionally, if your code is supported by a number of unit tests that thoroughly test your code, it offers a way for your user to understand the code by looking at what the tests are doing. You will also find that if you follow the Test Driven Development process, and you write tests for each bit of functionality, your functions tend to be small, do one thing only and do it well, and tend to flow more like a story than simply a large complex web of "stuff".
Tests tend to stay up-to-date more than comments. I often ignore comments anymore due to simple fact that they become obsolete very quickly.

This question is subjective, and should be avoided on StackOverflow, as per the FAQ
What kind of questions should I not
ask here?
Avoid asking questions that are
subjective, argumentative, or require
extended discussion. This is a place
for questions that can be answered!
The short answer would be:
Avoid excessive commenting:
// add one to the count:
i++;
Use good variable and method names:
int x = i + j;
int runSum = prevSum += newValue;
Use coding shorthand where available:
if (x == y)
{
z = a;
}
else
{
z = b;
}
z = (x == y) ? a : b;

Keep code nice, clear and simple. Don't comment what you're doing when it's obvious (for instance I know what a foreach or if does, I don't normally need an explanation).
Code tricks (such as auto properties) that make simple things take up fewer lines are good too.

Buy & read Code Complete 2. There's loads of stuff in there about writing easy to read / maintain code.

I don't think it's a subjective question, but it's too broad! It's not just about commenting and giving good variables names. It deals with how humans comprehends code. So your system must be implemented in a way that the reader can easily construct a mental model of its design in two way:
Top-down: assuming the user knows the system domain, he tends to make assumptions on how it would be implemented, so he'll scan the system packages and classes looking for entities he can identify. Giving good names to your classes and properly modularizing it would help very much.
Bottom-up: once the user reaches a portion of code he'll start navigation from there, building chunks of knowledge. If your system has low cohesion and lots of implicit dependencies the user will be lost.
Kent Beck adopts three principles: Communication, Simplicity and Flexibility. Of course, sometimes you'll have to trade simplicity for flexibility, and vice-versa.
This could go on and on. The answer to this question fits in a large book. As #rmbarnes suggested, buy and read Code Complete 2. I also suggest Implementation Patterns by Kent Beck - its highly related to your question.

Document the code as to why it does what it does.
Make sure that all variables functions etc. are named consistently and descriptively
Use white space to group logical portions of code together, so it flows while reading.
Place the functions/methods etc. in a logical order.
(this one is my personal preference) Make sure that code can easily be read on the screen without having to scroll horizontally (some people say vertically too, but this doesn't seem to bother me).

Since everyone else said pretty much what I'm thinking when I read this question, I'll just share two books related to this subject that you might be interested in reading. These books use open source code examples to explain how to read and write high quality code. In addition to Code Complete, I think they are valuable resources when you want to write good code in any language.
Code Reading: The Open Source Perspective
Code Quality: The Open Source Perspective

My rules:
Give everything a meaningful name, and call it what it is. Avoid using "x" and "y" for variables.
Don't abbreviate ANYTHING. I don't care how long the variable name is, don't abbreviate, even with comments. Interpretation of abbreviations is subjective. Does Cmp mean computer? Computer? Company? Compliment? Make it a strong rule, no exceptions, and its easy to follow.
Don't put multiple statements on the same line. Each line performs a single action.
Avoid Hungarian Notation like the plague. Or is it ntHungarian?
Use brackets even for single-line (if, for) substructures. Indentation differences are too easy to lose.

A lot of good answers here, I would like to add something from the perspective of an engineer who likes the big picture. I frequently found that getting a high level overview, in terms of class diagram or a package level overview (diagram/comments etc), heck if nothing exists a 10 line header comments in a file to help me a lot. We can use Doxygen/Javadocs to generate them, or spend 10-15 minutes to just jot down something in comments section.
They dont have to be 100% accurate, and I doubt the overall structure of classes/packages will change without a complete rewrite.
I personally found this kind of big picture overview very helpful and am sure there are others who feel the same.

Probably the most important point is to keep your syntax consistent. I would also have a look at the design guidelines for the language you are writing in.

I am most likely in the minority, but I don't mind whitespace. I LOVE WHITESPACE. Since the compiler takes it out and HD space being so cheap I like to have white space in my code.
For example I like:
int total = 10;
int sum = 0;
for (int i = 0; i < total; i++)
{
sum += i;
}
// Next coding statement is a space below the bracket
return sum;
I do not like:
int total = 10;int sum = 0;
for (int i = 0; i < total; i++)
{
sum += i;
}
return sum;
What I also put in Brackets even though technically they are not needed. The best example is the if statement. I find it greatly helps readability.
if(true)
// some action
if(true)
{
// Some action
}
The best code to me, is one that as simple as possible. With the least comments as possible, and most importantly works.

From being a developer with several years under the belt, this used to be a real question for me. I couldn't even say how many hours I passed thinking about this and trying different things in my code. The above answers are very nice too. I just want to add a thing or two.
We each have different things that make our reading different than the others. Something that you find easy to read, might really be hard for somebody else to read.
Cleanliness of your code is a very important aspect. Soon as it gets too cramped just forget about it.
Most important: You are you own teacher. No matter what style you follow, you will want to change a thing or two based on your experience. As months pass and you have to go back to your old for fixes or documentation, you will have the "I can't believe I wrote code that reads like that" effect. Take notes of what was bugging you with the code readability and make sure not to write like that again.

Related

Tools and techniques to improve comprehension of unfamiliar code? [closed]

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.
I've realised that my greatest weakness as a programming student is my poor ability to comprehend other people's code.
I have no trouble whatsoever with 'textbook' code, or clearly-commented code, but when given a program of a few hundred lines, containing a dozen or so different functions and no comments, I find it very difficult to even begin.
I know this type of code is what I'm probably more likely to encounter in my career, and I think that having poor code comprehension skills is going to be a great hindrance to me, so I'd like to focus on improving my skills in this area.
What tools/techniques have helped improve code comprehension in your experience?
How do you tend to tackle unfamiliar, uncommented code? Why? What about your technique do you find helpful?
Thanks
Familiarizing yourself with foreign code
If the codebase is small enough, you can start reading it straight away. At some point the pieces will start falling together.
In this scenario, "small enough" varies, it will get larger as your experience increases. You will also start benefiting from "cheating" here: you can skip over pieces of code that you recognize from experience as "implementing pattern X".
You may find it helpful to make small detours while reading the code, e.g. by looking up a function as you see it being called, then spend a little time glancing over it. Do not stay on these detours until you understand what the called function does; this is not the point, and it will make you feel like you are jumping around and making no progress. The goal when detouring is to understand what the new function does in less than half a minute. If you cannot, it means that the function is too complicated. Abort the detour and accept the fact that you will have to understand your "current" function without this extra help.
If the codebase is too large, you can't just start reading it. In this case, you can start by identifying the logical components of the program at a high level of abstraction. Your goal is to associate types (classes) in the source code with these components, and then identify the role each class plays in its component. There will be classes used internally in a component and classes used to communicate with other components or frameworks. Divide and conquer here: first split the classes into related groups, then focus on a group and understand how its pieces fit together.
To help you in this task, you can use the source code's structure as a guide (not as the ultimate law; it can be misleading at times due to human error). You can also use tools such as "find usages" of a function or type to see where each one is referenced. Again, do not try to fully digest what the IDE tells you if you can't do it reasonably quickly. When this happens, it means you picked a complicated piece of metal out of a machine you don't quite understand. Put it back and try something else until you find something that you can understand.
Debugging foreign code
This is another matter entirely. I will cheat a little by saying that, until you amass tons of experience, there is no way you will be debugging code successfully as long as it is foreign to you.
I find that drawing the call-graph and inheritance trees out often works for me. You can use any tool you have handy; I usually just use a whiteboard.
Usually, the code units/functions are easy enough to understand on their own, and I can see plainly how each unit operates, but I often times have trouble seeing the bigger picture, and that's where the breakdown happens and I get this "I'm lost" feeling.
Start small. Say to yourself: "I want to accomplish x, so how is it done in the code?" where x is some small operation that you can trace. Then, just trace the code, making something visual that you can look back on after the trace.
Then, pick another x and repeat the process. You should get a better feel for the code every time you do this.
When it comes time to implement something, choose something that is similar (but not almost identical) to one of the things you traced. By doing this, you go from a trace-level understanding to an implementation-level understanding.
It also helps to talk to the person who wrote the code the first time.
The first thing I try and do is figure out what the purpose of the code is at a high-level -- the detail's kind of irrelevant until you understand a bit about the problem domain. Good ways to figure that out include looking at the names of the identifiers, but it's usually even more helpful to consider the context -- where did you get this code? Who wrote it? Was it part of some application with a known purpose? Once you've figured out what the code's supposed to do, you can make a copy and start reformatting it to make it easier for you personally to understand. That can include changing the names of identifiers where necessary, sorting out any weird indentation, adding whitespace to break things up, commenting bits once you've figured out what they do, etc. That's a start, at any rate... :)
Also -- once you've figured out the purpose of the code, stepping it through a debugger on some simple examples can also sometimes give you a clearer idea of what's going on FWIW...
I understand your frustration, but keep in mind that there is a lot of bad code out there, so keep your chin-up. not all code is bad :)
this is the process that I tend to follow:
look for any unit tests as they should document what the code is supposed to do...
navigate through the code using code rush / resharper / visual studio shortcuts - this should give you some ideas about the logical and physical tiers involved...
scan the code first, looking for common patterns, naming conventions, and code styles - this should give you insight into the teams standards and maybe the original coders mind set...
as I navigate through the code heirarchy I make a note of the the objects being used... typically with pen & paper drawing a simple activity diagram :
I tend to start from a common entry point, so if it is a UI, start from the view and work your way through to the data access code, if its a service start from the service boundary and work your way through to the data access code...
look for code that could be refactored - if you can see code that can be refactored, you have learned how to simplify it without changing its behavior...
practice building the same thing that you are reviewing, but in a different way...
as you read through untested code, think of ways to make it testable...
use code rush diagnostics tools to find methods that are of high maintenance complexity or cyclomatic complexity and pay special attention to these areas because chances are, this is where the most bugs are...
Good luck
Understand is a terrific code analysis tool. It was in wide use at my previous employer (L-3) so I purchased it where I currently work.

Basic Code Layout Question

HI, I have a simple question, I've asked 3-4 different people and have had different answers from each of them.
Which code layout is better and used more?
does it really matter as long as it's consistent?
Which is seen as better practice in the world of working as a programmer?
Eg
A)
for(int i=0;i<8;i++)
{
for(int p=0;p<8;p++)
{
if(array[i][p]->Equals(String))
{
//Do Stuff
}
}
}
OR
B)
for(int i=0;i<8;i++){
for(int p=0;p<8;p++){
if(array[i][p]->Equals(String)){
//Do Stuff
}
}
}
Thanks,
Tim
Several published style guides exist -- for example, Google's is here, and it mandates, for functions:
ReturnType ClassName::FunctionName(Type par_name1, Type par_name2) {
DoSomething();
...
}
and for blocks:
if (condition) { // no spaces inside parentheses
... // 2 space indent.
} else { // The else goes on the same line as the closing brace.
...
}
with similar examples for other blocks.
So, look around a few such style guides, pick one that's from a somewhat prestigious source and that you like, and if anybody objects to your style just say "oh, I picked it up from X" (where X may be Google, geosoft, or whatever other source you like (many more are listed here).
In almost all cases in practice, there is a clear answer: Use the style that is currently in use in the codebase that you're working with. If you are starting a new project, use the style that is currently in use in the other projects maintained by the team that will be maintaining your code.
The codebases I've worked with have largely had their roots in GCC and other FSF software, which means that all of my projects have used the style with the "{" on a separate line. I could come up with justifications for why that's "better", but that's a matter of subjective style. Being consistent within a project and within a team is objectively better.
This is entirely subjective. Both are popular.
There's no right or wrong here. It's up to the preference of you, or your team/organization.
As far as the braces go, my current team has chosen option B, but I actually prefer option A.
Personally I would recommend a little more spacing especially after the "for" and "if", and a bit more indentation on option B, for readability. But, that's just my preference.
What, no middle ground? Just two examples, each designed to take a (relatively) extreme position?
Clearly, you've left out a whole bunch of intermediate examples with lots and lots of slightly different formatting rules.
You're not really putting any effort into it if you can't think of at least ten more variants. Two variants isn't enough focus on nuance.
You can -- if you want -- be lazy. A decent IDE will format for you. I use Eclipse and it formats for me and that's what I use without thinking about it at all.
You can also download and read open-source code and actually emulate styles you find there. That's a little less lazy approach, you do have to read other's people's code.
I am not sure its possible to come up with reasons why one is better than the other that arent completely subjective and only valid for a small set of projects.
I like the compressed style, it tends to make code more compact and since I like my functions to be compact and fit on screen it helps.
It drives other people nuts though, and they dont like not seeing a block start and end on its own line. I can see their point.
Usually its not a big deal as each developer uses their own settings and we let the source control system store it in an agnostic format (doesnt really matter which one).
Of course YMMV.
As some have already pointed out, you should use the style that is already in use by the code base or the team.
However, if you are in college or have never used a language that uses curly braces, I would suggest placing the curly braces on their own line. I have found that new developers can have problems identifying missing curly braces when they are placed on the same line as code. This probably isn't as big of a deal with modern IDEs.
When I was younger, I used to believe that all of these questions were matters of opinion, subjective, and best left to individual taste.
As I have aged, my vision has become increasingly astigmatic. Without surgery, astigmatism is correctable using either glasses or contacts -- but the correction is far from perfect.
Astigmatism makes reading harder, including reading code.
For a person with astigmatism, such as myself, identifiers_with_underscored_spacing are much easier to read than IdentifiersWithCamelCaseWordBreaks.
Similarly, for me, braces on lines by themselves are easier to read than braces sharing a line with code.
Therefore I recommend the second style you propose because it is more accessible.

What is a good example to show to a non-programmer to explain what programming "looks like"? [closed]

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 last month.
The community reviewed whether to reopen this question last month and left it closed:
Original close reason(s) were not resolved
Improve this question
A friend of mine asked me the other day if I'm just looking at lists of numbers when I'm programming, or how it works. I tried to explain that it's generally more like math formulae, with the odd english word tossed in, and that it's generally mostly readable. But that's a very vague explanation, and it doesn't really explain much to a non-programmer.
But it got me to thinking about what would make a good example. Not because I want to teach her programming or anything, but simply to give her an idea of what program code "looks like".
And that got me to wonder about what would actually work as a good example. And that's turning out to be surprisingly difficult.
My first thought was obviously a simple "Hello World" program. But it really doesn't show anything useful. It doesn't really show how we use functions, or variables, or control flow structures like if or while to make a program that actually does something. There's no logic to it. The program doesn't react to anything.
So perhaps something like computing prime numbers would be a better example. But then again, that might be too theoretical and impractical... (What good is that? What does it have to do with writing "real" programs?) And again, there's no significant control flow logic in it. It's just a straight sequence of maths.
And also, which language should be used?
Ideally, I don't think it has to be a very "clean" language. But rather, it should probably make the structure clear. If it does that, then a certain amount of noise and clutter might be fine. Perhaps something like C++ would actually be a better example than Python for that reason. The explicit curly braces and type specifiers are obvious "hooks" to help explain how the program is structured, or to highlight that it's not just simple statements that can almost be read out as english.
But with C++ we also get into some downright weird syntax. Why is std::cout << x used to print out x? Why not a "normal" function call syntax? And printf isn't much better, with its arcane format string, and lack of extensibility (do I want to complicate the program by using char* for strings? Or do I use std::string and settle for calling the seemingly unnecessary s.c_str() to get a string that can be printed with printf?
Perhaps a higher level language would be better after all. But which one? And why?
I know there are plenty of similar questions here about which language/example program to use to teach programming. But I think the requirements here are different. When teaching programming, we want simplicity more than anything. We want to avoid anything that hasn't been taught yet. We want to make sure that the student can understand everything on the screen.
I'm not interested in simplicity per se. But rather in giving an "outsider" an idea of "what a program looks like". And programs aren't simple. But they do generally exhibit a certain structure and method to the madness. What language/program would best highlight that?
Edit
Thanks for all the suggestions so far. Some of you have had a somewhat different angle on it than I'd intended.
Perhaps an example is in order. I can't fly an airplane, but I've got a basic understanding of what the cockpit looks like, and what a pilot "does" while flying.
And I'm not a trained carpenter, but I know a saw or a hammer when I see one.
But when you see anything to do with programming in movies, for example, it's usually just screens filled with garbage (as in the green text in the Matrix). It doesn't look like something a normal human being can actually do. There's nothing recognizable in it. Someone who isn't a programmer simply thinks it's black magic.
I don't want to teach her to fly, or to program software.
But I'd like to give her a basic frame of reference. Just an idea of "ah, so that's what you're working with. So it's not just random symbols and numbers on the screen". Even just showing a simple if-statement would be a revelation compared to the Matrix-style random symbols and numbers.
Some of you have suggested explaining an algorithm, or using pseudocode, but that's what I want to avoid. I'd like something that simply shows what actual code looks like, in the same way that you don't have to be a carpenter to look at a saw and get a basic idea of what it is and how it works.
When I was a kid, we once went on vacation in Italy. On the way down, the pilot let me into the cockpit of the plane. Of course, I didn't learn how to fly the plane. But I did get a peek into the pilot's world. I got an idea of how they make the plane go, what the pilot actually does.
That's really all I want to do. My friend has no interest in learning programming, and I don't want to force her to understand source code. But she was curious about what kind of tools or entities I work with. Is it Matrix-style symbols scrolling across the screen? Pure mathematics? English in prose form?
All I'm interested in conveying is that very high-level understanding of "What does it look like when I work".
BASIC
10 PRINT "Sara is the best"
20 GOTO 10
Update: when I was 12, my cousin (he was 14) brought Turbo Pascal 7.0 and installed it in my computer.
He programmed a tic tac toe game from scratch (in BGI mode, for those who know).
I watched/observed step by step how a program evolves until it becomes a complete application.
Until then, I knew only how to print strings in BASIC :-B
You can do a similar thing. Pair programming. Well, actually your friend will be an observer but she'll get an idea ;)
Why not consider a language that doesn't exist (or does, if you so believe) and use Pseudo Code? I think, depending upon what you want to achieve - I'd consider the example of task familiar to the person, but carved up into a pseudo code example.
I generally find the idea of "cooking" or "recipes" to be a great fit when explaining things to non-programmers.
I ask the person to imagine they had a recipe that was fairly complex - e.g. a curry & rice dish. I then suggest that they should try and write it down for someone who has absolutely no idea what they are doing, so that they can cook it.
There is a very definite few stages involved:
Gather the ingredients and tools for the job.
Prepare the ingredients. This is complex. e.g.
get 3 Small Red Peppers.
for each red pepper you have, chop it into chunks about 1cm square.
place the red pepper chunks into a bowl for later.
Seperately to this, call the prepare rice function and have this working asynchronously in the background while you continue on with the cooking.
I'm sure you can see where this is going... ;)
There are a lot of similarities with Cooking and Programming (as there are with many things, but more people have an understanding of cooking than of building a house).
There stages / similarities (as I see it) are:
Gathering: (declaration of what is required to achieve the goal and getting them together).
Preperation: Chopping the ingredients or readying the data connection objects etc for first use.
Asynchronous: The ability to have one thing going while another thing going.
Functions: The rice making, the chicken cooking and the curry cooking all require separate processes and only at the end can you have the makeCurry(chickenMeat, rice) function.
Testing: Ensure that as you are going along, you aren't missing any bits and that everything is going smoothly - e.g. ensuring chicken is cooked before you move to the next stage.
Garbage: Once you've done, you must ensure that you tidy up. ;)
Principals of Best Practice: There are efficient ways of doing things that like cooking, beginning programmers have to learn in addition to the code - sometimes it can be hard to get your head around. e.g. D.R.Y, how to chop efficiently with a knife & don't eat raw chicken ;)
Basically, I think for teaching programming as a general topic - I wouldn't necessarily teach from a language unless you had a compelling reason to do so. Instead, teach initially from the abstract until they understand at least the fundamentals of how things might fall together. Then they may find it easier when sat in front of a monitor and keyboard.
I think there may not be one "right answer" for this one. But I think maybe a few really good ideas you could maybe take bits from all of.
I would explain that programming is giving detailed instructions so the computer can make complex tasks.
How to make two cups of coffee?
Fill the kettle
Boil water
Coffee in cup
Pour on water
Add sugar
Add milk
Do 3 to 6 again
To answer your question directly - what programming “looks like”, I'd show them a print out of a large application. Toy apps or cute things like qsort in haskell really give the wrong idea.
It looks a bit like this. Sometimes.
Maybe everyone is concentrating too much on the code rather than tools. Possibly it's best to show her a project in an IDE, and how it includes various source files and maybe some diagrammatic things like a database schema or a visual user interface designer too. Visual Studio, Eclipse or Xcode are quite far away from most people's mental image of rapidly scrolling glowing green symbols on a black background.
I think you should download some big win32 application, written in AT&T assembly language, and show it to her in notepad, and tell her, "As you can see, it takes a superhuman like myself to program."
Code something that has any comprehensible value to a non-programmer. If I'd demonstrate Quicksort to my mother, it wouldn't be of any use.
Ask the person about his interests. If he/she's into stock exchange for example, hack together a script that reads some stock statistics from a appropriate web page and compiles them into an excel sheet (use csv, to avoid heavy brain-damage ^^) or maybe into a nice graph.
If the person uses Twitter, code something that counts the followers of his followers or something like that.
These tasks are simple enough to be done in a very short time and they already utilize a lot of the basic tools that we programmers use, like loops, libraries (for all the http stuff involved), maybe recursion.
After you're finished or while you're coding (even better), you can explain how your program does its magic.
Just keep it simple and talk in human language. If you show them megabytes of code and talk about things like prototypal inheritance, you just intimidate them and they will lose interest immediately.
To give my wife an idea of what I do to bring in a paycheck (It's real work! I promise! we don't just browse the web all day!) I sat down with her one evening with Python and showed her a couple of the basic concepts: calling a function (print), assigning and reading a variable, and how an if statement works. Since she's a teacher, I likened the concept of conditionals to working with preschoolers :)
IF you hit Jonny THEN you're in time out OTHERWISE you can have a snack.
After reviewing a couple of the very high level concepts, I then showed her the code to a simple number guessing game and let her play it while looking though the code.
# Guessing Game
import random
print("Guess a number between 1 and 100: ")
target = random.randint(1, 100)
guess = 0
guess_count = 1
while guess != target:
guess_count += 1
guess = int(input())
if guess == target:
print("Correct!")
if guess < target:
print("Higher...")
if guess > target:
print("Lower...")
print("Congratulations! You guessed the number in " + str(guess_count) + " guesses!")
Aside from the somewhat abstract concept of "import", this is a very straightforward example that is easy to follow and "connect" to what's happening on the screen, not to mention it actually does something interesting and interactive. I think my wife walked away from the experience a little less mystified by the whole concept without really needing to know much in the way of code.
I think the key is being able to have someone see the code AND it's end result side by side.
There was a CLI graphics package called LOGO, and best known for Turtle Graphics, used to draw shapes on screen using commands like LT 90, RT 105 etc. See if you can find that, it would be a nice experience to try and draw something of medium complexity.
LOGO - Logic Oriented Graphic Oriented programming language.
REPEAT 360 [FD 1 RT 1] -- draws a circle, etc.
See more at logothings or Wikipedia which also has links to modern logo interpreters.
The computer programmer writes programs.
While not programming, the computer programmer annoys attractive women in his workplace.
Then:
(source: markharrison.net)
Now:
When my 5 y.o. daughter asked me the question I made her "develop" the program for a little arrow "robot" that will get him into the upper-left-corner of the board using flowchart-like pieces of paper signifying moves, turns and conditions. I think it applies to grown-ups as well.
I do not claim the invention of this answer, though.
About your edit: I'm afraid, programmers have even less idea of the idea others have about programming. ;-) People think that programming is a matrix-like green video card corruption about as much as they think that spies are all equipped with James Bond's hi tech toys. And any professional in any field is normally irritated when watching the movie concerning his job. Because the movie maker has no idea! Do we know how to properly depict programming in the movie on the other hand? ;-)
I've found that the best approach to "teach someone what programming is without teaching them programming" is actually to just drop anything related to a specific programming language.
Instead (assuming they're actually interested), I would talk them through implementing a function in a program, like a simple bank loan application (most people have had to deal with loans at some stage, if they're above a certain age), and then poking holes in all the assumptions.
Like, what should happen if the user types in a negative loan amount? What if the user cannot afford the loan? How would the loan application know that? How would the loan application know which bank account to check and which payment history to check (ie. who is the user actually)? What if the user tries to type in his name in the loan amount field? What if the user tries to take the loan over 75 years? Should we limit the choices to a list of available lengths?
And then in the end: Programming is taking all of those rules, and writing them in a language that the computer understands, so that it follows those rules to the letter. At this point, if it is felt necessary, I would pull out some simple code so that the overall language can be looked at, and then perhaps written out one of the rules in that language.
Bonus points if you can get your friend to then react with: But what if we forgot something? Well, then we have bugs, and now you know why no software program is bugfree too :)
Definitively something either with graphics, or windows, in a higher level language.
Why? A non-programmer is usually a non-matematician too, that's why he won't get the beauty of sorting. However showing something drawn on a screen ("look, a window!", "look, so little typing and we have a 3D box rotating!") can work wonders ;).
What does it look like when you work?
It looks like typing.
Seriously though, programming is kind of like if Legos were text, and to build a big Lego house, you had to type a lot of text in, just right, hooking up the right pegs with the right holes. So that is how I generally describe it.
It's really hard to understand what programming is like just from a source code example, because it is so abstract.
There is nothing wrong with starting on hello world, as long as you can show what the computer actually does with it. You can then introduce one construct at a time. That's what programming is like- Making incremental changes, and seeing the results.
So you have a hello world program. Now change it to
string Name = getLine();
printf("Hello, %s", name);
then the if construct
printf("Do you like cake?");
string answer = getLine();
if(answer == "yes") {
printf("Yeay! I like cake too!");
} else if(answer == "no") {
printf("Filthy cake hating pig!");
}
then demonstrate that the last program fails when it recieves an answer other than either "yes" or "no", and how you would go about fixing it....
and so on. I don't think you need to go into deep concepts like recursion, or even functions really.
It doesn't really matter what programming you use for this, as long as you're able to show, on a computer, the result of these different programs. (though these psuedocode examples are probably pretty close to being valid python)
Robotics is great for explaining programming, I think, because even simple, contrived examples are practical. The robotics equivalent of Hello World or printing a list of numbers might be having the robot move in a line or spin in a circle. It's easy for a non-programmer to understand that for a robot to do ANYTHING useful it must first move and position itself. This lets you explain simple program structure and flow control.
You want the robot to move forward, but only while there is nothing blocking its path. Then you want it to turn and move again. That's a simple routine using basic flow control, and the functions that you're calling are pretty easy to understand (if your platform has decent abstractions anyway).
Graphics might also work. Anything that has immediate results. jQuery even, because everyone is familiar with rotating pictures and web animations. Even contrived examples like pushing elements around in the DOM has an easy to see effect, and most people will understand what and why the statements in the program do.
Things like Robocode and LOGO are probably really good for this.
(source: wikimedia.org)
{
wait for 6/8;
play F (5), sustain it for 1/4 and a half;
play E flat (5), sustain it for 1/8;
play D flat (5), sustain it for 1/8 and a half;
play F (4), sustain it for 1/16;
// ...
}
Perhaps a metaphor could be that of a composer writing a musical score. The job of a composer is the intellectual activity of creating music. With a score, the composer is telling the pianist what to play, and he does it by means of precise instructions (notes, pauses and so on). If the "instructions" are not precise enough, the pianist will play something different.
The job of a software developer is the intellectual activity of solving problems (problems that have to do with automated processing of data). With source code, the developer is telling the computer what to do, and he does it by means of precise instructions. If the instructions are not precise enough, the computer will do something different and will not solve the problem correctly.
I would just write something in pseudocode that demonstrates how to use a computer to solve an everyday problem. Perhaps determining which store is cheaper to buy a particular grocery list from or some such.
Why not just show the timelapse video A Day in the Life of a Scrum Team?
A programmer writes instructions for the computer to perform.
Running the program results in the computer actually following those instructions.
An example is a cook will follow a recipe in order to bake a loaf of bread. (even if it's in their head)... that's programming. Unlike my wife, the computer follows the recipe exactly every time. My wife, does it in her head and it turns out different but delicious every time ;-)
If you want to go ahead and teach this in more detail then pseudo-code is easy to understand.
e.g.
IF today's date is the 1st of may then
print to screen "Happy Birthday"
ELSE
print to screen "It's not your birthday yet"
The beauty of psuedo code is nearly anyone can understand it and this is the point of it.
Want to show her what programming looks like? Just pop a terminal and
find /
Surprised this is still open, and surprised no one has already given this answer. (I think. I might have accidentally skipped one of the 40 questions that no one is going to read anyway.)
Your answer is in your question
When I was a kid, we once went on vacation in Italy. On the way down,
the pilot let me into the cockpit of the plane. Of course, I didn't
learn how to fly the plane. But I did get a peek into the pilot's
world. I got an idea of how they make the plane go, what the pilot
actually does.
That's really all I want to do.
That's all you have to do. Pick a short exercise out of a tutorial. A moderately longer GUI one could also be beneficial due to the added visuals. (Games might be pushing the length a bit.) And let her watch you code. That's it. It's the same as your pilot example.
Also there are a number of online REPLs that will make watching you code even more immediate.
I say show him bubble sort.
It's an easy, understandable trick, converted to a formal language.
That's what our job is about. Expressing our ideas in a strict, formal language, such that even a machine can understand. A little similar to designing procedures for organizational design.
Code up something quick that reads stock quotes and writes them to an excel spreadsheet. This is easy enough to do with a few minutes and impresses non technical types very quickly as they see the practical value of it.
My usual choice is to retrieve a set of customer records from a database. Using C# and LINQ in Visual Studio, it takes maybe 10 minutes at most to build a web page and dump out the "Northwind" database customers into a grid. The nice thing is that a "list of customers" is something that almost anybody can understand.
Totally depends on the level of her interest (or your level of interest in her). Most people ask that question as idle conversation, and don't really want to know.
Programming is more than algorithms (like "How to make a cup of coffee), it's also fundamentally rooted in mathematics. Most people will be quickly tripped up by the subtle use of mathematical terms (what's a "function"?).
In order to really teach programming, it may help to think back to your own first programming experiences, your first programming teacher, your first programming language. How did you learn? when you were learning, what skills did you already have fresh in your mind (i.e., calculus)? What motivated you to want to understand what a variable is or why there are three different kinds of loops?
Language-wise: Use something like python. Really high level, non-curly-bracket probably better.
Alice which was developed at Carnegie Mellon.
Alice is an innovative 3D programming environment that makes it easy to create an animation for telling a story, playing an interactive game, or a video to share on the web. Alice is a teaching tool for introductory computing. It uses 3D graphics and a drag-and-drop interface to facilitate a more engaging, less frustrating first programming experience.
In pseudo-code:
function dealWithPerson(person){
if(ILike(person)){
getCookie().giveTo(person);
}
else{
person.tell("You shall receive no cookies!");
}
}
dealWithPerson(Person.fromName("Nick"));
dealWithPerson(Person.fromName("John"));
This demonstrates the concept of functions, object-orientation and strings, in a C-like syntax(when I say C-like syntax I refer to the weird characters).
It also shows how code can be reused.
Note that although it is pseudo-code, I wouldn't be surprised if there was some language that accepted this syntax(perhaps JavaScript allows this?).
You could also adapt this example to have loops.
Hope this helps show that person how a program looks like(since it is a realistic syntax and it is relatively easy to understand).
I have been teaching programming for many years and found out that the number of ways you need to explain things is equal to the number of students you have. But one method that works most of the time is as follows:
Present a flow chart that shown the flow of logic of a simple application
Write the instructions in full human language (e.g. English)
Abbreviate each instruction to the short-hand used in the programming language
Choose a less cryptic language like Basic or Pascal for teaching purposes
All code is simply shorthand for natural language. Written in full English most programs seem trivial.
As for a good algorithm, that is another story. It is sad to see many Computer Science courses no longer teach algorithms or brush over it.

Working with a severely limited interpreted language

I'm coding in an embedded language called JS.
I want to be able to call three functions in any order. (ABC, ACB, BAC, BCA, CBA, CAB.)
The trick? The language doesn't have user-defined functions.
It does have a conditional and a looping construct.
I think I have three choices.
Duplicate a whole bunch of code.
Write a preprocessor (that would create all the duplicated code).
Do a loop with three iterations, using an array to control which functionality gets called on each pass of the loop.
I hate #1. Duplicated code is nasty. How do I change anything without screwing up?
I guess #2 is OK. At least I don't have duplicated code in the source. But my output code is what I'll be debugging, and I wonder if I want to diverge from it. On the plus side, I could add a bunch of sugar to the language.
I think my best bet is #3.
Any other ideas? There is no goto. No functions. No existing preprocessor.
Funny thing about #3 is that it's essentially the infamous for/switch nightmare.
Perhaps some kind of mutant state-machine, viz:
int CODEWORD=0x123;
while (CODEWORD)
{
switch(CODEWORD&15)
{
case 1:
/// case 1
break;
case 2:
/// case 2
break;
case 3:
//// case 3
break;
}
CODEWORD=CODEWORD>>4;
}
DRY, no preprocessor, no array. for/switch seems somewhat unavoidable.
You might be able to use the C preprocessor instead of writing your own. That would at least let you try it to see if it's a workable solution.
The technically best solution (assuming that you have access to the code or the developers) is to modify the JS language to do what you really need.
Failing that, the best solution depends on aspects of the problem that you haven't explained:
are the 'functions' recursive?
are there function parameters?
do you need (are you likely to need) other control structures not provided in JS?
does the function call order depend on runtime parameters?
are you skilled and confident enough to design and implement a preprocessor language that meets your current and projected requirements?
is implementing a preprocessor going to save you / coworkers time in the long run?
If the answers to 5. and enough of the others are "yes", then your option #2 is the right answer. Otherwise ... an ugly solution like your #1 or #3 might actually be a better idea.
EDIT: If you don't have source code access and the development team is not responsive to your needs, consider looking for an open-source alternative.

Writing easily modified code

What are some ways in which I can write code that is easily modified?
The one I have learned from experience is that I almost always need to write one to throw away. That way I have developed a sense of the domain knowledge and program structure required before coding the actual application.
The general guidelines are offcourse
High cohesion, low coupling
Dont repeat yourself
Recognize design patterns and implement them
Dont recognize design patterns where they are not existing or necassary
Use a coding standard, stick to it
Comment everyting that should be commented, when in doubt : comment
Use unit tests
Write comments and tests before implementation, that way you know exactly what you want to do
And when it goes wrong : refactor, refactor, refactor. With good tests you can be sure nothing breaks
And oh yeah:
read this : http://www.pragprog.com/the-pragmatic-programmer
Everything (i think) above and more is in it
I think your emphasis on modifiability is more important than readability. It is not hard to make something easy to read, but the real test of how well it is understood comes when someone else (or you) has to modify it in repsonse to changing requirements.
What I try to do is assume that modifications will be necessary, and if it is not really clear how to do them, leave explicit directions in the code for how to do them.
I assume that I may have to do some educating of the reader of the code to get him or her to know how to modify the code properly. This requires energy on my part, and it requires energy on the part of the person reading the code.
So while I admire the idea of literate programming, that can be easily read and understood, sometimes it is more like math, where the only way to do it is for the reader to buckle down, pay close attention, re-read it a few times, and make sure they understand.
Readability helps a lot: If you do something non-obvious, or you are taking a shortcut, comment. Comments are places where you can go back and refactor if you have time later. Use sensible names for everything, makes it easier to understand what is going on.
Continuous revision will let you move from that first draft to a better one without throwing away (too much) work. Any time you rewrite from scratch you may lose lessons learned. As you code, use refactoring tools to eliminate code representing areas of exploration that are no longer needed, and to make obvious things that were obscure. The first one reduces the amount that you need to maintain; the second reduces the effort per square foot. (Sqft makes about as much sense as lines of code, really.)
Modularize appropriately and enforce encapsulation and separation of logic between your modules. You don't want too many dependencies on any one part of the code or that part becomes inherently harder to understand.
Considering using tried and true methods over cutting edge ones. You give up some functionality for predictability.
Finally, if this is code that people will be using before and after modification, you need(ed) to have an appropriate API insulating your code from theirs. Having a strong API lets you change things behind the scenes without needing to alert all your consumers. I think there's a decent article on Coding Horror about this.
Hang Your Code Out to D.R.Y.
I learned this early when assigned the task of changing the appearance of a web-interface. The code was in C, which I hated, and was compiled to a CGI executable. And, worse, it was built on a library that was abandoned—no updates, no support, and too many man-hours put into its use to change it. On top of the framework was a disorderly web of code, consisting of various form and element builders, custom string implementations, and various other arcane things (for a non-C programmer to commit suicide with).
For each change I made there were several, sometimes many, exceptions to the output HTML. Each one of these exceptions required a small change or improvement in the form builder, thanks to the language there's no inheritance and therefore only functions and structs, and instead of putting the hours in the team instead wrote these exceptions frequently.
In my inexperience I was forced to change the output of each exception, rather than consolidate the changes in an improved form builder. But, trawling through 15,000 lines of code for several hours after ineffective changes would induce code-burn, and a fogginess that took a night's sleep to cure.
Always run your code through the DRY-er.
The easiest way to modify a code is NOT to write code. Write pseudo code not just for algo but how your code should be structured if you are unsure.
Designing while writing code never works...for me :-)
Here is my current experience: I'm working (Java) with a kind of database schema that might often change (fields added/removed, data types modified). My strategy is to parse this schema and to generate the code with apache velocity. The BaseClass generated is never modified by the programmer. Else, a MyClass extends BaseClass is created and the logical components of this class (e.g. toString() ! )are implemented using the 'getters' and the 'setters' of the super class.

Resources