Turning the Graph Function Into an Object in JavaScript, Part 5

Today’s goal was to come up with a reasonably automated way to specify formatting for the numeric values associated with the major tickmarks on each axis. I chose to implement settings for decimal places, overall precision width, and whether or not trailing zeros would be stripped. If the formatted string with decimal places is used unless it is longer than the formatted string at the specified precision, in which case the latter is used. Trailing zeroes are then stripped from each string.

This may result in different strings having different formats. First there’s always that one string that has fewer decimal places than all the others because it happens to end in a zero. Alternatively, some strings might be in fixed decimal while others may be in scientific notation. I therefore made a second pass that involved assigning consistent formatting based on the “worst” format of the bunch. If any value was in scientific notation I applied the toPrecision function to all values. If that didn’t apply, I applied the toFixed function so they all matched the value with the most decimal places. That could be annoying when a floating point operation leaves one string with a value like 12.0000001, as sometimes happen, but the extraneous digit would probably be to the right of whatever place the used specified to begin with. If all values were successfully stripped to the decimal point, the values are all displayed as whole numbers.

The first sieve, applied to individual values, is fairly quick. Remember that for the time being these functions are object methods. Once I get everything working I’ll clean it all up to hide the elements that should be private.

The next bit of code does the same thing to either the y- or the y-axis. It cycles through the values to generate a formatted string, then determines whether any string uses scientific notation using by search for the letter ‘e’, or whether any string includes trailing decimals by searching for the ‘.’ character. The latter search term is formatted as it is because the search function actually takes a regular expression as its parameter and the decimal point has a special meaning in regular expressions. Again, a second pass is made to apply the “worst” format consistently. The pixel with of each string is then calculated based on the prevailing font (which should be set just prior to this call) along with a value for the widest string in the group.

I experimented with the graphing tools in Excel to see how it formatted axis values under different combinations of conditions and found that, without going into an extreme amount of coding, it produces similar results in most cases. There is always more one could do, but this first pass is reasonably quick and effective. It often takes human intervention to get decent-looking labels anyway, this this approach seems good enough for now.

If you look carefully at the second block of code you might notice that it’s missing its ending brace. Tomorrow I’ll describe how the information I calculated today, along with the height and angle information, are used to figure out how much space is needed to draw all of the values.

Posted in Software | Tagged , , | Leave a comment

Turning the Graph Function Into an Object in JavaScript, Part 4

Picking up from last week I’ve finished turning the JavaScript graphing widget into an object, the results of which are shown below. There is a long list of TODOs included in the code that is not close to being exhaustive; I’ll be working those off over the course of the next few posts.

The fun part for me was leveraging a functional parameter. I’d done that somewhere in the mists of time but it was nice to implement it here per my reading and have it work on the first try. See lines 374 and 379 below.

The current form of the graph is meant to support a single type of plot, which is the single curve in segmented colors as shown. I’ve set the object up so it plots the y-value at every pixel along the x-axis and draws lines from point to point after the initial moveTo call. The vagaries of the way pixels work on canvases and the fact that lines and characters are antialiased this technique yields a fairly thick plotted line.

I’ve broken the original functions down so the calculation of the pixel location on the graph is separated from the calculation of the effective value to plot, and that is separated from the function used to repeatedly call for the next point to be plotted. A package like Microsoft Excel plots only from a discrete set of values calculated in cells, and there is usually a fair amount of distance between plotted points on the x-axis. I’ve stubbed in a plotting call that draws specific figures at a specified point (a ‘+’ and an ‘X’ to start) but have not yet implemented anything that plots successive such values from a list. That functionality will definitely be included as I describe how I did the individual sections of curve fit and show the resulting function along with discrete control (x,y values from the steam tables used to derive the actual curve fit) and test (x,y values from the steam tables in the same range of x values but not used to derive the actual curve fit) points.

Posted in Software | Tagged , , | Leave a comment

Turning the Graph Function Into an Object in JavaScript, Part 3

Today I’ll describe the sizing of characters so the graph object knows exactly how to place them. I hacked together a tool that prints out letters in a specified font and then draws horizontal lines at various offsets from the baseline. A section of that output is shown below:

Looking at the output in a magnifying glass shows how the different characters are laid out. If you were to draw a single character using the fillText function and set the x and y coordinates with left alignment, you’d get output like that shown below. The light green pixel shows the base X and y locations you specified and the values shown in the margin are offsets from that base point.

The base row of pixels for each character is mostly drawn one pixel up from the location specified (the green row). The red line is drawn one row of pixels above the top of each character. The blue line of pixels is drawn one row of pixels below the bottom of the descenders.

Rerunning that exercise for Arial fonts from 4px to 30px allowed me to build the following table.

Remembering that the numbers 0 through 9 don’t have descenders, we see that the 12px Arial digits are drawn between vertical pixels -1 and -9 inclusive, so the actual characters are 9 pixels high. A full-height character would span from 1 to -9 inclusive, which would be 11 pixels high in total, or 13 if the bounding box is included. There isn’t a one-to-one correspondence between specified pixel size for a font and its actual pixel size, though it’s close. The differences are biggest for the smaller specified sizes and decrease as the fonts get larger. It may be that the pixel height of the bounding box is always equal to the specified pixel size for fonts sized 24px and up.

In the course of my research I noticed a discussion of assigning character heights by point size instead of pixel size (e.g., 12pt vs. 12px), where someone stated that points are more accurate. I’d have to repeat this analysis to see, but that’s not going to happen today.

The next item in the queue is to determine the effective height and width of rotated text. That process begins once we know the size of the bounding box for said text.

The process for rotating elements on a canvas is a bit backwards from how I originally learned how to do it. I am used to translating the individual element to the origin (or whatever point I actually want it to rotate around), performing the rotation, and then translating the element back to its original location. The mathematical operations are performed on a copy of the object based on its native dimensions in “model” space. How the object is drawn on screen is a translation from model space to screen space.

In order to rotate items on a canvas object you apparently save the context, do a translation (with values that seem to have the opposite sign of what I would expect, though I’m sure the designers did this to make the operations more approachable for those who don’t know what’s going on behind the scenes), perform the desired rotation on the entire canvas, draw the desired element around what is now considered coordinate 0,0, then restore the original context. It may be that the code isn’t actually doing anything with the information on the canvas while things are being rotated, but doing this way feels impossibly weird and wasteful. Nonetheless if you follow the steps as shown you get the results you want.

In the figure below I’ve worked out the code to draw three bits of text, with their bounding boxes, each normally and then rotated counter-clockwise by 45 degrees. The top example is left justified, the next example is centered, and the bottom example is right justified. The green point (actually the upper left pixel of it) shows the coordinate that defined the base location of the textFill operation and also the point about which the text was rotated. You can adjust things up or down by a few pixels to do the rotation around a point in the middle of the text with respect to its height.

OK, now that we know how to draw the box rotate it, we need to be able to figure out how much space it’s going to take up on the unrotated screen. With that information we can calculate the margins between the edges of the graph area (and axes and tick marks) and the edges of the canvas itself. Then we can work out any minor adjustments.

The x dimensions as shown are the width or height of the bounding rectangle multiplied by the cosine of the angle of rotation. The y dimensions as shown are the height or width of the bounding rectangle multiplied by the sine of the angle of rotation. The sum of x1 and x2 is the total number of pixels covered across the width, and y1 plus y2 is the total number of pixels covered across the height of the text. Once you know that you can make the slight adjustments to any tick marks and so on. If you’re always going to rotate by the same amount you can calculate the sine and cosine values once each and then apply them where needed. If the only rotation you’ll allow is 45 degrees as shown then you can use the constant value (0.7071067812) for both the sine and cosine.

Note that the dimensions only consider the bounding box. The methods described don’t consider whether the characters drawn will set pixels near any particular corner but I don’t think it matters and it would be madness to try. Indeed, you will get more consistent results by not worrying about that detail and placing all of your items in the same way.

Note also that you don’t have to go through the hassle of drawing out the bounding boxes. I only drew those to illustrate the process. You get the base width of the text from the measureText function, the height from the table (or some other method), and the angle from your own definitions. I’m guessing that in most cases you’ll want to right-justify your text and place your items just to the left of or just below the tick marks on the x- and y-axes, possibly with a minimal offset.

I’ve created a jsfiddle here to demonstrate the scripting code in action. It includes the code used to draw the font detail above and the rotation examples. It isn’t the cleanest, but it works.

Finally, I think it would be a good idea to back up and actually implement the basic graph as an object rather than try to account for every possible option up front, so that’s what I’ll present on Monday.

Posted in Software | Tagged , , | Leave a comment

Turning the Graph Function Into an Object in JavaScript, Part 2

In drawing a graph I’ve created variables for all sorts of coordinates (where do the axes begin and end?) and characteristics (how many tickmarks per interval, how long are they, and what color?). However, rather than define the locations directly they should be calculated indirectly based on the presence and size of other items associated with the graph.

Let’s begin with the top of the graph with respect to the canvas upon which it’s drawn. We have to leave a certain amount of buffer space to make it look nice, we may have to leave space for half the text of half the label at the top of the y-axis (in the left margin as shown), and we may have to leave room for the title of the graph, if one is specified. Given that the origin of the coordinate system is defined to be the upper left corner of the canvas and positive values increase going right and down, we need to allow pixels as follows:

  • margin between top of graph area and top of next feature up, either the title or the top of the canvas
  • height of the title text, if it is present
  • margin between the top of the title text and the top of the canvas
  • height of any y-axis label text that extends beyond the top of the y-axis itself
  • margin between top of topmost y-axis label and top of canvas, if the top of the label text represents the topmost element to be drawn

We might decide to package up the specification, location, and drawing of axes but the same values will have to be considered. Also, the top label on the y-axis may not be drawn at the top of the axis itself; there may be offsets. It may also be possible for label text to be drawn at an angle.

If there are any other elements added to the upper margin of the graph they would have to be taken into account as well. Similarly, if text for a title is present but is not located in the upper margin (as opposed to being located in the graph area itself), then that would also have to be considered.

Even more interestingly it may be possible to define an axis aligned to the top of the graph, in which case we’d have to account for the length of the longest tick marks, the height of tick labels and an additional axis title, and additional margins as needed. Secondary y-axes are commonly drawn on the the right side of graphs (and more than one can be placed on either the right or left side), but it is uncommon to encounter even one, much less more than one, placed along the top of the graphing area. Nonetheless in order to be completely flexible we’ll go ahead and plan for such an occurrence. (It’s also possible to draw axes in the middle of a graph, as in cases where an origin would be in the middle of the graph area.)

However we ultimately decide to structure things, we’ll need to know the height of the label text we plan to draw before we formally draw it. There are two aspects to this. The first is the height and width of the text itself and the second has to do with the angle at which the text is drawn. The width is easily calculated as shown:

The fillText function itself can take an optional fourth parameter, that specifies the maximum width in pixels. This doesn’t define where line or word wraps take place, it defines the width the text will take (in pixels) after the text is stretched or compressed to the desired width. If the maximum width in pixels is defined, that value overrides the textWidth value calculated above.

Now it gets trickier. There is no function to calculate the height of the text you plan to draw so there are a few ways to approach it.

  • Do some outside experimentation with a particular font and size so you know how it will behave–and then stick to using that font and that size. Pay attention to the number of vertical pixels in capital letters and descenders. Note that numerical digits have the same height as capital letters and also have no descenders. This method has the virtues of being completely accurate and completely automated once you’ve done the work up front.
  • Perform the experiments described above on numerous fonts and numerous sizes and build a table of height values you can reference.
  • Make the height a default or even a user-supplied parameter. This method can generate undesired or unexpected results or can place some of the burden on the user to adjust things, and in a way that may not always be understandable.
  • Use one of the other automated or semi-automated methods described at links like this.

You can see from the third option, which actually subsumes the first two, that this is a tricky problem that I’ll discuss in detail tomorrow. I also have a discussion of determining the effective width and height of rotated text in the queue. The two concepts work together, as you’ll see, so I’ll address them both at the same time.

Posted in Software | Tagged , , | Leave a comment

Reverse Engineering Or… What Was It I Was Trying To Do There?

While continuing the process of turning the JavaScript graph widget into an object I found I needed to create labels of various kinds, which you see added in the examples below. I also wanted to test out some more of the thermodynamic functions I wrote when I was doing power plant simulations. The graphs I generated for specific enthalpy of saturated fluid (hf), specific enthalpy of vaporization (hfg), and specific enthalpy of saturated vapor (hg) are shown below.



These graphs represent represent the thermal energy contained per unit mass of saturated water in its liquid and gaseous states and the amount of energy it takes to transition between the two. If you’re not a thermodynamics geek its not all that important. What you need to know is that water is used in power plants (and a lot of other applications) and you have to know how it acts in order to a) design the plant and b) model said plant, as we did for the training simulators.

Strictly speaking the saturation curves for water are only defined between 32.018 degrees Fahrenheit (0.0866 psi) and 705.44 degrees Fahrenheit (which occurs at 3204 psi). Since my models didn’t have to deal with temperatures higher than about 560 degrees Fahrenheit (around 1100 psi, the operating pressure in a boiling water reactor or BWR) my steam tables only had to cover up to somewhere in the low 600s. One of my models did have to deal with very low temperatures, however, which story I’ll get to.

The two graphs above are plotted from 33 degrees to 633 degrees and the graphing function is in this case designed not to graph the segments that make discontinuous jumps to zero. (I’ll have to deal with that when I generalize the functions that may include values both above and below zero.) The bottom graph, for vapor, however, is plotted from -40 to almost 700 degrees. The upper section was generated as a normal curvefit but the lower section appears to be generated by a linear function I developed. As I mentioned above any water vapor that exists in a region below 32 degrees will be superheated and not saturated. I think what I must have done was to use a different source for the properties of superheated vapor and simply extend the function and graph as shown. I do not actually remember what I did back then and I don’t have time to figure it out now. However, the section of the model that inspired me to do this work needed to represent vapor at temperatures somewhat below 32 degrees, and the functions I wrote seemed to work smoothly enough.

You can see from the two graphs below that I also extended the functions for enthalpy of fluid and enthalpy of vaporization down to -40 degrees as well.  In these cases I’m not sure what the point was or how I generated the numbers.  It looks like I assumed a constant heat of vaporization and generated the liquid curve by subtracting it from the vapor curve.  I’d have to look at my notes to see what I was thinking, but I’m pretty sure any vapor that remained in the colder parts of the model was never allowed to condense into a liquid.  At that point it should more or less have been treated as a contaminant in the air mixture that was being processed in the system I was simulating.

If nothing else, remember to take good notes.  You may find yourself revisiting some very old code and scratching your head a lot (or wondering what you were drinking…). That said, I had developed a consistent way of representing what happened in the various model nodes of a system that contained high-pressure steam with a bit of air and dissociated hydrogen and oxygen at one end and cold, low-pressure air with traces of water vapor at the other, so I’m sure I developed the functions for completeness and consistency. It was a very, very challenging exercise, particularly for a modeler with as little experience as I had at he time. As I have described elsewhere I developed an entire continuous simulation framework so I could do my own testing and development. I had to learn a lot, and I had to do it quickly. Fortunately I had my own computer, the latest copies of Borland’s Pascal products, several books of steam tables, and no fear.


A couple of final notes are these.  I mentioned that the graphs, which plot by sections, are set up to not draw discontinuities to zero, but they do draw internal discontinuities, as you can see in the two plots above.  The numbers below each plot are widgets I added to the web page in question to record the range of non-zero y-values I generated for each function.  I used those to help me identify the values to use on the y-axis.  The more I work with these functions and the more I look at things I’ve done previously, the bigger this project gets.

Fortunately it’s fun!

Posted in Tools and methods | Tagged , , , , | Leave a comment

Turning the Graph Function Into an Object in JavaScript, Part 1

Sometimes it is simple enough to build an object from the ground up in a slow, methodical, organized fashion. By contrast, one may also choose to hack something together to get it to work, play with it, and then refine it. In the particular case of the graphing widget I threw together last week I am clearly taking the latter tack. This is a problem I have solved before but for novel problems it’s often a good idea to work through various trials and prototypes, object-oriented or not. It’s also good to write out the code you want to be able to generate automatically, or at least some examples of it. This ensures that you aren’t trying to debug the resultant code at the same time you’re trying to figure out how to generate it.

Those observations aside, creating a graph on a web page–at least the way I’ve done it–relies on the HTML5 canvas object. There are a couple of ways to proceed that I’ll discuss today. The graph object must be associated with a canvas, but the canvas object itself can be created either as part of the original HTML for a page, which can them be referred to by the graph object, or created as part of the graph object’s constructor and added to an existing page. In either case it is important to remember that the native dimensions of the canvas itself have to be specified at the time of its creation and insertion into the page. Applying style properties that attempt to modify the dimensions of the canvas after it is created and added to the page have unexpected effects, which I’ll describe.

The normal way to define a canvas element in a page is by using the following HTML statement like that shown below. An id must be included so the object can be uniquely referenced, and the dimensions need to be specified as the object is created. If dimensions are not specified the canvas assumes default dimensions of 300 pixels wide and 150 pixels high (in browsers that support the canvas element).

If you want to create the canvas on the fly in JavaScript you must specify its dimensions before you add it to the page as follows:

This uses the object constructor approach, which allows for creation of multiple such objects. It is a means of defining a type rather than a specific, instantiated object.

In this case I’ve provided the constructor with a width, a height, and an id value (expressed as a string). When the constructor is called it looks for an element having the provided id. If the id is found and the located element is, in fact, a canvas, then the graph object assumes its width and height. If the id is found and the located element is not a canvas than the constructor can raise an error of some sort. If no element with the specified id is found then a canvas element is created and added to the page using the document.body.appendChild() function. This is the only case in which the width and height parameters are actually used.

After that the canvas can be referenced and modified as usual, as shown in the example.

I noted above that the dimensions of the canvas element must be set when the object is created and added onto or inserted into the page. If you do not manipulate the dimensions further with CSS commands then any drawing commands will map 1-to-1 by pixel as expected. If you do apply CSS styling to change the width and height of an existing canvas it will change the size of the element on the page, but it will treat the pixels inside the canvas boundaries as if they still had the original dimensions. The interior objects will simply be scaled so they occupy the same relative proportion and location of the interior space. This will also affect the thickness of any lines or other objects drawn with the object.

That said, changing the dimensions of a canvas by directly modifying its width and height properties in JavaScript appears not to have the same effect. If you specify new dimensions then the graphing space in the canvas will have the same dimensions on a 1-to-1 pixel basis. I don’t know why you’d want to modify a created canvas object in that way, but if you do, now you know it’ll work. In short, CSS bad, JavaScript good–in this limited case.

Note that this process could be expanded to include the ability to handle inserting the newly created graph element into the middle of a page using the insertBefore() function. It could be expanded again to make the append and insert operations apply to any level of element and not just the document as a whole. On the other hand, at some point, given that we’ve created the ability to attach to an existing canvas element (and safely modify its dimensions), we might leave it to external code to arbitrarily place the new canvas and then attach to that in the simplest way. The possibilities, of course, are endless.

Posted in Software | Tagged , , | Leave a comment

Migrating WordPress Databases To More Recent Versions

I’m going to interrupt my previous project with a note on how to migrate WordPress databases to more recent versions. It turns out that all of my sites were using version 5.1 of MySQL, support for which seems to have been discontinued right around the end of 2014. My current host creates new databases in version 5.5 so I thought it prudent to update. This discussion assumes that you are supporting your own copies of WordPress on an internet host and not simply using a subdomain at WordPress.com.

After looking through the WordPress admin UI I didn’t see an obvious upgrade route like those that existed for some migrations of phpBB versions (never mind that those could be problematic, particularly if your database was corrupted). Some Googling indicated that you have to move the database by hand, which means exporting it from one database and importing it to another. When that is done you have to update the wp-config.php file in the WordPress root directory on your host.

I was comfortable enough with phpMyAdmin but there is a minor hitch you need to know about to make the export->import process work correctly. You can use the quick export function to generate an SQL file that you save to your local drive. (It goes without saying that you want to be sure you are careful to select the correct database in phpMyAdmin for each export and import operation.) If you try to import that file into a new database, however, it will balk because the imported file does not contain a command that allows the SQL to work with the target database. Mine threw “Error 1046 No database Selected.” I found the guidance for what to do here. It took a little bit of doing but I found that editing the SQL file and adding a command near the beginning in the form:

…gave the importing database enough information to process the file correctly. You do not have to include the create database command discussed at the link, because of course you’ve already created the new database on your host. I didn’t experiment with the form of the apostrophes (my example uses backticks or grave, apparently pronounced “grah-vuh” marks). I moved on when I got it working but there are a lot of discussions on this topic.

The wp-config.php file refers to the database name, user, and host, all of which will presumably be readily identifiable and will share some common text. I made it a point to duplicate each line and comment the original out so I could backtrack in case the process didn’t work. I then edited the uncommented copy of each line, saved the file, and copied it back to the host.

If you navigate to the site in your browser and see your latest post(s), can log in, and can otherwise manipulate and edit things then congratulations, your migration was successful. If not then either you’ve made a mistake somewhere in the process or there is some other requirement of hiccup I did not encounter.

As I mentioned above there are situations that may be more complex. If WordPress (or similar packages like phpBB) change their database schema then the upgrade or migration process will necessarily be different. In those cases there will be (almost certainly be) a ready-made upgrade procedure that includes the use of ready-made scripts that will handle changing the schema and moving the data as needed. That said, it may change the schema within an existing database version and you still may need to move the updated information to a new database version.

Over the years I’ve encountered discussions of other differences between database versions that had to be accounted for (e.g., here and here), and those would have to be dealt with as you find them.

Here is a description of the process in its simplest form:

  1. Back everything up. Document whatever you did.
  2. Log into the phpMyAdmin facility on you internet host.
  3. Create a new MySQL database.
  4. I use the same text description and password I used for the original database. You could presumably change these things if you’d like, but especially with the database password I can’t guarantee that a change will work. I didn’t test it.
  5. Record the name, username, host, and password information for the newly created database.
  6. Select the old database in the phpMyAdmin tool.
  7. Perform a quick export of the database and save it someplace where you can edit it (like your local drive). I saved mine as uncompressed SQL files since they may be edited as simple text files.
  8. Add a command to use the new database by name near the top of the file (before any other important operations are performed). I placed mine just under a commented line that contained the name of the old database. The command to add takes the following form:
    • USE my_database_name ;
  9. Select the newly created database in the phpMyAdmin tool.
  10. If you have not already done so, ensure that your host has finished creating the new database.
  11. Perform an import from the SQL file you saved and edited.
  12. Locate the wp-config.php file in the root directory of your WordPress installation on your server.
  13. Copy the wp-config.php file from your server to a place where it can be edited.
  14. Locate the commands for defining the following three variables:
    • define(‘DB_NAME’, ‘my_database_name’);
    • define(‘DB_USER’, ‘my_database_username’);
    • define(‘DB_HOST’, ‘my_database_hostname’);
  15. Duplicate each of the lines and comment out the first of each (use /* and */).
  16. Change the uncommented form of each assignment to use the appropriate name for the new database.
  17. Modify the ‘DB_PASSWORD’ value using the same method, if necessary.
  18. Save the file and copy it back to its original location on the host.
  19. Navigate to your website and see if the WordPress page works correctly.
  20. If everything looks like it’s working, try editing an existing post or adding a new post.
  21. Look at the listing of databases on your phpMyAdmin page. If you have successfully transitioned to using the newly created database, the interface should now show that it is storing more data than the older database did.
Posted in Tools and methods | Tagged , , | Leave a comment

Checking My Steam Table Functions

While I was working out a steam table page yesterday I found it necessary to graph the functions out as a means of verifying them.  Here’s the first graph I created in JavaScript.  It shows not only the curve of the enthalpy of saturated steam in BTU/lbm as a function of temperature in degrees Fahrenheit, but also color codes the section of curve that generated the number.  This shows me that there’s a minor hiccup at the beginning of the second section, in orange, which is something I’m going to have to look at.

My next project will be to turn the graph routines into a single object with cleaner interface functions. When that’s done I’ll plot out more of the functions I created.

Posted in Simulation | Tagged , , , , | Leave a comment

Steam Tables (and Thermodynamic Properties of Fluids In General)

A little while ago I was ruminating on the subject of needing to know the thermodynamic properties of materials before you could do simulations of those materials. I therefore figured I’d spend the week dusting off some old functions I’d written for the saturated thermodynamic properties of steam and implementing them as a web page using Javascript and jQuery. That work is proceeding but let me describe how I produced the functions themselves.


I started by using a curve fit program I’d written to develop functions of the thermodynamic properties of saturated water in its liquid and gaseous forms.  The fit program could also generate functions for the first three derivatives of the originally fit functions in many cases, although it was rare to ever employ more than the first derivative. In order to make reasonable curves I had to do the fits piece-wise over the applicable range of temperatures and pressures.  The resulting functions looked something like this:

The functions can be written more efficiently but this is the closest translation from the original Pascal.  If I chose to continue using these tools I would make them far more efficient.

Posted in Simulation | Tagged , , , , | Leave a comment

Learn Your Customer’s Culture

Every customer you work with will have an interesting variation in culture, and it’s good to get to know what they are. The differences may be merely interesting, may be motivating, or may be important to how you relate to them.

An early customer I worked with on a business process reengineering effort acknowledged that a certain amount of “slippage” was considered normal in the course of a workday. We were measuring the type, number, and duration of different activities in each type of employee’s work day and expected the total amount of process-related effort to total something less than 480 minutes (or less than eight full hours). Management understood that people needed time for administrative and personal activities to some extent and, since the employees’ activities could be readily quantified on an objective basis, the company had a good handle on what constituted acceptable performance. I’ve heard rougher stories about how employees can be treated in environments that are relentlessly driven by performance metrics, but this company had a good attitude and appeared to support the well-being of their employees. They proved to be easy to work with in the procedural sense, though they were difficult to work with in other ways.

One of the more interesting and motivating traditions I ever encountered was when I worked with the Royal School of Artillery at its home base at Larkhill, just a couple of miles from Stonehenge (I got up and ran there every other day). The location also figured in the plot of an interesting movie, though possibly only because I spent time there.

The Royal Artillery’s interesting tradition is that the artillery pieces themselves (cannons in the old days and everything from howitzers to air defense missiles today) nominally serve as the unit colors, in place of a formal flag or guidon. Even better, you were supposed to show respect to the equipment by always running toward it and always walking away from it. My opinion on such things has changed over they years but this remains a fascinating piece of psychology.

Industrial environments are shaded by companies’ approaches to market competition, safety, and location, among other things. I’ve been at a couple of steel mills where employees have been killed, in one case while I was working there. Management’s reaction has ranged from encouraging employees to nap during slow times to ensure they are fresh when things need to happen, to reviewing safety procedures and working to educate the employees further. Those efforts were of course in addition to trying to figure out exactly what went wrong in the first place. It is recognized that locations like caster decks are inherently dangerous, as is molten steel under any conditions.

Some companies run on a bureaucratic basis where employees may get paid the same no matter how the business performs, in which case the employees generally move at the same speed and level of effort no matter what may be going on. In companies where employees are incentivized based on a lower base wage but bonuses based on production and sales the employees from top to bottom are generally far more proactive and aggressive in their efforts to keep a plant running at top speed and fixing problems as soon as they occur.

Managers in bureaucratic environments are often more laid back in their approach to getting things done and my be more demanding in terms of documentation and ease of use, while managers in more aggressive and entrepreneurial environments will demand more features and quicker completion, if possible. Ideally you, as a vendor, will always try to provide the best possible product along every axis, but I know it can be tempting to hold out on customers who are troublesome and uncooperative. You may also be tempted to get out as soon as you meet the local manager’s minimum requirements.

In some ways the more adept managers and employees you meet in the field will be able to deal with lesser deliverables in terms of polish and completeness, since they will be able to bring more understanding and interaction to their end of the process. That actually does a disservice to the better workers and companies, who should get the best of what you have to offer. Over time, of course, you should be providing the best product and service you can by leveraging your own experience and the feedback you get from customers at all levels. Ask them for feedback and listen to what they tell you. Not every idea may be a winner but they’ll come up with a lot of things you won’t think of.

Posted in Management | Tagged , , | Leave a comment