I got a chatbot in ruby that if a character is repeated five times or more in the chat, in the first and second attempt, it warns the user, at the third attempt it kicks the user and the fourth one bans the user for two hours, and it's currently working
require_relative '../plugin'
class Flood
include Chatbot::Plugin
match /(.*)/, :method => :check_swear, :use_prefix => false
def initialize(bot)
super(bot)
#data = {}
end
def check_swear(user, message)
message = message.downcase
array = ["aaaaa", "ñññññ", "bbbbb", "ccccc", "ddddd", "eeeee", "fffff", "ggggg", "hhhhh", "iiiii", "jjjjj", "mmmmm", ".....", "*****", "?????", "!!!!!", "zzzzz", "kkkkkk", "ooooo", "nnnnn", "ppppp", "qqqqq", "rrrrr", "-----", "_____", "¨¨¨¨¨¨¨¨", "{{{{{", "}}}}}", "#####"]
array.each do |e|
if message.include? e
if(#data[user.name] and #data[user.name] == 3)
#client.send_msg "%s: [[Wiki_Freddy_Fazbear's_Pizza:Reglas_y_Lineamientos|Has sido advertido. Tendrás un ban de 2 horas.]] 4/3" % user.name
#client.ban user.name, "7200", "Ban automático por exceso de carácteres - Si crees que esto fué un error, contacta con un [[Wiki_Freddy_Fazbear%27s_Pizza:Administradores|moderador u Admin en su muro de mensajes]]."
#client.send_msg "!mods por si acaso consideran necesario más tiempo de ban."
#client.kick user.name
#data[user.name] = 0
elsif(#data[user.name] and #data[user.name] == 2)
#data[user.name] ||= 0
#data[user.name] += 1
#client.send_msg "%s: [[Wiki_Freddy_Fazbear's_Pizza:Reglas_y_Lineamientos|Por favor, no repitas carácteres, última advertencia antes de un ban.]] 3/3" % user.name
#client.kick user.name
elsif(#data[user.name] and #data[user.name] == 1)
#data[user.name] ||= 0
#data[user.name] += 1
#client.send_msg "%s: [[Wiki_Freddy_Fazbear's_Pizza:Reglas_y_Lineamientos|Por favor, no repitas carácteres, última advertencia antes de un kick]], 2/3" % user.name
else
#data[user.name] ||= 0
#data[user.name] += 1
#client.send_msg "%s: [[Wiki_Freddy_Fazbear's_Pizza:Reglas_y_Lineamientos|Por favor, no repitas carácteres]], 1/3" % user.name
end
end
end
end
end
Now, I need to change it, being all the same except for that it does not trigger with 5 characters or more, but if 5 or more words in a message are in capital letters, can someone help me?
Edit: By the way, if someone can also help me to make it trigger not just with the characters in the array list but any character, it would be awesome
Something like the following will return true if a message has 5 or more uppercase words.
def is_message_shouting?(message)
shouted_words = 0
message.split(' ').each do |word|
shouted_words += 1 if word.upcase == word
end
shouted_words >= 5
end
puts is_message_shouting? 'THIS IS A VERY SHOUTY MESSAGE'
puts is_message_shouting? 'this is not a shouty message'
puts is_message_shouting? 'THIS IS ALSO not a shouty message'
Outputs:
true
false
false
def shouting?(message)
message.split.count { |word| word == word.upcase } >= 5
end
Nothing original to add, just a cleaner implementation of the same.
Something like
class String
def is_upper?
self == self.upcase
end
end
def shouting?(msg)
count = 0
0.upto(msg.size) { |i| count += 1 if msg[i].is_upper? }
count >= 5
end
Related
I've got these three classes
class Totalizavel
def retorna (qnt, valor)
total = qnt * valor
return total
end
end
class Venda < Totalizavel
def initialize (num, data, cliente, itens)
#venda_num = num #int
#venda_data = data #tipo Date
#venda_cliente = cliente #tipo Cliente
#venda_itens = itens #tipo Item_Venda
end
def get_num
return #venda_num
end
def get_data
return #venda_data
end
def get_cliente
return #venda_cliente
end
def get_item
return #venda_itens
end
def set_num (numero)
#venda_num = numero
end
def set_data (data)
#venda_data = data
end
def set_cliente (cliente)
#venda_cliente = cliente
end
def set_item (item)
#venda_itens = item
end
end
class ItemVenda < Totalizavel
def initialize (produto, valor, quantidade)
#item_produto = produto
#item_valor = valor
#item_qnt = quantidade
end
def get_produto
return #item_produto
end
def get_valor
return #item_valor
end
def get_qnt
return #item_qnt
end
def set_produto (produto)
#item_produto = produto
end
def set_valor (valor)
#item_valor = valor
end
def set_qnt (qnt)
#item_qnt = qnt
end
end
And this attribute "#venda_itens" should to be an array of "ItemVenda", how is the best way to initialize it ? I've tried creating an auxiliar array and then "pass" it to the class like this:
remind that's only part of the code
def manipvendas
while true
puts "\n1- Add sell"
puts "2- show sells"
puts "0- get back to previous menu"
print "Insert the desired option: "
escolha = gets.chomp
return if escolha == "0"
if escolha == "1" #add sell
print "\nInsert the number: "
numvend = gets.chomp
numvend = numvend.to_i
print "\nInsert the date (Year, month, day): "
ano = gets.chomp
mes = gets.chomp
dia = gets.chomp
data = Time.new(ano.to_i, mes.to_i, dia.to_i)
print "\nInsert the client: "
clientenum = gets.chomp
vendai = Venda.new(numvend,data,clientenum,selecproduto)
#vendas.push(vendai)
end
if escolha == "2" #show sells
if #vendas.size == 0
puts "\nThere are no sells"
else
puts "\nPrinting sells database: \n\n"
i = 0
for a in 1..#vendas.size do
puts "Code: " + #vendas[i].get_num.to_s
puts "Date: " + #vendas[i].get_data.day.to_s + "/" + #vendas[i].get_data.month.to_s + "/" + #vendas[i].get_data.year.to_s + "\n"
puts "Client: " + #vendas[i].get_cliente.to_s
puts "Itens: "
if #vendas[i].get_item.size == 0
puts "\nThere are no itens"
else
j = 0
for a in 1..#vendas[i].get_item.size do
puts "Number: " + #vendas[i].get_item[j].get_produto.to_s
puts "Unity value: " + #vendas[i].get_item[j].get_valor.to_s
puts "Sold: " + #vendas[i].get_item[j].get_qnt.to_s
puts "Total value: " + #vendas[i].get_item[j].retorna(#vendas[i].get_item[j].get_valor.to_f, #vendas[i].get_item[j].get_qnt.to_i).to_s
j = j+1
end
end
i = i+1
end
end
end
end
end
def selecproduto
while true
#itemvenda.clear
puts "\nInsert the product number: "
print "Insert -1 to return: "
produtonum = gets.chomp
return if produtonum == "-1"
produtonum = produtonum.to_i
print "\nInsert the amount sold: "
produtoqnt = gets.chomp
produtoqnt = produtoqnt.to_i
valor = produtoqnt.to_i
vendaitem = ItemVenda.new(produtonum, #produtos[produtonum].get_valor, valor)
#itemvenda.push(vendaitem)
return vendaitem
end
end
It's returning correctly until I try to add another "product", when I do this then select to show the registered sells, it returns me the amount of sells I created but with the parameters of the last sell multiplied for the number os registered sells
What's wrong with my code ?
We can refactor some methods. Let's go!
When you instantiate a new object Venda, you can pass the array of ItemVenda, like this:
itens = [item1, item2, item3]
cliente = Cliente.new("João", "flow#stackoverflow.com")
venda = Venda.new(1, DateTime.now, cliente, itens)
venda.total(itens)
require 'date'
class Venda
attr_accessor :num, :data, :cliente, :itens
def initialize(num, data, cliente, itens)
#num = num #int
#total = total #int
#data = data #tipo Date
#cliente = cliente #tipo Cliente
#itens = itens #tipo Item_Venda
end
def total(itens)
itens.map { |item| item.quantidade * item.valor }.sum
end
def add_item(item)
#itens << item
end
end
class ItemVenda < Venda
attr_accessor :produto, :valor, :quantidade
def initialize (produto, valor, quantidade)
#produto = produto
#valor = valor
#quantidade = quantidade
end
end
class Cliente
attr_accessor :nome, :email
def initialize(nome, email)
#nome = nome
#email = email
end
end
The book Ruby Wizardry Chapter 4 includes the following sample program
we_wanna_ride = true
stops = ["East Bumpspark", "Endertromb Avenue", "New Mixico", "Mal Abochny"]
while we_wanna_ride
print "Where ya headin', friend?"
destination = gets.chomp
if stops.include? destination
puts "I know how to get to #{destination}! Here's the station list:"
stops.each do |stop|
puts stop
break if stop == destination
end
else
puts "Sorry, we don't stop at that station. Maybe another time!"
we_wanna_ride = false
end
end
It then goes on to pose a few additional challenges:
"What if a passenger is going the other way on the train (for instance, from Mal Abochny to East Bumpspark)? How could you update your program to work in both directions? Even trickier, what if the train route is a big circle (meaning if a passenger goes from East Bumpspark to Mal Abochny, the next stop after Mal Abochny should be East Bumpspark again)? How could you update your program to print out the right list of train stops if a passenger wants to go all the way around the circle?"
Does anybody have any ideas how to proceed here ? I'm a beginning programmer so any help would be greatly appreciated. Here's my progress so far. I figured I would get a departure from the user and then use to.i to get the input into an integer. I could then use the integer value to compare to the index position in the array. If the rider wants to go in the opposite direction I could use something like stops.each.reverse to print out the array items in reverse order.
we_wanna_ride = true
stops = ["East Bumpspark(1)", "Endertromb Avenue(2)", "New Mixico(3)", "Mal Abochny(4)"]
puts "#{stops}"
while we_wanna_ride
print "Select a destination number"
destination = gets.chomp.to_i
print "Select a departure number"
departure = gets.chomp.to_i
if departure <= destination
stops.each do |stop|
puts stop
break if stop == destination
end
else puts "Sorry"
we_wanna_ride = false
end
end
Here is how I solved this challenge. It works but is rather lengthy. More advanced ruby coders may be able to provide a shorter solution:
we_wanna_ride = true
stops = ["East Bumpspark", "Endertromb Avenue", "New Mixico", "Mal Abochny"]
while we_wanna_ride
print "Where do you wish to depart from?: "
depart = gets.chomp.split.map(&:capitalize).join(' ')
depart_index = stops.index(depart)
# puts depart_index
print "Where ya headin' friend?: "
destination = gets.chomp.split.map(&:capitalize).join(' ')
destination_index = stops.index(destination)
# puts destination_index
index_diff1 = depart_index - destination_index
index_diff2 = destination_index - depart_index
if stops.include? destination && depart
puts "\nI know how to get to #{destination}! Here's the station list:"
if destination_index > depart_index && index_diff2 < 3
stops[depart_index..-1].each do |stop|
puts stop
break if stop == destination
end
we_wanna_ride = false
elsif destination_index > depart_index && index_diff2 >= 3
dubstops = stops.concat(stops)
dubstops[0..depart_index+4].reverse_each do |stop|
puts stop
break if stop == destination
end
we_wanna_ride = false
elsif destination_index < depart_index && index_diff1 < 3
stops[0..depart_index].reverse_each do |stop|
puts stop
break if stop == destination
end
we_wanna_ride = false
elsif destination_index < depart_index && index_diff1 >= 3
dubstops = stops.concat(stops)
dubstops[depart_index..-1].each do |stop|
puts stop
break if stop == destination
end
we_wanna_ride = false
end
else
puts "Sorry, we don't service that station. Maybe another time!"
we_wanna_ride = false
end
end
I have to build a method that takes an array and a string. The method should return an array with three elements. Its element at index 0 should be the string argument, and it should not include the last element of the array argument.
For array:
best_teams = ([Boston Celtics, LA Lakers, Chicago Bulls]
and string:
my_team = ("Utah Jazz")
I expect the output:
[Utah Jazz, Boston Celtics, LA Lakers]
I tried this:
def teams(best_teams, my_team)
sec = my_team.split + best_teams
return sec - sec[3].split
end
but it doesn't seem to work. Any ideas?
Look, asuming the following values:
best_teams = ['Boston Celtics', 'LA Lakers', 'Chicago Bulls']
my_team = "Utah Jazz"
def teams(best_teams, my_team)
# sec = nil
sec = my_team.split + best_teams
# the values at this point are
# sec = ["Utah", "Jazz"] + ['Boston Celtics', 'LA Lakers', 'Chicago Bulls']
# your single team name now become in an array with two values
# finally
# sec = ["Utah", "Jazz", 'Boston Celtics', 'LA Lakers', 'Chicago Bulls']
return sec - sec[3].split
# ["Utah", "Jazz", 'Boston Celtics', 'LA Lakers', 'Chicago Bulls'] - ["LA", "Lakers"]
# ["Utah", "Jazz", "Boston Celtics", "LA Lakers", "Chicago Bulls"]
end
Please check
https://apidock.com/ruby/String/split.
The real problem is that I guess so you don't know how split work
I create an array from a text file which contains the english irregular verbs. I want the code to ask me the verbs in random order letting me proceed only if I respond correctly. I need to compare a string with an element of array. I wrote this:
a = []
File.open('documents/programmi_test/verbi.txt') do |f|
f.lines.each do |line|
a <<line.split.map(&:to_s)
end
end
puts ''
b = rand(3)
puts a[b][0]
puts 'infinitive'
infinitive = gets.chomp
if infinitive = a[b][1] #--> write like this, I receive alway "true"
puts 'simple past'
else
puts 'retry'
end
pastsimple = gets.chomp
if pastsimple == a[b][2] #--> write like this, I receive alway "false"
puts 'past participle'
else
puts 'retry'
end
pastpart = gets.chomp
if pastpart == a[b][3]
puts 'compliments'
else
puts 'oh, no'
end
can somebody help me?
if infinitive = a[b][1] is assigning to inifinitive the value of a[b][1], unlike pastsimple == a[b][2] that's a comparation between both values.
You could try replacing the = for ==.
a = []
File.open('documents/programmi_test/verbi.txt') do |file|
file.lines.each do |line|
a << line.split.map(&:to_s)
end
end
puts ''
b = rand(3)
puts a[b][0]
puts 'infinitive'
infinitive = gets.chomp
puts infinitive == a[b][1] ? 'simple past' : 'retry'
pastsimple = gets.chomp
puts pastsimple == a[b][2] ? 'past participle' : 'retry'
pastpart = gets.chomp
puts pastpart == a[b][3] ? 'compliments' : 'oh, no'
My first hangman game from scratch is almost done with the real basic stuff. I just need a counter for when a player gets it right to work correctly. I haven't figured out a good way to do it without deleting everything and starting over.
the #correct_tries counts correctly then in the elsif compare the numerical value to the number of elements in the given word that were answered correctly.
It'll keep counting when it should have stopped when #correct_tries was compared to the number when .inspect happens on the array. But it keeps counting.
class Hangman
Profanity = ['cobol','snit','crap','court']
Adjective = ['foul','repugnant','swift','fast']
Noun = ['king','queen','prince','princess']
def self.start_game
print "Welcome to Hangman V1 by Clueless! Please select which category of words do you want to use: \n Profanity, Adjective, Noun "
#selection = gets.chomp.downcase
case
when #selection == 'profanity'
puts 'You have selected profanity! '
hangman_word_selection
when #selection == 'adjective'
puts 'You have selected Adjectives! '
hangman_word_selection
when #selection == 'noun'
puts 'You have selected nouns! '
hangman_word_selection
end
end
def self.hangman_word_selection
if #selection == 'profanity'
hangman_word = Profanity.sample
hangman_word_setup(hangman_word)
#puts '_ ' * hangman_word.size
elsif #selection == 'adjective'
hangman_word = Adjective.sample
hangman_word_setup(hangman_word)
elsif
#selection == 'noun'
hangman_word = Noun.sample
hangman_word_setup(hangman_word)
end
end
def self.hangman_word_setup(hangman_word)
hangman_word_array = hangman_word.chars.to_a
#hangman_end = false
#while(#hangman_end == false)
#puts "*" * 40
#puts
#puts
puts 'You have five tries to get the word correct. If you can guess the whole word do so but you only have one try. Or just guess letter by letter.'
p hangman_word_array
#total_tries = 0
#correct_tries = 0
game_check = true
while game_check == true
first_try = gets.chomp.downcase
if(first_try == hangman_word_array[0] || first_try == hangman_word_array[1] || first_try == hangman_word_array[2] || first_try == hangman_word_array[3] || first_try == hangman_word_array[4])
puts 'Check'
#correct_tries += 1
p #correct_tries
#correct tries equal to the number of chars in the given word check it.
puts 'You have gotten it correct!'
elsif(first_try == hangman_word)
puts 'You have completed the word! Congratulations you win!'
hangman_win
break
elsif(first_try != hangman_word_array)
puts 'Wrong.'
#total_tries += 1
p #total_tries
#puts "*" * 40
elsif(#correct_tries == hangman_word_array.inspect)
puts 'done.'
break
end
end
end
def self.hangman_loss
puts ' +---+-
| |
| 0
| |\\
| /\\
-+----------'
puts 'You lose!'
end
def self.hangman_win
puts 'NEED HANGMAN VICTORY POSE HERE.'
end
start_game
end
The elsif condition
elsif(#correct_tries == hangman_word_array.inspect) will never be true. #correct_tries is a numerical value and hangman_word_array.inspect will return the array of words for hangman in a string format (e.g. hangman_word_array = ['a', 'b', 'c'] then hangman_word_array.inspect will be "[\"a\", \"b\", \"c\"]".