News:

SMF for DIYStompboxes.com!

Main Menu

Basic programming hygene

Started by R.G., March 03, 2006, 11:25:31 AM

Previous topic - Next topic

R.G.

Remember back when your mother was telling you not to eat stuff you picked up out of the dirt? Or washing your hands before eating? Or absolutely, no questions allowed bathing at least occasionally? She was trying to teach you basic hygene.

There is a lot of that that's needed for programming as well. It's just not as clearly taught.

The big danger to your programming is - you.

If you are not well-disciplined, it may well never work. So help yourself out - practice good programming hygene. Here are some, but by no means all, pointers.
=========================================================================
1. Have a clear idea of what you're trying to do.
Simple yes? No, not if you look at what many people do. I have a cartoon from the late 60's showing a boss-type guy saying to a room full of people "You guys get started coding while I go down and find out what they want."
Write it down. There is no substitute. If you're making a PWM LFO, write down
QuoteI'm making a PWM LFO. It takes in a speed control parameter from a pot, and poduces a sine wave formed output signal by PWM on an output pin.
Of course, that's not nearly enough. You'll want to select a uC to do that with, then have some idea which pins do what, then how to generate a sine with a PWM, and probably some idea how to do PWM with the uC that you select. Write that down too. How fast will the PWM LFO oscillate? Write that down. Will it also do tap tempo? Write that down. You get the idea.

Never write a line of real code until you have clearly written down what you're going to do, well enough that someone else can understand it.

2. Stop writing down what you're doing as you program only when they pry your cold, dead fingers off the keyboard.
Never stop documenting your work. If you change pins, write that down. If you change out one PWM module for another, write that down. Well written programs are well written in comments much more than they're well written in code. A well written program may have so much accurate, clear commentary that it gets hard to find the code. I like a ratio of about 1.5 comment lines to each line of real code. More than that is uneeded (for my purposes, yours might vary) and less than that indicates that I'm rushing things.

3. Pseudocode is our friend
Once you're absolutely bored to death with writing down what you're going to do, start writing down HOW you're going to do it. Use pseudocode.
Pseudocode is what I think of as language-independent programming. You write down what you are going to program in statements that look like programming, but which are close to human language. I find that structured BASIC kind of syntax is good for this, whatever language it eventually gets tranlated into.

For instance, a PWM LFO might go like this. Notice that there isn't a compiler in the world that would compile this stuff, but that it gets across the formalism of programming.
QuoteInitialize    This section of code will set all the uC registers to the initial conditions, set the internal I/O sections to what they're going to have to be, and initialize all of
                the data memory. In particular, the PWM section is activated, variable PWM% is set to 50%, input speed is set to lowest, and all my loop counters are
                initialized.
Main         This is the entry to the main program. Because I did a good job of setting up initial conditions, I can simply start whatever processing I want, and can loop
                loop right back to here at any time.
GOSUB READ_THE_SPEED_POT - I go the subroutine I have debugged like crazy to be sure that it reads the speed pot; this returns a value of 0 to 255.
IF SPEEDPOT is different from its previous value, THEN update it.
ENDIF       Very important! I have finished processing that IF statement. If I should ever get here by accident, I have program flow problems.
GOSUB READ_THE_TAP_TEMPO_SWITCH - I go to the subroutine that I have previously debugged to death to read the value of the TT switch.
IF  the tap tempo switch ticked, THEN figure out if it's a first tick or a second tick
     IF it's a second tick THEN update the LFO based on the tap tempo
     ; comment - ARGH!!! I gotta figure out how to ignore the speed pot if they did tap tempo!!!!
     ENDIF
ENDIF
(other stuff, other stuff, other stuff)
GOTO MAIN - take a flying jump back to the main label and do the loop all over again. Notice that I should NEVER execute the END instruction after this.
END          This is the end of the program. What follows is the subroutine libraries.
INTERRUPT - this is where they program goes when interrupted, like by the timer to do another on/off on the PWM. Since this particular cheap, small, trivial uC
                has no PWM module, I'm faking it by doing the PWM in software, timed by the timer causing a timer interrupt. ... ooops, I have to go back and initialize
               the timer, and interrupts, don't I...
RETURN FROM INTERRUPT and now we return you to your regularly scheduled program...
=========Subroutines after this==========
SUBROUTINE READ_THE_SPEED_POT - this subroutine reads the speed pot and converts that reading into 0 to 255 in the SPEEDPOT variable... oops, I got to define
                and initialize the SPEEDPOT variable in the Initialize section...
Notice that when you're done writing pseudocode, it is pretty trivial to transcode into whatever language you are writing the actual program in, even one that you have not previously used.
4. All programs look alike.
That is, the format of every program is always the same. Well mostly. They all look like
QuoteINITIALIZE
MAIN LOOP
(body of the program that does the stuff)
GOTO MAINLOOP
END
INTERRUPTS
SUBROUTINES
You have to insert what you are actually doing in the slots, of course.
5. Never write alone
That is, never write code that is not reviewed by someone else if you can possibly help it. No matter how much time it takes to explain it to them, it helps YOU to understand your code better. The other person does not even have to be a programmer, although it is better if they are. This helps YOU to understand what YOU did.
6. Never write just one program
Any program more substantive than a light blinker or "hello world" and especially any program using uC I/O stuff should have the I/O subroutinized until you can prove that it cannot be done that way. It does not do you any good at all to get the clever main loop right if your uC cannot actually read and write the I/O to make it work.

So do the I/O first. Prove beyond a shadow of a doubt that you can read the pots by reading a pot and then blinking an LED at a speed proportionate to the pot setting. Prove you can do A/D by reading the pot with the A/D and use that result as an LED speed setting. Reading a switch? Prove you can read a switch by having the LED pin blink at different rates depending on the switch setting. Using interrupts? Prove that you can take an interrupt by making the external LED blink at different rates depending on the external interrupt pin.

These I/O operations have to work right when you get the final program to work. So get them to work right in trivial programs. Think of it as creating pearls that you'll then string together. By the way - once you have a set of pearls, you can reuse them without re-creating them from scratch the next time. So you'll want your pearls to be clean - that is, well written, producing easy to understand results with as few side effects as you possibly can. It's almost impossible to overstate how valuable this approach is. You haven't lived through programming hell until a side effect from a poorly-thought-out I/O routine has subtle side effects on your main loop.

R.G.

In response to the questions in the forum - PCB Layout for Musical Effects is available from The Book Patch. Search "PCB Layout" and it ought to appear.

H.Manback

I agree with almost all of what has been said. There is just one point I do not completely agree with, and that is the bit about commenting. Now I know there are people who call themselves 1337 programmers who think it is a challenge to write the shortest code possible with as much shorthand gibberish as possible, and they do not believe in comments. This I hate a lot more than over commented code :icon_wink:.
My idea of a well written program is one that is _structured_ in a clear and understandable way, with good names for functions and variables. In an ideal world you would not need comments because you can read the program so well that everything is obvious from reading the code itself. This I have rarely seen, and in most situations I don't think it is even possible. Comments should be just that, comments. Every piece of code that is not understandable for someone else than you (that by the way includes yourself a couple of months later) should have at least a short explanation. What is also incredibly useful is commenting each function, stating what it does (in the case of a data structure or library be _very_ precise).

IMHO, over commenting can make code unreadable almost as much as under commented code. Now I can imagine that code for embedded programs requires more comments than usual due to the bit wizardry that is often used, but still I would try not to over comment.

Also, and this is in no way meant as a discouraging remark or anything, I think it is important especially for programming to learn things right the first time. Having a good foundation in programming and a general understanding of how processors work helps a lot in writing good code. Of course this is easy for me to say, since I am now finishing up my bachelor in computer science and roughly half way through the masters, so things like how a processor works logically and coding assembly is not new for me. Learning everything about computers is absolute overkill, and would probably take you 20 years or more :icon_wink:, but a basic understanding of how a program is executed, how calculations are made, and what registers do what will help a lot, especially in embedded programming. If you really want to get a book or something, I can recommend Structured Computer Organization by Andrew Tanenbaum (I am slightly biased since I am doing my bachelor thesis with him, but it really is a good book).

Thinking some more, another very important and powerful practice is divide and conquer. Every time you are writing a function, and you find yourself putting several distinguishable steps in the same function, break it up. R.G.'s pseudo code tip leads to exactly this if done right. You start out by identifying very general steps, and breaking them up in sub steps. These sub steps translate into functions, and you can start all over again by writing a function's body in pseudo code etc. etc. until you reach a step where a function becomes trivial.

And as a last note, do take this with a pinch of salt because as of yet I have not gotten into microcontrollers and the like. The programming I have done so far has all been for 'normal' computers. In theory programming is programming, and the general rules for good code are the same, but in practice some things work better in one area of programming than in others.

R.G.

I'd agree with you on overcommenting - it's just that I've NEVER seen code over commented. I've seen it poorly commented, or maliciously commented, but never over commented. It is always doggone difficult to figure out what the heck the yo-yo who wrote this was trying to do!
(sorry - I've also had to maintain other people's code for a living, too)

You are deat right - any commenting style that hides the actual programming flow from someone reading it later is, of course, counterproductive, and just get in the way.

I would actually prefer all code to be written a langage that I just invented, where the programming statements are all that you see. However, when you mouse-over or cursor-over the statement, the comments applying to that statement appear in a small scrollup box  on the screen. Someday that will happen.

You have a lot more experience with coding than most of the people who will use this, I think. I was trying to lead the beginner in a humorous way down the path of structuring their programming. I was hiding the more rigid formalisms of good programming in there. I think I got a lot of them. I didn't touch on data structures or other higher level stuff much because I didn't want to scare them off.

Thanks for the commentary. I think that between you and I, perhaps others, we can give a fair framework to beginners.

I did forget to mention that parsimony of typing is a good reward for block structuring: if you ever do anything more than once, you can avoid retyping it if you'll set it up to be callable... 8-)

Did I mention that I did my first programming on card punches? And that my first computer did math by table lookup, having no built in arithmetic ability?

R.G.

In response to the questions in the forum - PCB Layout for Musical Effects is available from The Book Patch. Search "PCB Layout" and it ought to appear.

bioroids

Quote from: H.Manback on March 04, 2006, 06:31:04 PM
I can recommend Structured Computer Organization by Andrew Tanenbaum (I am slightly biased since I am doing my bachelor thesis with him, but it really is a good book).

I studied here with some of his books (translated to spanish). It must be cool to have the guy around to ask questions.

R.G. I think it's good that you focused the posts on broad subjects instead of going straight to specific material. That is good for begginers in programming and uC stuff. Thanks!

Miguel
Eramos tan pobres!

H.Manback

I completely agree on making sure people don't run away scared screaming 'oh the horror!' :icon_wink:, I think you've done a good job in your posts. I gathered from earlier posts that you have a long history in the computer area, whenever I see stuff from like the sixties it's very hard to imagine how people worked back then. But I'm sure that in 20 years time people will make fun of how we used to do it in the 00s :icon_smile:.

It's true you don't see over commented code often, probably never actually, but the reason I mentioned it is that that's what my professor told us when it came to commenting code. Once you have some experience, the danger of over commenting is far far behind you of course :icon_lol:, but in the beginning you still have to find the balance (later on you will probably still try to keep a good balance, because when you're busy coding away a lot of trivial stuff, comments explaining what a function does get lower on your list of priorities).

What I've been thinking about since this new sub forum started, is what is the best way of learning programming, if you are not really in to computer science in the first place. Computer science students get a lot of logic courses, math courses and explanations of how computer systems work. It's hard for me to put my finger on what is most relevant for people who want to do digital embedded stuff, I don't even know what is most relevant for myself when it comes to programming. Learning all of those things is useful, but it's too much for the people who just want to build a stompbox with a microcontroller. I have never looked in to how tutorials on the web are for learning the principles of programming. I suspect it's hard to find a good one.

@bioroids
It's actually pretty weird when you see the people on slashdot responding on a new minix release. It's also pretty unconvenient since articles from his web page that are linked on slashdot tend to slashdot all the web sites of the students and teachers of our department :icon_evil: :icon_wink:

R.G.

QuoteIt's hard for me to put my finger on what is most relevant for people who want to do digital embedded stuff, I don't even know what is most relevant for myself when it comes to programming.
Yes - it is tough to figure out how to put into simple terms the ideas that constitute formal programming.

To me, there are only a few principles. This is a nonexhaustive list off the top of my head.
1. The computer is a very fast idiot. It has no common sense, and does not understand you. To get any useful work out of it, you must tell it what to do in exhaustive (to you, the human) detail, because it will do EXACTLY what you tell it to, step by step, and will never vary. Even if you told it to do something incorrect. It will not interpret, evaluate, or guess what you meant. It has no idea what you meant. All it knows is what you tell it to do.
2. That's just the first communication difficulty. The second communication problem is with yourself. You, being human, forget easily. In particular, you are not good at formal logic, you're terrible at binary logic, and if you ever manage to get the tiny, baby steps written down right to get a computer to do something, you can't hold on to it for long in your head. So you simply must, must, must write down your notes to yourself so you can figure out what you did when you come back to it after things like sleeping. God forbid somebody that's not you ever has to figure out what you did. Comments at least give you and your followers a chance.
3. Computers compartmentalize very well. If you ever get a computer to do a set of baby steps correctly, you can make it remember that forever and do it over and over whenever you like. That's what subroutines and callable routines do. So to attack a problem you the human need to cut it up into a whole series of simple operations - this is the divide and conquer you were talking about, my pearls to string together. Get the computer to do one thing right. Don't clutter it up with a lot of other stuff. Then get it to do a second thing right. After you can get a few things it will reliably do right in the can, you can string those together in any order you like.
4. You have to do the part that the computer can never do - see the big picture of the problem to be solved, and break it down into little problems that you can get the computer to do right. Then you can string it all back together and solve the big problem.  Big problems are overwhelming if you attack them all at once.

Beyond that, I try to ignore languages, computer architectures, and such. I was serious about my first computer. It was an IBM 1620, which did arithmetic by table lookup. It's nickname was "CADET", which stood for "Can't Add, Don't Even Try." Whatever language you learn will become obsolete tomorrow. Whatever architecture you learn will become passe. Learn to ADAPT.
R.G.

In response to the questions in the forum - PCB Layout for Musical Effects is available from The Book Patch. Search "PCB Layout" and it ought to appear.

The Tone God

Quote from: R.G. on March 04, 2006, 09:56:59 PM
Whatever language you learn will become obsolete tomorrow.

I don't belive that for a second. Do you know how many languages I have learned ? Why I...hey wait a minute...:icon_redface:

Andrew

Peter Snowberg

25 years of assembly and it's not obsolete yet. Hehehe.  :icon_wink:

> 1. The computer is a very fast idiot. It has no common sense, and does not understand you.

I try to make that point any time I explain how computers work. Computers are quite stupid, but they can do lots of very simple things very quickly which makes them appear to be complex

> Learn to ADAPT.

This is the mantra of every successful technology person I've ever met. :icon_cool: :icon_cool: :icon_cool:
Eschew paradigm obfuscation

The Tone God

I usually tell lay persons that its not the program in the computer your trying to debug but the program in your head.

"To make a simple thing complex is easy. To make a complex thing seem simple, now thats genius." Einstein

Andrew

R.G.

Quote25 years of assembly and it's not obsolete yet. Hehehe.
Yeah. I speak 1620 assemble, 8080 assembler, CDC6600 assembler, 8051 assembler, 8086 assembler, 6502 assembler, 6800 assembler, 80x86 assembler, 68000 assembler, PIC 12Bit assembler, POWER architecture assembler ...

oh, wait... that's one per processor!
:icon_biggrin:

It all blurs. If one chip doesn't have a 'decrement and jump if not zero', it probably has a 'decrement; test for zero; jump if zero' series available. If it doesn't have a register file, it probably has memory addresses that can be used that way. I was a demon in the first three or four assembly languages I had to use, then I started noticing that I was forever compensating for stuff that wasn't in this one. I finally figured out that the fastest way for me to code was to code in a processor- and language- independent way, then get out the book for whatever hunk of slightly-cleaned-up sand this was and start translating. The better I learned the last processor architecture, the more it impeded my using the next one.

Heh... the thing that worked absolutely the best was to write my processor- and language-independent program, then hand it off to some young fire-breather who was up to his synapses in whatever processor was then current to transcode. The young dragon would transcode it in nanoseconds, catch one or two mistakes I'd made, then I could give him a dinner for two for doing it so fast and his ego popped out of his shirt buttons. Talk about win-win!
R.G.

In response to the questions in the forum - PCB Layout for Musical Effects is available from The Book Patch. Search "PCB Layout" and it ought to appear.