## Instructions

**Objective**

## Requirements and Specifications

- [5 %] Write code to count the number of prime numbers from the smallest int (in the upper left) to the largest int( in the lower right). Print out the number of primes as a labelled output.
- [5 %] Write code to count the number of twin prime numbers from the smallest int (in the upper left) to the largest int( in the lower right). Print out the number of pairs of twin primes as a labelled output. [ TWIN PRIMES is a pair of prime numbers that differ by 2. The first several twin primes are: 3,5 5,7, 11,13 17,19.
- [5 %] Write code to count the number of primes per row in the rectangle. Print this out. Check that the sum of the number of primes in each row is the same as the number of primes.
- [5 %] Write code to count the number of primes per column in the rectangle. Print this out. Check that the sum of the number of primes in each column is the same as the number of primes.
- [10] A prime gap is the difference between two successive prime numbers. For your range of ints, find

- the average prime gap
- the maximum prime gap
- The most common gaps (there may be more than one most common gaps). I recommend using dictionaries – see chapter 20. What is the most number of occurrences of these more common gaps? [Hint – make a dictionary whose keys are gaps and whose corresponding values are the number of times the corresponding gap occurs. Find the largest gap occurrence number using dict.values(). Then find the gap or gaps that have that max number of occurrences.

- [40 %] Write code using the turtle module to draw a rectangle of consecutive ints from the int in the upper left to the int in the lower right. If the int is one of a pair of twin primes, the twin primes should be red. If the int is a prime (but not a twin prime), the int should be blue. Otherwise, the int is black.
- [10 %] Write your code using appropriate helper functions – you must use helper functions. This will make your code easier to write and easier to explain.
- [10 %] Every function must have a docstring just below the function header.
- [10 %] Submit a youtube link of a video that explains your code.

**Source Code
**

import turtle

UL = 4275

numRows = 31

numCols = 59

# Calcualte the final number to be shown

BR = UL + numRows*numCols - 1 # number at bottom right corner

# Define a function to know if a number is prime

def isPrime(n):

if n%2 == 0 and n != 2: # if the number is pair but it is now 2, then it is not prime

return False

for i in range(2, int(n/2)+1):

if n%i == 0:

return False

return True

"""

** QUESTION 1
**

"""

# All prime numbers are odd, so check only for odd numbers between UL and BR

primes = 0

for i in range(UL, BR+1):

if i%2 != 0 and isPrime(i):

primes += 1

print("Number of primes within range is", primes)

"""

** QUESTION 2
**

"""

print()

def getTwinPrimes(a, b):

"""

This function get all twin primes between a and b, with a gap of 2

:param a: Initial number

:param b: Final number

:return: Set with twin primes

"""

twin_primes = list()

for i in range(a, b- 1):

pair = (i, i + 2)

if pair[0] % 2 != 0 and pair[1] % 2 != 0 and isPrime(pair[0]) and isPrime(pair[1]):

twin_primes.append(pair[0])

twin_primes.append(pair[1])

return set(twin_primes)

# Now, get all twin primes

twin_primes = getTwinPrimes(UL, BR)

print("Number of twin primes within range is", len(twin_primes))

"""

**QUESTION 3
**

"""

print()

n = UL

sum_primes = 0

row_primes = list()

for row in range(numRows):

row_primes_n = 0

sum_row = 0

for col in range(numCols):

if n%2 != 0 and isPrime(n):

row_primes_n += 1

n += 1

row_primes.append(row_primes_n)

sum_primes += row_primes_n

print("The number of primes in each row is:")

print(row_primes)

print("As a check, the total number of primes is", sum_primes)

"""

** QUESTION 4
**

"""

print()

n = UL

sum_primes = 0

column_primes = list()

for col in range(numCols):

col_primes = 0

sum_col = 0

for row in range(numRows):

if n%2 != 0 and isPrime(n):

col_primes += 1

n += 1

column_primes.append(col_primes)

sum_primes += col_primes

print("The number of primes in each column is:")

print(column_primes)

print("As a check, the total number of primes is", sum_primes)

"""

** QUESTION 5
**

"""

print()

avg_gap = 0.0

max_gap = 0.0

gaps = dict() # to count the most frequent gap

gaps_lst = list()

n_gaps = 0 # count number of gaps

prev = None

for n in range(UL, BR+1):

if n%2 != 0 and isPrime(n):

if prev != None:

gap = abs(n-prev)

if gap > max_gap:

max_gap = gap

avg_gap += gap

# append gap

gaps_lst.append(gap)

# store in dict

gaps[gap] = gaps.get(gap, 0) + 1

# increment counter

n_gaps += 1

prev = n

avg_gap = avg_gap / n_gaps

# Print

print("Average prime gap is", avg_gap)

print("Max prime gap is", max_gap)

print("Prime gaps:")

print(gaps)

# Sort dict by values

gaps = {k: v for k, v in sorted(gaps.items(), key = lambda item: item[1], reverse = True)}

gaps = list(gaps.items())

print("Most common gap is", gaps[0][1])

print(f"The corresponding gaps are [{gaps[0][0]}]")

"""

**QUESTION 6
**

"""

# Create turtle screen

turtle.tracer(0,0)

turtle.speed("fastest")

wn = turtle.Screen()

# Calculate width and height

size = 20

HEIGHT = (numRows + 1)*size

WIDTH = (numCols + 1)*size

# set size

wn.setup(WIDTH, HEIGHT)

wn.bgcolor("white")

wn.title("Numbers grid")

turtle.pencolor("black")

turtle.pensize(3)

def drawSquare(pen, x, y, size):

"""

This function draws a square starting at position (x,y) with size

:param pen: Turtle object

:param x: X-position

:param y: Y-position

:param size: Size of square

:return: None

"""

pen.penup()

pen.goto(x,y)

pen.pendown()

pen.pencolor("black")

for i in range(4):

pen.forward(size)

pen.right(90)

def drawNumber(pen, n, x, y, pen_color):

"""

This function draws a number n at positions (x,y)

:param pen: Turtle object

:param n: number to be drawn

:param x: X-position

:param y: Y-position

:param pen_color: font color

:return: None

"""

pen.penup()

pen.goto(x+3, y-10)

pen.pendown()

pen.pencolor(pen_color)

pen.write(str(n), font=("Arial", 5, "normal"))

def drawGrid(pen, UL, BR, numRows, numColumns, size):

"""

This function receives a turtle object and draw a grid given the number of rows and columns

:param pen: Turtle object

:param UL: Initial number at upper-left corner

:param BR: Final number at bottom-right corner

:param numRows: Integer that defines the number of rows

:param numColumns: Integer that defines the number of columns

:param size: Integer that defines the size of each square

:return: None

"""

# Calculate width and height

HEIGHT = (numRows + 1) * size

WIDTH = (numCols + 1) * size

# Draw each square with each number

x, y = 0,HEIGHT/2# Starting positions

num = UL

font_color = "black"

# Get all twin primes

twin_primes = getTwinPrimes(UL, BR)

for row in range(numRows):

x = -WIDTH/2

for col in range(numCols):

drawSquare(pen, x, y, size)

# Check is the number is twin prime

if num in twin_primes:

font_color = "red"

elif isPrime(num): # check if it is just a prime

font_color = "blue"

else:

font_color = "black"

drawNumber(pen, num, x, y, font_color)

x += size

num += 1

y -= size

drawGrid(turtle, UL, BR, numRows, numCols, size)

wn.exitonclick()