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!
Thursday, March 29, 2012
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.
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:
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.
Monthly Plan
| Month | Task | System | Milestone / Deliverable |
|---|---|---|---|
| November | Complete Technical Writing Component | Taskstream | TWA Paper |
| November - December | Design and create database tables | MySQL | Operational SQL Database |
| December | JDBC connection between Java files and database | Java/MySQL | Java Logic Files – built using JDBC API |
| January | Program Logic | Java | Java Files |
| January - February | GUI | Java Swing | GUI |
| February | User Guide | Google Docs | User Guide |
| March | Capstone Writing | Taskstream | Final Paper |
Weekly Plan
| Week | Task | Deliverable |
|---|---|---|
| Oct 30 - Nov 12 | Install and configure MySQL | MySQL installation - client/server architecture |
| Nov 13 - Nov 19 | Design SQL tables - outline | Define database tables, relationships, and primary/foreign keys |
| Appendix 2 - Table Relationship Diagram | Nov 15 | Submit Technical Writing paper for grading |
| Technical Writing Paper | Nov 19 - Dec 10 | Design SQL tables |
| Operational MySQL Database | Dec 11 - Dec 24 | JDBC connectivity and initialization |
| JDBC interface between Java instance and MySQL database | Dec 25 - Dec 31 | Holidays - not much will be done |
| Jan 1 - Jan 11 | Creation Logic | Java controls for creating new recipe objects and necessary related objects (ingredients, instructions, etc) in the database |
| Jan 12 - Jan 21 | Modification Logic | Java controls for updating and deleting recipe objects and necessary related objects (ingredients, instructions, etc) in the database |
| Jan 22 - Jan 28 | Validation Logic | Java controls for updating validation lists |
| Jan 29 - Feb 11 | GUI | Structured Graphical User Interface |
| Feb 12 - Feb 18 | GUI | GUI controls connected to Java logic pieces |
| Feb 19 – Mar 3 | Write User Guide | A fully-illustrated users guide for how to operate the Chef Helper program |
| Mar 4 - Mar 24 | Capstone writing | Capstone Writing Project |
| Mar 25 - Mar 31 | Submit 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:
| Days | Task | Deliverable |
|---|---|---|
| Jan 1 - Jan 31 | Install and configure MySQL | MySQL installation - client/server architecture |
| Feb - Feb 29 | Design SQL tables - outline Define database tables, relationships, and primary/foreign keys | Appendix 2 - Table Relationship Diagram |
| Feb 1 - Feb 29 | Design SQL tables | Operational MySQL Database |
| Mar 1 - Mar 28 | Create basic GUI layout | Non-functional GUI |
| Mar 29 - Apr 7 | Create Java classes for Ingredients, Recipes, Meal Plans, and Daily Plans Each class should export to GUI-ready formats | Java classes for Objects |
Apr 8 - Apr 14 | Finalize GUI and connectors | Complete GUI |
| Apr 15 - Apr 23 | Database Conference in Ft Lauderdale - no work will be done | |
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 |
Apr 24 - Apr 31 | Integrate all pieces Create main classes to load program components | Completed, usable program |
May 1 - May 5 | Write User Guide | A fully-illustrated users guide for how to operate the Chef Helper program |
May 5 - May 10 | Capstone writing | Capstone Writing Project |
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.
Subscribe to:
Comments (Atom)
