COCOMO - appropriate for languages like Python?

Andrae Muys amuys at shortech.com.au
Mon Jul 8 01:41:15 EDT 2002


Skip Montanaro <skip at pobox.com> wrote in message news:<mailman.1025982488.10814.python-list at python.org>...
> For example, in C I can write
> 
>     if ((c = gets(s)) == EOF) {
>         ...
>     }
> 
> while in Python, even though I have to express that concept in two lines:
> 
>     s = sys.stdin.readline()
>     if s == "":
>         ...
> 
> you can argue the Python code is less likely to contain a bug.  Together,
> the cost to create those two (fully debugged) lines of Python code may well
> be less than the cost to create the one line of C code, not twice the cost
> of the one line of C code, as COCOMO would estimate it.

Of course you can argue that the Python code is definately less likely
to contain a bug, as you can reasonably argue that the C code most
definately does ;)

Hint:  Do-not use gets()!!!

#include "buffer.h"  /* Handles char* buffers, includes BUFFER_SIZE */
#include "list.h"    /* Standard Linked List impl, used for vector 
                        scatter gather on input */
#include <stdio.h>
#include <stdlib.h>

char *readline(FILE *in) {
    List *buffers = newList();
    List *currBuffer = buffers;
    List *prevBuffer = NULL;
    int totalLength = 0;
    char *result = NULL;
    char *head = NULL;

    buffers->data = newBuffer(BUFFER_SIZE);
    buffers->data[0] = '\0';

    while (fgets(currBuffer->data, BUFFER_SIZE, in) != NULL) {
        totalLength += strlen(currBuffer->data);
        if (currBuffer->data[strlen(currBuffer->data) - 1] == '\n') {
            break;
        }
        currBuffer->next = newList();
        currBuffer = currBuffer->next;
        currBuffer->data = newBuffer(BUFFER_SIZE);
    }

    if (buffers->data[0] == '\0') {
        return NULL;
    }
    result = newBuffer(totalLength + 1);
    head = result;
    currBuffer = buffers;
    
    while (currBuffer != NULL) {
        strcpy(head, currBuffer->data);
        head = head + strlen(currBuffer->data);

        prevBuffer = currBuffer;
        currBuffer = currBuffer->next;
        delBuffer(prevBuffer->data);
        delList(prevBuffer);
    }

    return result;
}

if ((s = readline(stdin)) == NULL) {
    ...
}

So the actual C code equivalent is ~30 lines (I personally prefer to
include whitespace) compared to 2.  So a 15:1 cost factor is suddenly
more reasonable.  Note I haven't even attempted to compile the
readline() function, and it assumes the existence of suitable
buffer/list libraries (and accompaning logging/error functionality,
readline() will be longer if error-recovery is required).

However the really important thing to notice is that the language has
very little to do with the number of lines.  In fact for this trivial
example C and python are equivelent in almost all meaningful measures
once you have access to a decent IO library!

This agrees with my personal experience and annocdotal evidence, that
the libraries and frameworks used are at least as important as the
language itself when determining programmer productivity.  Hence the
signifigant impact of Python's 'Batteries-included' approach (and I
personally believe a signifigant part of the continued success of Perl
courtesy of CPAN).

Andrae Muys



More information about the Python-list mailing list