HAPLAB Data Collection and Analysis
From MCIS Wiki
Progress Report: Adam: as of April 19, I'm struggling to get the graphs working. For now, I can generate a graph with data that I manually enter, but it is a separate file. I so far have not figured out how to get information from the database to generate a graph, nor can I display the image on the page that it is created on so far. I'm also struggling to figure out the layout of the pages themselves, as I have to move from a conveniently made array of rows and columns to a bunch of input fields.
these are the stories for what we'll be doing.
1. for the username and password access, the general idea is that an individual (perhaps the athlete/user or haplab person) walks up to the computer and starts using our program. They are greeted by a screen that asks for a username and password. They put in the credentials, they get logged in to their account.
2. after logging in, the user will be able to navigate to many different pages by clicking on a link, a tab, or a button(one of these three). In the first page, the user will be able to type in information on things such as their height, weight, body mass index = kg/m2, muscular fitness, cardiovascular test results, body fat, etc. before testing. There will be a button at the bottom that submits all the entered data into a table witin the database. The second page will allow them to input the same information but this will be their post test results. These results will also be submitted but go to a different table within the database. that way users can track their progress.
3. The user will be able to go to a page that allows them to input their training information. They type in information, and submit it. This records the information into a another table that they can later go back to to track their progress as is the case with any of the other tables.
4. If a user wants to see graphs and charts of their progress, they can go to a page that has a dropdown menu or a clickable checkbox that indicates what stat(s) they want to see. When they've selected their choices, they can then click a "generate chart" button which then creates charts or graphs based on the stats they want to look at.
5. The user can look at databases by searching for entries with specific stats (top speed < 25mpg or something).
6. The user is able to search the database using group criteria (freshmen, men, women, etc.)
Group Responsibilities:
Adam: work on graphing data. blogging of results Chris: Login and Forum stuff.
Contents |
Final Results
05/04/09(Chris)-As of 1:40 p.m. today all the basic funcionalities I have been working on are now working.
The login page ended up looking pretty much the same as our original concept, but getting the entire login system took me a lot more effort than I originally thought it would. The login code that I used came straight from the book for the most part, I originally started off trying to stick it together out of my own knowledge, and a website I found. However up till a little while ago I could not get the add user function to work correctly.
So now when someone goes to the home page they end up at the login page. If they are already registered they can go ahead and login and it will take them to the index page.
If they are not registered then they can click the link below the login boxes and the add user screen will show up, and they can then put in their username, and password, confirm the password, and check whether they are an administrator or not. Upon successful registration they will be automatically redirected to the index page.
Once the user is logged in and at the index page they have the option of entering in their general info, or the results of any of the other tests.
We split the original HAPLAB data sheet into separate forms to better facilitate data entry. These forms we ended up calling: the general info form, the male/female body fat assessment forms, the cardiopulminary form, the cycle ergometer form, the muscular fitness form, and the flexibility form.
The way it looks now
Login
Login
The code behind it
Controller
require 'digest/sha1'
class Login < ActiveRecord::Base
validates_presence_of :username
validates_uniqueness_of :username
attr_accessor :password_confirmation
validates_confirmation_of :password
has_one :generalinfo
has_many :flexibility
has_many :musclefitness
has_many :femalebfassess
has_many :malebfassess
def validate
errors.add_to_base("Missing password") if hashed_password.blank?
end
def self.authenticate(username, password)
login = Login.find_by_username(username)
if login
expected_password = login.encrypted_password(password, login.salt)
if login.hashed_password != expected_password
login = "Incorrect Password for #{username}"
end
else
login = "#{username} not found."
end
login
end
def password
@password
end
def password=(pwd)
@password = pwd
return if pwd.blank?
create_new_salt
self.hashed_password = self.encrypted_password(@password, self.salt)
end
def encrypted_password(password,salt)
string_to_hash = password + "wibble" + salt
Digest::SHA1.hexdigest(string_to_hash)
end
def create_new_salt
self.salt = self.object_id.to_s + rand.to_s
end
end
Model
require 'digest/sha1'
class Login < ActiveRecord::Base
validates_presence_of :username
validates_uniqueness_of :username
attr_accessor :password_confirmation
validates_confirmation_of :password
has_one :generalinfo
has_many :flexibility
has_many :musclefitness
has_many :femalebfassess
has_many :malebfassess
def validate
errors.add_to_base("Missing password") if hashed_password.blank?
end
def self.authenticate(username, password)
login = Login.find_by_username(username)
if login
expected_password = login.encrypted_password(password, login.salt)
if login.hashed_password != expected_password
login = "Incorrect Password for #{username}"
end
else
login = "#{username} not found."
end
login
end
def password
@password
end
def password=(pwd)
@password = pwd
return if pwd.blank?
create_new_salt
self.hashed_password = self.encrypted_password(@password, self.salt)
end
def encrypted_password(password,salt)
string_to_hash = password + "wibble" + salt
Digest::SHA1.hexdigest(string_to_hash)
end
def create_new_salt
self.salt = self.object_id.to_s + rand.to_s
end
end
Add User
The tricky part
For me the add user method was one of the most frustrating things I had to deal with on this project. again the code did come straight from the book and due to that there was an error that no one who looked at the code could find. This error stated that I was returning a nil object at some point. I finally had to place a breakpoint in several different places and run the debugger several different times to narrow down where the problem was occuring from this general spot:
def password=(pwd)
@password = pwd
return if pwd.blank?
create_new_salt
self.hashed_password = self.encrypted_password(self.hashed_password, self.salt)
end
To this exact line:
self.hashed_password = self.encrypted_password(self.hashed_password, self.salt)
I was stuck at this point for several days, attempting to talk with Peterson and not getting the chance to. Then finally just before class one day I had a thought, "well why don't I check where each of these variables are being assigned, so I took a more careful look at the self.hashed_password variable in the problem line, and the problem method, and I realized that self.hashed_password never got assigned anything before sending it into the encrypted_password method to be encrypted. So I replaced:
self.hashed_password = self.encrypted_password(self.hashed_password, self.salt)
With:
self.hashed_password = self.encrypted_password(@password, self.salt)
And wouldn't you know it with the changing of one word the problem was solved.
Index
General info
The Code Behind it
Controller
class GeneralinfoController < ApplicationController
def list
end
def submit
if param_posted?(:generalinfo)
@info = Generalinfo.new(params[:generalinfo])
@info.save
end
end
private
def param_posted?(symbol)
request.post? and params[symbol]
end
end
Male Body Fat Assessment
The Code Behind it
Controller
class MalebfassessController < ApplicationController
def list
end
def submit
if param_posted?(:malebfassess)
info = Malebfassess.new
p = params[:malebfassess]
info.age = p[:age].to_i
info.chest1 = p[:chest1].to_f
info.chest2 = p[:chest2].to_f
info.chest3 = p[:chest3].to_f
@chestavg = (info.chest1 + info.chest2 + info.chest3)/3
info.ab1 = p[:ab1].to_f
info.ab2 = p[:ab2].to_f
info.ab3 = p[:ab3].to_f
@abavg = (info.ab1 + info.ab2 + info.ab3)/3
info.thigh1 = p[:thigh1].to_f
info.thigh2 = p[:thigh2].to_f
info.thigh3 = p[:thigh3].to_f
@thighavg = (info.thigh1 + info.thigh2 + info.thigh3)/3
@foldsum = @chestavg + @abavg + @thighavg
@bodydensity = 1.10938-(0.0008267*@foldsum)+(0.0000016*(@foldsum*@foldsum))-(0.0002574*info.age)
info.percentbodyfat = (4.95/@bodydensity)-4.50
info.norm = p[:norm].to_f
info.save
end
end
private
def param_posted?(symbol)
request.post? and params[symbol]
end
end
Accessing Submitted Info for Calculations
<% form_for :malebfassess, :url => {:action => :submit} do |form| %>
<label>Age:</label><%= form.text_field :age %>
<table>
<tr>
<td>
<table>
<tr>
<th>Chest</th>
<td>
<p>
<label>1.</label>
<%= form.text_field :chest1 %>
<label>2.</label>
<%= form.text_field :chest2 %>
<label>3.</label>
<%= form.text_field :chest3 %>
</p>
</td>
</tr>
</table>
</td>
<td>
<table>
<tr>
<th>Abdomen</th>
<td>
<label>1.</label>
<%= form.text_field :ab1 %>
<label>2.</label>
<%= form.text_field :ab2 %>
<label>3.</label>
<%= form.text_field :ab3 %>
</td>
</tr>
</table>
</td>
<td>
<table>
<tr>
<th>Thigh</th>
<td>
<label>1.</label>
<%= form.text_field :thigh1 %>
<label>2.</label>
<%= form.text_field :thigh2 %>
<label>3.</label>
<%= form.text_field :thigh3 %>
</td>
</tr>
</table>
</td>
</tr>
</table>
<label for="norm">Norm(choose from chart below)</label>
<%= form.text_field :norm %>
<label>Percent Body Fat:</label>
<p>
<%= submit_tag "Submit Data" %>
</p>
<% end %>
Female Body Fat Assessment
The Code Behind it
Controller
class FemalebfassessController < ApplicationController
def list
end
def submit
if param_posted?(:femalebfassess)
info = Femalebfassess.new
p = params[:femalebfassess]
info.age = p[:age].to_i
info.triceps1 = p[:triceps1].to_f
info.triceps2 = p[:triceps2].to_f
info.triceps3 = p[:triceps3].to_f
@tricepsavg = (info.triceps1 + info.triceps2 + info.triceps3)/3
info.sup1 = p[:sup1].to_f
info.sup2 = p[:sup2].to_f
info.sup3 = p[:sup3].to_f
@supavg = (info.sup1 + info.sup2 + info.sup3)/3
info.thigh1 = p[:thigh1].to_f
info.thigh2 = p[:thigh2].to_f
info.thigh3 = p[:thigh3].to_f
@thighavg = (info.thigh1 + info.thigh2 + info.thigh3)/3
@foldsum = @tricepsavg + @supavg + @thighavg
@bodydensity = 1.099421-(0.0009929*@foldsum)+(0.0000023*(@foldsum*@foldsum))-(0.0001392*info.age)
info.percentbodyfat = (5.01/@bodydensity)-4.57
info.norm = p[:norm].to_f
info.save
end
end
private
def param_posted?(symbol)
request.post? and params[symbol]
end
end
Accessing Submitted Info for Calculations
<% form_for :femalebfassess, :url => {:action => :submit} do |form| %>
<p>
<label>Age:</label>
<%= form.text_field :age %>
</p>
<table>
<tr>
<td>
<table>
<tr>
<th>Triceps</th>
<td>
<label>1.</label>
<%= form.text_field :triceps1 %>
<label>2.</label>
<%= form.text_field :triceps2 %>
<label>3.</label>
<%= form.text_field :triceps3 %>
</td>
</tr>
</table>
</td>
<td>
<table>
<tr>
<th>Suprailim</th>
<td>
<label>1.</label>
<%= form.text_field :sup1 %>
<label>2.</label>
<%= form.text_field :sup2 %>
<label>3.</label>
<%= form.text_field :sup3 %>
</td>
</tr>
</table>
</td>
<td>
<table>
<tr>
<th>Thigh</th>
<td>
<label>1.</label>
<%= form.text_field :thigh1 %>
<label>2.</label>
<%= form.text_field :thigh2 %>
<label>3.</label>
<%= form.text_field :thigh3 %>
</td>
</tr>
</table>
</td>
</tr>
</table>
<p>
<label for="norm">Norm(choose from chart below)</label>
<%= form.text_field :norm %>
<label>Percent Body Fat:</label>
</p>
<p>
<%= submit_tag "Submit Data" %>
</p>
<% end %>
Cardiopulminary
Cycle Ergometer
Muscular Fitness
The Code Behind it
Controller
class MusclefitnessController < ApplicationController
def list
end
def submit
if param_posted?(:musclefitness)
@info = Musclefitness.new(params[:musclefitness])
@info.save
redirect_to(:action => "submit")
end
end
private
def param_posted?(symbol)
request.post? and params[symbol]
end
end
Flexibilty
The Code Behind it
Controller
class FlexibilityController < ApplicationController
def list
end
def submit
if param_posted?(:flexibility)
@info = Flexibility.new(params[:flexibility])
@info.save
redirect_to(:action => "submit")
end
end
private
def param_posted?(symbol)
request.post? and params[symbol]
end
end
Here is the zip file containing all the code for the project: [1]









