Jeremy Oglesby
SOFTWARE DEVELOPER
A self-taught software developer with experience in Ruby on Rails, JavaScript, React, C#, and .NET. Jeremy lives in Phoenix, AZ with his wife and three children.
A self-taught software developer with experience in Ruby on Rails, JavaScript, React, C#, and .NET. Jeremy lives in Phoenix, AZ with his wife and three children.
This snippet is an adaptation of a classic technical interview problem which displays sequences of the Foobar pattern.
puts "How many turns of FooBar should we play?"
turns = gets.chomp.to_i
def foobar(turns)
current_turn = 1
output = []
turns.times do
phrase = ""
if current_turn % 3 == 0
phrase << "Foo"
end
if current_turn % 5 == 0
phrase << "Bar"
end
if phrase != ""
output << phrase
end
if current_turn % 3 != 0 && current_turn % 5 != 0
output << current_turn
end
current_turn += 1
end
return output
end
puts foobar(turns).inspect
class Image
attr_accessor :rows, :height, :length
def initialize(rows)
@rows = rows
@height = rows.count
row_lengths = 0
first_row_length = 0
rows.each_with_index do |row, index|
if index == 0
first_row_length = row.count
else
row_length = row.count
fail "All rows are not the same length!" unless first_row_length == row_length
end
row_lengths += index == 0 ? first_row_length : row_length
end
@length = row_lengths / rows.count
end
def output_image
@rows.each { |row| puts row.join(" ") }
end
def blur(distance=1)
fail "Distance supplied must be an integer!" unless distance.class == Integer
ones = []
@rows.each_with_index do |row, i|
row.each_with_index do |column, j|
if column == 1
ones << [i, j]
end
end
end
ones.each do |one_pixel|
@rows.each_with_index do |row, i|
row.each_with_index do |column, j|
if ((i - one_pixel[0]).abs + (j - one_pixel[1]).abs) <= distance
@rows[i][j] = 1 if @rows[i][j]
end
end
end
end
end
end
# EXECUTE >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
image = Image.new([
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
])
puts "Image:"
image.output_image
image.blur(3)
puts "\n\nBlurred Image:"
image.output_image
image_2 = Image.new([
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
])
puts "\n\n\nImage 2:"
image_2.output_image
image_2.blur
puts "\n\nBlurred Image 2:"
image_2.output_image
This program creates a class to simulate a pixilated image with arrays, and implements an algorithm to simulate blurring instances of an image by manipulating pixels based on Manhattan distance from a focal point.
This snippet is an implementation of the linked list data-type in Ruby. Here, I demonstrate use of a stack for iteratively reversing the order of items in a Linked List.
class LinkedListNode
attr_accessor :value, :next_node
def initialize(value, next_node=nil)
@value = value
@next_node = next_node
end
end
class Stack
attr_reader :data
def intialize
@data = nil
end
def push(value)
if @data == nil
@data = LinkedListNode.new(value)
else
new_data = LinkedListNode.new(value, @data)
@data = new_data
end
end
def pop
if @data
top_value = @data.value
@data = @data.next_node
return top_value
else
return nil
end
end
end
def print_values(list_node)
if list_node
print "#{list_node.value} --> "
print_values list_node.next_node
else
print "nil\n"
return
end
end
def reverse_list(list)
reversed_list = Stack.new
while list
reversed_list.push(list.value)
list = list.next_node
end
return reversed_list.data
end
# EXECUTE >>>>>>>>>>>>>>>>>>>>>>>>>>>>
stack = Stack.new
stack.push 2
stack.push 4
stack.push 6
stack.push 8
print_values(stack.data)
puts "---------------------------"
revlist = reverse_list(stack.data)
print_values(revlist)
class LinkedListNode
attr_accessor :value, :next_node
def initialize(value, next_node=nil)
@value = value
@next_node = next_node
end
end
def print_values(list_node)
if list_node
print "#{list_node.value} --> "
print_values(list_node.next_node)
else
print "nil\n"
return
end
end
def reverse_list(head, previous=nil)
new_head = head.next_node
head.next_node = previous
if new_head
reverse_list(new_head, head)
else
return head
end
end
def infinite_list?(head)
tortoise = head
hare = head
return t_and_h_race(tortoise, hare)
end
def t_and_h_race(tortoise, hare)
tortoise = tortoise.next_node
if hare.next_node
hare = hare.next_node.next_node
else
hare = nil
end
if tortoise == nil || hare == nil
return false
elsif tortoise == hare
return true
else
t_and_h_race(tortoise, hare)
end
end
# EXECUTE >>>>>>>>>>>>>>>>>>>>>>>>>>>>
node1 = LinkedListNode.new(2)
node2 = LinkedListNode.new(4, node1)
node3 = LinkedListNode.new(6, node2)
node4 = LinkedListNode.new(8, node3)
puts "\n**\nReverse Recursively:"
print_values(node4)
puts "---------------------------"
new_head = reverse_list(node4)
print_values(new_head)
inf_node1 = LinkedListNode.new(2)
inf_node2 = LinkedListNode.new(4, inf_node1)
inf_node3 = LinkedListNode.new(6, inf_node2)
inf_node4 = LinkedListNode.new(8, inf_node3)
inf_node1.next_node = inf_node3
puts "\n**\nDetect Infinite List:"
puts "inf_node4 is infinte? #{infinite_list?(inf_node4)}"
puts "--------------------------"
puts "node4 is infinite? #{infinite_list?(node4)}\n\n"
And here I implement a method for reversing a Linked List in a recursive manner, rather than iteratively. I also wrote a Ruby adaptation of the "Tortoise-and-Hare" algorithm to detect an infinitely looped Linked List.
This module presents 4 different algorithms for producing a Fibonacci sequence. Two are iterative, and two are recursive. I was proud to have come up with the idea, in both iterative and recursive methods, to hold on to only the last number passed, rather than building a massive array, or performing double recursion, to speed up the algorithm when only the final value of the sequence is desired as output. My 'hold' methods benchmark much faster than the traditional methods (tests and benchmarks are viewable in the GitHub repo).
module Fibonacci
def self.iterative_fib(number)
res = [0]
i = 1
first_run = true
number.times do
if first_run
res[i] = 1
first_run = false
else
res[i] = res[i - 1] + res[i - 2]
end
i += 1
end
res.last
end
def self.semi_iterative_fib(number)
res = 0
prev = 0
first_run = true
number.times do
if first_run
res += 1
first_run = false
else
hold = res
res += prev
prev = hold
end
end
res
end
def self.recursive_fib1(num)
num <= 1 ? num : recursive_fib1(num - 1) + recursive_fib1(num - 2)
end
def self.recursive_fib2(number)
fib(number, 1, 0)
end
def self.fib(times, num, previous)
if times.zero?
previous
else
hold = num
num += previous
previous = hold
times -= 1
fib(times, num, previous)
end
end
end
module TreeTraversal
def self.depth_first(payload, origin)
traversal_hash = { payload: payload, node: origin, path: [], checked: [] }
dive(traversal_hash)
end
def self.dive(hash)
res = 'Payload not found.'
unless hash[:node].nil?
if hash[:payload] == hash[:node].payload
res = hash[:node]
elsif hash[:node].children.count.zero? || all_children_checked(hash)
# climb tree
hash[:checked] << hash[:node]
if hash[:path].count.zero?
return res
else
hash[:node] = hash[:path].pop
res = dive(hash)
end
else
hash[:checked] << hash[:node]
hash[:path] << hash[:node]
i = 0
while i < hash[:node].children.count do
if hash[:checked].include?(hash[:node].children[i])
i += 1
else
hash[:node] = hash[:node].children[i]
res = dive(hash)
end
end
end
end
return res
end
def self.breadth_first(payload, origin)
traversal_hash = { payload: payload, checking: [origin], to_check: [] }
shallow_dive(traversal_hash)
end
def self.shallow_dive(hash)
res = 'Payload not found.'
unless hash[:checking].count.zero?
hash[:checking].each do |node|
res = hash[:payload] == node.payload ? node : nil
end
unless res
hash[:checking].each do |node|
node.children.each do |child|
hash[:to_check] << child
end
end
hash[:checking] = hash[:to_check]
hash[:to_check] = []
res = shallow_dive(hash)
end
end
return res
end
def self.all_children_checked(hash)
res = true
hash[:node].children.each do |child|
res = hash[:checked].include?(child)
if res == false
return res
end
end
return res
end
end
Here I've provided both depth-first and breadth-first methods for retrieval of a value from a tree structure. I worked hard to produce algorithms in response to this challenge without looking at solutions presented online, and came up with the idea to build a hash object to pass recursively into 'dive' methods for diving down the tree, and then climbing back up when needed. While my methods may not be as efficient as some classical solutions, I am proud that this module represents my raw and unaided programming in response to a challenge. (Tests viewable in GitHub repo)
This is an algorithm for sorting an array using the binary tree sort technique. As with the Tree Traversal module above, this snippet represents my raw and unaided response, as a novice developer, to the challenge of using the binary tree data structure as a sorting tool. (Tests and dependencies viewable in GitHub repo)
require 'binary_tree'
module BTreeSort
def self.sort(array)
res = []
btree_trunk = BinaryTree.new(array.slice!(0))
array.each do |item|
add_to_btree(item, btree_trunk)
end
unpack_hash = { node: btree_trunk, res: res, path: [], pushed: [] }
unpack_btree(unpack_hash)
return res
end
def self.add_to_btree(item, node)
res = nil
# compare item to payloads in depth-first manner
if item > node.payload
if node.right
res = add_to_btree(item, node.right)
else
res = BinaryTree.new(item)
node.right = res
end
else
if node.left
res = add_to_btree(item, node.left)
else
res = BinaryTree.new(item)
node.left = res
end
end
end
def self.unpack_btree(hash)
unless hash[:node].nil?
if hash[:node].right.nil? && hash[:node].left.nil?
hash[:res] << hash[:node].payload
hash[:pushed] << hash[:node]
hash[:node] = hash[:path].pop
return unpack_btree(hash)
end
if hash[:node].left # node has left
if hash[:pushed].include?(hash[:node].left) # node has pushed-left
if hash[:node].right # node has pushed-left / right
if hash[:pushed].include?(hash[:node].right) # node has pushed-left / pushed-right
hash[:node] = hash[:path].pop
return unpack_btree(hash)
else # node has pushed-left / unpushed-right
hash[:res] << hash[:node].payload
hash[:pushed] << hash[:node]
hash[:node] = hash[:node].right
return unpack_btree(hash)
end
else # node has pushed-left / no-right
hash[:res] << hash[:node].payload
hash[:pushed] << hash[:node]
hash[:node] = hash[:path].pop
return unpack_btree(hash)
end
else # node has unpushed-left
hash[:path] << hash[:node]
hash[:node] = hash[:node].left
return unpack_btree(hash)
end
else # node has no-left / right
if hash[:pushed].include?(hash[:node].right) # node has no-left / pushed-right
hash[:node] = hash[:path].pop
return unpack_btree(hash)
else # node has no-left / unpushed-right
hash[:res] << hash[:node].payload
hash[:pushed] << hash[:node]
hash[:node] = hash[:node].right
return unpack_btree(hash)
end
end
end
end
end
require 'rails_helper'
RSpec.describe GramsController, type: :controller do
describe 'grams index action' do
it 'should successfully show the page' do
get :index
expect(response).to have_http_status(:success)
end
end
describe 'grams new action' do
it 'should require users to be logged in' do
get :new
expect(response).to redirect_to new_user_session_path
end
it 'should successfully show the new form' do
user = FactoryBot.create(:user)
sign_in user
get :new
expect(response).to have_http_status(:success)
end
end
describe 'grams create action' do
it 'should require users to be logged in' do
post :create, params: { gram: { message: 'Hello!' } }
expect(response).to redirect_to new_user_session_path
end
it 'should successfully create a gram in the database' do
user = FactoryBot.create(:user)
sign_in user
post :create, params: {
gram: {
message: 'Hello!',
picture: fixture_file_upload('/picture.png', 'image/png')
}
}
expect(response).to redirect_to root_path
gram = Gram.last
expect(gram.message).to eq('Hello!')
expect(gram.user).to eq(user)
end
it 'should properly deal with validation errors' do
user = FactoryBot.create(:user)
sign_in user
gram_count = Gram.count
post :create, params: { gram: { message: '' } }
expect(response).to have_http_status(:unprocessable_entity)
expect(gram_count).to eq Gram.count
end
end
describe 'grams show action' do
it 'should successfully show the page if the gram is found' do
gram = FactoryBot.create(:gram)
get :show, params: { id: gram.id }
expect(response).to have_http_status(:success)
end
it 'should return a 404 error if the gram is not found' do
get :show, params: { id: 'TACOCAT' }
expect(response).to have_http_status(:not_found)
end
end
describe 'grams edit action' do
it 'should successfully show the edit form if the gram is found' do
gram = FactoryBot.create(:gram)
sign_in gram.user
get :edit, params: { id: gram.id }
expect(response).to have_http_status(:success)
end
it 'should return a 404 message if the gram is not found' do
user = FactoryBot.create(:user)
sign_in user
get :edit, params: { id: 'TACOCAT' }
expect(response).to have_http_status(:not_found)
end
it 'should not let unathenticated users edit a gram' do
gram = FactoryBot.create(:gram)
get :edit, params: { id: gram.id }
expect(response).to redirect_to new_user_session_path
end
it 'should not let users who did not create a gram edit it' do
gram = FactoryBot.create(:gram)
user = FactoryBot.create(:user)
sign_in user
get :edit, params: { id: gram.id }
expect(response).to have_http_status(:forbidden)
end
end
describe 'grams update action' do
it 'should allow users to successfully update grams' do
gram = FactoryBot.create(:gram, message: 'Initial Value')
sign_in gram.user
patch :update, params: { id: gram.id, gram: { message: 'Changed Value' } }
expect(response).to redirect_to root_path
gram.reload
expect(gram.message).to eq 'Changed Value'
end
it 'should return a 404 error if the gram cannot be found' do
user = FactoryBot.create(:user)
sign_in user
patch :update, params: { id: 'TACOCAT', gram: { message: 'Changed Value' } }
expect(response).to have_http_status(:not_found)
end
it 'should render the edit form with an http status of unprocessible_entity if validation fails' do
gram = FactoryBot.create(:gram, message: 'Initial Value')
sign_in gram.user
patch :update, params: { id: gram.id, gram: { message: '' } }
expect(response).to have_http_status(:unprocessable_entity)
gram.reload
expect(gram.message).to eq 'Initial Value'
end
it 'should not let unathenticated users update a gram' do
gram = FactoryBot.create(:gram, message: 'Initial Value')
patch :update, params: { id: gram.id, gram: { message: 'Changed Value' } }
expect(response).to redirect_to new_user_session_path
end
it 'should not let users who did not create a gram update it' do
gram = FactoryBot.create(:gram, message: 'Initial Value')
user = FactoryBot.create(:user)
sign_in user
patch :update, params: { id: gram.id, gram: { message: 'Changed Value' } }
expect(response).to have_http_status(:forbidden)
end
end
describe 'grams destroy action' do
it 'should allow a user to destroy a gram' do
gram = FactoryBot.create(:gram)
sign_in gram.user
delete :destroy, params: { id: gram.id }
expect(response).to redirect_to root_path
gram = Gram.find_by_id(gram.id)
expect(gram).to eq nil
end
it 'should return a 404 error if the gram to be destroyed cannot be found' do
user = FactoryBot.create(:user)
sign_in user
delete :destroy, params: { id: 'TACOCAT' }
expect(response).to have_http_status(:not_found)
end
it 'should not let unathenticated users destroy a gram' do
gram = FactoryBot.create(:gram)
delete :destroy, params: { id: gram.id }
expect(response).to redirect_to new_user_session_path
end
it 'should not let users who did not create a gram destroy it' do
gram = FactoryBot.create(:gram)
user = FactoryBot.create(:user)
sign_in user
delete :destroy, params: { id: gram.id }
expect(response).to have_http_status(:forbidden)
end
end
end
I know how to write tests! At least in RSpec...
Here are the controller tests I wrote for the Grammable app
(viewable below), which I developed in a test-driven manner.
The GitHub link for this one goes to the top level of the project
repo, with tests and the FactoryBot
model viewable in
the 'spec' directory.
A Yelp clone built in Rails that integrates with the Google Maps API and includes features like user comments, star ratings, image uploading, and user authentication.
An app that emulates an online video learning platform. Integrates video uploads with AWS content management, and credit card payment via the Stripe API. Built in Rails and utilizes nested and namespaced resources.
A simple React.js app that highlights some of the things I have been learning and building as a developer - a sort of adjunct to this portfolio page. It demonstrates basic knowledge of the React.js framework and building a componentized UI.
A React.js notes app built on top of a Rails API. Demonstrates use of multiple interacting componenets, maintenance of state, and passing of both data and functional props. Persists CRUD operations to a Postgres database via endpoints on a Rails server.
no longer viewable
An equipment database application built in Ruby on Rails with sprinklings of JQuery. Featured tiered user access and ruby scopes to allow complex search queries and filtering, and was used in production by a department of 15 people.
A spacious, soothing Instagram-like Rails app that was built using industry-standard, test-driven development following numerous red/green/refactor cycles. RSpec was used as the testing framework.
This single-page to-do application features a fluid user interface that makes all HTTP requests via JavaScript to allow a seamless user experience.
Jeremy has developed proficiency and expertise in the following programming languages and comfort with the following tools.
Currently entertaining new opportunities. Please check out my resume above.
Check out my github portfolio: jmoglesby
Get in touch via email: iaminaband@gmail.com