Screenshot of Nutrition Analyzer tile and logo (symbolizing the food pyramid)
on Windows 8 start screen.
Some images in this submission had to be resized to meet the 640 pixel size
constraint for bitmap files. Unfortunately this did compromise the image quality
to some degree.
Nutrition Analyzer is a new application that has been running as a Windows
7 desktop application for almost a year, to be debugged and fine-tuned. It is
now being converted to a Windows 8 application to take advantage of the significantly
improved ease-of-use features of Windows 8. The application provides diet or
food analysis to any user who is interested in the nutritional content of daily
Potential users include (but are not limited to):
- Ordinary people who are just trying to control weight gain.
- Professionals who need to assess the nutritional value of specific diets to meet special needs, including institutions like hospitals that may have to obey special dietary rules for some patients.
- Diabetics who want to monitor their intake of sugars and carbohydrates.
- Athletes who want to monitor their intake of electrolytes, carbohydrates or protein.
- People with cardiovascular problems that want to monitor their intake of cholesterol and saturated fats.
- Any person who is concerned about the nutritional content of the food he or she eats.
It is important to note that the application merely analyzes the content of
foods. It does not give nutritional advice. It tells you what is in the food
that you eat, not what you should be eating. That is the domain of professionals
in the field of nutrition. However, the users have the ability to plug in their
own particular nutritional needs. For example: There are many excellent tables
on the website of the Institute Of Medicine (IOM), that give the recommended
intake of all nutrients, for both sexes of all age groups. The user has the
ability to look up data on the IOM website, that pertain to his or her personal
circumstances and to plug that data into the Nutrition Analyzer, even to adapt
the recommendations to his or her personal preferences. The application will
then warn users if their daily intake of any particular nutrient or nutrient
factor (like calories), falls below the minimum requirement or exceeds the maximum
tolerable level (potentially toxic level). But the accuracy of this daily requirement
data as entered, remains the responsibility of the user and his or her professional
advisor. This will be made very clear in the license agreement of the application.
The analysis of foods in the application is based on the most complete and
comprehensive database that is distributed free as a public service by the US
Department of Agriculture. The data in the tables of this database is available
for free as an unrestricted download of delimited text files. (It is almost
a 100MB download.) This database is used by thousands of manufacturers to calculate
the familiar nutrition labels that appear on just about every food item in the
stores. The database contains the nutrient content of almost 8,000 different
food types. There are 146 nutrients (like vitamins) and other nutrient factors
(like calories) listed for a 100 gram portion of every food type. It lists all
the vitamins, macro minerals (calcium, potassium, etc.), micro minerals (zinc,
copper, selenium, etc.), all 14 essential amino acids (from tryptophan to tyrosine)
all saturated fats, unsaturated fats and other long chain fatty acids (the omega-3s,
omega-6s, etc.) as well as other nutrient factors like sugars and other carbohydrates,
dietary fiber, calories, caffeine, alcohol, etc. This "master data"
is embedded in the application as a C# DataTable object. This is the main reason
the main exe in the assembly is almost 40MB long, but it does mean the user
has all the data right on his desktop / ultrabook. There is no need to run queries
against external databases, or to even have a database engine on his or her
machine. The user does not even need a network or Internet connection. It also
means the data analysis executes at a very high speed. Embedding the master
data also means that the data integrity is preserved. The data cannot be modified
maliciously or by accident, without corrupting the entire application. However,
we may later decide to distribute the master data table in a separate DLL, rather
than embedding it in the main application. This will simplify upgrading the
user's installation every few years, when the USDA publishes an updated version
of the database. All the upgrade will entail is replacement of the DLL on the
It will be impractical to expect the user to scroll through 8,000 entries to
find a particular food entry. So the application allows the user to create a
shortened version of the embedded Master USDA Table, called the "Basic Foods Table" which the user fills with entries of particular interest to
him. Most people need about a hundred entries for their short version of the
data table, but its length is unrestricted. This table is saved as a file on
the user's computer and can be edited by him at any time.
The user also has the capability to make custom entries into a third data table,
called the "Other Foods Table". The purpose of this table is to allow
the user to enter foods that are not in the master USDA data base. Typical examples
will be multivitamin tablets and fish oil capsules. The user can enter his favorite
brand of multivitamin with the content of each vitamin into this table. When
he or she selects an entry from this table, all the user needs to specify is
the number of pills or capsules taken and his or her intake of the relevant
nutrients will be adjusted accordingly. The user can also create custom entries
for items that may have close approximations in the USDA table, but for which
there are no exact matches. For example: He or she can create a custom entry
for "KASHI Almond Crunch Granola Bar" by running a query for "Granola
Bar" against the master USDA data table and selecting the closest approximation.
(There are more than 20 entries to select from.) The user can then adjust those
nutrients that appear on the Kashi label to their exact values and know that
the other nutrients for this custom item will be a reasonable approximation
of the actual values. When the user selects his or her custom entry, all he
or she needs to do, is specify the number of bars eaten and his or her daily
nutrient totals will be adjusted accordingly.
Users have the ability to view their average daily intake of all nutrients
for a period of any number of days. The period of interest is selected by picking
two dates from date pickers.
The User Interface
The main user screen:
As you can see, the Basic Foods Table appears on the left. The Other Foods Table
is on the right. The user selects a food type by clicking (or tapping - in the
case of Windows 8) on the item. The rows can be set wide for finger tapping, or narrow for mouse input. The
selection made by the user is displayed at the bottom of the screen, with the typical portion
size for the selection and the calories in one typical portion. The user then
enters the number of portions he or she had in the Manage Entries group on the
right. The time and date for the entry will initially default to the current
system time and date, but the user can change these values with the date picker
and by entering the desired time in the appropriate text boxes. When the user
clicks or taps ADD ENTRY the item with all 146 nutrients in quantities appropriate for
the portion size entered, is saved in the user's personal table.
This personal table, and all other tables (except the main USDA table), can
be edited by the user as detailed further down in this submission.
Please note that the visual styles in this submission have been modified to reflect the GUI windows as they appear in the version published by the AppUp store.
Viewing user Entries:
When the user clicks or taps VIEW ENTRIES in the above window, he or she is
presented with the window below. By default, the period to view will be the
current day, but he or she can select any number of days for which data exists. If
he selects days for which no entries exist, those days are simply ignored. Here
is a screen shot of a typical VIEW ENTRIES window:
On the left the user can see every portion of every food type that he or she
consumed during the selected period. The 146 nutrients for every food entry
are listed in columns to the right. The
total for each nutrient column is calculated and divided by the number of days
in question to give the average daily intake in the TOTALS (Daily Average) column.
In the rows at the bottom, the user can see how his or her daily totals
compare with the recommended daily intake. The user has to make a one-time entry
of the recommended values that best suit his or her personal needs. However,
we will provide links to the website of the Institute Of Medicine where many
excellent tables of these values are available for on-line viewing. These tables
provide recommended data for both sexes and for all age groups. Other than the
USDA data, these IOM tables are copyrighted, so we could not embed them into
the application. But for the user to select appropriate data and manually and
entering it into a special table in the application is an easy task that most
people can accomplish in less than 30 minutes. This only needs to be done once
and the table of recommended values is stored as a file on the user's computer.
Of course, the user (usually in consultation with a healthcare professional)
has the ability to modify the data in the recommended intake table to suit any
special needs he may have, like lowering the limits of sugars for diabetics,
or cholesterol for people with cardiovascular issues. Weight watchers can set
lower limits for the daily calorie intake (or carbohydrates - if they are on
an Atkins type diet.) When the average intake of any nutrient is deficient,
the Difference row right at the bottom displays the shortfall against a blue
background. If the maximum tolerable intake level is exceeded, the difference
is displayed against a red background.
The user can print the data if desired, by clicking PRINT. This will invoke
a standard Windows print dialog. His or her daily intake levels of the 146 nutrients
will be printed in vertical columns across three pages, along with warnings
pertaining to excessive / inadequate levels. This will provide the user with
a printout to discuss with his or her professional adviser.
This is a partial image of a printed report:
The user can also delete incorrect rows by selecting the row and clicking or
tapping DELETE ENTRY. Of course, the incorrect entry can then be replaced by
making the correct entry for the same date and time from the main window. All
this personal data is stored in a C#
DataTable object and the software re-orders
all entries in the table by date and time, before saving it as a serialized
stream to a file on the user's computer (or in the cloud - as the case may be.)
Like other tables, except for the embedded master USDA table, the file is automatically
read when the application is started.
If the user clicks or taps EDIT TABLES in the main window (see above), he or
she is presented with the following window:
The user has the option to back up any of the four lesser tables: The personal
table, the Basic Foods Table, the Other Foods Table and the Recommended Intake
Table. Since the Master USDA Table is embedded in the application, either in
the main exe file, or as a DLL, this cannot be backed up. If this master data
becomes corrupted the whole application needs to be re-installed, as the entire
application is probably corrupted. In this case it is very likely that the operating
system will refuse to run the app.
If the user clicks VIEW PERSONAL TABLE, he or she is presented with the VIEW
ENTRIES window covered some paragraphs back. From that window faulty entries
can be deleted, later to be replaced by the correct entries.
If the user selects to edit the Basic Foods Table he or she is presented with the window below:
If the user clicks IMPORT NEW ITEM, he or she gets a window that allows him
or her to run a query against the embedded Master USDA Table to search for
key word(s). For example: If the user enters "Potato" as a keyword,
he or she will get a list of over 100 entries out of the almost 8,000 in the Master USDA Table that contain the word "potato". When the user selects
one item, it and all its nutrient data is transferred to the Basic Foods Table,
where it can later be easily selected for dietary intake. This is the only way
data can be added to the Basic Foods Table, by importing an entire item from
the Master USDA Table. Note that the USDA database, in common with all major
international databases that provide nutritional data, works in the metric system.
Nutrient content is usually given as micrograms, milligrams or grams per standard
portion of 100 grams for each food type. This is not an issue, as all food scales
nowadays measure in grams, or have the option to be set to grams. American users
soon get used to even think portion sizes in grams.
The user has the ability to delete an entire entry and to save the table as
a file on his or her computer.
By selecting to edit the Other Foods Table, the user has the opportunity to enter custom
entries for supplements like multivitamin tablets, fish oil capsules, etc.,
for which there are no equivalents in the Master USDA Table. The user is presented
with the following window:
By clicking CREATE NEW ENTRY the user can create a new, custom entry by setting its description and nutrients in the window below:
The user will enter his or her New Unit of Measure (in this case "cup")
The user may then click ACCEPT - SAVE to
permanently add his custom entry to the Other Foods Table, where it then becomes
available for selection when he or she makes new entries into the personal data
This project started as a hobby when I retired as an electronics engineer in
2010. Although not trained as a programmer, I have been writing apps for Microsoft
platforms since I got my first IBM PC in 1984. Those first apps were in the
original Microsoft Basic running on DOS II that booted from a floppy disk. I
have experienced the complete evolution of the C language, from C6 to C++ to
versions running on the MFC libraries to today's "visual" C# versions.
C# is the only language I use nowadays and Visual Studio my only IDE.
I am very excited about the new technology with Windows 8 running on an Ultrabook
with "touch" capabilities, as it will considerably improve the functionality
of my app. It will be so much easier to scroll through 146 columns of data,
looking for a specific nutrient column, by swiping the screen with a fingertip
rather than dragging a scroll bar with a mouse. I already got some complimentary
copies of Windows 8 from Microsoft and have been looking for a suitable Ultrabook
but could not find "touch-enabled" versions to match Windows 8 functionality.
To keep busy in my retirement, I started this project and initially the USDA
database delimited text files were converted to a proper SQL relational database
in a special C# app that I coded. I installed SQL Express on my desktop and
for about 6 months ran the first version of the Nutrition Analyzer on top of
the SQL Express engine. But then some friends and family members (and even my
neighbor - a doctor) saw the app and started asking for copies. I realized that
I could never hand out an app that required access to a SQL database engine.
Maintaining a SQL database engine is just too complicated for the man in the
street. That is when I decided to recode the app, using embedded C#
objects to hold the data, instead of a SQL database. The first challenge was
to code an app to extract the master data in a specific table format from my
SQL database and to save the desired table as C#
DataTable object file on my
computer. That was the easy part. Things got a little more complicated when
I successfully embedded the resulting DataTable file as a static resource in
my project during compile time, but then tried to read the file data, now embedded
in the main exe of the project, during run time. I cover how I got this done
in the "Using the code" section below. I ran hundreds of tests to
verify that I get exactly the same result when I ran a nutrition query against
the on-line USDA database and when I run the same query against me embedded
DataTable file. After sorting out some glitches related to rounding errors,
I got the app to return exactly the same data as the on-line USDA database
engine for specific queries. Today I am satisfied that my app will return data
that is a 100% match for data in the actual USDA database. At the same I started
re-coding the app to avoid the requirement for a SQL database engine; I also
decided to convert it from a Forms project to a WPF project. This conversion
was completed before the app was submitted to the Intel AppUp store. The app was published by the AppUp store on November 30.
Using the code
One challenge I faced with this project, was to embed a database table written
out by another app as a serialized stream to an XML file on my computer, into
my main project assembly. Embedding the file as a static resource using Visual
Studio 2012 at compile time is quite easy. But reading the file, now embedded
into the main exe of the project, during runtime to reconstruct the original
DataTable object, was a little more challenging.
Important: There are risks, uncertainties and limitations involved in serializing / deserializing
DataTable objects as well as using blocks of unmanaged memory as done below.
Study the Microsoft documentation on these topics and be sure you address any
vulnerabilities. You follow the approach below at your own peril. I shall not
be responsible if you cause a disaster because you did not fully understand
and address the risks.
In the end I used the following approach:
First copy the XML file (here called FullUSDA.DatTbl) to the solution folder.
Then add it to the project as static resource. In Visual Studio 2012 this is
quite easy. If you do it correctly, your file will show up as resource under
your project's Resources, something like this:
Now this file will be compiled as a resource into the NutritionAnalyzer project,
where it can be accessed during runtime.
Since this file represents a serialized
DataTable object, to reconstruct the
DataTable object at runtime, we need to de-serialize the file and for this we
need the following namespaces and steps:
public partial class MainWindow : IDisposable
public DataTable _fullUsdaDataTable = new DataTable();
private void InitializeFullUsdaDataTable()
IFormatter formatter = new BinaryFormatter();
byte tableByteArray = Properties.Resources.FULL_USDA;
Stream tableStream = new MemoryStream(tableByteArray);
int tableStreamLength = (int)tableStream.Length;
IntPtr tableDataPtr = Marshal.AllocCoTaskMem(tableStreamLength);
_fullUsdaDataTable = (DataTable)formatter.Deserialize(tableStream);
catch (Exception InitializeFullUsdaDataTable)
Points of Interest
I needed to make use of older Windows Forms controls, specifically
DataGridView objects, in this project.
The reason I needed Forms controls, is that WPF projects do not have controls
with the same functionality offered by Forms
too limited in their utility. I had no option but to host
DataGridViews as child
objects in my WPF windows. This is relatively easy in Visual Studio 2012, but
slightly more convoluted in VS 2010 and earlier. . It is important to remember that Forms
DataGridViews are disposable
objects, so the window that will host these controls needs to be derived from
IDisposable. You also need to provide methods to dispose of the
in order to produce "clean" code.
See the snippet below:
public partial class MainWindow : IDisposable
protected virtual void Dispose(bool disposing)
public void Dispose()
This is the submission to CodeProject of the application, as validated and published by the Intel AppUp store. The current version of the Nutrition
Analyzer is: 3.3.0
Thank you for considering this submission for the Ultrabook competition.