Associate software consultant at Infinity Works
Languages: Python, JavaScript, SQL
Tools: AWS, MySQL / PostgreSQL, Git
Generate prime numbers
Rust
: Check if a given number is prime
pub fn is_prime(number: u128) -> bool {
match number {
0 | 1 => false,
2 => true,
_ => {
let test_divisors = Divisors::new(number);
for divisor in test_divisors {
if number % divisor == 0 {
return false;
}
}
true
}
}
}
Calculator icon by smalllikeart
Adds features to the Raspberry Pi Sense HAT. Can play the snake game on the 8x8 LED grid.
Python
: Initialising the SnakeHat
class to describe the pixels for the
snake game
class SnakeHat(SenseHat):
'''Describes the 8x8 LED grid for a snake game.'''
def __init__(self):
'''Connect to SenseHat and create snake with one pixel.'''
super().__init__()
# Light pixels
self.clear()
snake_pixel = self.set_random_pixel(colour=(255, 0, 0))
# Describe position of snake on LED grid
self.snake = deque([snake_pixel])
self.free_coords = {
(x, y)
for x in range(8)
for y in range(8)
}
self.food_on_board = False
self.food_coord = None
Python module to create and visualise Collatz sequences.
Plots produced using collatz
Python
: Sample of the class definition for a Collatz sequence; used to create
Collatz sequences and provide methods to plot and analyse them
class Collatz(tuple):
'''Create a Collatz sequence starting from any whole number > 0.'''
# ==============================
# INTERNAL METHODS
def __new__(cls, start_number):
cls._check_valid_first_term(start_number)
sequence = cls._generate_sequence(start_number)
return super().__new__(cls, sequence)
Python
: Extract from a function used to generate a comparison plot (multiple
sequences on the same plot):
def plot_comparison(sequences, scale='linear'):
'''Plot each sequence in sequences on the same plot.'''
linear = True if scale == 'linear' else False
plt.style.use('ggplot')
plotted_sequences = 0
for sequence in sequences:
if len(sequence) == 1:
print(f'Sequence {sequence!r} not plotted as only contains one element')
continue
x_values = range(len(sequence))
sequence_label = Collatz.convert_to_scientific_form(sequence[0])
try:
plt.plot(x_values, sequence, label=sequence_label)
plotted_sequences += 1
except OverflowError:
print(f'ERROR: Sequence {sequence!r} too large to plot')
continue
...
Intuitive command-line interface for MySQL cafe database. Add people, drinks, preferences, and rounds to the database without writing complex SQL queries. Command auto-completion and suggestion makes mybrew
easy to use.
Start mybrew
by entering py -m mybrew
in the terminal
Auto-suggestion and auto-completion make mybrew
easy to use
Python
: Function in test suite checks that list overwriting behaviour is as
expected
@pytest.mark.parametrize('input_list, input_overwrite, expected_output', [
([], 'n', True),
([], 'y', True),
(['example'], 'y', True),
(['example'], 'n', False)
])
def test_want_to_overwrite(monkeypatch, input_list, input_overwrite, expected_output):
'''Test `want_to_overwrite` function returns False only if the list is
populated and the user requests no overwrite.'''
monkeypatch.setattr('builtins.input', lambda _: input_overwrite)
assert want_to_overwrite(input_list) == expected_output
Python
: Sample of mybrew
prompt that defines auto-suggestion for user
commands
mybrew_completer = NestedCompleter.from_nested_dict({
'add': {
'drink': None,
'person': None,
'preference': None,
'round': None
},
'print': table_names,
'save': table_names,
'read': table_names,
'help': None,
'clear': None,
'exit': None
})
# Get user input
user_input = prompt(FormattedText([('#268bd2', 'mybrew> ')]),
completer=mybrew_completer)
My online digital portfolio - you’re looking at it! Built using the static site generator Jekyll. Forked from Jerome Lachaud’s freelancer-theme.
HTML
/ Jekyll Liquid
: Extract from a layout file that adds a markdown-
formatted summary and a GitHub repository link to each project post. A website
link is added if available.
{{ post.summary | markdownify }}
<p>
<a href="https://github.com/{{ post.github-repo }}">
<i class="fa fa-fw fa-github"></i>
GitHub repo
</a>
</p>
{% if post.website %}
<p>
<a href="{{" post.website }}>
<i class="fa fa-fw fa-globe"></i>
Website
</a>
</p>
{% endif %} {% if post.content %}
<p>{{ post.content }}</p>
{% endif %}
Cloud database application for a cafe chain. Extracts, cleans, and transforms transaction data for business analysis. Processes 150,000 orders per day from AWS S3 and Kinesis data stream. Python Lambda functions extract and transform the data before loading it into a RedShift data warehouse. AWS QuickSight is used to analyse and visualise the data.
AWS Quicksight bar plot of highest-selling products
Grafana dashboard with AWS CloudWatch used to track metrics
Python
: Sample of the load Lambda that stores cleaned transation data as the
parent table in a relational database
with conn.cursor() as cursor:
psycopg2.extras.execute_values(cursor, """
INSERT INTO transactions_g3 VALUES %s;
""", [(
transaction['unique_id'],
transaction['date'],
transaction['time'],
transaction['location'],
transaction['first_name'],
transaction['total'],
transaction['payment_method'],
transaction['date_time']
) for transaction in transaction_list])
conn.commit()
logging.info('Transactions written to database')
YAML
: Extract from the serverless.yml file that gives the extract Lambda
permission to send JSON data to an SQS queue for further processing
iamRoleStatements:
- Effect: "Allow"
Action:
- sqs:SendMessage
- sqs:GetQueueUrl
- sqs:GetQueueAttributes
Resource: !GetAtt Group3SQSExtracttoTransform.Arn