Beginning Perl Lesson 6

Table of Contents

Numbers

Designating numbers

In computer languages, numbers are generally categorized into two groups: integers and floating point numbers. An integer has no decimal point or fractional part, whereas a floating point number does. For most programming languages, these are stored differently in memory. Perl version 5.8 also makes this distinction.

What we do have to worry about is providing numbers to Perl in the correct format. In general, numbers are formatted in Perl just as you would write them out naturally:

$x  = 45;                    #  an integer
$y  = 57.234;                #  a floating point number
$pi = 3.14159265358979;      #  another floating point number
$z  = -30;                   #  a negative integer

If you want to use a number such as Avogadro’s number (6.02 x 1023), then you have to convert it to the format that Perl recognizes, 6.02e23 or 6.02E23, where the e or E indicates the power of 10 that is used. Negative powers are allowed (e.g., 1.465e-4 for 1.465 x 10-4). Perl does not recognize a number such as e-40; this has to be written as 1e-40.

If you have a long integer, such as 288,456,349, you can’t put the commas into the number in Perl. Instead, you can replace the commas with underscores, like this: 288_456_349.

$avogadro = 6.02e23;
$pValue   = 1.47e-48;
$longInt  = 288_456_359;
$longFrac = 0.004_452_123

For hard-core computer types coming from low-level languages such as C, there are formats for expressing integers in binary (base 2), octal (base 8), and hexadecimal (base 16) format. See the references below for more information on these.

References:

Math operators

Adding with the + operator

Numbers and the values of variables are added using the + operator:

$x = 4.23 + 5.27;            # $x contains 9.50
$x = $x + 2.22;              # $x now contains 11.72
$y = 5.67;
$z = $x + $y;                # $z contains 17.39
$i = 4;
$i = $i + 1;                 # increment $i

As shown on line 2 above, you can add something to a variable and put the result back into the variable. There is a more efficient way to write this, using the += operator.

Incrementing a variable means to increase its value by 1, as shown in line 6 above. Incrementing a variable containing an integer is common in loops. There is a more efficient way to write this, using the ++ operator.

Subtracting with the - operator

Numbers and the values of variables are subtracted using the - operator:

$x = 4.23 - 5.27;            # $x contains -1.04
$x = $x - 2.22;              # $x now contains -3.26
$y = -5.67;                  # not subtraction, but initialization with a
                             #   negative number
$z = $x - $y;                # $z contains -8.93
$i = 4;
$i = $i - 1;                 # decrement $i

As shown on line 2 above, you can subtract something from a variable and put the result back into the variable. There is a more efficient way to write this, using the -= operator.

Decrementing a variable means to reduce its value by 1, as shown in line 6 above. Decrementing a variable containing an integer is common in loops. There is a more efficient way to write this, using the -- operator.

Multiplying with the * operator

Numbers and the values of variables are multiplied using the * operator:

$x = 4 * 5                   # $x contains 20.0
$x = $x * 0.5                # $x now contains 10.0
$y = -3;                     # initialization with a negative number
$z = $x * $y;                # $z contains -30.0

As shown on line 2 above, you can multiply a variable by something and put the result back into the variable. There is a more efficient way to write this, using the *= operator.

If multiplication and addition or subtraction occur in an expression without parentheses, multiplication happens before addition or subtraction. Operations in parentheses occur first, so use parentheses to make things happen the way you want them to.

$x = 2 + 3 * 5;              # $x contains 2 + 15 = 17
$x = ( 2 + 3 ) * 5;          # $x contains 5 * 5  = 25

Dividing with the / operator

Numbers and the values of variables are divided using the / operator:

$x = -20 / 4;                # $x contains -5.0
$x = 1 / 7;                  # $x contains 0.142857142857
$x = $x / 2;                 # $x now contains 0.0714285714286

As shown on line 3 above, you can multiply a variable by something and put the result back into the variable. There is a more efficient way to write this, using the /= operator.

If division and addition or subtraction occur in an expression without parentheses, division happens before addition or subtraction. Operations in parentheses occur first, so use parentheses to make things happen the way you want them to.

$x = 6 + 15 / 3;             # $x contains 6 + ( 15 / 3 )     = 11
$x = ( 6 + 15 ) / 3;         # $x contains 21 / 3             = 7
$x = 6 + 15 / 3 + 4;         # $x contains 6 + ( 15 / 3 ) + 4 = 15
$x = ( 6 + 15 ) / ( 3 + 4 )  # $x contains 21 / 7             = 3

If multiplication and division occur in an expression without parentheses, the operators are left-associative, meaning things on the left happen first. Operations in parentheses occur first, so use parentheses to make things happen the way you want them to.

$x = 2 * 3 / 6;              # $x contains ( 2 * 3 ) / 6 = 1
$x = 2 * ( 3 / 6 );          # $x contains 2 * 0.5       = 1
$x = 8 / 2 / 2;              # $x contains ( 8 / 2 ) / 2 = 2
$x = 8 / ( 2 / 2 );          # $x contains 8 / 1         = 8

Finding the remainder with the % (modulo) operator

The % (modulo or modulus) operator converts two numbers to integers, divides the first by the second, and returns the remainder. Customarily, this is used only on integer values.

$x = 10 % 3                  # $x contains 1

Calculating a power with the ** (exponentiation) operator

When you want to find the power of a number, use the ** operator.

$x = 2 ** 3;                 # $x contains 8
$x = 2 ** 0.5;               # one way to find a square root; $x = 1.414...

Combining math operators with the = (assignment) operator

In the examples above, we have changed the value of a variable and assigned the result back to the variable, like this:

$x = $x + 5;
$x = $x - 4;
$x = $x * 3;
$x = $x / 2;
$x = $x % 2;
$x = $x ** 2;

This sort of thing is so common that Perl provides a shorter way to write these:

$x += 5;    # $x = $x + 5;
$x -= 4;    # $x = $x - 4;
$x *= 3;    # $x = $x * 3;
$x /= 2;    # $x = $x / 2;
$x %= 2;    # $x = $x % 2;
$x **= 2;   # $x = $x ** 2;

Incrementing and decrementing

We often use a variable in a loop as a counter to keep track of the number of times we’ve gone through the loop. Each time through the loop, we will either increment the counter (increase its value by 1) or decrement the counter (decrease its value by 1). We have seen two ways to do this:

$x = $x + 1;  # increment $x
$x += 1;      # increment $x
$y = $y - 1;  # decrement $y
$y -= 1;      # decrement $y

Here are two ways to write a loop that prints "I do not like Draco Malfoy.\n" three times:

#   loop with increment (counting up)

$i = 0;
while ( $i < 3 )
{
    print( "I do not like Draco Malfoy.\n" );
    $i += 1;
}

#   loop with decrement (counting down)

$i = 3;
while ( $i > 0 )
{
    print( "I do not like Draco Malfoy.\n" );
    $i -= 1;
}

Since incrementing and decrementing a variable are so common, Perl provides third, shorter ways to write these operations:

++$x;         # increment $x
$x++;         # increment $x
--$x;         # decrement $x
$x--;         # decrement $x

We can change our loop examples as follows:

#   loop with increment (counting up)

$i = 0;
while ( $i < 3 )
{
    print( "I do not like Draco Malfoy.\n" );
    $i++;
}

#   loop with decrement (counting down)

$i = 3;
while ( $i > 0 )
{
    print( "I do not like Draco Malfoy.\n" );
    $i--;
}

There is a difference between putting the ++ or -- before or after the name of the variable. Put these operators before the variable if you want to increment or decrement the variable before using the variable. Put these operators after the variable if you want to increment or decrement the variable after using it.

Here are two simple loops that show the difference. In the first loop, we increment the variable after using it:

#   loop with increment (counting up)
#   increment the variable after using it

$i = 0;
while ( $i < 5 )
{
    print( $i++, "\n" );
}

The output from this loop is:

0
1
2
3
4

In the second loop, we increment the variable before using it:

#   loop with increment (counting up)
#   increment the variable before using it

$i = 0;
while ( $i < 5 )
{
    print( ++$i, "\n" );
}

The output from this loop is:

1
2
3
4
5

References:

Math functions

Finding the square root of a number

Square roots of a number can be determined either by using the sqrt() function or by exponentiating the number to the 0.5 power. You have to use the exponentation operator to find any other root such as a cube root.

$x = 2;
$y = sqrt( $x );             # Calculate the square root of 2.
$y = $x ** 0.5;              # Calculate the square root of 2.
$z = sqrt( 45 );             # Calculate the square root of 45.
$r = 64 ** ( 1 / 3 );        # Calculate the cube root of 64.

Finding the natural logarithm of a number

Use the log() function to find the natural logarithm of a number. If you want the base 10 logarithm, then calculate the natural logarithm of the number and divide that by the natural logarithm of 10.

$x = log( 20 );              # Find the natural logarithm of 20.
$x = log( 20 ) / log( 10 );  # Find the logarithm of 20 to base 10.

Getting a random number

Use the rand() function to get a random number between 0 and 1, including 0 but excluding 1. Give the rand() function an argument to change the range; rand( 10 ) returns a random number between 0 and 10, including 0 but excluding 10.

$x = rand();                 # Get a random number between 0 and 1.
$y = rand( 4.0 );            # Get a random number between 0 and 4.

Strings

A string is simply a sequence of characters of any length, such as "" (a zero-length string), "a" (a string one character in length), or "Hermione Granger’s parents are muggles.".

Strings in quotation marks are called string literals. It makes a difference whether you put a string in single or double quotes.

Double quote strings

Double quote strings are bounded by double quote characters. These are the most common string literals. Use a double quote string when you want to include a special character such as a tab ("\t") or a newline ("\n"), or when you want the value of a variable to appear in the string ("Welcome, $user."). The code:

$user = "Hermione";
print( "Welcome, $user.\n" );

produces:

Welcome, Hermione.

If you want to print the name of the variable in a double-quoted string, then you have to put a backslash in front of its name. The code:

$user = "Hagrid";
print( "\$user contains $user.\n" );

produces:

$user contains Hagrid.

If you want to include double quote characters in a double quote string, then you have to a backslash in front of each double quote character that you want to include. The code:

print( "Ron asked, \"Why?\"\n" );

produces:

Ron asked, "Why?"

Single quote characters in a double quote string are not a problem and don’t require a backslash in front of them. The code:

print( "Harry answered, 'Because.'\n" );

produces:

Harry answered, 'Because.'

Finally, if you want a backslash to appear in your output, then you have to put a backslash in front of the backslash. The code:

print( "This is a backslash: \\.\n" );

produces:

This is a backslash: \.

Single quote strings

Single quote strings are bounded by single quote charcters. Use single quote strings when you want the string to appear exactly as entered. Special characters and variables are not converted. Double quote characters are not a problem in single quote strings, but if you want to use single quote characters, you have to put a backslash in front of each one. And to put a backslash in a single quote string, put a backslash in front of it.

This code:

$user = "Roger";
print( 'Welcome, $user, to \'Who wants to be a "Perl" programmer?\'\n' );

produces:

Welcome, $user, to 'Who wants to be a "Perl" programmer?'\n

Note that the variable, $user, was not replaced with its value, and that the new line string, \n, was not converted to a new line character.

References:

Concatenating strings with the . operator

Two strings can be concatenated using the . operator. If you want to append a string to a variable, you can use the .= operator.

$x =  "Mr. and Mrs. Dursley, of number four, " . "Privet Drive, were ";
$x .= "proud to say that they were perfectly normal, ";
$y =  "thank you very much.";
$x .= $y;

When all the concatenations are complete, the variable $x contains the string "Mr. and Mrs. Dursley, of number four, Privet Drive, were proud to say that they were perfectly normal, thank you very much.". (This is the first sentence of Harry Potter and the Sorcerer’s Stone, by J. K. Rowling.)

References:

Getting a substring with the substr() function

You can pull a part of a string out a string using the substr() function. This function takes three arguments. The first argument is a string literal or a variable that contains a string. The second argument is the character position from which you want to obtain the substring. (The first character is at position 0.) The third argument is the number of characters you want in the substring.

This function is handiest when you have a data file with fixed-width columns, where you know the character position of each column of data.

Here is an example:

#   Initialize a fixed-width data line with first name in character columns
#   0-11, last name in character columns 12-23, and the Hogwarts house in
#   columns 24-35.

$data = "Harry       Potter      Gryffindor  ";

#   Extract the fields.

$firstName = substr( $data,  0, 12 );  # contains "Harry       "
$lastName  = substr( $data, 12, 12 );  # contains "Potter      "
$house     = substr( $data, 24, 12 );  # contains "Gryffindor  "

#   Print the extracted fields to display their contents.

print( "'$firstName'\n" );
print( "'$lastName'\n" );
print( "'$house'\n" );

The output from this code fragment is:

'Harry       '
'Potter      '
'Gryffindor  '

References:

Printing formatted numbers and strings

You can format numbers and strings using the printf() and the sprintf() functions. There are many formats, given in Programming Perl, 3rd Edition, pp. 797-799. We’ll concentrate on four of these.

Using printf()

The printf() function prints to a filehandle (such as STDOUT, STDERR, or a file handle corresponding to a file you have opened). printf() takes as an argument a formatting string that contains fields for formatting numbers and strings. You indicate the position of each formatted field within the formatting string with the % symbol followed by a letter. Succeeding arguments of the printf() function are the values that you want to print in the fields.

Formatting integers with %d

A %d field indicates that you want to print an integer at that position.

$x = 4;
printf( STDOUT "The integer is %d.\n", $x );
printf( STDOUT "%d squared equals %d.\n", $x, $x ** 2 );

The output from this code fragment is:

The integer is 4.
4 squared equals 16.

Formatting floating point numbers with %f

A %f field indicates that you want to print a floating point number at that position. You can indicate how many digits you want after the decimal by putting a decimal point and the number of digits you desire in front of the f. For example, %.4f indicates that you want to print a floating point number with 4 digits of precision.

$x = 4;
printf( STDOUT "%f squared equals %f.\n", $x, $x ** 2 );
printf( STDOUT "%.4f squared equals %.4f.\n", $x, $x ** 2 );

The output from this code fragment is:

4.000000 squared equals 16.000000.
4.0000 squared equals 16.0000.

Formatting strings with %s

The %s field indicates that you want to format a string at that position in the string.

#   Example of printing strings.

$name = 'Dumbledore';
$occupation = 'headmaster';

printf( STDOUT "%s's occupation is %s.\n", $name, $occupation );

The output from this code fragment is:

Dumbledore's occupation is headmaster.

Formatting percent symbols with %%

Finally, the %% field indicates that you just want to print a percent symbol at that position in the string.

$successes = 30;
$total = 50;

printf( "The success rate was %.2f%%.\n", 100 * $successes / $total );

The output from this code fragment is:

The success rate was 60.00%.

Using sprintf()

Use the sprintf() function when you want to format a string but you’re not ready to send it to a filehandle yet. sprintf() returns the formatted string, which you can save in a variable for later use.

#   Example of printing an integer and a floating point number, with
#   four places after the decimal for the floating point number.

$x = 5;
$formattedString =
    sprintf( "The square root of %d is %.4f\n", $x, sqrt( $x ) );
print( STDOUT $formattedString );

The output from this code fragment is:

The square root of 5 is 2.2361

References:

Homework assignment

Write a script that creates a file containing the following calculations on the integers 1 through 10:

The output should look something like this:

n   1/n     sqrt(n)  log(n)  n**2
 1  1.0000  1.0000   0.0000    1.0000
 2  0.5000  1.4142   0.6931    4.0000
...
10  0.1000  3.1623   2.3026  100.0000

As you work on this script or any other script, write a few lines of code, then test the script. Don’t try to write the entire script at once. Analyze the problem and try to break it into small parts. Then add each part one at a time.

Here are the individual parts of the script:

Here are the steps I would use to write the script.

  1. Write a script that opens a file for writing, writes the column names, then closes the file. Use the open() function and make sure to put <> in front of the file name to indicate that you want to write to the file. Use the print() function to print the column names to the file. Use the close() function to close the file.
  2. When you have completed step 1 successfully, then add a while loop that increments a variable from 1 to 10. Print the value of the variable to the output file each time through the loop.
  3. When you have completed step 2 successfully, then calculate the reciprocal of the number (1/$n), the square root of the number (sqrt( $n )), the natural logarithm of the number (log( $n )), and the number squared (n**2), and save these values to variables. Use the print() function to print the values of these variables to the output file so you can check that the calculations are correct.
  4. When you have completed step 3 successfully, then substitute printf() for print() and use %d and %f to format the output correctly.