Practical activity

Duration2h30

Presentation & objectives

Here are a few exercises to make you manipulate simple programs and your IDE.

During these activity, please pay attention to the good programming practices you studied earlier. These are good reflexes to acquire quickly.

For each exercise, we ask you to show your solution to another student, so that they can give you remarks on readability.

Important

The aim of this session is to help you master the basics of algorithms and programming by tackling very classic and simple problems. An intelligent programming assistant such as GitHub Copilot, that you may have installed already, will be able to provide you with a solution to these exercises based only on a wisely chosen file name. So, for the sake of training, we advise you to postpone the discovery of Copilot’s functionalities for now.

Important

We provide you the solutions to the exercises. Make sure to check them only after you have a solution to the exercises, for comparison purpose! Even if you are sure your solution is correct, please have a look at them, as they sometimes provide additional elements you may have missed.

Activity contents

1 — The interactive Python interpreter

Consider the following Python code (that you wrote during the practical activity of algorithmics session 1) that simply reverses a string.

# The string to manipulate
s = "IMT Atlantique"
print(s)

# Loop to append to a new string
result = ""
for i in range(len(s)):
    result = s[i] + result

# Print the result
print("Reversed string:", result)
/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */
public class Main {

    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        // The string to manipulate
        String s = "IMT Atlantique";
        System.out.println(s);

        // Loop to append to a new string
        String result = "";
        for (int i = 0; i < s.length(); i++) {
            result = s.charAt(i) + result;
        }

        // Print the result
        System.out.println("Reversed string: " + result);
    }

}

Open a terminal (within the VSCode IDE if you want) and start an interactive Python interpreter. Then, run statement by statement the code above. What does the output look like?

Correction
$ python3
Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> # The string to manipulate
>>> s = "IMT Atlantique"
>>> print(s)
IMT Atlantique
>>> 
>>> # Loop to append to a new string
>>> result = ""
>>> for i in range(len(s)):
...     result = s[i] + result
... 
>>> # Print the result
>>> print("Reversed string:", result)
Reversed string: euqitnaltA TMI

Create a new file within you IDE and paste the same code in it. Then, run the entire file using the non-interactive Python interpreter (use the Run button in VSCode). What does the output look like?

Correction
$ /bin/python3 session_1.py
IMT Atlantique
Reversed string: euqitnaltA TMI

Here, /bin/python3 is the interpreter used by VSCode to execute the code. This one is the default interpreter on Linux, which is the systm on which we ran that code. You may see differences based on your system. This is also true for the file name.

2 — Fixing syntactic bugs

The following code contains a syntax error. Use the Error tab of your IDE find the location of the error. What does it say?

# The string to manipulate
s = "IMT Atlantique"
print(s)

# Loop to append to a new string
result = ""
for i j in range(len(s)):
    result = s[i] + result

# Print the result
print("Reversed string:", result)
/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */
public class Main {

    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        // The string to manipulate
        String s = "IMT Atlantique";
        System.out.println(s);

        // Loop to append to a new string
        String result = "";
        for (int i j = 0; i < s.length(); i++) {
            result = s.charAt(i) + result;
        }

        // Print the result
        System.out.println("Reversed string: " + result);
    }

}
Correction
Output
Expected "in" Pylance [Ln 7, Col 7]
Unexpected indentation Pylance [Ln 8, Col 1]
Unindent not expected Pylance [Ln 11, Col 1]
Main.java:25: error: ';' expected
        for (int i j = 0; i < s.length(); i++) {
                  ^

As you can see, the Problems tab does not directly tell you that there is an extra j. As it is trying to parse the program, it encounters something unexpected, and indicates it to you. In this case, the shown errors are indirect consequences of your syntax error.

Therefore, you may sometimes need some interpretation to link error messages to the actual errors to correct. With time and experience, you will learn to interprete these messages efficiently.

Check again your code. Your IDE should have underlined the lines that correspond to the problems identified above. This will help you find errors more easily.

3 — Fixing semantic bugs

Here is a code that is syntactically correct:

# Needed imports
import random



# Fill a list with 10 random numbers
numbers = []
for i in range(10):
    numbers.append(random.randint(-50, 50))

# Let's do the following operation 50 times
for i in range(50):

    # Divide each number by the subtraction of the two next numbers in the list
    for j in range(len(numbers) - 2):
        numbers[j] /= numbers[j + 1] - numbers[j + 2]

# Print the final list
print("Final list", numbers)
/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */
// Needed imports

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Main {

    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        // Use a random number generator
        Random random = new Random();

        // Fill a list with 10 random numbers
        List<Double> numbers = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            numbers.add((double) (random.nextInt(101) - 50));
        }

        // Let's do the following operation 50 times
        for (int k = 0; k < 50; k++) {
            // Divide each number by the subtraction of the two next numbers in the list
            for (int j = 0; j < numbers.size() - 2; j++) {
                numbers.set(j, numbers.get(j) / (numbers.get(j + 1) - numbers.get(j + 2)));
            }
        }

        // Print the final list
        System.out.println("Final list " + numbers);
    }

}

However, when running it, we get the following output:

Output
Traceback (most recent call last):
  File "session_1.py", line 14, in <module>
    numbers[j] /= numbers[j + 1] - numbers[j + 2]
ZeroDivisionError: float division by zero
Final list [0.0, 0.0, -Infinity, 0.0, 0.0, Infinity, 5.139385345176833E-80, 2.240361480978435E-62, -41.0, -23.0]

Here, no error is raised, but the values Infinity and -Infinity indicate that the division by zero was not handled correctly.

3.1 — Using prints

Using the print command, try to find the error.

Correction

Before anything, note that the program uses random numbers. Therefore, we should set the seed to a value that leads to the error. On our computer, seed 42 leads to an error. It may be different for you, try to find such a value.

# Needed imports
import random



# Set the seed
random.seed(42)

# Fill a list with 10 random numbers
numbers = []
for i in range(10):
    numbers.append(random.randint(-50, 50))

# Let's do the following operation 50 times
for i in range(50):

    # Divide each number by the subtraction of the two next numbers in the list
    for j in range(len(numbers) - 2):
        numbers[j] /= numbers[j + 1] - numbers[j + 2]

# Print the final list
print("Final list", numbers)
/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */

// Needed imports

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Main {

    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        // Use a random number generator
        Random random = new Random();

        // Set the seed
        random.setSeed(42);

        // Fill a list with 10 random numbers
        List<Double> numbers = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            numbers.add((double) (random.nextInt(101) - 50));
        }

        // Let's do the following operation 50 times
        for (int k = 0; k < 50; k++) {
            // Divide each number by the subtraction of the two next numbers in the list
            for (int j = 0; j < numbers.size() - 2; j++) {
                numbers.set(j, numbers.get(j) / (numbers.get(j + 1) - numbers.get(j + 2)));
            }
        }

        // Print the final list
        System.out.println("Final list " + numbers);
    }

}

At this point, we get the following output when running the program:

Output
Traceback (most recent call last):
  File "session_1.py", line 17, in <module>
    numbers[j] /= numbers[j + 1] - numbers[j + 2]
ZeroDivisionError: float division by zero
Final list [-0.0, -0.0, Infinity, 0.0, 0.0, -Infinity, -2.8530960909304215E-69, -5.679991152181034E-82, 25.0, -20.0]

Here, no error is raised, but the values Infinity and -Infinity indicate that the division by zero was not handled correctly.

The error message tells us that the crash occurs in the last loop. It seems to be related to the subtraction of two numbers being 0. Let’s have a look at the numbers list before that loop, and what parts of it lead to a problem.

# Needed imports
import random



# Set the seed
random.seed(42)

# Fill a list with 10 random numbers
numbers = []
for i in range(10):
    numbers.append(random.randint(-50, 50))

# Let's do the following operation 50 times
for i in range(50):

    # Debug
    print("Current list", numbers)

    # Divide each number by the subtraction of the two next numbers in the list
    for j in range(len(numbers) - 2):

        # Debug
        print("  numbers[j+1] =", numbers[j + 1], "/ numbers[j+2] =", numbers[j + 2], "/ difference =", numbers[j + 1] - numbers[j + 2])

        numbers[j] /= numbers[j + 1] - numbers[j + 2]

# Print the final list
print("Final list", numbers)
/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */

// Needed imports

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Main {

    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        // Use a random number generator
        Random random = new Random();

        // Set the seed
        random.setSeed(42);

        // Fill a list with 10 random numbers
        List<Double> numbers = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            numbers.add((double) (random.nextInt(101) - 50));
        }

        // Let's do the following operation 50 times
        for (int k = 0; k < 50; k++) {
            // Debug
            System.out.println(numbers);

            // Divide each number by the subtraction of the two next numbers in the list
            for (int j = 0; j < numbers.size() - 2; j++) {
                // Debug
                System.out.println("  numbers[j+1] = " + numbers.get(j + 1) + "/ numbers[j+2] = " + numbers.get(j + 2) + "/ division = " + (numbers.get(j + 1) / numbers.get(j + 2)));

                numbers.set(j, numbers.get(j) / (numbers.get(j + 1) - numbers.get(j + 2)));
            }
        }

        // Print the final list
        System.out.println("Final list " + numbers);
    }

}

Here is what we get:

Output
Current list [31, -36, -47, 44, -15, -19, -22, -33, 44, -37]
  numbers[j+1] = -36 / numbers[j+2] = -47 / difference = 11
  numbers[j+1] = -47 / numbers[j+2] = 44 / difference = -91
  numbers[j+1] = 44 / numbers[j+2] = -15 / difference = 59
  numbers[j+1] = -15 / numbers[j+2] = -19 / difference = 4
  numbers[j+1] = -19 / numbers[j+2] = -22 / difference = 3
  numbers[j+1] = -22 / numbers[j+2] = -33 / difference = 11
  numbers[j+1] = -33 / numbers[j+2] = 44 / difference = -77
  numbers[j+1] = 44 / numbers[j+2] = -37 / difference = 81
Current list [2.8181818181818183, 0.3956043956043956, -0.7966101694915254, 11.0, -5.0, -1.7272727272727273, 0.2857142857142857, -0.4074074074074074, 44, -37]
  numbers[j+1] = 0.3956043956043956 / numbers[j+2] = -0.7966101694915254 / difference = 1.192214565095921
  numbers[j+1] = -0.7966101694915254 / numbers[j+2] = 11.0 / difference = -11.796610169491526
  numbers[j+1] = 11.0 / numbers[j+2] = -5.0 / difference = 16.0
  numbers[j+1] = -5.0 / numbers[j+2] = -1.7272727272727273 / difference = -3.2727272727272725
  numbers[j+1] = -1.7272727272727273 / numbers[j+2] = 0.2857142857142857 / difference = -2.012987012987013
  numbers[j+1] = 0.2857142857142857 / numbers[j+2] = -0.4074074074074074 / difference = 0.693121693121693
  numbers[j+1] = -0.4074074074074074 / numbers[j+2] = 44 / difference = -44.407407407407405
  numbers[j+1] = 44 / numbers[j+2] = -37 / difference = 81
Current list [2.3638209938787975, -0.03353543008715422, -0.04978813559322034, -3.361111111111111, 2.4838709677419355, -2.492019430950729, -0.006433933039437627, -0.005029721079103795, 44, -37]
  numbers[j+1] = -0.03353543008715422 / numbers[j+2] = -0.04978813559322034 / difference = 0.01625270550606612
  numbers[j+1] = -0.04978813559322034 / numbers[j+2] = -3.361111111111111 / difference = 3.311322975517891
  numbers[j+1] = -3.361111111111111 / numbers[j+2] = 2.4838709677419355 / difference = -5.844982078853047
  numbers[j+1] = 2.4838709677419355 / numbers[j+2] = -2.492019430950729 / difference = 4.975890398692664
  numbers[j+1] = -2.492019430950729 / numbers[j+2] = -0.006433933039437627 / difference = -2.4855854979112912
  numbers[j+1] = -0.006433933039437627 / numbers[j+2] = -0.005029721079103795 / difference = -0.0014042119603338322
  numbers[j+1] = -0.005029721079103795 / numbers[j+2] = 44 / difference = -44.005029721079104
  numbers[j+1] = 44 / numbers[j+2] = -37 / difference = 81
Current list [145.4416923383329, -0.010127502009044973, 0.008518098930252016, -0.6754793296882482, -0.9993102107447938, 1774.6746939531017, 0.0001462090374718159, -6.209532196424438e-05, 44, -37]
  numbers[j+1] = -0.010127502009044973 / numbers[j+2] = 0.008518098930252016 / difference = -0.01864560093929699
  numbers[j+1] = 0.008518098930252016 / numbers[j+2] = -0.6754793296882482 / difference = 0.6839974286185002
  numbers[j+1] = -0.6754793296882482 / numbers[j+2] = -0.9993102107447938 / difference = 0.32383088105654556
  numbers[j+1] = -0.9993102107447938 / numbers[j+2] = 1774.6746939531017 / difference = -1775.6740041638466
  numbers[j+1] = 1774.6746939531017 / numbers[j+2] = 0.0001462090374718159 / difference = 1774.6745477440643
  numbers[j+1] = 0.0001462090374718159 / numbers[j+2] = -6.209532196424438e-05 / difference = 0.00020830435943606026
  numbers[j+1] = -6.209532196424438e-05 / numbers[j+2] = 44 / difference = -44.000062095321965
  numbers[j+1] = 44 / numbers[j+2] = -37 / difference = 81
Current list [-7800.32206051368, -0.014806345148840596, 0.026304158832723037, 0.0003804072865313625, -0.0005630949133829072, 8519623.395101551, -3.32292798030757e-06, -7.666089131388194e-07, 44, -37]
  numbers[j+1] = -0.014806345148840596 / numbers[j+2] = 0.026304158832723037 / difference = -0.041110503981563636
  numbers[j+1] = 0.026304158832723037 / numbers[j+2] = 0.0003804072865313625 / difference = 0.025923751546191674
  numbers[j+1] = 0.0003804072865313625 / numbers[j+2] = -0.0005630949133829072 / difference = 0.0009435021999142697
  numbers[j+1] = -0.0005630949133829072 / numbers[j+2] = 8519623.395101551 / difference = -8519623.395664645
  numbers[j+1] = 8519623.395101551 / numbers[j+2] = -3.32292798030757e-06 / difference = 8519623.395104874
  numbers[j+1] = -3.32292798030757e-06 / numbers[j+2] = -7.666089131388194e-07 / difference = -2.5563190671687508e-06
  numbers[j+1] = -7.666089131388194e-07 / numbers[j+2] = 44 / difference = -44.00000076660891
  numbers[j+1] = 44 / numbers[j+2] = -37 / difference = 81
Current list [189740.36572287712, -0.5711497860353364, 27.879276630317488, -4.465071621885766e-11, -6.609387378630434e-11, -3332769959947.7046, 7.552108914573704e-08, -9.464307569615054e-09, 44, -37]
  numbers[j+1] = -0.5711497860353364 / numbers[j+2] = 27.879276630317488 / difference = -28.450426416352823
  numbers[j+1] = 27.879276630317488 / numbers[j+2] = -4.465071621885766e-11 / difference = 27.87927663036214
  numbers[j+1] = -4.465071621885766e-11 / numbers[j+2] = -6.609387378630434e-11 / difference = 2.144315756744668e-11
  numbers[j+1] = -6.609387378630434e-11 / numbers[j+2] = -3332769959947.7046 / difference = 3332769959947.7046
  numbers[j+1] = -3332769959947.7046 / numbers[j+2] = 7.552108914573704e-08 / difference = -3332769959947.7046
  numbers[j+1] = 7.552108914573704e-08 / numbers[j+2] = -9.464307569615054e-09 / difference = 8.49853967153521e-08
  numbers[j+1] = -9.464307569615054e-09 / numbers[j+2] = 44 / difference = -44.00000000946431
  numbers[j+1] = 44 / numbers[j+2] = -37 / difference = 81
Current list [-6669.1571840138595, -0.020486535343364014, 1300147916305.0884, -1.3397479200622142e-23, 1.9831513900029704e-23, -3.9215795757362864e+19, -1.7163883893066504e-09, -1.168433033285809e-10, 44, -37]
  numbers[j+1] = -0.020486535343364014 / numbers[j+2] = 1300147916305.0884 / difference = -1300147916305.109
  numbers[j+1] = 1300147916305.0884 / numbers[j+2] = -1.3397479200622142e-23 / difference = 1300147916305.0884
  numbers[j+1] = -1.3397479200622142e-23 / numbers[j+2] = 1.9831513900029704e-23 / difference = -3.3228993100651846e-23
  numbers[j+1] = 1.9831513900029704e-23 / numbers[j+2] = -3.9215795757362864e+19 / difference = 3.9215795757362864e+19
  numbers[j+1] = -3.9215795757362864e+19 / numbers[j+2] = -1.7163883893066504e-09 / difference = -3.9215795757362864e+19
  numbers[j+1] = -1.7163883893066504e-09 / numbers[j+2] = -1.168433033285809e-10 / difference = -1.5995450859780694e-09
  numbers[j+1] = -1.168433033285809e-10 / numbers[j+2] = 44 / difference = -44.00000000011684
  numbers[j+1] = 44 / numbers[j+2] = -37 / difference = 81
Current list [5.129537262934622e-09, -1.5757080472493495e-14, -3.9126912824800088e+34, -3.416347658355685e-43, -5.057021926249269e-43, 2.451684300813796e+28, 3.900882702959301e-11, -1.4425099176368013e-12, 44, -37]
  numbers[j+1] = -1.5757080472493495e-14 / numbers[j+2] = -3.9126912824800088e+34 / difference = 3.9126912824800088e+34
  numbers[j+1] = -3.9126912824800088e+34 / numbers[j+2] = -3.416347658355685e-43 / difference = -3.9126912824800088e+34
  numbers[j+1] = -3.416347658355685e-43 / numbers[j+2] = -5.057021926249269e-43 / difference = 1.640674267893584e-43
  numbers[j+1] = -5.057021926249269e-43 / numbers[j+2] = 2.451684300813796e+28 / difference = -2.451684300813796e+28
  numbers[j+1] = 2.451684300813796e+28 / numbers[j+2] = 3.900882702959301e-11 / difference = 2.451684300813796e+28
  numbers[j+1] = 3.900882702959301e-11 / numbers[j+2] = -1.4425099176368013e-12 / difference = 4.0451336947229815e-11
  numbers[j+1] = -1.4425099176368013e-12 / numbers[j+2] = 44 / difference = -44.00000000000144
  numbers[j+1] = 44 / numbers[j+2] = -37 / difference = 81
Current list [1.3109997422754321e-43, 4.027171922060274e-49, -2.3848068803464593e+77, 1.3934696474671249e-71, -2.0626725572173683e-71, 6.060823908025844e+38, -8.865642506725394e-13, -1.780876441526915e-14, 44, -37]
  numbers[j+1] = 4.027171922060274e-49 / numbers[j+2] = -2.3848068803464593e+77 / difference = 2.3848068803464593e+77
  numbers[j+1] = -2.3848068803464593e+77 / numbers[j+2] = 1.3934696474671249e-71 / difference = -2.3848068803464593e+77
  numbers[j+1] = 1.3934696474671249e-71 / numbers[j+2] = -2.0626725572173683e-71 / difference = 3.456142204684493e-71
  numbers[j+1] = -2.0626725572173683e-71 / numbers[j+2] = 6.060823908025844e+38 / difference = -6.060823908025844e+38
  numbers[j+1] = 6.060823908025844e+38 / numbers[j+2] = -8.865642506725394e-13 / difference = 6.060823908025844e+38
  numbers[j+1] = -8.865642506725394e-13 / numbers[j+2] = -1.780876441526915e-14 / difference = -8.687554862572702e-13
  numbers[j+1] = -1.780876441526915e-14 / numbers[j+2] = 44 / difference = -44.00000000000002
  numbers[j+1] = 44 / numbers[j+2] = -37 / difference = 81
Current list [5.497299395936719e-121, -1.6886784230827175e-126, -6.900198947584002e+147, -2.2991422760556847e-110, -3.403287388841545e-110, -6.9764438946299935e+50, 2.0149187515284978e-14, -2.1986128907739692e-16, 44, -37]
  numbers[j+1] = -1.6886784230827175e-126 / numbers[j+2] = -6.900198947584002e+147 / difference = 6.900198947584002e+147
  numbers[j+1] = -6.900198947584002e+147 / numbers[j+2] = -2.2991422760556847e-110 / difference = -6.900198947584002e+147
  numbers[j+1] = -2.2991422760556847e-110 / numbers[j+2] = -3.403287388841545e-110 / difference = 1.1041451127858606e-110
  numbers[j+1] = -3.403287388841545e-110 / numbers[j+2] = -6.9764438946299935e+50 / difference = 6.9764438946299935e+50
  numbers[j+1] = -6.9764438946299935e+50 / numbers[j+2] = 2.0149187515284978e-14 / difference = -6.9764438946299935e+50
  numbers[j+1] = 2.0149187515284978e-14 / numbers[j+2] = -2.1986128907739692e-16 / difference = 2.0369048804362376e-14
  numbers[j+1] = -2.1986128907739692e-16 / numbers[j+2] = 44 / difference = -44.0
  numbers[j+1] = 44 / numbers[j+2] = -37 / difference = 81
Current list [7.96687086516761e-269, 2.4472894707970443e-274, -6.249358773299426e+257, -3.295579109903561e-161, 4.8782552260775314e-161, -3.42502193481704e+64, -4.579360798928404e-16, -2.7143369021900854e-18, 44, -37]
  numbers[j+1] = 2.4472894707970443e-274 / numbers[j+2] = -6.249358773299426e+257 / difference = 6.249358773299426e+257
  numbers[j+1] = -6.249358773299426e+257 / numbers[j+2] = -3.295579109903561e-161 / difference = -6.249358773299426e+257
  numbers[j+1] = -3.295579109903561e-161 / numbers[j+2] = 4.8782552260775314e-161 / difference = -8.173834335981092e-161
  numbers[j+1] = 4.8782552260775314e-161 / numbers[j+2] = -3.42502193481704e+64 / difference = 3.42502193481704e+64
  numbers[j+1] = -3.42502193481704e+64 / numbers[j+2] = -4.579360798928404e-16 / difference = -3.42502193481704e+64
  numbers[j+1] = -4.579360798928404e-16 / numbers[j+2] = -2.7143369021900854e-18 / difference = -4.552217429906503e-16
  numbers[j+1] = -2.7143369021900854e-18 / numbers[j+2] = 44 / difference = -44.0
  numbers[j+1] = 44 / numbers[j+2] = -37 / difference = 81
Current list [0.0, -0.0, inf, -9.622067165183299e-226, -1.424298973529967e-225, 7.523854006436124e+79, 1.0407638179382736e-17, -3.351033212580352e-20, 44, -37]
  numbers[j+1] = -0.0 / numbers[j+2] = inf / difference = -inf
  numbers[j+1] = inf / numbers[j+2] = -9.622067165183299e-226 / difference = inf
  numbers[j+1] = -9.622067165183299e-226 / numbers[j+2] = -1.424298973529967e-225 / difference = 4.620922570116372e-226
  numbers[j+1] = -1.424298973529967e-225 / numbers[j+2] = 7.523854006436124e+79 / difference = -7.523854006436124e+79
  numbers[j+1] = 7.523854006436124e+79 / numbers[j+2] = 1.0407638179382736e-17 / difference = 7.523854006436124e+79
  numbers[j+1] = 1.0407638179382736e-17 / numbers[j+2] = -3.351033212580352e-20 / difference = 1.044114851150854e-17
  numbers[j+1] = -3.351033212580352e-20 / numbers[j+2] = 44 / difference = -44.0
  numbers[j+1] = 44 / numbers[j+2] = -37 / difference = 81
Current list [-0.0, -0.0, inf, 1.2788747837148755e-305, -1.8930444055820065e-305, 7.205963978141975e+96, -2.3653723134960764e-19, -4.137078040222657e-22, 44, -37]
  numbers[j+1] = -0.0 / numbers[j+2] = inf / difference = -inf
  numbers[j+1] = inf / numbers[j+2] = 1.2788747837148755e-305 / difference = inf
  numbers[j+1] = 1.2788747837148755e-305 / numbers[j+2] = -1.8930444055820065e-305 / difference = 3.171919189296882e-305
  numbers[j+1] = -1.8930444055820065e-305 / numbers[j+2] = 7.205963978141975e+96 / difference = -7.205963978141975e+96
  numbers[j+1] = 7.205963978141975e+96 / numbers[j+2] = -2.3653723134960764e-19 / difference = 7.205963978141975e+96
  numbers[j+1] = -2.3653723134960764e-19 / numbers[j+2] = -4.137078040222657e-22 / difference = -2.3612352354558536e-19
  numbers[j+1] = -4.137078040222657e-22 / numbers[j+2] = 44 / difference = -44.0
  numbers[j+1] = 44 / numbers[j+2] = -37 / difference = 81
Current list [0.0, -0.0, inf, -0.0, -0.0, -3.051777251981763e+115, 5.375846167036538e-21, -5.107503753361305e-24, 44, -37]
  numbers[j+1] = -0.0 / numbers[j+2] = inf / difference = -inf
  numbers[j+1] = inf / numbers[j+2] = -0.0 / difference = inf
  numbers[j+1] = -0.0 / numbers[j+2] = -0.0 / difference = 0.0
Traceback (most recent call last):
  File "session_1.py", line 21, in <module>
    numbers[j] /= numbers[j + 1] - numbers[j + 2]
ZeroDivisionError: float division by zero

This output clearly shows us two things:

  • The error comes from a subtraction -0.0 - (-0.0) = 0.0, which sets the denominator of the division to 0.
  • Apparition of these 0s is caused by a very fast decrease of all values in the list (except the last two).
[-35.0, 9.0, -46.0, 39.0, -39.0, 6.0, -47.0, -26.0, 25.0, -20.0]
  numbers[j+1] = 9.0/ numbers[j+2] = -46.0/ division = -0.1956521739130435
  numbers[j+1] = -46.0/ numbers[j+2] = 39.0/ division = -1.1794871794871795
  numbers[j+1] = 39.0/ numbers[j+2] = -39.0/ division = -1.0
  numbers[j+1] = -39.0/ numbers[j+2] = 6.0/ division = -6.5
  numbers[j+1] = 6.0/ numbers[j+2] = -47.0/ division = -0.1276595744680851
  numbers[j+1] = -47.0/ numbers[j+2] = -26.0/ division = 1.8076923076923077
  numbers[j+1] = -26.0/ numbers[j+2] = 25.0/ division = -1.04
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.6363636363636364, -0.10588235294117647, -0.5897435897435898, -0.8666666666666667, -0.7358490566037735, -0.2857142857142857, 0.9215686274509803, -0.5777777777777777, 25.0, -20.0]
  numbers[j+1] = -0.10588235294117647/ numbers[j+2] = -0.5897435897435898/ division = 0.179539641943734
  numbers[j+1] = -0.5897435897435898/ numbers[j+2] = -0.8666666666666667/ division = 0.6804733727810651
  numbers[j+1] = -0.8666666666666667/ numbers[j+2] = -0.7358490566037735/ division = 1.1777777777777778
  numbers[j+1] = -0.7358490566037735/ numbers[j+2] = -0.2857142857142857/ division = 2.5754716981132075
  numbers[j+1] = -0.2857142857142857/ numbers[j+2] = 0.9215686274509803/ division = -0.3100303951367781
  numbers[j+1] = 0.9215686274509803/ numbers[j+2] = -0.5777777777777777/ division = -1.5950226244343892
  numbers[j+1] = -0.5777777777777777/ numbers[j+2] = 25.0/ division = -0.02311111111111111
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-1.315177964180458, -0.38235294117647056, 4.508136094674554, 1.9253493013972058, 0.6095083833121744, -0.19055922281728732, -0.036030050595390196, -0.012839506172839505, 25.0, -20.0]
  numbers[j+1] = -0.38235294117647056/ numbers[j+2] = 4.508136094674554/ division = -0.08481397481059696
  numbers[j+1] = 4.508136094674554/ numbers[j+2] = 1.9253493013972058/ division = 2.341464009363416
  numbers[j+1] = 1.9253493013972058/ numbers[j+2] = 0.6095083833121744/ division = 3.1588561439213083
  numbers[j+1] = 0.6095083833121744/ numbers[j+2] = -0.19055922281728732/ division = -3.1985247121656526
  numbers[j+1] = -0.19055922281728732/ numbers[j+2] = -0.036030050595390196/ division = 5.288896897682073
  numbers[j+1] = -0.036030050595390196/ numbers[j+2] = -0.012839506172839505/ division = 2.8061866329101983
  numbers[j+1] = -0.012839506172839505/ numbers[j+2] = 25.0/ division = -5.135802469135802E-4
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[0.26892565437509375, -0.1480389098208511, 3.4260494811449784, 2.4064832604729385, -3.9442933301742342, 8.217108634672064, 0.0014404622308674094, -2.853223593964335E-4, 25.0, -20.0]
  numbers[j+1] = -0.1480389098208511/ numbers[j+2] = 3.4260494811449784/ division = -0.04320979910989984
  numbers[j+1] = 3.4260494811449784/ numbers[j+2] = 2.4064832604729385/ division = 1.4236747611831166
  numbers[j+1] = 2.4064832604729385/ numbers[j+2] = -3.9442933301742342/ division = -0.6101177217381637
  numbers[j+1] = -3.9442933301742342/ numbers[j+2] = 8.217108634672064/ division = -0.48000988006064577
  numbers[j+1] = 8.217108634672064/ numbers[j+2] = 0.0014404622308674094/ division = 5704.494334241538
  numbers[j+1] = 0.0014404622308674094/ numbers[j+2] = -2.853223593964335E-4/ division = -5.0485431072227955
  numbers[j+1] = -2.853223593964335E-4/ numbers[j+2] = 25.0/ division = -1.1412894375857339E-5
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.07524314593193977, -0.14519793498383293, 0.5394693754761493, -0.197878769851462, -0.48009404072635886, 4761.375597527968, -5.761783164846961E-5, -6.3404968754763E-6, 25.0, -20.0]
  numbers[j+1] = -0.14519793498383293/ numbers[j+2] = 0.5394693754761493/ division = -0.2691495413538119
  numbers[j+1] = 0.5394693754761493/ numbers[j+2] = -0.197878769851462/ division = -2.7262620233646224
  numbers[j+1] = -0.197878769851462/ numbers[j+2] = -0.48009404072635886/ division = 0.4121666862435557
  numbers[j+1] = -0.48009404072635886/ numbers[j+2] = 4761.375597527968/ division = -1.0083095334373877E-4
  numbers[j+1] = 4761.375597527968/ numbers[j+2] = -5.761783164846961E-5/ division = -8.263718819856761E7
  numbers[j+1] = -5.761783164846961E-5/ numbers[j+2] = -6.3404968754763E-6/ division = 9.087273880904064
  numbers[j+1] = -6.3404968754763E-6/ numbers[j+2] = 25.0/ division = -2.53619875019052E-7
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[0.10989738341880077, -0.1969191024672884, 1.9115527441294646, 4.155496988323788E-5, -1.008309521235744E-4, -9.285536423854238E7, 2.304712681417842E-6, -1.4089993056614E-7, 25.0, -20.0]
  numbers[j+1] = -0.1969191024672884/ numbers[j+2] = 1.9115527441294646/ division = -0.10301525975259805
  numbers[j+1] = 1.9115527441294646/ numbers[j+2] = 4.155496988323788E-5/ division = 46000.5806646134
  numbers[j+1] = 4.155496988323788E-5/ numbers[j+2] = -1.008309521235744E-4/ division = -0.4121251362608355
  numbers[j+1] = -1.008309521235744E-4/ numbers[j+2] = -9.285536423854238E7/ division = 1.0858925916713115E-12
  numbers[j+1] = -9.285536423854238E7/ numbers[j+2] = 2.304712681417842E-6/ division = -4.028934495271595E13
  numbers[j+1] = 2.304712681417842E-6/ numbers[j+2] = -1.4089993056614E-7/ division = -16.357088837144488
  numbers[j+1] = -1.4089993056614E-7/ numbers[j+2] = 25.0/ division = -5.6359972226455995E-9
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.05212181684862627, -0.10301749923518168, 13425.152691977572, 4.4752363230765706E-13, 1.0858925916712844E-12, -3.796814089996627E13, -9.218850673713952E-8, -3.1311095681364443E-9, 25.0, -20.0]
  numbers[j+1] = -0.10301749923518168/ numbers[j+2] = 13425.152691977572/ division = -7.673469464279654E-6
  numbers[j+1] = 13425.152691977572/ numbers[j+2] = 4.4752363230765706E-13/ division = 2.9998756987984584E16
  numbers[j+1] = 4.4752363230765706E-13/ numbers[j+2] = 1.0858925916712844E-12/ division = 0.4121251362612933
  numbers[j+1] = 1.0858925916712844E-12/ numbers[j+2] = -3.796814089996627E13/ division = -2.860009908128657E-26
  numbers[j+1] = -3.796814089996627E13/ numbers[j+2] = -9.218850673713952E-8/ division = 4.118533019330298E20
  numbers[j+1] = -9.218850673713952E-8/ numbers[j+2] = -3.1311095681364443E-9/ division = 29.442759740920767
  numbers[j+1] = -3.1311095681364443E-9/ numbers[j+2] = 25.0/ division = -1.2524438272545777E-10
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[3.882370509474452E-6, -7.673469464279654E-6, -2.103039706905665E16, 1.1786819730961717E-26, -2.860009908128657E-26, 4.263333772029585E20, 3.687540269023737E-9, -6.958021262525432E-11, 25.0, -20.0]
  numbers[j+1] = -7.673469464279654E-6/ numbers[j+2] = -2.103039706905665E16/ division = 3.6487515851852907E-22
  numbers[j+1] = -2.103039706905665E16/ numbers[j+2] = 1.1786819730961717E-26/ division = -1.7842299745888047E42
  numbers[j+1] = 1.1786819730961717E-26/ numbers[j+2] = -2.860009908128657E-26/ division = -0.4121251362612933
  numbers[j+1] = -2.860009908128657E-26/ numbers[j+2] = 4.263333772029585E20/ division = -6.70838846090892E-47
  numbers[j+1] = 4.263333772029585E20/ numbers[j+2] = 3.687540269023737E-9/ division = 1.1561456854702463E29
  numbers[j+1] = 3.687540269023737E-9/ numbers[j+2] = -6.958021262525432E-11/ division = -52.99696752701981
  numbers[j+1] = -6.958021262525432E-11/ numbers[j+2] = 25.0/ division = -2.783208505010173E-12
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[1.8460757049551046E-22, 3.6487515851852907E-22, -5.2072298871878E41, -2.7646955085457766E-47, -6.70838846090892E-47, 1.1347343777909453E29, -1.4750161076053896E-10, -1.5462269472278738E-12, 25.0, -20.0]
  numbers[j+1] = 3.6487515851852907E-22/ numbers[j+2] = -5.2072298871878E41/ division = -7.007087576761132E-64
  numbers[j+1] = -5.2072298871878E41/ numbers[j+2] = -2.7646955085457766E-47/ division = 1.8834731966294512E88
  numbers[j+1] = -2.7646955085457766E-47/ numbers[j+2] = -6.70838846090892E-47/ division = 0.4121251362612933
  numbers[j+1] = -6.70838846090892E-47/ numbers[j+2] = 1.1347343777909453E29/ division = -5.911857957426599E-76
  numbers[j+1] = 1.1347343777909453E29/ numbers[j+2] = -1.4750161076053896E-10/ division = -7.693030414651719E38
  numbers[j+1] = -1.4750161076053896E-10/ numbers[j+2] = -1.5462269472278738E-12/ division = 95.39454154837016
  numbers[j+1] = -1.5462269472278738E-12/ numbers[j+2] = 25.0/ division = -6.184907788911496E-14
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[3.5452164489555316E-64, -7.007087576761132E-64, -1.3203943486694417E88, 2.4364252662618483E-76, -5.911857957426599E-76, -7.77452909337256E38, 5.9000644304211934E-12, -3.4360598827286084E-14, 25.0, -20.0]
  numbers[j+1] = -7.007087576761132E-64/ numbers[j+2] = -1.3203943486694417E88/ division = 5.3068142739494135E-152
  numbers[j+1] = -1.3203943486694417E88/ numbers[j+2] = 2.4364252662618483E-76/ division = -5.419391954899945E163
  numbers[j+1] = 2.4364252662618483E-76/ numbers[j+2] = -5.911857957426599E-76/ division = -0.4121251362612933
  numbers[j+1] = -5.911857957426599E-76/ numbers[j+2] = -7.77452909337256E38/ division = 7.60413638745811E-115
  numbers[j+1] = -7.77452909337256E38/ numbers[j+2] = 5.9000644304211934E-12/ division = -1.3177024056358571E50
  numbers[j+1] = 5.9000644304211934E-12/ numbers[j+2] = -3.4360598827286084E-14/ division = -171.71017478705568
  numbers[j+1] = -3.4360598827286084E-14/ numbers[j+2] = 25.0/ division = -1.3744239530914434E-15
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[2.6849679056321607E-152, 5.3068142739494135E-152, -1.581635784615922E163, 3.1338557448306322E-115, 7.60413638745811E-115, -1.3100728469994853E50, -2.360025772168474E-13, -7.635688628285796E-16, 25.0, -20.0]
  numbers[j+1] = 5.3068142739494135E-152/ numbers[j+2] = -1.581635784615922E163/ division = -3.35526948E-315
  numbers[j+1] = -1.581635784615922E163/ numbers[j+2] = 3.1338557448306322E-115/ division = -5.04693232043264E277
  numbers[j+1] = 3.1338557448306322E-115/ numbers[j+2] = 7.60413638745811E-115/ division = 0.4121251362612933
  numbers[j+1] = 7.60413638745811E-115/ numbers[j+2] = -1.3100728469994853E50/ division = -5.8043614939995E-165
  numbers[j+1] = -1.3100728469994853E50/ numbers[j+2] = -2.360025772168474E-13/ division = 5.551095511112765E62
  numbers[j+1] = -2.360025772168474E-13/ numbers[j+2] = -7.635688628285796E-16/ division = 309.0783146166998
  numbers[j+1] = -7.635688628285796E-16/ numbers[j+2] = 25.0/ division = -3.0542754513143186E-17
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[1.69758925E-315, -3.35526948E-315, 3.5381129532088862E277, 2.392123271624348E-165, -5.8043614939995E-165, 5.569113966965522E62, 9.440103088673896E-15, -1.6968196951746212E-17, 25.0, -20.0]
  numbers[j+1] = -3.35526948E-315/ numbers[j+2] = 3.5381129532088862E277/ division = -0.0
  numbers[j+1] = 3.5381129532088862E277/ numbers[j+2] = 2.392123271624348E-165/ division = Infinity
  numbers[j+1] = 2.392123271624348E-165/ numbers[j+2] = -5.8043614939995E-165/ division = -0.4121251362612933
  numbers[j+1] = -5.8043614939995E-165/ numbers[j+2] = 5.569113966965522E62/ division = -1.0422414639796209E-227
  numbers[j+1] = 5.569113966965522E62/ numbers[j+2] = 9.440103088673896E-15/ division = 5.89942071040227E76
  numbers[j+1] = 9.440103088673896E-15/ numbers[j+2] = -1.6968196951746212E-17/ division = -556.3409663100596
  numbers[j+1] = -1.6968196951746212E-17/ numbers[j+2] = 25.0/ division = -6.787278780698485E-19
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.0, -0.0, Infinity, -4.2953390535977105E-228, -1.0422414639796209E-227, 5.888835770361958E76, -3.7760412354695584E-16, -3.7707104337213807E-19, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = -4.2953390535977105E-228/ division = -Infinity
  numbers[j+1] = -4.2953390535977105E-228/ numbers[j+2] = -1.0422414639796209E-227/ division = 0.41212513626129327
  numbers[j+1] = -1.0422414639796209E-227/ numbers[j+2] = 5.888835770361958E76/ division = -1.7698599597990817E-304
  numbers[j+1] = 5.888835770361958E76/ numbers[j+2] = -3.7760412354695584E-16/ division = -1.5595263407206063E92
  numbers[j+1] = -3.7760412354695584E-16/ numbers[j+2] = -3.7707104337213807E-19/ division = 1001.4137393581073
  numbers[j+1] = -3.7707104337213807E-19/ numbers[j+2] = 25.0/ division = -1.5082841734885524E-20
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[0.0, -0.0, Infinity, 7.294037770956036E-305, -1.7698599597990817E-304, -1.5610852220907494E92, 1.5104164941878233E-17, -8.379356519380846E-21, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 7.294037770956036E-305/ division = Infinity
  numbers[j+1] = 7.294037770956036E-305/ numbers[j+2] = -1.7698599597990817E-304/ division = -0.4121251362612933
  numbers[j+1] = -1.7698599597990817E-304/ numbers[j+2] = -1.5610852220907494E92/ division = 0.0
  numbers[j+1] = -1.5610852220907494E92/ numbers[j+2] = 1.5104164941878233E-17/ division = -1.033546196097502E109
  numbers[j+1] = 1.5104164941878233E-17/ numbers[j+2] = -8.379356519380846E-21/ division = -1802.544730844593
  numbers[j+1] = -8.379356519380846E-21/ numbers[j+2] = 25.0/ division = -3.3517426077523383E-22
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.0, -0.0, Infinity, 0.0, 0.0, -1.0329731322979623E109, -6.041665976751293E-19, -1.862079226529077E-22, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = 0.0/ division = NaN
  numbers[j+1] = 0.0/ numbers[j+2] = -1.0329731322979623E109/ division = -0.0
  numbers[j+1] = -1.0329731322979623E109/ numbers[j+2] = -6.041665976751293E-19/ division = 1.7097488280101998E127
  numbers[j+1] = -6.041665976751293E-19/ numbers[j+2] = -1.862079226529077E-22/ division = 3244.5805155202675
  numbers[j+1] = -1.862079226529077E-22/ numbers[j+2] = 25.0/ division = -7.448316906116307E-24
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[0.0, -0.0, Infinity, 0.0, -0.0, 1.7102759457493246E127, 2.416666390700517E-20, -4.137953836731282E-24, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = 1.7102759457493246E127/ division = -0.0
  numbers[j+1] = 1.7102759457493246E127/ numbers[j+2] = 2.416666390700517E-20/ division = 7.077004721589099E146
  numbers[j+1] = 2.416666390700517E-20/ numbers[j+2] = -4.137953836731282E-24/ division = -5840.244927936481
  numbers[j+1] = -4.137953836731282E-24/ numbers[j+2] = 25.0/ division = -1.6551815346925128E-25
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.0, -0.0, Infinity, -0.0, -0.0, 7.07579316398299E146, -9.666665562802069E-22, -9.19545297051396E-26, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = -0.0/ division = -Infinity
  numbers[j+1] = -0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = 7.07579316398299E146/ division = -0.0
  numbers[j+1] = 7.07579316398299E146/ numbers[j+2] = -9.666665562802069E-22/ division = -7.319786867574153E167
  numbers[j+1] = -9.666665562802069E-22/ numbers[j+2] = -9.19545297051396E-26/ division = 10512.440870285667
  numbers[j+1] = -9.19545297051396E-26/ numbers[j+2] = 25.0/ division = -3.678181188205584E-27
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[0.0, -0.0, Infinity, 0.0, -0.0, -7.320483231370316E167, 3.866666225120828E-23, -2.0434339934475466E-27, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = -7.320483231370316E167/ division = 0.0
  numbers[j+1] = -7.320483231370316E167/ numbers[j+2] = 3.866666225120828E-23/ division = -1.8932286380993646E190
  numbers[j+1] = 3.866666225120828E-23/ numbers[j+2] = -2.0434339934475466E-27/ division = -18922.3935665142
  numbers[j+1] = -2.0434339934475466E-27/ numbers[j+2] = 25.0/ division = -8.173735973790186E-29
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.0, -0.0, Infinity, 0.0, 0.0, -1.893128591105603E190, -1.5466664900483312E-24, -4.540964429883437E-29, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = 0.0/ division = NaN
  numbers[j+1] = 0.0/ numbers[j+2] = -1.893128591105603E190/ division = -0.0
  numbers[j+1] = -1.893128591105603E190/ numbers[j+2] = -1.5466664900483312E-24/ division = 1.2240056943668866E214
  numbers[j+1] = -1.5466664900483312E-24/ numbers[j+2] = -4.540964429883437E-29/ division = 34060.30841972557
  numbers[j+1] = -4.540964429883437E-29/ numbers[j+2] = 25.0/ division = -1.8163857719533748E-30
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[0.0, -0.0, Infinity, 0.0, -0.0, 1.2240416318462765E214, 6.186665960193325E-26, -1.0091032066407637E-30, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = 1.2240416318462765E214/ division = -0.0
  numbers[j+1] = 1.2240416318462765E214/ numbers[j+2] = 6.186665960193325E-26/ division = 1.9785157946494767E239
  numbers[j+1] = 6.186665960193325E-26/ numbers[j+2] = -1.0091032066407637E-30/ division = -61308.55515550602
  numbers[j+1] = -1.0091032066407637E-30/ numbers[j+2] = 25.0/ division = -4.036412826563055E-32
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.0, -0.0, Infinity, -0.0, -0.0, 1.9784835237287429E239, -2.47466638407733E-27, -2.2424515703128082E-32, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = -0.0/ division = -Infinity
  numbers[j+1] = -0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = 1.9784835237287429E239/ division = -0.0
  numbers[j+1] = 1.9784835237287429E239/ numbers[j+2] = -2.47466638407733E-27/ division = -7.994950496999671E265
  numbers[j+1] = -2.47466638407733E-27/ numbers[j+2] = -2.2424515703128082E-32/ division = 110355.39927991084
  numbers[j+1] = -2.2424515703128082E-32/ numbers[j+2] = 25.0/ division = -8.969806281251233E-34
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[0.0, -0.0, Infinity, 0.0, -0.0, -7.995022944954163E265, 9.89866553630932E-29, -4.983225711806241E-34, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = -7.995022944954163E265/ division = 0.0
  numbers[j+1] = -7.995022944954163E265/ numbers[j+2] = 9.89866553630932E-29/ division = -8.076869468543613E293
  numbers[j+1] = 9.89866553630932E-29/ numbers[j+2] = -4.983225711806241E-34/ division = -198639.7187038395
  numbers[j+1] = -4.983225711806241E-34/ numbers[j+2] = 25.0/ division = -1.9932902847224964E-35
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.0, -0.0, Infinity, 0.0, 0.0, -8.076828807849667E293, -3.959466214523728E-30, -1.1073834915124979E-35, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = 0.0/ division = NaN
  numbers[j+1] = 0.0/ numbers[j+2] = -8.076828807849667E293/ division = -0.0
  numbers[j+1] = -8.076828807849667E293/ numbers[j+2] = -3.959466214523728E-30/ division = Infinity
  numbers[j+1] = -3.959466214523728E-30/ numbers[j+2] = -1.1073834915124979E-35/ division = 357551.4936669111
  numbers[j+1] = -1.1073834915124979E-35/ numbers[j+2] = 25.0/ division = -4.429533966049992E-37
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[0.0, -0.0, Infinity, 0.0, -0.0, Infinity, 1.5837864858094913E-31, -2.4608522033611066E-37, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 1.5837864858094913E-31/ division = Infinity
  numbers[j+1] = 1.5837864858094913E-31/ numbers[j+2] = -2.4608522033611066E-37/ division = -643592.6886004399
  numbers[j+1] = -2.4608522033611066E-37/ numbers[j+2] = 25.0/ division = -9.843408813444427E-39
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.0, -0.0, Infinity, -0.0, -0.0, Infinity, -6.335145943237966E-33, -5.4685604519135706E-39, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = -0.0/ division = -Infinity
  numbers[j+1] = -0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = -6.335145943237966E-33/ division = -Infinity
  numbers[j+1] = -6.335145943237966E-33/ numbers[j+2] = -5.4685604519135706E-39/ division = 1158466.839480792
  numbers[j+1] = -5.4685604519135706E-39/ numbers[j+2] = 25.0/ division = -2.1874241807654282E-40
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[0.0, -0.0, Infinity, 0.0, -0.0, -Infinity, 2.5340583772951862E-34, -1.2152356559807935E-40, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = -Infinity/ division = 0.0
  numbers[j+1] = -Infinity/ numbers[j+2] = 2.5340583772951862E-34/ division = -Infinity
  numbers[j+1] = 2.5340583772951862E-34/ numbers[j+2] = -1.2152356559807935E-40/ division = -2085240.3110654254
  numbers[j+1] = -1.2152356559807935E-40/ numbers[j+2] = 25.0/ division = -4.860942623923174E-42
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.0, -0.0, Infinity, 0.0, 0.0, -Infinity, -1.0136233509180746E-35, -2.700523679957319E-42, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = 0.0/ division = NaN
  numbers[j+1] = 0.0/ numbers[j+2] = -Infinity/ division = -0.0
  numbers[j+1] = -Infinity/ numbers[j+2] = -1.0136233509180746E-35/ division = Infinity
  numbers[j+1] = -1.0136233509180746E-35/ numbers[j+2] = -2.700523679957319E-42/ division = 3753432.559917766
  numbers[j+1] = -2.700523679957319E-42/ numbers[j+2] = 25.0/ division = -1.0802094719829276E-43
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[0.0, -0.0, Infinity, 0.0, -0.0, Infinity, 4.054493403672298E-37, -6.001163733238486E-44, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 4.054493403672298E-37/ division = Infinity
  numbers[j+1] = 4.054493403672298E-37/ numbers[j+2] = -6.001163733238486E-44/ division = -6756178.607851979
  numbers[j+1] = -6.001163733238486E-44/ numbers[j+2] = 25.0/ division = -2.4004654932953945E-45
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.0, -0.0, Infinity, -0.0, -0.0, Infinity, -1.6217973614689192E-38, -1.3335919407196636E-45, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = -0.0/ division = -Infinity
  numbers[j+1] = -0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = -1.6217973614689192E-38/ division = -Infinity
  numbers[j+1] = -1.6217973614689192E-38/ numbers[j+2] = -1.3335919407196636E-45/ division = 1.2161121494133562E7
  numbers[j+1] = -1.3335919407196636E-45/ numbers[j+2] = 25.0/ division = -5.334367762878654E-47
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[0.0, -0.0, Infinity, 0.0, -0.0, -Infinity, 6.487189445875677E-40, -2.963537646043697E-47, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = -Infinity/ division = 0.0
  numbers[j+1] = -Infinity/ numbers[j+2] = 6.487189445875677E-40/ division = -Infinity
  numbers[j+1] = 6.487189445875677E-40/ numbers[j+2] = -2.963537646043697E-47/ division = -2.189001868944041E7
  numbers[j+1] = -2.963537646043697E-47/ numbers[j+2] = 25.0/ division = -1.1854150584174788E-48
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.0, -0.0, Infinity, 0.0, 0.0, -Infinity, -2.5948757783502705E-41, -6.5856392134304374E-49, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = 0.0/ division = NaN
  numbers[j+1] = 0.0/ numbers[j+2] = -Infinity/ division = -0.0
  numbers[j+1] = -Infinity/ numbers[j+2] = -2.5948757783502705E-41/ division = Infinity
  numbers[j+1] = -2.5948757783502705E-41/ numbers[j+2] = -6.5856392134304374E-49/ division = 3.940203364099274E7
  numbers[j+1] = -6.5856392134304374E-49/ numbers[j+2] = 25.0/ division = -2.634255685372175E-50
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[0.0, -0.0, Infinity, 0.0, -0.0, Infinity, 1.0379503113401082E-42, -1.4634753807623195E-50, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 1.0379503113401082E-42/ division = Infinity
  numbers[j+1] = 1.0379503113401082E-42/ numbers[j+2] = -1.4634753807623195E-50/ division = -7.092366055378693E7
  numbers[j+1] = -1.4634753807623195E-50/ numbers[j+2] = 25.0/ division = -5.853901523049278E-52
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.0, -0.0, Infinity, -0.0, -0.0, Infinity, -4.151801245360433E-44, -3.2521675128051545E-52, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = -0.0/ division = -Infinity
  numbers[j+1] = -0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = -4.151801245360433E-44/ division = -Infinity
  numbers[j+1] = -4.151801245360433E-44/ numbers[j+2] = -3.2521675128051545E-52/ division = 1.2766258899681647E8
  numbers[j+1] = -3.2521675128051545E-52/ numbers[j+2] = 25.0/ division = -1.3008670051220617E-53
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[0.0, -0.0, Infinity, 0.0, -0.0, -Infinity, 1.6607204981441733E-45, -7.227038917344787E-54, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = -Infinity/ division = 0.0
  numbers[j+1] = -Infinity/ numbers[j+2] = 1.6607204981441733E-45/ division = -Infinity
  numbers[j+1] = 1.6607204981441733E-45/ numbers[j+2] = -7.227038917344787E-54/ division = -2.297926601942697E8
  numbers[j+1] = -7.227038917344787E-54/ numbers[j+2] = 25.0/ division = -2.890815566937915E-55
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.0, -0.0, Infinity, 0.0, 0.0, -Infinity, -6.642881992576694E-47, -1.6060086482988416E-55, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = 0.0/ division = NaN
  numbers[j+1] = 0.0/ numbers[j+2] = -Infinity/ division = -0.0
  numbers[j+1] = -Infinity/ numbers[j+2] = -6.642881992576694E-47/ division = Infinity
  numbers[j+1] = -6.642881992576694E-47/ numbers[j+2] = -1.6060086482988416E-55/ division = 4.1362678834968543E8
  numbers[j+1] = -1.6060086482988416E-55/ numbers[j+2] = 25.0/ division = -6.424034593195367E-57
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[0.0, -0.0, Infinity, 0.0, -0.0, Infinity, 2.6571527970306775E-48, -3.568908107330759E-57, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 2.6571527970306775E-48/ division = Infinity
  numbers[j+1] = 2.6571527970306775E-48/ numbers[j+2] = -3.568908107330759E-57/ division = -7.445282190294338E8
  numbers[j+1] = -3.568908107330759E-57/ numbers[j+2] = 25.0/ division = -1.4275632429323038E-58
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.0, -0.0, Infinity, -0.0, -0.0, Infinity, -1.062861118812271E-49, -7.930906905179465E-59, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = -0.0/ division = -Infinity
  numbers[j+1] = -0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = -1.062861118812271E-49/ division = -Infinity
  numbers[j+1] = -1.062861118812271E-49/ numbers[j+2] = -7.930906905179465E-59/ division = 1.340150794252981E9
  numbers[j+1] = -7.930906905179465E-59/ numbers[j+2] = 25.0/ division = -3.172362762071786E-60
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[0.0, -0.0, Infinity, 0.0, -0.0, -Infinity, 4.2514444752490843E-51, -1.7624237567065477E-60, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = -Infinity/ division = 0.0
  numbers[j+1] = -Infinity/ numbers[j+2] = 4.2514444752490843E-51/ division = -Infinity
  numbers[j+1] = 4.2514444752490843E-51/ numbers[j+2] = -1.7624237567065477E-60/ division = -2.4122714296553655E9
  numbers[j+1] = -1.7624237567065477E-60/ numbers[j+2] = 25.0/ division = -7.049695026826191E-62
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.0, -0.0, Infinity, 0.0, 0.0, -Infinity, -1.7005777900996337E-52, -3.916497237125661E-62, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = 0.0/ division = NaN
  numbers[j+1] = 0.0/ numbers[j+2] = -Infinity/ division = -0.0
  numbers[j+1] = -Infinity/ numbers[j+2] = -1.7005777900996337E-52/ division = Infinity
  numbers[j+1] = -1.7005777900996337E-52/ numbers[j+2] = -3.916497237125661E-62/ division = 4.342088573379659E9
  numbers[j+1] = -3.916497237125661E-62/ numbers[j+2] = 25.0/ division = -1.5665988948502644E-63
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[0.0, -0.0, Infinity, 0.0, -0.0, Infinity, 6.802311160398535E-54, -8.70332719361258E-64, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 6.802311160398535E-54/ division = Infinity
  numbers[j+1] = 6.802311160398535E-54/ numbers[j+2] = -8.70332719361258E-64/ division = -7.815759432083386E9
  numbers[j+1] = -8.70332719361258E-64/ numbers[j+2] = 25.0/ division = -3.481330877445032E-65
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.0, -0.0, Infinity, -0.0, -0.0, Infinity, -2.7209244641594143E-55, -1.9340727096916842E-65, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = -0.0/ division = -Infinity
  numbers[j+1] = -0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = -2.7209244641594143E-55/ division = -Infinity
  numbers[j+1] = -2.7209244641594143E-55/ numbers[j+2] = -1.9340727096916842E-65/ division = 1.40683669777501E10
  numbers[j+1] = -1.9340727096916842E-65/ numbers[j+2] = 25.0/ division = -7.736290838766737E-67
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[0.0, -0.0, Infinity, 0.0, -0.0, -Infinity, 1.0883697856637656E-56, -4.297939354870409E-67, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = -Infinity/ division = 0.0
  numbers[j+1] = -Infinity/ numbers[j+2] = 1.0883697856637656E-56/ division = -Infinity
  numbers[j+1] = 1.0883697856637656E-56/ numbers[j+2] = -4.297939354870409E-67/ division = -2.5323060559950176E10
  numbers[j+1] = -4.297939354870409E-67/ numbers[j+2] = 25.0/ division = -1.7191757419481636E-68
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.0, -0.0, Infinity, 0.0, 0.0, -Infinity, -4.353479142655063E-58, -9.550976344156465E-69, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = 0.0/ division = NaN
  numbers[j+1] = 0.0/ numbers[j+2] = -Infinity/ division = -0.0
  numbers[j+1] = -Infinity/ numbers[j+2] = -4.353479142655063E-58/ division = Infinity
  numbers[j+1] = -4.353479142655063E-58/ numbers[j+2] = -9.550976344156465E-69/ division = 4.558150900791032E10
  numbers[j+1] = -9.550976344156465E-69/ numbers[j+2] = 25.0/ division = -3.820390537662586E-70
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[0.0, -0.0, Infinity, 0.0, -0.0, Infinity, 1.741391657062025E-59, -2.1224391875903257E-70, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 1.741391657062025E-59/ division = Infinity
  numbers[j+1] = 1.741391657062025E-59/ numbers[j+2] = -2.1224391875903257E-70/ division = -8.204671621423857E10
  numbers[j+1] = -2.1224391875903257E-70/ numbers[j+2] = 25.0/ division = -8.489756750361302E-72
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.0, -0.0, Infinity, -0.0, -0.0, Infinity, -6.9655666282481E-61, -4.716531527978501E-72, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = -0.0/ division = -Infinity
  numbers[j+1] = -0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = -6.9655666282481E-61/ division = -Infinity
  numbers[j+1] = -6.9655666282481E-61/ numbers[j+2] = -4.716531527978501E-72/ division = 1.4768408918562943E11
  numbers[j+1] = -4.716531527978501E-72/ numbers[j+2] = 25.0/ division = -1.8866126111914005E-73
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[0.0, -0.0, Infinity, 0.0, -0.0, -Infinity, 2.78622665129924E-62, -1.048118117328556E-73, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = -Infinity/ division = 0.0
  numbers[j+1] = -Infinity/ numbers[j+2] = 2.78622665129924E-62/ division = -Infinity
  numbers[j+1] = 2.78622665129924E-62/ numbers[j+2] = -1.048118117328556E-73/ division = -2.658313605341329E11
  numbers[j+1] = -1.048118117328556E-73/ numbers[j+2] = 25.0/ division = -4.192472469314224E-75
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.0, -0.0, Infinity, 0.0, 0.0, -Infinity, -1.1144906605196959E-63, -2.3291513718412356E-75, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = 0.0/ division = NaN
  numbers[j+1] = 0.0/ numbers[j+2] = -Infinity/ division = -0.0
  numbers[j+1] = -Infinity/ numbers[j+2] = -1.1144906605196959E-63/ division = Infinity
  numbers[j+1] = -1.1144906605196959E-63/ numbers[j+2] = -2.3291513718412356E-75/ division = 4.784964489614392E11
  numbers[j+1] = -2.3291513718412356E-75/ numbers[j+2] = 25.0/ division = -9.316605487364942E-77
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[0.0, -0.0, Infinity, 0.0, -0.0, Infinity, 4.457962642078784E-65, -5.175891937424968E-77, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 4.457962642078784E-65/ division = Infinity
  numbers[j+1] = 4.457962642078784E-65/ numbers[j+2] = -5.175891937424968E-77/ division = -8.612936081305906E11
  numbers[j+1] = -5.175891937424968E-77/ numbers[j+2] = 25.0/ division = -2.070356774969987E-78
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[-0.0, -0.0, Infinity, -0.0, -0.0, Infinity, -1.7831850568315134E-66, -1.1501982083166594E-78, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = -0.0/ division = -Infinity
  numbers[j+1] = -0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = -1.7831850568315134E-66/ division = -Infinity
  numbers[j+1] = -1.7831850568315134E-66/ numbers[j+2] = -1.1501982083166594E-78/ division = 1.5503284946350632E12
  numbers[j+1] = -1.1501982083166594E-78/ numbers[j+2] = 25.0/ division = -4.600792833266638E-80
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
[0.0, -0.0, Infinity, 0.0, -0.0, -Infinity, 7.132740227326054E-68, -2.5559960184814653E-80, 25.0, -20.0]
  numbers[j+1] = -0.0/ numbers[j+2] = Infinity/ division = -0.0
  numbers[j+1] = Infinity/ numbers[j+2] = 0.0/ division = Infinity
  numbers[j+1] = 0.0/ numbers[j+2] = -0.0/ division = NaN
  numbers[j+1] = -0.0/ numbers[j+2] = -Infinity/ division = 0.0
  numbers[j+1] = -Infinity/ numbers[j+2] = 7.132740227326054E-68/ division = -Infinity
  numbers[j+1] = 7.132740227326054E-68/ numbers[j+2] = -2.5559960184814653E-80/ division = -2.790591290343114E12
  numbers[j+1] = -2.5559960184814653E-80/ numbers[j+2] = 25.0/ division = -1.0223984073925861E-81
  numbers[j+1] = 25.0/ numbers[j+2] = -20.0/ division = -1.25
Final list [-0.0, -0.0, Infinity, 0.0, 0.0, -Infinity, -2.8530960909304215E-69, -5.679991152181034E-82, 25.0, -20.0]

This output shows us two things:

  • The error comes from a division 3.5381129532088862E277 / 2.392123271624348E-165 = Infinity, which sets the denominator of the division to Infinity, which in turn introduces 0s.
  • Apparition of these values is caused by a very fast decrease of all values in the list (except the last two).

We have found the source of our problem! Correcting it obviously depends on what the algorithm was supposed to do, as this is a toy example.

Still note that the error is not caused by the presence of two consecutive random numbers in the initial list, which could have been the easiest solution you may have thought of! Since errors are not always obvious, always execute your programs frequently, and use debugging tools!

Now, use the step-by-step debugger of VSCode to debug the same program. How do you do it?

Correction

As the error occurs on line 14, let’s put a breakpoint at that line. Then, running the step-by-step debugger, let’s see the contents of variables everytime it reaches this breakpoint:

i
j
numbers
0 0 [44, -38, 27, -10, -17, -28, -17, 19, -19, 45]
0 1 [-0.676923076923077, -38, 27, -10, -17, -28, -17, 19, -19, 45]
0 2 [-0.676923076923077, -1.027027027027027, 27, -10, -17, -28, -17, 19, -19, 45]
14 2 [-0.0, -0.0, -inf, -0.0, 0.0, -3.238439139240665e+104,
-1.080447209418469e-17, 9.822769774067204e-25, -19, 45]

4 — Step-by-step programming

You are going to implement a Monte Carlo strategy to estimate the value of $\pi$. The principle illustrated in the figure below is to generate pseudo-randomly the Cartesian coordinates of points located in the unit subspace, the dark cyan square. Considering $N$ pseudo-randomly generated points, the ratio between the number of points located in the top right-hand quarter of the disc and the total number of points generated is an estimate of $\frac{\pi}{4}$.

To determine if a point falls in the top right-hand quarter of the disc, one just has to compute its Euclidean distance from the origin. If this distance is less than 1, it is in the disc. As a recall, for a point whose coordinates are $(x,y)$, the distance from origin is computed as follows: $\sqrt{x^2 + y^2}$.

4.1 — Get your tools

To estimate $\pi$, you need a few programming tools:

  • A random number generator, and a method of that generator to obtain a number in the $[0, 1]$ interval. Find the correct method in the documentation of the random module.

  • A method to compute the square root of a value. Find the correct method in the documentation of the math module.

You will ask through a prompt the number of points to generate (the value to assign to N). Let’s follow some steps to reach a functioning program.

4.2 — Split your algorithm into pieces

A complete source code is always written step-by-step, and each step tested. It is clearly the best and only way to efficiency reach the objective. So, in your opinion, what should we do?

--- secondary_color: lightgray --- # Quiz Put the proposed steps in order! 1. Ask for the value of `N`. 2. Define a loop that will make `N` turns. 3. Generate random points in the unit subspace. 4. Compute the distance between a pseudo-random point and the origin. 5. Estimate the value of $\pi$.

Implement this algorithm one step after the other, and use the print statement to check that every step seems correct.

Correction

Let’s write the program one step after the other. First, let’s ask for a value of N and check that the input works as expected. We also directly add the imports and the random seed. The print helps us check that the input works well, and that our type conversion is fine.

# Needed imports
import random
import math
from typing import Tuple
from numbers import Number



# Set the seed
random.seed(42)

# Ask for a value of N
N = int(input("Enter a value for N: "))
print(N, type(N))
/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */

// Needed imports

import java.util.Random;
import java.util.Scanner;

public class Main {

    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        // Use a random number generator
        Random random = new Random();

        // Set the seed
        random.setSeed(42);

        // Ask for a value of N
        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter a value for N: ");
        int N = scanner.nextInt();
        System.out.println(N + " " + ((Object) N).getClass().getSimpleName());
    }

}

Now, let’s generate $N$ points. We check if all points seem right visually with a print, by running the program again.

# Needed imports
import random
import math
from typing import Tuple
from numbers import Number



# Set the seed
random.seed(42)

# Ask for a value of N
N = int(input("Enter a value for N: "))

# Generate N points in the unit square
points = [(random.random(), random.random()) for i in range(N)]
print(points)
/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */

// Needed imports

import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Main {

    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        // Use a random number generator
        Random random = new Random();

        // Set the seed
        random.setSeed(42);

        // Ask for a value of N
        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter a value for N: ");
        int N = scanner.nextInt();
        System.out.println(N + " " + ((Object) N).getClass().getSimpleName());

        // Generate N points in the unit square
        List<double[]> points = new ArrayList<>();
        for (int i = 0; i < N; i++) {
            double x = random.nextDouble();
            double y = random.nextDouble();
            points.add(new double[]{x, y});
        }
        for (double[] point : points) {
            System.out.println("(" + point[0] + ", " + point[1] + ")");
        }
    }

}

Everything seems right, so let’s continue. To compute the norm, let’s define a function to do it, and let’s test it for a few controlled points.

# Needed imports
import random
import math
from typing import Tuple
from numbers import Number



def norm (p: Tuple[Number, Number]) -> Number:

    """
        This function calculates the norm of a 2D point.
        In:
            * p: The point as a tuple of two numbers.
        Out:
            * The norm of the point.
    """

    # Use the formula given
    return math.sqrt(p[0]**2 + p[1]**2)



# Set the seed
random.seed(42)

# Ask for a value of N
N = int(input("Enter a value for N: "))

# Generate N points in the unit square
points = [(random.random(), random.random()) for i in range(N)]

# Test the function
print(norm((1, 1)) == math.sqrt(2))
print(norm((3, 4)) == 5)
/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */

// Needed imports

import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Main {

    /**
     * This function calculates the norm of a 2D point.
     *
     * @param p The point as an array of two numbers.
     * @return The norm of the point.
     */
    public static double norm(double[] p) {
        // Use the formula given
        return Math.sqrt(p[0] * p[0] + p[1] * p[1]);
    }

    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        // Use a random number generator
        Random random = new Random();

        // Set the seed
        random.setSeed(42);

        // Ask for a value of N
        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter a value for N: ");
        int N = scanner.nextInt();
        System.out.println(N + " " + ((Object) N).getClass().getSimpleName());

        // Generate N points in the unit square
        List<double[]> points = new ArrayList<>();
        for (int i = 0; i < N; i++) {
            double x = random.nextDouble();
            double y = random.nextDouble();
            points.add(new double[]{x, y});
        }

        // Test the function
        System.out.println(norm(new double[]{1, 1}) == Math.sqrt(2));
        System.out.println(norm(new double[]{3, 4}) == 5);
    }

}

Finally, let’s compute $\pi$.

# Needed imports
import random
import math
from typing import Tuple
from numbers import Number



def norm (p: Tuple[Number, Number]) -> Number:

    """
        This function calculates the norm of a 2D point.
        In:
            * p: The point as a tuple of two numbers.
        Out:
            * The norm of the point.
    """

    # Use the formula given
    return math.sqrt(p[0]**2 + p[1]**2)



# Set the seed
random.seed(42)

# Ask for a value of N
N = int(input("Enter a value for N: "))

# Generate N points in the unit square
points = [(random.random(), random.random()) for i in range(N)]

# Compute pi as the ratio of points inside the unit circle
circle_points = [p for p in points if norm(p) <= 1]
pi = 4 * len(circle_points) / N
print("Estimated value of pi with", N, "points:", pi)
/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */

// Needed imports

import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Main {

    /**
     * This function calculates the norm of a 2D point.
     *
     * @param p The point as an array of two numbers.
     * @return The norm of the point.
     */
    public static double norm(double[] p) {
        // Use the formula given
        return Math.sqrt(p[0] * p[0] + p[1] * p[1]);
    }

    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        // Use a random number generator
        Random random = new Random();

        // Set the seed
        random.setSeed(42);

        // Ask for a value of N
        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter a value for N: ");
        int N = scanner.nextInt();
        System.out.println(N + " " + ((Object) N).getClass().getSimpleName());

        // Generate N points in the unit square
        List<double[]> points = new ArrayList<>();
        for (int i = 0; i < N; i++) {
            double x = random.nextDouble();
            double y = random.nextDouble();
            points.add(new double[]{x, y});
        }

        // Compute pi as the ratio of points inside the unit circle
        List<double[]> circlePoints = new ArrayList<>();
        for (double[] p : points) {
            if (norm(p) <= 1) {
                circlePoints.add(p);
            }
        }
        double pi = 4.0 * circlePoints.size() / N;
        System.out.println("Estimated value of pi with " + N + " points: " + pi);
    }

}

Varying the value of $N$, observe the precision of the estimate of $\pi$ obtained.

Correction

Here are some possible results we observed. Note that because we use random numbers, you may get different results.

N
Estimate of pi
10 3.6
100 3.12
1,000 3.128
10,000 3.126
100,000 3.13728
1,000,000 3.140592
10,000,000 3.1423096
100,000,000 3.14147488

5 — A classical sorting problem

Sorting an array of values according to an ordering relation is a very classical algorithmic problem. It is often used to empirically discover theoretical concepts such as termination, complexity, etc.

The selection sort algorithm is very easy to understand. Consider you have a set of unsorted cards in your right hand and that you progressively construct a sorted permutation of these cards in your left hand. The selection sort strategy is to first select the card with the lowest value in your right hand and to place it in the first position in your left hand. You then do the same with the card having the second lowest value, and so on.

Identifies the different steps to finally have a program that generates an array of size N composed of randomly generated values, then sorts by selection this array and checks that the array is indeed sorted. Then write a function that performs that sort.

Correction
# Needed imports
import random
from typing import List
from numbers import Number



def selection_sort (l: List[Number]) -> List[Number]:
    
    """
        This function takes a list of numbers and sorts them in ascending order using the selection sort algorithm.
        In:
            * l: A list of numbers to be sorted.
        Out:
            * A sorted list of numbers.
    """

    # Initialize a new list and work on a copy
    l_copy = l.copy()
    sorted_l = []

    # Loop through the list to add the minimum element to the new list
    while len(l_copy) > 0:

        # Extract the minimum element
        # Here, we choose to use a loop to compare with the next program we will write
        # We could also use the min() function on the list
        min_element = float("inf")
        min_index = None
        for i in range(len(l_copy)):
            if l_copy[i] < min_element:
                min_element = l_copy[i]
                min_index = i

        # Add the minimum element to the new list 
        sorted_l.append(min_element)

        # Remove it from the original list
        del l_copy[min_index]
    
    # Return the sorted list
    return sorted_l



# Set the seed
random.seed(42)

# Test the function
print(selection_sort([random.randint(0, 100) for i in range(10)]))
/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */

// Needed imports

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Main {

    /**
     * This function takes a list of numbers and sorts them in ascending order using the selection sort algorithm.
     *
     * @param l A list of numbers to be sorted.
     * @return A sorted list of numbers.
     */
    public static List<Integer> selectionSort(List<Integer> l) {
        // Initialize a new list and work on a copy
        List<Integer> lCopy = new ArrayList<>(l);
        List<Integer> sortedL = new ArrayList<>();

        // Loop through the list to add the minimum element to the new list
        while (!lCopy.isEmpty()) {
            // Extract the minimum element
            // Here, we choose to use a loop to compare with the next program we will write
            // We could also use the min() function on the list
            int minElement = Integer.MAX_VALUE;
            int minIndex = -1;
            for (int i = 0; i < lCopy.size(); i++) {
                if (lCopy.get(i) < minElement) {
                    minElement = lCopy.get(i);
                    minIndex = i;
                }
            }

            // Add the minimum element to the new list
            sortedL.add(minElement);

            // Remove it from the original list
            lCopy.remove(minIndex);
        }

        // Return the sorted list
        return sortedL;
    }


    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        // Use a random number generator
        Random random = new Random();

        // Set the seed
        random.setSeed(42);

        // Test the function
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(random.nextInt(101));
        }

        // Print the sorted list
        System.out.println(selectionSort(list));
    }

}

A slight variation of the algorithm consists in positioning the lowest and largest value at the same time, the second lowest and the second largest, and so on. Implement this strategy in a new function.

Correction
# Needed imports
import random
from typing import List
from numbers import Number



def selection_sort_2 (l: List[Number]) -> List[Number]:
    
    """
        This function takes a list of numbers and sorts them in ascending order using the selection sort algorithm.
        In:
            * l: A list of numbers to be sorted.
        Out:
            * A sorted list of numbers.
    """

    # Initialize a new list and work on a copy
    l_copy = l.copy()
    sorted_l = []

    # Loop through the list to add the minimum and maximum elements to the new list
    while len(l_copy) > 0:

        # Extract the minimum and maximum elements
        min_element = float("inf")
        min_index = None
        max_element = float("-inf")
        max_index = None
        for i in range(len(l_copy)):
            if l_copy[i] < min_element:
                min_element = l_copy[i]
                min_index = i
            if len(l_copy) > 1 and l_copy[i] > max_element:
                max_element = l_copy[i]
                max_index = i

        # Add the elements to the new list
        middle = len(sorted_l) // 2
        sorted_l.insert(middle, min_element)
        if max_index is not None:
            sorted_l.insert(middle + 1, max_element)
        
        # Remove them from the original list
        # We remove the elements from the end to avoid index errors
        if max_index is not None:
            del l_copy[max(min_index, max_index)]
            del l_copy[min(min_index, max_index)]
        else:
            del l_copy[min_index]
        
    # Return the sorted list
    return sorted_l



# Set the seed
random.seed(42)

# Test the function
print(selection_sort_2([random.randint(0, 100) for i in range(10)]))
/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */

// Needed imports

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Main {

    /**
     * This function takes a list of numbers and sorts them in ascending order using the selection sort algorithm.
     *
     * @param l A list of numbers to be sorted.
     * @return A sorted list of numbers.
     */
    public static List<Integer> selectionSort2(List<Integer> l) {
        // Initialize a new list and work on a copy
        List<Integer> lCopy = new ArrayList<>(l);
        List<Integer> sortedL = new ArrayList<>();

        // Loop through the list to add the minimum and maximum elements to the new list
        while (!lCopy.isEmpty()) {
            // Extract the minimum and maximum elements
            int minElement = Integer.MAX_VALUE;
            Integer minIndex = null;
            int maxElement = Integer.MIN_VALUE;
            Integer maxIndex = null;
            for (int i = 0; i < lCopy.size(); i++) {
                if (lCopy.get(i) < minElement) {
                    minElement = lCopy.get(i);
                    minIndex = i;
                }
                if (lCopy.size() > 1 && lCopy.get(i) > maxElement) {
                    maxElement = lCopy.get(i);
                    maxIndex = i;
                }
            }

            // Add the elements to the new list
            int middle = sortedL.size() / 2;
            sortedL.add(middle, minElement);
            if (maxIndex != null) {
                sortedL.add(middle + 1, maxElement);
            }

            // Remove them from the original list
            // We remove the elements from the end to avoid index errors
            if (maxIndex != null) {
                lCopy.remove(Math.max(minIndex, maxIndex));
                lCopy.remove(Math.min(minIndex, maxIndex));
            } else {
                lCopy.remove(minIndex.intValue());
            }
        }

        // Return the sorted list
        return sortedL;
    }


    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        // Use a random number generator
        Random random = new Random();

        // Set the seed
        random.setSeed(42);

        // Test the function
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(random.nextInt(101));
        }

        // Print the sorted list
        System.out.println(selectionSort2(list));
    }

}

Use the script given below to compare the time taken by these two solutions to sort a same list. Compute and display the mean time on 10 executions for different sizes of arrays (up to $10^4$).

# Needed imports
import random
import time
import matplotlib.pyplot as plt
import tqdm
import itertools



# Constants
sizes_to_test = [10**i for i in range(1, 5)]
number_of_tests = 10

# We will store the results in a dictionary
results = {"selection_sort": {size: [] for size in sizes_to_test},
           "selection_sort_2": {size: [] for size in sizes_to_test},
           "built-in": {size: [] for size in sizes_to_test}}

# Loop for each pair test/size
# We use tqdm to display a progress bar
configurations = itertools.product(range(number_of_tests), range(len(sizes_to_test)))
nb_configurations = number_of_tests * len(sizes_to_test)
for i, (i_test, i_size) in enumerate(tqdm.tqdm(configurations, total=nb_configurations, desc="Tests")):

    # Set the seed to the loop index for reproducibility while guaranteeing a different list each time
    random.seed(i)
    l = [random.randint(0, 100) for j in range(sizes_to_test[i_size])]

    # Compare the two functions
    for function in [selection_sort, selection_sort_2]:

        # We use time.process_time() instead of time.time() to measure the CPU time instead of the wall time, which may include other processes
        t0 = time.process_time()
        result = function(l)
        elapsed_time = time.process_time() - t0

        # Store the result
        results[function.__name__][sizes_to_test[i_size]].append(elapsed_time)

    # Compare with the built-in function
    t0 = time.process_time()
    result = sorted(l)
    elapsed_time = time.process_time() - t0
    results["built-in"][sizes_to_test[i_size]].append(elapsed_time)

# Plot the average time as a function of the size
plt.figure(figsize=(10, 6))
for function_name in results:
    average_times = [sum(results[function_name][size]) / number_of_tests for size in sizes_to_test]
    plt.plot(sizes_to_test, average_times, label=function_name)
plt.xlabel("Size of the list")
plt.ylabel("Average CPU time (s)")
plt.xscale("log")
plt.yscale("log")
plt.legend()
plt.show()
/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */

// Needed imports

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

public class Main {

    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        // Define the constants
        List<Integer> sizesToTest = Arrays.asList(10, 100, 1000, 10000);
        int numberOfTests = 10;

        // Initialize random number generator
        Random random = new Random();

        // We will store the results in a map
        Map<String, Map<Integer, List<Long>>> results = new HashMap<>();
        results.put("selection_sort", new HashMap<>());
        results.put("selection_sort_2", new HashMap<>());
        results.put("built-in", new HashMap<>());
        for (int size : sizesToTest) {
            results.get("selection_sort").put(size, new ArrayList<>());
            results.get("selection_sort_2").put(size, new ArrayList<>());
            results.get("built-in").put(size, new ArrayList<>());
        }

        // Loop for each pair test/size
        for (int i = 0; i < numberOfTests; i++) {
            for (int size : sizesToTest) {
                // Set the seed to the loop index for reproducibility
                random.setSeed(i);
                List<Integer> l = new ArrayList<>();
                for (int j = 0; j < size; j++) {
                    l.add(random.nextInt(101));
                }

                // Compare the two functions
                for (String functionName : Arrays.asList("selection_sort", "selection_sort_2")) {
                    // Sort
                    long t0 = System.nanoTime();
                    if (functionName.equals("selection_sort")) {
                        List<Integer> result = selectionSort(l);
                    } else {
                        List<Integer> result = selectionSort2(l);
                    }
                    long elapsedTime = System.nanoTime() - t0;

                    // Store the result
                    results.get(functionName).get(size).add(elapsedTime);
                }

                // Compare with the built-in function
                long t0 = System.nanoTime();
                l.sort(Integer::compareTo);
                long elapsedTime = System.nanoTime() - t0;
                results.get("built-in").get(size).add(elapsedTime);
            }
        }

        // Print results (since Java does not have a built-in graphing library like matplotlib)
        for (String functionName : results.keySet()) {
            System.out.println("Function: " + functionName);
            for (int size : sizesToTest) {
                List<Long> times = results.get(functionName).get(size);
                double averageTime = times.stream().mapToLong(Long::longValue).average().orElse(0);
                System.out.println("Size: " + size + ", Average Time: " + averageTime + " ns");
            }
            System.out.println();
        }
    }

}
Correction

Here is the obtained plot:

Notice how the built-in sorted function is much faster! This function uses a more advanced algorithm called Powersort. Also, when calling sorted, the interpreter calls a compiled version of the sorting function in the background. Therefore, it can directly be interpreted as binary code by your computer, and is therefore a lot faster.

Important

Most of Python built-in functions (and those of libraries) use the same trick, so it is always better to use them rather than reinvent the wheel. The fewer loops you write, the faster your Python code!

To go further

6 — Respecting conventions

Refactor the following code to respect good programming practices.

  • Convert code that is used multiple times into a function (if you already know about functions, which are otherwise seen in session 2. If you don’t know about them, forget about the root of 144).
  • Use semantically meaningful names for variables and functions. For example, the function for calculating the square root of a number is usually called sqrt. We suggest to use this conventional name for your function.
  • Combine repeated prints into a single print call.
  • Following the Python naming convention, use snake_case for names of variables and functions.
# Let us calculate some square roots, using Heron's method

# Calculate square root of 36
x = 36
n = 1
for _ in range(10):
    n = (n + x/n) * 0.5
print("Square root of ")
print(x)
print(" is ")
print(n)

# Calculate square root of 144
x = 144
n = 1
for _ in range(10):
    n = (n + x/n) * 0.5
print("Square root of ")
print(x)
print(" is ")
print(n)
/**
 * In Java, the entry point of a program is the 'main' function, in the 'Main' class, in a file named 'Main.java'.
 * To enable asserts, you should compile your program with `javac Main.java`.
 * Then, run it with the command `java -ea Main`.
 */
public class Main
{

    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     * 
     * @param args Command line arguments received.
     */
    public static void main (String[] args)
    {
        // Calculate square root of 36
        double x = 36;
        double n = 1;
        for (int i = 0; i < 10; i++)
        {
            n = (n + x / n) * 0.5;
        }
        System.out.print("Square root of ");
        System.out.println(x);
        System.out.print(" is ");
        System.out.println(n);

        // Calculate square root of 144
        x = 144;
        n = 1;
        for (int i = 0; i < 10; i++)
        {
            n = (n + x / n) * 0.5;
        }
        System.out.print("Square root of ");
        System.out.println(x);
        System.out.print(" is ");
        System.out.println(n);
    }

}
Correction
def sqrt (x: float, nb_iterations: int = 10) -> float:

    """
        Define a function to calculate square root using Heron's method.
        In:
            * x:             Number to calculate square root.
            * nb_iterations: Number of iterations to perform to control precision.
        Out:
            * Square root of x.
    """

    # Use Heron's method to calculate square root
    n = 1
    for _ in range(nb_iterations):
        n = (n + x / n) * 0.5
    return n



# Calculate square root of 36
x = 36
result = sqrt(x)
print("Square root of", x, "is", result)

# Calculate square root of 144
x = 144
result = sqrt(x)
print("Square root of", x, "is", result)
/**
 * In Java, the entry point of a program is the 'main' function, in the 'Main' class, in a file named 'Main.java'.
 * To enable asserts, you should compile your program with `javac Main.java`.
 * Then, run it with the command `java -ea Main`.
 */
public class Main
{

    /**
     * Define a function to calculate square root using Heron's method.
     * @param x             Number to calculate square root.
     * @param nb_iterations Number of iterations to perform to control precision.
     * @return              Square root of x.
     */
    public static double sqrt (double x, int nb_iterations)
    {
        // Use Heron's method to calculate square root
        double n = 1;
        for (int i = 0; i < nb_iterations; i++)
        {
            n = (n + x / n) * 0.5;
        }
        return n;
    }



    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     * 
     * @param args Command line arguments received.
     */
    public static void main (String[] args)
    {
        // Calculate square root of 36
        double x = 36;
        double result = sqrt(x, 10);
        System.out.println("Square root of " + x + " is " + result);

        // Calculate square root of 144
        x = 144;
        result = sqrt(x, 10);
        System.out.println("Square root of " + x + " is " + result);
    }

}

7 — A classical sorting problem (again)

Design an algorithm based on sorting comparisons that satisfies the following invariant:

After i iterations of the inner loop, the i highest values of the list l of size N are sorted in an ascending order in the right side of l.

At each iteration, the first value of the array (index 0) is moved by swapping neighbours to the right until a highest value is found. In this case, it is this highest value that is moved to the right side of the array. An inner loop is used to apply the previous process until no more swaps can be performed anymore.

Correction

The correction, with music and images!

Here is a code to implement this sorting algorithm, called the “bubble sort”:

# Needed imports
import random
from typing import List
from numbers import Number



def bubble_sort (l: List[Number]) -> List[Number]:
    
    """
        This function takes a list of numbers and sorts them in ascending order using the bubble sort algorithm.
        In:
            * l: A list of numbers to be sorted.
        Out:
            * A sorted list of numbers.
    """

    # Initialize a new list
    sorted_l = l.copy()

    # Loop through the list to sort it
    for i in range(len(sorted_l)):

        # Loop through the list to compare elements
        for j in range(len(sorted_l) - 1):

            # Swap elements if they are not in the right order
            if sorted_l[j] > sorted_l[j + 1]:
                sorted_l[j], sorted_l[j + 1] = sorted_l[j + 1], sorted_l[j]
    
    # Return the sorted list
    return sorted_l
    


# Set the seed
random.seed(42)

# Test the function
print(bubble_sort([random.randint(0, 100) for i in range(10)]))
/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */

// Needed imports

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Main {

    /**
     * This function takes a list of numbers and sorts them in ascending order using the bubble sort algorithm.
     *
     * @param l A list of numbers to be sorted.
     * @return A sorted list of numbers.
     */
    public static List<Integer> bubbleSort(List<Integer> l) {

        // Initialize a new list
        List<Integer> sortedL = new ArrayList<>(l);

        // Loop through the list to sort it
        for (int i = 0; i < sortedL.size(); i++) {
            // Loop through the list to compare elements
            for (int j = 0; j < sortedL.size() - 1; j++) {
                // Swap elements if they are not in the right order
                if (sortedL.get(j) > sortedL.get(j + 1)) {
                    int temp = sortedL.get(j);
                    sortedL.set(j, sortedL.get(j + 1));
                    sortedL.set(j + 1, temp);
                }
            }
        }

        // Return the sorted list
        return sortedL;
    }


    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        // Use a random number generator
        Random random = new Random();

        // Set the seed
        random.setSeed(42);

        // Test the function
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(random.nextInt(101));
        }

        // Print the sorted list
        System.out.println(bubbleSort(list));
    }

}

If we add it to the time comparison, we obtain the following plot:

A slight improvement may certainly be applied on your algorithm to reduce the numbers of swaps. Try to find out what can be improved and compare the two versions according to the time they take to sort the same array.

Correction

Here is a possible code that implements two optimizations:

  • Introduce a flag to detect if the list is already sorted – This allows the algorithm to stop early if no swaps are made during a pass, meaning the list is already sorted.

  • Reduce the range of the inner loop – With each pass, the largest element is bubbled to the correct position, so the range of the inner loop can be reduced with each iteration.

# Needed imports
import random
from typing import List
from numbers import Number



def bubble_sort_2 (l: List[Number]) -> List[Number]:
    
    """
        This function takes a list of numbers and sorts them in ascending order using the bubble sort algorithm.
        In:
            * l: A list of numbers to be sorted.
        Out:
            * A sorted list of numbers.
    """

    # Initialize a new list
    sorted_l = l.copy()

    # Loop through the list to sort it
    n = len(sorted_l)
    for i in range(n):

        # Flag to detect if any swap was made during this pass
        swapped = False  

        # Loop through the list to compare elements
        for j in range(0, n - i - 1):

            # Swap elements if they are not in the right order
            if sorted_l[j] > sorted_l[j + 1]:
                sorted_l[j], sorted_l[j + 1] = sorted_l[j + 1], sorted_l[j]
                swapped = True 

        # If no swaps were made, the list is already sorted
        if not swapped:
            break
    
    # Return the sorted list
    return sorted_l
    


# Set the seed
random.seed(42)

# Test the function
print(bubble_sort_2([random.randint(0, 100) for i in range(10)]))
/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */

// Needed imports

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Main {

    /**
     * This function takes a list of numbers and sorts them in ascending order using the bubble sort algorithm.
     *
     * @param l A list of numbers to be sorted.
     * @return A sorted list of numbers.
     */
    public static List<Integer> bubbleSort2(List<Integer> l) {
        // Initialize a new list
        List<Integer> sortedL = new ArrayList<>(l);

        // Loop through the list to sort it
        int n = sortedL.size();
        for (int i = 0; i < n; i++) {
            // Flag to detect if any swap was made during this pass
            boolean swapped = false;

            // Loop through the list to compare elements
            for (int j = 0; j < n - i - 1; j++) {
                // Swap elements if they are not in the right order
                if (sortedL.get(j) > sortedL.get(j + 1)) {
                    int temp = sortedL.get(j);
                    sortedL.set(j, sortedL.get(j + 1));
                    sortedL.set(j + 1, temp);
                    swapped = true;
                }
            }

            // If no swaps were made, the list is already sorted
            if (!swapped) {
                break;
            }
        }

        // Return the sorted list
        return sortedL;
    }


    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        // Use a random number generator
        Random random = new Random();

        // Set the seed
        random.setSeed(42);

        // Test the function
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(random.nextInt(101));
        }

        // Print the sorted list
        System.out.println(bubbleSort2(list));
    }

}

If we add it to the time comparison, we obtain the following plot:

How can you visualize this invariant using a step-by-step debugger?

Correction

Add a breakpoint at the end of the loop. It will allow you visualize the sorted list at each iteration, and to check that the invariant holds. Here is what we get, with a breakpoint on line 37 (if not swapped:) of the improved algorithm correction.

Iteration (i + 1)
sorted_l
1 [14, 3, 81, 35, 31, 28, 17, 94, 13, 94]
2 [3, 14, 35, 31, 28, 17, 81, 13, 94, 94]
3 [3, 14, 31, 28, 17, 35, 13, 81, 94, 94]
4 [3, 14, 28, 17, 31, 13, 35, 81, 94, 94]
5 [3, 14, 17, 28, 13, 31, 35, 81, 94, 94]
6 [3, 14, 17, 13, 28, 31, 35, 81, 94, 94]
7 [3, 14, 13,17, 28, 31, 35, 81, 94, 94]
8 [3, 13, 14, 17, 28, 31, 35, 81, 94, 94]
9 [3, 3, 14, 17, 28, 31, 35, 81, 94, 94]

Note that the last iteration is not performed as the list is already sorted, which makes the invariant true for the last index as well.

To go beyond

Important

The content of this section is very optional. We suggest you directions to explore if you wish to go deeper in the current topic.

8 — Compare sorting algorithms

There are many other sorting algorithms in existence. You can for instance check this link. Try coding a few of them and compare their performance on various list sizes.

9 — Optimize your solutions

What you can now do is to use AI tools such as GitHub Copilot or ChatGPT, either to generate the solution, or to improve the first solution you came up with! Try to do this for all exercises above, to see the differences with your solutions.