capabilities.py :  » Project-Management » Jest » jest-2.0.0b8 » libjest » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Project Management » Jest 
Jest » jest 2.0.0b8 » libjest » capabilities.py
#Copyright 2009 Brian Jaress
#brian_jaress@gna.org

#This file is part of Jest.
#
#Jest is free software; you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation; either version 3 of the License, or
#(at your option) any later version.
#
#Jest is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""COCOMO II estimation

This is an implementation of the COCOMO II estimation formulas for
software projects.  The formulas relate the size of the project, in
lines of code, to the time it takes and number of people.

The formulas also take into account ratings for different situational
and individual factors, such as how well the team gets along.  These
ratings are optional, and the default of 'normal' is usually
appropriate.
"""

from operator import mul
from itertools import chain

__all__ = ['Capabilities', 'RATING_LIST', 'AREA_TABLE', 'TIME_UNIT_LIST']

RATING_LIST = [
    'extra-easy',
    'very-easy',
    'easy',
    'normal',
    'hard',
    'very-hard',
    'extra-hard'
    ]

RATING_TABLE = dict((rating, idx) for idx, rating
        in enumerate(RATING_LIST))

def look_up(table, area, rating):
    """Find the constant associated with a particular rating in a
    particular area."""
    return table[area][0][RATING_TABLE[rating]]
def look_up_all(table, area_ratings):
    """Look up ratings in multiple areas at once."""
    return [look_up(table, area, area_ratings.get(area, 'normal'))
            for area in table.keys()]

#Areas that affect the exponent
CRITICAL_AREA_TABLE = {
    'precedent':   ([0, 1.24, 2.48, 3.72, 4.96, 6.20, 6.20],
        'Similar past work, existing studies of the problem, etc.'),
    'flexibility': ([0, 1.01, 2.03, 3.04, 4.05, 5.07, 5.07],
        'Flexibility of the requirements'),
    'risk':        ([0, 1.41, 2.83, 4.24, 5.65, 7.07, 7.07],
        'How well the risks have been studied and planned for'),
    'team':        ([0, 1.10, 2.19, 3.29, 4.38, 5.48, 5.48],
        'How well everyone involved gets along'),
    'process':     ([0, 1.56, 3.12, 4.68, 6.24, 7.80, 7.80],
        "The quality of your official development policies.")
    }

#Areas that affect the coefficient
RELEVANT_AREA_TABLE = {
    'reliability':            ([0.82, 0.82, 0.92, 1.00, 1.10, 1.26, 1.26],
        'Required reliability of the program'),
    'data':                   ([0.90, 0.90, 0.90, 1.00, 1.14, 1.28, 1.28],
        'Size of dataset'),
    'documentation':          ([0.81, 0.81, 0.91, 1.00, 1.11, 1.23, 1.23],
        'Percentage of time spent writing documentation'),
    'complexity':             ([0.73, 0.73, 0.87, 1.00, 1.17, 1.34, 1.74],
        'Complexity of the problem'),
    'reusability':            ([0.95, 0.95, 0.95, 1.00, 1.07, 1.15, 1.24],
        'Required reusability of the code'),
    'speed':                  ([1.00, 1.00, 1.00, 1.00, 1.11, 1.29, 1.63],
        'How fast the program has to be'),
    'memory':                 ([1.00, 1.00, 1.00, 1.00, 1.05, 1.17, 1.46],
        'How tight the memory usage requirements are'),
    'platform-volatility':    ([0.87, 0.87, 0.87, 1.00, 1.15, 1.30, 1.30],
        'Rate of change in the platform under the program'),
    'analyst':                ([0.71, 0.71, 0.85, 1.00, 1.19, 1.42, 1.42],
        'Analyst skill level, not including experience'),
    'application-experience': ([0.81, 0.81, 0.88, 1.00, 1.10, 1.22, 1.22],
        'Team experience with similar applications'),
    'programmer':             ([0.76, 0.76, 0.88, 1.00, 1.15, 1.34, 1.34],
        'Programmer skill level, not including experience'),
    'platform-experience':    ([0.85, 0.85, 0.91, 1.00, 1.09, 1.19, 1.19],
        'Team experience with platform'),
    'language-experience':    ([0.84, 0.84, 0.91, 1.00, 1.09, 1.20, 1.20],
        'Language and tool experience'),
    'turnover':               ([0.81, 0.81, 0.90, 1.00, 1.12, 1.29, 1.29],
        'People leaving'),
    'tools':                  ([0.78, 0.78, 0.90, 1.00, 1.09, 1.17, 1.17],
        'Tool and language capability'),
    'collaboration':          ([0.80, 0.86, 0.93, 1.00, 1.09, 1.22, 1.22],
        'Physical proximity and communication methods of team members')
    }

AREA_TABLE = dict((key, val[1]) for key, val in chain(
    CRITICAL_AREA_TABLE.iteritems(), RELEVANT_AREA_TABLE.iteritems()))

#COCOMO II constants
CRITICAL_MIN = .91
CRITICAL_CALIBRATION = 0.01
RELEVANT_CALIBRATION = 2.94
TIME_COEFFICIENT = 3.67
TIME_EXP_MIN = 0.28
TIME_EXP_CALIBRATION = 0.2

def seq(init, *funcs):
    """Simple function composition.

    Functions will be applied in order from left to right."""
    return reduce(lambda x, f: f(x), funcs, init)

class Capabilities():
    """The ability of your team to do work.

    We don't include schedule pressure.  The results are what you'd
    get from standard COCOMO II using a schedule of "Nominal" (normal).
    """

    def __init__(self, **area_ratings):
        """Store aggregates of the ratings."""
        self.exp = CRITICAL_MIN + CRITICAL_CALIBRATION * sum(
                look_up_all(CRITICAL_AREA_TABLE, area_ratings))
        self.coef = RELEVANT_CALIBRATION * reduce(mul,
                look_up_all(RELEVANT_AREA_TABLE, area_ratings),
                1.0)
        self.time_exp = TIME_EXP_MIN + TIME_EXP_CALIBRATION * (
                self.exp - CRITICAL_MIN)

    def lines_to_time(self, lines):
        """Typical COCOMO II calculation."""
        return seq(lines,
                self._lines_to_effort,
                self._effort_to_time)

    def time_to_lines(self, months):
        """Default calculation (inverse of typical)."""
        return seq(months,
                self._time_to_effort,
                self._effort_to_lines)

    def lines_to_people(self, lines):
        """Typical COCOMO II staff estimation."""
        return seq(lines,
                self._lines_to_effort,
                self._effort_to_people)
    def time_to_people(self, months):
        """Default staff estimation."""
        return seq(months,
                self._time_to_effort,
                self._effort_to_people)

    def _lines_to_effort(self, lines):
        """COCOMO II effort formula."""
        ksloc = lines / (10. ** 3)
        return self.coef * ksloc ** self.exp

    def _effort_to_lines(self, person_months):
        """Reverse of COCOMO II effort formula."""
        ksloc =  (person_months / self.coef)**(1/self.exp)
        return ksloc * (10. ** 3)

    def _effort_to_time(self, person_months):
        """COCOMO II time formula."""
        return TIME_COEFFICIENT * person_months ** self.time_exp

    def _time_to_effort(self, months):
        """Reverse of COCOMO II time formula."""
        return (months / TIME_COEFFICIENT)**(1/self.time_exp)

    def _effort_to_people(self, person_months):
        """COCOMO II staff formula."""
        try:
            return person_months / self._effort_to_time(person_months)
        except (ZeroDivisionError):
            #If nothing needs to be done, no one needs to do it.
            return 0
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.