Ruby: creating a case statement that checks csv file for string to authenticate user (terminal only) - ruby

I apologies if this is simple but I'm just starting out. Any constructive help welcome.
Problem:
Trying to create authentication from ruby terminal to CSV.
I'd like to create clean (and as short as possible) loop statement that goes to csv file checks the top row for header "pin" and then checks the gets.chomp entry against that to authenticate.
require 'csv'
class Menu
def self.login
system "clear"
puts "Welcome to Hip-Bikes & Coffee"
puts "Please login with your pin:"
print "> "
customer_pin = gets.chomp
verified = authentication(customer_pin)
end
def self.authentication(customer_pin)
case
when CSV.foreach('customers.csv', headers: true) { |row| ["pin"] == login.verified }
puts verified
else
puts "login failed. Please try again in 3 seconds..."
sleep(3.0)
self.login

This should work for you
UPD
require 'csv'
class Menu
class << self
def login
login_start
verified(gets.chomp)
end
def verified(input)
if authentication(input)
puts 'verified'
else
failed
end
end
def authentication(customer_pin)
CSV.foreach('customers.csv', headers: true).any? { |row| row['pin'] == customer_pin }
end
def failed
puts "login failed. Please try again in 3 seconds..."
sleep(3.0)
login
end
def login_start
system "clear"
print "Welcome to Hip-Bikes & Coffee\nPlease login with your pin:\n> "
end
end
end

Related

No Method Errors in Ruby

I was able to get a menu and pull up names of cat breeds, however when I continue to learn about the cat's breed I get this error down below. Not sure where to go from here. Am I suppose to delete something off? or perhaps try another api? really running out of ideas here.
Error below:
Traceback (most recent call last):
4: from bin/run.rb:5:in `<main>'
3: from /Users/jason/Development/code/Cat Breeds/Cat_breeds/lib/cli.rb:9:in `call'
2: from /Users/jason/Development/code/Cat Breeds/Cat_breeds/lib/cli.rb:24:in `menu'
1: from /Users/jason/Development/code/Cat Breeds/Cat_breeds/lib/cli.rb:44:in `list_of_breeds' /Users/jason/Development/code/Cat Breeds/Cat_breeds/lib/cli.rb:54:in `breed_selection': undefined method `get_metric_weight' for
#<CatBreed:0x00007fc581afc488> (NoMethodError)
in my cli.rb file
class CLI
def initialize
API.new.get_breed_data
end
def call
greeting
menu
end
def greeting
puts "Welcome! Start searching for Cat breeds"
puts ""
puts "--To search for cat breeds, enter 'breeds'"
puts ""
puts "--If there is nothing you would like to do at the moment, enter 'exit'"
end
def menu
input = gets.strip.downcase
if input == "breeds"
list_of_breeds
elsif input == "exit"
goodbye
else
invalid_entry
end
end
def goodbye
puts "Goodbye!"
end
def list_of_breeds
puts "Select which breed you would like to know about:"
CatBreed.all.each_with_index do |breed, index|
puts "#{index + 1}. #{breed.name}"
end
input = gets.strip.downcase
breed_selection(input)
end
def breed_selection(breed)
input = gets.strip.downcase
breed = CatBreed.find_by_name(breed)
if breed
puts "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
puts "Name of Breed: #{breed.name}"
puts "Approximate Weight: #{breed.get_metric_weight}"
puts "Approximate Height: #{breed.get_metric_height}"
puts "Bred For: #{breed.bred_for}"
puts "Breed Group: #{breed.breed_group}"
puts "Average Life Span: #{breed.life_span}"
puts "Temperament: #{breed.temperament}"
puts "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
puts ""
puts "To continue searching for breeds, enter 'breeds'."
puts "If there is nothing else you would like to do, enter 'exit'."
puts ""
puts "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
menu
else
incorrect_breed_name
end
end
def incorrect_breed_name
puts "The breed name that you entered may have been spelled incorrectly."
puts "Please enter 'breeds' to pull up the list and try again."
menu
end
def invalid_entry
puts ""
puts "Hmmmmmm, I'm not understanding, please try again."
puts ""
menu
end
#binding.pry
end
something I'm doing wrong here? If you need more info let me know..
The error message says:
/Users/jason/Development/code/Cat Breeds/Cat_breeds/lib/cli.rb:54:in `breed_selection':
undefined method `get_metric_weight' for #<CatBreed:0x00007fc581afc488> (NoMethodError)
This error has got nothing to do with VSCode. It says that your CatBreed instance does not respond to a get_metric_weight method.
However, you have not shown the CatBreed class definition above, so I cannot comment further on the resolution.
Your code also assumes it has methods such as get_metric_height, bred_for and breed_group. If these methods aren't defined either, then I would expect a similar error to be raised once this issue is fixed.

How to click context in RecyclerView by using Appium, Ruby

How to click an element in RecyclerView by using Appium, Ruby. I tried using all ways but not able to click
I have tried all possible ways
require 'selenium-cucumber'
require 'appium_lib'
def alert1
$driver.find_element(xpath: "/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.ScrollView/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.LinearLayout[2]/android.widget.Button[2]")
end
def alert2; $driver.find_element(xpath: "/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.ScrollView/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.LinearLayout[2]/android.widget.Button[2]") end
def phoneNumber; $driver.find_element(id: "com.accushield.familyapp:id/phone_number") end
def sendCode; $driver.find_element(id: "com.accushield.familyapp:id/send_code") end
def confirmationCode; $driver.find_element(id: "com.accushield.familyapp:id/confirmation_code") end
def submitCode; $driver.find_element(id: "com.accushield.familyapp:id/submit_confirmation_code") end
def dashboardScreen1; $driver.find_element(xpath: "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.support.v7.widget.RecyclerView/android.widget.FrameLayout[1]/android.view.ViewGroup").click end
Then(/^do user Login with OTP$/) do
alert1.click
alert2.click
phoneNumber.send_keys("8131234567")
sendCode.click
confirmationCode.send_keys("123456")
submitCode.click
sleep 40
#residentClick.click
#$driver.find_element(xpath: "//android.widget.ImageView[#index='1']").click
dashboardScreen1.click
#if dashboardScreen.displayed?
# puts "User has signed in successfully"
# else
# puts "User sign in got failed"
# end
I need to click any element in recycler view. Please find the image for elements
https://i.stack.imgur.com/cmJ23.png

Ruby: Chatterbot can't load bot data

I'm picking up ruby language and get stuck at playing with the chatterbot i have developed. Similar issue has been asked here Click here , I did what they suggested to change the rescue in order to see the full message.But it doesn't seem right, I was running basic_client.rb at rubybot directory and fred.bot is also generated at that directory . Please see the error message below: Your help very be very much appreciated.
Snailwalkers-MacBook-Pro:~ snailwalker$ cd rubybot
Snailwalkers-MacBook-Pro:rubybot snailwalker$ ruby basic_client.rb
/Users/snailwalker/rubybot/bot.rb:12:in `rescue in initialize': Can't load bot data because: No such file or directory - bot_data (RuntimeError)
from /Users/snailwalker/rubybot/bot.rb:9:in `initialize'
from basic_client.rb:3:in `new'
from basic_client.rb:3:in `<main>'
basic_client.rb
require_relative 'bot.rb'
bot = Bot.new(:name => 'Fred', :data_file => 'fred.bot')
puts bot.greeting
while input = gets and input.chomp != 'end'
puts '>> ' + bot.response_to(input)
end
puts bot.farewell
bot.rb:
require 'yaml'
require './wordplay'
class Bot
attr_reader :name
def initialize(options)
#name = options[:name] || "Unnamed Bot"
begin
#data = YAML.load(File.read('bot_data'))
rescue => e
raise "Can't load bot data because: #{e}"
end
end
def greeting
random_response :greeting
end
def farewell
random_response :farewell
end
def response_to(input)
prepared_input = preprocess(input).downcase
sentence = best_sentence(prepared_input)
reversed_sentence = WordPlay.switch_pronouns(sentence)
responses = possible_responses(sentence)
responses[rand(responses.length)]
end
private
def possible_responses(sentence)
responses = []
#data[:responses].keys.each do |pattern|
next unless pattern.is_a?(String)
if sentence.match('\b' + pattern.gsub(/\*/, '') + '\b')
if pattern.include?('*')
responses << #data[:responses][pattern].collect do |phrase|
matching_section = sentence.sub(/^.*#{pattern}\s+/, '')
phrase.sub('*', WordPlay.switch_pronouns(matching_section))
end
else
responses << #data[:responses][pattern]
end
end
end
responses << #data[:responses][:default] if responses.empty?
responses.flatten
end
def preprocess(input)
perform_substitutions input
end
def perform_substitutions(input)
#data[:presubs].each {|s| input.gsub!(s[0], s[1])}
input
end
# select best_sentence by looking at longest sentence
def best_sentence(input)
hot_words = #data[:responses].keys.select do |k|
k.class == String && k =~ /^\w+$/
end
WordPlay.best_sentence(input.sentences, hot_words)
end
def random_response(key)
random_index = rand(#data[:responses][key].length)
#data[:responses][key][random_index].gsub(/\[name\]/, #name)
end
end
I'm assuming that you are trying to load the :data_file passed into Bot.new, but right now you are statically loading a bot_data file everytime. You never mentioned about bot_data in the question. So if I'm right it should be like this :
#data = YAML.load(File.read(options[:data_file]))
Instead of :
#data = YAML.load(File.read('bot_data'))

Uninitialized Constant Error from Ruby EventMachine Chat Server

I'm trying to build a chat server in ruby using EventManager. Needless to day, I'm new to Ruby and feeling a little over my head with the current error I am getting, as I have no clue what it means and a search doesn't return anything valuable. Here's some of the logistics-
(ive only implemented LOGIN and REGISTER so I'll only include those..)
user can enter-
REGISTER username password - registers user
LOGIN username password - logins user
I'm taking in the string of data the user sends, splitting it into an array called msg, and then acting on the data based on msg[0] (as its the command, like REGISTER, LOGIN, etc)
Here is my code, all contained in a single file- chatserver.rb (explanation follows):
require 'rubygems'
require 'eventmachine'
class Server
attr_accessor :clients, :channels, :userCreds, :userChannels
def initialize
#clients = [] #list of clients connected e.g. [192.168.1.2, 192.168.1.3]
#users = {} #list of users 'logged in' e.g. [tom, sam, jerry]
#channels = [] #list of channels e.g. [a, b, c]
#userCreds = {} #user credentials hash e.g. { tom: password1, sam: password2, etc }
#userChanels = {} #users and their channels e.g. { tom: a, sam: a, jerry: b }
end
def start
#signature = EventMachine.start_server("127.0.0.1", 3200, Client) do |con|
con.server = self
end
end
def stop
EventMachine.stop_server(#signature)
unless wait_for_connections_and_stop
EventMachine.add_periodic.timer(1) { wait_for_connections_and_stop }
end
end
# Does the username already exist?
def has_username?(name)
#userCreds.has_key?(name)
end
# Is the user already logged in?
def logged_in?(name)
if #users[name] == 1
true
else
false
end
end
# Did the user enter the correct pwd?
def correct_pass?(pass)
if #userCreds[name] == pass
true
else
false
end
end
private
def wait_for_connections_and_stop
if #clients.empty?
EventMachine.stop
true
else
puts "Waiting for #{#clients.size} client(s) to stop"
false
end
end
end
class Connection < EventMachine::Connection
attr_accessor :server, :name, :msg
def initialize
#name = nil
#msg = []
end
# First thing the user sees when they connect to the server.
def post_init
send_data("Welcome to the lobby.\nRegister or Login with REGISTER/LOGIN username password\nOr try HELP if you get stuck!")
end
# Start parsing incoming data
def receive_data(data)
data.strip!
msg = data.split("") #split data by spaces and throw it in array msg[]
if data.empty? #the user entered nothing?
send_data("You didn't type anything! Try HELP.")
return
elsif msg[0] == "REGISTER"
handle_register(msg) #send msg to handle_register method
else
hanlde_login(msg) #send msg to handle_login method
end
end
def unbind
#server.clients.each { |client| client.send_data("#{#name} has just left") }
puts("#{#name} has just left")
#server.clients.delete(self)
end
private
def handle_register(msg)
if #server.has_username? msg[1] #user trying to register with a name that already exists?
send_data("That username is already taken! Choose another or login.")
return
else
#name = msg[1] #set name to username
#userCreds[name] = msg[2] #add username and password to user credentials hash
send_data("OK") #send user OK message
end
end
end
EventMachine::run do
s = Server.new
s.start #start server
puts "Server listening"
end
Whew, okay, it's only the beginning, so not that complicated. Since I'm new to Ruby I have a feeling I'm just not declaring variable or using scope correctly. Here's the error output:
chatserver.rb:16:in start': uninitialized constant Server::Client
(NameError) from chatserver.rb:110:inblock in ' from
/Users/meth/.rvm/gems/ruby-1.9.3-p392#rails3tutorial2ndEd/gems/eventmachine-1.0.3/lib/eventmachine.rb:187:in
call' from
/Users/meth/.rvm/gems/ruby-1.9.3-p392#rails3tutorial2ndEd/gems/eventmachine-1.0.3/lib/eventmachine.rb:187:in
run_machine' from
/Users/meth/.rvm/gems/ruby-1.9.3-p392#rails3tutorial2ndEd/gems/eventmachine-1.0.3/lib/eventmachine.rb:187:in
run' from chatserver.rb:108:in<\main>'
ignore the slash in main in that last line.
line 108 is the last function- EventMachine::run do etc.
Any help would be appreciated, if I didn't provide enough info just let me know.
I would think that when you call EventMachine::start_server you need to give it your Connection class as the handler. Client is not defined anywhere.

Thor::Group do not continue if a condition is not met

I'm converting a generator over from RubiGen and would like to make it so the group of tasks in Thor::Group does not complete if a condition isn't met.
The RubiGen generator looked something like this:
def initialize(runtime_args, runtime_options = {})
super
usage if args.size != 2
#name = args.shift
#site_name=args.shift
check_if_site_exists
extract_options
end
def check_if_site_exists
unless File.directory?(File.join(destination_root,'lib','sites',site_name.underscore))
$stderr.puts "******No such site #{site_name} exists.******"
usage
end
end
So it'd show a usage banner and exit out if the site hadn't been generated yet.
What is the best way to recreate this using thor?
This is my task.
class Page < Thor::Group
include Thor::Actions
source_root File.expand_path('../templates', __FILE__)
argument :name
argument :site_name
argument :subtype, :optional => true
def create_page
check_if_site_exists
page_path = File.join('lib', 'sites', "#{site_name}")
template('page.tt', "#{page_path}/pages/#{name.underscore}_page.rb")
end
def create_spec
base_spec_path = File.join('spec', 'isolation', "#{site_name}")
if subtype.nil?
spec_path = base_spec_path
else
spec_path = File.join("#{base_spec_path}", 'isolation')
end
template('functional_page_spec.tt', "#{spec_path}/#{name.underscore}_page_spec.rb")
end
protected
def check_if_site_exists # :nodoc:
$stderr.puts "#{site_name} does not exist." unless File.directory?(File.join(destination_root,'lib','sites', site_name.underscore))
end
end
after looking through the generators for the spree gem i added a method first that checks for the site and then exits with code 1 if the site is not found after spitting out an error message to the console. The code looks something like this:
def check_if_site_exists
unless File.directory?(path/to/site)
say "site does not exist."
exit 1
end
end

Resources