コード例 #1
0
def openFunctionCache( name ):
    if name in g.cursors:
        return g.cursors[ name ]
    else:
        debugPrint( 'opening', name, 'function cache database' )
        g.databases[ name ] = sqlite3.connect( getCacheFileName( name ) )
        g.cursors[ name ] = g.databases[ name ].cursor( )
        g.cursors[ name ].execute(
            '''CREATE TABLE IF NOT EXISTS cache( id TEXT PRIMARY KEY NOT NULL, value TEXT NOT NULL, precision INTEGER )'''
        )

        return g.cursors[ name ]
コード例 #2
0
    def isCompatible( self, other ):
        if isinstance( other, RPNUnits ):
            return self.getUnitTypes( ) == other.getUnitTypes( )
        elif isinstance( other, dict ):
            return self.getUnitTypes( ) == other
        elif isinstance( other, list ):
            result = True

            for item in other:
                result = self.isCompatible( item )

                if not result:
                    break

            return result
        elif isinstance( other, RPNMeasurement ):
            debugPrint( 'units: ', self.units, other.units )
            debugPrint( 'types: ', self.getUnitTypes( ), other.getUnitTypes( ) )
            debugPrint( 'dimensions: ', self.getDimensions( ), other.getDimensions( ) )

            if self.getUnitTypes( ) == other.getUnitTypes( ):
                return True
            elif self.getDimensions( ) == other.getDimensions( ):
                return True
            else:
                debugPrint( 'RPNMeasurement.isCompatible exiting with false...' )
                return False
        else:
            raise ValueError( 'RPNMeasurement or dict expected' )
コード例 #3
0
def getPartitionNumber( n ):
    '''
    This version is, um, less recursive than the original, which I've kept.
    The strategy is to create a list of the smaller partition numbers we need
    to calculate and then start calling them recursively, starting with the
    smallest.  This will minimize the number of recursions necessary, and in
    combination with caching values, will calculate practically any integer
    partition without the risk of a stack overflow.

    I can't help but think this is still grossly inefficient compared to what's
    possible.  It seems that using this algorithm, calculating any integer
    partition ends up necessitating calculating the integer partitions of
    every integer smaller than the original argument.
    '''
    debugPrint( 'partition', int( n ) )
    if real_int( n ) < 0:
        raise ValueError( 'non-negative argument expected' )
    elif n in ( 0, 1 ):
        return 1

    sign = 1
    i = 1
    k = 1

    estimate = log10( fdiv( power( e, fmul( pi, sqrt( fdiv( fmul( 2, n ), 3 ) ) ) ),
                            fprod( [ 4, n, sqrt( 3 ) ] ) ) )
    if mp.dps < estimate + 5:
        mp.dps = estimate + 5

    partitionList = [ ]
    signList = [ ]

    while n - k >= 0:
        partitionList.append( ( fsub( n, k ), sign ) )
        i += 1

        if i % 2:
            sign *= -1

        k = getNthGeneralizedPolygonalNumber( i, 5 )

    partitionList = partitionList[ : : -1 ]

    total = 0

    for partition, sign in partitionList:
        total = fadd( total, fmul( sign, getPartitionNumber( partition ) ) )

    return total
コード例 #4
0
def flushDirtyCaches( ):
    for name in g.dirtyCaches:
        saveOperatorCache( g.operatorCaches[ name ], name )

    g.dirtyCaches.clear( )

    if g.factorCacheIsDirty:
        saveFactorCache( )

    for name in g.dirtyCaches:
        debugPrint( 'flushing the', name, 'pickle cache' )
        saveOperatorCache( g.operatorCaches[ name ], name )

    for name in g.databases:
        debugPrint( 'closing the', name, 'function cache database' )
        g.databases[ name ].close( )
コード例 #5
0
def evaluateDiceExpression( args, sumIfPossible=True ):
    result = [ ]

    for diceCount, diceValue, dropLowestCount, dropHighestCount, modifier in args:
        if dropLowestCount == 0 and dropHighestCount == 0:
            if sumIfPossible:
                result = [ 0 ]

                for i in range( 0, diceCount ):
                    result[ 0 ] += ( randrange( diceValue ) + 1 )
            else:
                for i in range( 0, diceCount ):
                    result.append( randrange( diceValue ) + 1 )
        else:
            dice = [ ]

            for i in range( 0, diceCount ):
                dice.append( randrange( diceValue ) + 1 )

            dice.sort( )
            debugPrint( 'dice', dice )

            if dropHighestCount > 0:
                debugPrint( 'drop', dice[ dropLowestCount : -dropHighestCount ] )
                result.extend( dice[ dropLowestCount : -dropHighestCount ] )
            else:
                debugPrint( 'drop', dice[ dropLowestCount : ] )
                result.extend( dice[ dropLowestCount : ] )

    return result, modifier
コード例 #6
0
ファイル: rpnDice.py プロジェクト: flawr/rpn
def evaluateDiceExpression( args ):
    result = 0

    for diceCount, diceValue, dropLowestCount, dropHighestCount, modifier in args:
        if dropLowestCount == 0 and dropHighestCount == 0:
            for i in range( 0, diceCount ):
                result += randrange( diceValue ) + 1
        else:
            dice = [ ]

            for i in range( 0, diceCount ):
                dice.append( randrange( diceValue ) + 1 )

            dice.sort( )
            debugPrint( 'dice', dice )

            if dropHighestCount > 0:
                debugPrint( 'drop', dice[ dropLowestCount : -dropHighestCount ] )
                result += sum( dice[ dropLowestCount : -dropHighestCount ] )
            else:
                debugPrint( 'drop', dice[ dropLowestCount : ] )
                result += sum( dice[ dropLowestCount : ] )

        result += modifier

    return result
コード例 #7
0
    def getReduced( self ):
        debugPrint( 'getReduced 1:', self, [ ( i, self.units[ i ] ) for i in self.units ] )
        if not g.unitConversionMatrix:
            loadUnitConversionMatrix( )

        value = self.value
        units = RPNUnits( )

        debugPrint( 'value', value )

        for unit in self.units:
            newUnit = g.basicUnitTypes[ getUnitType( unit ) ].baseUnit
            debugPrint( 'unit', unit, 'newUnit', newUnit )

            if unit != newUnit:
                value = fmul( value, power( mpf( g.unitConversionMatrix[ ( unit, newUnit ) ] ), self.units[ unit ] ) )

            units.update( RPNUnits( g.unitOperators[ newUnit ].representation + "^" + str( self.units[ unit ] ) ) )
            debugPrint( 'value', value )

        reduced = RPNMeasurement( value, units )
        debugPrint( 'getReduced 2:', reduced )
        return reduced
コード例 #8
0
def convertUnits( unit1, unit2 ):
    if isinstance( unit1, RPNGenerator ):
        unit1 = list( unit1 )

        if len( unit1 ) == 1:
            unit1 = unit1[ 0 ]

    if isinstance( unit2, RPNGenerator ):
        unit2 = list( unit2 )

        if len( unit2 ) == 1:
            unit2 = unit2[ 0 ]

    if isinstance( unit1, list ):
        result = [ ]

        for unit in unit1:
            result.append( convertUnits( unit, unit2 ) )

        return result

    if not isinstance( unit1, RPNMeasurement ):
        raise ValueError( 'cannot convert non-measurements' )

    if isinstance( unit2, list ):
        return unit1.convertValue( unit2 )
    elif isinstance( unit2, str ):
        measurement = RPNMeasurement( 1, { unit2 : 1 } )
        return RPNMeasurement( unit1.convertValue( measurement ), unit2 )
    elif not isinstance( unit2, RPNMeasurement ):
        raise ValueError( 'cannot convert non-measurements' )
    else:
        debugPrint( 'convertUnits' )
        debugPrint( 'unit1:', unit1.getUnitTypes( ) )
        debugPrint( 'unit2:', unit2.getUnitTypes( ) )

        return RPNMeasurement( unit1.convertValue( unit2 ), unit2.getUnits( ),
                               unit2.getUnitName( ), unit2.getPluralUnitName( ) )
コード例 #9
0
    def convertValue( self, other, tryReverse=True ):
        if self.isEquivalent( other ):
            return self.getValue( )

        if self.isCompatible( other ):
            conversions = [ ]

            if isinstance( other, list ):
                result = [ ]
                source = self

                for count, measurement in enumerate( other ):
                    with extradps( 1 ):
                        conversion = source.convertValue( measurement )

                    if count < len( other ) - 1:
                        result.append( RPNMeasurement( floor( conversion ), measurement.getUnits( ) ) )
                        source = RPNMeasurement( chop( frac( conversion ) ), measurement.getUnits( ) )
                    else:
                        result.append( RPNMeasurement( conversion, measurement.getUnits( ) ) )

                return result

            units1 = self.getUnits( )
            units2 = other.getUnits( )

            unit1String = units1.getUnitString( )
            unit2String = units2.getUnitString( )

            debugPrint( 'unit1String: ', unit1String )
            debugPrint( 'unit2String: ', unit2String )

            if unit1String == unit2String:
                return fmul( self.getValue( ), other.getValue( ) )

            if unit1String in g.operatorAliases:
                unit1String = g.operatorAliases[ unit1String ]

            if unit2String in g.operatorAliases:
                unit2String = g.operatorAliases[ unit2String ]

            exponents = { }

            if not g.unitConversionMatrix:
                loadUnitConversionMatrix( )

            # look for a straight-up conversion
            unit1NoStar = unit1String.replace( '*', '-' )
            unit2NoStar = unit2String.replace( '*', '-' )

            debugPrint( 'unit1NoStar: ', unit1NoStar )
            debugPrint( 'unit2NoStar: ', unit2NoStar )

            if ( unit1NoStar, unit2NoStar ) in g.unitConversionMatrix:
                value = fmul( self.value, mpmathify( g.unitConversionMatrix[ ( unit1NoStar, unit2NoStar ) ] ) )
            elif ( unit1NoStar, unit2NoStar ) in specialUnitConversionMatrix:
                value = specialUnitConversionMatrix[ ( unit1NoStar, unit2NoStar ) ]( self.value )
            else:
                # otherwise, we need to figure out how to do the conversion
                conversionValue = mpmathify( 1 )

                # if that isn't found, then we need to do the hard work and break the units down
                newUnits1 = RPNUnits( )

                for unit in units1:
                    newUnits1.update( RPNUnits( g.unitOperators[ unit ].representation + "^" +
                                                str( units1[ unit ] ) ) )

                newUnits2 = RPNUnits( )

                for unit in units2:
                    newUnits2.update( RPNUnits( g.unitOperators[ unit ].representation + "^" +
                                                str( units2[ unit ] ) ) )

                debugPrint( 'units1:', units1 )
                debugPrint( 'units2:', units2 )
                debugPrint( 'newUnits1:', newUnits1 )
                debugPrint( 'newUnits2:', newUnits2 )

                debugPrint( )
                debugPrint( 'iterating through units:' )

                for unit1 in newUnits1:
                    foundConversion = False

                    for unit2 in newUnits2:
                        debugPrint( 'units 1:', unit1, newUnits1[ unit1 ], getUnitType( unit1 ) )
                        debugPrint( 'units 2:', unit2, newUnits2[ unit2 ], getUnitType( unit2 ) )

                        if getUnitType( unit1 ) == getUnitType( unit2 ):
                            conversions.append( [ unit1, unit2 ] )
                            exponents[ ( unit1, unit2 ) ] = units1[ unit1 ]
                            foundConversion = True
                            break

                    if not foundConversion:
                        debugPrint( 'didn\'t find a conversion, try reducing' )
                        reduced = self.getReduced( )

                        debugPrint( 'reduced:', self.units, 'becomes', reduced.units )

                        reducedOther = other.getReduced( )

                        debugPrint( 'reduced other:', other.units, 'becomes', reducedOther.units )

                        # check to see if reducing did anything and bail if it didn't... bail out
                        if ( reduced.units == self.units ) and ( reducedOther.units == other.units ):
                            break

                        reduced = reduced.convertValue( reducedOther )
                        return RPNMeasurement( fdiv( reduced, reducedOther.value ), reducedOther.getUnits( ) ).getValue( )

                debugPrint( )

                value = conversionValue

                if not foundConversion:
                    # This is a cheat.  The conversion logic has flaws, but if it's possible to do the
                    # conversion in the opposite direction, then we can do that and return the reciprocal.
                    # This allows more conversions without fixing the underlying problems, which will
                    # require some redesign.
                    if tryReverse:
                        return fdiv( 1, other.convertValue( self, False ) )
                    else:
                        raise ValueError( 'unable to convert ' + self.getUnitString( ) +
                                          ' to ' + other.getUnitString( ) )

                for conversion in conversions:
                    if conversion[ 0 ] == conversion[ 1 ]:
                        continue  # no conversion needed

                    debugPrint( 'unit conversion:', g.unitConversionMatrix[ tuple( conversion ) ] )
                    debugPrint( 'exponents', exponents )

                    conversionValue = mpmathify( g.unitConversionMatrix[ tuple( conversion ) ] )
                    conversionValue = power( conversionValue, exponents[ tuple( conversion ) ] )
                    debugPrint( 'conversion: ', conversion, conversionValue )

                    value = fmul( value, conversionValue )

                value = fmul( self.value, value )

            return value
        else:
            if isinstance( other, list ):
                otherUnit = '[ ' + ', '.join( [ unit.getUnitString( ) for unit in other ] ) + ' ]'
            else:
                otherUnit = other.getUnitString( )

            raise ValueError( 'incompatible units cannot be converted: ' + self.getUnitString( ) +
                              ' and ' + otherUnit )
コード例 #10
0
def parseDiceExpression( arg ):
    counter = Counter( arg )

    if ( counter[ 'a' ] > 1 ):
        raise ValueError( 'dice expressions can only contain a single \'x\'' )

    if ( counter[ 'h' ] > 1 ):
        raise ValueError( 'dice expressions can only contain a single \'h\'' )

    if ( counter[ '+' ] > 1 ):
        raise ValueError( 'dice expressions can only contain a single \'+\'' )

    if ( counter[ '-' ] > 1 ):
        raise ValueError( 'dice expressions can only contain a single \'-\'' )

    if ( counter[ '+' ] + counter[ '-' ] > 1 ):
        raise ValueError( 'dice expressions can only have a single modifier (\'+\' or \'-\')' )

    import re
    expressions = re.split( ',', arg )

    result = [ ]

    for expr in expressions:
        pieces = re.split( '([dhx+-])', expr )

        debugPrint( 'pieces', pieces )

        diceValue = 0
        diceCount = 0
        dropLowestCount = 0
        dropHighestCount = 0
        modifier = 0

        defaultState = 0
        diceValueState = 1
        dropLowestCountState = 2
        dropHighestCountState = 3
        plusModifierState = 4
        minusModifierState = 5

        state = defaultState

        for piece in pieces:
            if state == defaultState:
                if piece == 'd':
                    state = diceValueState
                elif piece == 'x':
                    state = dropLowestCountState
                elif piece == 'h':
                    state = dropHighestCountState
                elif piece == '-':
                    state = minusModifierState
                elif piece == '+':
                    state = plusModifierState
                else:
                    if piece == '':
                        diceCount = 1
                    else:
                        diceCount = int( piece )
            elif state == diceValueState:
                diceValue = int( piece )

                if ( diceValue < 2 ):
                    raise ValueError( 'dice value must be greater than 1' )

                state = defaultState
            elif state == dropLowestCountState:
                if piece == '':
                    dropLowestCount = 1
                else:
                    dropLowestCount = int( piece )

                if ( dropLowestCount < 1 ):
                    raise ValueError( 'drop lowest count must be positive' )

                state = defaultState
            elif state == dropHighestCountState:
                if piece == '':
                    dropHighestCount = 1
                else:
                    dropHighestCount = int( piece )

                if ( dropHighestCount < 1 ):
                    raise ValueError( 'drop highest count must be positive' )

            elif state == plusModifierState:
                if piece == '':
                    modifier = 1
                else:
                    modifier = int( piece )

                state = defaultState
            elif state == minusModifierState:
                if piece == '':
                    modifier = -1
                else:
                    modifier = -int( piece )

                state = defaultState

        if diceCount == 0:
            diceCount = 1

        if dropLowestCount != 0 and diceValue == 0:
            raise ValueError( 'dice expression requires \'d\' if \'x\' is used' )

        if dropHighestCount != 0 and diceValue == 0:
            raise ValueError( 'dice expression requires \'d\' if \'h\' is used' )

        if ( dropLowestCount + dropHighestCount ) >= diceCount:
            raise ValueError( 'this dice expression is dropping as many or more dice than are being rolled' )

        debugPrint( 'expression', expr )
        debugPrint( 'diceCount', diceCount )
        debugPrint( 'diceValue', diceValue )
        debugPrint( 'dropLowestCount', dropLowestCount )
        debugPrint( 'dropHighestCount', dropHighestCount )
        debugPrint( 'modifier', modifier )

        result.append( ( diceCount, diceValue, dropLowestCount, dropHighestCount, modifier ) )

    return result
コード例 #11
0
ファイル: rpnDice.py プロジェクト: flawr/rpn
def parseDiceExpression( arg ):
    import re
    expressions = re.split( ',', arg )

    result = [ ]

    for expr in expressions:
        pieces = re.split( '([dhx+-])', expr )

        debugPrint( 'pieces', pieces )

        diceValue = 0
        diceCount = 0
        dropLowestCount = 0
        dropHighestCount = 0
        modifier = 0

        defaultState = 0
        diceValueState = 1
        dropLowestCountState = 2
        dropHighestCountState = 3
        plusModifierState = 4
        minusModifierState = 5

        state = defaultState

        for piece in pieces:
            if state == defaultState:
                if piece == 'd':
                    state = diceValueState
                elif piece == 'x':
                    state = dropLowestCountState
                elif piece == 'h':
                    state = dropHighestCountState
                elif piece == '-':
                    state = minusModifierState
                elif piece == '+':
                    state = plusModifierState
                else:
                    if piece == '':
                        diceCount = 1
                    else:
                        diceCount = int( piece )
            elif state == diceValueState:
                diceValue = int( piece )

                if ( diceValue < 2 ):
                    raise ValueError( 'dice value must be greater than 1' )

                state = defaultState
            elif state == dropLowestCountState:
                if piece == '':
                    dropLowestCount = 1
                else:
                    dropLowestCount = int( piece )

                if ( dropLowestCount < 0 ):
                    raise ValueError( 'drop lowest count must be non-negative' )

                state = defaultState
            elif state == dropHighestCountState:
                if piece == '':
                    dropHighestCount = 1
                else:
                    dropHighestCount = int( piece )
            elif state == plusModifierState:
                if piece == '':
                    modifier = 1
                else:
                    modifier = int( piece )

                state = defaultState
            elif state == minusModifierState:
                if piece == '':
                    modifier = -1
                else:
                    modifier = -int( piece )

                state = defaultState

        # trailing x means drop count is 1
        if state == dropLowestCountState:
            dropLowestCount = 1
        elif state == dropHighestCountState:
            dropHighestCount = 1

        if diceCount == 0:
            diceCount = 1

        if dropLowestCount != 0 and diceValue == 0:
            raise ValueError( 'dice expression requires \'d\' if \'x\' is used' )

        if dropHighestCount != 0 and diceValue == 0:
            raise ValueError( 'dice expression requires \'d\' if \'h\' is used' )

        if dropLowestCount >= diceCount:
            raise ValueError( 'drop lowest count \'x\' cannot be greater than or equal to dice count \'d\'' )

        if dropHighestCount >= diceCount:
            raise ValueError( 'drop highest count \'h\' cannot be greater than or equal to dice count \'d\'' )

        debugPrint( 'expression', expr )
        debugPrint( 'diceCount', diceCount )
        debugPrint( 'diceValue', diceValue )
        debugPrint( 'dropLowestCount', dropLowestCount )
        debugPrint( 'dropHighestCount', dropHighestCount )
        debugPrint( 'modifier', modifier )

        result.append( ( diceCount, diceValue, dropLowestCount, dropHighestCount, modifier ) )

    return result