14
$\begingroup$

As someone who likes to advocate for best practices like correct use of VCS, indentation, sufficient commenting, and testing, I try and integrate them when I teach. But for all of these things, my students always ask me why they need to do it for projects of the relatively small size and short duration they're working on. They're right that it isn't necessary, but I don't know how else to teach it and get them to practice it.

What ways do you find effective to introduce programming best practices? How do you ensure that your students continue to use them?

$\endgroup$
6
  • $\begingroup$ This question is specifically about coding style? $\endgroup$
    – Ben I.
    Commented Jun 4, 2017 at 14:46
  • $\begingroup$ No one needs to follow your best practices. They just greatly reduce the risk of certain kind of failure. $\endgroup$
    – hotpaw2
    Commented Jun 4, 2017 at 16:41
  • $\begingroup$ Well, in many ways writing clean code is needed to work effectively in a group. In a professional environment, you want to have clean code because if nobody can read your code you're almost useless. $\endgroup$
    – thesecretmaster
    Commented Jun 4, 2017 at 16:44
  • $\begingroup$ In many professional environments, there may be automated style checks, and there will certainly be review (which may demand a consistent use of mostly arbitrary style). $\endgroup$ Commented Jun 5, 2017 at 15:49
  • $\begingroup$ It is school: it is all practice. So we start on smaller problems. But also you need to convince them of the value. For instance you would have a hard time convincing me of the value of most comments. $\endgroup$ Commented Jun 5, 2017 at 16:06

11 Answers 11

10
$\begingroup$

I've faced resistance too. Here are some ideas:

  • Students would not turn in an assignment to an English teacher that was not properly punctuated and proofread, even if that teacher will be the only reader. They should not turn in an assignment to a CS teacher that is not properly formatted, documented, and tested.
  • Companies want to hire programmers capable of writing scalable programs. I can write a much stronger letter of recommendation for students who do well at this. (Adapt to college letters of recommendation for high school students.)
  • Rhetorically ask why people try their best when practicing CPR on a dummy.
  • When I interviewed job candidates for Google, I asked questions about testing. It would be hard for candidates to answer well without having practiced writing tests.
  • Give prizes for and share examples of student code that follows best practices. (Get a student's permission before sharing their code.)
  • Show them disastrous bugs that came from not following best practices, such as this one.
$\endgroup$
1
  • 4
    $\begingroup$ Similar to your link, but on a much larger scale, is the goto fail; bug, which potentially left millions of users with an insecure SSL library that could be attacked. All because of some sloppy programming and some missing braces! $\endgroup$
    – Aurora0001
    Commented Jun 5, 2017 at 15:54
6
$\begingroup$

Best Practices serves two purposes, allowing future maintainers (which easily could be themselves) to understand what the code is supposed to do, and helping the them avoid errors, and find errors while writing the code. Not all parts of best practices serve both purposes.

I think the avenue to take is focus on reduction of errors first. That targets their self-interest in that it makes their work easier, and maybe their grades better. (Broken code won't earn as many points as working code.) To demonstrate the "finding errors" create some sample programs written without best practices, and some with best practices. In both sets make similar errors - logic, syntax, etc. - in different places. It's especially helpful if the compiler/interpreter gives errors that include line numbers that can be misleading, such as when the error is a missing close brace, and the error gives the last line of the function, the point where it becomes obvious that it won't be found. Finding the error in one should be easier than in the other.

In class the added benefit of being readable is that you can spot the errors more easily, and probably understand what they were trying to do, and help them understand the missed concepts better. A benefit to them in the here and now of the class, not some possible future work environment.

Later, you can change focus to the usefulness of best practices for maintaining code. Again, using sample code in both good and bad style, have code that needs to be modified. You can change the conditions of some logic, add some functionality to existing routines, and need to add a new function that utilizes an existing function that is, in one case, well documented, and in the other, not even self-documented.

If this is their second year/semester/term, then you also use the review of their own code from the past, as suggested by @Sean in his answer. If it's a project they've done for you, or another class you have input from, then you can plan to have them make controlled modifications to it as suggested above.

Lastly, find samples of code that do follow best practices, but are also styled with enough difference that you can show that best practices is not a rigid fill-in-the-blank template, but a set of guidelines that make things easier. Within those guidelines there is still plenty of room for them to develop their own unique style, and to shine in their own way.

The take away should be that best practices and clean code are a tools for making their programming easier, but is not a cage that makes everything look the same and removes individuality.

$\endgroup$
5
$\begingroup$

You can introduce the idea of best practices. Show them examples of right vs wrong for each of the practices you want to teach them:

public void method(){
System.out.println("this is incorrect indentation");
String example="It makes the code difficult to read.\n";
example+="If you can't read the code, you'll see how difficult it is to work on it";
int x=5;
if("this is completely bad: 5".contains((""+x)))
System.out.println("because there's no indentation.");
}

and then show the best practice code:

public void betterMethod(){
    System.out.println("this is the correct way to do indentation");
    String example="It makes the code very easy to read.\n";
    example+="If you can read the code, you'll see how easy it is to work on it";
    int x=5;
    if("this is the best practice: 5".contains((": "+x)))
        System.out.println("because the indentation is good");
}

And this idea works for other best practices: show the bad and emphasize just how bad it is (you might want to exaggerate the "badness" of the worst-practice code).

Then, show them the correct way to do it. It's better if both examples give the same output. that way students see how much easier it becomes when applying best practices:

An example for comments and meaningful naming:

the bad example:

int[] b = {1,3,4,6,7,9,11,2,5,8};
int a = 0;
Arrays.sort(b);
double s=0;
for(int i=0;i<b.length;i++) {
    System.out.print(b[i]+",");
    s+=b[i];
    if(a<b[i] && i<=b.length/2) {
        a=b[i];
    }
}
System.out.println();
System.out.println(a);
System.out.println(s/b.length);

the better way:

//create array of numbers
int[] numberArray = {1,3,4,6,7,9,11,2,5,8};

//create variable for median
int median = 0;

//sort array
Arrays.sort(numberArray);

//create variable for average
double average=0;

//iterate over array
for(int i=0;i<numberArray.length;i++) {
    //print sorted array, each number in a different iteration of the loop.
    System.out.print(numberArray[i]+",");
    //sum numbers in array, one by one.
    average+=numberArray[i];
    //if the current value of the median variable is smaller than the current 
    //value in the array, and the loop hasn't passed the middle yet, set the median variable
    //to be the current value in the array 
    if(median<numberArray[i] && i<=numberArray.length/2) {
        median=numberArray[i];
    }
}

System.out.println();
//print results
System.out.println(median);
//calculate and print calculation
System.out.println(average/numberArray.length);

Before showing the correct way, ask if anyone can see what this program does. It would be difficult for most. Then show the best-practice version, and they'll see just how better it is.

$\endgroup$
4
  • $\begingroup$ This answers the part of my question about indentation, but it doesn't really address testing or commenting which, in my experience, are harder to teach. $\endgroup$
    – thesecretmaster
    Commented Jun 4, 2017 at 10:59
  • $\begingroup$ Good point, I'll add more about that. $\endgroup$
    – ItamarG3
    Commented Jun 4, 2017 at 10:59
  • $\begingroup$ @thesecretmaster did you see the edit? $\endgroup$
    – ItamarG3
    Commented Jun 4, 2017 at 12:17
  • $\begingroup$ this is pretty much what I do to. I have a bunch of repositories of the many many projects I have worked, and then I show them how 'clean' and hence appealing it looks (similar to how you have compared above). Some students seem to like it, while others ignore. I cannot do anything about those who ignored, but those who liked the 'clean' look, I find they end up adopting the best practices. $\endgroup$
    – Jay
    Commented Aug 21, 2017 at 4:14
5
$\begingroup$

Maybe the easiest way to practice is to have an element of peer review. I find it's much easier as a reviewer to insist on good practice and make 'helpful' suggestions than to follow these rules myself. You might need to be careful to balance the level of reviewer and reviewee though.

Justifying the time spent is probably harder. Some of these might work:

  • If you plan ahead, you can have students look back at some of their code from 6 months previous - but that isn't necessarily an introduction to the art.

  • Mention that people will use some of these decorations as a proxy for code quality. This will benefit them both when you're marking their code, when it comes to making contributions to a group project (or trying to get their idea across) and when they're working.

  • Explain that even if the code isn't functionally perfect, code that has been written nicely tends to be much easier to debug and improve than something that is badly presented.

Demonstrating the practical value I think is not really possible at an introductory level because you won't have the example to try and debug, etc. More, this could be something to re-enforce every so often by 'presenting' the wrong example code 'by mistake' - maybe for rewards if that's appropriate.

I think you can also show any audience that a well presented piece of work (in any subject) is likely to be better received than something handed in on a bit of scrap paper that looks like the dog slept on it. Making the comparison between something written, and some code is probably important. They won't have the opportunity to hand in some code which is scribbled in pencil, and may not appreciate that untidy code actually looks this bad to an experienced eye. The extreme of this is in a professional environment, where your code will be judged not ready for review unless it passes an automated lint and style check (far more strict than compiles with no warnings)

$\endgroup$
1
  • 1
    $\begingroup$ I like to show the same program - say a simple game like BlackJack or HangMan - done really really poorly and done "right". They both compile and run the same, one is pleasing to look at, easy to understand and modify/update, etc and the other is done all wrong with poor variable names, insane inconsistent spacing, lack of hard returns, lack of comments, badly named source files, etc. $\endgroup$
    – ivanivan
    Commented Jun 24, 2017 at 0:51
3
$\begingroup$

Good coding style and practices are part of the student's grade. I post a style guidelines document ( naming conventions, indentation, etc) and dedicate 10 points of their programming projects to following those guidelines. In addition, I dedicate 10 points to "elegance" -- writing efficient code and communicating well with the user. Similarly, a student doesn't get credit for a lab until the code is clean, as well as correct. This establishes good habits from the beginning.

$\endgroup$
2
$\begingroup$

Here is an amusing exercise. Have your students build an API for extended precision rational arithmetic, BigFraction.java. Ask them to javadoc it and to have all of the basic goodies (toString, equals, add, subtract, multiply, divide, pow, etc).

Now take these APIs and assign as second project: Solve some problems with BigFraction (compute harmonic numbers, bernoulli numbers, etc) using another student's .class file (no they can't see the code) and their javadoc. This often has entertaining results and it cements the idea that documenting programs enhances their usefulness.

$\endgroup$
2
  • $\begingroup$ I do an assignment almost exactly like this (and it's a doozy). The only difference is that... this is a better basis for the assignment. Please excuse me while I go convert a lab to rational numbers... $\endgroup$
    – Ben I.
    Commented Jun 22, 2017 at 18:41
  • $\begingroup$ Use BigIntegers for your state variables. $\endgroup$ Commented Jun 22, 2017 at 19:02
2
$\begingroup$

The best way to learn is by doing.

I have heard of teachers developing a bit of code as a class to the point where something is working properly for everyone, then deliberately breaking something and running a light obfuscation tool on it. Then the students are tasked with reading through code without comments and with meaningless variable names, trying to fix it.

Another alternative is to show two short code snippets in class, one with descriptive names and one with non-descriptive names and ask the class to determine the output of each, one after the other. Time how long it takes for at least half the class to find an answer and then (in most cases) they will see it takes much longer when you have to decipher non-standard code. I remember learning pointers in C in this way.

$\endgroup$
1
$\begingroup$

One of the first principle to realize is that the students are not only learning from what you teach, they are also learning from what you do. They won't buy into a practice that you aren't following yourself. Would you purchase a Lincoln Towncar from a salesman that drives a Honda CRV to work every day? Your students are watching you, and they are evaluating you. Use that to enhance the lessons, not diminish them.

Every time you produce "throw-away" code in demonstrations, problems, or handouts, make sure that you have followed whatever "best practices" you are trying to get them to follow. Then, don't make them create "throw-away" code. It might be the next lesson, it might not be for two weeks farther into the term, but as much as possible have the code created in one lesson be applied or modified in a later lesson. Emphasize your set of best practices early on, and help them understand them with code reviews on the earliest assignments that focus on those practices. For later assignments, place less emphasis on the review of best practices, and more on the code itself.

Not knowing the language, and course objectives, I can't layout a definitive plan for the scaffolding. I'm sure that if you work backwards from the larger projects, you can design smaller projects that cover the earlier material that can end up in the finished version of the large one(s). If the students have enough time, and new material, between writing, and then reusing a program, they will see the benefits of best practices. Either from the hard work of rediscovering what the old ones do, or being able to easily see what they do from reading them if they did use best practices earlier. Of course, if they get to see other students' work, or have to figure out what other code does without best practices, that helps. Having to reuse their own code (when they think I'll always know what this does) will drive the point home in a firm, and memorable way.

Summary

  • Practice best practices
  • Code reviews that explain best practices
  • Avoid "throw-away" code in examples and projects where possible
  • Scaffold projects to include earlier work
  • Have "memory loss" time between reuse of some code
$\endgroup$
1
$\begingroup$

Coding style has to be part of the grade

For this to work, students need to know that they have written bad code or are not following industry standard guidelines. You should introduce them to lint tools so they can make it part of their workflow earlier in the learning process.

Here are some of the lint tools that we use:

The easier you make it for students to know where they have gone wrong, the more likely it is that they'll improve their code. I suggest automating this in some way to make it part of their submission.

$\endgroup$
0
$\begingroup$

Best practices are sometimes best taught in conjunction with or after one teaches a problem or solution area where lack of best practices can cause bad things to happen. Show them, or better yet let them experience, the bad things that can happen first, after violating a certain practice. Make them value the practice. Otherwise you might be creating blind followers of unsupported dogma or the latest methodology fads.

In engineering labs, we often broke things (with a loud bang) in conjunction with the learning theory on how to design things that didn't fall down.

$\endgroup$
0
$\begingroup$

I would explain to them that while the projects now are short term and never updated/maintained, if they go into it further they will REALLY appreciate their prior work to comment and indent properly. The way I would try to show this is by making them go back later in the year/semester and make them do revisions to old projects. My teacher did this and it caused me to not only comment my code, but archive very well because review 1 can also be 4,5,7, and 8.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.