More results...

Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors
post
page
Python IDE Dashboard

Insertion, Bubble, Merge and Quick Sort Algorithms

In computer science, sorting algorithms are used to sort the elements of a data sets in numerical or alphabetical order. In this blog post will investigate the Python code used to implement 4 of the most frequently used sorting algorithms:

  • Insertion Sort
  • Bubble Sort
  • Merge Sort
  • Quick Sort

We will implement the first two algorithm using nested loops. (Iterative algorithms) whereas the Merge sort and Quick sort algorithms will be based on using recursive functions to implement the divide-and-conquer approach these algorithms are based on.

Insertion SortBubble SortMerge SortQuick Sort

Insertion Sort Algorithm

def insertionSort(list):
  #Iterate through each value of the list
  for i in range(1,len(list)):
    pointer = i
    
    #Slide value on the left to insert it in postion
    while list[pointer]<list[pointer-1] and pointer>0:
      #Swap values with the previous value...
      tmp=list[pointer]
      list[pointer]=list[pointer-1]
      list[pointer-1] = tmp
      
      pointer = pointer - 1
   
    #Print list at the end of each iteration
    print(list) 

Bubble Sort Algorithm

def bubbleSort(list):
  counter = len(list)-1
  sorted=False
  
  #The Bubble sort stops iterating if it did not perform any "swap" in the previous iteration.
  while sorted==False:
    sorted=True
    for pointer in range(0,counter):
      if list[pointer]>list[pointer+1]:
        #Swap values with the next value...
        tmp = list[pointer]
        list[pointer] = list[pointer+1]
        list[pointer+1] = tmp
        sorted=False
    #Print list at the end of each iteration
    print(list)  
    counter-=1

Merge Sort Algorithm

#Merge Sort: A divide-and-conquer algorithm implemented using a recursive function!
def mergeSort(list):
  midPointer = len(list) // 2
  
  leftList = list[0:midPointer]
  rightList = list[midPointer:len(list)]
  
  if len(leftList)>2: 
    leftList = mergeSort(leftList)
  else:
    if len(leftList)==2:
      if leftList[0]>leftList[1]:
        tmp = leftList[0]
        leftList[0] = leftList[1]
        leftList[1] = tmp
       
  if len(rightList)>2: 
    rightList = mergeSort(rightList)
  else:
    if len(rightList)==2:
      if rightList[0]>rightList[1]:
        tmp = rightList[0]
        rightList[0] = rightList[1]
        rightList[1] = tmp
        

  #Merge left and right...'
  leftPointer = 0
  rightPointer = 0
  sortedList=[]
  while leftPointer<len(leftList) and rightPointer<len(rightList):
    if leftList[leftPointer] < rightList[rightPointer]:
       sortedList.append(leftList[leftPointer])
       leftPointer += 1
    else:   
       sortedList.append(rightList[rightPointer])
       rightPointer += 1
  
  while leftPointer<len(leftList):
    sortedList.append(leftList[leftPointer])
    leftPointer+=1
  while rightPointer<len(rightList):
    sortedList.append(rightList[rightPointer])
    rightPointer+=1
    
  return sortedList

Quick Sort Algorithm

#Quick Sort: Another divide-and-conquer algorithm implemented using a recursive function!
def quickSort(list, leftPointer, rightPointer):
  # Use the mid value as the pivot
  pivotPointer = leftPointer + ((rightPointer-leftPointer) // 2)
  
  # Alternative approach: use the first value as the pivot
  #pivotPointer = leftPointer
  
  # Alternative approach: use the last value as the pivot
  #pivotPointer = rightPointer
  
  print("Pivot: " + str(list[pivotPointer]))
  left_Pointer = leftPointer
  right_Pointer = rightPointer
  
  while leftPointer<rightPointer:
    #Find the next value to swap (left side of the pivot)
    while list[leftPointer]<=list[pivotPointer] and leftPointer<pivotPointer:
      leftPointer = leftPointer+1
      
    #Find the next value to swap (right side of the pivot)
    while list[rightPointer]>=list[pivotPointer] and rightPointer>pivotPointer:
      rightPointer = rightPointer-1  
    
    if leftPointer<rightPointer:  
      #Swap both values 
      tmp = list[leftPointer]
      list[leftPointer] = list[rightPointer]
      list[rightPointer] = tmp
      #Has the pivot moved?
      if leftPointer == pivotPointer:
        pivotPointer = rightPointer
      elif rightPointer == pivotPointer:
        pivotPointer = leftPointer
  
  print(list)
  # Let's implement the double recursion to quick sort both sub lists on the left and the right of the pivot Pointer
  if pivotPointer-1-left_Pointer>=1: #Stop the recursion if there is only on value left in the sublist to sort
    quickSort(list,left_Pointer,pivotPointer-1)
  if right_Pointer - (pivotPointer+1)>=1: #Stop the recursion if there is only on value left in the sublist to sort
    quickSort(list,pivotPointer+1,right_Pointer)

Full Python Code

See below the full code for all four sorting algorithms.

Tagged with:

Quick Sort Algorithm

The quick sort algorithm is a divide-and-conquer algorithm that can be implemented using a recursive function. The following graphic explains the different steps of a quick sort algorithm.

Note, that the quick sort algorithm starts by identifying a pivot. Depending on the implementation, this pivot can be one of the following three values:

  • The first value of the list of values to be sorted,
  • The mid-value of the list,
  • The last value of the list.

The example below uses the mid-value of the list (value in the middle position):
Quick-Sort-Algorithm

Python Code

Here is our Python implementation of a quick sort algorithm using a recursive function. This implementation uses the mid-value as the pivot.

Tagged with:

Breadth-First Traversal of a Binary Tree

A tree is a complex data structure used to store data (nodes) in a “parent/child” relationship. The top node of a tree (the node with no parent) is called the root. Each node of a tree can have 0, 1 or several child nodes. In a Binary Tree, each node can have a maximum of two child nodes.
Binary-Search-Tree

The Breadth-First Traversal of a tree is used to read all the values of a tree, one level at a time, from the top level (root node) to the bottom level:
breadth-first-traversal

In this blog post will first:

  1. Investigate how to use Python to create a binary tree data structure,
  2. Use our binary tree data structure to initialise different binary trees,
  3. Use an algorithm to implement a breadth-first traversal of our tree,

Using a Node Class to create a Binary Tree

The following Python code is all what’s needed to create a Node/Tree structure.

#A class to implement a Node / Tree
class Node:
  def __init__(self, value, left=None, right=None):
    self.value = value
    self.left = left
    self.right = right

Initialising the values of a Binary Tree

Binary Tree #1Binary Tree #2Binary Tree #3
BST-Tree-1
BST-Tree-2
BST-Tree-3

In order to initialise the above Binary Tree (Tree #1) we will need the following Python code:

tree = Node(47)  #The root node of our binary tree
tree.left = Node(36)
tree.right = Node(66)

tree.left.left = Node(25)
tree.left.right = Node(39)
tree.left.right.left = Node(38)
tree.left.right.right = Node(42)

tree.right.left = Node(63)
tree.right.left.right = Node(64)
tree.right.right = Node(68)

Note that we have included other trees (#2 and #3) for you to initialise in Python for testing purposes.

Breadth-First Traversal of a Binary Tree

In order to implement a Breadth-First Traversal of a Binary Tree, we will need to use a queue data structure and we will base our algorithm on the following steps:

  • Initialise the queue by enqueuing the root node of the tree to traverse
  • While the queue is not empty:
    • Dequeue a node from the queue,
    • Output the value of this node,
    • Enqueue the left and right node of this node to the queue.

In Python, a queue can be implemented as a simple list:

  • Enqueuing an element to a list is done using the following instruction:
    list.append(element)
  • Dequeuing an element from a list is done by removing its first element using the following instruction:
    node = list.pop(0)
  • Checking if a queue is empty can be done by checking if the length of the list is equal to 0:
    if len(list)==0:

Full Python code for the Breadth-First Traversal of a Binary Tree

Your Task:

Tweak the above code to perform a breadth-first traversal of the two other binary trees provided in the above tabs.

Rush Hour Backtracking Algorithm

rush-hourIn this challenge we will implement a backtracking algorithm to solve a game of Rush Hour using a trial and error approach. We will also investigate the need to apply some basic heuristics to improve our algorithm and avoid a situation of stack overflow, a common issue with recursive/backtracking algorithms when there are too many paths to investigate!

First, you will need to be familiar with the rules of the Rush Hour game. You can find out more about this game on this page.

The goal of the game is to get the red car out of the parking bay through the exit of the board (on the right hand side of the 6×6 board). To do so the player has to move the other vehicles out of its way by sliding them either vertically or horizontally depending on the orientation of the vehicle. The vehicles of different colours and length (cars are 2 squares long and trucks are three squares long) are set up at the start of the game based on a given configuration). In the physical game, there are 40 different initial configurations to solve. The 40 configurations are categorised in 4 grouped based on their difficulty level: the number of moves needed to solve the puzzle. The 4 categories are: Beginner Level, Intermediate, Advanced and Expert Level!

To implement this game, we are using a 2D array/grid to represent the parking bay with all the vehicles. Each number on this array represent the colour of a vehicle. On this grid/array:

  • An empty square has a value 0,
  • The bordering walls have a value of 1.
  • The red car has a value of 2.
  • All the other colours/vehicles have a value between 3 and 14.

rush-hour-2D-grid

A backtracking algorithm is a recursive algorithm that will test potentially every possible move, one by one. To reduce the number of possibilities, a backtracking algorithm will aim to identify as soon as possible, when a move can be discarded as it will not lead to a solution. (Without the need to investigate different moves to complete the puzzle, hence saving some processing time!).

Backtracking algorithms, being recursive use a “call stack” to record/memorise the state of the variables and data structures used in the recursive function for each move in order to be able to reload them when backtracking. In this case the full copy of the 2D grid will be pushed to a the call stack for each move/call of the recursive function. Such an algorithm is hence fairly greedy in terms of system resources and when there are too many moves to investigate before reaching a solution, the code may generate a stack overflow error which would stop the execution of the code before finding a solution!

One approach to make a backtracking algorithm more effective is to apply some heuristics in the implementation of the game to try to focus first on the moves which are more likely to lead towards a solution. Our second approach is applying some basic heuristics based on the following assumptions:

  • If the red car can slide to the right, this should be the first move to make as it will bring the car closer to the exit gate so may be more likely to lead to a solution in less steps. (though this is not always the case, especially with “expert level” challenges)
  • If the red car cannot be moved to the right, the algorithm should focus on sliding other horizontal cars/trucks to the left (when possible), as this would free up spaces on the right of the grid, which could be needed to then slide vertical cars that may be obstructing the exit gate.
  • Then, the first set of vehicles to focus on are the vertical cars/trucks which are blocking the path for the red car to reach the exit gate. When possible these should be moved up or down. Trucks (which are 3 square long) should preferably moved down as if they are not parked alongside the bottom edge of the grid, they will block the path of the red car.

Python Implementation

Solution #1: Without heuristicsSolution #2: With basic heuristics
Without implementing any heuristics… This solution is ineffective and may lead to a stack overflow!

This time we have implemented some basic heuristics as described above. In this case, the algorithm is a lot quicker to find a working solution!

Tagged with:

Noah’s Ark Backtracking Algorithm

In this challenge, we are going to use a backtracking algorithm to solve a puzzle game called Noah’s Ark.

First, you will need to fully understand how the game works. You can check the “How To Play” tab on this page. The game consists of trying to fill up Noah’s Ark by positioning different pieces on a grid. Each piece represents an animal. The pieces come in different shapes (to some extent similar to the shapes using in a Tetris game) and different colours. Each colour represents an animal and, for each animal, there are two pieces of different shapes. The animals are:

  • 2 Lions (yellow),
  • 2 Zebras (red),
  • 2 Hippopotamus (blue),
  • 2 Giraffes (yellow),
  • 2 Elephants (purple).

There are just enough spaces/cells on the grid to fit all the pieces/animals. The rule is that two pieces of the same colour must be adjacent (have at least one edge in common).

The game starts with a given grid where 1,2, or 3 animals/pieces are already positioned. The player can then use a trial and error approach to position all the remaining pieces on the grid. Each puzzle (starting grid) should have a unique solution.

To implement this game in Python, we will use a 2D array to represent the ark with all its cells.
noah-s-ark-2d-grid

All our animals will also be stored as 2D arrays using different values to represent each colour:
noah-s-ark-2d-animals
A backtracking algorithm is a recursive algorithm that will test potentially every possible position of the different pieces of the game, one by one. To reduce the number of possibilities, a backtracking algorithm will try to identify as soon as possible, when an incomplete grid can be discarded as it will not lead to a solution. (Without the need to investigate different moves to complete the grid, hence saving some processing time!).

In our backtracking algorithm, we are positioning one piece at a time on the ark (the 2D grid). A soon as we place a piece on the grid, we check if the piece is in a valid position. If not we try a different position for the piece. If there is no valid position for the piece on the grid, we backtrack one step, cancelling the previous move and we then resume our search for a solution from there.

In the algorithm, an invalid position is defined as follows:

  • When positioning the piece, if we create an isolated blank cell, the grid can be discarded as it will be impossible to fill it in later on: All pieces in the game need a gap of at least two consecutives empty cells,
  • If both pieces of the selected colour (both animals of a pair) are on the grid, then we check that the two pieces are adjacent. If not, the grid is not a valid one and can be discarded.

Each puzzle to solve will always start with an initial grid with 1, 2 maybe 3 pieces already placed on the grid. Each puzzle should have a unique solution.

For this demo, we will use the following initial grid, with just one piece already in place:
noah-s-ark-2d-initial-grid

Our Solution

When running this code, you can see how the algorithm is trying to find a solution by shifting different pieces on the grid, one at a time and applying a trial and error approach, backtracking a few steps when a grid cannot be solved.

The algorithm is first trying to position the second blue piece as follows:
noah-s-ark-position-1
However this position is immediately discarded as the two blue pieces are not adjacent.

The second position to be investigated is as follows:
noah-s-ark-position-2
Once again, this position is immediately discarded as the two blue pieces are not adjacent.

The third position to be investigated by the algorithm is as follows:
noah-s-ark-position-3
In this case, the two blue pieces are adjacent, however the algorithm is discarding this position too because it has generated an isolated empty space (in the top right corner of the ark).

The 4th position to be investigated is as follows:
noah-s-ark-position-4
This position is a valid position, so the algorithm can investigate it further by starting to place other pieces till it either finds a solution or backtracks to test a fifth position of the blue piece and so on…

Python Code

You can change the SPEED constant on line 3 to speed up/slow down the algorithm. We are pausing the algorithm for a few milliseconds between each move for visualisation purpose only.

Tagged with:

Prime Factor Tree Algorithm

prime-factor-tree-150The Prime Factor Tree is a visual technique used in Maths to workout all the prime factors of a large number.

tree-leaf With this approach, all the leaf nodes (nodes without sub-branches) are the prime factors of the root node. For instance, with the above tree, the prime factors of 150 are 2, 3, 5 and 5 again. In other words:

150 = 2 x 3 x 5 x 5 = 2 x 3 x 52

We have decided to create our own Prime Factor Tree Algorithm to build a binary tree structure to store all the prime factors of any given root number.

The aim of this challenge is to demonstrate one way to implement a Binary Tree Structure in Python using a very basic Node Class.

#A class to implement a Node / Tree
class Node:
  def __init__(self, value, left=None, right=None):
    self.value = value
    self.left = left
    self.right = right

With this approach, a Tree is in fact just a Node (a root Node)!
Here is how we could create a basic prime factor tree for number 10 = 2 x 5:

tree = Node(10)
tree.left = Node(2)
tree.right = Node(5)

We then added two additional methods to our Node Class:

  1. The drawTree() method is used to draw the tree on screen. It’s based on a complex algorithm that we imported from the tree.py module.
  2. The buildPrimeFactorTree() method is used to recursively add branches/sub-nodes to our root tree to build the Prime Factor Tree progressively.

Here is the full implementation of our Prime Factor Tree Algorithm in Python:

Tagged with:

TCP/IP Protocols and Packet Switching

The TCP/IP protocols are a suite of protocols used to support different types of communication between devices over an IP network such as the Internet.

These protocols resulted from research and development conducted by the US Defense Advanced Research Projects Agency (DARPA). After initiating the pioneering ARPANET in 1969, DARPA started work on a number of other data transmission technologies which relied on packet switching: when sending data across two devices/computers, data is packetized, addressed, transmitted, routed, and received.

This research lead to the definition of the TCP/IP Protocols which are the underlying protocols for all Internet communication. They rely on packet switching and the use if IP addresses to locate devices on an IP network or on the Internet .

Packet Switching:

Let’s investigate how packet switching is used to transfer data (in the example below, a picture file) between two devices.

Step 1: Data packetsStep 2: AddressingStep 3: RoutingStep 4: Error DetectionStep 5: Re-ordering
Packet-Switching-1
Packet-Switching-2
Packet-Switching-3
Packet-Switching-4
Packet-Switching-5

Packet Switching: Quiz!

Packet Switching – Quiz!Open in New Window

The 4 Layers of the TCP Stack

Internet communications do not rely only on the TCP/IP protocol. Every communication will use a range of protocols depending on the type of data link used (Ethernet cable, Wi-Fi, Optic Fibre, etc.) as well as the type of application being used (E-Mail Client, Web Browser, FTP Client, etc.)

All the protocols used on a TCP/IP network have been categorised/grouped into 4 abstract layers called the TCP Stack.

A layer can hence be defined as being a sub-group of protocols needed in a network communication.

The four layers to the TCP stack are:

  • The Application Layer: This layer regroups a range of application protocols such as:
    • HTTP & HTTPS protocols for accessing web pages from a web server. When using the HTTPS protocol, all data being transferred is encrypted,
    • FTP protocol for transferring (downloading & uploading) files between two computers,
    • SMTP protocol for sending/transferring e-mails to an e-mail server,
    • IMAP and POP3 for retrieving e-mails from an e-mail server.

  • The Transport Layer: The main protocol of this layer is the TCP protocol used to communicate using packet switching.
  • The Internet Layer: This layer regroups routing protocols using the IP addressing system. This layer regroups the IP protocols such as IPv4 protocol and more recently the IPv6 protocol for uniquely addressing devices on the Internet.
  • The Link Layer (aka Physical Layer): This layer regroups various protocols used to transfer data across a data link. This includes the Ethernet protocol used to transfer data over an Ethernet cable and various wireless communication protocols (Wi-Fi, Bluetooth, etc.). The protocols used depend on the type of hardware, network topologies and communication links being used to transfer data across the network.

IP Addresses vs. Domain Names

When we use our web browser to access a web page, it is very unlikely that we know the IP address of the web-server hosting the required web page. We may however enter a web address / URL using a domain name such as 101computing.net.

Domain Name Servers (DNS) are the Internet’s equivalent of a phone book. They maintain a directory of domain names and translate them to numerical IP addresses. These IP addresses are used to identify and locate the web-servers on the Internet.

Domain names such 101computing.net are easy for people to remember. Computers however access websites based on IP addresses, hence the needs for domain name servers: when typing a website address in your web browser such as http://www.101computing.net, your request will reach a domain name server that will convert the domain name part of the address (101computing.net) into its matching IP address.

DNS-Domain-Name-Server


Did you know?


Currently most IP addresses are using the IPv4 format, based on 4 numbers between 0 and 255 sepearated by a dot.
ipv4

The IPv4 protocol however will soon be upgraded to the IP version 6 (IPv6) internet protocol. The reason for this upgrade is that there is need to generate more IP addresses to allow more devices (webservers, desktops, laptops, smartphones, smartwatches and other connected objects) to have a unique IP address on the network. An IPv6 address is based on 128 bits (instead of 32 bits for an IPv4 address).
ipv6

MI6: Mission Alpha

cyber-securityThis is a confidential mission with the highest level of priority. The MI6 needs your skill to complete a very confidential mission:

Mission Code: Alpha-01

Mission Priority: Critical

Mission Context:
The MI6 network has been hacked! As a result, all of our secret agents’ smartphones have been locked and so has the main MI6 Server. All Mi6 operations are currently on pause as it is impossible for us to communicate effectively with our secret agents.

A network forensic team has been dispatched at the Mi6 headquarters. They are currently reviewing all the log files for the past 12 hours to see if the hacker has left any “footprints” when hacking into the network. The MI6 firewall has not detected any suspicious activity and we hence believe the hack was the result of an insider attack. While scanning the main servers for malware, the network forensic team identified twelve suspicious files containing computer code.

We believe these 12 extracts of code have been used to lock the smartphones of our 12 secret agents (001 to 012).

To unlock the main server, we need an activation code. This activation code consists of 12 short codes of 3 characters each. We believe each agent was sent one of these short codes.

Mission Code: Alpha-01

Your Task:
Study the 12 code extracts to unlock the phones of our twelve secret agents. If you manage to unlock a phone, check if a message was sent to this phone to retrieve the 3-character long activation code. Repeat this process for each phone to retrieve the 12 activation codes. Enter these codes in the corresponding input boxes to check them one at a time. Then enter them on the tablet below to regain full access to the MI6 server.

MI6: Mission Alpha-01Open in New Window


Mission Code: Alpha-02

Mission Code: Alpha-02

Mission Priority: Critical

Mission Context:
Following this recent hacking attack on the MI6 central server and on all our secret agents’ smartphones, a Network Forensics Team from the MI6 Cyber Security Division has been tasked to:

  1. Conduct a Network Forensics Analysis of the recent hacking attack.
  2. Perform a full review of the current network security measures in place at the MI6 to protect the network against a wide range of potential threats.
MI6: Mission Alpha-02: Network Forensics ReportOpen in New Window

Your Task:
The Network Forensics Team needs your help to complete the full review of the Network Security measures in place at the MI6. Your task is to complete the table in the report to describe the potential Network Security threats and use the information given in the Network Forensic Report to identify the measures currently in place to minimise/prevent these threats.


Mission Code: Alpha-03

Mission Code: Alpha-03

Mission Priority: High

Mission Context:
Now that you have completed a full review of the Network Security measures used to protect the MI6 network from various threats we would like you to you to make additional recommendations on how the MI6 could make sure their network is even more secure. To do so we would like you to create a presentation to describe how the following strategies could be used to protect the network further and, for each of them, identify the threat(s) that they would address:

  1. Penetration testing,
  2. 2-Step Authentication,
  3. Additional Authentication Methods using Biometrics,
  4. CAPTCHA,
  5. SPAM filters,
  6. Account Lockout Threshold,
  7. Proxy Servers,
  8. VPNs.

Dice Score Frequency Analysis

two-diceIn this challenge we will use a Python algorithm to perform a frequency analysis of the score obtained when throwing a set of two dice.

Frequency analysis using 1 dice


Let’s consider a single 6-sided dice.

When using single dice, the score of the dice can be any of the 6 values/sides (1 to 6). Each value has an equal probability of 1/6.

The dice experiment can be simulated using a computer algorithm to simulate throwing a dice a 1,000 times and keeping a record of the number of times each of the 6 values appeared. We can then calculate the frequency of each value as a percentage. In theory, each value should have a very similar frequency of around 16.67% (matching the 1/6 probability).

When completing such an experiment in real life, we would mot likely use a tally chart to record the number of occurrences for each of the 6 possible values.
dice-tally-chart

To record our “tallies” in a Python program we will use a dictionary with 6 keys (the 6 values of a dice, from 1 to 6) and for each key, the associated value will be the number of occurrences of when the value appeared.

Here is the Python implementation of our dice experiment (frequency analysis).

Run the above code several times.

  • Do you notice the frequencies changing slightly every time you run this code?
  • Does the experiment confirm the theory: each side having an equal probability, the percentage for each value should be 16.67%?
  • What do you think will happen if, instead of 1,000 iterations you were completing 1,000,000 iterations?
  • Change the value of n in the above code from 1,000 to 1,000,000 and run the code. Does the outcome confirm your prediction?

Using two dice


We are now going to simulate the same experiment, this time using two dice, and recording the total score (by adding the value of both dice). The dice score will be as follows:

Total Score Possible Combinations Probability
2 1+1 1/36 = 2.78%
3 1+2 or 2+1 2/36 = 5.56%
4 1+3 or 2+2 or 3+1 3/36 = 8.33%
5 1+4 or 2+3 or 3+2 or 4+1 4/36 = 11.11%
6 1+5 or 2+4 or 3+3 or 4+2 or 5+1 5/36 = 13.89%
7 1+6 or 2+5 or 3+4 or 4+3 or 5+2 or 6+1 6/36 = 16.67%
8 2+6 or 3+5 or 4+4 or 5+3 or 6+2 5/36 = 13.89%
9 3+6 or 4+5 or 5+4 or 6+3 4/36 = 11.11%
10 4+6 or 5+5 or 6+4 3/36 = 8.33%
11 5+6 or 6+5 2/36 = 5.56%
12 6+6 1/36 = 2.78%

Your Task:


Your task consists of adapting the Python program given above (1 dice experiment) to implement the experiment with two dice and see whether your program produces the expected probabilities for all possible scores from 1 to 12.
unlock-access

Solution...

The solution for this challenge is available to full members!
Find out how to become a member:
➤ Members' Area
Tagged with:

Random Odd and Even Numbers

random-numbersIn this challenge we will focus on using the random library to generate random numbers in Python.

The randint() function is used to generate a random integer (whole number) within a given range.

import random
number = randint(1,100)

The above code would generate a random number between 1 and 100.

The aim of this challenge is to write our own function called randomOddNumber() to generate a random odd number within a given range and a another function called randomEvenNumber() to generate a random even number. Both functions will take two parameters, the lower and higher values of the range.

Random Odd Number Functions


We will investigate three different algorithms to implement the randomOddNumber() function:
Method #1: SequencingMethod #2: IterationMethod #3: Selection
The first method is based on a sequencing algorithm.
sequencing-label
Here is the approach we will use:
To generate an odd number, let’s say between 0 and 100, we will first generate a random number between 0 and 49, then multiply this number by 2 (this will hence become an even number between 0 and 98) and finally we will add 1 to make it an odd number (between 1 and 99).

Python Code:

The second algorithm is based on a while loop (a form of iteration).
iteration-label
With this approach we are generating a random number between 1 and 100. We will repeat this process as long as the number generated is even (not odd). A number is even if the remainder of dividing this number by two is zero.

Python Code:

Our third approach will be based on using an IF statement, a form of selection.
selection-label
We will generate a random number, check if this number is odd or even by checking whether the remainder of dividing this number by two is zero (for an even number) or 1 (for an odd number). If the number is even, we will add 1 to this number to change it to an odd number.

Python Code:

Random Even Number Functions


Your task consists of adapting the above three functions to create three additional functions, this time to generate random even numbers using all three methods/programming constructs: sequencing, selection and iteration.

Extension Task: Random Prime Number Function


For this more complex extension task, you will need to write a function called randomPrimeNumber() to generate a random prime number within a given range. This function will take two parameters: the lower and higher values of the range.

unlock-access

Solution...

The solution for this challenge is available to full members!
Find out how to become a member:
➤ Members' Area
Tagged with: