[OT] Application design

T

Tim Cambrant

I'm very sorry if I'm not allowed to post such a question here, but I really
don't know where else to ask such a question, and since my language of
choice is C, I thought I'd post here. You are welcome to ignore this if it's
really not allowed.

One of the things that puzzle me about programming isn't the language
itself, and not the math you have to know, but the simple logic behind it
all. I have really no idea how to create a program larger than the average
test-program you see in books. I just don't know how to pull it all together
to perform a larger task than converting fahrenheit to celsius :) Even the
medium-sized open source programs make me confused.

I've been looking for a usenet-group or a web-forum of some sort where
people discuss the process of building and planning a program, with
flowcharts, algorithms etc. I know there are books on the subject, but since
I'm a poor student, I would have to wait for quite a while to get my hands
on such a book, especially since the library of my town isn't the best.
However, you are welcome to recommend me books as well. Where do I look for
help on application design and development?

Once again, I'm very sorry for cluttering up this great group with an
off-topic question, but I feel that if I get the opportunity to solve my
long-lived problem, I could start giving something back to the language
itself by support etc, and not by asking stupid questions about my puny
test-programs that fail to run :)

Thank you in advance.
 
A

Allin Cottrell

Tim said:
I'm very sorry if I'm not allowed to post such a question here, but I really
don't know where else to ask such a question, and since my language of
choice is C, I thought I'd post here. You are welcome to ignore this if it's
really not allowed.

One of the things that puzzle me about programming isn't the language
itself, and not the math you have to know, but the simple logic behind it
all. I have really no idea how to create a program larger than the average
test-program you see in books...

Try the "The Practice of Programming" by Kernighan and Pike. It's oriented
towards C.

http://cm.bell-labs.com/cm/cs/tpop/
 
R

Richard Heathfield

Tim said:
I'm very sorry if I'm not allowed to post such a question here, but I
really don't know where else to ask such a question, and since my language
of choice is C, I thought I'd post here. You are welcome to ignore this if
it's really not allowed.

Well, presumably we're welcome to ignore it whether it's allowed or not. The
comp.programming newsgroup is probably a better bet, but let's take a quick
stab at this anyway.

Step 1: decide what unsolved problem you are now trying to solve. If you
have no unsolved problems, proceed from step 5.
Step 2: is this problem too big for a computer to understand?
Step 3: if not, tell the computer all about it; otherwise, divide it into
two or more problems.
Step 4: proceed from step 1.
Step 5: time to debug.
One of the things that puzzle me about programming isn't the language
itself, and not the math you have to know, but the simple logic behind it
all. I have really no idea how to create a program larger than the average
test-program you see in books. I just don't know how to pull it all
together to perform a larger task than converting fahrenheit to celsius :)
Even the medium-sized open source programs make me confused.

For now, just take any of your existing programs, preferably one that does
something remotely useful. Think about how you might make it better.

Make it better. (Come back in a couple of hours, when you're finished.)

What problems did you have whilst extending that program to incorporate this
extra functionality? How might you have written the /original/ program in
such a way that it could be extended more easily?

Rewrite this new program accordingly.

Now extend it to do some /other/ useful thing, too. Add another ten features
or so.

At each stage, think about why it's hard (if it's hard) to grow this
program, and how it might be made easier.

Repeat the experiment, using a different base program.

Add twenty features to this one. If you can't think of twenty useful
features, think up some silly ones, but pretend they're useful.
I've been looking for a usenet-group or a web-forum of some sort where
people discuss the process of building and planning a program, with
flowcharts, algorithms etc.

If you want more immediate feedback, try IRC. The guys in Undernet #c are
decent enough sorts, provided you follow the usual conventions.
 
T

Tim Cambrant

Richard Heathfield said:
For now, just take any of your existing programs, preferably one that does
something remotely useful. Think about how you might make it better.

I have one or two of those, yes...
Make it better. (Come back in a couple of hours, when you're finished.)

What problems did you have whilst extending that program to incorporate this
extra functionality? How might you have written the /original/ program in
such a way that it could be extended more easily?

This is a very good point. I find planning with pen and paper to be somewhat
difficult, but it's easier when you have code to improve. I guess I'm the
"write a function, compile, correct errors, add next function"-type of
programmer, for good and bad.

Thank you very much, I'll definately try your method. Infact, i just printed
out your post and put it infront of me, while trying to extend/improve some
K&R-exercises I've done :)
 
R

Richard Heathfield

Tim said:
This is a very good point. I find planning with pen and paper to be
somewhat difficult, but it's easier when you have code to improve. I guess
I'm the "write a function, compile, correct errors, add next
function"-type of programmer, for good and bad.

That can lead to difficulties when it comes to adding new functionality.
Inelegance, at the very least. The point about extending your exercise
programs, rather than "real" programs, is that you should not be afraid to
refactor the whole thing mercilessly, if it leads to a cleaner design. As
you refactor, you will find yourself discovering good design principles
more or less automatically (I hope!). Or at least, you'll discover why your
previous designs were less than perfect. In its own way, that is a step
forward.
 
T

Tim Cambrant

Richard Heathfield said:
That can lead to difficulties when it comes to adding new functionality.
Inelegance, at the very least. The point about extending your exercise
programs, rather than "real" programs, is that you should not be afraid to
refactor the whole thing mercilessly, if it leads to a cleaner design. As
you refactor, you will find yourself discovering good design principles
more or less automatically (I hope!). Or at least, you'll discover why your
previous designs were less than perfect. In its own way, that is a step
forward.

I will think about that. Thank you very much for your advices. I suppose I
should just stick with small programs until i feel 'enlightened' :)

I have a friend who tought himself C++ by reading one or two online
tutorials, and then modifying an open source X Window Manager for *nix. His
version is now superior to the predecessor and he's been working on it
constantly as an open source project for over two years. Still, he has yet
to read a book about programming. Some people just catch the logic easily, i
guess...

However, thank you again for the help.
 
R

Richard Heathfield

Tim said:
I will think about that. Thank you very much for your advices. I suppose I
should just stick with small programs until i feel 'enlightened' :)

On the contrary, start to write bigger programs /now/. Be self-critical, but
in a constructive way. "Boy, adding that feature was hard work! How could I
have made it easier? How could I have designed the original program to make
adding this feature simpler?" Learn the lessons as you encounter them.
I have a friend who tought himself C++ by reading one or two online
tutorials, and then modifying an open source X Window Manager for *nix.
His version is now superior to the predecessor and he's been working on it
constantly as an open source project for over two years. Still, he has yet
to read a book about programming. Some people just catch the logic easily,
i guess...

I doubt whether his code would stand up to rigorous scrutiny. Whilst it is
possible to "grok" a language just by inspection of well-written code, it's
not terribly easy. A combined approach - theory /and/ practice - is better
for the vast majority of people.
 
M

Malcolm

Tim Cambrant said:
One of the things that puzzle me about programming isn't the language
itself, and not the math you have to know, but the simple logic behind it
all. I have really no idea how to create a program larger than the
average test-program you see in books. I just don't know how to pull
it all together to perform a larger task than converting fahrenheit to
celsius :) Even the medium-sized open source programs make me
confused.
I'll give you a C answer (I would have answered differently on
comp.programming).
The first thing to do is to define the core functionality of your program.
With some programs, like text editors, you can keep on adding features as
you feel like it, but core functionality is the ability to load, display,
and modify a text file. Other programs are very closely defined - for
instance a program to play chess doesn't have much room for new features.

As Richard Heathfield said, you then need to determine that the core
function can be done by a computer. It may be that this is almost impossible
(for instance, face recognition) or it may be that it is possible but beyond
your technical skills (for instance, writing a C compiler is very hard, but
obviously not unachievable).

Often there will be a few functions which are at the heart of your program.
Design these functions so they are testable, and then write them. For
instance, a simple chess program will have a function to assess the strength
of a position.

You would write

int pos_strength(BOARD *board, int white)

you can then write and test that function independently.

You can write a quick ugly-looking interface that at least allows you to see
the board and play chess, until you are satisfied that your higher-level
chess function is playing a legal game and is making sensible moves. Of
course you can keep on refining it at any time.

We now have a function

void playmove(BOARD *board, int white, MOVE *mv)

this should be completely portable, and it lets us play a game of chess.

Now we write the interface proper. How to do this depends on your platform,
but using a typical windowing system you will have to associate game data,
including the board, with a window. You will need a dispaly function to draw
chess pieces in the appropriate positions, and you will need to intercept
mouse clicks when the player moves pieces. You will also need to idiot-proof
the program by rejecting illegal moves.
 
T

Tim Cambrant

Malcolm said:
I'll give you a C answer (I would have answered differently on
comp.programming).

That will be fine :)
The first thing to do is to define the core functionality of your program.
With some programs, like text editors, you can keep on adding features as
you feel like it, but core functionality is the ability to load, display,
and modify a text file. Other programs are very closely defined - for
instance a program to play chess doesn't have much room for new features.

I can't really believe why i havn't thought of this before. Creating the
core of the program first and then building on to it, that is. That does
require that the project is big enough to define a core from.
As Richard Heathfield said, you then need to determine that the core
function can be done by a computer. It may be that this is almost impossible
(for instance, face recognition) or it may be that it is possible but beyond
your technical skills (for instance, writing a C compiler is very hard, but
obviously not unachievable).

That's fine, I don't reach for the sky (at least not yet). :)

Thanks a lot for the help. I'm sure I'll get helped from the
"core-thinking". It all sounds very reasonable.
 
M

Matt Gregory

Tim said:
One of the things that puzzle me about programming isn't the language
itself, and not the math you have to know, but the simple logic behind it
all. I have really no idea how to create a program larger than the average
test-program you see in books. I just don't know how to pull it all together
to perform a larger task than converting fahrenheit to celsius :) Even the
medium-sized open source programs make me confused.

I think you want to learn how to identify the different functionings of a
program that can be written independently of each other. You want to
strive to create your programs as a bunch of black boxes that allow you to
forget about the internals of the functions and only give you the interfaces
(typically function prototypes) to worry about. Then, theoretically, you
can just glue the boxes together and not worry about it. This can be done
with both code and data. For example, take the ctype.h header. On my
machine the isalpha(), isdigit(), etc. functions are implemented as macros
that perform indexing into a lookup table. If you just had the table it
would be a pain in the ass to figure out if a character is alphanumeric or
whatever. You would have to go "if (_pcchar[c] & _ALNUM)" or something
completely strange. Luckily, ctype.h provides a handy interface so you can
just say "if (isalnum(c))" and you don't have to worry about remembering
cryptic names. When programming in C, you want to get into sort of a
library writing mentality, since most C programming is about building up
the language to match the problem you are working on, otherwise your
program logic will be drowning in statements mostly devoted to bookkeeping
and low level grunge like string handling and error checking.

There's a poster around here by the name of Phlip, and he always talks
about the value of unit testing, which is a methodology where you take a
part of your program and write a separate program that tests that one part
extensively. The benefit of writing a separate program is that it's easier
to create different scenarios that bombard the unit without having a bunch
of extraneous code in the way. Say you were implementing some functions
like those in ctype.h and you just got done writing an isalnum() function.
You could write a unit test that cycles through all the characters in
whatever character set you are using (e.g. ASCII) and prints the results
of all their isalnum()'s to a file. You then look over the output and say,
"ok, that looks good" and recompile your main program and continue with
something else. Maybe later you decide, "oh, this program is real dog...
this profile says isalnum() is taking up 95% of the execution time! I
better do something to speed that up!" So you reimplement it with a faster
algorithm. Now you can just recompile and run your unit test and just use
diff or something to compare the new output with the old output and if it
matches you don't need to worry about it. If it doesn't match, you'll have
a pretty good idea where the bug is. I've just started doing this recently,
but I've found that it really does save a lot of time. It makes debugging
far more interactive and gives you more confidence in your code. But the
reason I went off on this tangent in the first place is that I think it
also helps you to make your code more modular by having to isolate it enough
from the rest of your program to make a unit test for it.

Matt Gregory
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top