3
\$\begingroup\$

There are no requirements for this project nor will it ever be used for any purpose.

I used this project to cement my knowledge of basic programming skills, I got bored copying the examples and felt I would learn faster if I built everything into a functional program with a little complexity. It follows British registration number formatting in case you're curious

Any feedback is appreciated. The code is below, but I have it on github if you prefer to try it out yourself.

https://github.com/Niall47/RubySomDemo use (V3.rb)

require 'json'
require 'colorize'

class Car
  attr_accessor :vrm
  attr_accessor :make
  attr_accessor :model
  attr_accessor :description
  attr_accessor :colour
  attr_accessor :date

  def initialize(aMake, aModel, aDescription, aColour, aVRM, aManufactureDate)
    @vrm = aVRM
    @make = aMake
    @model = aModel
    @description = aDescription
    @colour = aColour
    @date = aManufactureDate
  end

  def text_format
    return "#{@vrm} -- #{@make} #{@model}  #{@date} (#{@description}, #{@colour})"
  end
end

def save_to_file
  @back_up = Hash.new
  $all_vehicles.each do |a_vehicle |
  #itterate through each record and create a hash with vrm as key
    @back_up[a_vehicle[1].vrm] = a_vehicle[1].make, a_vehicle[1].model, a_vehicle[1].colour, a_vehicle[1]. description, a_vehicle[1].date
  end
  File.write("vehicles.json",@back_up.to_json)
  p 'Saved records to \'vehicles.json\''
end

def open_file
  $all_vehicles = {}
  #If file exists itterate through records and recreate objects
  if File.file?("vehicles.json")
    File.open('vehicles.json') do |f|
      @load_vehicles = JSON.parse(f.read)
    end
    @load_vehicles.each do |a_vehicle|
      new_car = Car.new(a_vehicle[1][0], a_vehicle[1][1], a_vehicle[1][3], a_vehicle[1][2], a_vehicle[0], a_vehicle[1][4])
      $all_vehicles[new_car.vrm] = new_car
    end
    count
  else
    p 'Unable to find file, creating blank file'
    save_to_file
  end
end

def count
  p "You have #{$all_vehicles.count} records on file"
end

def gen_vrm(aManufactureDate)
  suffix_age = { 1963 => "A",1964 => "B",1965 => "C",1966 => "D",1967 => "E",1968 => "F",1969 => "G",1970 => "H",1971 => "J",1972 => "K",
1973 => "M",1974 => "N",1975 => "P",1976 => "R",1977 => "S",1978 => "T",1979 => "V",1980 => "W",1981 => "X",1982 => "Y"}
  prefix_age = { 1983 => "A",1984 => "B",1985 => "C",1986 => "D",1987 => "E",1988 => "F",1989 => "G",1990 => "H",1991 => "J",1992 => "K",
1993 => "L",1994 => "M",1995 => "N",1996 => "P",1997 => "R",1998 => "S",1999 => "T",2000 => "V",2001 => "W",}
  if aManufactureDate.is_a?Integer
     if (1983..2001).include?(aManufactureDate)    #PREFIX STYLE
       prefix = prefix_age[aManufactureDate]
       numbers =('0'..'9').to_a.shuffle.first(3).join
       suffix =('A'..'Z').to_a.shuffle.first(3).join
       @vrm = (prefix.to_s + numbers +suffix.to_s)
     elsif (1963..1982).include?(aManufactureDate) # SUFFIX STYLE
       prefix =('A'..'Z').to_a.shuffle.first(3).join
       numbers =('0'..'9').to_a.shuffle.first(3).join
       suffix = suffix_age[aManufactureDate]
       @vrm = (prefix.to_s + numbers + suffix.to_s)
     elsif (1903..1962).include?(aManufactureDate)   # HISTORIC
       numbers =('0'..'9').to_a.shuffle.first(1).join
       suffix =('A'..'Z').to_a.shuffle.first(3).join
        if (1903..1930).include?(aManufactureDate)
       @vrm = (numbers + suffix.to_s)
        else
          @vrm = (suffix.to_s + numbers)
        end
     elsif aManufactureDate > 2001                 #CURRENT STYLE
       prefix =('A'..'Z').to_a.shuffle.first(2).join
       extract_year = aManufactureDate.to_s #Convert to string so we can grab the last 2 digits
       extract_year.to_i
       numbers = extract_year.chars.last(2).join
       suffix =('A'..'Z').to_a.shuffle.first(3).join
       @vrm = (prefix.to_s + numbers + suffix.to_s)
     else                                          #Q PLATE
       prefix = "Q"
       numbers =('0'..'9').to_a.shuffle.first(3).join
       suffix =('A'..'Z').to_a.shuffle.first(3).join
       @vrm = (prefix.to_s + numbers + suffix.to_s)
     end
  end
end

def check_valid?(aVRM, aManufactureDate)
#VRM should be unique, not be blank, not contain letter 'I' 
#and only contain 'Q' as first character for vehicles with no manufacture date
  bad_value = (aVRM.nil?) || (aVRM.include?("I")) 
  bad_q = aVRM.include?("Q") && (aVRM[0] != 'Q' || (aVRM[0] == "Q" && (1903..2019).include?(aManufactureDate)))
  already_exists = $all_vehicles[aVRM]
  return !(bad_value || bad_q || already_exists)
end

def add_new
  p "Manufacture Date?"
  aManufactureDate = gets.to_i
  new_vrm = ''
  30.times do
    new_vrm = gen_vrm(aManufactureDate)
    break if check_valid?(new_vrm, aManufactureDate)
    new_vrm = ''
  end
  raise 'We were unable to generate a valid VRN' if new_vrm.empty?
  p "New VRM generated: #{new_vrm}"
  p 'Make?'
  make = gets.chomp!
  p 'Model?'
  model = gets.chomp!
  p 'Description?'
  description = gets.chomp!
  p 'Colour?'
  colour = gets.chomp!
  # Make the car object
  new_car = Car.new(make, model, description, colour, new_vrm, aManufactureDate)
  # Add the car to our big list
  $all_vehicles[new_vrm] = new_car
  p "We added #{new_car.text_format} to the list"
end

def show_registrations
  p 'Printing all registration marks on file:'
    p  $all_vehicles.keys
end

def search
  p 'Search by: [1]VRM, [2]Manufacture, [3]Model, [4]Year'
  match_field = gets.to_i
  p 'Enter the exact value to match against'
  match_value = gets.chomp!
   found_vehicle = nil
  found_list = []
  #Search stops when it finds VRM, but continues for everything else to generate a list
  $all_vehicles.each do |a_vehicle|
    case match_field
    when 1
      found_vehicle = a_vehicle if a_vehicle[1].vrm == match_value
    when 2
      found_list << a_vehicle if a_vehicle[1].make == match_value
    when 3
      found_list << a_vehicle if a_vehicle[1].model == match_value
    when 4
      found_list << a_vehicle if a_vehicle[1].date == match_value.to_i
    else
      p "There is no option #{match_field}"
      break
    end
    break if found_vehicle
  end

  if found_vehicle
     text =  "Found a vehicle : #{found_vehicle}"
     p found_vehicle[1].text_format
  elsif found_list != []
    p 'Found these vehicles'
    found_list.each do |vehicles|
      p vehicles[1].text_format
    end
  else
    p "Unable to find a vehicle for #{match_value}"
  end
end

def bulk_add
  make_model = {
  "audi" =>%w[A1 A3 A4 A5 A6 A7 A8 Allroad Quattro Cabriolet E-tron Fox Q2 Q3 Q5 Q7 Q8 R8 RS Q3 RS3 RS4 RS5 RS6 RS7 S1 S2 S3 S4 S5 S6 S7 S8 SQ5 SQ7 TT V8_Quattro],
  "aston_martin" =>%w[DB11 DB4 DB5 DB6 DB7 DB9 DBS Lagonda_Rapide V12_Vanquish V8_Vanquish Vantage Virage Volante],
  "bmw" =>%w[1_Series 2_Series 3_Series 4_Series 5_Series 6_Series 7_Series i3 i4 i8 M2 M3 M4 M5 M6 X1 X2 X3 X4 X5 X6 X7 Z3 Z4],
  "citroen" =>%w[Ax Berlingo C2 C3 C4 C4 Aircross C4_Cactus C4_Picasso C5 C6 CX_D Dispatch DS DS3 DS4 DS5 C4_Picasso Xantia Xsara],
  "daewoo" =>%w[Cielo Espero Kalos Korando Lacetti Lanos Leganza Matiz Musso Nubira Tacuma],
  "fiat" =>%w[Argenta Croma Doblo DUCATO Freemont Panda PANORAMA Punto Regata Ritmo Scudo Superbrava],
  "jauguar" =>%w[240 340 420 E_Type Majestic S-TYPE Sovereign V12_Vanden X-TYPE XE XF XJ XJ12 XJ6 XJ8 XJR XJS XJSC XK XK8 XKR],
  "land_rover" =>%w[Defender Discovery Discovery_3 Discovery_4 Discovery_Sport Freelander Freelander_2 Range_Rover Range_Rover_Evoque Range_Rover_Sport],
  "nissan" =>%w[300ZX 350Z 370Z Almera Altima Bluebird Cabstar Cedric Cube Dualis Elgrand Gazelle GT-R Homer Juke Leaf Maxima Micra Murano Navara Nomad NX-R Pathfinder Patrol Pintara Pulsar Qashqai Serena Skyline Stanza Sunny TERRANO_II Ute X-Trail],
  "mercedes" =>%w[A150 C220 C230 C280 C320 C350 C43_AMG E63 S65 SLS Sprinter Valente Viano Vito],
  "mitsubishi" =>%w[3000 Challenger Colt Cordia D50 Eclipse Cross Express Galant Grandis L200 L300 Lancer Magna Mirage Nimbus Outlander Pajero Pajero_Sport Sigma Starion Triton Verada],
  "renault" =>%w[Alaskan Captur Caravelle Clio Clio_RS Dauphine Floride Fluence Fuego Grand_Scenic Kadjar Kangoo Koleos Laguna Latitude Master Megane RS R25 R4 R8 Scenic Trafic Virage Zoe],
  "vauxhall" =>%w[Astra Corsa Insignia Zafira],
  "vw" =>%w[Amarok Arteon Beetle Bora Caddy Caravelle Citivan CRAFTER Eos Golf Jetta Karmann Kombi Multivan Passat Polo Scirocco T-CROSS Tiguan Touareg Transporter Up! Vento]
  }
  description = %w[fast slow low broken stolen slammed undercover untaxed exported cloned]
  colour = %w[blue red green silver grey white black]
  p 'How many records are we generating?'
  count = gets.chomp.to_i
  count.times do |index|
    @aManufactureDate = rand(1903..2019).to_i # in theory no Q plates
    #if we don't get a valid vrm after 30 tries then something is wrong
    30.times do
      @new_vrm = gen_vrm(@aManufactureDate)
      break if check_valid?(@new_vrm, @aManufactureDate)
      @new_vrm = ''
    end
    raise 'We were unable to generate a valid VRN' if @new_vrm.empty?
      make = make_model.keys.sample
      model = make_model[make].sample
      new_car = Car.new(make, model, description.sample, colour.sample, @new_vrm, @aManufactureDate)
      $all_vehicles[@new_vrm] = new_car
      p "We added #{new_car.text_format} to the list"
  end
end

def help
  p ("new - adds new record")
  p ("search - allows you to search by VRM, make, model and manufacture date")
  p ("save - backs up all records to vehicles.json")
  p ("vrm - displays all VRMs currently on file")
  p ("count - displays number of current records")
  p ("bulk - generates new records")
end

def ascii_intro
  if File.file?("intro.txt") #print from a file so ruby can't parse through and ruin it
      File.open('intro.txt').each do |line|
      print line.red
    end
  end
end

########################  Program starts here  ########################

default_message = 'OPTIONS: new, search, save, bulk, vrm, count, help & exit'
$all_vehicles = {}
input = nil
ascii_intro
open_file

while input != ("exit")
  p default_message
  input = gets.downcase.chomp!
  case input
  when "new"
    add_new
  when "help"
    help
  when "search"
    search
  when "count"
    count
  when "bulk"
    bulk_add
  when "vrm"
    show_registrations
  when "save"
    save_to_file
  when "exit"
    exit
  end
end
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.