|
~ Introduction to Programming: C ~ Session 20 - Pseudocode & Test Plans |
In This Session...
In this session we will be covering the following topics:-
In the last session, we covered:-
In this session we will be taking a look at pseudo-code - a way of drafting out our programs without having to worry about the exact syntax (words and structure) that we would use in C to make the program work. Most people love using pseudo-code - it doesn't actually do anything, but it's a good way of getting what you want to do in a form that is a bit more methodical, but without being tetchy about how it looks!
We will also look at the test plan, and how we can take our specification how how a program should work, and design a plan that should tell us whether our program is working correctly - i.e. to specification - so that we can prove that our program works properly. As you may imagine, this counts for a lot in the written exam.
Rather than wade through a load of dry theory on this one, we can get creative, which is a huge relief for most people after the complexities of the last few sessions (pointers and parameter passing - phew!)
So let's get cracking. What program are we going to write today?
Exercise 63: Specification for a "Pairs" game
Let's do a game - a somewhat simple game, but something we can play.
The card game we know as "pairs" involves the following steps:-
Okay, so how should we simulate this with a computer program?
We need to define the scope of our program, which means we may come up with a good plan for how to implement the game, but restraints of time may means that we trim down our specs to something that is playable, but with few bells-and-whistles. I would recommend trimming things down to a minimum (but don't skimp on validation / good structure / proper use of variables etc.) in your feature list to make the program usable but not "clever" - this should give you time to complete the program in the time you are given to do the exam (6 hours).
We will discuss between us a list of features during the session, pare this down to the minimum, and use this as a template for designing a program.
Another way of working out how you are going to write a program, either instead of, or in conjunction with JSP, is to using something called pseudocode. Most people like writing pseudocode, mostly because it doesn't actually have to execute correctly, and is by its very nature a rough draft.
Pseudocode does not have any strict rules about how to write it. Generally, it is a rough English-style version of a computer program. It tends to include words in common with most programming languages - such as if and loop and while and else (or maybe otherwise) etc. and logic tends to be in generalised form rather than exact logical rules. Here's a bit of pseudocode for our card game. If we have extra features, we may wish to add to it
Of course, if you type this into your C compiler, then it won't work, because it isn't C. The trick is to turn it into C instructions. Having broken it down, we can do this a lot easier now. Generally, you need to go through the following steps to work out how to structure your program:-
We need to work out a plan as to how we would expect the program to behave if we put in specific input values. The idea is to test combinations of input values that are most likely to "break" our program. We are playing devil's advocate. Testing is often seen as a bit boring, but can be quite fun if you have any destructive tendencies, or of an ornery nature.
When constructing our test plan, we have to think about a number of things to come out with our list of things to test. It is often useful to go through our JSP diagram, and pick a level at which we think we would can effectively test without missing anything important, or go through our pseudocode and pick out chunks of code an call them an 'action' which needs to be tested, because it does a specific task. Typically, this will be a single function if you have structured your program well.
If you find that your test plan is mainly testing specific functions, then top marks to you from the examiner - this will impress!
Here is an example partial Test Plan:-
| Function name | Test Description | Test Methodology | Input Value(s) | Expected Output(s) | Actual Output(s) | OK? |
| setup_cards() | Test to make sure all card values populated | Put in breakpoint at end of function, and inspect contents of card array | Program-created | 1..51 to represent each card | Same in the same order. | Yes |
| shuffle_cards() | Test before and after swap that the two cards have swapped properly | Put breakpoint after card numbers have been input. Check variables. Put breakpoint after they are swapped. Check variables again and make sure they have swapped values | Card1: 5 Card2: 20 |
Card1: 20 Card2: 5 |
As expected | Yes |
| get_card() | Should return suite and number depending in number passed as parameter | Test A,2,10,J,Q,K of each suite using a test function test_card() called from main() instead of main_loop() | 0,1,9,10,11,12 for Hearts 13,14,22,23,24,25 for Diamonds 26,27,35,36,36,38 for Spades 39,40,48,49,50,51 for Clubs |
0: AH, 1: 2H, 9:10H, 10:JH, 11: QH, 12:KH
13: AD, 14: 2D, 22:10D, 23:JD, 24: QD, 25:KD 26: AS, 27: 2S, 35:10S, 36:JS, 37: QS, 38:KS 49: AC, 40: 2C, 41:10C, 42:JC, 43: QC, 44:KC |
0: AH (OK), 1: 2H (OK), 9:10H (OK),
10:JH (OK), 11: QH (OK), 12:KH (OK)
13: AD (OK), 14: 2D (OK), 22:10D (OK), 23:JD (OK), 24: QD (OK), 25:KD (OK) 26: AS (OK), 27: 2S (OK), 35:10S (OK), 36:JS (OK), 37: QS (OK), 38:KS (OK) 39: AC (OK), 40: 2C (OK), 41:10C (OK), 42:JC (OK), 43: QC (OK), 44:KC (OK) |
Ok |
If you're wondering about the last test, here's the code for it:-
#include <stdio.h>
#include <conio.h>
#include <string.h>
void test_card();
void get_card( int card_no, char *res);
main()
{
test_card();
getch();
}
void test_card()
{
int i;
char str[4];
printf("Card No: "); scanf( "%d", &i );
get_card(i,str);
printf("Card for %d is %s", i, str);
}
void get_card( int card_no, char *res)
{
/* 13 cards per suite */
switch (card_no % 13)
{
case(0): strcpy(res,"A"); break;
case(1): strcpy(res,"2"); break;
case(2): strcpy(res,"3"); break;
case(3): strcpy(res,"4"); break;
case(4): strcpy(res,"5"); break;
case(5): strcpy(res,"6"); break;
case(6): strcpy(res,"7"); break;
case(7): strcpy(res,"8"); break;
case(8): strcpy(res,"9"); break;
case(9): strcpy(res,"10"); break;
case(10): strcpy(res,"J"); break;
case(11): strcpy(res,"Q"); break;
case(12): strcpy(res,"K");
}
/* 4 suites */
switch (card_no / 13)
{
case(0): strcat(res,"H"); break;
case(1): strcat(res,"D"); break;
case(2): strcat(res,"S"); break;
case(3): strcat(res,"C"); break;
}
}
If you put the test values in, you may get a better idea of how this works. The string is made up of two things - the value and the suite.
If the cards run from 0 to 12 for the first suite (hearts), you can see how the first case works. However, the diamonds suite then runs from 13 to 24 (13 being Ace of Diamonds, 14, 2 of Diamonds etc.) How do be reset the value back to 0 when we hit 13? Remember our modulus (%) operator? This divides one number by another, and returns the remainder. So if we divide by 13 and get the remainder, then 1/13 give us 0 remainder 1, 12/13 gives us 0 remaidner 12, 13/13 gives us 1 remainder 0, 14/13 gives us 0 remainder 1 etc. etc. So this does the job we want - find the remainder, and this automatically resets the number back to 0 every 13 numbers in the series!
So how do we find the suite? Well, if we divide the suite number by 13, then every 13 cards, the integer value will increase by 1. As a switch statement can only take integer (or character) values, this gets converted automatically for us. So 0/13 gives 0, 12/13 gives 0 remainder 12 (i.e. 0 is the result here) but 13/13 gives 1 remainder 0 (i.e. 1 is the result here) - so this is the beginning of the diamonds suite. Great! For further clarification, here's a list of all the values in a table:-
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| AH | 2H | 3H | 4H | 5H | 6H | 7H | 8H | 9H | 10H | JH | QH | KH |
| 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| AD | 2D | 3D | 4D | 5D | 6D | 7D | 8D | 9D | 10D | JD | QD | KD |
| 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
| AS | 2S | 3S | 4S | 5S | 6S | 7S | 8S | 9S | 10S | JS | QS | KS |
| 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 |
| AC | 2C | 3C | 4C | 5C | 6C | 7C | 8C | 9C | 10C | JC | QC | KC |
A Microsoft-Word based test plan template is available from the contents page. You can use this and fill it in when you do your exam. Make sure you save it to your floppy disk so the examiner can see it too!
Code Stubs
Here's a sample set of code stubs for our pairs program:-
/* Define Prototypes */
void get_cards_out();
void play_again_loop();
void shuffle();
void game_loop();
void show_all_cards();
void turn_over_cards();
void compare_cards();
main()
{
get_cards_out();
play_again_loop();
}
void get_cards_out()
{
}
void play_again_loop()
{
shuffle();
game_loop();
}
void shuffle()
{
}
void game_loop()
{
show_all_cards();
turn_over_cards();
compare_cards();
}
void show_all_cards()
{
}
void turn_over_cards()
{
}
void compare_cards()
{
}
This is taken from our JSP diagram. Now all that remains is to fill in the gaps!
In the next session we will be covering the following topics:-
Implementing what we did today as a C program.
![]()
(c) Copyright
2003-4 Simon Huggins. All Rights Reserved.
If you have any issues or questions regarding the content of this web
site, please contact the
author by clicking here.
Alternatively, you can leave a voice message on 00 44 (0)7050-618-297 or fax
on 00 44 (0)7050-618-298
This Page was last updated: 29 January 2004 13:07