Computer Science

Previous ] Home ] Up ] Next ]


Effective Strategies for Taking the
Advanced Placement Computer Science Test
Lionel E. Deimel
Allegheny College
Meadville, Pennsylvania 16335

Although I was not involved in creating the Advanced Placement Computer Science test—I did eventually contribute test questions to Educational Testing Service for the test—I was a grader of the test for the first few years. This was a very gratifying enterprise, but the actual grading made one feel like a bureaucrat in a very large bureaucracy. The experience gave me insight into how one could maximize one’s score, however. I wrote this article in 1986 for a newsletter for computing teachers (citation).

The free-response portion of the Advanced Placement test in Computer Science (APCS test) is difficult, particularly in light of the time allowed for its completion. Doubtless even experienced programmers might find it hard to achieve full or nearly full credit. Scores can be improved, however, by applying good test-taking strategy, by employing specific techniques applicable to programming generally, and by using common sense.

I offer below some practical test-taking advice to students planning to sit for the APCS test, given from the point of veiw of a Reader of that examination. Application of these suggestions will not compensate for poor preparation, of course, but it should help students improve their scores by helping them show more clearly what they know and what they can do. Much of my advice can be applied to any of the free-response questions, though some of it is specific to problems requiring Pascal code. In fact, many of these ideas can be applied by any student taking a test on which code is called for. I conclude with some related suggestions for teachers of the APCS course.

Advice to Students: How to Score As High As Possible

My first piece of advice is a standard test-taking suggestion—read all the problems before answering any of them. This advice is practical for the free-response section of the APCS test, as there are only a handful of problems. Although questions are sometimes easier or more difficult than they first appear, a quick appraisal of the entire test usually will allow you to make a reasonable estimate of how much time and effort you should devote to each item. Since all questions on the test are weighted equally, it makes sense to answer the easier ones first. Having an overview of the examination will help you avoid spending too much time on any problem, thereby leaving too little time for the remaining ones. Checking over the entire test booklet also provides insurance against difficulties resulting from very rare (but not unknown) printing errors. Identifying duplicate or missing pages immediately can save valuable time. When you eventually read a question in order to answer it, you will be giving that problem a second reading, and you should be better prepared to provide a correct response than if you had read it but once.

Allocation of your time among the problems should be influenced not only by your appraisal of your own capabilities and problem difficulties, but also by your knowledge of the test as a whole. The examination is designed to measure a broad range of knowledge and skill, as outlined in the booklet “AP Course Description in Computer Science.” Individual questions have specific primary objectives, however, and can be expected to be scored with different emphases. For a question requiring the writing of a brief, straightforward program, you can reasonably expect that errors of syntax, documentation, formatting, or modular design will be heavily penalized. Such mechanics will likely be given only minor scoring emphasis on a problem requiring you to generate and implement a complex algorithm. Keep these matters in perspective. Avoid doing a slapdash job on an easy problem or spending excessive time converting a good response to a difficult problem into a splendid one.

It is sometimes helpful to ask what the test writers seem to be looking for. Although you have a right to expect that questions be reasonably explicit, many questions in the past have stopped short of saying “write it this way,” yet have strongly implied that some particular technique (such as writing a likely-to-be-changed calculation as a function) is to be used. You are well-advised to take obvious hints and not seek perverse rationale for alternative approaches. In particular, an argument can almost always be made for not using procedures or functions in the short fragments of code required on the APCS test. Since you will not be around to state your case when your answer is being scored, however, modularize your code if the question at all suggests that you should.

When answering questions on the APCS examination, students sometimes err on the side of writing too much. Do not write code to perform unnecessary operations. If you are asked to find the largest value stored in an array, for example, do not first read values into the array from an input file. To do so is not only to waste time, but to sacrifice the correctness of your answer. If the array is already filled with the values to be processed, to read in a new set of values before finding the maximum is to solve the wrong problem!

Avoid the temptation to show off, by using recursion to do something easily done iteratively, for example. If the test designers want you to do something fancy, their intention will be made clear. The most obvious danger of trying to be clever is that you might make errors. Even if you avoid this peril, you run the risk that an offbeat solution may be scored incorrectly. (Yes, Readers are human and can misinterpret your answers. The scoring process is designed to minimize this, but mistakes can be made, especially if the code is obscure or poorly commented.) Finally, you may be subjected to point deductions for inefficiency, inappropriateness, or lack of clarity. This is not to say that displays of cleverness on the examination are punished. For many good reasons, however, disciplined programmers attempt to produce straightforward code whenever possible, resorting to non-obvious devices or advanced techniques only when they are clearly needed, often only after more conventional approaches have failed to satisfy fully the program requirements.

Although you should not go out of your way to display everything you know, neither should you be reluctant to demonstrate knowledge which is clearly relevant. Certain components of your answer are usually assigned a fixed number of points. One point might be allocated to the procedure statement, for example. This means that if you can write an acceptable procedure statement, even if you have no idea what code should go inside the procedure, you can increase your raw score by doing so. Similar advice applies to declarations. Recognition that certain variables of particular types are required to solve the problem at hand is a significant indicator of programming competence. Declare needed variables, even if you do not show or show correctly how they are to be used. Also, if you know what a segment of code needs to do but cannot seem to write it, communicate your understanding by means of a comment or invoke an incomplete procedure to perform the required operation. In so doing, you illustrate your grasp of the algorithm as a whole, even though you are unable to supply the implementation details. Remember that a blank response represents a certain zero score for the question. You should not waste a Reader’s time with nonsense, but meaningful statements relevant to the solution can rightfully earn some credit.

After answering each problem, there are several checks you should make. First, be sure the Reader can find your answer. Mark out any irrelevant scratch work or false starts, since if you appear to have given two answers, the first will be scored and the second ignored, even if the second is “clearly” your intended response. Be sure you indicate where your answer is located if it is not on the page where it is expected. The scoring process probably catches all misplaced responses, but why take any chances? If you use extra pages for your answers, be sure each carries a preprinted test number label and is stapled into the test booklet when the booklet is turned in. Where Pascal code is called for, do a quick check of mechanics—are begin’s matched with end’s, semicolons properly placed, prompts written where terminal input is required, comments included to provide documentation, all variables declared, parameters declared var where appropriate, and so forth. Next, be sure you have fulfilled all requirements of the problem. For example, if a procedure is called for, is your answer actually in the form of a procedure? If a question has several parts, have all of them been answered? Be especially careful to check for unstated but implied requirements. For example, will your linked-list procedure work on an empty list as well as a nonempty one?

Given that your answer addresses all requirements of the question, is it correct? Answers on the test often show little evidence that the writer examined the code after writing it. A quick rereading can uncover mistakes and inconsistencies, such as loops with incorrect or missing initialization and off-by-one errors. If time permits, code should be traced with representative and perhaps even extreme test data. Question 2 from the 1985 test can be used to illustrate the kind of error which is often missed, but which can be caught through tracing:

2. A circularly linked list contains nodes defined by:

        Ptr = ^Node;
        Node = record
Datum : integer;
                       Link : Ptr

Suppose p is of type Ptr and points to a node in a circularly linked list with an unknown but even number of nodes. You are to write a procedure that will break the list into two disjoint circularly linked lists each containing exactly half the nodes from the original list. Pointer p should point to a node in one list, and a new pointer q should point to a node in the other. The choice of which nodes to include in which list is up to you. Your procedure should begin with a few comments to describe how it works.

The code below for manipulating the lists almost works. (We ignore the possibility that p points to a null list.)

    pstart := p;
    q := p^.link;
        p^.link := q^.link;
        p := p^.link;
        q^.link := p^.link;
        q := q^.link
    until p=pstart

The student who wrote this probably did draw some pictures and trace the code, but did not trace it far enough. The problem is that on the last time through the loop, the assignment to q^.link is incorrect because p no longer points to the second node of the list. This error is easily found, but only if the code is traced from beginning to end. To appreciate the mistake, try doing so yourself for a 2- or 4-node list.

Correcting this problem requires that pointers be maintained to the starting modes of both lists. The loop needs to terminate one iteration earlier than in the original solution, after which the ends of the lists can be properly connected:

    pstart := p;
    qstart := p^.link;
    q := qstart;
    while q^.link<>pstart do
p^.link := q^.link;
            p := p^.link;
            q^.link := p^.link;
            q := q^.link
    p^.link := pstart;
    q^.link := qstart

Some Ideas for Teachers

Teachers, of course, can help their students by communicating to them the above suggestions. Students need experience applying these strategies, however, so that tests resembling the free-response portion of the APCS examination should be given from time to time. To best simulate conditions of the examination, a grading scheme should be constructed in advance and should be as objective as possible. (Since dozens of people are involved in grading the APCS examination, requirements for reliability necessarily limit the use of subjective evaluation.)

The conventional wisdom is that program-writing tests are prone to give capricious results, as “the right trick” may not occur even to a talented student, and the errors which invariably are made make it difficult to separate the totally muddled answer from the slightly wrong one. If students will apply the test-taking strategies suggested, however, the reliability of such tests should be improved. In any case, on your trial tests, try to pose questions whose answers require programming and problem-solving skills and understanding of computer science concepts, rather than inspiration.

Encourage your students in the use of a variety of techniques to verify program correctness. They should be adept at determining that first and final transits of loops perform the correct operations, for instance. Emphasize formal desk checking of program execution, particularly for recursive code and code involving pointers or complex data structures. Be sure your students can draw diagrams of typical linked list structures and use them in program traces.

Make your students aware of the APCS course syllabus. They need to know what the test designers consider important. Students can easily underestimate the importance placed on comments, modularization, prompts, and properly labeled output.

Although professional programming is not a timed activity, the time pressures on the programmer are very real. The suggestions I have made encourage care and aim at minimizing the effects of inevitable errors. Students who apply these strategies in the right spirit will likely score higher on the APCS test and become better programmers, and may even find that these lessons can be applied to other intellectual activities.


Previous Home Up Next

Send mail to Lionel Deimel with questions or comments about Lionel Deimel’s Farrago.
Copyright © 2000-2017 by Lionel Deimel. All rights reserved.