So I have two model objects who hold similar data yet have different attribute names for them. I'll simplify the list for brevity and clarity. I want to actually make a temporary object with the info, compare the objects, and then update one if some of the data has changed. I'm open to suggestions about how to better accomplish this (please keep in mind that there are a lot more attributes then I'm showing)
Member object has the attributes employeenumber, employeefirstname and employeelastname
Censusitem object has the attributes employee_id, employee_fn, employee_ln
I have a has with the fields mapped over that I thought would simplify this:
maps={
employeenumber: :employee_id,
employeefirstname: :employee_fn,
employeelastname: :employee_ln
}
I thought I could then loop them and assign them somehow, but I'm obviously not even close:
def clean_member(censusitem, maps)
tempmember=Member.new
maps.each do |mname,ciname|
tempmember.i[o]=censusitem.i[1]
end
return tempmember
end
Feel like I'm missing something big, which is very normal for me;-) Any help would be greatly appreciated!
Mark
I believe this should work:
def clean_member(censusitem, maps)
tempmember=Member.new
maps.each do |mname,ciname|
tempmember.send("#{mname}=", censusitem.send(ciname))
end
return tempmember
end
Related
I am attempting to populate an array of tuples in a for-loop. The array needs to be predefined.
I am trying to do something along the following lines:
for class in keys(classes)
arr[class]=pmap(y->func(arg,y),1:length(arg1),batch_size=Int(round(length(arg)/nworkers())))
end
In the specific case, classes is a dictionary of type Dict{String,Tuple{Int64,Int64}}. For e.g. classes=Dict("Item1" => (5000,10000), "Item2" => (5000,10000))
The type-definition of broadcasting operation pmap(...) when class is Item1 is an Array{Tuple{Float64,Float64,Float64,Array{Float64,1}},1}. What is an appropriate way of preallocating arr?
arr[Item1] will be of type Array{Tuple{Float64,Float64,Float64,Array{Float64,1}},1}. So, I presume arr would have to defined as an Array{Array{Tuple{Float64,Float64,Float64,Array{Float64,1}},1}}, or something to this extent. But, I couldn't come up with the right notation for defining this.
It seems like I have overthought this; defining arr as a Dict{String,Array{Tuple{Float64,Float64,Float64,Array{Float64,1}},1}} was helpful.
This method works, but I'm sure the performance could be greatly improved. Also, I'm realizing how fun and awesome it is to take smelly code like this, and rubify it. But I need a little more help to get my Ruby skills to the level to refactor something like this.
An objective can have "preassign" objectives. These are pre-requisites that must be completed before the a student can try the objective in question.
ObjectiveStudent is the join model between an objective and a student. It has a method called "points_all_time" that finds the student's best score on that objective.
The check_if_ready method is the one that I'm trying to refactor in this question. It also belong to the ObjectiveStudent model.
It needs to check whether the student has passed ALL of the preassigns for a given objective. If so, return true. Return false if the student has a less-than-passing score on any of the preassigns.
def check_if_ready
self.objective.preassigns.each do |preassign|
obj_stud = self.user.objective_students.find_by(objective_id: preassign.id)
return false if obj_stud.points_all_time < 7
end
return true
end
Right now I suspect this method is making too many calls to the database. What I'm really hoping to find is some way to look at the scores for the pre-reqs with a single db call.
Thank you in advance for any insight.
The following should work for you:
def is_ready?
user.objective_students
.where(objective_id: objective.preassigns.select(:id))
.none? { |obj_stud| obj_stud.points_all_time < 7 }
end
We collect all the objective_students for the user where the objective_id is in the list of objective.preassigns ids. This results in one 1 query being executed.
Then we use Enumerable#none? to make sure that none of the objective_students have points_all_time less than 7.
You could also use the inverse .all? { |obj_stud| obj_stud.points_all_time >= 7 } if you wanted
One way you could "rubify" this method is to rewrite the signature as:
def is_ready?
It is common practice to append ? to functions that return a boolean value in Ruby. (Note: I also don't really see a reason to have the word 'check' in the declaration, but that's just an opinion).
Furthermore, if objective_id is the primary key for the objective_students model, you can simply write objective_students.find(preassign.id) instead of the find_by method.
I would also suggest having a separate method for returning a student's points (especially since I suspect you will need to get a student's points more than just once) :
def getPoints(preAssignId)
return self.user.objective_students.find_by(objective_id: preAssignId).points_all_time
end
Then your main method can be written in a more clear, self-describing manner as:
def is_ready?
self.objective.preassigns.each {|preassign| return false if getPoints(preassign) < 7 }
return true
end
I have a method drive that goes like this:
public double drive(double milesTraveled, double gasUsed)
{
gasInTank -= gasUsed;
return totalMiles += milesTraveled;
}
I know I can't return multiple values from a method, but that's kind of what I need to do because I need both of these values in my main method, and as it is now it's obviously only returning the one. I can't think of anything that would work. Sorry if this is a super beginner question. What can I do to get both values to return from the method?
You can return multiple value from a function. To do this You can use structure.
In the structure you can keep required field and can return structure variable after operation.
You can also make a class for the required field if You are using OOPS supporting language but Structure is best way.
In most languages you can only return a single value from a method. That single value could be a complex type, such as a struct, array or object.
Some languages also allow you to define output parameters or pass in pointers or references to outside storage locations. These kinds of parameters also allow you to return additional values from your method.
not sure, but can you take array of your values?
array[0]=gasInTank;
array[0] -= gasUsed;
array[1]=milesTraveled;
array[1] -= milesTraveled;
return array;
I'd like to know if I can add something similar to this in my class and have it build a class attribute that I can reference in other classes. I don't want to have to remember id's and I don't want to keep having to update id's as the id's in the weight tables change. Nor do I want to lock the weight table into a set of specific id's.
So I'd love to do something like the following:
class Weight < ActiveRecord::Base
attr_accessible :name
##kind = {
Weight.all.each do |weight|
weight.name.delete(' ').underscore.to_sym: weight.id,
end
}
cattr_reader :kind, :instance_accessor => false
end
Then in other areas of the code I can do things like..
scope :light, where(weight_id, Weight::kind(:light))
I'm sure there's some magic ruby way, I'm just not sure of the right syntax.
This is the closest I've come so far.
def self.kinds
kinds = Weight.all.map { |weight| { weight.name.delete(' ').underscore.to_sym => weight.id } }
kinds.reduce({}, :update)
end
and then...
scope :light, where(weight_id, Weight.kinds[:light])
Why not turn kind accessor into a class method which would lazily load the weights from database and lookup the neccessary one?
However, the stuff you are trying to do doesn't seem really good. What is the table behind Weight changes? What your classes will be loaded prior to the database connection gets set up (in some test environment, for instance)? I would suggest rewriting the scope to inner joing weight model with the appropriate name...
What is the terminology for the usage of "new" in:
list.Add(new{a=1, b=2})
And what type should I replace the T in List getList if I want to use the list as the returned value? I don't want to replace T with "object" because I want to parse it in Linq query.
Thanks.
Since you did not specify a type: new {1), it's called object initializers with anonymous types. (MSDN Explaining them) The Object Initializer part is where you do { a=1, b=2}.
If you want to be able to reference a type, you will have to create a type and stuff the values in.
list.Add(
new MyType() {
a=1,
b=2
});
If you are just going to be pairing two items look into using the Pair Class. There is also a Triplet Class just in case you might want to store 3 items.