Noffica
6/25/2015 - 11:35 PM

candidates.rb

require 'active_support/all'

@candidates = [
  {
    id: 5,
    years_of_experience: 4,
    github_points: 293,
    languages: ['C', 'Ruby', 'Python', 'Clojure'],
    date_applied: 5.days.ago.to_date,
    age: 26
  },
  {
    id: 7,
    years_of_experience: 1,
    github_points: 145,
    languages: ['JavaScript', 'Ruby', 'Go', 'Erlang'],
    date_applied: 15.days.ago.to_date,
    age: 19
  },
  {
    id: 9,
    years_of_experience: 6,
    github_points: 435,
    languages: ['JavaScript', 'SQL', 'C#'],
    date_applied: 1.day.ago.to_date,
    age: 32
  },
  {
    id: 10,
    years_of_experience: 3,
    github_points: 232,
    languages: ['Java', 'Ruby', 'JavaScript'],
    date_applied: 12.days.ago.to_date,
    age: 31
  },
  {
    id: 11,
    years_of_experience: 12,
    github_points: 32,
    languages: ['VB', 'Cobol', 'Fortran'],
    date_applied: 2.days.ago.to_date,
    age: 42
  },
  {
    id: 13,
    years_of_experience: 2,
    github_points: 328,
    languages: ['Python', 'Ruby', 'JavaScript'],
    date_applied: 4.days.ago.to_date,
    age: 25
  },
  {
    id: 15,
    years_of_experience: 3,
    github_points: 400,
    languages: ['JavaScript', 'Ruby'],
    date_applied: 12.days.ago.to_date,
    age: 31
  },
]
# In this file we define the methods to help filter out candidates
# This way, we keep these methods separated from other potential parts of the program

# Define a method find that:
  # Takes in an id
  # Returns the candidate with that :id
  # If there is no candidate with that id, it naturally returns nil
def find(id)
  @candidates.each do |candidate|
    return (candidate) if (candidate[:id] == id)
  end
end

# Define a method `experienced?` that:
  # Takes in a candidate (hash)
  # Returns true if the candidate has 2 years of experience or more
  # Returns false otherwise
def experienced?(candidate)
  return (candidate[:years_of_experience] >= 2)
end

# Define a method *qualified_candidates* that:
  # Takes in the collection of candidates
  # Returns a subset of the candidates that meet the following criteria:
    # Are experienced
    # Have 100 or more Github points
    # Know at least Ruby or Python
    # Applied in the last 15 days
    # Are over the age of 17 (18+)
def qualified_candidates(candidates)
  @qualified_candidates = []

  candidates.each do |candidate|
    if ( (experienced?(candidate)) && (github_points_enough?(candidate, 100)) && (know_two_languages?(candidate, 'Ruby', 'Python')) && applied_in_last_x_days?(candidate, 15) && age_limit_ok?(candidate, 18) )
      @qualified_candidates << candidate
    end
  end
  # @qualified_candidates = candidates.where((experienced?(candidate)),                            (github_points_enough?(candidate, 100)), (know_two_languages(candidate, 'Ruby', 'Python')),  applied_in_last_x_days?(candidate, 15), age_limit_ok(candidate, 18))

  return (@qualified_candidates)
end

def github_points_enough?(candidate_hash, threshold_integer)
  return ( candidate_hash[:github_points] >= threshold_integer )
end

def know_two_languages?(candidate_hash, language_one, language_two)
  return ( (candidate_hash[:languages] && [language_one, language_two]).length > 0 )
end

def applied_in_last_x_days?(candidate, days_integer)
  return ( candidate[:date_applied] >= (days_integer).days.ago.to_date )
end

def age_limit_ok?(candidate_hash, age_limit)
  return ( candidate_hash[:age] >= age_limit )
end

# Task 5 - Sort on Experience and Points
  # Define a method ordered_by_qualifications that:
    # Takes in a collection of candidates
      # Instead of filtering on the candidates, returns them all back but reordered such that:
      # Candidates with the most experience are at the top
      # For Candidates that have the same years of experience, they are further sorted by their number of Github points (highest first)
def ordered_by_qualifications(candidates)
  ordered_candidates = candidates.sort_by { |candidate| [candidate[:years_of_experience], candidate[:github_points]] }
  return (ordered_candidates).reverse
end

# Task 6 - REPL-based Menu
  # Create a REPL that presents the user with a menu where they can type in one of the following commands:

    # find 1: This will display candidate with id 1
    # all: This will print them all out to the screen (one per line)
    # qualified: This will print only qualified candidates, ordered by experience and points (one per line)
    # quit: Exit the REPL / program
    # Bonus: When printing out candidates, colour the output based on their qualification (green for qualified, red for unqualified)
def repl
  loop do
    pp "Please enter a command."
    input = gets.chomp

    case input
    when /^find\s(\d+)$/
      puts find($1)

    when "all"
      @candidates.each do |candidate|
        pp candidate
      end

    when "qualified"
      pp ordered_by_qualifications(qualified_candidates(@candidates))

    when "quit"
      break

    else
      puts "Command not recognised."
    end

    break if (input == "quit")
  end
end
# This is the main entry point into the program
# It requires the other files/gems that it needs

require 'pry'
require './candidates'
require './filters'
require 'byebug'

## Your test code can go here

# binding.pry
# byebug

pp repl