Guess A Number - Ruby Online - ruby

I have been trying to create a Ruby program that will be running online where a user can guess a number, and it will say higher or lower. I know it will take a random number store in a variable, then run a loop? With conditionals to check?
Im not asking for full code, the basic structure for I can use this to get me going.
Any idea how i would do this? I found info to create a random number like this:
x = rand(20)
UPDATE: My code I am going to be working with is something like this: http://pastie.org/461976

I would say to do something like this:
x = rand(20)
loop {
# get the number from the user somehow, store it in num
if num == x
# they got it right
break
elsif num > x
# the guess was too high
else
# the guess was too low
end
}
If you're running it online, this structure may not be feasible. You may need to store the guess in the user's session and have a textbox for the guess, and submit it to a controller which would have the above code without the loop construct, and just redirect them to the same page with a message if they didn't get it right.

Related

Validating a PIN entered by users

How would you refactor this code that checks if users have added a 4+ digit PIN so the code will be as short as possible?
def has_pin?
return self.pin.to_i > 1000 rescue nil
false
end
Ideally without using AR validation on user creation time as they're created with no PIN at first, but may choose to add them later in some specific cases.
PS: the PIN is stored as string for some reason.
I would go with:
def pin_valid?
pin.present? && pin.match?(/\A\d{4,}\z/)
end
Why do you aim to have your code as short as possible? I would always aim to have my code as easy to understand as possible.

Query Pandas DataFrame distinctly with multiple conditions by unique row values

I have a DataFrame with event logs:
eventtime, eventname, user, execution_in_s, delta_event_time
The eventname e.g. can be "new_order", "login" or "update_order".
My problem is that I want to know if there is eventname == "error" in the periods between login and update_order by distinct user. A period for me has a start time and an end time.
That all sounded easy until I tried it this morning.
For the time frame of the 24h logs I might not have a pair, because the login might have happened yesterday. I am not sure how to deal with something like that.
delta_event_time is a computed column of the eventtime minus the executions_in_s. I am considering these the real time stamps. I computed them:
event_frame["delta_event_time"] = event_frame["eventtime"] - pandas.to_timedelta(event_frame["execution_in_s"], unit='s')
I tried something like this:
events_keys = numpy.array(["login", "new_order"])
users = numpy.unique(event_frame["user"])
for user in users:
event_name = event_frame[event_frame["eventname"].isin(events_keys) & event_frame["user" == user]]["event_name"]
But this not using the time periods.
I know that Pandas has between_time() but I don't know how to query a DataFrame with periods, by user.
Do I need to iterate over the DataFrame with .iterrows() to calculate the start and end time tupels? It takes a lot of time to do that, just for basic things in my tries. I somehow think that this would make Pandas useless for this task.
I tried event_frame.sort(["user", "eventname"]) which works nicely so that I can see the relevant lines already. I did not have any luck with .groupby("user"), because it mixed users although they are unique row values.
Maybe a better workflow solution is to dump the DataFrame into a MongoDB instead of pursuing a solution with Pandas to perform the analysis in this case. I am not sure, because I am new to the framework.
Here is pseudocode for what I think will solve your problem. I will update it if you share a sample of your data.
grouped = event_frame.groupby('user') # This should work.
# I cannot believe that it didn't work for you! I won't buy it till you show us proof!
for name, group in grouped:
group.set_index('eventtime') # This will make it easier to work with time series.
# I am changing index here because different users may have similar or
# overlapping times, and it is a pain in the neck to resolve indexing conflicts.
login_ind = group[group['eventname'] == 'login'].index
error_ind = group[group['eventname'] == 'error'].index
update_ind = group[group['eventname'] == 'update_order'].index
# Here you can compare the lists login_ind, error_ind and update_ind however you wish.
# Note that the list can even have a length of 0.
# User name is stored in the variable name. So you can get it from there.
Best way might be to create a function that does the comparing. Because then you can create a dict by declaring error_user = {}.
Then calling your function inside for name, group in grouped: like so: error_user[name] = function_which_checks_when_user_saw_error(login_ind, error_ind, update_ind).

How to read value in cell from database

I am still fairly new to Ruby and to databases in general, and am trying to better learn how to use the two together. I have browsed through several online tutorials but haven't been able to figure a few things out. I am working with PostgreSQL and am simply trying to read the data in my database and manipulate in some way the data contained in the actual cell. From a tutorial I have the following functions:
def queryUserTable
#conn.exec( "SELECT * FROM users" ) do |result|
result.each do |row|
yield row if block_given?
end
end
end
and a simple way to print out the information in the rows would be something like
p.queryUserTable {|row| printf("%s %s\n", row['first_name'], row['last_name'])}
(with p being the connection). However all this is doing it printing out each value in the row and column specified as a whole, then continuing to the next row. What I would like to know is how I can grab for instance the value in row 1 under column first name and use it for something else? From what I understand, it looks like the rows are hashes and so I should be able to do something similar to {|row, value| #my_var = value } but I get no results by doing so, so I am not understanding how this all works properly. I am hoping someone can better explain how this works. Hope that makes sense. Thanks!
EDIT:
Does it have anything to do with this line in my function?:
result.each do |row| #do I need to add |row,value| here as well?
Is there a reason you're not using an ORM like ActiveRecord? Although it certainly has some downsides, it may well be helpful for someone who is new to databases and ruby. If you want a tutorial on active record and rails, I highly recommend Michael Hartl's awesome free tutorial[1].
I'm not exactly sure what you're trying to do, but I can correct a couple of misconceptions. First of all, result is not a hash - it is an array of hashes. That is why doing result.each { |row, value| ... doesn't initialize value. Once you have an individual row, you can do row.each { |col_name, val| ...
Second, if you want to grab a value from a specific row, you should specify the row in the query. You must know something about the row you want information about. For getting the user with id = 1, for instance:
user = #conn.exec("SELECT first_name FROM users WHERE id = 1").first
unless user.nil?
# do something with user["first_name"]
If you were to use activerecord, you could just do
user = User.findById(1)
I would not want to set the value in the queryUserTable loop, because it will get set on each loop, and just retain the value of the last time it executes.
[1] https://www.railstutorial.org/book

Ruby regular expression for asterisks/underscore to strong/em?

As part of a chat app I'm writing, I need to use regular expressions to match asterisks and underscores in chat messages and turn them into <strong> and <em> tags. Since I'm terrible with regex, I'm really stuck here. Ideally, we would have it set up such that:
One to three words, but not more, can be marked for strong/em.
Patterns such as "un*believ*able" would be matched.
Only one or the other (strong OR em) work within one line.
The above parameters are in order of importance, with only #1 being utterly necessary - the others are just prettiness. The closest I came to anything that worked was:
text = text.sub(/\*([(0-9a-zA-Z).*])\*/,'<b>\1<\/b>')
text = text.sub(/_([(0-9a-zA-Z).*])_/,'<i>\1<\/i>')
But it obviously doesn't work with any of our params.
It's odd that there's not an example of something similar already out there, given the popularity of using asterisks for bold and whatnot. If there is, I couldn't find it outside of plugins/gems (which won't work for this instance, as I really only need it in in one place in my model). Any help would be appreciated.
This should help you finish what you are doing:
sub(/\*(.*)\*/,'<b>\1</b>')
sub(/_(.*)_/,'<i>\1</i>')
Firstly, your criteria are a little strange, but, okay...
It seems that a possible algorithm for this would be to find the number of matches in a message, count them to see if there are less than 4, and then try to perform one set of substitutions.
strong_regexp = /\*([^\*]*)\*/
em_regexp = /_([^_]*)_/
def process(input)
if input ~= strong_regexp && input.match(strong_regexp).size < 4
input.sub strong_regexp, "<b>\1<\b>"
elsif input ~= em_regexp && intput.match(em_regexp).size < 4
input.sub em_regexp, "<i>\1<\i>"
end
end
Your specifications aren't entirely clear, but if you understand this, you can tweak it yourself.

Create Random Integer Based on Id in Ruby

I have a scenario where I need to generate 4 digit confirmation codes for individual orders. I don't want to just do random codes due to the off chance that two exact codes would be generated near the same time. Is there a way to use the id of each order and generate a 4 digit code from that? I know I am going to eventually have repetitive codes with this but it will be ok because they will not be generated around the same time.
Do you really need to base the code on the ID? Four digits only gives you ten thousand possible values so you could generate them all with a script and toss them in a database table. Then just pull a random one out of the database when you need it and put it back in when you're done with it.
Your code table would look like this:
code: The code
uuid: A UUID, a NULL value here indicates that this code is free.
Then, to grab a code, first generate a UUID, uuid, and do this:
update code_table
set uuid = ?
where code = (
select code
from code_table
where uuid is null
order by random()
limit 1
)
-- Depending on how your database handles transactions
-- you might want to add "and uuid is null" to the outer
-- WHERE clause and loop until it works
(where ? would be your uuid) to reserve the code in a safe manner and then this:
select code
from code_table
where uuid = ?
(where ? is again your uuid) to pull the code out of the database.
Later on, someone will use the code for something and then you just:
update code_table
set uuid = null
where code = ?
(where code is the code) to release the code back into the pool.
You only have ten thousand possible codes, that's pretty small for a database even if you are using order by random().
A nice advantage of this approach is that you can easily see how many codes are free; this lets you automatically check the code pool every day/week/month/... and complain if the number of free codes fall below, say, 20% of the entire code space.
You have to track the in-use codes anyway if you want to avoid duplicates so why not manage it all in one place?
If your order id has more than 4 digits, it is theoreticly impossible without checking the generated value in a array of already generated values, you can do something like this:
require 'mutex'
$confirmation_code_mutex = Mutex.new
$confirmation_codes_in_use = []
def generate_confirmation_code
$confirmation_code_mutex.synchronize do
nil while $confirmation_codes_in_use.include?(code = rand(8999) + 1000)
$confirmation_codes_in_use << code
return code
end
end
Remember to clean up $confirmation_codes_in_use after using the code.

Resources