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.