Python - Working With Numeric Values

Applies to TestComplete 15.47, last modified on January 20, 2023

This topic contains information on handling numeric data type values and provides examples in the following sections:

Basics

Numeric values can be of integer and floating-point types. The TestComplete scripting engine does not distinguish floating-point and integer data types, so a variable can have a value of both types.

An integer value can accept zero, positive and negative numbers within the range ±1.7976931348623157x10^308. Generally, an integer number is considered to be in decimal numeration, however the octal or hexadecimal representation is also possible.

Octal and hexadecimal numbers can be negative, but cannot be written in the exponential form or have a fractional part.

An integer is treated as octal, if it is prefixed with 0o and contains digits from 0 to 7. For instance, 061 is an equivalent to decimal 49. An integer is treated as hexadecimal if it is prefixed with zero followed by the letter "x" (uppercase or lowercase) and contains digits from 0 to 9 or letters from A to F (uppercase or lowercase). The letters from A to F are used to represent numbers from 10 to 15. For instance, 0xff is an equivalent to decimal 255 and OX5EA is an equivalent to decimal 1514.

Floating-point numbers have a fractional part that can be as small as ±5x10^-324. Generally, the fractional part is separated by the decimal point character. For example, 123.456. Another possible notation for a floating point value is scientific or exponential notation. In this notation, the exponent symbol "e" means "ten to the power of". For example, 37e2 is a scientific notation for 3700.

The aqConvert and aqString objects contain several methods that can be helpful when dealing with numerical values. The tables below list those methods. The objects are available for all supported scripting languages, so you can use them to work with date values regardless of the chosen language.

Method Description
FloatToStr Converts a floating-point value to a string.
Format FormatConverts a floating-point value to a string using format specifiers.
IntToStr Converts the given number to a string.
StrToFloat Converts the specified string to a floating-point value.
StrToInt Converts the specified string to an integer value.
StrToInt64 Converts the specified string to a long integer value.

To perform mathematical operations with numbers, Python has its own inherent object Math. The object contains properties and methods that correspond to some frequently used constants and mathematical operations. The table below lists the properties and methods available in Python.

Property Description
e Returns the mathematical constant e, the base of natural logarithms. Approximately equal to 2.718.
pi Returns the ratio of the circumference of a circle to its diameter. Approximately equal to 3.14159.
Method Description
abs(x) The absolute value of x.
acos(x) Returns the arc cosine of x, in radians.
asin(x) Returns the arc sine of x, in radians.
atan(x) Returns the arc tangent of x, in radians.
atan2(y, x) Returns atan(y / x), in radians.
ceil(x) The ceiling of x.
choice(seq) A random item from a list, tuple, or string.
cmp(x, y) -1 if x < y, 0 if x == y, or 1 if x > y
cos(x) Returns the cosine of x in radians.
degrees(x) Converts angle x from radians to degrees.
exp(x) The exponential of x.
fabs(x) The absolute value of x.
floor(x) The floor of x.
hypot(x, y) Returns the Euclidean norm, sqrt(x*x + y*y).
log(x) The natural logarithm of x, for x> 0.
log10(x) The base-10 logarithm of x for x> 0.
max(x1, x2,...) The largest of arguments.
min(x1, x2,...) The smallest of arguments.
modf(x) The fractional and integer parts of x in a two-item tuple. Both parts have the same sign as x. The integer part is returned as a float.
pow(x, y) The value of x**y.
radians(x) Converts angle x from degrees to radians.
random() A random float r, above 0 and below 1.
randrange ([start,] stop [,step]) A randomly selected element from range(start, stop, step)
round(x [,n]) x rounded to n digits from the decimal point.
seed([x]) Sets the integer starting value used in generating random numbers. Call this function before calling any other random module function. Returns None.
shuffle(lst) Randomizes the items of a list. Returns None.
sin(x) The sine of x radians.
sqrt(x) The square root of x for x > 0
tan(x) The tangent of x radians.
uniform(x, y) A random float r, above x and below y.

Language-Specific Operations

Python also has additional arithmetic operations:

Modulus (%) Calculates the remainder of the division and is only concerned with the resulting remainder after division is performed on two operands. If the operands are floating point numbers, then they are rounded to an integer.
Increment (+=x) Adds x to the operand.
Decrement (-=x) Subtracts x from the operand.
Flood division (//) A division operand that always returns an integer.
Exponent (**) Exponential calculation of operators.

The sample code below demonstrates how to use them:

Python

def PythonOperators():
  aVar=7

  #Modulo
  Log.Message(7%3)    #Posts 1
  Log.Message(6%3)    #Posts 0
  Log.Message(59%10)  #Posts 9
  #Exponential
  Log.Message(15**3) #Posts 3375
  #Increment
  aVar+=1
  Log.Message(aVar)   #Posts 8
  #Decrement
  aVar-=1
  Log.Message(aVar) #Posts 7
  #Floor division
  Log.Message(aVar//3)  #Posts 2

Rounding Off

Python has three routines that can be used for rounding. These routines are: floor, ceil and round.

The floor routine always returns a value that is smaller than the input value, or, in other words, it rounds down the input value. It does not distinguish between positive and negative input. That is, for 0.5 the routine will return 0, and for -0.5 it will return -1.

The ceil routine is similar to floor, but it always returns a value that is greater than the input value, or, in other words, it rounds up the input value. Like the former routine, it does not distinguish between positive and negative input. For 0.5 the routine will return 1, and for -0.5 it will return 0.

The round routine implements the most common method of rounding, which is also known as symmetric arithmetic rounding. It returns the nearest integer that corresponds to the given floating-point value. If the fractional part of an input value is equal to or greater than 0.5, then the resulting integer is greater than the input value. Otherwise, the result is less than the input value. This rule applies both to positive and negative numbers, however, for negative numbers, absolute values are used instead of the actual input values. That is, for 0.4 the routine will return 0, for 0.5 it will return 1, and for -0.5 it will return -1.

Note: Due to the way floats are represented, the result may be inconsistent for border cases (for example, 2.675 will be rounded to 2.67). See Python Wiki for more information.

Below is an example that demonstrates the specifics of rounding with these methods:

Python

import math
def Rounders():
    PositiveFloat1=123.456
    PositiveFloat2=123.567
    NegativeFloat1=-123.456
    NegativeFloat2=-123.567

    Log.Message("Using the Floor method")
    Log.Message(math.floor(PositiveFloat1))  #Result is: 123
    Log.Message(math.floor(PositiveFloat2))  #Result is: 123
    Log.Message(math.floor(NegativeFloat1))  #Result is: -124
    Log.Message(math.floor(NegativeFloat2))  #Result is: -124

    Log.Message("Using the Ceil method")
    Log.Message(math.ceil(PositiveFloat1))   #Result is: 124
    Log.Message(math.ceil(PositiveFloat2))   #Result is: 124
    Log.Message(math.ceil(NegativeFloat1))   #Result is: -123
    Log.Message(math.ceil(NegativeFloat2))   #Result is: -123

    Log.Message("Using the Round method")
    Log.Message(round(PositiveFloat1))  #Result is: 123
    Log.Message(round(PositiveFloat2))  #Result is: 124
    Log.Message(round(NegativeFloat1))  #Result is: -123
    Log.Message(round(NegativeFloat2))  #Result is: -124

Division Operations

The standard operation of division, which is performed by the / operator, generally returns a floating-point result. The returned result (quotient) can be an integer only if the first operand (dividend) is evenly divisible by the second operand (divider), or, in other words, it is divided without a remainder (modulo). However, sometimes, you may need to get an integer quotient for numbers which are not evenly divisible. Such an operation is called integer division. Use the floor division operator // to remove the digits after the decimal point.

The code snippet below demonstrates how to perform division in Python:

Python

def IntDiv1(a,b):
  return round(a/b) 

def IntDiv2(a,b):
  return (a-(a%b))/b

Converting to Strings

One of the most frequent actions performed over numbers is converting them to strings. This can be required to post a numerical value to the TestComplete log, output the test result, write data to a text file and in many other situations. Python has the universal str method for converting any numbers to a string.

TestComplete also provides the aqConvert object with two methods: IntToStr and FloatToStr. You may also find the Format method of the aqString object useful.

The IntToStr method accepts an integer value and returns a string holding its decimal representation. Integer values can be decimal, octal or hexadecimal, but the resulting string is always decimal.

To convert floating-point numbers, use the FloatToStr or Format method. The FloatToStr method is the simplest: the generated string contains up to 15 digits and the decimal separator is displayed only when required. To specify the format of the resulting string, use the Format method. It provides more flexibility, since it allows you to set a user-defined formatting string.

The code below demonstrates how to use these methods.

Python

def NumToStrDemo():

  int=17
  Log.Message(aqConvert.IntToStr(int)) #Posts 17
  int=0xff
  Log.Message(aqConvert.IntToStr(int)) #Posts 255
  int=0X47C
  Log.Message(aqConvert.IntToStr(int)) #Posts 1148
  int=0o31
  Log.Message(aqConvert.IntToStr(int)) #Posts 25
  
  floatpt=-1234.567890
  Log.Message(aqConvert.FloatToStr(floatpt)) #Posts -1234.56789
  Log.Message(aqString.Format("%1.4E",floatpt)) #Posts -1.2346E+003

Getting Numerical Values From Strings

Python's int and float methods convert strings to integers or floats.

The aqConvert object has three methods that convert a string to a number. They are StrToInt, StrToInt64 and StrToFloat.

The int, StrToInt and StrToInt64 methods accept a string holding a decimal representation of a number and return an integer. The input string can contain only digits and + or - signs. The other symbols are not allowed. If the input string does not hold a valid integer, an exception occurs.

To get a floating-point number from a string, use the floatStrToFloat methods. They accept a string that consists of digits, decimal separator, "+" or "-" symbols and mantissa (the "e" or "E" character followed by a positive or negative integer) and returns a floating-point number. If the input string for the StrToFloat method does not hold a floating-point number, an exception occurs.

Below is an example that demonstrates how to use those methods:

Python

def StrToNumDemo():

  int=aqConvert.StrToInt("-1024");
  Log.Message(int); #Posts -1024
  
  floatpt=aqConvert.StrToFloat("-1234.56789e2")
  Log.Message(aqConvert.FloatToStr(floatpt)) #Posts -123456.789

However, sometimes, the functionality of these methods is insufficient, since they have some drawbacks when working with arbitrary strings. The default methods cannot recognize strings containing characters other than those mentioned above. If these methods cannot recognize a string, they raise an exception.

A versatile routine that would extract numbers from any textual string and recognize both integer and floating point values can be implemented via regular expressions. The following regular expression pattern would match positive or negative integer numbers, as well as floating-point numbers both in general and scientific notations: \+?\-?\ *\d+\.?\d*(?:[Ee]\ *-?\ *\d+)?.

Below is a sample routine that verifies whether a string contains a number. It uses the regular expression to check the input string and returns True if the input string holds an integer or a floating point number.

Python

import re
def ContainsNumber(Strng):
  reg = r"(\+?\-?\ *\d+\.?\d*(?:[Ee]\ *-?\ *\d+)?)" #Specify the regular expression
  if re.findall(reg, Strng):
    return True #Return the verification result
  else:
    return False

The same regular expression can be used to extract a number from a string. Since the input string can contain more than one number matching the regular expression, only the first occurrence will be returned by the routine. If the string does not hold any number, it is convenient to set the default value that would be returned in this case.

Python

def ExtractNumber(Strng, DefaultValue):
  reg = r"(\+?\-?\ *\d+\.?\d*(?:[Ee]\ *-?\ *\d+)?)" #Specify the regular expression
  MatchArr=re.findall(reg, Strng); #Search for occurrences
  #If no numbers were found then return default value
  if not MatchArr:
    return DefaultValue
  #Else, convert a string with first occurrence into a number
  else:
    return float(MatchArr[0])

Here is an example of how to use those two routines:

Python

def NumberFromStr():
  aStr="A value is : -1.234e2"
  Log.Message(ContainsNumber(aStr)) #Posts True
  Log.Message(ExtractNumber(aStr,-50)) #Posts -123.4

See Also

Working With Numeric Values
aqConvert Object

Highlight search results