Lecture Notes for CS 384 Software Engineering II

Announcements

  • Reading Assignment: we are starting in on Bruegge Chapter 10

    What CS 384 is all about

    CS 384 is all about the back-end software engineering issues: programming, debugging, testing, managing change, and so on. The goal for CS 384 is to learn back-end software engineering by completing the project designed in CS 383.

    Taking Stock of our Situation

    We have a design document, sort of, that has a lot of useful ideas and a lot of flaws. We have to proceed and do our best and learn what we can along the way.

    Command and Control

    It is well and good for the instructor to leave things up to the students to take ownership of the project. I would love it if students ran the web discussion board, and students ran the project wiki, and students ran the project documentation and software repositories. But in a course where things unfortunately must be graded, the instructor must retain enough control over the project to be able to measure or observe student contributions.

    Consequently, the source code repository we will use (for grading purposes) will be hosted on a CS department machine, and since CVS is more universally present on CS machines, we will use it instead of SVN (sorry). Similarly, I will want a "working copy" capability on my office web server.

    CVS and Version Control

    CVS stands for "Concurrent Versions System". It is a software version control system, whose primary function is to aid in the coordination of programmers on large projects. Compared with earlier tools SCCS (source code control system) and RCS (revision control system), CVS offers some significant advantages: For these good technical and political reasons, CVS will be our source code control system of choice. There is a newer system called subversion which is said to compete favorably with CVS; feel free to check it out, it seems to be on our system, and to use mostly the same commands as CVS.

    Major CVS Commands

    CVS works using a "repository" which is a database for source files. You can specify which repository to use via a command line option, but it is usually done by setting a CVSROOT environment variable. This can be set to either a local directory or an internet machine and directory name. When you checkout a project from a repository, your project directory remembers which repository it belongs to, so there is no problem using CVS with many different projects in different repositories; you don't have to keep resetting CVSROOT all the time.

    Unless you are creating your own repository, the first command you need is

    cvs checkout projectname
    
    which grabs a copy of a named project from the repository. The various cvs commands that manipulate the repository have the syntax
       cvs command [filenames...]
    
    The other commands you need immediately for CVS include:
    cvs diff [filenames...]
    Show any differences between your file and the version in the repository
    cvs update [filenames...]
    Merge in any changes others' have committed to the repository. If you have changed lines that others have changed, the conflict is reported and both copies of the changed lines are left in for you to merge by hand.
    cvs commit [filenames...]
    Merge your changes into the repository.
    cvs log [filenames...]
    Show history of changes that were made to a file or files.
    There are a few other CVS commands, and command-line options, that you may find useful; read the manuals! One option of special interest is -r tag which let's you ask for older versions from the repository instead of the current version. This may help if the current repository gets broken. :-) Use it with care, however; when you go back to an earlier version, the repository doesn't think any changes you make apply to the current version. You may need to use Dr. J's "Texas Three-Step"

    Similarly, there are "gotchas" to avoid if you have to move a directory around in the CVS repository. One student just did a "mv" and then was stuck in a "eternal CVS conflicts from hell" mode, until he found out he needed to delete the CVS/ directories from the files' old locations, and do new "cvs add" commands for the directories at their new locations. His GUI client interface for CVS (Eclipse) allowed him to get into this mess and failed to warn / prevent it...

    Project Documentation

    Damian was kind enough to send me this morning a file named Compilation-DrJ-revised-ball.doc

    Team Assignments

  • We had one voluntary person move (Rflamm --> datatype group).
  • We had two departures (hani - from what group? .
  • We have one new person (Ryan)
  • We had one group say they could use additional staffing (library).

    Project File Organization

    Let's work on file organization. By default, I would start off with a top-level project directory containing src/ doc/ and web/ directories. src/ is for Java stuff, doc/ is for documentation, and web/ is for html, php, etc. You can rename directories, but its a pain and you should minimize it. You can more easily add new top-level directories or subdirectories. If src/ and web/ cannot or should not be distinct, we should discuss that now.

    Group cs384 userid checks

    Who all is missing? K.C. !
     arp7257  - Brandon
     dave6169 - Trevor
     aize5319 - AWOL
     beer6572 - Mike
     calh1578 - Mark
     doug6431 - Patrick
     edwa0661 - Joseph
     eklu5841 - Nate
     flam6816 - Russell
     flam7141 - Chris 
     gent7907 - Joey
     groe3433 - Andrew
     grze7206 - Kane
     hust4149 - Benny - account broken!  What about account "benny"
     kins7078 - AWOL
     mart6325 - Dan
     mort6379 - Brandon
     odom6103 - Alex
     sand5360 - Ben
     sava0751 - Ryan
     shan0081 - Justin
     smit5617 - Chris
     stei1055 - Curt
     thro0179 - Dean
    

    Mapping Models to Code

    If we designed things right last semester, we are ready to code them.

    Goals:

    1. implement the use cases
    2. implement subsystems reflected in the design
    3. integrate subsystems to form a coherent whole
    Working on an object design model, and turning one to code, involves many transformations that are error prone. Potential problems:
    1. modify things to speed them up or make things more modular
    2. implement "associations" in varying ways, since languages do not have associations, only models do
    3. who enforces required "contract" properties such as making sure that parameter values are within valid range?
    4. new requirements show up during coding or later
    5. requirements not quite right, need to "adjust" on the fly
    6. design not quite right
    7. when we go to code, we discover some of these things
    8. add undocumented parameters that we need
    9. add extra class member variables
    10. pile up enough surprise changes...and the design doc gets worthless
    Chapter 10 suggests some approaches to implementing your model that might help a bit with all this. Its examples are Java-based, lucky us.

    Four Types of Transformations

    model transformations
    editing the class diagram. Simplify or optimize a class diagram, correct it, or fill in missing parts. The more code already written, the more code may have to be changed or recoded to stay consistent.
    refactoring
    an improvement to the code. sometimes this doesn't change the model. If the model needs to be changed, you hope to minimize such change, but failing to update the model leaves other developers unaware. Refactor in TINY incremental steps, and test each step, or risk pandemonium. Note on refactoring example in Figures 10-2, 10-3: some refactorings like "set parent class to new superclass" are pretty limited in languages with no multiple inheritance... Work through those examples pp 396-397 and ask Dr. J about any parts you find unclear.
    forward engineering
    generate the code from the model. often mechanical, or easy. This is what we need to do right now. Review how to do this for classes, inheritance, public vars (vs. private w/ getters and setters?), aggregation, user defined associations...
    reverse engineering
    construct an object model from the code. This is often the first step in a fix-the-legacy-program job. Note: some aspects of code are hard to map back onto model!

    Guidelines for successful transformations

    address a single criteria at a time.
    if you are improving speed, don't go refactoring your classes at the same time.
    keep your transformations local.
    change as few methods or as few classes as possible. If you change the parameters of a function, keep both old and new around for testing (at least for awhile). If you are changing lots of subsystems at once, this is an architecture change, not a model transformation.
    validate each transformation
    maybe it looks easy and obvious, but maybe you missed something

    Optimizing the Object Design Model

    Direct translation of model to code is often inefficient. Inefficiency is often due to redundant memory references. You may need to optimize access paths between classes.
    repeated assocation traversal
    x.y.z.a, if it is done often enough, may warrant x having a direct reference to z.
    replace "many" associations with qualified assocations
    add hash tables or other means of quickly picking subjects from "many" associations
    misplaced attributes
    if a class has no interesting behavior, or is only referenced from a single calling/owning class (for example some aggregations are like this), it is a candidate for absorption into the parent class. See the Person and SocialSecurity example
    lazy construction
    if construction is slow and the object is not used in every single execution, consider a proxy for it that constructs it only if it is used.
    cache expensive computations
    for example, if method m() is called a lot and is slow, AND if m() is a pure math function or you can otherwise prove it is safe to do so, remember the results of previous calls to m() to reduce future calls. (Dynamic programming).

    Mapping associations to collections

    Unidirectional one-to-one associations are the best special case, you can implement them as a pointer.

    Bidirectional one-to-one associations introduce a mutual dependency, you can almost just use two pointers, but be careful of the methods to establish and break such associations, to keep things consistent.

    Reading

    Read Chapter 10 (OK to skim or skip 10.6).

    CVS Status

    As of noon today, Joey added "You can't go fishin in a watermelon patch.", Dan added the rousing "You can't rollerskate in a buffalo herd.", and 16 students toal (about 2/3rds) managed to commit names to the Credits.java file. We need more like 100% compliance. In a couple cases there are problems accessing CVS, and (for example) my CVS hints e-mail only works if your login shell is bash, some folks have other login shells and need a different hint.

    Mapping associations to collections, cont'd

    Things get interesting when multiplicity >1 is involved.

    one-to-many

    The many-folks may have a single reference back to the one, but the one will need what--an array (often dynamically sized) of references. For low multiplicities, this is almost what linked lists were born for, but for higher multiplicities a linked list is too slow. The example in Figure 10-10 in the text uses a Set (really, a HashSet). Whatever language you are using, you will need to study the container classes, and if you are using a strongly typed language, understand how the container classes handle their generic, polymorphic nature. For example, in C++ the way container classes manage to work with any type is using templates. In C, one would just break the type system and typecast pointers as needed. How do Java's container classes (such as HashSet) handle this problem? If we don't know, we better find out ASAP, and you-all should know it well before the midterm!

    A key point are the methods that establish (and break) the objects' participation in a given association. In Figure 10-10 examine and understand the dovetailing between the removeAccount in class Advertiser and the setOwner in class Account.

    many-to-many

    Both sides have a collection, and sets of operations on both sides must keep these collections consistent. See Figure 10-11. Many supreme software engineering gurus just throw up their hands and demand that a new class be introduced in order to implement the association. Don't be surprised if a lot of things in the UML model get turned into classes in the implementation, and don't expect implementation classes to all have a mapping back to a model class.

    Qualifiers

    Earlier I have said "many" multiplicities can be reduced by using qualifiers, which amount to introducing a hash table or similar structure to look up references. The Java class for doing this might well be called Map. Figure 10-12 is very interesting, but its UML seems bogus.

    Project Status

    Pretty much everybody has working CVS by now. ksh was an extra pain, and may yet be. Don't just make CVS possible, make it so it is easy for you.

    As of last night only Russ and Trevor turned in a placeholder starting point .java file into the repository. They get an "A" for HW#1. We have to get on with the actual coding, from the UML specs you wrote last semester. Time for HW#2.

    CVS: Moving a File Example

    Suppose someone added a file to CVS! Hurray! How did they?
    cvs add Bullet.java
    cvs commit -m "bullets" Bullet.java
    
    Now suppose that they put this in the wrong directory, say, the top level directory instead of the src/ directory where it belongs. The following works; shorter variations exist.
    mv Bullet.java src/Bullet.java
    cvs remove Bullet.java
    cvs commit -m "moved to src/" Bullet.java
    cd src
    cvs add Bullet.java
    cvs commit -m "moved to src/" Bullet.java
    

    Mapping Contracts to Exceptions?

    A good object-oriented design may have "contracts" for method behavior, most commonly a method may be said to require 0 or more preconditions, and to guarantee 0 or more postconditions or invariants. In Java, you may implement contracts by inserting runtime checks, which slow execution down, and if the contract is violated a class can report it by generating an exception. The better way to implement this is to allow such checks to be easily turned on/off at compile time. And if you use exceptions, be sure you handle them; one of the most irritating and common failures in Java applications, which users really hate, are ExceptionNotHandled errors. Aggressive use of throw/try/catch can increase your total code size by 100%, but aggressive error handling is usually better than no error handling, and you have the same problems in most languages.

    Object Persistence

    Basic idea: when objects (and UML relationships) have to survive across runs, what do you do? Serialization is the act of taking some structure and converting it to a string, from which the structure can be restored. It works for both persistence and mobility of that structure across machines. Java tends to support Serialization a lot.
    serialize whole universe
    simplest notion of persistence, used in early programming languages, not very efficient/scalable
    serialize disjoint structures independently
    single database table might store mixed types of data. Need a primary key to get the data back, still not super scalable.
    one table per class
    each table needs a primary key, may need lots of references across tables (foreign keys). Keep it Simple, or go take the database course.

    Remainder of Class Time

    Meet in your groups, and discuss and divide the labor for HW#2.

    Design Document Starting Point

    This is what Damian sent me as our starting point.

    Student request

    Justin asked for GUI tutorials and/or technical resources. The "Java in a Nutshell" covers the language, but not the extensive class libraries. Extensive Java documentation is available on-line and I will post your recommended links to the class web page. I realize that references such as Sun's Swing JavaDoc page are not useful as tutorials, so please dig up some good online tutorials for your teammates.

    For those of you who prefer paper, your options are to buy, or to go to the library (duh). In addition I have a small cachet of Java books you are welcome to borrow on a until-the-next-class basis (i.e. don't borrow for long periods, borrow when you will have time to read). Unfortunately, my Java collection is not very current, there have been many new versions that need new books over the years.

    It is fair game to ask Java questions by e-mail or in class. I am not likely to know the answers right-off, since Java class libraries are a bit of a moving target. Rather, I will do my best to point you in the right direction, but it will take me awhile to do so.

    Introduction to Software Testing

    Reading Assignment: Read Bruegge Chapter 11.

    Testing is the process of looking for errors (not the process of demonstrating the program is correct). Bruegge gets more subtle, calling testing a matter of looking for differences between the design (expected behavior) and the implementation (observed behavior). Passing a set of tests does not guarantee the program is correct, but failing a set of tests does guarantee the program has bugs.

    Testing is best done by someone other than the person who wrote the code. This is because the person who wrote the code would write tests that reflect the assumptions and perspectives they have already made, and cannot be objective.

    Kinds of errors include:

    Syntax & semantics errors
    typos, language misuse
    Logic errors
    I/O errors
    formatting & parsing failures, network handshake trouble, ...
    Design errors
    misinheritance
    Documentation errors
    program does one (reasonable) thing, document says another

    Buzzwords

    software reliability
    probability P that a software system will not within time T under specified conditions (hardware OK, power steady, etc.)
    failure
    any deviation from expected behavior
    fault
    synonym for defect, or bug
    fault avoidance
    looking for bugs via static analysis, such as examining source code or running a static bug checker (e.g. lint) or model checker (e.g. ESC/Java)
    fault detection
    experiments during development to identify erroneous states and their causes
    fault tolerance
    mechanisms for handling or recovering from faults at runtime.
    erroneous state
    manifestation of a fault at runtime
    failure
    when an erroneous state results in a discrepancy between the specification and the actual behavior
    test driver
    For component testing, a fake "main()" that simulates the context in which a component will be run, and calls the test component. The driver determines what gets tested in the component.
    test stub
    For component testing, a simulation of the child components that are called by the component under test. Fake versions of associated classes that this component interacts with. Fake results of queries or computations (return values) that this component can use for its test. All this fakeness means that testing on "live" data after integration is often a whole new ballgame.
    Creep backwards from here to notice some added buzzwords.

    Bolden of the Day

    Bruce found this interesting blog on why
    Testing Trumps Design

    Different Kinds of Testing

    Bruegge Figure 11-1 is a cool summary of testing activities, with roles (for certain tests) for not just the Developer, but also the Client Customer and the User.

    Kinds of testing include:

    black box
    tests written from specifications, cast in terms of inputs and their expected outputs
    white box
    tests written with the program source code in hand, for example, to guarantee that every line of code has been executed in one or more tests.
    component inspection
    hey, reading the code looking for bugs is a form of testing, and it can be very productive
    unit testing
    testing individual functions, classes, or modules
    integration testing
    testing how units interact; culminates in a structural test
    system testing
    functionality, performance, acceptance test, installation test
    regression testing

    Test Cases

    A test case is a set of input data and expected output that exercises a (part of a) piece of software for the purpose of finding flaws. A test case has five components, given below. The purpose for this much detail is presumably to support reproducing and reviewing the test results by a third party (for example, the boss, or more likely the developer who must debug things) after the tester is finished.

    name
    location
    the full path name of the program
    input
    input data or commands. May be files, redirected keyboard input, or a recorded session of GUI input, net traffic, database results, etc.
    oracle
    expected test results against which the execution may be compared. If the expected output includes outgoing network traffic, graphical display of certain pixel patterns, etc, it will be difficult to automate the comparison, a comprehensive recording facility or a smart human can do the job.
    log
    actual output from the test.

    Real-Life Example Test Case

    In the Icon programming language (a pair of large C programs), there exists a suite of test cases created by systematically creating tests each time a new feature was added to the language, and then augmenting this suite with new test cases when pernicious bugs were reported by real users. One test case, for the "synchronous threads" feature in the language, looks like this
    Namecoexpr
    Location.../unicon/tests/general/coexpr
    Input.../unicon/tests/general/coexpr.dat
    Oracle.../unicon/tests/general/coexpr.std
    Log.../unicon/tests/general/coexpr.out
    In this case, "diff coexpr.std coexpr.out" shows whether the test case matches the expected case. One part of Bruegge's test case definition that is missing are instructions on how to run the program in order for it to produce the log, for example in this case there is a shell script that you run in order to run the test case with the proper input and output redirection (for example, to catch error output in the log)

    Major Announcement

    There will be No Class on Friday March 7 (the day before spring break). Your CS department loves you.

    Minor Announcement

    Dr. Ahmed of NIAT is looking to hire a CS person to translate matlab or some such into C++ or C#...

    HW#2 and CVS

    Do you know what sticky bits are? :-)

    I got a lesson from trying to do a "cvs update -d" recently.

    [jeffery@virtual ~/l33t]$ cvs update -d .
    Password: 
    cvs update: Updating .
    cvs update: Updating datatypes
    cvs update: failed to create lock directory for `/net/faculty/jeffery/384/l33t/datatypes' (/net/faculty/jeffery/384/l33t/datatypes/#cvs.lock): Permission denied
    cvs update: failed to obtain dir lock in repository `/net/faculty/jeffery/384/l33t/datatypes'
    cvs [update aborted]: read lock failed - giving up
    
    Turns out your files in CVS are (or were) owned by you, and group ugrad, because I hadn't set my sticky bits.

    Project Discussion

    Consider the following e-mail I received from a team member:
    It seems many people expect us to run as an applet... this seems to conflict with our plan of storing files locally with updates from the server. If we need local file access, we'll need to run as an application.

    It also seems like it might be a good idea for the activities to use a common constructor pattern. That being a contructor for that activity which takes the frame it's going to draw to as an argument. In briefly playing around with trying to integrate an activity into my UI mockup, it became apparent that this was a problem... there's no way to access the drawing space without passing it in, and if the class isn't set up to use it, it involves a lot of code rewriting. If we follow this model, the main() in each activity class can call "new Activity(new JFrame());" as a way of testing it standalone. (Or even better, set up the JFrame with the proper dimensions)

    So, what did we decide last semester on this topic? Do we have a record of that decision? What does our end-of-semester document have to say about it? Did this actually come out different in different folks memories, or did we fail to decide anything, or are some folks plowing ahead with what they think it should be, independent of what the group decided?

    Reviewing our design doc, it appears, broadly, that most teams understand us to be implementing a web-oriented solution, or a hybrid of some kind. But applications are far easier for testing. One might argue for an application-then-applet approach. How mutually exclusive are "application" and "applet" anyhow? How close could you get to writing code that runs both ways?

    Links on applets and on CONVERTING between applets and applications:

    A note on Java "extends"

    One night long ago when I tried to make the students' software engineering project, I came across a baffling error that looked like:
    StarSystemGame.java:4: cannot resolve symbol
    symbol  : constructor Game ()
    location: class Game
      {
      ^
    1 error
    
    It seemed to be complaining that Game() must provide a default constructor in order for any subclass to be allowed. But Game() should not have a default constructor, so I tried hard to understand why Java complains. In looking for an answer, I first looked at other code in our project that was doing "extends" to see if it would show how to "do things right" so it would compile. I game across the following bogosity:
       // Constructor methods
       /**
        * This empty constructor method was added by the Galactic and Province 
        * Team to allow Sovereign to extend Charactr.
        */
       public Charactr()
       {
    
       }
    
    This pretty much proves that the error is common, and that one "solution" is to add a default constructor that makes no sense. But, wanting a better fix and some understanding, I went to google, and after some searching, came across some notes from Stanford which pretty much explain the situation.

    In brief: the compiler error message seems to blame the parent for the child's mistakes (a common pattern in the real world). The correct solution is

    Without it, Java supplies a default constructor which calls the superclass default constructor (which doesn't exist and generates an error message). This issue is compounded by the fact that The reason the child got a default constructor added was because it did not inherit the parent's constructor.

    This analysis got StarSystemGame compiling OK by adding the constructor:

      public StarSystemGame(String sourceFile) {
         super(sourceFile);
         }
    
    I thought I was done, and feeling pretty clever, but there was one problem: subclass Sovereign DOES define its constructor. And taking out the dummy constructor from Charactr.java still causes Sovereign.java to fail. Darn!

    I thought: maybe since Java doesn't inherit constructors, the subtype must define all the same constructors its supertype does, but that didn't work. Then I thought: maybe the subclass constructor always calls a superclass constructor, and if you don't do it yourself, it gets done unto you. This seems to be the case. So for class Sovereign to compile OK without the bogus superclass Charactr default constructor, subclass Sovereign's constructor has to call a superclass constructor. The following works, although I was just guessing at the parameter names due to TERRIBLE PARAMETER NAMES IN THE Charactr CONSTRUCTOR!

       super('?', name, combatRating, 0, (Environ)null, "", "", "", "", "",
             enduranceRating, 0, leadershipRating, 0, 0, 0, false);
    
    Questions: what is the "scom" parameter? Characters do not have a space combat value (they do have a space leadership value). The constructor is confused about this because class Unit requires all units to have a space combat value. The spacecombat attribute should be moved down into class MilitaryUnit where it belongs. This got me wondering whether that first Charactr constructor was being used at all. Apparently not. Sovereign constructors were being passed a space leadership rating, but the superclass didn't seem to have a field to store it in. I added spaceLeadership to class Charactr. Code for parsing characters from .dat files probably needs to know about space leadership and do the right thing with it.

    Unit Testing

    One method of unit testing that is statistically shown to be cost-effective is to read the source code! This may be done with the aid of a partner or team, performing either a walkthrough (where the code author sets the agenda and others review) or an inspection (where the leadership sets the agenda).

    Whole books have been written about methods of writing good tests, much of which boils down to: write tests to challenge the boundary conditions and assumptions that programmers typically make when writing code.

    Junit HowTo / CppUnit Docs

    JUnit is for Java, CppUnit is a port of it for C++

    Example of (white box) testing: Testing Loops

    If your job is to write tests for some procedure that has a loop in it, you can write tests that:
    1. skip the loop entirely
    2. execute only one iteration of the loop
    3. execute two iterations
    4. execute M iterations, for some random 2 < M < N-1
    5. execute (N-1), N, and (N+1) iterations
    where N is the maximum number of allowable passes.

    Public versus Accessors

    In reading past students' homeworks, I noticed there is a temptation for teams to declaring "everything is public". While public methods are normal, public fields are only normal in a rapid prototyping context. For this reason, I am not surprised to see the actual Java code using lots of privates where the design claimed fields were public. One point I would like to reiterate is: if a field is public there is no reason to write accessor get/set methods. In fact, a big advantage of declaring a field public for rapid prototyping purposes is that you get to defer writing these methods.

    Testing is like detective work?

    A SE author named Lethbridge makes an unfortunate analogy between programmers and criminals; they have a modus operandi, and once you find what type of bugs a programmer is writing in one place, the programmer may well repeat similar bugs elsewhere in the code.

    In selecting test cases, look for equivalence classes

    You usually cannot test all the possible inputs to a program or parameters to a procedure that you wish to test. If you can identify what ranges of values ought to evoke different kinds of responses, it will help you minimize test cases to: one representative from each class of expected answer, plus extra tests at the boundaries of the equivalence classes to make sure the ranges are nonoverlapping.

    Some (Lethbridge) Bug Categories

    Announcement

    What: 2008 Spring Career Expo of the Palouse

    When: Wed., Feb. 13, 11 a.m. to 5 p.m.

    Where: UI Kibbie Dome

    Why: Students will be able to speak with more than 170 employers seeking full-time employees and interns in a variety of majors.

    CVS Examples

    Please understand that we have a wide range of previous experience and technical levels in this class. Some of you are CVS novices, some are not. To be frank, I've used CVS successfully for 10+ years without having to learn most of its features, so I am only an intermediate CVS practitioner.

    Deleting a File

    rm foo.java
    cvs remove foo.java
    cvs commit -m "(give reason for removing the file here)" foo.java
    

    Branch and Merge Example

    From the fine folks at Brookhaven National Lab and Cal Poly, here is a
    good example.

    Now, Dr. J asks, when is it useful and appropriate to create branches, and when not? How am I supposed to know about work you are doing on a branch? Am I supposed to know? A simple answer for our class might be:

    Create branches whenever you want, Dr. J will only grade the trunk.
    So for example, in the current trunk the HW#2 turnin, if I graded this way, would show many directories as empty and teams as not having committed anything that the other teams can easily see.

    What's in CVS?

    Lots of work in branches...
    src/algorithm has 779 lines of .java, 51 lines of .html
    commits evident from stein, cho, odom, morton
    src/chat has 323 lines of .java
    commits evident from sanders, odom, eklund, husted
    src/datatype has 1442 lines of .java, about a meg of .class, .png, .wav...
    commits evident from calhoun, flam6816, grze7206
    src/library_station has 450 lines of .java
    commits evident from groenewold
    src/navigation has 1373 lines of .java
    commits evident from shan0081, mart6325, dave6169
    web has 84 lines of php and 213 lines of html.
    commits evident from beery, ball, arp
    web/system has goodness knows what.
    Code Igniter? What else? Questions:

    HW#3

    Coverage Testing

    Coverage means: writing tests that execute all the code. Since a significant portion of errors are due to simple typos and logic mistakes, if we execute every line of code we are likely to catch all such "easy" errors.

    There are at least two useful kinds of coverage: statement coverage (executing every statement), and path coverage (executing every path through the code). Statement coverage is not sufficient to catch all bugs, but path coverage tends to suffer from a combinatorial explosion of possibilities. Exhaustive path coverage may not be an option, but some weaker forms of path coverage are useful.

    Coverage testing clarification: "all possible paths" is impractical due to combinatorial explosion. "all nodes" is inadequate because it misses too much. The right compromise is "cover all edges".

    Inspections

    Idea: examine source code looking for defects.

    Roles:

    author
    moderator
    runs the meeting. establishes and enforces the "rules"
    secretary
    recording defects when they are found
    paraphrasers
    step through the document, explaining it in their own words

    Writing Formal Test Cases

    A test plan should be written before testing starts. Lethbridge points out that it can be developed right after requirements are identified. In recent years the "extreme programming" community has argued in favor of writing the test cases first, before coding. If you can't come up with satisfactory test cases, you certainly don't know the problem yet well enough to code a solution or know whether your program is in fact a solution.

    A test case includes: a test case #/id, a descriptive name, a set of instructions, a description of the expected (correct) results, and (for some tests) instructions on how to restore the system back to normal after the test.

    Test cases are generally assigned a priority; Lethbridge suggests they be designated priority I (critical), II (general), and III (cosmetic).

    In-class exercise: if we wanted test cases for our semester project, what should be in them?

    Announcement

    If any of you are proficient Flash programmers and would like to make some quick cash, Scott Lynch at "The Beach" in Moscow has a small job he wants done, his number is 208-794-2354.

    Usability Testing (Bruegge 11.4.2)

    • Tests the user's understanding of the system
    • Find differences between system and user's expectations of what it should do (principle of least surprise)
    • empirical: sit "typical" users down in front of the system or a simulation of the system user interface
    • observe or record users' interactions
    • time how long they take, observe errors or difficulty performing a task
    • solicit user's feedback afterwards
    • process: develop test objectives, train users, conduct experiments, collect data
    • even a few "discount usability tests" are better than none at all...
    Three types of usability tests:
    scenario test
    give users the vision, see how difficult it is for users to understand the scenario.
    prototype test
    vertical prototype would do one whole use case in detail. horizontal prototype would do one layer (say, UI, without underlying functionality)
    product test
    use a functional version of the system. only available after it is implemented, but oh by the way, output of usability test will tell you possibly many or major things to revise in your user interface. (CS majors are not always good at usability!)

    (more on) Unit Testing (Bruegge 11.4.3)

    Motivation:
    • reduce overall complexity of testing, focus on smaller units, divide and conquer
    • easier to pinpoint/localize trouble
    • allows everything to be tested in parallel
    Most important kinds of unit tests:

    equivalence tests

    partition possible range of inputs into equivalence classes. develop 2 test cases for each class: a valid input, and an invalid input. Example:
    int getNumDaysInMonth(int month, int year) { ... }
    
    Equivalence classes: months with 31 days, months with 30 days, and February, which has leap years.

    boundary tests

    focus on boundaries between equivalence classes. developers and ordinary tests often overlook boundaries (0, null input, y2k, etc.). Note: watch out for combinations of invalid input.

    path tests

    what is a flow graph? can you draw one for a given piece of java code? is there a remarkable similarity between flow graph and "flow chart" or "UML activity diagram"? path coverage may be tractable at the method level, even if it isn't at the program level

    Announcement

    From: Stan_Gotshall@selgs.com [mailto:Stan_Gotshall@selgs.com]
    Subject: SEL Job openings
    
    I just wanted to give you an update on the job openings at SEL. There are 10...that's right...10 software engineering jobs open. This may be an all-time high over the last 2 years. A UI CS graduate would be qualified for most of these positions. As always, to apply go to selinc.com and if a potential applicant has any questions at all, please have them email me here at stan_gotshall@selgs.com or call me at (509) 336-2426. SEL is looking for lots of good engineers and I can say from personal experience that SEL is a great place to work and will be good for anyone's career.

    state-based tests

    Developed for OO systems. Compares end-states of the system after a set of code is executed, instead of comparing outputs. Derive test cases from a UML statechart. Test every transition in the statechart. See Figure 11-14.

    State-based testing is harder than it would seem; it is hard to automatically generate the inputs needed before the test that are to put the system in the state needed in order to test a given transition.

    polymorphism and testing

    If you use "virtual" methods and/or polymorphism, how does it affect your testing strategy? Need to execute a given polymorphic code with all of its possible runtime types. Example (Fig 11-15): your network interface has open/close/send/receive methods, it is an abstract class with several concrete implementations. Test the clients that use the network interface against each of the concrete implementations.

    Integration Testing

    There are several ways to test combinations of units.

    Big Bang

    The "big bang": what happens when you link it all together? This has the advantage of not requiring any additional test stubs that would be needed to test partially integrated subsystems. But when things go wrong, you have a needle in a haystack problem of finding the bugs.

    Top Down

    Top down = work from the user interface gradually deeper into the system. This is a layered, breadthfirst approach. Advantage: it is more "demo-able" for customers. Subsets of functionality may become usable before the whole system integration is completed.

    Bottom Up Testing

    Bottom up = test individual units first
    Focus on small groups (2+) of components. Add components gradually. Advantage: it is more debuggable and emphasizes meat-and-potatoes over shallow surface behavior.

    Sandwich Testing

    Sandwich testing selects a "target layer" and tests it against the layers above and below it. New target layers are selected to generate additional tests until the whole system has been tested. If the target layers are selected to gradually work from top and bottom into the middle, then sandwich testing is a combination of top-down and bottom-up testing.

    ACM talk

    Yeah, so I am giving a talk to the ACM chapter this evening.

    How is your Unit Testing Going?

    HW#3 is mainly about getting some experience unit testing, and having some tangible test driver code to show for it. If anyone thinks they do not have anything that they can unit test for HW#3, ask your teammates to help you find what to work on, or report to Dr. J for advice or reassignment. :-) For the current homework, due this week, you've gotta have a fairly complete class with a decent amount of code to test, plus you've gotta write tests to attempt to thoroughly exercise the class' public interface.

    Have you figured out JUnit? Have any of you observed how nicely JUnit is integrated into Netbeans? Watch and enjoy a Netbeans/JUnit demo here. Are you doing PHP? There is a PHPUnit project on sourceforge; it looks moribund, but it might work. Have you tried it already? Googling for "PHP Unit Test" had plenty of hits including a page that contains a list of them. In the worst case if no tool worked for you, you write the test driver by hand.

    Questions:

    System Testing

    Tests the whole system.

    Functional (requirements) testing

    Looks for differences between the requirements and the system. This is traditional blackbox testing. Test cases are derived from the use cases. Try to create test cases with the highest probability of finding the bugs the customer will care about the most.

    Performance testing

    This tests one of the non-functional requirements. Typically, a system will be tested to see if it can handle the required userload (stress test) with acceptable performance...which may require a fairly elaborate fake user environment; consider what it would take to test how a web server handles lots of hits.

    Other forms of performance testing include volume testing (how does the system handle big input datasets), security testing (by "tiger teams" ?), timing tests, recovery tests (e.g. artificially crash the network or other external resource).

    Pilot test

    Also "field test", these tests include alpha test, and beta test.

    Midterm Examination Wednesday March 5; review Monday March 3.

    Today is mainly a "crunch day" -- homework will be graded based on what is in CVS by the end of the day, and your class time is mainly allocated for you to work on your assignment together.

    Announcement: SOA Contest

    If any of you are looking for an excuse to learn service oriented architecture, a contest at http://www.cretaceoussoftware.com/contest claims to be offering a $5000 scholarship to the best SOA project developed using their language/tool/thing.

    Trevor Demo #2

    Trevor hopefully has a more complete and coherent Activity architecture and activation demo for us.

    HW#4

    Woo hoo, we have project code walkthroughs coming up!

    Where we are At, Where we are Headed

    You are, hopefully, in the heat of coding your project. We are doing homeworks that mainly address this from a testing point of view. Basic Questions:

    We ran out of time and didn't get to question #2 above last time; please E-MAIL Dr. J your answer.

    Dr. J's Testing Book Show-and-Tell

    This semester is about half devoted to software testing, from the feel of it. A whole semester or two could easily be devoted to the subject. Here are some of Dr. J's book collection:
    Structured Testing, by Thomas McCabe
    Following the "structured programming" movement, testers naturally developed whitebox testing techniques relating to the control structures. This book really covers many areas of testing, but has a chapter on cyclomatic complexity that is worth a whole lecture or more.
    Testing Computer Software, by Kaner et al
    This book has many useful checklists, including a checklist of 400 common bugs in an appendix!
    Testing Object-Oriented Software, edited by Kung et al
    This book is a collection of the best published papers on it topic of testing OO systems. Besides interesting research, it may identify best practises and differences between OO and traditional code for test purposes.
    Black-Box Testing, by Beizer
    Although this book says it is about functional (black-box) testing, its chapters on things like syntax, control-flow, and data-flow testing are packed with examples that would seem to be white-box. It has a whole chapter on state-based testing.
    The Art of Software Testing, by Myers
    Good luck finding your own copy of this classic. It is one of the best early works in the field. Various individual elements like the checklist for code inspections are worth the price of admission.

    Myers' Checklist for Code Inspections

    Figures 3.1 and 3.2 of [Myers] give a list of low-level things to look for.
    1. Unset variables used?
    2. Subscripts within bounds?
    3. Noninteger subscripts?
    4. Dangling references?
    5. Correct attributes when aliasing?
    6. Record and structure attributes match?
    7. Computing addresses of bit strings? Passing bit-string arguments?
    8. Based storage attributes correct?
    9. Structure definitions match across procedures?
    10. String limits exceeded?
    11. Off-by-one errors in indexing or subscripting operations?
    Data Reference Computation
    1. Computations on nonarithmetic variables?
    2. Mixed-mode computations?
    3. Computations on variables of different lengths?
    4. Target size less than size of assigned values?
    5. Intermediate result overflow or underflow?
    6. Division by zero?
    7. Base-2 inaccuracies?
    8. Variable's value outside of meaningful range?
    9. Operator precedence understood?
    10. Integer divisions correct?
    Data Declaration Comparison
    1. All variables declared?
    2. Default attributes understood?
    3. Arrays and strings initialized properly?
    4. Correct lengths, types, and storage classes assigned?
    5. Initialization consistent with storage class?
    6. Any variables with similar names?
    1. Comparisons between inconsistent variables?
    2. Mixed-mode comparisons?
    3. Comparison relationships correct?
    4. Boolean expressions correct?
    5. Comparison and Boolean expressions mixed?
    6. Comparisons of base-2 fractional values?
    7. Operator precedence understood?
    8. Compiler evaluation of Boolean expressions understood?
    Control Flow Input/Output
    1. Multiway branches exceeded?
    2. Will each loop terminate?
    3. Will program terminate?
    4. Any loop bypasses because of entry conditions?
    5. Are possible loop fallthroughs correc?
    6. Off-by-one iteration errors?
    7. DO/END statements match?
    8. Any nonexhaustive decisions?
    1. File attributes correct?
    2. OPEN statements correct?
    3. Format specification matches I/O statement?
    4. Buffer size matches record size?
    5. Files opened before use?
    6. End-of-file conditions handled?
    7. I/O errors handled?
    8. Any textual errors in output information?
    Interfaces Other Checks
    1. Number of input parameters equal to number of arguments?
    2. Parameter and argument attributes match?
    3. Parameter and arguments UNIT SYSTEMS match?
    4. Number of arguments transmitted to alled modules equal to number of parameters?
    5. Attributes of arguments transmitted to called modules equal to attributes of parameters?
    6. Units system of arguments transmitted to called modules eual to units system of parameters?
    7. Number, attributes, and order of arguments to built-in functions correct?
    8. Any references to parameters not associated with current point of entry?
    9. Input-only arguments altered?
    10. Global variable definitions consistent across modules?
    11. Constants passed as arguments?
    1. Any unreferenced variables in cross-reference listing?
    2. Attribute list what was expected?
    3. Any warning or informational messages?
    4. Input checked for validity?
    5. Missing function?







    Check out Myers' checklist, above. For each item mentioned, ask whether it applies (or can be adapted) to Java, and if so, how?

    Testing Odds and Ends

    We will probably scratch our way through a few more testing topics as needed in future lectures.

    Acceptance test

    Benchmark tests, possibly against competitors or against the system being replaced (shadow testing). A specialized team from the customer may be involved in the evaluation of the system.

    Installation test

    Anytime you install a program on a new computer, you may need to verify that the program is running in the new environment. Software is often shipped with a self-check capability, which might run when first installed and then disable itself. More paranoid software self-checks every time it is executed, or even periodically during execution.

    Managing test activities

    Planning the testing process

    Start the selection of test cases early; parallelize tests. Develop a functional test for each use case. Develop test drivers and stubs needed for unit tests. Some expert (Bruegge?) says to allocate 25% of project resources for testing -- do you agree?

    The Test Documents

    Test Plan

    Scope, approach, resources, schedule. This is by definition given in the ANSI/IEEE Standard for Software Test Documentation.

    Is your test plan a product, or a tool? If you are using your test plan to sell your software, e.g. to a company that will use it in-house, they may want an impressive test plan to give them some confidence in your code. If you are making a product that requires a government or standards-organization approval, you may have to meet their standards. Otherwise...

    A test plan is a valuable tool to the extent that it helps you manage your testing project and find bugs. Beyond that it is a diversion of resources.
    - from [Kaner et al]
    as a practical tool, instead of a product, your test documentation should:
    • facilitate the technical tasks of testing. For example, the test plan document might cover overall file organization and how to run the full range of implemented tests. It may also help you to:
      • improve coverage, don't forget items
      • avoid unnecessary repetition
    • improve communication about testing tasks and process
    • provide structure for organizing, scheduling, and managing the testing

    Test Case Specifications

    These are sort documents, discussed in an earlier lecture, that list inputs, drivers, stubs, expected outputs, etc.

    Test Incident Reports

    These reports give actual results from a test run; often they are given as differences from expected output. These are similar to bug reports, and in fact, bug reports can often be turned into test cases + test incident reports.

    Test Report Summary

    List the results of testing. Prioritize failures in order to marshall developer attention and resources where they are most needed. Draw some conclusions about the current state of the software.

    Software Metrics

    Software metrics, or measurement, concerns itself with observing properties of a software system. Engineers really want
    • ability to estimate
    • monitor progress
    • evaluate tools
    • improve processes
    In addition, the engineers' managers often want to validate / justify what the team is doing, i.e. argue that they are using good or best methods.

    Metrics Taxonomy

    Dimension 1: static vs. dynamic. Are we measuring properties of the source code or .exe (products)? Properties of the execution(s) (resources)? Properties of the development activity (processes)?

    Dimension 2: direct vs. indirect. Are we measuring things that are objectively observable, or do we want to put a number on something more abstract (typically, the *-"lities")? Exercize: how many "lities" can you think of? How would you measure each?

    Q: does quality = #bugs / #KLOC ? Such definitions have been proposed for many or most of the "lities".

    Size-oriented, direct measures

    • lines of code
    • execution speed
    • memory size
    • bug reports per customer-week

    Function-oriented, indirect measures

    • # user-input activities
    • # user-output views
    • # user "queries" (for database apps)
    • # of data files
    • # of external interfaces
    Weight each of these; perhaps just designate as "simple", "average", or "complex".

    Sum of weights = "function points" of program.

    Measurement Relations and Scale Types

    Want measure M(x) to preserve relations such that, for example, M(x) < M(y) is equivalent to some underlying true relation R between x and y. Don't define a measure unless you understand the empirical relations (the scale type) for the attribute you are measuring.
    Scale Type admissible transform
    nominal any 1:1 renaming function
    ordinal x >= y is equivalent M(x) >= M(y)
    interval M(x) = α x + β
    ratio M(x) = α x
    absolute M(x) = x
    log-interval M(x) = α x β
    difference M(x) = x + β

    Metrics in Bruegge

    Bruegge says precious little about software metrics. He mentions management metrics versus quality metrics. Management metrics might include how many development tasks have been completed, how much $ has been spent, team turnover rates... Quality metrics might include change requests per week, defects discovered per test-hour or test-week, how much code is changed per week ("breakage"? "rework"? "flux"?).

    Some "-ities" Bruegge mentions are stability, modularity, maturity. Suppose one wants to measure some of these, or some of the nice ones you came up with in class -- how do you put a number on them? If project A has a "maturity score" of 1.7 and project B has a score of 3.4, does that mean project B is "twice as mature" as project A? This comes back to explain the topic of scale types mentioned last lecture.

    Metrics in the Java World?

    JMT
    Java metrics freeware from Magdeburg.
    PMD
    Cool sourceforge project, kind of like "lint", but oh by the way it calculates cyclomatic complexity.
    cyvis
    A tool mentioned in a nice article about cyclomatic complexity.

    Metrics for our project?

    wc -l */*.php */*.java */*/*.java */*/*/*.java

    11LKOC? 2.2KLOC of that are unit tests?
          39 web/account.php
          32 web/forgot.php
         115 web/index.php
          44 web/login.php
          36 web/modProfile.php
          76 web/system.ini.php
          35 src/Credits.java
           4 src/L33t.java
          67 src/admin/User.java
         128 src/algorithm/Activity.java
          21 src/algorithm/AllTests.java
          36 src/algorithm/BinarySearch.java
          15 src/algorithm/CaseyTest.java
          83 src/algorithm/Comparison.java
          45 src/algorithm/ComparisonTest.java
         246 src/algorithm/Decryption.java
         107 src/algorithm/DecryptionTest.java
          78 src/algorithm/GreaterThanX.java
          45 src/algorithm/GreaterThanXTest.java
          82 src/algorithm/NPC.java
          36 src/algorithm/Organize.java
         177 src/algorithm/Sort.java
         219 src/algorithm/ToolSelection.java
         136 src/algorithm/ToolSelectionTest.java
         180 src/chat/Chat_Channel.java
         130 src/chat/Chat_Client.java
         123 src/chat/Chat_Client_Engine.java
         135 src/chat/Chat_Client_EngineTest.java
         139 src/chat/Chat_ClientAboutBox.java
          44 src/chat/Chat_ClientApp.java
         320 src/chat/Chat_ClientView.java
         171 src/chat/Chat_Server.java
          11 src/chat/Chat_Tunnel.java
         150 src/chat/helpForm.java
          42 src/chat/UserListModel.java
         207 src/datatype/GameSkele.java
         175 src/library_station/Book_Sort.java
         185 src/library_station/Card_Sort.java
         438 src/library_station/init_lib_stat2.java
         215 src/library_station/Library_Matching.java
          86 src/library_station/Library_Matching_Test.java
          57 src/library_station/library_quiz.java
          57 src/library_station/library_review.java
          57 src/library_station/library_test.java
          41 src/library_station/start_book_test.java
          42 src/library_station/start_card_test.java
          43 src/library_station/start_init_test.java
         319 src/navigation/Client.java
          37 src/navigation/L33tActivity.java
          20 src/navigation/L33tActivityCompletion.java
          13 src/navigation/L33tActivityControl.java
          25 src/navigation/L33tActivityFactory.java
          58 src/navigation/L33tActivityManager.java
          36 src/navigation/L33tActivityViewer.java
         284 src/navigation/L33tDemoActivity.java
          25 src/navigation/L33tMap.java
         262 src/navigation/L33tMapCanvas.java
          31 src/navigation/L33tMapCanvasDemo.java
         262 src/navigation/L33tMapCanvasItem.java
          37 src/navigation/L33tMapCanvasItemPath.java
          35 src/navigation/L33tMapCanvasItemZComp.java
          13 src/navigation/L33tMapLocation.java
          15 src/navigation/L33tMapRegion.java
          71 src/navigation/L33tMapWidget.java
          48 src/navigation/L33tPath.java
          70 src/navigation/L33tPathCubic.java
         106 src/navigation/L33tRange.java
         129 src/navigation/LoginPage.java
         143 src/navigation/sampleChat.java
         282 src/navigation/trophyCase.java
          69 src/shooter/BaseTarget.java
          50 test/admin/getinfoTest.java
          66 test/admin/storeinfoTest.java
          86 test/admin/UserTest.java
         164 test/chat/Chat_ChannelTest.java
         138 test/chat/Chat_ServerTest.java
         351 test/datatypes/BaseTargetTest.java
         259 test/datatypes/ShooterTest.java
          23 test/navigation/L33tActivityFactoryTest.java
          36 test/navigation/L33tActivityManagerTest.java
         127 test/navigation/L33tMapCanvasItemTest.java
          46 test/navigation/L33tMapCanvasItemZCompTest.java
          60 test/navigation/L33tRangeTest.java
          20 test/navigation/L33tUnitTests.java
          56 test/navigation/trophyCaseTest.java
          27 src/admin/stnapi/Get.java
          89 src/admin/stnapi/getinfo.java
         107 src/admin/stnapi/Store.java
         159 src/admin/stnapi/storeinfo.java
          73 src/datatype/Binary Blaster/BaseTarget.java
          39 src/datatype/Binary Blaster/Button.java
           0 src/datatype/Binary Blaster/Enemy.java
         856 src/datatype/Binary Blaster/Shooter.java
         302 src/datatype/boxing/Boxing.java
          59 src/datatype/boxing/BoxingTest.java
          33 src/datatype/boxing/Button.java
         140 src/datatype/fighter/fighter.java
         127 src/datatype/fighter/sprites.java
         202 src/datatype/fighter/Test_Media.java
       11035 total
    

    cvsmine

    This program must surely be buggy as heck; how far off is it?
    Summary of Project Authorship:
    
    calh      345 lines in   9 revisions to 5 files 
    flam      616 lines in   9 revisions to 8 files 
    grze      241 lines in   6 revisions to 6 files 
    edwa       83 lines in   5 revisions to 3 files 
    kins      147 lines in   3 revisions to 3 files 
    arp       342 lines in  13 revisions to 5 files 
    mort       42 lines in   2 revisions to 2 files 
    ball        1 lines in   1 revisions to 1 files 
    doug        1 lines in   1 revisions to 1 files 
    dave      906 lines in  46 revisions to 23 files 
    mart       36 lines in   6 revisions to 5 files 83% empty comments
    cho       246 lines in  18 revisions to 11 files 22% empty comments
    aize      249 lines in   7 revisions to 5 files 
    eklu      845 lines in  12 revisions to 12 files 
    groe     1185 lines in  59 revisions to 18 files 
    smit      521 lines in   7 revisions to 7 files 
    stei      560 lines in   9 revisions to 9 files 
    benny      81 lines in   5 revisions to 3 files 
    beer        1 lines in   1 revisions to 1 files 
    gent        2 lines in   3 revisions to 2 files 100% empty comments
    sand      181 lines in  10 revisions to 4 files 
    shan      317 lines in   8 revisions to 5 files 
    odom      167 lines in   8 revisions to 8 files 25% empty comments
    sava        1 lines in   1 revisions to 1 files 
    
    average of 296 lines from 24 authors
    

    Note: three lectures between 17 and 18 are in-class code walkthrough exercises.

    Multiple NASA-related Summer Internship Opportunities

    http://spacegrant.nmsu.edu/opportunities/ispcs_summer.html

    The New Mexico Space Grant Consortium is proud to announce the 2008 International Symposium for Personal and Commercial Spaceflight (ISPCS) Summer Internships. The ISPCS summer internships are designed to give students real-world experience in the growing personal and commercial spaceflight industry. Students are placed with top players from business and government to participate on the ground floor of what may become the foundational enterprise of the 21st Century! Internships are available across the United States including New Mexico, Colorado, and Washington D.C. in fields as diverse as engineering, business management, graphic design, and public policy!

    Students will be given a $5000 stipend for a 10 week internship which will take place during the s summer 2008 academic term. At the end of the internship, students write a one page report on their experiences. The internships are funded by the International Symposium for Personal and Commercial Spaceflight.

    Internships are open to graduate and undergraduate students. Internships are open to all majors unless specifically stated by the internship opportunity listed. New Mexico Space Grant will accept applications until the internships are filled. New internships are expected to appear regularly, so check back often!

    The Virginia Space Grant Consortium (VSGC) in partnership with NASA Langley Research Center is offering the NASA Langley-VSGC Geographic Information Systems (GIS) Internship program. This program will place student interns at NASA Langley to support the NASA GIS team. Positions are open to high school, undergraduate and graduate students and are available in summer and fall 2008 and spring 2009.

    This is a great opportunity for any student majoring in civil engineering, technology, geography or other major and interested in developing and improving their skills and experience in GIS. Prior experience in GIS is not required as training will be provided. Students will work 20 hours per week and be paid a stipend based on their academic level. Deadline for summer applications is March 24 and the deadline for fall internships is July 1. Please view the attached flyer and visit http://www.vsgc.odu.edu/gisintern/ for more information and to apply. The NASA Langley GIS team site can be viewed at http://gis.larc.nasa.gov/

    If you have any questions or concerns, please contact Chris Carter (cxcarter@odu.edu), Assistant Director of VSGC, at 757-766-5210. Thank you for considering!

    StatCVS

    Is StatCVS the final solution to the CVS metrics problem? Did smit5617 write 73.4% of our project?

    Highlights from the Midterm Exam

    Graduating in May?

    The college of engineering is seeking your input on where to hold the reception. http://www.registrar.uidaho.edu/graduation/moscow-may.html

    Bolden of the day: 12 principles that guide programming at Google:

    1. All developers work out of a ~single source depot; shared infrastructure!
    2. A developer can fix bugs anywhere in the source tree.
    3. Building a product takes 3 commands ("get, config, make")
    4. Uniform coding style guidelines across company
    5. Code reviews mandatory for all checkins
    6. Pervasive unit testing, written by developers
    7. Unit tests run continuously, email sent on failure
    8. Powerful tools, shared company-wide
    9. Rapid project cycles; developers change projects often; 20% time
    10. Peer-driven review process; flat management structure
    11. Transparency into projects, code, process, ideas, etc.
    12. Dozens of offices around world => hire best people regardless of location

    project tweak news

    There is now a top-level makefile. "make test" cd's into test/ and does a make there. There is now a test/makefile. Making there cd's into respective subdirectories and does a "make". All projects should provide a directory with a makefile and tests under the project test/ directory. Files may need to be moved. My next step is to work out what the CLASSPATH and other settings needed on CS lab linux machines, in the presence of the directory change.

    A "Weak Tests" Explanation?

    One of you provided an excellent hypothesis for why some of the tests in some of the homeworks have been missing or trivial, according to your own midterm assessments. He said the reason there aren't tests in many cases is because the code isn't done -- meaning not written at all, or not finished enough to test anyhow. After all, how can you write tests if you don't have the code written yet? I immediately agreed, and said that I would be realistic in my expectations of test-related homeworks.

    By the way, eXtreme Programming (XP) advocates do in fact tell you to write the tests before coding.

    Dr. J's take: it is quite possible to write blackbox tests ahead of time, but whitebox tests can't be written until there is code.

    Corollary: testing can be included in the spiral model, and multiple iterations of increasing testing go along with multiple iterations of increasing code functionality.

    Software Complexity Revisited

    Why measure? Because code that is too complex is more buggy and more expensive to maintain.

    Potential downsides: rewriting to reduce a particular complexity metric may just move the complexity around, into unmeasured areas. For example, one can reduce "cyclomatic complexity" internal to methods by writing more methods, but does that help>

    Halstead's "Software Science"

    One of the older proposed measures of software complexity takes almost an information-theoretic approach, and measures complexity in terms of some low-level, observable properties of the source code, in particular from the following direct metrics: Halstead defined the following metrics: From all this

    Strengths: scales well; can be applied to whole programs with about the same effort as individual functions/methods. Some information-theoretic validity. May actually give very high level languages their claimed benefit of being "higher level".

    Weaknesses: software science seems to be voodoo. "Volume" and "potential volume" definitions seem to be just made up numbers. The program level #'s might not have a stable scale type, to where you can say that a number of .5 or above is "good" and below .5 is "bad". Doesn't acknowledge control or data flow paths as being fundamental to complexity.

    Any Entrepreneurs?

    For those of you not right about to graduate, there is an interdisciplinary Entrepreneurship Certificate coordinated by the college of business. You get a certificate (which also appears on your official transcripts) if you complete introduction to entrepreneurship, enterprise accounting, and two CS courses: a CS tech elective and our 481 capstone, which you probably are taking anyhow. If any of you think you may want to do your own startup someday, it might be useful.

    Issues we promised to work on

    • How do we integrate activities w/ chat
    • How do we integrate activities w/ admin
    • How do we integrate activities w/ navigation
    Option #1: brainstorm in-class.
    Option #2: graded homework assignment.

    If we brainstorm in class, I suggest (somewhat arbitrarily) that we meet for 10 minutes in three groups: chat+library, admin+datatype, navigation+algorithm. Each team-pair is assigned to come up with the best "answer" to the integration question that you can. You will each get 5 minutes (less is OK) to report back to the whole class. Designate a spokesperson to talk. Designate a recorder to write down the results and e-mail them to me. Algorithm+Nav, part of your mission is to "diff" L33tActivity with Activity, merge these classes into "Activity", and agree on a minimalist adequate method set.

    How is the test/ directory going?

    Algorithm team, do you need any help moving into test/?

    HW#5

    McCabe's Cyclomatic Complexity

    Given a flow graph G, the # of cycles (cyclomatic number) will be
    v(G) = e - n + p
    where e=#edges, n=#nodes, and p=#connected components. McCabe wanted a complexity measure based on the cyclomatic #, but he needed the #'s to be 1-based, not 0-based, so that the complexity of a whole program could be the sum of the complexities of the functions/methods, so he defined "cyclomatic complexity" to be
    e - n + 2p
    Before McCabe came along, major corporations had been having gigantic problems with overly complex subroutines, so the point where they had instituted maximum size limits, such as each subroutine may have at most 50 lines (IBM) or two pages (TRW). McCabe's point was that such limits miss the boat: some nasty spaghetti may become overly complex in far fewer lines, while plenty of far larger routines are not complex at all and forcing them to be broken into pieces by arbitrarily limiting their size only complicates and slows them down.

    Note that although the cyclomatic complexity of a whole program is the sum of all the subroutines and may go very high, McCabe was not worrying about whole program complexity, he was only worried about individual routine complexity, so in applying his measure to our whole system we should be interested in the maximum, and the distribution, of the individual routines' complexity, not the sum.

    Brandon Arp asked how that applies to OOP programs with complex interconnections of objects. One answer was that cyclomatic complexity measures control flow complexity without measuring data complexity and is therefore incomplete, and that OOP systems often have a lot of data complexity. Another answer is that McCabe's metric is generally applied at the single function/method unit level, at which calls to subroutines are abstracted/ignored. Measuring the control complexity of Java is just as useful (in looking for red-flags) as in non-OO languages. A third answer is: OOP programs tend to be broken down into smaller functions, and so the individual functions' complexity may be lower (which is good), but there must also be a coarser-grained complexity measure for the call graph, and OO programs may have worse characteristics for that measure.

    Ez, practical cyclomatic complexity? PMD from sourceforge is said to be integrated into Netbeans, Eclipse, etc.

    Software Quality

    What we have said so far: quality is probably not equal to #bugs/#KLOC. Probably not change requests or defect reports per week. Some folks say it is totally: how users perceive the software, how much value they obtain from it. Others argue quality might be a multiplied combination of normalized measures of the following properties.


    Understandability
    • definition: understandability is the opposite of "density"...the more expertise required to understand, the less understandable it is. Combination of comments, variable names, and (limits on) complexity
    • how to measure: subjective; peer review; walkthrough ratings; it's possible to measure/detect absence of comments, and possibly the use of poor variable names
    • how does it relate: Consistency helps understandability


    Completeness
    • definition: satisfies all the requirements; is fully commented
    • how to measure: blackbox observation? user satisfaction; lack of feature requests
    • how does it relate: lack of comments leads to lack of understandability (?)


    Conciseness
    • definition: functionality / code
    • how to measure: Function points / KLOC ?
    • how does it relate: more concise sometimes is more complex


    Portability
    • definition: a program is portable if it runs on multiple operating systems; if it fits on a flash drive? runs on different hardware? lack of CPU, word-size, compiler dependencies.
    • how to measure: count how many [CPU, OS, GPU, wordsize] combos you run on?
    • how does it relate: size/complexity may drive minimum requirements


    Consistency
    • definition: a program is consistent if it is formatted + commented consistently; consistently not-crashy; returns the same value of given the same input; API consistency (return values + params are similar across the interface); file/function/class names are predictable; consistent software design methods; consistent testing; consistent GUI
    • how to measure: peer review; look for absence of variations
    • how does it relate: reliability, testability


    Maintainability


    Testability
    • definition: a program is testable if it can be run in a batch mode; if various system states that need testing are recreatable artificially
    • how to measure: #people needed; amount of manual effort per test run; peer evaluate results from test runs; complexity required in order to automate tests
    • how does it relate:


    Usability
    • definition: a program is usable if end users have an easy learning curve; if a program can be run successfully by a moron; low # of keyboard or mouse clicks to accomplish a given task
    • how to measure:
    • how does it relate: GUI consistency; undestandability


    Reliability
    • definition: how often it needs maintenance? if it copes with errors without failing or losing a user's work
    • how to measure: MTTF; hours/months between failures
    • how does it relate: consistency of behavior


    Structured
    • definition: a program is appropriately structured if it uses data types proportional to the size / complexity of the application domain problems it must solve.
    • how to measure: look for excessive coupling; low cohesion; look for excessive numbers of idiot classes; look for monster/monolith classes
    • how does it relate: understandability; maintainability, ....


    Efficiency
    • definition: a program is efficient if results consume "minimal" memory, time, disk, or human resources to obtain.
    • how to measure: are we within epsilon of the optimal?
    • how does it relate: hyperefficient algorithms are often less understandable/maintainable than brute force algorithms


    Security
    • definition: a program is secure if it has no undocumented side effects? if it is impossible (or difficult?) for a program to give up information that is private; to give up control over computer resources to an unauthorized user
    • how to measure: how many minutes it takes a whitehat to hijack your application and use it to bring Latvia down off the net
    • how does it relate: complexity; usability

    Software Verification

    The process of checking whether a given system complies with a given criterion. One common criterion would be: check/confirm that the software complies with the design and that the design complies with the requirements. Some folks would narrow the definition to refer to a static analysis, that is, things that are checked without running the program.

    There is a whole field called Formal Methods which deals with constructing proofs of desired properties of programs. While historically these have been used only in safety-critical systems such as radiation therapy machines, or operating systems used in national security and defense hardware...there is a general trend toward reducing the cost of these methods which seems likely to end up in the mainstream someday.

    Example Verification Tools:

    ESC/Java2
    ACL2
    Zed, with real-world examples

    Integration Topics with Trevor

    Project Watch

    Algorithm team, please rename the HTML files that are spelled Algorthim... and have you moved your tests yet?

    What is the shooter/ directory in CVS src/ ? Should it be deleted?

    Chat team, what does the @Action mean in:

    @Action
    public void showAboutBox()
    

    ESC/Java2 Discussion

    Extended Static Checker for Java local class copy installed at /net/faculty/jeffery/html/courses/384/escjava. There is a copy of the whole thing as a .tar.gz file in case you have trouble downloading from Ireland. My .bashrc for CS lab machines had to have a couple things added:
    export PATH=/opt/csw/bin:/net/faculty/jeffery/html/courses/384/escjava:$PATH
    export ESCTOOLS_RELEASE=/net/faculty/jeffery/html/courses/384/escjava
    export SIMPLIFY=Simplify-1.5.4.linux
    
    The same distribution, which tries to bundle a half-dozen platforms, almost (and sort-of) works for me on Windows, but may be somewhat sensitive about Java versions and such. It gives seemingly-bogus messages about class libraries (on my Windows box) and doesn't handle Java 1.5 stuff (in particular, Generics such as Comparator<tile>). There is at least one system (KIV) that claims to handle generics, but I haven't evaluated it yet.

    "Mid" Term grades posted

    Discussion of re-grading policies.

    Notes from the Code

    Software Validation

    Validation is related to verification, but it generally refers to a process of runtime checking that the software actually meets its requirements in practice. This may include dynamic analysis.

    Validation Testing: an old example

    Prologue: This is approximately what I learned about testing from a university, so according to Kaner, it should not be useful, or I should not have learned anything from it.

    The Unicon test suite attempts to validate, in a general way, the major functions of the Unicon language; it is used by folks who build Unicon from sources, especially those who build it on a new OS platform. The unicon/tests/README file divides the testing into categories as follows:

    The sub-directories here contain various test material for
    Version 11.0 of Unicon and Version 9.4 of Icon.
    
    	bench		benchmarking suite
    	calling		calling C functions from Icon
    	general		main test suite
    	graphics	tests of graphic features
    	preproc		tests of the rtt (not Icon) preprocessor
    	samples		sample programs for quick tests
    	special		tests of special features
    

    Each subdirectory has a suite of tests and sample data, and a Makefile for building and running tests. The master test/Makefile automates execution of the general and posix tests, which are routinely run on new Unicon builds. The general/ directory contains tests "inherited" from the Icon programming language (50 files, 5K LOC):

    augment.icn   collate.icn   gc1.icn	 mem01c.icn   prefix.icn  struct.icn
    btrees.icn    concord.icn   gc2.icn	 mem01x.icn   prepro.icn  tracer.icn
    cfuncs.icn    diffwrds.icn  gener.icn	 mem02.icn    proto.icn   transmit.icn
    checkc.icn    endetab.icn   helloc.icn	 mffsol.icn   recent.icn  var.icn
    checkfpc.icn  env.icn	    hellox.icn	 mindfa.icn   recogn.icn  wordcnt.icn
    checkfpx.icn  errors.icn    ilib.icn	 numeric.icn  roman.icn
    checkx.icn    evalx.icn     kross.icn	 others.icn   scan.icn
    ck.icn	      fncs.icn	    large.icn	 over.icn     sieve.icn
    coexpr.icn    fncs1.icn     meander.icn  pdco.icn     string.icn
    
    Some of these tests were introduced when new language features were introduced and may constitute unit tests; many others were introduced when a bug was reported and fixed (and hence, are regression tests). A semi-conscious attempt has been made to use pretty much every language feature, thus, the test suite forms somewhat of a validation of a Unicon build.

    The tests are all run from a script, which looks about like the following. Each test is run from a for-loop, and its output diff'ed against an expected output. Some differences are expected, such as the test which prints out what operating system, version and so forth.

    for F in $*; do
       F=`basename $F .std`
       F=`basename $F .icn`
       rm -f $F.out
       echo "Testing $F"
       $IC -s $F.icn || continue
       if test -r $F.dat
       then
          ./$F <$F.dat >$F.out 2>&1
       else
          ./$F </dev/null >$F.out 2>&1
       fi
       diff $F.std $F.out
       rm -f $F
    done
    

    Sample test (diffwrds.icn):

    #
    #          D I F F E R E N T   W O R D S
    #
    
    #  This program lists all the different words in the input text.
    #  The definition of a "word" is naive.
    
    procedure main()
       words := set()
       while text := read() do
          text ? while tab(upto(&letters)) do
             insert(words,tab(many(&letters)))
       every write(!sort(words))
    end
    
    Sample data file (diffwords.dat):
    procedure main()
       local limit, s, i
       limit := 100
       s := set([])
       every insert(s,1 to limit)
       every member(s,i := 2 to limit) do
          every delete(s,i + i to limit by i)
       primes := sort(s)
       write("There are ",*primes," primes in the first ",limit," integers.")
       write("The primes are:")
       every write(right(!primes,*limit + 1))
    end
    
    Sample expected output (diffwrds.std):
    The
    There
    are
    by
    delete
    do
    end
    every
    first
    i
    in
    insert
    integers
    limit
    local
    main
    member
    primes
    procedure
    right
    s
    set
    sort
    the
    to
    write
    

    What I Have Learned About Testing

    Remember, this was in an academic environment, so Kaner would dismiss it.

    Software Certification

    • Loosely, some organization promises that some property has been checked.
    • Verification or validation performed by a third party who is willing to testify or make the matter part of public record.
    • Sometimes has an "insurance" aspect, sometimes not
    • People willing to pay for certification are often the same people who are willing to pay to prove a program is correct.
    • Certification doesn't prove anything, it just guarantees some level of effort was made to check something.
    Certification Examples:
    Certification of software usually includes certification of the process used to create the software. Certification of software is also often confused with certification of the people who write software.

    Windows Certification

    M$ doesn't certify that your program is bug-free, but it may certify that your program was written using current standards and API's. The large body of software developers tends to prefer the status quo, while M$ marketing people tend to want to force everyone to migrate to whatever is new and hot.

    The last time I noticed much about this, the public rollout to developers of a new forthcoming version of Windows included lots of talk about a new look and feel (you had to take advantage of it), and new installer protocols (you had to register your software in a particular way during installation so that the control panel would know how to uninstall you). If you were willing to jump through these relatively simple hoops in support of the M$ marketing push for their new OS, and then submit your software (and maybe pay a modest fee), they would certify you as Windows compatible, and you'd be eligible for subsidizing on your advertising fees as long as you advertise your M$-compatibility.

    "Certified for Vista" - tested by M$. "Works with Vista" - tested by you.

    Windows Vista Software Logo Spec 1.1.doc has 3 sections:

    security and compatibility
    follow user account control guidelines, support x64 versions of vista, sign files and drivers, perform windows version checking, support concurrent user sesions, avoid running anything in safe mode, and follow anti-malware policies.
    • .exe's include a manifest that says to run as the invoker, at the highest available access, or requires administrator privileges. Nobody by special people get elevated privileges.
    • no 16-bit code is allowed
    • if you depend on drivers, x64 drivers must be available; 32-bit application code is ok.
    • binaries must be signed with an Authenticode certificate
    • drivers must be signed via WHQL or DRS
    • version check can't autofail on increased Windos version #'s, unless your EULA prohibits use on future OS'es. Use the version checking API, not the registry key everyone uses.
    • app must handle multiple users/sessions unless they can't. 3D apps are a good example; maybe they don't work over the remote desktop connection
    • if app can't handle multiple users, it must write a nice message, not fail silently
    • sound from one user session should not be heard by another user
    • applications must support "fast user switching"
    • installing software should not degrade the OS or other applications
    • must use Windows Installer (MSI) and do so correctly
    • don't assume the installing user will be the running user. User data should be written at first run, not during the install.
    • Applications should be install in "Program Files" or AppData by default
    • Software must be correctly identified in "Software Explorer" (i.e. Add/Remove Programs)
    • don't repackage and/or install Windows resources yourself
    • don't reboot during installation; be "restart manager aware"
    • support command line installation
    • pass a number of "Application Verifier" tests; get Application Verifier from www.microsoft.com/downloads/
    • Windows Error Reporting must not be disabled; handle only exceptions that you know and expect
    • sign up to receive your crash data
    installation
    reliability
    If M$ certifies you, you are legally allowed to use their logo on your box.

    GMPs and QSRs

    FDA tends to be picky about instruments that will be used on humans; a natural result of centuries of no regulation and many horrible deaths and maimings. Even with current regulations in place, FDA estimates that medical errors kill 100,000 Americans and injure another 1.3M each year. Woo hoo!

    Testing samples gave way to testing the manufacturing process and testing environment.

    GMP
    (current) Good Manufacturing Practice. not specific to software. documentation of every part of the process. Your food or drug can be 'adulterated' even if its not in violation of any specific regulatory requirement, if your process is not using cGMP.
    QSR
    Quality System Regulation. Needs a formal quality system and quality policy. It must be audited, an improvement cycle needs to be documented. A software development lifecycle model (from among well known standards) must be documented. Safety and risk management must be a documented part of the software process.

    Intro to DO-178B (thanks to JA-F)

    • Requirements for software development (planning, development, verification, configuration management, quality assurance)
    • 5 software levels, level A = failure critical, level E = no effect on safety
    • Level A (catastrophic) - failure would prevent safe flight and landing
    • Level B (major hazard) - failure would reduce the capability of the aircraft or crew (if software makes the users unsafe...the software is unsafe)
    • Level C (major) - pain, irritation, or injury, probably short of death
    • Level D (minor) - failure just makes more work for everyone
    • Level E (no effect)
    So... which category your software gets labeled determines how much testing, verification, validation, or proof gets applied to it. I hope the labeling is correct!

    Data Classification (CC1 and CC2) - what, you mean software certification includes certification of the data?! Well, we are used to some data being checked. Baselines, traceability, change control, change review, unauthorized change protection, release of information...

    How much independence is required during certification? Depending on your level, some objectives may require external measurement, some may require thorough internal (documented) measurement, and some may be left up to the discretion of the software developer (e.g. for level "E" stuff).

    DO-178B Required Software Verification:

    structural coverage testing
    test at the object code level. test every boolean condition.
    traceability
    requirements must be explicitly mapped to design must be explicitly mapped to code. 100% requirement coverage.

    How to be Certifiable

    There is "Microsoft certified" and "Cisco certified", which usually refers to passing an expensive test that covers a specific set of user tasks on a specific version of software... this is the kind of certification you'd expect to get from "Lake Washington Vocational Technical School".

    But...there is also the title: IEEE Computer Society Certified Software Development Professional and the forthcoming title: Certified Software Development Associate.

    Mostly, the big and expensive test may make you more marketable in a job search or as an independent software consultant. It is loosely inspired by the examination systems available for other engineering disciplines. It covers the SoftWare Engineering Body of Knowledge (SWEBOK), a big book that sort of says what should be covered in classes like CS 383/384. Any teacher of such a course has to pick and choose what they cover, and the test let's you fill in your gaps and prove that you are not just a Jeffery-product or UI-product, you know what the IEEE CS thinks you need to know.

    Project Status

    • How are we doing on integration of library and admin?
    • Algorithm team, thanks for moving stuff to test/
    • Can we please remove src/admin/test/ ?
    • What is l33t's l33t subdirectory, with nbproject, etc.? Explain or remove.
    • Time for two homeworks left: public alpha and final project turnin.

    Admin Team (java portion) Test Example

    • This one is about as simple as one can get (2 tests on 2 toy java files).
    • Like many teams, makefile assumes all tests and java files in same directory.
    • Srcs to be tested live in src/admin/stnapi
    • Split test/makefile into test/makefile and src/admin/stnapi/makefile
    • Add src/admin/makefile; have it cd into and call stnapi makefile
    • Fancypants makefile rules non-portable
      .SUFFIXES: .java .class
      .java.class:
      	$(JC) $(JFLAGS) $*.java
      
    • was &(JC) intended to read $(JC) ?
    • boo: someone's edit wrapped lines (broken storeinfo.java file!)
    • Packages: in order to work across our many directories, all our Java files need to declare what package they live in. The package generally consists of the directory structure relative to a directory on the classpath. Do we assume src/, so that we have package names like admin.stnapi, or do we go one level higher?
    • CLASSPATH - you sort of have a choice of putting it in your .bashrc or .cshrc or .profile or whatever, OR putting it in your makefiles. Pro of putting it in makefile is it is more explicit; con of doing so is it may be a platform dependence, unless we can manage to get it working using relative paths. For example, how can we guarantee junit lives at the same place on different machines? Option A: place junit.jar in the CVS repository (or in a directory accessible relative to CVS directories) and use relative paths in makefile. Option B: leave it up to programmers to set your CLASSPATH externally
    • java junit.textui.TestRunner getinfoTest
    • Todo:
      • actually write enough code to be worth testing
      • get rest of tests runnable from cmdline
      • actually test enough to be useful
      • merge tests into suite

    Project Status

    • Checkout HW#6
    • Weekend e-mails
    • End of semester projection. Do we pull the oars together, or do we deal with failure?

    Product Support

    For software, support implies technical assistance in using the software correctly and in fixing problems that occur. Some software engineering texts will have more to say on this topic than others; to my knowledge it is not a substantial focus in our Bruegge text. So, today's lecture consists mostly of my thoughts and (limited) experiences in this regard.

    Support for Using the Software

    What kinds of support have you seen for folks who just need to use the software?











    A lot of this is really about how long will it take (how much it will cost) to solve a problem. Humans timeout quickly, some more than others. If you give them the tools to fix the problem themselves, working on it immediately, they will probably be happier than if you make them wait for your fix.
    printed and online (noninteractive) manuals
    Manuals are out of style, but that is because as Negroponte would say, they are made out of atoms. The need for a good manual is very strong, proportional to the feature count of the software system.
    interactive tutorials
    Some of you criticized emacs' usability earlier this semester, but that's because your personal learning style didn't fit emacs' extensive online tutorial, or you never used the tutorial. Besides emacs, I learned UNIX shell programming, C programming, and EverQuest with the help of extensive interactive tutorials. The best tutorials test whether the material has been mastered, and report results or even adjust their content or exercises based on observed performance. Our semester project has, in places, interactive tutorial elements, but perhaps in order to get on the same page I should have forced all of us to go through some tutorials to get a feel for a variety of features in them.
    searchable help
    Besides being a hypertext form of the online manual, a help system usually has a search capability. Google is thus the world's largest help system, and if you get your manual searchable via google, you almost don't need to provide redundant internal capability. Almost.
    context sensitive help
    One area where google can't fulfill all your product support needs (yet) is in understanding the context of the question. To provide context to google one generally supplies additional keywords, but it doesn't really know which keywords are the search term and which are the context, it just searches for places where all the keywords show up in proximity.
    web or e-mail support
    we probably have all seen web forms that turn around and send an e-mail to the produt support team. One advantage of this method is that the team gets an electronic artifact that records the incident. A major deficiency of this method is, the user doesn't know (or may not feel) that they have been heard, and doesn't get an immediate answer. Sending an autoreply message let's them know that the system heard them, but doesn't guarantee a human will ever see their message, or care about them.
    online chat
    humans crave interactivity. if a user knows a human saw their plea for help they probably immediately will feel more hopeful and perhaps more emotionally prepared for whatever wait is needed.
    phone support
    the 45 minute wait on muzak might be tolerable if the phone support is good, but it is easy for this to go wrong.

    Fixing Problems that Occur

    How do you know a bug...is a bug? When a user doesn't get what they need, sometimes it is a bug, and sometimes not. Blue screens of death are not ambiguous, but if the user got the wrong answer, it might be human error rather than a bug to report. A human at the right point in the pipeline (to perform triage, work with the user to solve user problems and determine when a bug report should be filed) would be real helpful, but humans are expensive, especially smart humans. Is it better to do that than just treat all user problems as bug reports?

    Why has Dr. J failed to introduce bug trackers in this course?!! Because we haven't completed enough system integrated functionality to justify one yet? Because setup and administration of yet another system would impose an additional load on someone that Jeffery was not willing to ask for? Sorry, it would be useful for you to have exposure to one anyhow.

    Upward Bound Announcement

    Upward Bound Engineering Instructor Position Description
    Provides instruction and guidance in an academic project designed to expose
    students to their unique talents and engage students as active members in a
    challenging academic and socially rewarding educational process; works with
    UB personnel to develop an engaging, exciting and challenging academic
    project relating to Engineering; implements strategies to create a
    collaborative environment for culturally diverse high school students.
    
    MINIMUM QUALIFICATIONS
    
    Bachelor's degree in related field.
    Demonstrated teaching experience.
    Excellent verbal and written communication skills.
     **Employment will be contingent upon satisfactory completion of a criminal background investigation.**
    
    DESIRABLE QUALIFICATIONS
    
    Master's Degree in related field.
    Post-secondary teaching experience.
    Knowledge of interactive and/or innovative teaching techniques.
    Experience developing curriculum.
    Experience working with a culturally diverse high schools student population.
    Effective and relevant academic project idea.
    

    Project Status

    • Trevor's DataLoader.java; what else is new?
    • Does the dat/ directory exist (yes but empty)
    • Please create subdirs to parallel src/
    • Woops, src/datatype/fighter/man permissions
    • Why is library_station named library_station and not library?

    Bug Tracker Demo

    Let's go visit
    unicon.org for a look at one. Caveat: this demo is for the minority of you that have never looked at a bug tracking system before, it is not a particular positive example or role model.

    Famous bug tracking systems. You guys know more than I do about the currently-popular bug trackers. There are plenty of fancy commercial ones. There are popular open source ones. Check out this comparison chart. What I have mainly heard from you is that we should consider using Trac.

    Software Project Management

    I do not know why this came at this point in the schedule I was given, perhaps it should have been a CS 383 topic. Managing a software project includes:
    Project planning
    requirements (which we did study), estimation and scheduling (which we did not study much)
    Project monitoring and control
    how to keep the team and management up to date? how to stay on the same page in the face of changes?
    risk management
    measuring or assessing risk; developing strategies deal with risk. Strategies include: get someone else to take the risk, concluding the project is not worth the risk, reducing the negative effect of the risk, or being prepared to deal with what you see may come.
    software process
    We've under-discussed this aspect of SE. It is really all about what procedures or structure are imposed on the humans doing the software, in order for management to be able to have a chance of tracking the project and knowing what's going on .
    dealing with problems
    project managers, developers, and customers may introduce problems which affect the whole project in different ways.
    • If a project manager doesn't know how to ... motivate their team members, or
    • is so unrealistic in their estimation that the schedule is impossible, or
    • cannot deal with the conflict between schedule and quality concerns, it can kill a project.
    If developers
    • don't know or don't bother to learn the application domain they are asked to code for, or
    • don't bother to format or document their code or follow project standard procedures for testing and check-in, or
    • "panic/shutdown" under deadline pressure
    ... that can kill a project. If customers
    • keep changing requirements, or
    • don't have the funds to build what they need, or
    • don't have the time available that is necessary
    the project can fail.

    Project Management This Year

    It ain't over yet, but so far this year we have seen many issues related to project management. Some of these are inherent in the artificial university environment we are in, some are due to instructor or student character traits.
    • requirements that were fuzzy for an extended portion of the project duration
    • different team members reading common documentation and sitting in common discussions and hearing completely different answers
    • negative impacts of team members not perceiving there to be a real customer, or the customer not present enough
    • team members not bothering to study their application domain
    • team members not bothering to show up, or write code

    Experiences with Project Management

    • My Ph.D. advisor was running a small team, about a half-dozen at its largest. He was dictatorial. He did not just lead by giving orders or by verbal tirade though, he also led by doing many menial tasks for the team that he was unwilling to ask a student to do, because their time was too valuable. Respect your subordinates.
    • My own (==grant/research) projects have ranged in size from 1-15. As a manager I am constantly spread too thin. Some of my team members get this, and some don't.
    • Some team members are too independent, and some are too dependent. Too independent means: I don't know what they are doing. Too dependent means: they are basically trying to get me to do their job for them.
    • I repeatedly encounter a cycle that starts with quality concerns that need greater review and intervention on my part, so I tell students I have to look at, test and approve what they are doing, and then (ouch) I become the bottleneck in the project (very, very bad). So then I try to allow students enough autonomy to make forward progress, and then bug reports from my customer raise quality concerns, and...

    Experiences with Project Management, Cont'd

    • Managing other programmers is often said to be like herding cats. People-person skills are usually not taught in engineering colleges. It is not enough to be "nice", but sometimes that helps. I struggle with being too "nice". Some students or student employees will exploit that. Then they act surprised when they get fired from paid employment or get a lower grade than others in a class.
    • To inspire loyalty and hard work, you probably have to build a relationship with someone. It may not have to be a "we go to date movies" type of relationship, but they have to feel you listen and care about them. It is easier to do this with a paid employee than with a student in a class. Many students do Not like to hang out w/ profs.
    • Sometimes you have to "clear the air" with someone. There are some conflict resolution techniques that work better than others. Not threatening their reptile or mammalian brains, and making it clear that you are dependably honest and not manipulative, seems to help.
    • Some SE classes have been spectacularly more successful than others, despite the instructor/manager not being much smarter, and not doing all that much differently from semester to semester. Tools and processes may be the same, with way different outcomes. No wonder software project estimation and planning has such a poor track record!
    • Having good (== smart) people helps in some ways, but I have seen smart people who were liabilities (prima donnas, sociopaths, lazy web surfers)
    • Having teams where the folks really like each other helps a Lot. Having teams where everyone is pulling their weight helps a Lot.
    • I have seen teams with spectacular personality conflicts, sometimes related to personal differences. There can be team members who are much worse than merely "dead weight".

    Software Project Estimation

    I looked at websites for some of this material, in addition to consulting Roger S. Pressman's (and "Ted" Theodore Logan's) book on software engineering.
    • Historically, software was an insignificant % of the budget for a computer project. Moore's law has fixed that.
    • Big software cost estimate errors kill corporations, and someday countries.
    • Ways to be accurate: estimate after finished, estimate base done having done the same thing previously, decompose into estimatable subcomponents, use an (empirically validated?) model
    • Estimate based on size, in LOC or function points (FP)?
    • reason decomposing helps: "similar" projects are rare, but similar functions, classes, modules, data structures and algorithms are common
    • Example based on LOC: after careful decomposition, one gets an estimate that a software will take 33KLOC, that the organization writes 620LOC per person-month, and each month costs $8K. Then total cost is $431K and 54 months. (Pressman)
    • Example based on FP: after careful decomposition, the project has 320 FP, but weighted by difficulty it is adjusted to 375 FP. The organization averges 6.5 FP/month @ $8K, cost/FP is $1230 and total project cost is $461K and 58 months. (Pressman)

    COCOMO

    "you get there fast, and then you take it slow".

    Boehm's COnstructive COst MOdel.

    Count SLOC (yes declarations, no comments, no generated code, no test drivers)

    5 scale drivers:

    • precedentedness
    • development flexibility
    • architecture / risk resolution
    • team cohesion
    • process maturity
    Cost drivers: 17 parameters that assess not just the software to be developed, assess your environment and team as well.

    Effort = 2.94 * EAF * (KSLOC)E

    where EAF is an Effort Adjustment Factor derived from cost drivers, and E is an exponent derived from the 5 scale drivers. EAF defaults to 1 and E defaults to 1.0997

    Example: Average? 8KSLOC? Then effort = 2.94 * (1.0) * (8)1.0997 = 28.9 person-months

    Calculators:

    lecture 30 starts here

    Announcements

    • Dr. J will regrettably be unable to attend on Monday 4/21 due to a NASA workshop. I recommend that you go ahead and meet that day anyhow, and work on your project for Wednesday 4/23's turnin.
    • By the way, the chapter in the Brugge text that covers all this project management stuff is chapter 14; surprisingly, it is near the end of the book, just like the CS 384 schedule has it. Read Chapter 14.
    • Discussion of who hosts the chat server, and how the app should be told where to go for chat service.

    Project Scheduling

    Bruegge et al don't say a whole lot about project scheduling. In addition to what he does have to say in chapter 14, your assigned reading shall be this fine document which apparently originated in Gov. Schwarzeneggar's IT office.

    Dr. J's take on the scheduling thing (have to try this some time):

    • Make a task list, assign a time estimate to each task. For each task, define the milestone/deliverable that shows the task is complete. Rule of thumb: don't try to break things down finer than 1 week's effort; smaller than that and the planner/scheduler will spend the whole project just updating the charts continuously.
    • Identify the dependencies between task list items. Should end up with a partial ordering (no cycles). The more dependencies, the less parallelism and the harder it will be for more programmers to speed things up.
      (from Sommerville, 6ed)
      The labels here should correspond nicely to those in the task list; the task list effectly forms the glossary for interpreting the chart.
    • If you have a lone ranger, one-engineer project, the schedule identifies the milestones at which pieces are delivered for customer acceptance tests.
    • On multi-programmer projects, a primary goal is to parallelize to keep the whole engineering staff productive. Avoid keeping a $100K/yr. engineer waiting for others to finish their work.
    • The larger the project, the more difficult it is to keep everyone at work. Allow a lot of room actual times to differ from estimates, and be prepared to put people to work on backup tasks when their primary task is stalled waiting for another task to finish. In one's schedule, one can attempt to identify "slack" (blue parts of the bars)
      (from Sommerville, 6ed)
      Care should be used in interpreting slack in this chart, as the total slack along each path from start to finish is duplicated in each node on the path. For example, T4 and T8 are each shown with a lot of slack, but if T4 uses its slack, T8 will have none.

    lecture 31 starts here

    Personnel Issues