Ruby on Rails Model Actions - ruby-on-rails-4

I am working on a webserver project and have little experience with MVC architecture. What reading I have done points me to the idea of "Skinny Controllers, Fat Models." Keeping this in mind, I've tried tinkering around in rails to get the effect I'm looking for:
I accept through a form a string and must sanitize it (Assuming this is done through Callbacks). After it has been sanitized, I'm converting it into an array and sorting it.
Each step of the sort is being recorded in a variable #states. I need to put #states variable into the database when the process is done.
My question is: how is this setup best enacted? I think I'm correct that the sanitation should be performed through a callback... but the second part is what's giving me fits.
Here's something of an example:
recieve input: "4 3 2 1\r\n5 2 2 1\r\n1 5 4 3"
sanitize input to: 4 3 2 1 5 2 2 1 1 5 4 3 # Presumably through a callback
until input.sorted? do:
input.bubblesort(#states) # each time bubblesort moves an entry, it sends a copy of the array to #states
#Do something with #states in the model.rb file
I would love some input on this because I'm at an impasse and nothing quite makes sense.

The value you get from the form submission will be stored in the params hash. I'm fairly certain rails sanitizes everything automatically as of rails 4 and that you only need to be wary of tainted data during ActiveRecord queries.
Assuming you have your input: "4 3 2 1\r\n5 2 2 1" I would replace all r's and n's with spaces via the .gsub method. Once you have input such as
input= "4 3 2 1 5 2 2 1" you can do input.split(/\s/) which will convert the string to an array with all elements split where there are spaces. From there you can easily order the array since strings are comparable in ruby.
EDIT***
#states = input.bubblesort(#states) #then maybe something like this depending on your table setup: #new_state = YourModel.create(#states) ' If you're using a db like Postgresql you can specify that the input of a certain attribute will be an array. This is done as so via a migration: 'add_column :table_name, :column_name, :string, array: true, default: []'
Normally, the only logic that is kept in the model are your validations and sort/scope methods.

Related

R: Concat columns from data frame using wildcards

I got stuck with a specific question in R around concatenating columns of a data frame by using a wildcard. Perhaps I am searching wrongly. However I could not find a matching answer yet.
Here is my question:
I have a data frame df where each column represents a user (U1, U2, U3), e.g.:
> df <-data.frame(U1=1:3, U2=4:6, U3=7:9)
> df
> U1 U2 U3
1 1 4 7
2 2 5 8
3 3 6 9
I would like to concatenate the values from all users into a single vector as one would do using the c() function, e.g.:
> c(df$U1, df$U2, df$U3)
[1] 1 2 3 4 5 6 7 8 9
However, my number of users is large and varies over time. So, I look for an elegant dynamic way of concatenating the columns such as
> c(df$U*)
Unfortunately this does not seem to work. I played around with grep and regular expressions but could not get it to work. For sure, I could use a for-loop and program my own cat function but I assume there is a better way. I just don't find it. Maybe I am just blind. Hope you can help.
sub_df <- df[, grep(pattern ='^U.*', names(df))]
stack(df)$values
Hope this works for you. You could first subset some columns according to your need.
Coerce the data frame to a matrix first:
as.vector(as.matrix(df))
Use the bracket [ to select columns whose names match a certain expression:
df[, grep("U.*", colnames(df)), drop = FALSE]

Read array from YML in rails

I have an array in YML localization file:
en:
difficulty:
0: "Difficulty"
1: "Beginner"
2: "Intermediate"
3: "Advanced"
How can I read values from this array in view template? For example I can get 1 or 2 from db and I want to get values for 1(Beginner) or 2(Intermediate) in erb file and show it to user.
In Rails and Erb:
<%= t('difficulty')[1] %>
Would produce
Beginner
So replace '1' with the value from your database. You'd probably set this as an instance variable in your controller (ex. #difficulty = 1 or #difficulty = current_user.difficulty).
Note thought that you've created a Hash, not an Array. But since you used integer keys, the method for accessing them is identical. An array in YML is represented as:
en:
difficulty:
- Difficulty
- Beginner
- Intermediate
- Advanced
Note that you may want to rewrite this as:
en:
difficulty:
-
- Beginner
- Intermediate
- Advanced
Since it seems like you don't intend to use a difficulty of 0.

Access 2010 Query add text to end of existing text if condition is met

I have a column of data, diagnosis codes to be exact. the problem is that when the data is imported it turns 111.0 into 111 (or any whole number). I am wondering if there is an update query I can run that will add the ".0" to the end of any value that is 3 characters long. I had a problem of it stripping a value from 008.45 to 8.45 but I figured that part out using:
UPDATE Master SET DIAGNOSIS01 = LEFT("00", 3-LEN(DIAGNOSIS01)) + DIAGNOSIS01
WHERE LEN(DIAGNOSIS01)<3 AND Len(DIAGNOSIS01)>0;
I got that from here on stackoverflow. Is there a variation of this update query I can use to add to the right if it's only 3 digits?
Additional info... formats of the values in this column include xxx.x or xxx.xx with x being a number
When it comes to sql I am very new so please treat me like I'm 3... ;)
UPDATE Master
SET Master.DIAGNOSIS01 = IIf(Len([Master].[DIAGNOSIS01])=3,[Master].[DIAGNOSIS01] & ".0",[Master].[DIAGNOSIS01]);

Counting unique login using Map Reduce

Let say I have a very big log file with this kind of format( based on where a user login )
UserId1 , New York
UserId1 , New Jersey
UserId2 , Oklahoma
UserId3 , Washington DC
....
userId999999999, London
Note that UserId1 logged in New York first and then he flied to New Jersey and logged again from there.
If I need to get how many unique user login (means 2 login will same userid considered as 1 login), how should I map and reduce it?
My initial plan is that I want to map it first to this kind of format :
UserId1, 1
UserId1, 1
UserId2, 1
UserId3, 1
And then reduce it to
UserId1, 2
UserId2, 1
UserId3, 1
But would this cause the output to be still big in number (Especially if common behaviour of user is to login 1 or 2 times a day ). Or is there a better way to implement this?
Do map-reduce.
For example, you have 10000 lines of data, but you can only process 1000 lines of data in a time.
Then, process 1000 lines of data for 10 times.
If the sum of lines of the 10 processing's result > 1000:
do the above step again.
else:
use set directly.
I recommend making use of a custom key in the map phase. You can refer the tutorial here for writing and using custom keys. The custom key should have two parts 1) userid 2)placeid. So essentially in the mapper phase you are doing this.
emit(<userid, place>, 1)
In the reduce phase, you just have to access the key and emit the two parts of the key separately.

"fill in the blanks"

I'm trying to make a simple "fill in the blanks" type of exam in django and would like to know what is the best way to design the database.
Example: "9 is the sum of 4 and 5, or 3 and 6."
During the exam, the above sentence would appear as "__ is the sum of __ and _, or _ and __."
Obviously there are unlimited number of answers to this question, but assume that the above numbers are the only answers. But the catch is that you can switch the places of 4 and 5, or the places of 3 and 6 and still get the right answer. Besides, the number of blanks is not known, so it can be 1 or more.
I would go with something like. First define a Question table:
Question
--------------------------
Id Text
1 9 is the sum of 4 and 5, or 3 and 6
...
Then save the position of the hidden substrings, let's call them fields, in another table:
QuestionField
--------------------------
Id QuestionId StartsAt EndsAt Set
1 1 0 1 1
2 1 16 17 2
3 1 22 23 2 # NOTE: Is in the same set as QuestionField #2
...
This table lets you retrieve the actual value of the field by querying the Question table (e.g. entry one refers to the value '9' in the first question).
The "Set" column contains an identifier of the "set" in which this field is, where fields in the same set can be replaced by each other. When you populate it, you would have to ensure that all questions that can be replaced by each other are in the same set. The actual number of the set doesn't matter, as long as it's unique. But it makes sense to have it equal to the ID of one of the elements of the set.