Wednesday, May 9, 2012

It's time to start on paperwork...


If you've been reading previous entries of this blog, you're probably wondering how I moved on to step 13 so quickly. No I didn't suddenly feel a mass of inspiration and crank out every remaining piece. And no, I didn't give up either. However, I need to submit my paperwork within the next 6 days or so and since there's a lot of writing to be done, I need to get started. I have completed the vast majority of my project (I'd say around 90%) and am still poised to finish laying out these last components and ironing out some bugs. 

However, I've been burning the candle at both ends and it's physically, mentally, and emotionally wearing me out. I've developed a twitch, it hurts to look at any light, I'm having regular anxiety attacks, and I haven't consistently showered or done anything but work and schoolwork for weeks. Besides, I've hit the cap of one of the common project constraints - time, and have to go live with what's working and just note what I didn't have time to fully implement. It will just have to be enough. 
  1. Write the Recipe Builder update logic
  2. Write the Recipe Builder delete logic
  3. Write the HTML builder for Recipes
  4. Write the database interaction methods for the Meal, Meal Plan, and Daily Plan classes
  5. Update the meal planner tab based on the successes and failures of number 4
  6. Write the GUI logic for the meal planner tab (all three interaction methods)
  7. Write randomizer logic for meal plans
  8. Design GUI for meal plan randomizer
  9. Design GUI for shopping lists
  10. Design logic for shopping lists
  11. Design printer control for shopping lists and meal plans
  12. Debug remaining errors on Recipe Builder
  13. Write Capstone Project Paperwork and submit it.
  14. CELEBRATE!!!!!!!! (when I pass, anyway)
Wow, apparently I'm too fried to even comprehend what I'm reading about my capstone deliverables. I guess tonight is going to be a time to try to relax enough that I can stop panicking and start working again later. I am taking Friday off to work on my project and paper, but Sunday is Mother's Day so the weekend is shot. Again, though, perhaps if I clear my mind for the rest of the day I'll be able to come back and really push through the report-writing phase tomorrow, Friday, and Saturday. 

Tuesday, May 8, 2012

Meal Randomizer

Now that I've laid the groundwork for Chef Helper and a user can view formatted recipes, build recipes using customizable components, and create full meal plans, it's on to the little tidbit of functionality that prompted this venture from the beginning. Of course I'm referring to the meal randomizer. Though I've built menu plans to hold up to 6 recipes, for appetizer, main course, two sides, dessert, and a beverage, the randomizer is going to start by being focused on main dishes. For one thing, I'm not quite sure how to have it pick complimentary foods to put together and for another, who has time to regularly cook a main dish, two sides, an appetizer, a dessert, and a custom beverage? Exactly.

I've been giving a lot of thought to how best to accomplish this. Iterating through recipe lists should be fairly simple and straightforward. If I shoot for a simple randomizer to start (I can always add complex logic later that looks at spreading out costs, ethnicities, primary foods, etc), I should be able to get this part done fairly quickly. I'm thinking I'll have the user create the meal plan framework which will create all the daily plans and meals to work with and then just iterate through these lists, filling in the blanks.

Remember when I said quickly fairly quickly? It should come as no surprise that I was wrong. To start with, some of yesterday's work didn't get saved (or I totally overlooked something) so I spent most of my time this evening tracking down those bugs and using a different algorithm for creating daily plans from the meal planner.

I'm now running into another problem with the randomizer. I've got it set to search through the master recipe list for recipes with a meal part of main dish. I can't get the equivalency to work! No matter how I do the search, I can't seem to figure out how to find these matches. I think part of this might also be related to my Recipe Builder snafu where I can't get meal part, ethnicities, food types, and commitments to update or store correctly.  So I went back to try to locate these failures. Ironically, they seem to be the same type of errors I'm hitting with the randomizer.

I think part of the problem is the difference between what's in the database and what's loaded in the master lists. I update those damned master lists after almost every transaction, but it still seems like I can't get them to match up. I'm wondering if I'm going to have to recode chunks of the writers and loaders to solve this problem. I sure hope not, but this program has reached a level of complexity where I've lost track of what it's doing.

In fact, despite the looming deadline, I'm thinking I will finish tonight's work with some code cleanup and go through each class and add the comments describing each step. Maybe that will help me wrap my mind around how I decided to code each phase. I'll just have to work on the functional coding again tomorrow when I've taken some time to refamiliarize myself with my design. Sometimes it stinks to have a memory as bad as mine!

Monday, May 7, 2012

Another day, another migraine

First off, I'd like to admit that I probably don't have a migraine. I do, however, have a headache that's been going on for at least a week and yesterday my eye started twitching. I've heard that stress can cause that, so figure at least I have a reason for feeling this lousy.

That being said, I am again hard at work on Chef Helper. I don't really know what I meant when I scheduled task number 5, so we'll just call it done in light of me getting closer to completion of the meal planning section. I've now got my UI to drill down to the level of Meals and Recipes and have realized I'll need to update the deletion scripts on the Meal Planner and Daily Planner as such:

  • If a meal plan is deleted, so is every daily plan associated with it and every meal associate with each of those.
  • If a daily plan is deleted, so is every meal associated with it.
  • If a meal is deleted, who cares. 
After an hour or so of work, I've got the code ready to accomplish each of these tasks. I've tested it a bit and it seems to work, but further testing/debugging will be needed down the line.

So I moved on to implementing the meal planner tab button logic. I've managed to come up with code to successfully save a recipe to the breakfast appetizer slot and update the tab. I've also managed to come up with code to successfully clear a recipe from the breakfast appetizer slot but I cannot seem to get the tab to update and I've tried a number of algorithms. For the time being, I'm just going to offload that work to another method and get all the other buttons working. Then I'll toy with that method and see if I can't get everything to refresh properly. What do you know, I found a workaround that works just as well without the overhead. I just set the associations on each daily plan as I updated it rather than trying to rebuild all the master lists from the database. 

And with that little bit of success, which has been copied to the other 34 buttons on the meal planner (yeah, that was a lot of copy/paste/update/pray there), I have completed the meal planner. Tomorrow work will begin on the randomizer logic and GUI. Hopefully that won't take more than a couple of days, and I'm taking Friday off to work on this thing. As you can see, that's followed by creating shopping lists which is followed by printing. Then the last step of the coding phase is to debug those pesky little errors on the recipe builder and Chef Helper will be done at last!



  1. Write the Recipe Builder update logic
  2. Write the Recipe Builder delete logic
  3. Write the HTML builder for Recipes
  4. Write the database interaction methods for the Meal, Meal Plan, and Daily Plan classes
  5. Update the meal planner tab based on the successes and failures of number 4
  6. Write the GUI logic for the meal planner tab (all three interaction methods)
  7. Write randomizer logic for meal plans
  8. Design GUI for meal plan randomizer
  9. Design GUI for shopping lists
  10. Design logic for shopping lists
  11. Design printer control for shopping lists and meal plans
  12. Debug remaining errors on Recipe Builder
  13. Write Capstone Project Paperwork and submit it.
  14. CELEBRATE!!!!!!!! (when I pass, anyway)

Sunday, May 6, 2012

Onward we stumble...

It's another Saturday closer to my deadline so instead of getting much-needed rest, I'm up with less than enough sleep and already cracking the whip. Okay, so technically it was work that called me with an over-the-phone fix-it request. But since I'm up and really want to finish this, I'm working already.

It looks like today's task is to get the meal plan section going. My hope is that with my pre-designed GUI skeleton and the practice I've gotten working with the myriad of Recipe classes that this section will go quickly and smoothly. I guess it's time to find out!

Okay, first point. I've already mentioned that I wish I had written interfaces and coded to the interfaces so I would always remember the methods I need. I'm hitting that again with the meal plans as I now have to look at my recipe classes to try to remember what methods I need. Another point that I may have mentioned before is that it's handy to have code to determine a new object's database ID. My original plan was to do so but I had changed it (by accident - I forgot!) to just write to the database and then search for the new object to get its ID. Yeah, it's way easier to determine what that ID should be ahead of time. I'm definitely using this approach for all the meal planner classes.

Oy, another bit of a snag! I wrote most of the important methods for the Meal class and am working on the ones for the Daily Plans and then Meal Plans, but guess what I need for testing and don't have... that's right, recipes. And as you'll note in a previous post, I have some bugs to track down in the recipe builder. That and I wrote the SQL scripts to do a cleanup of the database and it takes a ton of SQL coding to build a single recipe. Perhaps I overreacted. I can just make a bunch of BS ones by taking my eggplant recipe and adding digits to it. Yeah, that will work for testing.

It's taken a number of hours today, but I have entered all the database interactions and whatnot for the meals, daily plans, and meal plans. I haven't been able to test them because I need some fodder for testing and am thinking it will be easier to create fodder if I implement the rest of the GUI first. Probably not my best plan, but I really want to be done with this project.

Aside from being uncertain if my various methods will work, I've discovered two potentially life-shattering issues. First off, when coding for the daily plans and meal plans, I'm afraid I may have hit a circular bit of logic. The meal plans contain a list of the daily plans involved and the daily plans contain the meal plan they belong to. I'm not sure if this is going to turn into a cluster when I try to update one master list and it requires entries from the other master list. Perhaps I'm being paranoid about it and it will work after all, so I'm still hoping. If not, throw another problem on the debug file!

The other concern I have involves dates. I think I've zeroed in on working code to pull them from the database and put them back into the database. However, I didn't think about how the use was going to put them into the form for the database. Trying to parse user input for dates doesn't seem like a particularly winning idea. I guess I was just imagining a date picker GUI piece and didn't realize Java doesn't have one natively. I'm going to search around and see if anyone has an implementation they're willing to share...

So a search for pre-built date modules came up with some solutions, but I really don't know how to import the libraries and then use them. I think my knowledge of Java Swing is still too rudimentary to be able to plug in custom components outside of the NetBeans IDE. It's a shame but perhaps it should be a version 2.0 issue and I should go with a rudimentary date entry field. Yeah, I think I'll do that and see what happens.

  1. Write the Recipe Builder update logic
  2. Write the Recipe Builder delete logic
  3. Write the HTML builder for Recipes
  4. Write the database interaction methods for the Meal, Meal Plan, and Daily Plan classes
  5. Update the meal planner tab based on the successes and failures of number 4
  6. Write the GUI logic for the meal planner tab (all three interaction methods)
  7. Write randomizer logic for meal plans
  8. Design GUI for meal plan randomizer
  9. Design GUI for shopping lists
  10. Design logic for shopping lists
  11. Design printer control for shopping lists and meal plans
  12. Write Capstone Project Paperwork and submit it.
  13. CELEBRATE!!!!!!!! (when I pass, anyway)

Thursday, May 3, 2012

Worn out - making little progress

The time crunch draws ever nearer, and with having to renew my driver's license this morning, being very busy at work, not getting enough sleep, a 3-day headache that just started laying off this evening, and being tense and stressed all the time, I'm not doing so hot. I am absolutely exhausted and demoralized, with emphasis on the exhausted. I can't concentrate, I have no motivation, all I really want to do all day long is curl up in bed and sleep.

Needless to say (but I will anyway), I'm not getting much work done on ChefHelper at the moment. Thanks to Lyndsie's support (and prodding - thanks love!) I am still trying to get stuff done, and as you can see have made slow but measurable progress despite my hardships.

If you look at my list of remaining tasks, you'll see that I'm on number 3 - Write the HTML builder for Recipes. I'm well into the coding for this section but unfortunately discovered some pretty serious bugs in the process. I'm attempting to push through the HTML and check it off the list, but I'm going to have to note these bugs on the Recipe Builder to track down later:

  • Builder doesn't load commitment. If you save without setting it, it reverts to null
  • Builder doesn't properly save the food type. It saves as a blank every time and overwrites whatever's been previously stored
  • Builder can't load or save meal parts :(
  • Additionally, I overlooked the note builder for recipes. It's probably best left until version 2 since it's not vital at this stage.
I have built what appears to be a working class for converting Recipes to html. It's not half as pretty as I had wanted but aesthetics will also have to wait until version 2 because it appears that though a JTextPane will accept an html-tagged String, it only recognizes very basic html and style choices. I'm sure there's a way to do it better but I don't have time right now. 


  1. Write the Recipe Builder update logic
  2. Write the Recipe Builder delete logic
  3. Write the HTML builder for Recipes
  4. Write the database interaction methods for the Meal, Meal Plan, and Daily Plan classes
  5. Update the meal planner tab based on the successes and failures of number 4
  6. Write the GUI logic for the meal planner tab (all three interaction methods)
  7. Write randomizer logic for meal plans
  8. Design GUI for meal plan randomizer
  9. Design GUI for shopping lists
  10. Design logic for shopping lists
  11. Design printer control for shopping lists and meal plans
  12. Write Capstone Project Paperwork and submit it.
  13. CELEBRATE!!!!!!!! (when I pass, anyway)
Since as I mentioned, I already feel like crap, I'm going to count the HTML builder as a 'win' and call it a night. Tomorrow I'll start on the database portion of the meal planner and will hopefully get most if not all of the meal plan working this weekend. I may also consider starting number 12 before then. The program is running at about 66% of capacity and that should give me plenty to write about. We'll see.

Wednesday, May 2, 2012

Got a couple out of the way but wasted too much time!

I only scheduled a couple of hours to work this evening. Though I squandered a lot of that time chasing functionality I could do without, I did accomplish goals:

  1. Write the Recipe Builder update logic
  2. Write the Recipe Builder delete logic
  3. Write the HTML builder for Recipes
  4. Write the database interaction methods for the Meal, Meal Plan, and Daily Plan classes
  5. Update the meal planner tab based on the successes and failures of number 4
  6. Write the GUI logic for the meal planner tab (all three interaction methods)
  7. Write randomizer logic for meal plans
  8. Design GUI for meal plan randomizer
  9. Design GUI for shopping lists
  10. Design logic for shopping lists
  11. Design printer control for shopping lists and meal plans
  12. Write Capstone Project Paperwork and submit it.
  13. CELEBRATE!!!!!!!! (when I pass, anyway)
I'd like to note very briefly where I went wrong today. I set up two save buttons, one to update the recipe and one to save the information in a second recipe. I envisioned the second recipe saving all the recipe details as well as all of the associated instructions and ingredients. 

Yeah, that functionality eludes me despite having blown a solid hour on it this evening. It's really not that important anyway. If I just change that second save option to save basics in a new recipe, it will work just fine. I would have liked the functionality to copy the ingredient and instruction lists but found there to be too many variables to pull off in my limited time. 

I have commented out all my new algorithms and that functionality has officially been moved to the version 2.0 list. Tomorrow I'll start on item 3 above and see if I can't get this sucker done! And thus concludes our broadcast day.

Monday, April 30, 2012

Over-optimistic but still going

Hello again, anyone willing to read this blog. As the title of this post suggests, I may have been a bit overly optimistic recently. Namely, I thought there was at least a passing chance that I could have my project at a sufficiently complete state by the end of today. Though I have been moving along quickly, I'm not quite that far along.

Thankfully, Lyndsie convinced me last week to take today off of work. I got to sleep in a smidge and have been working on my project all day long. I couldn't say how many hours I've put in today, but probably at least 8 hours of the day. I've been debating how many hours total this project has taken, and I kind of wish that I had been keeping track. My timelines have all focused around deadline dates rather than time worked (with my lack of experience, I had no way of forecasting how much time would be required for each step) so I didn't really think about it. I surmised 150 hours so far, but Lyndsie suggests significantly more. I can't even express how much I'm looking forward to finishing this baby and getting back to my everyday life!

Today's work has focused primarily on building the Recipe Builder in the GUI. In addition to laying out the elements of the main builder tab, I've almost finished the functionality. Perhaps more importantly, I've finished work on 4 pop-up windows for editing validations, instructions, foods, and ingredients. That's no small feat considering the interconnections of all the different components.

What's really interesting about working on these user interfaces is the number of features I've discovered I had planned that were real nice-to-haves but not need-to-haves. There's a lot of functionality that I thought would be in the prototype that I've had to cut for the sake of time and scope control, but the project is coming together. Most of these things I've cut have been aesthetic matters like logically sorting the validations instead of alphabetizing them and presetting sizes on the windows. As I've been advised, these things can all wait for version 2.0.

I'm just about out of time to work on this today and really just have one goal - finishing the Recipe Builder window, which at this point is mostly a matter of deciding the logic necessary to save new recipes or update current recipes.

I would like to note something that this experience is teaching me - the value of programming to an interface! Most of my classes have a method to write to the database. They also share a number of other methods involving lists and refreshing data. Though I have named all of these methods the same and have copied code between them (oh, by-the-way, really important to make sure everything's been renamed. Spent a log of debugging time finding mistakes), I find that I forgot to do a couple in my earlier work. For example, I apparently never got around to coding the Recipe class to write to the database. How silly is that? I've got my form ready to save this sucker and have to go back and write the database writer!

Short story long - if I'd written the Interface earlier (which I considered) I would have not been allowed to leave out these methods and would have remembered them earlier. Yet another live and learn experience.

Here's the final news of the night - I just finished the rather lengthy code to save a recipe to the database and guess what - now my program won't run. Apparently it can no longer find the Recipe class, which is really preposterous! Through process of elimination (and logic) I can determine conclusively that there's a problem in the new database writer method. And voila, a few minutes of searching and it's taken care of (ironically, I didn't really change anything in the end but went back to how it was when I started).

And that's all the work I am going to do on this sucker today. My remaining tasks include:

  1. Write the Recipe Builder update logic
  2. Write the Recipe Builder delete logic
  3. Write the HTML builder for Recipes
  4. Write the database interaction methods for the Meal, Meal Plan, and Daily Plan classes
  5. Update the meal planner tab based on the successes and failures of number 4
  6. Write the GUI logic for the meal planner tab (all three interaction methods)
  7. Write randomizer logic for meal plans
  8. Design GUI for meal plan randomizer
  9. Design GUI for shopping lists
  10. Design logic for shopping lists
  11. Design printer control for shopping lists and meal plans
  12. Write Capstone Project Paperwork and submit it.
  13. CELEBRATE!!!!!!!! (when I pass, anyway)

Sunday, April 29, 2012

Back on Track

As I had hoped, my brother-in-law helped set me back on the right track. As I mentioned, he is a skilled developer and really helped me get out of my myopic view that was sending me into a spiral of failure. I think I shall refer to this spiral as Uzumaki (Japanese for spiral, but it sounds cooler). We toyed around with a couple of things and refreshed my memory about how to build a GUI in NetBeans. I've now got a working version of the recipe listing tab where I just need to build the HTML for the recipe output and that tab will be finished.

Moving on, I'm grabbing my notes on the recipe builder page (thank heavens I drew something up a while back) and am building it this morning. I was able to copy the selection triggers and code from the recipe display page to easily create the recipe selection code on the builder page. I've created all the recipe properties and written the code to populate the recipe properties and instructions and ingredient lists whenever a recipe name is selected. I've even finished a button to clear the recipe builder in preparation for storing a new recipe.

Next on the agenda is figuring out how to create JDialogs in NetBeans so I can have popups to add elements to each validated list...

Check that one off the list, too! I am cruising along today, kicking butt and taking names. At this point, it may even be possible to have a working prototype by the end of tomorrow - so I can get to work on the documentation in time for my deadline. This is getting exciting!

I've been putting off writing the full set of logic for deletion requests but to finish the validation editor, think I may need to revisit this. I've got the basics in place for an object to delete its related entry from the database, but now I need to start thinking about foreign key constraints. For example, if a user wants to delete a cooking method, say 'Bake', what will happen to those recipes that already use this method? I think I configured the foreign key constraints to simply set the related values to null (of course, did I configure the object builders to handle nulls?) but am not sure if it will work. The logic I may need to implement is to have the GUI search through the Recipes list for instances of 'Bake' and deny the request to delete it if any are found. That would control the situation without needing to handle the null values, but could get annoying. Then again, unless you recently added one by mistake, why would you delete a method? Especially if you've used it before?

This same set of questions will come up for the other two validations I'm allowing the user to modify as well - ethnicities and food types.

I think this might be a good time to overwrite the equals() methods in my objects. Otherwise, how will I determine if the object chosen for deletion exists in other recipes. If I've coded this program right, the same object should be used in all places, but I have no way of knowing for certain. Should I take the risk?

It is really easy to determine equality for validation package objects because they just have one attribute to compare. So I went ahead and overwrote the equals method on the Ethnicity class and the Method class and was able to successfully set up Add and Delete buttons for them. I still need to do the same for Food Types, but it's late and I need another break. I'll either come back to this tonight or tomorrow morning.

Until next time, be well!

Saturday, April 28, 2012

Work on the GUI begins!

Lately I find that every time I think about working on my project, I get seriously depressed. That's not very conducive to success, but I feel so overwhelmed at this point with my deadline being so close and so many features of my program not implemented. Again I have very little experience programming a Java GUI (Graphical User Interface) and none of that experience is from WGU. All of my GUI-building was done when I was a student at the University of Utah. I really wish I had been able to stay there for my degree. The coursework may not have been as applicable as what I've learned (a lot more theory, math, and obscure things that won't mean much compared to the broad, applicable work I've done in my current studies) but at least it would have been more structured and would have involved a ton more hands-on work (of which WGU is pitifully lacking). That being said, I've made my bed and now have to sleep in it, despite the scratchiness of the fabric.

So again I start as a total novice and have to work out how to design and implement a fully-functional, complex GUI without much knowledge about how that's accomplished. Oh, and I have less than 2 weeks to learn and create it. I can see why I'm so stressed and depressed.

But enough complaining for now, if I don't start I'm guaranteed never to finish. So here goes...

First off, I sketched out a GUI in NetBeans a couple of months ago, to help wrap my mind around how I wanted everything structured. At the time, I envisioned a tree-like structure to list the available recipes, grouped by whichever field I felt was appropriate (I was thinking of meal parts or main ingredients, or categories, or... other things...). So I built in a couple of JTrees 'cause they looked very polished and appropriate. Now that I'm actually starting to code things, I've learned that a JTree is considered one of the hardest Swing elements to work with. I tried to go ahead with it anyway and it only took about half an hour today before I realized it was a dead end.

I think this is another example of controlling scope. I originally envisioned this type of interface, but the primary scope of my project is a working skeleton, not a polished, distributable piece of software. I am going to have to yet again make a command decision - with the resources available (limited time), I cannot complete this level of structure. It can always be added in later, should I decide to continue it. Throwing out the JTree in lieu of an alphabetized list of Recipes (or Meal Plans on the other tab) should work faster and get things running.

Another design change is the recipe builder. The meal planner builder fits just great inside the meal planning tab but the recipe builder requires significantly more space and variability. I was originally going to have a pop-up window but I have no idea how to tie windows together, or really how to create sub-windows and things. Luckily, I've already built the design based on Tabbed Windows so I'm just going to create a new tab for the recipe builder.

Two more hours of work into the GUI and I'm even more lost than when I started. I guess it's time to solicit some help. We're off to Springville to get a bit of advice/assistance from my super-intelligent brother-in-law. Here's hoping!

Thursday, April 26, 2012

Creating deletion logic - for reals this time

As you may have noticed in my last post, I had plans to complete the deletion logic yesterday. Though I did manage to do some research on the various auto-options, I didn't actually get any code written. Today I'm going to work on the coding.

To start, I have decided to change my foreign key constraints on all of my tables to cascade updates and set to null on deletions. Though this may obscure bug-searching later, I think it will be easier to handle null values than to handle SQL exceptions. Time will tell, of course. And this will probably necessitate some form of orphan searching in the future to clean up any data that becomes unreachable. I'm willing to take that risk to get this project finished in my required time frame.

Less than 30 minutes into coding the deletions, I ran into a bit of an oversight. I didn't really think out in advance how to determine equality. It seemed so simple and straightforward at the beginning that I forgot I need to create the equals() and hashCode() methods. Now I've gone to the work of having each method check one or more attributes of an object for equality when I could really have just coded these two methods in each class and others could just call on them. I don't really have time to seek out these codes I've made so will just have to live with the ungraceful and difficult-to-maintain way I've set it up. Perhaps a future release will improve upon this.

Forgetting these methods and having forgotten all the ins and outs of comparators, I'm going to have to have a very unpolished finished product in order to come in on time. I'm going to avoid the extra scope of making everything sortable for now and just get the down and dirty working. Sorting can be added in a future release as well.

You know what the saddest part of all this is? I probably could have cut out hours and hours of coding if I'd remembered my original plan of using database hits for a lot of these actions instead of trying to code and encapsulate them in Java objects. I created unique IDs for all of my tables so I would just need the ID (the primary key) to reference them from other tables, and then here I go trying to compare whole objects. Blech! What was I thinking?

Live and learn, I guess, which is really what I'm here to do. One thing I'm learning fast is that this stuff gets complicated rather quickly. Experience should help improve my ability to simplify things but I don't think I'm going to go into much coding professionally. It just gives me a headache to design at this level and I like to be a diverse IT person rather than specialized.

I am also noticing certain lack of consistency to my naming schemes that's starting to annoy me. For example, in Java, I've coded some of the IDs in caps and some in lowercase. It didn't seem like a big deal at the time, but now I'm really glad NetBeans gives me pop-ups so I can reference the right spellings. I'm also starting to see the value of programming to an interface - since many of my tables interact in the same way, it would really have helped to enforce consistency and remind me of my original design so I didn't get sidetracked on some of my methods.

All that being said, I've thrown together some usable (if not particularly smart or elegant) deletion methods and am now considering the main work of the recipes in the logic layer to be complete, at least as semi-functional skeletons.

I should probably start working on the meal plan portion and create all the same functionality, but like I said, I'm getting quite the headache with my failure to be consistent and don't really want to extend that. Also, I need to start creating a user interface so I can start work on my documentation. After all, my end-point for this project is not a fantastic, beautiful, professional piece so much as a skeleton that can be grown into a professional piece. At least that's how I'm viewing it.

When I say I'm going to start working on the User Interface, I totally mean that tomorrow I'm going to start working on it. I am totally fried tonight and don't expect to have much success by pushing forward in this state.

Wednesday, April 25, 2012

Vacation's over, back to work

We flew into Salt Lake last night at around midnight and slept until about noon today.  I'm still WAY tired, but there's still a lot of work to do, both for the home and for Chef Helper, so I guess I'll rest when I'm dead.  So here we go...

One thing I've been having a really hard time with on this project is avoiding scope creep.  Well, more scope change with a little creep mixed in.  As I've coded some of these connections, I've realized that they would work better re-factored a bit.  For example, I created the food types class to group food by its general type (i.e. dairy, meats, vegetables, etc) with the thought that I can group the shopping lists based on these types.  The way I've explained it to people, this is to make shopping easier, going from section to section.  But as I've built the relationships, I've realized that it's not as good of a grouping as I'd originally thought.  A better grouping would be specifically based on shopping area.  Let me explain - one of the food types is 'vegetables'.  It's a good type, trying to keep them all together, but the more I think about it, the more I realize there are actually three or four places in a supermarket where you'll find vegetables: fresh, frozen, canned, and perhaps even dried.  I have this insane urge to re-factor my system to take this into account, but I don't have the time to do so.  Instead I have to make do and hope that making-do doesn't suck up more time than re-factoring would.

That being said, the recipe classes in the logic layer are almost complete.  I have ways to add to the various parts, update them, and list/iterate through them for manipulation.  I've written the classes so that each component handles its own and only its own updates.  I'm thinking of this as a bottom-up model because you start with the smaller components and build them up into the overall components.  Again I have this scope-creep option nagging at me to allow top-down transactions, so you can make changes at the recipe level and it will pass the work down to the smaller components.  Again I don't have time to build this level of logic into the system and have to just ignore the urge to creep.

All this leads me to my current predicament - now that I have add, modify, and iterate/list capacities, I need to add delete capacities to each class.  That's what is on the docket for today and I'm hoping to finish it.  My major concern going into this is how to handle foreign key constraint issues.  I'm debating between having each class check the master lists before allowing a deletion and strictly denying such a delete or providing a cascade delete option to wipe out all dependent objects as well.  I know SQL databases have ONUPDATE and ONDELETE capacities, but I'm really not familiar enough with them to trust that they'll behave as I expect.

Okay, so I didn't get to work on this yesterday and totally forgot to post it, so even though this post says today, it was really yesterday. Yup, you heard it here, folks, this was yesterday. And don't let anyone tell you different.

Wednesday, April 18, 2012

Snippets here, tidbits there...

It's day three of the Chameleon Conference and I am ready for my real vacation.  The classes have been good and I've picked up a lot of good ideas, but I'm getting more tired every day.  Considering how jet-lagged I was to start, this decline is particularly sad.

Parts of these courses are bits I'm already familiar with so I'm trying to remote in and add work whenever I can, but there really isn't much time.  I have managed to create the database writer for another class but am probably not going to get much more done today.

But hey, I'm practically on vacation - a much-needed and well-deserved vacation (if you ask me, anyway) so I'll try not to worry too much until I get back next week.

Sunday, April 15, 2012

Last day to work before Florida

As the title of this post suggests, this is my last day of homework before leaving for Florida. It's really just a partial day since I have plants needing to go into the ground and final preparations to make before morning.

I sat down expecting to jump right in to attempting to fix my method of writing notes to the database. It turns out I just had to change one thing and suddenly it all worked. I had no idea I was so close when I stopped the other day!

With that fabulous realization, I'm saving my tester code so I remember how to use it properly (so I don't have to go through that mess again) and am moving on to other database-writer methods.

Wednesday, April 11, 2012

Database Modification Logic

Onward and upward, I dare say.

With my Florida trip less than 4 days away, I'm really pushing to get as much of ChefHelper completed as possible. So I'm working on writing methods for each class to write to the database.

Here is one thing that should really help this process - I don't intend on making the validation lists updateable through the GUI. So I don't need to write methods for these. I don't have time to work in ways to control their update so I just won't allow updates. This only applies to the commitment, meal part, fraction, and measure validations, since foodstuffs, food types, ethnicities, and methods need to be extensible. I guess I'm really half and half.

I'm starting on Notes because they only have a single foreign key constraint. Then I'll branch out to some of the other areas. Well, that wasn't as good an idea as I'd originally thought. You see, the Notes table is one of the few where I've included dates. Working with dates in Java is a lot more complicated than you'd expect. So instead of blasting through Notes and moving on to my next Database-writing victim, I had to take a refresher course on dealing with dates and work out how to handle null dates (just in case).

I was hoping to use a standard writeToDB() method for all of my classes, which would determine if an INSERT or an UPDATE was warranted and just do so. I started to get confused while building two simultaneous similar (yet different) SQL strings to use, so kept the same method and separated the implementation into two private methods. I think this will help keep things clearer, though it does add one more area to check if I need to debug the writing process. I'll have to test this pretty thoroughly before giving it the all-clear.

Yup, the date stumped me for tonight. I can't seem to figure out out to convert a java.sql.date to a java.Calendar.date and it's already half past midnight. It's a good thing I'm going into work late tomorrow! I'll be back to sort this date crap out Friday night or Saturday. Oy!

Tuesday, April 10, 2012

It's alive- IT'S ALIVE!!

Okay, so the title of this post might be a bit of an overstatement. ChefHelper is not really alive, so much as starting to form up from the primordial ooze and take its first breath of very real air. After yesterday's full-on programming sessions and some work this evening, I have successfully created and tested all the methods needed to:

  1. Retrieve all the recipe information in my database
  2. Convert that data into recipes and all their parts, every load, from scratch to objects to listings
  3. Easily access master lists of each component
  4. Print a text version of the eggplant recipe (and any other recipe I add with few null values) 
I am very excited to have gotten to this point, but there's still a long way to go. It took a long time to properly figure out how to load everything and in which order (dependencies can throw you for quite a loop!).  Oh look at that, I was just reviewing my EER diagram (I found out that that stands for Extended Entity Relationship - who knew?) and forgot to add the Notes list to the recipe class. I'll get right on that...

Now that I've created this template for 11 classes, Notes were not a challenge. Okay, so there were a few hold-ups, but not bad overall.

I'm pretty much done for the evening - I'm out of time and need to de-stress a little before going to bed, but I'd like to lay out what's next in this process.

Like I said, I now have all the methods and members in place to store all the lists in the Java portion. This sets me up rather well for adding the methods that INSERT, UPDATE, and DELETE from the database. I may have mentioned earlier that I've encapsulated this functionality in my Database class, so other classes just need to have ways to build SQL DML Strings to pass to this class. 

I'm planning on having each object know how to write itself to the database. Then the GUI only has to provide ways to select the object and tell it to do its job. The GUI will probably just create a blank member of each class to work with and then verify all requirements are met before being allowed to save it. I've got a bunch of ideas of how to accomplish this but we'll see what happens when I get that far. 

After completing and testing this functionality, I only have two major program pieces to build: the meal planning classes and objects (which should be easier now) and the GUI. Put it all together and I'll hopefully have everything running (cross your fingers, pray for me, wish upon eyelashes, stars, and satellites) by the end of the month. Which gives me one month to complete all the documentation and get it submitted with enough time for revisions, should any be required. The timeline is still very tight but I'm still very determined. 

Monday, April 9, 2012

Duplication of work (oops) and Recipe Creation Sequence

With the clock ticking down WAY faster than I'd like, and with a week and a half hiatus on the horizon, I'm squeezing in every possible minute to work on Chef Helper. Then I'm writing code as fast as my hands can type, hoping that what I'm doing will work.

Unfortunately, I spent the last couple of days working on some functions that apparently I'd already completed. I guess a week ago or so, I built the methods to load my validation classes from the database and put them all into a separate class called validations. I decided a couple of days ago that each class should have the methods to load itself and keep a list of all the created objects of its type. I forgot I'd created loaders for the validations and just retyped them all into their classes from scratch. A simple copy and paste would have saved hours of work. Oy!

I did finish all of the loading methods and members of the validations and am moving on to the more complicated classes. I keep getting mixed up and turned around regarding some of the relationships. So I've had to go back to my initial database loader SQL script and try putting in at least a recipe or two. I've avoided putting in any recipes as yet, simply because they are a lot of work to enter directly and will be significantly easier to load through the finished program. But, of course, I need examples to work with to build the finished program.

I grabbed a recipe that looked good for my first example - Eggplant Parmesan. After I added the needed validations, I realized there was one recipe layout issue I hadn't counted on in ChefHelper. This recipe has the ingredients listed in three groups. How can I accomplish ingredient grouping, I wonder? I did go ahead and create all the necessary validations to make a blank ingredient, so I can at least create spacing. Which will do for now.

With that concern dealt with, I proceeded to create all the requisite components of the Eggplant Parmesan recipe, starting from the ground up. This is the same procedure that I will have to do programmatically in my user interface, so it's good to delineate here:

  1. Check that the requisite measure, fraction, meal part, and commitment exist. Since these validations are meant to be static, they should already exist and shouldn't be extended. 
  2. Check to make sure the needed food type exists. If it doesn't, create it. If it does, bring it in from the food types master list.
  3. Check to make sure the needed ethnicity exists.  If it doesn't, create it. If it does, bring it in from the ethnicities master list.
  4. Check to make sure the needed method exists.  If it doesn't, create it. If it does, bring it in from the methods master list.
  5. Check to make sure the needed foodstuff exists.  If it doesn't, create it. If it does, bring it in from the foodstuffs master list.
  6. Create a new Recipe. Feed into the constructor the known and applicable values. The only requirement at this point is a name. 
    • I realized at this point that the name needs to be unique because I won't get an ID until I store the record and I need the ID to store everything else. I don't want to have to refactor all the connections in the database this far into development, so instead of changing the name to be a primary key I instead require simply that it be unique and then check it against the master list before allowing the user to store a recipe.
  7. I now search for the recipe's ID by querying the database by name. This ID will be used in Ingredients, Instructions, Notes, and Meals.
  8. I created each Ingredient. Since I've already checked that the needed foodstuffs exist, this is simply a matter of plugging in the needed constructor and feeding it all the values. One of these values is the recipe ID I determined earlier.
    • It was perhaps a good idea to use a complicated recipe for my demo, because it showed me that I needed more space for the preparation. I didn't anticipate really long instructions but when adding a whole item, I found I needed space for the description of the size and volume of that item. In my example, this amounted to: 1-pound, peeled and cut crosswise into 1/2-inch-thick-slices, each, for two eggplants. I increased the varchar for prep from 45 characters to 100.
  9. I created each Instruction. This was simply a matter of plugging in the needed constructor and feeding it all the values. One of these values is the recipe ID I determined earlier, and it's the only validated value.
Wow, it was only 9 steps but for 19 ingredients and 4 instructions, it took me in the neighborhood of 2-3 hours to create it using direct SQL. I am quite looking forward to accomplishing the same feat far more quickly using my user interface.


Now comes the fun parts I've been dreading - creating constructors for these last 3 classes.  Perhaps the best way to go about this is to create a very basic constructor and use the getter and setter methods to handle all the object attributes...

I tried to start with Ingredient, but it needed a Recipe object to associate itself with. So I tried to start with Instruction, but it also needed a Recipe object to associate itself with. It became clear that I needed to start with Recipe. But guess what Recipe needs? An ArrayList of Ingredients and an ArrayList of Instructions. Oh, and a primary Ingredient and a secondary Ingredient. Yeah, I kinda painted myself into a corner here.

So how did I get to this state? To handle the multiplicity of the Ingredients and Instructions, I had to associate them with their recipe through a foreign key in their tables. To build the objects in Java, I needed the Recipe to contain lists of Ingredients and a list of Instructions.

I've got some ideas on how to refactor to get away from this, but I figure this post is already way too long. If you're still awake, I'll see you next time!

Monday, April 2, 2012

Back in Business

Having finally (FINALLY!) figured out how to get my JDBC driver to load, I've moved on to the next step.  I'm still not feeling the urge to try to figure out the GUI (there's just an overwhelming amount I need to know) and am instead focusing on loading the data from the database and storing it somewhere accessible in the program.

I spent a couple more hours today writing up a validations class which I used to query the database for 8 different validations lists.  These include the list of food types, food stuffs, measurements, fractions, ethnicities, cooking methods, time commitments, and meal parts.  Other than the time commitments and meal parts, theses categories should all be extensible.  Furthermore, by grouping them all into a single class, I just have to have my main program load the class and the loader methods and these lists will be available whenever I need the user to pick from them.  This should, in essence, control user input and only allow accepted, sortable values.  If I reference these later, I should be able to avoid any foreign key failures when trying to update database tables.

The next step is a still a bit nebulous for me.  I have a way to query for validations and can probably use a similar method to query for Recipes, Instructions, Ingredients, Notes, Meals, Daily Plans, and Meal Plans.  However, I'm still trying to decide where to store the master collections of these objects.  I figure that to build the recipe trees in the GUI, I'm going to need a way to create objects for all of these entries in the database and then need a way to iterate through them.  So where should I store a master list?

I'm leaning toward creating a static ArrayList in each class with a load method to populate it from the database.  Then to get the list of recipes, for example, it should be a simple matter of Recipe.getRecipes().  I think.  Another approach would be to create a container class that just maintains these master lists.  I will need ways to sort these lists, convert them to hashes, and search through them, so maybe it's a good idea to put all of these things in the same class.  Or I could keep the lists with the classes and create a Converter class to change them as needed for each usage.  Decisions, decisions...

Of course, the hardest part about planning this is that I don't know what kind of memory hit we're talking about.  I mean, my project is to build a functional skeleton of the program and I think these methods will work swimmingly.  But how far can this program grow with this approach? 100 recipes? 1000? How slow will access be to the foodstuffs list once 10,000 foodstuffs have been entered?

For my purposes, I guess it doesn't matter up front.  If I continue to grow this program after graduation, I'll need to refactor to address these issues, should they come up.  But for now it's best to follow the advice I've been receiving since I first learned to program - know and limit your scope.  Right now, my scope is a skeleton,  and I have a very short time frame to complete it in.  So I will just pick a method and go with it and refactor later if necessary.  And I've decided to keep the master lists with each class and have my main program load them up with the program and just reload them as needed.

Chef Helper is really coming along now.  If I've done this right, I should only have a few major milestones to complete.  The first one after storing these values will be to create modification code in my database objects so I can store new and updated values to the base tables.  I've read about a way to turn my query engine into an interactive sort of system but need to explore it further.  It seems like it's a setting on the ResultSet where I can modify it directly and it will automatically pass on the modifications to the database. We'll have to see about that.

After that little piece, I'll need to finish designing the GUI and figure out how to use Listeners to load and update the screens as they're used and needed.  Once that's tied together and everything is integrated, I'll need to to some testing/debugging (I forgot to include that in my schedule) and then start on the documentation.  I don't recall what all will need to be recorded, but I know the end will include artifacts derived from this blog as well as my ERD and a user's guide for Chef Helper.

So back to the programming for me while I still have some time before going back to work tomorrow. I may need more time off...

ClassNotFoundException is the biggest pain in the ass ever!

Over the past few days, I've deviated a bit from my schedule, despite the fact that I just recreated it.  Right now I should be working on the Java classes that encapsulate the different parts of recipes and meal plans, but after creating the barebones classes with setter and getter methods, I felt it would be difficult to test any methods without having some basis for loading the objects.  In other words, I felt it would be difficult if not impossible to make sure my classes work unless I can load them interactively from the database.

A little while back, I found a bunch of really good templates for connecting my Java program to the MySQL database.  I especially liked one that separated the difference pieces of registering the connection, obtaining a connection, and using the connection.  I decided to use these pieces and separate out execution code to take a SQL statement and return a ResultSet object, leaving it up to the calling class to iterate through that and create the respective objects.  My goal was simply to only have a basic set of static methods to handle all of the database interactions so that I don't have to recreate the database connection controls in other objects.

While I think my code is set up right and should work, I'm stymied by the dumbest thing.  The very first step in using JDBC doesn't want to work and I can't think of any reason why not!

For those of you unfamiliar with JDBC, the very first step is to register what kind of database you'll be connecting to.  It takes the simplest line using a method from the Class class - Class.forName("com.mysql.jdbc.Driver");  I've read through numerous books and countless websites and this is simply the only line that's used to register the database.  They all mention that part of the registration is that you have to have the JDBC jar file in the CLASSPATH variable and then this line in your program and voila! you're good to go.

And that's where the title of this post comes into play.  I have set the CLASSPATH variable to match the JDBC containing folder.  I've set it it reference the folder and file.  I've tried both settings with 3 different JDBC builds.  I've tried this in the NetBeans IDE and I've tried it in the BlueJ IDE.  Though I've been able to access the database from NetBeans in the Services dialog, and have verified I can reach all the tables, I still can't connect my program to it.  I've uninstalled and reinstalled MySQL many times with different security settings (though I don't figure that's the problem). Hours and hours now I've been working on this. 3 days I've been working on this.

And every single freaking time I try this first step to database connectivity, completely independent of any attempt to actually connect or query the database, the Class.forName("com.mysql.jdbc.Driver"); fails with the same exception - java.lang.ClassNotFoundException: com.mysql.jdbc.Driver.


I'm at a loss.  I don't know where to turn or who to ask.  I've read other people's examples, I've read forums, I've read user guides and wikis and websites.  And every single one of them says this should work.  Without this piece working, my entire project might as well be scrapped and I might as well accept failure.  So if anyone reading this has any ideas, any ideas at all... help... please! 


*Update: I did it. I don't quite know how, but I did it.  I re-installed SQL Server with Norton disabled after reading something about how the firewall may block all incoming connections to the database.  Still no success but my NetBeans Services thing stopped working.  Then I came across this website: http://www.linglom.com/2007/12/05/accessing-mysql-on-netbeans-using-jdbc-part-i-create-a-connection/ and found my solution.  I couldn't get my code to work or connect to the right JDBC connector until I followed this website's instructions to add the JDBC driver to the package library.  Suddenly everything started working and I can move on. YAY!!!!

Thursday, March 29, 2012

Recap of work performed - Graphical User Interface (GUI)

Hello again, and welcome to my project blog, perhaps the driest and least entertaining blog you'll find on the Internet.  For my purposes, it will be invaluable.  For yours, I recommend a hearty helping right before bed as the ultimate sleep aid.

Back to the matter at hand.

In my initial projected timeline, I saved the creation of the GUI for the last step.  I designed Chef Helper with a 3-tier architecture in mind, trying to keep with what I understand the industry standard to be.  And the way I understand a 3-tier architecture is a data layer, a logic layer, and an interface layer all working together but being modular and individually replaceable.  So to run the same program on a different interface should only require changes to be made to the interface layer without affecting the other two tiers.

With that goal in mind, I scheduled to start at the data, move into the logic, and finish with the interface.  However, as I was spending all that time working on my data store (see last post), I realized that I wasn't totally sure how I wanted the data to come out the other end.  More specifically, I didn't really know how I wanted it to look and be accessible to the user.  Hoping to clarify that connection to the user, I started drawing up some prospective windows just on scratch paper and started thinking about what layout makes the most sense from a user's perspective.

While I still haven't firmly decided on a lot of the interface layout and design, I did realize that I needed to fit the interface into Java's Swing architecture and I didn't really remember much about how those components are created or interact.  So it was back to the books for me.  Unfortunately, Java Swing is a somewhat under-utilized method of creating user interfaces and good information on it is rather scarce.  Oracle (formerly Sun) provides a lot of documentation but it's all based on how the component classes are structured rather then how to actually use them to build an interface.  It took me weeks and money to find a couple of good resources and a good way to approach the interface.

'Why does this matter at this stage?' you're probably wondering.  Well, I realized that while I now knew what the interface between the logic layer and data layer would look like, I had no idea how to get from there to the user interface.  I had to to quite a bit of research on Java Swing just to get an idea of how its classes were going to fit together to create a usable interface.  I also had to relearn how to use the NetBeans IDE, since it remains the best program I know of for drawing out the user interface in a WYSIWYG environment.

The funny part about all this is that once I got a clearer picture of how I wanted the data to look to the user, I realized that my MySQL tables were going to be inadequate for a lot of the needed functionality.  So I went back to the drawing board and redesigned a number of tables to create a functional and ultimately cleaner data structure.

I am still waiting to flesh out the GUI until I get the logic in place, but I have decided that I need to break the logic layer down into two pieces of its own.  Instead of being one piece that accesses the data, processes it, and displays it to the GUI, I've decided it makes more sense to have a database connection logic section and a separate section to represent the Chef Helper objects in Java and ultimately work with and display them.

The Java DataBase Connectivity (JDBC) class turns out to be rather complicated and convoluted with many nested loops, try/catch blocks, and exceptions, so I'm going to work on the logic section next instead.

And that recap brings us up to today and my current tasks for completing Chef Helper, with very little time remaining and a lot of interruptions already in my schedule. Wish me luck!

Recap of work performed - building the MySQL database

If you look at my original post, you'll notice a bunch of dates have been changed.  When I recreated my timeline, I thought June was the last month this semester.  I received my biweekly phone call from my mentor and guess what? My semester ends in May.  Furthermore, I need to submit everything for grading early in the month so I have time to fix anything that needs fixing.  All I can say is... yikes!

With so little time left, I really have to try to speed up this process a bit.  But I also need to maintain this blog to give me reference points for my project documentation later.  So here goes - a recap of what I have encountered thus far in my project.

In my original timeline, I allotted one month to design the SQL tables.  I thought, 'hey, I administer a database every day and know a lot of this SQL stuff pretty darned well.'  Apparently, I didn't know it as well as I thought.

To begin with, though I had a general idea of how the different tables would work together, I didn't realize how hard it was going to be to deal with multiplicity.  One-to-one relationships were very easy to code but one-to-many relationships proved much more difficult.  I finally realized that the best way (perhaps the only way?) to set up these relationships was to create a separate table for anything that would be used more than once and have it reference the original piece.  To clarify this, let me use an example from my project:

A recipe is composed of a number of things.  I've opted to store a lot of metadata in the form of parameters for the purposes of sorting, storing, and retrieval.  I've then divided the recipe into two pieces of indeterminate length, instructions and ingredients.  Since I don't know how many instructions or ingredients will be in a recipe, I was stuck with figuring out a way to handle the one-to-many relationship.  In my mind, I was thinking that a recipe contains a bunch of these things so somehow it had to be able to reference any number of them.  It turned out that I was thinking about it the wrong way and I really needed a number of, say ingredients, that would all reference the one recipe.

Once I understood how to handle these relationships, I moved on to another topic - data validation.  I wanted a number of elements to be selected from controlled but extensible lists.  A good example of this is the ethnicity of a given recipe.  I figure users are going to want to have the option of looking up recipes by their ethnicity - maybe they feel like Mexican tonight or something.  While I may be able to think of a lot of ethnicities (Chinese, American, Italian, etc), I don't want to try to create a giant list with every possible ethnicity.  And a list of that size would be unmanageable.  So instead I wanted to create a few to get the user started but then allow the user to extend that list.

Ethnicity isn't the only category I want to be extensible.  I want users to be able to pick out recipes based on ingredients.  Since I've divided ingredients into counts, measures, and other factors, I needed a way to create an ongoing, non-duplicated record of foods in recipes.

To be very valuable with regard to sorting and searching, these lists have to be controlled.  After much internal debate, I decided to create individual tables for each of these things.  The tables only have a single value, the primary key representing the ethnicity, foodstuff, etc.  And I'll use these tables as foreign keys for their parent tables so the limitation is enforced at the lowest possible level, the database.

There were a number of validation lists that won't be able to support expansion as their contents will map to GUI fields and other contexts.  To be consistent with my validations, I created these the same way as the extensible lists - tables acting as foreign keys to their parent tables.

I created all my tables in an Entity Relation Model (ERM) using MySQL workbench (an amazing free table design program!) which enabled me to forward engineer and create the database directly from the ERM.

Perhaps I should back up a bit.  Unfortunately, this is my first time ever using MySQL - I use MS SQL 2000 at work - so I don't really know that much about how to properly configure MySQL.  It ended up taking days of work, perhaps even weeks, just to get the database to 1- run, 2- let me connect to it, and 3- let me make changes to its structure.  That was valuable time right down the toilet.  I finally figured out how to run the server as a localhost and how to get the rest of MySQL workbench to talk to it, but to be honest, I'm not sure I could recreate that success without some serious further study.

Having sorted out all the server configurations, I tried to use the forward engineering capability of the workbench.  Unfortunately, a bunch of my foreign keys refused to work!  It turns out that in MySQL, when using the INNODB engine, each foreign key relationship has to be given a name.  I'm not sure what the name is for, since I don't think it shows up in any dialect of SQL, but apparently these names also have to be unique.  Foolish me, I named all of the foreign key relationships after their foreign key fields.  I lost another chunk of time on this because the error MySQL gives doesn't tell you this at all.  It gives an error number that could refer to any number of things.  So figure in a few more annoying days trying to find out what the error meant and how to resolve it.

Once I got the tables about how I wanted them, I set forth to create views to easily and automatically pull out shopping lists.  Since my database is increasingly normalized, this turned into a monumental task as well. I'm actually not certain they work yet because it's too time-consuming to create records for a few recipes.  At least, until the program is finished...

That commentary covers January and February, two months that turned out to be WAY to short for what I needed to accomplish.  On the plus side, the data store is 1/4 to 1/3 of my total project (assuming each component is equal in time and difficulty) so I already have a deliverable to show for my efforts.

Wednesday, March 28, 2012

Chef Helper Begins



After many years of hard work, I have finally arrived at the very last class for my Bachelor's degree, the Capstone Project.  For my project, I have chosen to finally try to plan out and create the recipe program and randomizer that I have always dreamed of writing.

This crazy blog will chronicle the programming process and hopefully aid in the creation of documentation at the conclusion of this project. So without further adieu, let's dive in!

I'd like to introduce a new computer program, titled Chef Helper.  Chef Helper is (or will be) an electronic cookbook, providing storage capabilities for all your favorite recipes.  More than that, Chef Helper is a menu planner, capable of creating and storing meal plans for days, weeks, or even longer.  Built into the program is a shopping list generator which will extract a printable shopping list for any recipe or meal plan.

The program itself is being built using a three-tier architecture.  I am using MySQL for the data store and Java 7 for the application logic and graphical user interface.

I am currently about halfway through the programming process and am running into many matters of insufficient knowledge. Through my degree work, I have learned how to write simple bits of programs in a few different languages and I have been able to prove that I understood the nuances of the language.

Unfortunately this presents two problems at present:
  • First, note the use of the past tense. When prepared for an exam, I knew the nuances inside and out. But I've moved on through countless new projects and tasks and really can't remember a lot of what I studied for so long.
  • Second, I barely wrote any code in preparing for the exams and I definitely never wrote a full working program so I'm going into this with no real design or coding experience.
As I said, I'm about halfway through the coding process, so I'm going to have to start this blog with a recap of where I started and where I've gone from there.

Let's start with timeline changes.  My initial project proposal has to be submitted and approved as part of my Technical Writing course.  Since then, I've had one class that taught me Perl (and helped me lose Java clarity while improving some design structure knowledge).  In my proposal I had written the following timeline:

Monthly Plan

MonthTaskSystemMilestone / Deliverable
NovemberComplete Technical Writing ComponentTaskstreamTWA Paper
November - DecemberDesign and create database tablesMySQLOperational SQL Database
DecemberJDBC connection between Java files and databaseJava/MySQLJava Logic Files – built using JDBC API
JanuaryProgram LogicJavaJava Files
January - FebruaryGUIJava SwingGUI
FebruaryUser GuideGoogle DocsUser Guide
MarchCapstone WritingTaskstreamFinal Paper

Weekly Plan

WeekTaskDeliverable
Oct 30 - Nov 12Install and configure MySQLMySQL installation - client/server architecture
Nov 13 - Nov 19Design SQL tables - outlineDefine database tables, relationships, and primary/foreign keys
Appendix 2 - Table Relationship DiagramNov 15Submit Technical Writing paper for grading
Technical Writing PaperNov 19 - Dec 10Design SQL tables
Operational MySQL DatabaseDec 11 - Dec 24JDBC connectivity and initialization
JDBC interface between Java instance and MySQL databaseDec 25 - Dec 31Holidays - not much will be done
Jan 1 - Jan 11Creation LogicJava controls for creating new recipe objects and necessary related objects (ingredients, instructions, etc) in the database
Jan 12 - Jan 21Modification LogicJava controls for updating and deleting recipe objects and necessary related objects (ingredients, instructions, etc) in the database
Jan 22 - Jan 28Validation LogicJava controls for updating validation lists
Jan 29 - Feb 11GUIStructured Graphical User Interface
Feb 12 - Feb 18GUIGUI controls connected to Java logic pieces
Feb 19 – Mar 3Write User GuideA fully-illustrated users guide for how to operate the Chef Helper program
Mar 4 - Mar 24Capstone writingCapstone Writing Project
Mar 25 - Mar 31Submit capstone deliverables for grading

Note that it is currently March and I am not finished. So, like many real-world programming tasks, Chef Helper is behind schedule. I did get off to a good start while working on my Technical Writing project, which I submitted a little later than anticipated, I believe at the end of November.

At my mentor's advice, I actually shifted gears after that to complete my Perl programming course.  This took a couple of months so I didn't really get re-started on my capstone until sometime into February.  

In addition to changes to the dates in my timeline, as I've undertaken each task and come to better understand it, I've totally changed my approach to writing it.  Initially I was pretty set on doing the database, connectivity, logic, then GUI, in that order.  Having learned more about the JDBC package and the various GUI offerings in Java, I've discovered that I need to work harder on the end pieces (database and GUI), then create the logic to connect the two. I'm splitting the logic and the connectivity into two different entities, so the logic part works with the GUI (or other User Interface should one be needed), the connectivity works with the database, and the two work together to bridge the gap.

Since my original timeline is pretty much hosed, here's my new timeline:
DaysTaskDeliverable
Jan 1 - Jan 31Install and configure MySQLMySQL installation - client/server architecture
Feb - Feb 29Design SQL tables - outline
Define database tables, relationships, and primary/foreign keys
Appendix 2 - Table Relationship Diagram
Feb 1 - Feb 29Design SQL tablesOperational MySQL Database
Mar 1 - Mar 28Create basic GUI layoutNon-functional GUI
Mar 29 - Apr 7Create Java classes for Ingredients, Recipes, Meal Plans, and Daily Plans
Each class should export to GUI-ready formats
Java classes for Objects
Apr 24 - Apr 30
Apr 8 - Apr 14
Finalize GUI and connectorsComplete GUI
Apr 15 - Apr 23Database Conference in Ft Lauderdale - no work will be done
May 1 - May 15
Apr 15 - Apr 23
Create Java classes for database connections.
Classes should have methods for each needed SQL interaction and should output Objects
Java classes for Database interactions
May 15 - May 23
Apr 24 - Apr 31
Integrate all pieces
Create main classes to load program components
Completed, usable program
May 24 - May 31
May 1 - May 5
Write User GuideA fully-illustrated users guide for how to operate the Chef Helper program
Jun 1 - Jun 15
May 5 - May 10
Capstone writingCapstone Writing Project
Jun 15 - Jun 20
May 11
Submit capstone deliverables for grading


I will get into the details of my current progress and all further development in future posts. For now, consider this the jumping off point for completing Chef Helper and finally earning my Bachelor's Degree.