Tuesday, May 13, 2014

This is the end...as we know it....

The presentations today (including ours) went really well in my opinion. However, I don't think there was any question of who the winners were going to be. MechanApp and VisualScheduler had nice presentations and a lot of potential from the very start of the practice presentations. MechanApp had a slick presentation (as usual!) and their website interface is very simple and elegant. VisualScheduler is extremely useful with a nice interface. I think their schedule generator adds a lot of value to their site (on top of the value already added by removing the horror that is scheduling on myUNM!) and, from the sound of it, they are going to turn this into an actual product, which is great. It almost (almost!) makes me wish I wasn't graduating so I could actually try it out.

All the other presentations showed a lot of improvement from the last round of practice presentations. There were almost no glitches and the presentations themselves looked quite professional. I was pretty proud of our team in particular since our initial practice presentations had been so weak (due to lack of practice for the most part). After the optional practice round with Prof. Ackley, we really buckled down and practiced the presentation 10+ times. As I mentioned in a previous post, I also went through and made some edits to the slides, changing the colors, font sizes, and adding graphics, which I think helped make the slides look more professional and less "academic." Overall, I think we improved significantly since Friday (our last practice presentation) and I am glad that we were able to revamp the slides and do a lot of practice because it made a huge difference.

So back at the beginning of the semester, this day seemed so far away. Then suddenly it was the end of April and we were scrambling to wrap up any loose ends before the final presentation. As a team, I think we delivered an application that met our goals, looked pretty polished, and had a presentation to match. I learned a lot from this project, especially since this was my first time using Ruby, Rails, Bootstrap, and Haml and I had only had some limited experience with JavaScript and CSS prior to this. I'm glad that I decided to go with a project that used technologies that I wasn't familiar with since it challenged me and really helped me improve as a software developer. And kudos to everyone on my team; it was good working with you and I learned a lot!

Sunday, May 11, 2014

So, does practice really make perfect?

Ok...well maybe not perfect, but certainly it makes you better! Yesterday morning, Matt S., Matt F., Fernando, and I met to practice our presentation. We had made some changes based on Prof. Ackley's feedback (particularly the addition of our slogan--"Help you become a better you") so now we just needed to practice. We were able to practice in the room where the final presentation will be held, which was a great opportunity for us to familiarize ourselves with the projection equipment and figure out whose laptop would work best with the projector's resolution. It was decided that we would use my laptop since the higher resolution projector plays nicely with it.

Once we got everything set up, we went through the slides about five or six times, with Matt F. and Matt S. switching parts (i.e. changing up who would talk through the demo, who would talk through the slides, etc.) to see what worked best. Fernando and I were the audience and judges. In the end, we decided that the best format was to have Matt S. talk though the slides (which, by the end, he was able to do very nicely without any notecards) and to have Matt F. talk through the demo. Since Matt F. was in charge of running the computer, it made it smoother and easier if he also talked through the demo since there would be no possibility of mixing up what was being shown versus what was being said. All in all, it was a very productive few hours and I just wish that we had actually done a lot more practice prior to our practice presentations because we would have done so much better initially. But, at least we are finally practicing now so hopefully the final presentation will go really well.

After the meeting, I started going through the slides for the presentation to make more changes that were brought up during our presentation to Prof. Ackley yesterday. I decided to include a few graphics from the app on some of the slides to break up the monotony of text. I also removed all but the necessary keywords from most of the bullet-points to reduce the overall amount of text. For the bullet-points (not the text, just the bullet-point circles themselves), I reduced the font size significantly and changed their color to green (the same green used in our website) so that they are not so prominent. I think this helped make the slides look a little less academic, which was a criticism that has been brought up during several of our practice presentations.

I still think we might be able to make a few more changes that will improve the overall look and feel of the slides, but at least we have made some significant improvements that I think will help our final presentation.

That dang checkin button...again!

As I had written a few posts back, we had been having issues with the Checkin button; it was not disabling when it should and we had initially traced the problem back to the abandon challenge functionality, where certain records were not being removed and were being associated with the wrong challenge. So, I had fixed this issue...I thought. Then it starts appearing again without any apparent rhyme or reason. When it showed up in our presentation this morning, that was the last straw. As soon as I got home, I started combing through the code again to try to figure out what I had overlooked last time. I cleaned out my database and started taking challenges, abandoning challenges, completing challenges and....ah ha! I found where the bug was occurring. When you completed a 1 checkin challenge and then went to take another challenge within that same week, a date range search was being done in order to find the latest week record associated with the current challenge. Problem was, this was being called with ".first" to return on the first matching record. Thus, if two challenges were completed within the same week by the same user, the week record associated with the first challenge taken would be returned instead of the latest week record. Fixing this issue was a simple matter of replacing ".first" with ".last".

I did some testing after this fix to make sure that it was all working correctly and everything appears to be functioning as expected. I also made a small change to the abandon challenge functionality to make sure that all the Week and History records associated with the abandoned challenge are deleted so that they do not end up causing issues later on.

Saturday, May 10, 2014

Practice presentation...again

We had volunteered for a final practice presentation with Prof. Ackley yesterday morning. I think it was good that we did it because it is always helpful to get feedback. I think our biggest issue with our presentation is lack of practice. I think we really need to just sit down and run through it at least five or six times in order to figure out what works and what doesn't. You can have a decent presentation, but it won't have much impact if it isn't practiced and smooth.

Prof. Ackley also brought up a lot of things that we can change to make our presentation better. For instance, having a slogan ("Help make you a better you") and, at a minimum, using this slogan in the first and final slides. Also, and this is something I have brought up a previous meetings, we need to justify the honor system choice--i.e. if the user cheats they are only harming themselves. Regarding the competition, we should have more "damning with faint praise" for competitors to help emphasize what sets us apparent from these other applications and why we are "better".

The demo of the app itself still had some glitches and there was some confusion about whether we should show a user signing up (this was nixed as not a good idea) or just logging in. Also, initially starting with taking a simple, pre-made challenge (like "Check-in for signing up" or something similar) would be better than jumping into creating a challenge (though this can be done a little later, since it is an important feature of our application). I also think that whoever does the actual run-through of the slides should be the one whose Facebook account is used since this is less confusing than trying to switch accounts all the time. Prof. Ackley also mentioned that we should try to unify the fonts on our site a little more to go with our mostly lowercase theme. This is something that I finished working on last night so now the font capitalization looks a little more cohesive.

Friday, May 9, 2014

Debugging

Yesterday I ran through the website again, doing some randomized testing (i.e. just clicking on buttons in no particular order to make sure things are working) and found an issue with challenges that have parent challenges (i.e. where there are levels of challenges). If, for example, you click a level 2 challenge and you have not yet taken the level 1 challenge, the display modal just shows a button saying "View Parent Challenge". However, I discovered that this button was not actually "hooked up" to anything. So, I spent about an hour googling around and trying to figure out how to get a modal to refresh its content while it is being displayed. After some frustration, I found that some simple jQuery:

  $(document).ready(function(){
    $('.modal-id-here').on('hide.bs.modal', function () {
      $('.modal-id-here').removeData();
    });

  });

worked perfectly. It clears out the old content so that the new content can be loaded (in this case, the new content is the information about the parent challenge).

As I was testing this fix, I found some problems with the .csv file that is used to seed the challenges in the database. Some of the challenges were not having their parent challenges set properly and therefore were not being displayed as child challenges in the application. I went through the list and fixed this issue so that the challenges will now be correctly associated with their parent.

Wednesday, May 7, 2014

Ruby on Rails...then and now

I was thinking about my impression of Ruby on Rails now that I've been working with it for ~12 weeks. I had to learn a language that was very different from what I'm used to (Java, C, and C++), which was a little intimidating. I had picked Demigod partly because of the idea itself but also because of the opportunity to learn something more than just Java. I could have gone with a project that had more familiar tools, but I decided to try out something different and I'm glad I did. As frustrating as it was initially trying to remember how models, views, and controllers fit together (not to mention the seventh circle of hell that is setting up Ruby) and where a certain file is located in the maze of folders that makes up a Rails project, I felt I was finally (around week 4 or 5) able to really start making sense of it all.

As someone who is used to working in Java (school and work) with some C and Scheme/Haskell classes thrown in for good measure, I don't have much opportunity to work in other languages unless they are my own personal projects. I've taught myself the basics of Javascript, HTML, and CSS through some of my own projects, but it is never quite the same as having to work on a relatively large project in an unfamiliar language. I think it is a little like learning an actual language: you can take a lot of classes and practice as much as you like, but nothing is better for learning that going to the actual country and immersing yourself in the language. Having a large project is somewhat like that. You have to immerse yourself in the language so you can understand as much as possible as quickly as possible, otherwise there is no way that you can be a functioning member of the team. Though learning RoR could be quite a challenge at times, I think it worked well for our project and we were able to implement all the necessary functionality, create a good layout and design, and deliver a final project that met our requirements. For me, that indicates that the choice of language was a good one. If your language of choice does what you need in a relatively simple and efficient manner, then I say it was the right language for the job. As with any language, there are unique issues and problems that you have to overcome, but, overall, RoR worked for our project.

Sunday, May 4, 2014

Meeting: Clean up and fixes

We had a meeting today to make some final updates/improves to the code and go over our presentation. I updated the code that determines when the user can check-in and what defines a "day" and a "week" is. Previously, for testing purposes, we had set a day to be 20 seconds and a week to be 7*20 s = 140 seconds. This made it much easier to test the current progress code to ensure it was working as expected.

So I make the changes and run the code and...it breaks. When I take a challenge and check-in, everything is fine. But once I complete my first check-in, the "Checkin" button should then be greyed-out until 24 hours later since check-ins are permitted only once per 24 hours. However, the Checkin button is not disabled and I can click it until I finish the challenge. I ask Fernando to run his copy of the code with the seconds usage just to make sure that changing the timing didn't mess things ups. Well, the version of the code on his machine is behaving perfectly fine so I run grep in the command line to make sure that I have replaced all instances of 20.second and 140.second (rails handy way of giving a number of seconds) with 1.day and 7.day. There are no lingering occurrences so I comb through the Javascript for the current challenge progress bar to make sure that I haven't missed some code that might be messing up the timing. Nope, everything looks to be in order.

I clear out my database and take a challenge again. It works fine this time! I then login to my Facebook account and take a challenge there to make it is still working and...it breaks! The Checkin button doesn't disable after the first check-in. So it appears that this problem is caused when two or more users are all taking challenges (not necessarily the same ones) at the same time. Obviously, this is a major problem since our app should be able to handle this fine.

Matt S. and I start looking over the user's controller (which is where most of the methods that run the current progress bar are placed). We also query the database from the Rails console and notice some inconsistencies in the way the weeks and user challenges are being saved in the database. It appears that the wrong week record is being associated with the wrong user when the user is taking a challenge. We skim through the methods in the user's controller to see if we spot a place where the database is being accessed without specifying the current user id. Nothing. We can't find anything out of place so I go back to looking over the presentation.

However, the issue is still bugging me since it is a major problem with the logic of the code. I decide to go over the user's controller once again and finally find the problem. A "where" query is being run on the Weeks model but the current user id is not being passed in so there is the potential for a week record from another user to be returned for the current challenge depending on the matching results returned by the query. Once the current user id is specified in the query, I clear out the database and take challenges in both my administrator account and my Facebook account. Now the Checkin button is properly disabled no matter which account I am in.

So, problem is solved! Not quite. About an hour later, I find that it shows up again, but only after the Abandon a challenge button is pressed. After some digging around in the user challenge model (where the abandon challenge method is located), we discover that the Week records for an abandoned challenge are not being deleted and are causing issues when the next challenge is taken. After adding a line to delete all the Week records for the abandoned challenge, the code runs correctly.

We also spent some time going over the presentation and how we are going to do the demo. Next weekend, we'll meet to really hammer it out and hopefully, if we can get access to the room we will be presenting in, we can also practice in there, which would be really nice.


Wednesday, April 30, 2014

Footers

I was poking around the app some more yesterday morning and noticed that the footer was only appearing in the homepage when the user wasn't logged in. In most websites, the footer is part of the overall website template, so it almost always appears at the bottom of every page. Thus, I decided to move the footer code from the main page layout view to the application view so that it would be rendered on every page.

After moving the footer code and checking some pages on the app, I thought that everything was good. Then, I decided to sign out and then sign back in and discovered that the footer was not "sticky", i.e. if the content of the page was not tall enough to push the footer to the bottom, then the footer would just appear somewhere in the middle of the page. So I set about looking for solutions to this issue. I found several sites that listed out possibilities for getting the footer to work, but this site provided the best instructions. I had to adjust the margin padding to fit the smaller (84px) size of our footer, but other than that, the code worked pretty much as is. It is very important to add the CSS for having the height of the html and body set at 100% (I forgot to add this in the first time and nothing worked).

So, once again, I though I was done, but not so fast! I did more testing yesterday afternoon and found that the challenge category descriptions were still displaying the footer in the middle of the page. I looked through the views for these pages and discovered that the text had not been placed in a separate container. So, I wrapped the text in a new section and container and put some padding between the text and the title for each description page. I also changed all the line breaks to paragraphs, since this allows for cleaner and more flexible styling. Once these changes were complete, the footer "stuck" to the bottom of these pages as well.

Forgot password?

I was doing some more testing of our app yesterday--basically just trying sequences of actions that I could see a user doing. While doing this, I ran into an issue with the "Forgot Password" link that is displayed on the login form. When I clicked this link, it displayed a form where I could enter my email to have my password reset (which I had to restyle with CSS since it had accidentally been missed when I had redesigned the login and signup forms). However, when I clicked the button to have the application send an email to the provided address, the app blew up with an error message that said (in the true cryptic fashion of most error messages): "Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true". Essentially, this was telling me that the mailer for the application was not set up.

So I did some googling and found this blog post on mailer setup and this related blog post on environment variables. I was able to modify the instructions in the first blog post (with hard coded values for the mailer settings since at this point I just wanted to make sure it worked) and added these lines to the development.rb file (since I was just testing it locally):


  config.action_mailer.delivery_method = :smtp

  config.action_mailer.smtp_settings = {
    address: "smtp.gmail.com",
    port: 587,
    domain: "domain.com",
    authentication: "plain",
    enable_starttls_auto: true,
    user_name: "user@domain.com",
    password: "password123456"

  }

Obviously, the domain, user_name, and password fields are just filled in with nonsense values for the purposes of this example, but, for testing, I filled them in with my gmail account information so I could make sure everything was working. I also added this

  config.action_mailer.default_url_options = { :host => 'localhost:7777' }

to the development.rb file so that the mailer would work on the localhost setup (port 7777 is used instead of 3000 because we have Facebook authentication).

Once these changes have been made, the server needs to be restarted in order for the changes to take affect (which I forgot the first time and therefore spent several frustrating minutes trying to figure out what I did wrong).

Now, to ensure that the username and password for the mailer is not available for anyone with some computer skills to see, environment variables need to be used. This is where I need to discuss how to handle this with my teammates, since it appears that this requires setting up another gem called "foreman", which changes quite a few things about the app (including how the webserver is started) so we need to make sure that this will work without breaking other parts of the app. Fernando also has the same issue with code that he had added for a contact form so we need to figure out how to hide the username and password from the rest of world.

Monday, April 28, 2014

Presentation reactions

Today we had the final round of practice presentations before the final. Each of the groups showed improvements over their previous presentations, though there were still some a few issues to work out before the final. My reactions:

Automaton
  • The explanation of the app was much clearer and easier to follow than last time. I liked that they had included a slide explaining the more important parts of the game.
  • The demo itself was also a little easier to understand (and I noticed that they added tooltips over the icons that are dragged and dropped onto the main board). However, if I was someone who was using this app for the first time, I feel like I might really struggle to understand what is going on and what is expected to complete a certain level. My suggestion for them would be to include a demo tutorial on a simple level so the user can see how everything works before they start on their own.
  • Handout is good, but I agree with Fernando that the blue is too dark. I looked back at their previous hand-out and the blue on that one was much lighter (maybe due to using a different printer) and was much easier to read.
  • The presenters themselves did better than last time, though the demo did seem to go by really fast, so slowing down the talking will probably be good for the final presentation.
  • They mentioned that a user can create and upload a level but didn't demo it...maybe this could be something they could include as well to add some time to the presentation.
VisualScheduler

  • The slides had more of an impact this time, especially the one containing the ridiculous number of windows that you must click through just to find and register for once class on myUNM (though the sheer number of windows also made some of the text on the slide go out of the display zone, so this should probably be fixed).
  • I noticed that they had moved the calendar feature to be below the list of classes. Personally, I'd prefer it in another tab as well since I hate scrolling, but this way does provide a quick way to check if your schedule has conflicts.
  • Not related to the presentation, but I like their addition of the automated schedule generator. That is a pretty nice feature since I (and probably every other student at UNM) has to go through the agony of trying to determine how to create a "nice" schedule that includes all the classes you need to take.
  • Also noticed that Zach kept looking up at the slides and turning his whole body away from the audience, which was distracting and seemed to imply that he was really relying on the slides for guidance instead of just turning to them to point something out, gesture to something, etc.
G.E.R.A
  • Not sure exactly how to spell G.E.R.A. Is it is G.E.R.A or G.E.R.A. (with a period after the "A"?). The slides had both versions while the handout and the website only appears to have G.E.R.A (with no period after the A). I would assume that since it is an abbreviation, it would have the period after the A, but I'm not sure what they are going for.
  • The handout was much easier to read, though they did include a pie chart on a dark background with tiny, dark grey text that was impossible to read. I think that this should either be removed entirely or the colors should be changed. 
  • They mentioned spendable points during the presentation but didn't really explain what exactly these bought. I'm assuming that it would be buying things from the "Armory", but it wasn't really clear.
  • The presentation itself was much improved. It appeared that Ben made a real effort to memorize his notecards, which helped a lot and made the presentation flow better and look more convincing. He did mess up on one slide, but if he can power through his mistakes instead of focusing on them, I think he will have a pretty good presentation.


Presentation meeting

Yesterday we met to finalize our presentation. We finished adding in information about the competition and some statistics on the decline of educational performance in America (related to the need for our Intellectual challenges). I also made a few changes to the CSS for the homepage, reducing the height of the footer so that it was not overly large in comparison with other elements on the page. Additionally, Matt S. noticed that the "Abandon" button (allowing the user to abandon a challenge) was disabled when the check-in button was disabled. This was because, originally, this button was meant to be the "Fail" button but we found that this really didn't serve a purpose in our application so we changed it to "Abandon." Given the new context of the button, the user should be allowed to abandon a challenge whenever they want, so the disabling was removed.

Fernando suggested integrating a FAQ into the website, which he created a Google doc for. I think this is a good idea since having a quick reference guide for the user can be quite helpful for improving the overall user experience. I have been adding to it (as have Fernando, Matt S., and Matt F.) so hopefully we can get this integrated into the website this week.

Over the next couple of weekends, we will probably meet to run through the presentation so that it is smoother than last time and so that we can work through any bugs (such as the Facebook fiasco during our last presentation). I do hope that we can get access to the room where our final presentation will be held prior to May 13th since this would be very helpful for making sure the presentation goes as smoothly as possible.

Regarding marketing, I have been posting to my Facebook page via Demigod, so maybe it will entice someone to check it out before our final demo. I also plan to giving the link to a few friends and family over the next few weeks so they can try it out. It might also be a good idea to post up a few flyers around campus...you never know who may bite!

Wednesday, April 23, 2014

Presentation and code fixes

I worked on the presentation a little today. I added information about Demigod's competition (Fitocracy, DailyBurn, etc.) so we can utilize the Goldilocks method to justify why Demigod is different. I also broke out the "three stages to implementing healthy behavior" into three separate slides and added information on how Demigod helps users move through these three stages and build healthy habits.

We still need to work on a conclusion slide, as well as adding "intelligence" statistics (i.e. justifying why we are incorporating an intelligence category of challenges into our website). We also need to reduce and/or condense the amount of facts that we were previously using since having too many just bores the listener and takes away time from other important areas, like the demo.

I also worked on fixing an issue with our app that had been annoying me for quite awhile. We had incorporated a drop-down menu in the right side of the navbar. This menu has the user's name on it (as you see in most websites) and, when clicked, it displays a list of links relevant to the user (their created challenges, their completed challenges, etc). However, if you clicked the user's name again to close the drop down and then moved the mouse so it was no longer hovering over the name, the text for the name would turn dark grey (instead of white, which is the color it is supposed to show when the mouse is not hovering over it). I spent a good thirty minutes going through the CSS for the navbar in the Chrome's Developer Tools panel, trying to figure out where this color was being set. After some trial and error (read, "playing around") I finally discovered that I had to set the color and background-color properties of the default navbar "hover" and "focus" properties for the navbar links. This solved the problem and now the link is white when the menu is closed and the mouse is no longer hovering over the user's name in the navbar.

Finally, I added some text to the current challenge partial which tells the user how many check-ins they have to do for a given week. To improve this, I might end up adding another Ajax call to get the time and date when the user can next check-in (since we restrict check-ins to once per 24-hours).

Tuesday, April 22, 2014

Facebook button mods and more javascript

Last night, I made some modifications to the Facebook button we had been using. When taking a challenge, the user has the option of sharing their current progress. This had been displayed originally as:


I had done this original styling of the Facebook button, but it was more a temporary fix than anything else and didn't really match up with the color palette or design of the rest of the site. Also the placement below the check-in and abandon buttons just made the current challenge display awkwardly large (vertically). I found a simple Facebook "f" symbol from the (thousands!) of FB images littering the web and then used Photoshop to add some text (using the default font for our app). The text was specific to our application so I felt it worked better than the generic "share on facebook". I also decided to move the button to be in-line with the check-in and abandon buttons rather than below it since this looked cleaner. The result:


I also feel that the darker blue fits better with the other colors. I used this same blue color for the "share to facebook" button that appears when the user finishes a challenge. Now the Facebook buttons are at least consistent.

I also added a simple check for these buttons to determine if they should be displayed. Obviously, if a user is not logged in through Facebook, then these buttons should not be displayed because they will not work (and will actually cause a server error if clicked). Hence by adding one line prior to each button display in the current challenge partial view:

-unless current_user.auth_token.blank?

I was able to determine whether or not the user had logged in with Facebook (if the auth_token was blank, then the user was not logged in with Facebook).

While modifying the Facebook buttons, I also added some more Javascript to the current challenge partial. This code checks if the user has finished a week and then displays the time and date when they can start checking in for the next week. This information is also displayed in the modal that pops up when a user finishes a week, but this only displays once for a given week so the user could easily forget when they can start their next round of check-ins. Adding this to the current challenge fixed this issue.

Modal styling

I finished up restyling the new challenge modal so the layout was a little more uniform. I decided to change the overall layout of this modal to be two columns since there is so much information to enter for a new challenge. If the elements are just arranged vertically, then the user has to scroll the modal a little to get to the bottom (unless they have a fairly large screen). However, I did add some extra CSS to ensure that this two column layout is not used for a mobile screen size. In this case, the layout defaults to vertical so horizontal scrolling is not necessary.

To actually change the modal width so that the two column format would display, I had to do some googling since it was not a straightforward process (i.e. you couldn't just change the width property for the modal and call it good). After some false starts, I eventually found a solution that worked:

.modal.modal-wide .modal-dialog {
  width: 62%;
}
.modal-wide .modal-body {
  overflow-y: auto;

}

This allowed the width to be scalable (since it is a percentage), without causing the modal to jump to one side of the screen (which is what happens if you just try to set the width for the modal instead of the modal dialog component). As I was reading on stackoverflow.com, apparently you used to be able to set the width property for just the modal prior to Bootstrap 3.0. In Bootstrap 3.0 and later, you have to set it for the modal-dialog property (though it wasn't clear exactly why they changed it). The overflow-y CSS property tells the modal how to behave if the content overflows the top and/or bottom of the modal's area. Setting this property to "auto" just says that the default behavior should be used, which in this case, is scrolling. So scrolling will be implemented in the content overflows in the vertical directions.

Pitches, round 2

Our group had our second pitch today. I think it went better than last time, but it definitely needs some work before the final presentation. Some important points were brought up, namely:
  • More information about how Demigod helps users improve their brain/mind as well as their body.
  • Reducing and/or condensing the number of facts used in the presentation.
  • Addressing potential cheating by users (justifying our use of the honor system).
  • Breaking up the slide for "Our Solution".
  • Justifying why our app is "just right" compared to other applications similar to ours.
I added placeholders for all these items to the presentation slideshow so we can fix these issues before the final presentation. I also think that it would have been better during the demo to have chosen a challenge (or, better yet, created one) that was just one check-in (named "Finish this demo" or something like that). We also need to make sure that the Facebook functionality is working properly for whoever is doing the demo since this was an issue with the demonstration.

There were also two other presentations today--MechanApp and Powderade. MechanApp had a very nice presentation which flowed well. I also like that they added a conclusion, which is something that I think we should probably add to our presentation as well. They improved a lot from their last presentation and I like that they emphasized the graph search and made it easier to actually see the graph itself.

Powderade also improved from last time. They had slides and a (shorter) video, which worked better than just one long video. However, they did have technical difficulties with the video, which interrupted the flow of their presentation so, as was suggested in class, it might be good to have a local copy just in case. 

Friday, April 18, 2014

And.....more design!

I worked on getting the sign-up, login, and edit-account forms styled similarly to the rest of the site (dark grey and green theme). When I was looking through the forms (which are generated by Devise, which handles user authentication), I had thought that I could just add some classes to a stylesheet (as I had been doing for everything else), include them in the appropriate areas in the haml view and call it good. Nope! The way Devise works, it generates an .erb file (embedded Ruby) to go along with the haml view. To actually get the CSS to work properly, you have to edit the CSS classes referenced in the .erb file (or create your own CSS classes and then make sure they are used in the .erb file, not the .haml file). Once I figured this out, styling the forms was fairly straightforward.

I also decided to move the 'change profile picture' capability to a modal since it didn't really make sense to redirect the user to an entirely new page just to click a few buttons to upload the image. After some trial and error, I discovered that the best way to have the modal display when the "Change Profile Picture" link was clicked was to have the modal and form in a partial, which was rendered in the page by calling "= render 'partial_name_here'". However, the modal would only display when the link was clicked (this is very similar to how Matt F. had done the modals for the Challenges page). I did run into an issue when I was trying to get this to work because I had forgotten to include the "#" as the link path (the hash symbol just serves as a placeholder, or a link to the top of the current page; thus it does not redirect the user anywhere else). Because of this, the "link_to" method was trying to load the modal and data target information as a path. I realized my mistake when I was looking at the URL displayed in the browser and added the "#" since I just wanted to display the modal, not redirect the user to another page.

Wednesday, April 16, 2014

Pitches

Something that I should have done earlier is write down my reactions to the project pitches this past Monday. I took some notes during the pitches but had forgotten to put them in my blog so here they are.

Overall, I think it is really helpful (if stressful) to have multiple practice pitches. It is also very helpful to see how other groups do their pitches and note down what works and what doesn't. As I mentioned in a previous post, our initial slides were much too wordy and we needed a live demo (as well as more practice for the actual pitch so that transitions would go smoother). Nikan even mentioned today in the client meeting that practicing the pitch repeatedly is really key to making sure it is professional. We are planning to meet this Friday evening to practice the pitch and make any last minute adjustments to the slides. We will also have a live demo of our web application, which should look a lot nicer (and be more realistic) than the video we had used previously. We also plan to revamp our hand-out, which, as mentioned in class, really just needs to be a few key points and not copies of the slides.

As for the pitches made by the teams on Monday:

Automaton

  • Really colorful layout and handout (almost too colorful for my taste, but if it is catering more towards younger people, such as kids and teens, then I can understand why the use of bright colors would be important for capturing a child's interest).
  • I felt that the pitch needed some slides instead of just talking and a demo. Having a demo is important, but, for me, I also like seeing what is being said as well as hearing it since I tend to remember more of the information and it also makes it easier to take notes.
  • I think that they should have just had one person do the talking (with perhaps one other person maybe talking during parts of the demo) since having three people talking was just a little too awkward and forced.
  • The demo itself was a little confusing since there were no obvious directions or explanation of the what a level in the application was supposed to accomplish. As some people pointed out in class, having a more detailed and prominent description of the level (and maybe tooltips) would have helped out significantly with the demo. Also, they had too many options for beginning levels that would have just confused a user.
  • The graphics and level design was really nice and well-executed.
Visual Scheduler
  • The handout was very clean and simple, though I think that they could have less text and more direct and "catchy" statements.
  • The website itself was also simple, which I liked. However, I did find the placeholders for "future universities" a little distracting, especially since they made it seem as though they hadn't really experimented with getting data from other universities yet. Maybe this is something they can leave out until they are actually going to implement this feature.
  • I liked the tabbed layout (I hate scrolling) and found the overall idea behind the site to be very useful and possibly something that UNM might want to capitalize on. Hopefully they can get the user account feature implemented since this seems like a really important aspect of the website since students will most likely be using this multiple times a semester and for multiple semesters.
  • The demo itself was a little short and they had to improvise the last few minutes. I can sympathize with this since I tend to talk way too fast during a presentation; but this is something that can be fixed with more practice.
G.E.R.A.
  • The handout was too dark, especially with the dark green text that was used, but I did like the targeted text (in white). I also noticed that there was no period after the "A" in "G.E.R.A" on the handout.
  • The website itself was very dark as well (which was unfortunate since I like the dark, dystopian feel it provided). However, for the sake of the user's eyesight, I think they will have to either make the text larger and/or change the color scheme somewhat.
  • I did like how they "game-ified" the app, though the exact details of the "missions" the users are supposed to do were a little too vague, particularly the "past data" they would be entering.
  • They did rely a little too much on notecards, which I can understand when you have to give facts and numbers, but hopefully some memorization will help this issue.
  • I think it might be good for them to implement the Facebook sharing feature they mentioned in order to encourage users to share their progress and accomplishments with their friends.

Monday, April 14, 2014

CSS and design

After the client meeting last week, Fernando and I wrote down the notes we took at the meeting and put them in a google doc. These notes essentially encompass the final design and functionality tweaks that need to be made in the next week or so. I've been trying to get as many done as I can (and adding any additional tasks as they crop up), particularly those related to design of the Challenges page (and My Challenges, which lists all challenges created by a user, and View All, which lists all the challenges for a particular category), the modals, and the current-challenge bar. I was able to get the design of the Challenges and My Challenges page mostly done. I also added some functionality to the View All page, allowing the user to take a challenge from this page.

The design of the modals was fairly straightforward. I'm getting more comfortable with CSS and have a better understanding of how it works. For instance, if you want to override the layout of a component (say a modal-header), then, in a CSS stylesheet, you can do

.modal-header{
//layout changes here


and redesign the color, layout, etc. of all the modal headers in the application. This is very handy for application wide-changes. If, however, you only want to affect particular modals (say, you want the header to have blue text for certain modals), then you could create another class by doing

.modal-blue-header{
color: blue;
}

and then append this class to the modal header class in the Haml view code:

.modal-header.modal-blue-header

This makes it very easy to only change specific components or maybe make small modifications to components while still keeping an overall general theme (such as keeping a button the same color but changing its size).

I've also discovered the wonderful world of link styling in CSS. Additions to a class, such as :hover, can help customize the appears of links and button clicks, which comes in very handy. However, trying to get CSS to format a webpage nicely for different size screens can be a real annoyance. Every-time I make modifications to a page's design, I use the Chrome Emulator to test the display of the screen on a phone or tablet screen resolution and then do my best to make modifications to the CSS using the "@media" tag to create different styles for smaller screens. Overall, trying to get the components to display nicely on a small screen is a real challenge and you can't always make the page look as nice as you'd want. There are also some cases, such as with the tables display for the challenges page, where responsive CSS has some sizes where the styling just doesn't seem to want to cooperate, no matter what changes I make. I plan to continue testing the app at various screen resolutions so that, in general, it will look decent on a wide variety of resolutions.

In closing, CSS can be great...when it is doing what you want. I think this mug sums it up for me:

Friday, April 11, 2014

Cookies!

This morning I was trying to get a simple task done--display a message to the user when they have completed a week of the challenge. However, it turned out to be a little more complicated than I thought due to the fact that I had to save the number of the last week displayed as well as boolean which would be true if the modal with the message had been displayed and false otherwise. In a regular application (using Java for example), you could save these values somewhat persistently as static variables (or serialize them for more permanent storage). However, since this is a web application, every time a page reload occurs, the variables in the Javascript code would get reinitialized and nothing would work. After some googling, I found that there was a handy jQuery Javascript file called jquery.cookie.js that could be be used to store variables persistently as cookies.  A value can be saved by calling

$.cookie("nameThisVariable", "some value");

and then could be accessed by calling

var thisVar = $.cookie("nameThisVariable");

This allowed me to store the two values I needed to ensure that the message was only displayed once a week was complete and would not be redisplayed when the user reloaded the page.

Another task I tackled this morning was figuring out how to tell the user (once they had completed a week) when they could start checking in again (since our website only allows so many check-ins per week and once you complete your check-ins for the week, you cannot check-in until next week). Getting the time itself was easy because this is stored in our Week model. However, it has been trickier to figure out how to format the time based on time zone. By default, the timestamp is returned from Rails as UTC, which is not very user friendly. I then used the "in_time_zone" Ruby function to convert UTC time to MST explicitly. However, if we have users on central time, pacific time, eastern time, etc., this will not work. I will have to look into using Devise to get the user's timezone when they sign up so that we can then tailor the time display to the user's current timezone.


Wednesday, April 9, 2014

Profile page design and meeting

I have been working on getting the statistics for the user's profile page redesigned to match the color scheme and design for the rest of the site. I added a progress bar to each statistic display which will (eventually) show exactly how many points the user has toward completing the next level of a given statistic. I also discovered that spans nested in divs can be very useful for arranging items horizontally, though you do have to do some tweaking of widths and heights to make sure they are all vertically aligned and nicely spaced horizontally.

I have also been testing the layout of the redesigned pages using the phone emulator in Google Chrome, which is extremely handy for testing. This revealed some issues with both the home page and profile page layout that I was able to fix. I've tried to make it a habit to run the emulator every time I make a change to the CSS just to make sure it still looks good on a small screen.

Fernando and I were able to find some appropriate icons to use for the levels. At the last team meeting we made some changes to the statistic names because Fernando discovered that Altruism only applied to one of the challenges that we had and Willpower applied to all of them. Thus we changed these to Dietetic/Diet and Dexterity since these are not too general and not too specific. However, at the client meeting today, Prof. Ackley pointed out that having Altruism might be seen as a good thing since eliminating it might cause some criticism that our focus is too narcissistic.

The client meeting itself helped solidify most of our tasks for the next two weeks. Most important, in my opinion, is design. Fernando has worked on putting in some icons to represent each statistic so once we get the progress bar for each statistic working, this page will mostly be complete design-wise. We will need to added some more logic to the progress bar, however, in order to give the user more feedback on their progress (like displaying a modal when they complete a week).

Additionally, the challenges page will need to designed this week as well since it is our other "main" page. Hopefully Fernando and I can get some help on this from Matt F. since otherwise it might be very difficult to get this done before next week, given that we have other coding and design to do for the rest of the site.

Tuesday, April 8, 2014

More design and demo

A few days ago, I created a new logo for the site. It was larger than our previous logo so I had to some CSS manipulation of the toolbar and the toolbar background to get it to look like I wanted. Since the logo was larger, I wanted to give the appearance that it was dropping below the edge of the navigation bar. However, this wasn't possible with just straight CSS since the size of the navbar would adjust to the size of the logo and it would not give the desired effect. Thus I ended up having to create a background image for the navbar in Photoshop. The upper half of this image was black (the color of the navbar background) while the lower part was transparent. I added this same background layout to the logo and then placed both the navbar background and logo in the navbar layout with CSS. This allowed me to create the effect of the logo dropping below the edge of the navbar. However, low part of the navbar background was showing up as white instead of transparent. After some quick Googling, I discovered that this was because I had to set the "background-color" attribute to "transparent" for the navbar CSS. This fixed the issue.

Fernando and I worked on some more of the design on Saturday for the profile page. We redesigned the color and some of the layout of the progress bar, making the color of the bar and surrounding div match the color scheme for the homepage. We also started looking for icons to use for the statistics display on the profile page. These still need to be redesigned, as does the challenges page. However, since the profile page is what the user will be looking at most often, we need to make sure that it looks good and works well.

On Sunday we had a meeting to work on the demo. Over the week, Fernando and I had put together some information to use on the slides (some of which we used). We were able to get the slides done and did some practice run-throughs. However, due to the time constraint, we couldn't really make it polished, and this was clearly an issue during the demo yesterday. I think that, for the final presentation, everyone needs to start putting ideas and slides together much earlier because it is completely unrealistic to try to do this the day before. Also, it just makes us look unprofessional. We also need to cut back drastically on the text (as pointed out in class) and put all the facts and extra information into "cheat sheets" that can be used as talking points.

Friday, April 4, 2014

Design and demo

I started working on a layout for the homepage of our website this week. I have only basic experience with CSS so this has been quite a learning curve. I was able to find some templates and website design examples that I liked and I then modified and added to these to get a layout that I liked. Once of the most difficult things for me is making sure that the CSS I use for one element doesn't mess up the design of another element. This can be done by specifying element IDs when creating a CSS style (so the style only applies to the element with that id). Alternately, you can specify a sequence of class names that uniquely identify a particular part of your website and then assign a style to that. This works well if you have a certain grouping of elements that you want to be styled the same throughout your website.

Another part to CSS that is also tricky is making sure that resizing the window does not mess up the layout of the website. This can be partially accomplished by using the CSS "@media" tag, which allows you to specify how a layout looks at certain dimension (for instance, if the size of your screen goes below a certain number of pixels, you can change how the elements on the page are arranged so that they do not overlap each other). There is also a phone emulator in Google Chrome (in the Developer Tools), which allows you to simulated various phone displays. This can also be quite helpful (if a little slow since it is an emulator).

Fernando and I will be working on the layout of the profile page this week since it is what the user will be looking at every time they log in. This will be a challenging task since it is very important to create a design that is not only pleasant to look at and is well laid-out, but is also functional and easy to use. The most important part of the page is probably the progress bar so we will need to make sure that it is fully functional and well designed. I have started to try out some CSS to make it match the color scheme of the home page, but so far I have not found a layout that I like. We will also have to revamp the statistic buttons, maybe creating an icon for each one and making them more prominent in the layout.

Since we have a demo on Monday, I've also been researching some facts that we can use to justify why we are creating this website and why it will be useful to customers. Fernando created a Google document that we can all access to put down ideas for each of the slides that we will have in the presentation. We also decided to have a video of our website in use instead of a live demo because the very nature of the challenges (having to check-in over a period of weeks), makes it impossible to demo in one or two minutes.

Wednesday, April 2, 2014

More progress bar issues + coding session.

The progress bar is really turning out to be quite time-consuming, as there always seems to be something that we need to add or change to get it doing what we want. It already has an absolutely insane amount of Javascript backing it, with multiple Ajax calls, to ensure that the progress bar is "smarter" than the user and doesn't allow them to check-in when they shouldn't, or skip check-ins without a penalty, etc.

As I had mentioned a few posts back, I was trying to get an undo function working for check-ins. I had been using paper_trail but was having to manually "roll-back" the check-in count for certain models because, for whatever reason, paper_trail was only rolling back three of the fields when I asked for the previous version of the model. During our coding session this past Sunday, I followed the directions on paper_trail's git page for explicitly telling the gem which model attributes it should roll back, hoping that I could force it to rollback the check-in count. Did it work? No!! So I decided to chuck the whole idea of using paper_trail because forcing the roll-back manually was causing serious inconsistencies that would later manifest themselves it weird bugs. For now, I think I'll try using a modal to ask the user to confirm that they want to check-in, which I thought would be a little simpler to implement...

But no! Here I thought showing a simple confirmation modal (I didn't want to use the default browser alert function) would be simple and it took me nearly two hours just to get it to cooperate. Creating and displaying the modal itself is simple (using the $('#modal-name').modal('show') and $('#modal-name').modal('hide') jQuery calls). However, it became quite complicated when I wanted to connect the modal's "Cancel" and "OK" buttons to jQuery click events. Some examples I found suggested using the <a> (href) tag (or "%a" in HAML) with the buttons. Bad idea. This prevented the "OK" click event from being registered properly when the modal was opened and the OK button was pressed. After nearly an hour of googling, I finally decided to remove the <a> tag and, lo and behold, the click event finally registered. After moving the Javascript code that updates the progress bar to a separate function and then calling that function from the OK click event, the confirmation dialog was finally working. I had to pull the code into another function because it appears that the Bootstrap modals do not block other events from occurring so the update code was being run as soon as the user clicked "Check-in" and the modal appeared. Maybe there is a way to force the modal to block all events until it is dismissed, but I haven't found it.

Sunday, March 30, 2014

Postgre SQL on a Mac

I'm a Mac user (I know, I know, I should be using Linux) and sometimes there are some differences when using Rails and Ruby. For instance, I was trying to get the Postgre SQL gem to install and it was telling me that it could find the appropriate header files:

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    /Users/username/.rvm/rubies/ruby-2.0.0-p353/bin/ruby extconf.rb 
checking for pg_config... no
No pg_config... trying anyway. If building fails, please try again with
 --with-pg-config=/path/to/pg_config
checking for libpq-fe.h... no
Can't find the 'libpq-fe.h header
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

I did some googling and found that Macports is a useful tool for getting these Postgre SQL headers installed. After installing it and running the commands found on this blog, the bundle install command worked!

Saturday, March 29, 2014

Paper_trail

As I mentioned in my last post, I was looking at using a gem called "paper_trail" to add a kind of "version control" to certain models in our Rails app. I was hoping to implement the undo function as part of a Rails flash message (so when the user clicked "Check-in", a flash message would appear at the top of the page saying that the progress was updated and asking the user if they wanted to undo the check-in if it was a mistake). However, since the progress-bar is in a partial and the update to the progress value is made through an ajax call, I could not get the flash message to return as part of the page's response headers (they got cleared out after the redirect_to call at the end of the method that updates the progress value). Based on the googling I did, I believe this is due to the fact that custom ajax calls do not explicitly retrieve flash message unless you tell them to, and the fact that the progress-bar was in a partial, which made it impossible to display the flash message in the view that was calling the partial. There may be some simple workaround for this issue, but so far, I have not found one.

Thus, I decided to try a different approach. I would use a button to perform the undo (which was probably better than the flash message method since I had to revert the versions of more than one model, which would have been difficult if I had just been using a link in the flash message, since the link would have accepted only one model as an argument). The button would only be display immediately after a checkin occurred and would only remain on the page for about 10 seconds before fading away (preventing the user for undoing an action at a much later point, which could have caused issues with the application). If the user clicked the undo button within that time, it would undo the check-in (reverting the progress and checkin counts) and update the display before fading away.

I had hoped that paper_trail would be able to perform the reverts without any extra updates on my part but, unfortunately, this was not the case. A typical call to revert to a pervious version for a given model (which is stored in a rails instance variable) looks like:

@instance_var.versions.last.reify
@instance_var.save

I had thought that this was working fine for the models that I was having to "undo", but it wasn't. For some reason, when I examined the server requests in the terminal, the paper_trail gem was only updating certain fields during the "rollback". For instance, in one model, it would revert to the previous progress value but not to the previous checkin count value. I am not sure why this is since all attributes of the model are accessible. The only reason I can think of for these issues is the fact that "has_many" and "belongs_to" relationships are not fully supported by paper_trail so I guess this may be influencing the way certain models are reverted based on whether or not they have these relationships. So, I had to do some manual updates to certain models after reverting, but this seemed to work. Now, when the user performs a check-in, they see the undo button as shown below (and the button will fade out after 10 seconds if the user does not click on it).


Friday, March 28, 2014

Client meeting and other things

We had another client meeting yesterday and I think that it went fairly well. We had a demo working so I think this helped a lot since it shows what we've accomplished as well as what we still have to work on. Prof. Ackley brought up some good points, which Fernando put down in a Google doc so we can reference them. One of the suggestions was to change the Success button to be called "Check-in" since this is the term we had been using everywhere else so it made more sense. Fernando and I will also need to add some sort of confirmation modal or popover to the Check-in button so that the user can confirm that they really want to check-in, which should help prevent accidental check-ins on the part of the user. Or, we could figure out a way to "undo" an accidental check-in (one way would be to use the Paper Trail plugin).

This weekend, we plan to have a group meeting to start working on and (hopefully) implementing so basic overall design concepts (color, layout, etc.) so we can have some these for the next client meeting. Have a website that looks appealing, is easy to use, and is fully functioning is going to be very important for the final demo. We have most of the functionality complete so design will be our main focus over the next several weeks.

Fernando and I were able to get the check-in timing/verification mostly complete. The code now allows the user to check-in at any time on the first day of the current week (which is especially important if the challenge has 7 check-ins since, otherwise, the user would not be able to complete all the checkins before the week is up). The code also allows, at most, one check-in per 24 hours since the maximum number of check-ins per week is 7 (which was a design decision on the part of our team). This new code is working with the code that we had added last week, which will have the user retake a week if they miss one or more check-ins for that week. This code was modified slightly to fix a bug that was creating the "redo" week with a start date equal to the end date of the previous week. This was a problem if the user missed some check-ins for a given week and then completely missed the next week. It was also a problem if they had to do 7 check-ins for the week because then they would be "cheated" out of time or else the redo week's start and end times would have already passed if they had missed an entire extra week. Thus, the redo week is now created with a start date equal to the current time to avoid these problems.

Monday, March 24, 2014

Coding session

On Saturday, Fernando and I met with Matt S. and had an impromptu coding session for about 6 hours. Fernando and I were able to get most of the logic for the progress bar complete. This included checking that the user is checking in only once per 24 hours and is completing the requisite number of check-ins per week. This task turned out to be (in my opinion) a little more difficult than expected because it required some logic that would keep track of check-ins on a per week basis. After some brainstorming, Fernando and I decided that this would be best accomplished by creating another model in the database called Week. The purpose of Week was to keep track of how many check-ins the user has done during a week (which is defined based on when the user first started the challenge; so, if the user started the challenge in a Wednesday, then one week is 7 days from the start date, or, in this example, the following Wednesday). Adding this model made it relatively easy to quickly determine if the user is staying on track or whether they are missing check-ins.

Also Fernando and I had put some thoughts and suggestions in a Google doc, which we showed to Matt S. during the coding session, so we could agree on a resolution to the issues. One of these issues was what to do if the user misses a check-in for a given week. We decided that we would not take points away from the user since we want to keep them encouraged. However, we felt that there should be some sort of repercussion, which, in this case, would be to "redo" the week. Since we had implemented the Week model, keeping track of the check-ins and any "redone" weeks was straightforward. However, it was a little trickier to modify the progress bar Javascript code to work with this new penalty system. Since the users' controller was responsible for determining when the user had missed one or more check-ins and then performing the penalty calculations, we had to add some additional Ajax calls to the Javascript code in order to obtain the updated progress and number of check-ins from the controller. Last week, I had added a simple text display below the progress bar, whose function was to simply display the number of check-ins the user had so far completed (out of the total number required for the challenge). This was helpful in debugging the issue that I had mentioned in my previous blog post regarding the display and storage of the progress value. It has also been helpful as we have been debugging the code for validating the check-ins.

So far, we have most of the code working for this check-in validation. We have had to use a compressed timescale for testing this code since obviously it is impractical to continually test these for the "normal" timescale of weeks or months. We have been using 10 seconds to represent a day and 70 seconds to represent a week. However, this compressed timescale also presents its own issues as you have to be very aware of exactly how much time has passed and know when you need to "check-in" in order to test certain features. Using 1 minute to represent a day and 7 minutes to represent a week is a little easier to use for testing, but can get very tedious when you are continually making small changes and then retesting. I have just started using 20 seconds for a day and 140 seconds for a week and this seems to be working fairly well.

While working on getting the new functionality for the progress bar implemented, I learned two things that I should remember for future coding and debugging. First, to print out the value of a variable in Rails, you type:

raise @<variable_name>.inspect

Otherwise you will get an error since it is trying to print out the object, not the object's value. Second, when updating the attributes of a model (which is represented in the current context by an instance variable), you must use either "update_attribute" or "update_attributes" (for updating more than one attribute). You cannot just assign a new value to the attribute by calling "@instance_var.attribute = "some value". I lost about 20 minutes trying to figure out why my code wasn't updating the database before Matt pointed this out. So to do an update of a model's attribute:

@instance_var.update_attribute(:field_name, @instance_var.field_name + <some modifications or updates here such as +, -, etc.>)

There are some more test cases to run through and a few code adjustments to be made, but, overall, the progress bar functionality is mostly complete.

Guest speaker

I found Jeff Van Dyke's talk today in class to be really informative. All semester we have been discussing principles and practices for how to "do" software engineering. Almost all approaches have their pros and cons but it was very interesting to see these principles and conventions put to use in a successful business. I was particularly interested in the use of "small" commits and in the use of the "fudge factor" to encourage developers to become more accurate in their work estimates.

First, regarding commits, I have found that small commits can be quite tricky to do and still maintain a code base that is completely functional and runnable. Depending on the task, it can be difficult to break it up into tasks that you can code in a relatively short period of time (say an hour or two) while still maintaining a fully functional code base. I understand the importance of being able to do small commits, especially, as Jeff mentioned, when you need to "roll-back" the code in order to determine when and where a particular bug or problem was introduced. However, I think it takes a lot of skill and practice to plan out your commits so that you do them frequently enough that they are small, but at the same time, they keep the code base buildable and runnable. I personally have been trying to force myself to do more frequent commits when I am working on a feature or bug, but sometimes I get so caught up in coding that I forget or else I can't seem to figure out a good way to break up the feature's parts so that I commit every few hours. It is definitely something I need to practice more.

Second, the idea of allowing developers to use a "fudge factor" during work estimates is an interesting concept. I was familiar with the practice of adding a certain amount of "padding" to a work estimate, as I have done that at my work as well. I am usually optimistic about how long something will take me so I force myself to add some extra time for the unforeseen problems that inevitably occur. I have been also trying to do this for the Demigod project as well, but this has been harder than I expected because I also have to keep in mind the fact that I am still not an expert in all the tools we have been using so I still have a little bit of a learning curve when trying to do new things with the code. However, using a fudge factor for my estimates would be a good way for me to determine if I am consistently over- or under-estimating how long it takes me to complete a certain task or feature. It would also force me to keep track of my past estimates so I can use those to determine how I am doing.

Wednesday, March 19, 2014

Migrations and more Ajax

I had a pair programming session with Fernando last night where we set up the functionality for storing whether a user challenge has been completed and then marking it as completed on the challenges page (by displaying a Bootstrap glyphicon checkmark next to the completed challenge). However, we still need to decide whether a user should be allowed to retake a challenge or whether it is a "one-time only" thing. I think it might be good to allow users to retake challenges since they may need to do it again to maintain a habit. We also brainstormed about how certain parts of the code should be handled (such as what should happen if the user misses a check-in), which will have to be brought up at our next team meeting so we can make these decisions as a group.

Prior to the coding session with Fernando, I had initially played around with using "rails g migration" to add the boolean "finished" column to the user challenges. This worked well (with code added to the migration file to make sure the default value for finished was "false"). There seems to be a basic convention for performing migrations of different types, which look like the following:

 rails g migration change_data_type_for_progress_in_user_challenge #This is what we used for the boolean.
 rails g migration add_<column_name_here>_to_<table_name>
 rails g migration change_data_type_for_<column_name>_in_<table_name>
 rails g migration remove_<column_name>_from_<table_name>

However, as I was testing this, I noticed an issue with the progress bar itself. For challenges where the duration (times per week * number of weeks) did not evenly divide into 100, the percentage amount for each check-in is (obviously) a decimal value . Since the progress was being stored in the database as an integer, decimal values were being rounded up before being sent to the controller via Ajax. While this will work for small durations or durations that divide evenly into 100, this approach is very, very bad if you want any kind of precision for the progress value. I had initially noticed the problem when I added some text under the progress bar that would tell the user how many check-ins they had completed out of the total number that they had to do. Because of the rounding errors, the check-ins were not adding up (e.g. it would take 15 check-ins to get to 100% instead of 16). Also the rounding errors themselves would compound as the number of check-ins increased.

Therefore, when I met with Fernando last night, we discussed this issue and decided that the best solution was to convert the progress columns in the database (in the histories and user_challenges tables) to decimal values, which can be done with migrations, in particular, the "change" migration, as shown in the migration examples above. We chose to use the "decimal" type instead of "float" because it is more precise and precision is what we need for the progress bar.

Then, after applying the changes to the database, we had to update the Javascript for the progress bar so that it would use and store the decimal value instead of rounding it off. But, when we went to test out the updated code, the decimal value produced by the progress calculations in the Javascript were not being properly saved to the database. Instead they were being truncated prior to saving (i.e. 6.75 would be saved as 6). We used the "raise" keyword in the users controller and "console.log" in the Javascript to try to debug the problem. The Javascript was storing and calculating the value correctly, but when we printed out the Ajax URL and parameters that were being sent to the users controller, we discovered that the progress parameter was being truncated. The URL would contain the correct progress value, but the params[...] array contained only the truncated value of the progress. Since the params[...] array is used to get the progress value and store it in the database, this was where the problem was occurring.

At first we thought that maybe the "." in the decimal value was some sort of reserved character in Ajax. However, this did not make sense because the URL contained a "." and it was parsed just fine (and why would URLs disallow "." since these are used all the time for sending image requests (image.jpg, etc.)). Then we thought that maybe there was some restriction on sending decimal values via Ajax. Again, this did not make sense because I had seen examples where values such as latitude and longitude were passed via Ajax and were not truncated. After nearly an hour of searching through forums, I found a post on stackoverflow.com where another person had had a similar issue. It turns out that this was due to problems with the parameter parsing done server side (not with Ajax). I could not find a way to change this for the Rails server, so I did some more googling and found out that sending the progress via JSON (instead of as a "script") would allow us to prevent Rails from truncating the parameters:

        $.ajax({
          dataType: 'JSON',
          async: false,
          url: "/create_history/" + currProgress,
          data: {"newProgress":currProgress}

        });

Then in the users controller, we can grab the decimal progress value by using params[:newProgress].

Once this problem was solved, we made an update to the Haml and Javascript that displayed the progress bar, adding a hidden congratulations modal that could be displayed using jQuery when the user completed a challenge. We also added a button to the modal that the user can click to take them to the challenges page to find another challenge.

Friday, March 14, 2014

Over spring break...

I felt that our client meeting today with Nikan went well. We were able to successfully demo what we had accomplished and we identified what we needed to get done for the next meeting. I think we have made a lot of progress since our previous client meeting where our demo didn't really work and a lot of the functionality was not complete. 

Over spring break, Fernando and I are going to add a boolean column to the user challenges table that will be true if the user has completed the challenge and false otherwise. Once the challenge completion reaches 100%, the boolean will be set, the user will see a modal dialog that displays a congratulations message, and the user will be given the option to take another challenge. We will also have to mark the challenge as "completed" in the challenges list.

Adding the column to the user challenges table should be as simple as doing

rails g migration AddFinishedToUserChallenge finished:boolean

and then running a "rake db:migrate". Then we just add some extra logic to the progress bar javascript that updates this boolean to true once the challenge has 100% completion. It will probably be a little more difficult to actually mark the challenge as completed and then display the completed challenges in a separate section (called "completed challenges" or something similar) on the challenges page. Obviously the modal that displays the information about the challenge when it is clicked should no longer have the "Take this challenge" button.

We will also have to add a little more logic to make sure that the user is checking in the given number of times per week. Right now, the code is just designed to make sure that the user cannot check-in again until 24 hours after their previous check-in. But, if the user is only supposed to be checking in 3 times per week, we will have to add some code that counts the number of check-ins in a week to make sure the user is staying on track (this information can later be used to send the user "reminder" email messages when they are getting close to missing a check-in). In this case, the first week will start when the user clicks "Take this challenge" (the starting date) and the first week will end seven days from this point. The second week will end 14 days from the starting date and so on. Implementing these checks will be tricky, but the user history table will provide us with timestamps for each check-in so we can use Ruby's handy time features such as 1.minute, 1.day, and 1.week to calculate how much time has elapsed since a given check-in.

Wednesday, March 12, 2014

Ajax and other things

After going through what felt like half of stackoverflow.com and several tutorials on using ajax with jQuery and Rails, I finally figured out how to use ajax to pass an updated instance variable from a controller method to jQuery code in a view. It is so simple I can't believe I didn't figure it out before, but most of the information I found had to do with requesting http, javascript, and json, which was not what I wanted.

Prior to figuring this out, I had been using a hack to get around the fact that the instance variables were only updating on page loads. This was causing issues with the progress bar display because the code could save the updated progress (via ajax) but not access it. Hence I was storing the updated value locally (using an attribute of the progress bar) so that the Success button could be clicked repeatedly and the progress bar would fill up to 100% (which is what we need to demo for the client meeting on Friday). This worked but it wasn't really the right way to it.

Now, using ajax, jQuery can send a GET request to a controller method where the instance variable will be updated from the database and passed back to the jQuery code. Of course, a route also has to be added to the routes.db table so that the url that is given in the ajax call is valid. In the controller method, after getting the desired data from the database, the following render call is made:


render text: @instance_variable

This sends the instance variable back to the calling ajax code where the ajax success property is given a function that gets the requested data and sets it into a jQuery variable:

success: function(data){
    $jquery_var = data;
}

Since the render function in the controller method is passing back text, the data will have to parsed to a float or integer if the value needs to be in a numerical format. However, with just a few lines of code, you can really quickly get updated instance variables from a controller to jQuery code without having to reload the page. This feature is also really helpful to Fernando and I since we will be using timestamps from past user checkins to determine if they are staying "on-track" and will have to get updated information in order to test our code.

As a final note, I had to set "async: false" in the ajax call because ajax (being normally asynchronous) will update the database in the background and the next ajax request in the code to get the updated value might not get the latest version of the value. Thus I set all the ajax calls to be synchronous so that this problem would not happen.


Monday, March 10, 2014

Group coding session + some issues

Since we had to get twice as much done before this upcoming client meeting (due to a miscalculation on our timeline), we decided to meet for an informal group coding session yesterday morning. We all coded pretty much straight from 8:30am to 2:30pm and were able to get the action items mostly completed for this week's client meeting. I think it was good that we all got together and coded up our parts because 1) some parts were dependent on others so you could test them out and get them working without having to wait too long and 2) it gave us all motivation to get as much done as we could. Fernando and I collaborated on updating the progress bar so that it would be able to access the user's current progress on the challenge that they are taking (as stored in the database). There is a table in the database where the user's current challenge is stored as well as table that stores a history of the current challenge. This means that every time the user presses the Success button (to check-in) in order increment their progress in the challenge, a new row is created in the History table with the updated progress value. This allows us to keep track of the user's past check-in times so that we can determine if the user is checking in when they are supposed to.

Currently, the code stores the progress when it is updated and displays the current progress. However, there is an issue with dynamically access the values after the user clicks the Success button once for a page load. After the user clicks Success, the updated progress will get stored in the database and the progress bar will update. However, after the first click, it appears that the instance variables stored in the controller do not get refreshed (since the page is not reloaded) and therefore any additional button clicks will not update the database. Thus, we need to figure out a way (probably using ajax in some form) to call a method in the controller that will reload the updated values from the database for the next click of the Success button.

Additionally, Fernando and I will need to implement code that checks if the user has been checking in regularly as well as checks that they do not check in more than once in a 24 hour period. This should be fairly straightforward since the database date stamps each history row so that you exactly when the user last checked in and can then determine in what time range their next check-in should occur so that they can stay on track.

Friday, March 7, 2014

For next week...

Based on the client meeting today, I think we need to have some good demos to show at the next meeting because I feel that we are falling behind in expectations. We also somehow added an extra week to our timeline, which means that we need to get twice as much done by next week in order to get back on track.

So for the next client meeting, Fernando and I are tasked with updating the progress bar based on information from the user's challenge history. I have a feeling this is going to be a bit tricky because it seems like, from the initial research I've been doing, that there is no consensus on the "best" way to do this. I did find this example which shows three different ways of passing data to Javascript: script tag, data attribute, or a gem called "gon". I am going to try experimenting with using the script tag and the data attribute and see if there is one that seems more appropriate for what we are doing. However, since we are not using CoffeeScript or ERB (embedded Ruby), we are going to have to do some modifications to most of the example code we find since a significant portion of it seems to involve either CoffeeScript or ERB. I also looked at using the gon gem, and it seems like a really simple and straightforward way to get Rails data into Javascript code.

We are also going to have to figure out how to update the user history once the user clicks Success. This is going to be tricky as well since, depending on the type of challenge, we will have to determine whether the user is allowed to update their progress (for instance, if they have to complete a task twice a week, we can't let them click "Success" twice in a row and call it good). Thus, when the Success button is clicked, the code will have to go check the database and determine if the user has already completed their check-in for the day. If they have, then we should put a message stating this. Otherwise, we should update the user's history and update the progress bar. Eventually, we should also probably include some text with the progress bar that reminds the user how many times per week they have to check in, how long the challenge is (duration) and how many times they have already checked in.