0% found this document useful (0 votes)
54 views6 pages

Code 6

This document discusses structured programming and concepts in Java such as arrays, loops, methods, and debugging. The key ideas are: 1) Structured programming involves writing code in a readable way using structures like for loops and methods to group code logically. 2) Arrays provide a way to group similar data items, and can be initialized and accessed using indexes starting from 0. 3) Common loops in Java include while, for, and for-each loops to repeat code. 4) Methods define reusable groups of code through parameters and return values. Static and non-static methods are discussed. 5) Debugging is an important skill that benefits from practices like compiling frequently when writing

Uploaded by

Arfan Hassan
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
54 views6 pages

Code 6

This document discusses structured programming and concepts in Java such as arrays, loops, methods, and debugging. The key ideas are: 1) Structured programming involves writing code in a readable way using structures like for loops and methods to group code logically. 2) Arrays provide a way to group similar data items, and can be initialized and accessed using indexes starting from 0. 3) Common loops in Java include while, for, and for-each loops to repeat code. 4) Methods define reusable groups of code through parameters and return values. Static and non-static methods are discussed. 5) Debugging is an important skill that benefits from practices like compiling frequently when writing

Uploaded by

Arfan Hassan
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

Spaghetti Programing

>

Chapter 3

Structured Code
>

Programs used to be written like this 1 t=0 t=0; i=1 2 i=1 yes 3 if i>n goto 7 i>n? 4 t=t+i no t=t+i; i=i+1 5 i=i+1 6 goto 3 print t 7 print t This is spaghetti programming, and the flow diagram is no better (except that it helps follow the strands)
Code p2

Ian Holyer

COMS12100

Code p1

Structuring
>

Data and Code Structures


> > > > >

The idea with structured programming is that you say what you mean; the program is readable: total = 0; for (i = 1; i <= n; i = i+1) { total = total + i; } print (total); It is is still possible to make a spaghetti mess No language is readable unless you are fluent Clean structured code is clearer than flow diagrams
Code p3

> > >

Data structures: ways of grouping data Code structures: ways of grouping code so it is as easy to execute a group of lines as a single line The word code is unfortunate, because it implies something difficult to read, but we are stuck with it Structured programming is old (Algol, Pascal). It is used in C & Java for the medium scale We will look at: arrays for grouping data methods for grouping code loops for repeating code
Code p4

Java Arrays
> > > >

Using Arrays
>

>

This is the commonest Java way of grouping a variable sized collection of similar items Java also has a lot of library classes for storing other kinds of collections such as lists, trees, tables Arrays are efficient; they match (serial) hardware, but have fixed limits The limits of an array are fixed dynamically when you create it, and if you want an array which expands as needed, you can use (e.g.) java.util.ArrayList In Java, arrays are objects with a directly accessible length field, and indexable data, and bounds checks
Code p5

Arrays are accessed using indexes, starting from 0


int[] ns; in C it would be int ns[]; ns = new int[3]; ns[0] = 5; ns[1] = 9; ns[2] = 7;

>

Arrays can be initialised all in one go:


int[] ns = { 5, 9, 7 };

>

The length is a field which is always available:


i = ns.length;
3 ns ns.length 5 ns[0] 9 7 ns[1] ns[2]
Code p6

Java

Java

Why index from 0?


>

Example: substrings
>

There are two common conventions in everyday life Counting from 1 and Measuring from 0 as with a ruler
1 1 1 2 3 4 5 0 1 2 3 4 5

The substring() method of the String class lets you extract a substring between two positions
s= 0 1 s 1 p 2 o 3 t 4 s 5 p o t

s.substring(1,4)

> > >

In programs, it is usually better to measure positions between items (as with birthdays!) The example has 6 positions numbered from 0 to 5 Indexing arrays from 0 supports the positional idea
Code p7

> >

This convention avoids off-by-1 errors, special case problems etc. The explanations of substring in books and online documentation are often poor (and the substring method in JDK version 1.2 had a bug!)
Code p8

Java

Java

While Loops
>

For Loops
>

The while loop is fundamental


int total = 0; int i = 0; while (i < ns.length) { total = total + ns[i]; i++; }

A variation for common situations is the for loop:


int i; for (i = 0; i < n; i++) ... for (int i = 0; i < n; i++) ...

>

You can imagine converting for into while


{ int i = 0; while (i < n) { ... i++; } } The outer block keeps i local. The for loop keeps the code to do with i together and helps not to forget i++

>

The test is done before each execution of the loop statement(s), so there may be zero iterations
>

Advice: use while except for int i=0; i<n; i++


Code p10

Java

Code p9

Java

For each Loops


>

Example: searching
> >

A variation on for loops runs through arrays:


String[] names; for (String s : names) { ... }

Find a name in an array of strings The problem is too subtle to use for, so use while
int i = 0, pos = -1; boolean found = false; while (i < names.length && ! found) { if (names[i].equals(name)) { found = true; pos = i; } (don't forget this!) i++; }

> >

It means: "for each s in the array names" It is short for this (so use it when you don't need i)
for (int i = 0; i < names.length; i++) { String s = names[i]; ... }

Java

Code p11

Java

Code p12

Methods
> >

Returning from Methods


>

In Java, procedures are called methods A method is defined by return type argument types int process(String s, int n) { actions; argument names } Every method is defined inside a particular class Classes group code and associate it with data
Code p13

The last act of a method is to return the result


double average(double[] xs) { double total = 0; for (int i = 0; i < xs.length; i++) { total = total + xs[i]; } return total / xs.length; }

> >

>

A return type of void indicates nothing is returned


void increment()

Java

Java

Code p14

The Program Object


> >

Library Methods
> >

To have normal non-static methods and global data, you need a program object (in general, a current object)

class Calculator { double value; (global "register") public static void main(String[] args) { ... Calculator program = new Calculator(); String result = program.run(args); } ... String run(String[] args) { ... } }
Java Code p15 Java

Most library methods are associated with objects These examples are from the String class and are called on a String object
String s = "spots"; int n = s.length(); String s2 = s.substring(1,4); boolean b = s2.equals("pot"); char c = s.charAt(0); boolean plural = s.endsWith("s"); char[] cs = s.toCharArray();

Code p16

Static Methods
> >

Recursive Methods
>

Some methods don't have a current object These are the ones declared as static
class Prog { public static void main(String[] args) { ... }

Java methods can be recursive (essential for trees etc)


int fac(int n) { if (n == 0) return 1; return n * fac(n-1); }

>

Loops are usually better in simple cases like this


int fac(int n) { int f = 1; for (int i=1; i<=n; i++) f = f*i; return f; }

> >

The system calls main() with no current object There are common static methods in java.lang
Math.sqrt(2.0) Character.isUpperCase('C') Integer.parseInt("42")

Java

Code p17

Java

Code p18

Debugging
> > > > >

Rule One of Debugging


>

>

A bug is a mistake in your program, and everybody is human, so you will produce a lot of them Debugging is one of the most important skills for a programmer, yet it is often not covered well in books It is true that you learn it mostly by experience, e.g. in the lab, but a few rules and tricks can go a long way Debugging can take a very, very, very long time If you are bad at it, it can make you 10 or 100 times slower than other programmers, e.g. so that it is impossible for you to do a weekly assignment on time Your competence at debugging is critical, so think about it and pay some attention to it
Code p19

> >

>

There is one rule of debugging above all others - you should never forget it and never break it: Never write more than a handful of lines of code before re-compiling and re-running your program If you are a weaker programmer, you should write fewer lines of code at a time The reason is simple: if it turns out that there is a bug, you know it is in those few lines of code, you just wrote them so you are very familiar with them, and you can catch the bug really quickly Also, the chances of two interacting bugs is very low
Code p20

Rule Two of Debugging


>

Rule Three of Debugging


> > >

> >

This is nearly as important as rule one: Design your program in small pieces (methods and, later on, classes) Each piece needs to to carry out some well-defined, easy to understand task The reason is essentially the same as before: if a bug emerges which is not in the lines you just wrote, at least it is in the few lines of a self-contained method

>

If you can't spot a bug straight away, you need to treat it as a detective problem and track it down That means understanding and checking what the program is doing, to find out where it is going wrong Problem halving is the main detective principle: Find a way to split the search into two parts, and a way of testing which of the two parts contains the bug For example, this might be "does the program go wrong before or after the moment when..." or "is the bug inside or outside the code that deals with..."

Code p21

Code p22

Debugging by printing
>

Testing
>

One way to check programs is to add print statements:


System.out.println("Here, x is " + x);

> >

It is a crude technique, but it works in all languages , on all platforms, and in all IDEs It is really useful to define a method for yourself, to abbreviate the print statements and switch them on/off
void p(String s) { if (! printing) return; System.out.println(s); }
Code p23

> > >

Modern ("agile") development techniques begin with testing, but it is not about how much testing to do: - it is impossible to test everything - it is suicidal to test nothing So how much testing you do is down to experience The real issue is your attitude to testing and the approach you take Let's look at the first assignment (Grade) as an example, and see how programmers would have tested it in the past, and how they should test it now

Code p24

Testing the old, bad way


>

Unit Testing
> >

Here is the wrong way to test the grade assignment:


> java Grade 50 Lower second class > java Grade -p 50 50.0 > java Grade Error: 0 to 100 please

The new, right way to do testing is called unit testing The program tests itself, e.g. when it has no args:
> java Grade OK

> > >

> >

This involves boring typing, and checking by eye: Alan Turing said "There need be no real danger of it ever becoming a drudge, for any processes that are quite mechanical may be turned over to the machine itself." (1946, proposal for first computer)
Code p25

To get this to work well, you need to design the way the testing is going to work It may change the design of the program, so testing needs to be part of the program design from the start In fact the suggestion that there should be a run method which takes the arguments and returns a string was made with testing in mind
Code p26

A Design for Testing


>

The check method


>

Ideally, testing is done with one-line method calls, e.g.


... check("50", "Lower second class"); check("-p 50", "50.0"); check("", "Error: 0 to 100 please"); ...

The check method might look like this:


void check(String line, String expected) { String[] args = line.split(" "); String result = run(args); if (result.equals(expected)) return; report = report + "Error: ... \n"; }

> > >

It is convenient for the first string to contain all the command line arguments On the other hand, the main method is passed an array of strings, after they have been chopped up by the OS So, the check method will need to split the string
Code p27

>

This depends on a "global" report variable


class Grade { String report = ""; ...
Code p28

The test method


>

The main method


>

The main method cannot see the global report variable in the program object, because there is no program object when main is running, so the test method must return the report variable to main:
String test() { check("50", "Lower second class"); ... return report; }

The main method either calls run, or calls test (which calls check, which calls run)
public static void main(String[] args) { Grade program = new Grade(); String r; if (args.length == 0) r = program.test(); else r = program.run(args); System.out.println(r); }

>

Strictly speaking, if the result is an error message, it should be printed on System.err, and System.exit(1) should be called
Code p30

Code p29

Regression Testing
>

Test Driven Development


>

> > >

>

There is an old technique called regression testing: keep old tests and re-run them later, which used to be very cumbersome to do You can see that it is now built in to unit testing The point is that when you add a feature or fix a bug, you very often break something that used to work Unit testing guards against this: every time you add a feature or fix a bug (in fact every time you recompile the program) you should test it, so you know which five-line change contains the bug How much testing should you do? Enough so that if the testing succeeds, you are confident that your program is working properly
Code p31

The next step in modern development is to use this approach to testing to good advantage, to avoid unnecessary documentation and meetings: - write some tests before you start: these can take the place of specification and design documents, explaining what the program is supposed to do - add more tests as you program, to illustrate the features added or issues that crop up, and to take the place of team meetings and progress reports - when you can't think of any more tests, and all the tests succeed, then you know you have finished!

Code p32

Refactoring
> > > >

Simplicity
>

>

Unit testing leads to a technique called refactoring, which really just means changing your mind When you add a feature, you realise that your program design isn't good enough, and you need to "rewrite" it Programmers have always rewritten their programs, but now it is an officially allowed technique It works, because there is now a simple check that the program is back together and working properly again, namely when the testing succeeds once more The tests may need to be rewritten alongside the rest of the program and big refactoring steps may need to be broken down into stages
Code p33

>

>

Unit testing and refactoring lead to another feature of modern development, namely the advice: use the simplest thing which works properly The idea is that if you have a need for a feature today, use the simplest approach that gives you that feature, and don't spend lots of time and effort designing your program to be future-proof, in ways which may never be needed anyway Instead, trust yourself to be able to refactor your program to make it more sophisticated so that further features can be added, if and when that is needed

Code p34

You might also like