Monday, February 25, 2019

100 Days of Code...formalizing learning and practice

Over the years, I've tried to make sure that I dip my toes in the new technologies that come up pertaining to programming.

Of course - there are far too many new avenues to be able to keep up with everything. And, for anyone that's been in tech for a while you know that not every shiny new thing lasts. So, there is a bit of fear that I'll head down a road that everyone else shuns.

Those two things (too many things to learn and fear) have made my efforts to stay 'current' less than stellar. Add on top of that the fact that I have a full time job in IT that has its own demands on my brain and time and it has been difficult to make the kind of progress that I would like to.

Well, last week I stumbled onto the 100 Days of Code challenge wandering around in Twitter.

And - I'm in...

Today is my third (should have been fourth but I missed a day) day and I have already worked on three separate topics:

  • Practicing Python by working through the exercises in the book 'Exercises for Programmers' by Brian P. Hogan
  • Going through the React course on Scrimba (about halfway through with this)
  • Digging into code that I wrote at least six years ago at work to refactor/improve it


Hopefully, I'll be able to finish these three things quickly and then make a more concerted and focused learning journey.

I've got many other topics that I want to study - so I have in the back of my head the plan to move on to round 2, round 3, round...

First things first though - this is day three.

Friday, August 7, 2015

Getting to the Nexus of the problem of Nexus-OSS on TomEE-RS...

As I have mentioned on previous posts, I am trying to move my development target to Apache TomEE.

As part of that, I am also trying to make my laptop into a complete development environment that includes:

  • TomEE to host my apps (and development tools)
  • Nexus-OSS for repository management (one of those aforementioned dev tools)
  • MariaDB as a database

Well, to start with - I run Kubuntu. So, I installed Tomcat 7 the usual 'apt-get' way and followed the directions on the TomEE site for installing it as a WAR (I used the TomEE-RS version) onto an existing server. Pretty straight forward.

MariaDB required a bit of back and forth with installing and purging Maria vs MySQL but eventually it settled down and I did not need to manually change anything.

Nexus caused some trouble. I found a good list of steps for doing the install here:

http://www.hackrunner.com/2012/04/installing-nexus/

That post is a bit dated - so, I adapted as I typed because I was working with Tomcat 7 and Nexus 2.11.4.

  1. sudo mkdir /usr/share/tomcat7/sonatype-work
  2. sudo chown tomcat7:tomcat7 /usr/share/tomcat7/sonatype-work
  3. wget http://www.sonatype.org/downloads/nexus-2.11.4.war
  4. sudo cp nexus-2.11.4.war /var/lib/tomcat7/webapps/nexus.war

And, it looked like it was working until - it didn't. I got an error in the log file that included:

java.lang.RuntimeException: javax.naming.NameNotFoundException: Name [com] is not bound in this Context. Unable to find [com].

So I searched for some solution online. There was nothing specifically related to installing Nexus on TomEE. Instead, there were results about installing apps that included Jersey on TomEE. People were running into trouble because there is already REST support in the TomEE-RS server. The solution was to remove Jersey from the WAR file that you are trying to deploy (as well as whatever references there are to the included jars in web.xml).

The Nexus WAR was already exploded so, I checked the web.xml to see if there were any references to Jersey - Nope. But, there were several jar files hiding in the WEB-INF directory. I got rid of those with these commands (hoping that it would not end up removing something that I actually needed):

cd /var/lib/tomcat7/webapps/nexus
find . -name jersey* -exec sudo rm -v {} +

And, restarted Tomcat...


Success!

Now, as a note - I probably should have at least specified that the find search for jar files rather than any old file that had a name starting with 'jersey'. I did know that there were only jar files because I had already done the search once before adding the remove. If you are going to try this for something other than installing Nexus on TomEE-RS make sure that you have verified what is going to be removed first.

Wednesday, March 5, 2014

I am a happy boy...

Finally!!!!

I got all of the pieces worked out on my app running on Apache TomEE.

Before you invest too much time reading - this is really dry reading. But, if you are planning on connecting to a MySQL database from an app running on TomEE it might help you get it working.

You're still here! Well...

It took a bit longer than I had expected it to (of course I didn't get to work on it full time). But it works!

I've got my JSP sending data to my servlet using AJAX. The servlet is properly parsing the XML and uses JPA to access my MySQL database.

Perhaps strangely enough, the biggest headache that I ran into was getting the data source properly configured.

Here is what it took...

In the WEB-INF directory is my resources.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<resources>
<Resource id="pInit" type="DataSource">
ignoreDefaultValues true
JdbcDriver com.mysql.jdbc.Driver
JdbcUrl jdbc:mysql://ksdb:3306/projectInit
UserName username
Password password
defaultAutoCommit true
jtaManaged true
</Resource>
</resources>


In the META-INF directory is the persistence.xml file:

<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0"> <persistence-unit transaction-type="JTA" name="pilCommon"> <jta-data-source>pInit</jta-data-source> <class>com.pubint.projInit.entity.Project</class> <properties> <property name="openjpa.jdbc.DBDictionary" value="mysql" /> <property name="openjpa.AutoDetach" value="close" /> <property name="openjpa.DetachState" value="fetch-groups(AccessUnloaded=true)" /> <property name="openjpa.Multithreaded" value="true" /> <property name="openjpa.TransactionMode" value="managed" /> <property name="openjpa.NontransactionalRead" value="true" /> <property name="openjpa.RestoreState" value="all" /> <property name="openjpa.jdbc.SynchronizeMappings" value="false" /> <property name="openjpa.InverseManager" value="true" /> </properties> </persistence-unit> </persistence>

I might have gone overboard on the properties that I set in the persistence file but the minimal version that I modeled after from the TomEE site did not work. TomEE kept trying to use HSQL to connect to the database rather than MySQL (which is what it really should have been).

But that is okay - it works and I can finally move on to building the real pages and implementing the needed functionality.

Whew...

Monday, February 24, 2014

Did someone get the number of that bus...

So, headache it is.

If you caught my post from Friday then you know that I planned to push through getting the beginning of an app that would be deployed to Apache TomEE over the weekend or get a headache trying.

Well...My Saturday got swallowed up by household maintenance issues so Sunday got the brunt of the coding effort.  And (did I mention that I have the attention of a squirrel in the face of new tech?) a decent chunk of my time got eaten up by trying to wrangle heroku into submission as a TomEE hosting service. There were a couple of existing 'buildpacks' (heroku's means of customizing the deployment environment) for Tomcat and TomEE - but they did not work for me. So, I set out on the path of trying to build one that would work.

After many hours of trial and error - no success. But, I do have some clues and a new resolution to search for more experienced eyes (just have to figure out where they would be...).

And, most importantly - I have a renewed resolution to get back to the main effort and to quit yak shearing (I love that term!).

Putting away the clippers now.

Back to coding...

Friday, February 21, 2014

TomEE can you hear me...

When I was listing out my priorities of languages/technologies that I am going to be focusing on in the next year, I forgot to mention (Apache) TomEE.

TomEE is a full Java EE server based on Apache Tomcat (http://tomee.apache.org) and should make it easier to set up, configure, and maintain application servers. But, I have gotten stuck in my ways and lazy. For the past six (or so) years I have been using Apache Geronimo for my app servers. When Geronimo went from version 2.2.x to version 3.x I got left behind. Time constraints kept me from putting in the time to clean up my app and get it into a state that can be deployed on the new OSGi environment.

I still need to put in that time and get my app converted to be compatible. But, recently there are a procession of smaller more self-contained apps that need writing and since we have one externally written app that is running on Tomcat - it makes sense for us to move that app to TomEE and write these new apps for TomEE as well.

So, I am now in the process of trying to develop my first app for TomEE...Using a responsive web framework (Foundation). And, it needs to be ready for beta testing in two weeks.



By Monday I should either have the first functioning bits of this new project running on a TomEE instance or a massive headache. Or...maybe both.

Wish me luck!

And I'll see you in a couple of days...

Wednesday, February 12, 2014

Where did that piece of paper go (part two)...

I have generally had fairly bad luck at predicting the future of where technology was headed.

Back in 1995 I thought that Java was a toy and that it was not going to ever make any real impact on programming. When I first started doing web development I thought that JavaScript was pointless and that there was no good reason that anyone would ever use it for anything serious.

Well, I was at least right that for the most part, applets have faded into the mists of time. But, I use Java pretty much every day. I love the performance that I am able to get on the back-end server. And, over the past six years I have been able to figure out that JavaScript is worth my time too. If I had just figured out that everyone was just misusing it when they made all of those scrolling marquees and flashing text sooner! AJAX has made web browsers into my preferred front end clients.

Since I keep having it pushed into my face that I have been a bad prognosticator I have been trying to be more open minded about technology. Which, has the unfortunate side effect of eating all of my free time. The parade of technology that has been demanding my attention has done nothing but speed up over the past few years. In its wake are hours of my time that were spent starting to learn about a tool, language, or technique only to have something else come along and steal my attention.

I am really tired of swimming so hard against the stream and getting nowhere, so...

I have made a list of the new things that I am going to focus on in the next year or so. And here it is:
What would be really nice if each of those were nicely contained - but they aren't. So, each of them is really the label on a fairly big bag of learning.

On the plus side, I have some actual progress on the beginning of my list. My origami website (that goes along with the Android app that I wrote) Origami Central was written taking advantage of the Foundation framework and should be reasonably workable both on the desk top and on mobile devices. There is still a fairly long way to go with it so it will be getting better over time. And, I have also been able to jam the framework into the work I am doing at my day job as well (sorry that is private so no peeking).

And of course there is a whole handful of other things clambering for my attention. Hopefully, this is the best list for me to focus on and I'll be able to hold off on expanding it until I have a decent understanding of these...

Where did that piece of paper go...

I am sure that you have been waiting with bated breath to find out if I would actually finish an app for Android.

Well, I did! Actually, I finished the first version of it months ago. And, it is even available in the Play store (https://play.google.com/store/apps/details?id=net.jnwd.origamiFinder).

I had hoped to make it completely amazing before I officially told anyone about it so that I would not attract too much attention before it was 'ready'.

Well, work and a thousand other things got in the way of making the improvements that I had hoped to do - so...Here is the official announcement. If you are interested in finding what publications contain the directions to fold a particular origami model without being attached to the internet - then this is the app for you.  I didn't even have a chance to set up advertising in it. So, it is free and free of advertising too!

If you take a look, please leave some sort of review. I really would like to make it better in a lot of ways. But, if I am out in left field about people wanting it - then it will probably languish while I direct my attention toward other things.

Tuesday, October 29, 2013

Probably dumping the Litter out in the trash...

Well, I managed to get the first part of LitterBox written.

And, this is what I managed to make...

I have a screen that allows the user to set up attributes that can be used to describe things and swipe over to another screen that allow them to specify the values that can be selected for them.  And, another screen that allows the user to specify classes that things can be grouped into.  Again, swipeable to another screen that allows you to specify which attributes are used to describe the class.

I learned how to do a number of things in programming in Android:

  • Set up an SQLite database
  • Create a content provider pointing at that database
  • Setting up content loaders to manage adapters that will make loading data into views
I finally managed to figure out that the main idea that I had for what LitterBox would do and the way that it would help simplify future development was wrong.  But, it was worthwhile to do because I got my foot in the door.

While I was building my LitterBox...I think I've actually figured out a real, useful app to build.  And with the skills I've learned, I should be able to create it.


Friday, September 6, 2013

Nobody puts LitterBox in the corner...

Throughout my software development career, the screen real estate that I have been able to work with has been steadily growing.

I started out with 80x25 character based terminals and progressed all the way up to doing most of my development with a browser based UI.

Mobile development is forcing me to rethink how I use space.  Suddenly, I don't have a giant virtual workspace that is easily navigated with a mouse.

And, so - for the first time in a while I need to take a step backwards and carefully think about every little bit of screen space.  It is a good change and has been refreshing to view everything through a new lens.  But, it is taking some time to adapt to the new paradigm.

And, that is why LitterBox is coming along slower than I originally hoped and thought.

But, it is still coming (still not quite ready for prime time).

And when it gets here, all that data should fit into it quite nicely...

Friday, August 16, 2013

I don't have a cat...Why am I building a litterbox?

A little over a year ago, I got motivated enough to start trying to learn how to develop apps for Android.

Shortly after that, I got too busy to keep up with it - and I stopped.

But now (finally) I have gotten back to it!

So far, I have one very rough finished app that allows you to query a local SQLite database of origami models to find what publications they are in (needs a good bit of work before I do more than mention it).  And, the beginnings of my 'litterbox' project (for more detail - check out my earlier posts).

In case you don't feel like reading my old posts about litterBox - What it is meant to be is a way to define data structures using a standardized UI (nothing special there) and then it will provide a way to request that data and methods to update/delete it.

At first glance, that might look like it is just another front end for a database.  And, it is.

But, it will make it easier to define the data structures by non-programmers.  That is what will make it special.  Another thing that I hope to include is a way to disconnect the view of the data from the way it is stored.  I'm currently using local SQLite, but I also would like to enable a back end on NoSQL, cloud storage, etc.

There will also be an included basic UI for accessing data in those structures so that you can describe something and right away begin keeping track of those things.

At some point in the (hopefully near) future, I plan on making it possible for people to share the definitions that they come up with to build up so that other users will not have to reinvent them.  After all, once someone successfully describes an 'address' - why should everyone else have to do it all over again?

All of this was inspired by a project that I needed to do where the data structure needed to be modifiable by the users.  After implementing that project - suddenly it seemed like what I had done could be used to store information about anything.

I guess we'll see if I can really generalize this.

Stay tuned.

Wednesday, August 22, 2012

Building the litterBox...

In the past two posts, I went through figuring out what type of data tables could be used for storing a catalog of any type of item including a full description - in user data so that the same program could be used to keep track of a collection of anything.

http://bhindsight.blogspot.com/2012/07/a-litter-is-bunch-of-categories.html
http://bhindsight.blogspot.com/2012/08/litter-is-also-where-categories-put-all.html

Now that that is done, the next step is to build the processing side of the system.

Since I do most of my work building Java webapps that run on Apache Geronimo...I will lay out how I would build the back end running on Geronimo.

First of all, the information would have to be stored in the database tables.  As I said, MySQL is my (current) favorite database so, that is where the data would live.  What I have not recently mentioned is that the Java Persistence API (JPA) is Amazing!

Before I discovered JPA, all of the data access I did was done by manually coding the commands in SQL using JDBC to perform the connection to the database.  This was slow, error prone, painful to debug problems, and tedious.

Using JPA, all you have to do is to create Java classes that correspond to your database tables, add some fairly straightforward annotations to them, and list them in a configuration file.  And voila, reading and writing to/from the database is nearly as effortless as creating POJOs.

Geronimo comes with Apache OpenJPA baked in - so there is nothing extra to do except use it.

Here is a link to the persistence.xml that I made for my litterBox sitting in github:
https://github.com/jaydm/litter-ejb/blob/master/ejbModule/META-INF/persistence.xml

On the flip side, we will need to get that data sent over to the web client (and have new data sent from the web client).  For flexibility, I like to use XML.  Most programming languages have standardized methods for processing it - and that includes JavaScript.  I am going to choose it over JSON (JavaScript Object Notation) even though many languages also support JSON because it makes me nervous.  It is possible to put executable code into a JSON object, but it is not possible to do the same in XML (at least not easily).

And, to add to the attractiveness of XML, there is a built in standard to convert Java objects into XML - JAXB (Java Architecture for XML Binding).  In the same way that JPA makes it possible to simplify database access using annotations - JAXB makes it possible to marshal Java objects into XML using a essentially a block of boilerplate code (after those same POJO entity classes get a couple of JAXB annotations added).

Here is a link to the first entity class fully annotated (both for JPA and JAXB):
https://github.com/jaydm/litter-ejb/blob/master/ejbModule/net/jnwd/litter/entity/Attribute.java

And, that takes care of making Java aware of the data.  Now we need to establish the API between the web client and the server.  The interface we will be using should support all regular adding and updating functions.  Sometimes this is referred to as CRUD (create, read, update, delete) - but I hate actually deleting.  So instead, we will just mark things as being deleted with a 'deleted' attribute (so no table change needed).  We will also combine the 'create' and 'update' functions be having update automatically do the create if the record is not found.  That gets us down to only needing two functions: read and update.  We'll add one extra 'selectList' that will send back a simplified list of all of the records.

And our final interface becomes:

  • sendXML() - send the full XML of a table row to the client (identified by its ID).
  • selectList() - send a simplified XML of each table row as a part of a big list for use in populating drop down boxes.
  • update() - update existing table row or create new (and then update)
And a link to the interface for the attribute session bean:

Both the sendXML and selectList methods will return a string of XML data (to be interpreted by the client).  The update method will return the ID of the row that was just updated (or created).  That way, the program will be able to request the XML data if needed.

The update method is going to use an object that contains XML data parsed and processed from the message sent from the browser client (along with an XPath object for pulling the data out of it).  This will move the need for the servlet layer to understand the information that it is handing back and forth all of the way back to the session beans that will actually be doing the work.

So that is the rough (very rough) run down of how processing will be managed.

The github repo will be updated (as I have time) to fill in all of the functionality that is described here.  I really do plan on having a complete (if rudimentary) working app when all is said and done.

Next up...

Presentation.

Tuesday, August 7, 2012

Litter is also where cat(egories) put all their s**t...

In the quest to be able to store information about any collection (regardless of what it is a collection of), we began by trying to determine the necessary generic data structures.

When we left off - we had figured out tables to store the:

  • attributes that are necessary to flesh out a category
  • attribute value types that those attributes can contain
  • attribute values (the choices that attributes can actually hold)

But, those attributes are not describing anything yet.  Lets fix that and finally define the category table.

category (
id bigint auto_increment primary key,
categoryDescription varchar(255),
subCategoryOf bigint
)

Those first two columns are pretty straight forward.  There is an id and a description of the category.  But that third is not so obvious - especially this early on in figuring everything out.  The reason is that I am cheating a little bit and looking ahead.  And what I see when I do that is - in order to describe a category, there might be 'things' that are part of it.

For example (going back to crayons...and this is pushing a little bit) - crayons not only have a color and a length.  They also have a manufacturer.  And, a manufacturer would need its own set of attributes to describe it (name, address, phone number, etc).  I do not plan on actually going to that point.  But if I did, then it could be taken even further (addresses have the street number, street name, city, state, etc...phone numbers have area codes, prefixes, etc).  Being able to specify that a category can be a sub-category will allow us to support this type of nesting regardless of whether or not it would be silly (or necessary) to do so.

Having the category table allows us to define what a category is - but not to hold any actual things that belong to the category.  We also do not have anywhere to store the actual attribute values for a particular item (just the list of choices that it might have).

instance (
id bigint auto_increment primary key,
categoryID bigint,
instanceDescription varchar(255),
created date
)

instanceAttributeValue (
id bigint auto_increment primary key,
instanceID bigint,
attributeID bigint,
attributeValueID bigint
)

You may or may not be able to tell, but the way we have this set up, a user would have to have an entry in the attributeValues table to pick...No free text entry.  We will handle that by allowing the user to pick from the list or enter new text that would automatically get added to the attributeValues table.  But that is an implementation detail and I am going to try to keep the data structure clean.  To do that, let's add another column to the attributeValues table - (instanceSpecific boolean default false).  Here is the new structure of the table.

attributeValues (
id bigint auto_increment primary key,
attributeID bigint,
valueData varchar(255),
instanceSpecific boolean default false
)

Now we can tell that an entry in the table is a one-off and can be removed if there is no reference to it.

One more thing is missing - there is no way to tell which attributes belong to which categories.  This could be handled in one of two ways: add the categoryID as a column in the attribute (rigid) or make a join table (flexible).  To see how these choices would affect the system, let's take 'color' as an example.  The rigid route would force us to have a special color attribute for every category that we wanted to have it apply to - each with its own set of possible values.  The flexible way will allow us to use a single color attribute and apply it to as many categories as we wanted - much less redundancy.  If we come across an attribute the at first looks like it is a repeat but turns out to need a special set of values then we can always split it out later.

xCategoryAttribute (
id bigint auto_increment primary key,
categoryID bigint,
attributeID bigint
)

And that completes the first part of the trek.  All of the data structures have been figured out.

Here are the additional table entries to let us actually describe a crayon (some of the table definitions are from the previous post):

category
  • (1, 'Crayon', null)
attributeValueType
  • (1, 'Enter single value', true, false)
  • (2, 'Enter multiple values', true, true)
  • (3, 'Select single value', false, false)
  • (4, 'Select multiple values', false, true)
attribute
  • (1, 'Color', 3)
  • (2, 'Length', 1)
attributeValues
  • (1, 1, 'Red', false)
  • (2, 1, 'Orange', false)
  • (3, 1, 'Yellow', false)
  • (4, 1, 'Green', false)
  • (5, 1, 'Blue', false)
  • (6, 1, 'Indigo', false)
  • (7, 1, 'Violet', false)
  • (8, 2, '3 inches', true)
xCategoryAttribute
  • (1, 1, 1)
  • (2, 1, 2)
instance
  • (1, 1, 'Red crayon', '2012-08-07')
instanceAttributeValue
  • (1, 1, 1, 1)
  • (2, 1, 2, 8)
If that is anything less than dizzying to look at - you are following along far too well.  Here is an attempt to string things together.

Crayons (categoryID: 1) have two attributes: color (attributeID: 1) and length (attributeID: 2).  The value for a color must be a single value selected from a list (attributeValueTypeID: 3).  The value for the length of a crayon will be a single entered value (attributeValueTypeID: 1). The red crayon gets id 1, is a crayon (categoryID: 1), and was created on '2012-08-07'.

And, we have one crayon described - a new red one.  The values for its two attributes are (id: 1 / categoryID: 1) color (attributeID: 1) red (attributeValueID: 1) and (id: 2 / categoryID: 1) length (attributeID: 2) 3 inches (attributeValueID: 8).

That probably does not help much right now.  If you can make it through to the end and see this actually working it should all become a bit clearer.  And even if it doesn't get clearer, that is why we have computers manage all of this for us.

The next two parts are going to be tied pretty tightly together: data entry/display and processing.  But, I will try to pull them apart to make them a little bit easier to keep track of.

To do the pulling apart, we'll continue moving from back (server side) to front (user side).

And cover...

Processing.

Wednesday, July 11, 2012

A litter is a bunch of cat(egorie)s...

For some reason, I started thinking about organizing a bunch of 'anything'.  That probably grew out of my previous post about what programming is - but I can't be sure.

There are thousands of apps that slice into that pie of organizing something (your CD library, sock drawer, shopping list, etc).  But, as far as I know, there isn't one that will organize anything.

And, that led me to consider what it would take to make such a thing.  I did not go the next step to wonder how many people would want an app that would be generic enough to allow them to catalog their collection of stamps in the same place as they cataloged their collection of CDs, shirts, socks, etc.  Neither will I start trying to figure that out now - instead, I will go through the exercise of building it.

If you are interested in watching the app evolve, stay tuned.

Phase one: Figure out what your data is...

As I go through this, I will be designing the data structures to hold the information.  Since I am most familiar with SQL, I will be using tables (in my head, they are mySQL tables - but that is just in my head).  Also in my head, every table should have an id column that has no intrinsic meaning.  If your table has a name or description (or any other meaningful piece of information) as its primary key, things will get messy if you ever want to change that column.

Since this is intended to be a program to allow you to catalog anything - there is no way for me to determine exactly what the information being stored will be.  So, instead, I need to figure out a way to describe an 'anything' and group together all of the attributes that are necessary to describe one.

Aha!  An 'anything' has attributes that describe it!  I'll need an 'attribute' table.  There will not need to be much to it though.  Just the name of the attribute and the type of information that it will hold.

Crap - I need an attribute value type table too.

attributeValueType (
id bigint auto_increment primary key,
valueTypeDescription varchar(255),
enterValue boolean default true,
multiValue boolean default false
)

This table has two boolean (true or false) columns.  This took a little bit of thinking ahead.  And the reason for them is this.  An attribute will either allow the user to 'select a value from a list' or 'enter a value'.  Which of these two applies will be indicated by the value of the enterValue column.  If the value is 'true' then the user will be able to enter any value that they want.  If it is false, they they can only select from the list of options that the attribute permits.  The second boolean indicates whether or not it is possible to have more than one value for the attribute.  An example of an attribute that allows only one value might be the 'color' of a crayon.  But, a sweater might have several values for the 'color'.

You might be looking at this table and thinking to yourself that even though we have this nifty table, there are only four possible combinations of enterValue and multiValue.  And, you would be right.  Since you would be right, it would be an option to simply hard code these four values and forget about having the table altogether.  I hate hard coding if I can avoid it though.  If you decide to implement this system - feel free to get rid of this table.

But, there is a method to my madness... Keeping this in a table will allow us to extend the system later when we realize that there are more kinds of information we might want to keep track of (like dates or currency amounts for example).  For now, I am keeping things simple.

Here are generic versions of the four records that would go into the attributeValueType table:
  • ('Enter Single Value', true, false) - gets an id of 1
  • ('Enter Multiple Values', true, true) - gets an id of 2
  • ('Select Single Value', false, false) - gets an id of 3
  • ('Select Multiple Values', false, true) - gets an id of 4
Now, we can define our attribute table.

attribute (
id bigint auto_increment primary key,
attributeDescription varchar(255),
attributeValueTypeID bigint
)

Now we are starting to get somewhere interesting.  We can begin to think about one particular thing and how to describe it.  i.e. What are its attributes?  To help think about this, we should probably pick something to be our 'anything'.  As long as we keep the goal of a system that can keep track of 'anything' it won't hurt to narrow things down while we are designing/building it.

I will pick crayons - because there are not very many attributes to keep track of.  Actually, there are lots of attributes of crayons.  Most are things that would usually be ignored (diameter, wax type, melting point, flash point, weight, wrapper material, etc) with only a few that would 'usually' be kept track of (color, length).

So, lets make entries for the attributes to describe a crayon:
  • ('Color', 3) - gets an id of 1
  • ('Length', 1) - gets an id of 2
Here is the rational behind these choices for the attributeValueType.  The color will be a single value (most crayons have only one color) that will be picked from a list.  The length will simply be entered in.  It would be possible to change the length to a 'select from list', but in this case - it would probably be silly to try to enumerate all of the possible lengths that a crayon could have (3", 2.99", 2.98", endless silliness..., 0").

Wait a second.  We don't have a place to hold those color choices.  Time for another table.  Now, these values will need two things.  They will need to know what attribute they belong to (attributeID) and they will need the actual value that they are (valueData).

attributeValues (
id bigint auto_increment primary key,
attributeID bigint,
valueData varchar(255)
)

Since we are here, we will go ahead and enter the color choices that we will need for our crayons (I'll pretend there are only the seven colors of the rainbow for our crayons):

  • (1, 'Red') - gets an id of 1
  • (1, 'Orange') - gets an id of 2
  • (1, 'Yellow') - gets an id of 3
  • (1, 'Green') - gets an id of 4
  • (1, 'Blue') - gets an id of 5
  • (1, 'Indigo') - gets an id of 6
  • (1, 'Violet') - gets an id of 7

Each of those got an attributeID of 1 because they all belong to the attribute 'Color' that we created earlier.

Ack.  That is an awful lot of work considering that we didn't even get to making a 'thing' yet.

We'll take a break for now.  But come back!

Next time, we will finally make a cat(egory).

Monday, July 2, 2012

What is programming...

The non-programmers that I know usually do not have a particularly good idea of what programming is.

I know that none of the people that I have in my circle of people really know what I do for a living.  Most seem to think that I fix hardware.

To be clear, I am mostly going to talk about programming from a utility or business standpoint.  But even games follow the same principles (although it might not be as obvious).

Programming is a natural thing that people do all of the time - but usually, it is 'throw-away' coding.  They figure out how do perform a task, perform the task, and forget about the whole thing until (unless) they need to do it again.

Computer programming requires something more regimented.  We (you) are figuring out how to explain to a computer exactly how to perform a task.  Because computers are very good at doing exactly the same thing over and over again (but not good at filling in the blanks if you skip a step) it is important to include every necessary step.

Good computer programming would require making those steps simple.  Computers can follow complicated steps, but when you are trying to read your work in the future (or someone else is trying to read it) simple will be easier for you.  And a good practice would be to make sure that not only are your steps as simple as possible, but that you make them self describing.  Name variables so that the tell you what they hold.  Put in comments.  Include logging that makes your program tell you what it is doing as it is doing.

Great programming adds in speed and elegance.

There is no one way to add speed and elegance.  I think that mostly, they will come from practice at trying to be a good programmer.

I think that every program is made out of a small number of 'major' parts.

  • Data
  • Presentation/Input
  • Processing
The data is the information that your program has to work with.  Whether it is temperature and wind measurements for a weather modelling program - or the amount of money in your bank account along with your deposits and expenditures...data is the whole reason for writing a program.  It is what you want to keep track of and the building blocks that you need to solve a problem.

Presentation is how you show your data (and results) to your user.  Input is how you get the source data from them.  Ugly screens or complicated interfaces will make it more difficult for someone to use your program.  It may be the best at what it does, but if it is painful to use...no one will ever know that.

And processing is all of the work mixing the data together and applying various rules against it.  If you have the best data and the most pleasant, understandable presentation...It will not matter if you program does not do something useful (and correct) with it.

From the order that I listed them, you would probably infer that I think the data is the most important part of the puzzle.  And, you would be right.  If your data is wrong or you are keeping track of the wrong information - your system is never going to be useful.  So, the first step in any programming exercise should be to figure out what your data is.

But, whatever you come up with will probably be wrong.  With practice, you will get closer to being initially right (so keep practicing) but you will need to keep an open mind as to what needs to be kept track of.  And also, what your user will need back from you.  As you move through the process both sides of that equation will (hopefully) become clearer and clearer.  As changes make themselves obvious - adjust.

The next part of programming is figuring out how you will get that starting information from the user, how you will show them what they told you, and how you will give the results back to them after they have been processed.  You will also need to figure out how the processing actions are going to be started.  Will the user press a button on screen, set a timer, etc...?  A well designed user interface is one of the things that can make or break a program.

And finally, what processing needs to be done?  There needs to be a payoff for your user otherwise, they will not go through the bother of starting your program (never mind taking the time to enter all of their data into it!).  This is where the meat of programming is.  Someone has a problem that they want solved.  It is a problem that requires keeping track of a lot of information or performing difficult manipulation of information (or both).  Sometimes your user would be capable of doing that work themselves and sometimes they will not be.  You will need to make it 'cheaper' (in time, stress, accuracy) for them to use your program than to do the work themselves.

This is a little more than strictly 'programming'.  Working through all of these would encompass system analysis, system design, interface design, data processing, as well as the programming part.  If you have a team to work with and each person takes a piece - that might make it easier for each to become expert at the part they do.  But I would say that being able to see the big picture and all of the parts is what truly makes creating programs fulfilling.

Thoughts?

Thursday, August 12, 2010

Big snakes and programming...

I have started trying to learn Python again.

This time, I am using the book "Hello! Python" by Anthony Briggs.

I am only a few chapters in so far, but it is an easy read.  It is going fairly slowly for me, but that is because its audience is beginning programmers.  And, it seems like it would be great for new programmers (or hobbyists) getting started with Python.

The book is still in its 'early access' phase, so it is only available online as a PDF.  But, you can order it as a 'real' book too and get a copy in digital form to start on while you are waiting.

Did you miss me...

I had these grand plans for this blog and I think that those big plans kept me from keeping active here.

I thought that I needed to have something big and important to say before I said anything.

I am going to try to get over that.

Small things can be important too.

Monday, November 16, 2009

The little things mean the most...

There is a programming pattern that I had never seen before.

That is, there are multiple constructors of a Java class that share a 'base' block of code that needs to be called for each of them.

Well, I try to minimize opportunities for bad typing.  So, when I came across a situation like this - I created a method called base() that would be called by each of the constructors.  That way, the code would exist in one place and would be easier to keep clean and up to date.

Good plan right?

It worked, but today I was playing with the idea of making my big giant app send Twitter updates to let me know what was going on and notify me as errors occured.  The java library that I stumbled onto was twitter4j by Yusuke Yamamoto.

I wanted to make sure that if I tried to send a large (more than 140 character) tweet - it would be handled gracefully rather than getting truncated.  At first glance, they would have gotten truncated.  I'll have to check further to see if this is true.

But, my base() trick is not as clever as I thought.

There was a better way, that I never saw before today.  And that is to use the regular zero parameter constructor by calling it from each of the other constructors as this().  Clean and beautiful - thanks Yusuke.

To myself I say...

Duh.

Tuesday, November 10, 2009

Cookbooks and Recipes: Men, Women, and Programming...

Disclaimer: I think that everyone who chooses to be a programmer has to be (at least) a little bit crazy - whether male or female. But I think we are missing out by not having more female programmers - so if you are female and so inclined then I at least would welcome you. Also, I have a strange sense of humor.

So... Now that we've settled that...

I got to listen to Kirrily Robert speak at ApacheCon last week. She gave a keynote about women in open source and technology called 'Standing Out In the Crowd'. And it struck me that there are numerous books on programming that include the words 'cookbook' or 'recipe' in their titles.

Now, I love to cook - so I don't mean to imply that cooking is in any way a 'womanly' pursuit or task. But, there are many that think of it that way.

Anyway - one of the ideas that are presented as justification for the fact that there are few females in programming is that somehow the 'pink brain' is not suited to mathematics.

I will not even bother arguing whether or not this is true (Kirrily cited a study that determined that there was a slight difference). Regardless of any difference that may exist - it does not matter. I have been a programmer for over two decades and with the exception of a very small number of projects - there has been very very little math that was involved.

What is involved (as far as I am concerned) is understanding a problem and then teaching a computer to go through the steps to solve it.

So, how good a programmer you are is determined by:
  1. How well you can wrap your head around a problem.
  2. How well you can learn a particular language's syntax.
  3. How well you can break the solution of the problem into a sequence of steps.
  4. How well you can codify those steps in the language's syntax.
Most of the time, not much math.

Some languages may lend themselves to solving particular types of problems better or more 'elegantly'. But I have never heard of a language (human or computer) that is somehow easier to learn based on which gender you are.

Sometimes, boolean algebra can be used to make solutions 'prettier'. But most of the programmers that I have worked with never studied boolean algebra - male or female.

Hopefully, math will stop being used as justification for saying or thinking that 'women can't program'. And instead, the idea that programming is really teaching gains more mindshare.

Not every person who decides to be a programmer is cut out for it. There is a certain amount of insanity necessary to be good at it because you are effectively trying to teach a machine to solve a problem by describing the solution in a language that is not natural for you -or- the computer. And the computer is not going to go out of it's way to bridge that gap. That is all up to you!

There is nothing that I can see that makes males more suited to programming than females. And empathy (seeing a situation from the point of view of the other 'person') is often thought of as being a trait that is stronger in females. So, if there is a natural advantage held by anyone - it might be by women.

So, if you have an interest in foreign languages and in teaching completely empty-headed students who will force to you explain every single step in excruciating detail - then programming might be for you.

There may be a very good reason why there aren't more female programmers.

They are smarter than us.

Tuesday, November 3, 2009

Goin back to Cali...

I am in California.

This is the second time that I have been in this state.

The first time was over fifteen years ago.  And I was here to see how a software company was planning on translating their product from a character based program that ran from a command line in either DOS or _nix - to a windows program.

They were going to try to use a program to translate a BASIC language system to Visual Basic.  But the program required a person to make sure that the individual programs were written according to a set of programming standards.

They almost never were - so they ended up doing a substantial rewrite and forced those that had written customizations to write them all over again.

This time, I get to attend the 10th anniversary ApacheCon.

Over the past ten years, the Apache foundation has grown from a small group of people who forked the code from the NCSA web server - to an international group of programmers and users who develop and use a growing set of software projects (currently more than 60 and growing).

About three years ago, my day job gave me the opportunity to develop a substantial new system that would eventually replace a number of scattered information systems that spanned spreadsheets and flat file databases.  It would also integrate that information with the company's accounting system.

In trying to figure out the best platform for developing this new system I stumbled onto WebSphere community edition (WASCE) and through it - Apache Geronimo.

I was hooked.  Here was an environment to develop for that was scalable, standards based, open source, fast, ... everything I could hope for.

Through Geronimo - I found a number of other projects that are integrated by Geronimo.  And each of them was the same - open communities that seek feedback and encourage participation.

I do not know how many people are reading this.  Or how many of you are involved in software development.  But it is an amazing thing to find people spread out across the whole world who are passionate enough to give away their time and energy developing and/or supporting software.

Last time in California turned out to be a moderately interesting waste of time.

This time, nothing has really started yet - and I am already excited to get to be a part of something so bold and (at least in my experience) unique.

This is, in a word...

Awesome.

Wednesday, October 7, 2009

OSGi (or - late to the party again)...

Just when I thought that I might have been getting in on the beginning of 'the next big thing' - I find out that I am actually ten years (years?) late.

Recently the Apache foundation accepted a new podling into the Incubator called Aries.

If you are unfamiliar with the 'Incubator' and/or 'podlings' - take a look at this page on the Apache website:  http://incubator.apache.org/

Anyway, the Aries project seeks to develop the bridge between OSGi and Java EE.

I have come to really like the way that Java EE makes separating the front end development from back end processing.  And since OSGi seems to be the way that much of the Java world is going - I'm trying to get in on the ground floor with Aries.

But, the 'ground floor' is pretty high.  OSGi has been around for ten years now.  And so there is quite a lot of 'assumed knowledge' that goes along with it.  Also, the actual specifications for Java EE in OSGi are still being written and are not expected to be finished until the beginning of 2010.  Aries hopes to help in fleshing out those specs as well as providing an implementation of them.

Well, I should get back to reading the specs that have been written.  They are only 516 pages long (ack!).

So far.