<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Need more resources!]]></title><description><![CDATA[A collection of strange ideas from a software engineer.]]></description><link>https://feryance.com/</link><image><url>https://feryance.com/favicon.png</url><title>Need more resources!</title><link>https://feryance.com/</link></image><generator>Ghost 5.88</generator><lastBuildDate>Thu, 26 Feb 2026 20:06:52 GMT</lastBuildDate><atom:link href="https://feryance.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Software Project Cost]]></title><description><![CDATA[<h1 id="i-just-need-an-estimate">I Just Need An Estimate</h1>
<p>Throughout my career, it&apos;s been rare to be on a project where I am not asked for some sort of software estimate. No one likes estimating but I am diligent and do my best estimating how long developing something that I&apos;ve</p>]]></description><link>https://feryance.com/software-project-cost/</link><guid isPermaLink="false">6830ed503e558819b4159dec</guid><dc:creator><![CDATA[Daniel Feryance]]></dc:creator><pubDate>Fri, 26 Jul 2024 21:52:34 GMT</pubDate><content:encoded><![CDATA[<h1 id="i-just-need-an-estimate">I Just Need An Estimate</h1>
<p>Throughout my career, it&apos;s been rare to be on a project where I am not asked for some sort of software estimate. No one likes estimating but I am diligent and do my best estimating how long developing something that I&apos;ve never done before will take. But how are these estimates used? One common thing I&apos;ve seen is taking an hour estimate multiplied by some constant to determine the &quot;project cost&quot;. The constant is usually based off of loaded salaries and number of people involved. That dollar amount is not the cost of the project. It isn&apos;t that this number is off by some kind of factor, it is that it is almost unrelated.</p>
<p>So let&apos;s ignore the common issues when estimating. Ignore calendar time vs working hours time. Ignore staffing changes or priorities changing. Assume the features will be added in such a way to not accumulate technical debt. Let&apos;s assume the time estimate is 100% accurate (which happens 0% of the time). Can you now multiply it by a constant to get the cost? Nope!</p>
<h1 id="softwares-true-cost">Software&apos;s True Cost</h1>
<p>The obvious issue with this cost estimate is that hours isn&apos;t how salaries work. Software engineers are usually salaried. You pay staffing costs whether you take on a new project or not. You still have to pay them even if you give your engineers nothing to do. It also doesn&apos;t go up if they work overtime (usually exempt from overtime pay). Your cost isn&apos;t in hours. This is different for contractors, hourly employees, or companies with lots of turnover. But generally it isn&apos;t the case where you can decide not to do a $100K project and then have $100K left in the bank. Maybe if a project is 100% outsourced this can be close to true; there are always costs regarding managing the project internally though.</p>
<p>This gets into the issue of opportunity costs. Your staff probably won&apos;t sit around idle if you don&apos;t give the go ahead for a project. There are always other projects or features to do or to help with support or clean up technical debt. There is always more things to do than time. People like contributing and will do the best they can to make a difference. Unless you can massively change the number of staff you have quickly, taking on one project means you won&apos;t be doing any number of other projects in the same time. Delays, scope reduction, or cancelation of other work is part of the project cost. I&apos;ve been on a project providing a prototype / demo for something that would never be sold to anyone that left important and profitable work being delayed. That project cost a whole lot more than the wasted hours. Our main product was neglected during this time and we weren&apos;t in nearly as strong of a market position as we&apos;d otherwise be. Whoops!</p>
<h1 id="ongoing-future-costs">Ongoing Future Costs</h1>
<p>But probably the biggest factor in a project&apos;s cost is not the initial cost but future costs &#x2014; and I don&apos;t mean fixing the bugs you missed. While software design and source code are considered engineering details, they have a massive impact on the overall organization. If you asked me to add a feature to one application and to add the exact same feature to a totally different application, how long it would take would vary greatly. This is due to overall system structure, non-functional requirements, what other needs the software meets but also software complexity.</p>
<p>Complexity doesn&apos;t grow linearly. As an example, take an application with 4 different on-off settings. The possible number of setting combinations you could have is 16. If you add a new setting now you have 32. But if you do the same thing to an application that has 10 settings, you&apos;ve just added 1024 more possible combinations! This is a simplistic example but it has a profound impact in software development. Software complexity makes everything harder. It is harder for engineers to understand and work in. It is harder to test. There will be more bugs and surprise edge cases. Technical support is harder. Complexity is very expensive! Any time you add a feature, change a requirement, fix a bug, you are usually increasing the software complexity.</p>
<p>So unless you are just doing billable work for a customer where the customer pays the entire software maintenance cost, the cost of complexity is yours to bear. But don&apos;t worry, it gets worse than that. As your software gets larger and more complex, you&apos;ll have to increase staff. More people means communication becomes more difficult. You have more people who have to communicate with each other and miscommunications will be more common. You&apos;ll have more coordination costs and management costs for more staff. You will be paying the cost of a 2 week project years later.</p>
<p>There are likely even more aspects of software development costs that I haven&apos;t addressed. What is important to realize is that these costs are far more significant than the number of hours it takes to do a project. Project timelines matter for all sorts of things between making commitments to customers or investors, planning out when to do what, and prioritizing work. But the number of hours doesn&apos;t tell you much when it comes to knowing what a project will cost.</p>
<h1 id="dont-forget-about-profit">Don&apos;t Forget About Profit</h1>
<p>With all these gotchas when it comes to software cost, one thing is quite evident; developing software is very expensive. This is why it is important to do proper analysis on features and projects. Work on things that are valuable to all customers. I&apos;ve been on a number of projects that have been canceled or cut short. This is incredibly expensive. One of the most expensive things you can do is to tell developers to just &quot;make it all work&quot;. You have to prioritize.</p>
<p>So it is understandable to care about software costs and to look at these details. But it is a mistake to just take hours, multiply by some constant, and then compare it to expected revenue. Managing a business is much harder than that.</p>
<p>The upside is that the benefits of software can be way beyond the initial project too. A project that might be for one customer could potentially be sold to other customers. Or maybe it could be modified in a future project to be more generally useful. This is the business of software; develop it once, sell it everywhere. So if you are developing a product and you really need to know exactly the cost to know if it will be profitable, then you are in a very bad position indeed. It means the amount of profit you expect to get from it is very limited. Maybe consider a different product or approach.</p>
]]></content:encoded></item><item><title><![CDATA[Name Your Subexpressions]]></title><description><![CDATA[<h2 id="complicated-logic">Complicated Logic</h2>
<p>Everyone likes to joke about how they don&apos;t use any of the stuff they learned in college. This isn&apos;t the case for me. There is some I use and some I don&apos;t. One thing I learned pretty well is how to simplify</p>]]></description><link>https://feryance.com/name-your-subexpressions/</link><guid isPermaLink="false">6830ed503e558819b4159deb</guid><dc:creator><![CDATA[Daniel Feryance]]></dc:creator><pubDate>Thu, 11 Jan 2024 19:28:04 GMT</pubDate><content:encoded><![CDATA[<h2 id="complicated-logic">Complicated Logic</h2>
<p>Everyone likes to joke about how they don&apos;t use any of the stuff they learned in college. This isn&apos;t the case for me. There is some I use and some I don&apos;t. One thing I learned pretty well is how to simplify expressions and reason about boolean algebra. I use this most days in programming to verify that my code is correct and to simplify expressions. One common trick I use is to distribute a negation operator to an expression using De Morgan&apos;s theorems in order to cancel part of it out. Very handy!</p>
<p>What math won&apos;t tell you is why is code the way it is; what is the intent the programmer had while writing it. While maintaining and modifying code I sometimes run across some very complicated logic. Maybe this is a large &quot;if&quot; statement with lots of terms or nested &quot;if&quot; / &quot;else&quot; blocks. There is only so much boolean algebra can do to simplify this. Sometimes code is complicated because the problem being solved is complicated.</p>
<h2 id="example">Example</h2>
<pre><code>if (features[var1].status == &apos;e&apos; &amp;&amp; ((uid == &apos;0&apos; &amp;&amp; config.env == &apos;l&apos;) || 
user.flags.indexOf(&apos;call2&apos;) &gt;= 0) &amp;&amp; !(settings.flag2 || status == 3)) {
}
</code></pre>
<p>This code&apos;s boolean logic is actually pretty simple. But to understand code like this you have to understand the context. What do these variables mean, where is it used?</p>
<p>Once you figure this out, here are my tips on how to make the code easier to understand for both yourself and other programmers. Certainly you should consider boolean algebra to simplify any complex expressions. Also consider naming the magic numbers here too. But you should also name the subexpressions.</p>
<h2 id="subexpressions">Subexpressions</h2>
<pre><code>const isFeatureEnabled = features[var1].status == &apos;e&apos;;
const isRoot = uid == &apos;0&apos;;
const isLocalEnvironment = config.env == &apos;1&apos;;
const isUserEntitledToCall2 = user.flags.indexOf(&apos;call2&apos;) &gt;= 0;
const isSpecialCustomer = settings.flag2;
const isServiceDisabled = status == 3;
</code></pre>
<p>Try not to get hung up on the naming convention here. Some people like more terse names, some like it more spelled out. The point is to give names to these expressions by assigning them to a variable. Another possibility is to extract some of them to a function. This is naming it too.</p>
<pre><code>function isLocalEnvironment(config) {
</code></pre>
<p>Now we can put all these named subexpressions back into the conditional.</p>
<pre><code>const hasPermissions = (isRoot &amp;&amp; isLocalEnvironment(config)) || isUserEntitledToCall2;
if (isFeatureEnabled &amp;&amp; hasPermissions &amp;&amp; !(isSpecialCustomer  || isServiceDisabled )) {
</code></pre>
<p>Notice I added another variable for part of the remaining expression. Here hasPermissions is introduced to simplify the permission check.</p>
<p>Is this code right or wrong? That&apos;s always difficult but by naming these subexpression we now have a chance to analyze it. First we see if all the variables are checking the values they should. The definition for &quot;isServiceDisabled&quot; seems suspect. Maybe there are other statuses that are possible that should be checked. Or maybe it is ok. The point is we can check small parts of it without mental overload.</p>
<p>Then we can also check the main &quot;if&quot; statement. Are the &quot;and&quot;s and &quot;or&quot;s and &quot;not&quot;s right? That too can be checked piecemeal.</p>
<h2 id="comments">Comments</h2>
<p>I&apos;m never going to object to adding more comments to code. It is rare to encounter code that has been well documented. So it wouldn&apos;t be a bad thing to add comments to the &quot;if&quot; statement as well. But it is better to simplify complicated things than to document it. Add comments for knowledge that the code doesn&apos;t immediately provide.</p>
]]></content:encoded></item><item><title><![CDATA[Thoughts on Unit Testing]]></title><description><![CDATA[<p>Back when I was a new engineer out of college, I was excited about automated unit testing. It makes sense to use a computer, which is good at performing repeated operations quickly, for testing that the software works or that it still works. I still hold out hope for automated</p>]]></description><link>https://feryance.com/thoughts-on-unit-testing/</link><guid isPermaLink="false">6830ed503e558819b4159de9</guid><dc:creator><![CDATA[Daniel Feryance]]></dc:creator><pubDate>Wed, 17 Nov 2021 19:13:33 GMT</pubDate><content:encoded><![CDATA[<p>Back when I was a new engineer out of college, I was excited about automated unit testing. It makes sense to use a computer, which is good at performing repeated operations quickly, for testing that the software works or that it still works. I still hold out hope for automated unit testing, but it is not the miracle it feels like it could be. It is good for catching some bugs and hopeless for others.</p>
<h1 id="extremes">Extremes</h1>
<p>In my career I&apos;ve met engineers who thought unit testing was a waste of time. They thought it took too long to write, didn&apos;t catch all that much, and was busywork. This is a bad dismissive attitude. You must try a practice and give it a chance to see where it works best. As developers we have powerful computers at our disposal, it isn&apos;t a good use of resources to manually poke through code for every release to test it. Computers are good at this sort of thing.</p>
<p>I&apos;ve also met engineers who were at the other extreme. All code must have unit tests, target 100% code coverage, or maybe write your unit tests first. This also is crazy. Not all code equally benefits from unit tests. You are better off concentrating your efforts on unit testing code where you get the most value than to try to do everything. I&apos;ve never worked on a project where everything was specified ahead of time to be able to write tests before code. Engineering is generally more fluid than that. If you are working on a strict waterfall maybe this is possible, but that sounds like a terrible project to be on.</p>
<h1 id="what-works-well">What Works Well</h1>
<p>Algorithms and data structures often benefit from unit tests. It is great when working with a reversible algorithm as it is a simple test write to apply and reverse and can catch a great number of problems. Some algorithms are very complex to solve a problem but also very simple to check. Algorithms and data structures tend to be more isolated code. They don&apos;t generally depend on your database server, some web service, or operating system calls. So, there isn&apos;t much work needed to test them in isolation.</p>
<p>Really any problem that you can throw a ton of data at it and can validate its behavior with the data works well for a unit test. From a single unit test, you can try a large number of conditions.</p>
<p>For one project I had to design an algorithm that would significantly change the data storage format of what was essentially simplified program code. Unit testing worked well on that. Give the algorithm different scenarios and make sure it handles them ok. Apply the transformation and reverse it and verify that it reverses ok. This found a ton of bugs out of a small list of unit tests.</p>
<h1 id="what-doesnt-work-well">What Doesn&apos;t Work Well</h1>
<p>Sometimes the kinds of problems that introduce the largest number of bugs also are the hardest to unit test. Integration with another software system or with hardware often behaves vastly different than you think it will or has been specified to behave. These kinds of bugs tend to show up when code is moved to production, and you probably won&apos;t have logging around the unexpected integration behavior because it is unexpected.</p>
<p>What is or isn&apos;t integration testing vs unit testing isn&apos;t something everyone agrees on. But a common technique for isolating modules is to mock out the integration points. The same assumptions you made when writing your code will also be put into the mocked objects and unit tests. You are then testing that your code handles the way you think the integration behaves and not how it behaves. This can catch some issues, but the most difficult bugs that it would be great to catch slip through.</p>
<p>These kinds of bugs of missing information, false assumptions or not realizing something could behave a certain way are quite expensive. Unit tests may catch them by accident or when working on unit testing you suddenly realize something could happen. But in general, they aren&apos;t great for this.</p>
<h1 id="dont-only-do-unit-testing">Don&apos;t Only Do Unit Testing</h1>
<p>One bug I had to deal with that was very frustrating was in an interrupt handler for a input pin. On occasion, my microcontroller would just reset (probably watchdog or other check). I eventually traced it down to the timing of the input pin. The code I was running was a scripting language and the interpreter would fail out it the interrupt was triggered faster than it could run the script. This failed for even an empty interrupt handler.</p>
<p>This is an obvious case where unit testing won&apos;t catch the problem at all. Mock out an input pin? Well, the mocked code would always work. It wasn&apos;t a code logic issue, the problem happened even when the interrupt handler was empty.</p>
<p>This may seem obvious, there are many more QA practices than unit testing because there are all sorts of bugs in software. The best way to mitigate bugs is through multiple approaches. Don&apos;t spend so much time on code coverage and unit tests that you don&apos;t get to other forms of testing, review, or QA practices. Depending on the project you are working on, maybe the other QA practices are more valuable. Every project is different.</p>
<p>100% of code coverage also isn&apos;t a good target. How many possible states are you testing? Are edge cases covered? These kinds of problems are hard for your brain to think about at the same time and more likely to have bugs. If you are concerned about validating every line of code, it is better to use code reviews for that.</p>
<h1 id="use-your-debugger">Use Your Debugger</h1>
<p>I&apos;ve seen an odd mentality in software developers lately that there is a view that using a debugger is lazy and you should be unit testing and using logging. This seems to go along with the increase in cloud computing where debugging a running application is either difficult or simply not possible.</p>
<p>Yes, write unit tests! Yes, use log files! But a debugger is a wonderful tool to find bugs! Learn your debugger well. Hopefully it has something like a REPL where you can execute code snippets while you are running your program. Avoid development tools or languages that don&apos;t have a good debugger. Shipping code because the unit tests all pass isn&apos;t far removed from shipping code because it compiled. Great, it can catch some things, now finish testing it.</p>
<p>Sometimes it takes looking at a scenario in a debugger for the actual cause to be apparent. Code is complex, it is hard to keep all the possibilities in your head. This is even harder when digging through logs or writing unit tests. Sometimes it really helps to see what is going on.</p>
]]></content:encoded></item><item><title><![CDATA[Tips for Effective Code Reviews]]></title><description><![CDATA[<p>Here is my list of common mistakes from code reviews and ideas of how to improve. This isn&apos;t comprehensive; just a few things I often run into. While I&apos;ve seen plenty of ineffective code reviews, I still feel strongly about their potential value. Real issues are</p>]]></description><link>https://feryance.com/tips-for-effective-code-reviews/</link><guid isPermaLink="false">6830ed503e558819b4159ddb</guid><dc:creator><![CDATA[Daniel Feryance]]></dc:creator><pubDate>Wed, 13 May 2020 13:55:05 GMT</pubDate><content:encoded><![CDATA[<p>Here is my list of common mistakes from code reviews and ideas of how to improve. This isn&apos;t comprehensive; just a few things I often run into. While I&apos;ve seen plenty of ineffective code reviews, I still feel strongly about their potential value. Real issues are found even in problematic code reviews. There are many different practices that are helpful for ensuring code quality and I still recommend trying code reviews where possible.</p>
<h1 id="including-managers">Including Managers</h1>
<p>Including managers in a peer review is probably the most common mistake I&apos;ve seen. The downsides aren&apos;t obvious and sometimes including management just feels like the right thing to do. Having managers in code reviews is very tempting for many reasons. One common concern managers have is trying to keep track of how a project is going, what work is in progress, and how well their engineers are performing. Code reviews sound like a great way to accomplish that. Also, code reviews can bring out different team problems and personal conflicts so it is understandable for managers to want to be involved in order to monitor and deal with them.</p>
<p>Theses reasons are legitimate and understandable but they also make code reviews much less effective. There are plenty of other ways managers can look at team performance and the system source code. As the primary focus of a review should be finding bugs, anything that gets in the way of that needs to be avoided. Code reviews can be expensive as it includes several other engineers to look over each other&apos;s work. It is important to make them as useful as possible.</p>
<p>Having managers in a review meeting transitions it from a honest evaluation to a situation where making a good impression matters. It could be said that engineers should be professional and shouldn&apos;t think like that, but I don&apos;t think that is fair. Human behavior is surprisingly predictable. We often behave different in front of authority or someone important than how we behave otherwise. Just like how professionals don&apos;t air their dirty laundry in important meetings or in public, engineers are careful about what they say in front of management in review meetings as well.</p>
<p>It can be daunting to go through code review. The author of the code likely spent days or weeks working to get things right and everyone else is trying to pick it apart. If this is done in front of his / her manager, this can create a perilous situation. Even if everyone has the best intentions, presenting flaws in someone&apos;s work in front of their manager can go over very badly.</p>
<p>So one thing I&apos;ve seen myself do in code reviews is tell the author about defects outside of the review meeting. This was when I found a simple / dumb mistake that I thought would look bad. This isn&apos;t good process because it should be a team effort to look over defects found and analyze them. But reviews should be about the positive effort of making the work better and I didn&apos;t want embarrassment to be part of the process.</p>
<p>Another problem that can happen in review meetings is to nit-pick issues or try to make things look worse than they really are. This too is unfortunately common human behavior when people aren&apos;t getting along. Sometimes having a manger involved in the process increases the likelihood of this happening; now appearances matter. So if an engineer thinks another engineer is doing a bad job, he or she has the strong inclination to make them appear that way in code review in front of management.</p>
<p>Ultimately the end result of engineering is what matters most. The details of getting there sometimes can be ugly. A good engineer should want lots of defects to be found in review. This means they are caught before end users can encounter them. It is hard to keep this focus when you are being watched and evaluated. Sometimes the best engineers make the most mistakes because they work on the hardest and trickiest part of the project. So having management there keeping an eye on things can give the exact wrong impression of the quality of engineering being performed.</p>
<h1 id="moving-along-after-quick-approvals">Moving Along After Quick Approvals</h1>
<p>Ensuring that review feedback comes back from all reviewers is usually a challenge. There is always a lot going on in a project and the last thing someone needs is more work of looking over someone else&apos;s tasks. For code reviews to be successful they have to work around people&apos;s busy days.</p>
<p>What happens is that the people who look over the code with the least amount of detail and care are also the most responsive to getting their reviews in. In software-driven reviews, this results in a quick &quot;accept&quot; and in meeting reviews this results in the reviewer claiming to be ready but having no real understanding of the code. It is easy to just give up and go ahead with a code review with the few people who have said they looked over it. This turns code reviews into rubber stamps. The slow people are the most valuable to code reviews &#x2014; wait for them.</p>
<p>This makes things difficult. If reviews wait on people who are slow to come up with feedback, things may never move. I don&apos;t think there is any simple solution to this. Sometimes this can be caused by procrastination. But what is worse than procrastination is not taking reviews seriously.</p>
<p>An effective review has everyone who is most suited for finding bugs in the type of code being reviewed present and having spent time in looking for them. Don&apos;t give up on this goal even though sometimes allowances have to be made. Don&apos;t let code reviews switch to having the least attentive people rubber stamp it. There is little point in these kinds of code reviews.</p>
<h1 id="omitting-omissions">Omitting Omissions</h1>
<p>The usual way to to review code is to compare the new version to the old one in version control. Most tools have a way to pull up a difference showing the lines that were added, removed and changed. Some of the best ones allow for tagging lines with comments to track issues exactly where the are in the code. This usually works great but the routine makes it easy to forget to look for omissions.</p>
<p>A diff viewer only shows you what changed &amp;mdash not what should have changed. I don&apos;t know of any good way to determine what should have changed beyond experience with the code or just general software engineering experience. So there is no way to prescribe a fix for this common problem. The best I can say is to look out for it. Try to get into the mindset when reviewing code to look around at unchanged code and try to think about what could be missing.</p>
<p>I&apos;ve seen plenty of bugs in testing or production due to simple errors of omission. These are things that went through code review, weren&apos;t too complicated or involved to find, but were simply missed because they don&apos;t show up in a version control compare. Watch out!</p>
<h1 id="coding-standard-reviews">Coding Standard Reviews</h1>
<p>Different organizations can have different opinions regarding the value of having coding standards. If a project has a coding standard, there needs to be automated tools for checking it. It is a waste of code review time trying to find things that violates the coding standard. These kinds of inconsequential issues distract from finding real problems. In situations where automated standard checking tools aren&apos;t available, don&apos;t address coding standard problems beyond a single line item that standards compliance needs to be addressed. Log that and move on. Don&apos;t waste people&apos;s time in trying to compare coding styles against a coding standard. It is a distraction and makes code reviews slow and dreaded.</p>
<h1 id="including-optional-reviewers">Including Optional Reviewers</h1>
<p>I think there is plenty of room to be flexible on this, but it is good to try to avoid having optional reviewers. One potential benefit of code review is to help other people get up to speed with the code and learn about a project that they haven&apos;t been involved in. This means it is tempting to include anyone who may benefit from learning the system. This too can distract from having an effective code review.</p>
<p>One challenge to code reviews is ensuring the reviewers have looked over the code as in-depth as is reasonable. As soon as other people are included in the meeting that are there for other purposes, things can go down the slippery slope where rigor becomes optional. Having people involved that don&apos;t know the system can also slow down the process by asking obvious questions that could be dealt with in a one-on-one discussion rather than with the whole team.</p>
<h1 id="getting-off-track">Getting Off Track</h1>
<p>The overriding theme here is that code reviews are important and anything that distracts from finding defects should be minimized and avoided. It is possible to be too strict and take things too far, but usually the opposite is the problem. It takes care and discipline to have an effective review but the results can make the difference between a failed product and something solid and stable for years to come.</p>
]]></content:encoded></item><item><title><![CDATA[Timex Datalink]]></title><description><![CDATA[<p>When I was a kid I loved the different Timex sports watches. It was some of the coolest technology at the time to have a small microprocessor running on your wrist. I don&apos;t know when I first saw an ad for the Timex Datalink watch but I knew</p>]]></description><link>https://feryance.com/timex-datalink/</link><guid isPermaLink="false">6830ed503e558819b4159dd8</guid><dc:creator><![CDATA[Daniel Feryance]]></dc:creator><pubDate>Sat, 18 Feb 2017 01:36:12 GMT</pubDate><content:encoded><![CDATA[<p>When I was a kid I loved the different Timex sports watches. It was some of the coolest technology at the time to have a small microprocessor running on your wrist. I don&apos;t know when I first saw an ad for the Timex Datalink watch but I knew I had to have one. My first Datalink watch was a gold-colored 150 model. It was large, gold, and shiny and I was proud to show it off.</p>
<p>The original Timex Datalink watches used a small IR sensor on the front that would read serial data sent to it from a computer. The computer would flash a bunch of white lines on your CRT monitor with a specific timing rate while you held the watch up to the screen. This took advantage of the CRT refresh timings with some clever programming. It was fun to watch the white bars go across and hear the beeps of the watch reporting that it got the data. There is even a patent with drawings on how this works: <a href="https://www.google.com/patents/US5652602?ref=feryance.com">https://www.google.com/patents/US5652602</a><br>
<img src="https://patentimages.storage.googleapis.com/pages/US5652602-2.png" alt loading="lazy"><br>
<em>Datalink Patent Drawing</em></p>
<p>The original Datalink watches were limited in terms of I/O. Things like Bluetooth or high-resolution displays weren&apos;t possible at the time. This meant that the things to experiment with were mostly limited to setting alarms and adding appointments. Despite this, it was awesome and completely worth it!</p>
<p>In some sense the Datalink was the first smart-watch but it totally depends on your definition of smart-watch. The CRT monitor programming trick was a real wireless link even though it required line-of-sight and was single-directional. The Timex / Microsoft (yeah Microsoft was involved) software provided a simple GUI for inputting your watch data.</p>
<p>Timex later released a Datalink watch that had a USB connection. This allows two-way communication. So if you change something in your watch, it can sync back to the computer. It also had software that would allow for Microsoft Outlook synchronization. Having a USB connection was much nicer but there is still something awesome about reading lines flashing on the monitor.</p>
<h1 id="my-collection">My Collection</h1>
<p>Lately, I&apos;ve dug up my own Datalink watches and gotten the urge to get them back running again. Sadly, my original 150 watch has problems with it that I haven&apos;t been able to repair yet. The LCD zebra strips either have a fault or the connection pads aren&apos;t making good contact. This means some segments of the display don&apos;t work. I also happened to bend the back of the watch-case which damaged the peizo element when trying to open and close the watch. I must have opened and closed it too much and too hastily while working on repairing the LCD.</p>
<p>My original USB Datalink is in fine shape and I bought several other Datalink watches off of ebay to make up for my broken 150. Here is what my current collection looks like.<br>
<img src="https://feryance.com/content/images/2017/02/watches.jpg" alt loading="lazy"></p>
<p><em>My Datalink collection. The order of the watch models from left-to-right are: 70, Ironman, 150, 150s, Ironman USB.</em></p>
<h1 id="running-mcu-code">Running MCU Code</h1>
<p>I haven&apos;t done much with programming the MCU on the watches. Some clever programmers did some work to reverse-engineer the original Datalink watches but Timex was nice enough to release a SDK for the Ironman USB (<a href="https://assets.timex.com/developer/datalink/?ref=feryance.com">https://assets.timex.com/developer/datalink/</a>). There aren&apos;t a lot of good use-cases for writing code for these watches due to the limited MCU and LCD. It still could be fun to tinker with.</p>
<h1 id="serial-programming">Serial Programming</h1>
<p>Because CRT monitors aren&apos;t common anymore and it depended on some really old software, it is quite a challenge to have a good system to program the Datalink watches. Timex had a laptop adapter they made in order to program the watches on a laptop that had an LCD screen. The adapter has a serial port connector along with a LED that blinks with the same timing that the CRT would. These adapters are in high demand and often go for a large amount of money on ebay.</p>
<p>While it would be possible for me to reverse engineer the CRT programming timing for the Datalink and try to reproduce it, it is much easier to go off of the work of others. The difficulty there is many of the early Datalink interest web pages don&apos;t exist anymore. Thanks to the Internet Archive I was able to find code that someone wrote that talks to the watch via a LED attached to a serial port. I got this partially working but it was pretty flaky and would often result in programming errors.</p>
<p>After a desperate attempt at scouring the web for a solution, I finally found something that didn&apos;t require me to do significant work from scratch. There is a very nice github repo of <a href="https://github.com/dfries/datalink_ironman?ref=feryance.com">https://github.com/dfries/datalink_ironman</a> that not only includes a Linux application for talking to the serial port for programming the watch but also a MCU application for running on the Teensy (<a href="https://www.pjrc.com/teensy/?ref=feryance.com">https://www.pjrc.com/teensy/</a>) board. Unlike the serial port to LED connection, this has run really solid for me. It is a near-perfect programming solution.</p>
<p>Running the datalink_ironman code on a Teensy is quite a bit cheaper than trying to acquire a Timex official laptop adapter off of ebay. Also because it works with a Linux command-line application instead of the Windows 3.1 GUI application is is much more useful and versatile too.</p>
<p><img src="https://feryance.com/content/images/2017/02/teensy.jpg" alt loading="lazy"><br>
<em>Teensy Datalink programming cable. Not as fun as a CRT but it works!</em></p>
<h1 id="more-restoration">More Restoration</h1>
<p>I&apos;m not sure yet how much more I will do with my Datalink project. Some of the watches I got off of ebay came in pretty bad shape. I&apos;ve replaced the wrist straps of all of them. I tried to match the original wrist straps as much as possible but that is really hard to find. The 150 / 150s has a nice glass lens but most of the watches are plastic lenses. I&apos;ve been successful at polishing the scratches out of the plastic though and have a nice shine.</p>
<p>I haven&apos;t decided if I am going to try to attempt a paint restoration on the watches that has had paint has worn off. It is pretty impossible for me to match the existing color but I might be able to find something close. There is always the risk I will end up with a paint job that I am unhappy with and am unsure what to do.</p>
<p>I still have a chance to resurrect my old 150 watch. This has nostalgia and emotional appeal to me but has been quite frustrating so far. The zebra strips for the LED are flaky but I might be able to find a way to get contact with some really delicate work. It should be possible to bend the watch back into mostly the original shape but the piezo element is completely damaged. I haven&apos;t yet figured out if I can re-use a piezo disc element and find a way to mount it on the back of the watch cover.</p>
<p>Not only are the old Datalink watches cool from a nostalgia perspective, they are just generally interesting technology. They also easily outmatch today&apos;s smartphones as they can run for years on the same 3-volt battery. They don&apos;t deserve to be lost to history. Maybe someday something similar will be made again.</p>
]]></content:encoded></item><item><title><![CDATA[The Misunderstood Conditional (Ternary) Operator]]></title><description><![CDATA[<p>Most languages that come from a C background include a single conditional ternary operator with a syntax of <code>exp ? true_val : false_val</code>. This operator is often maligned and it is common to see its use prohibited in coding standards. Like all programming language features it can be abused at</p>]]></description><link>https://feryance.com/the-misunderstood-conditional-ternary-operator/</link><guid isPermaLink="false">6830ed503e558819b4159dd7</guid><dc:creator><![CDATA[Daniel Feryance]]></dc:creator><pubDate>Fri, 10 Feb 2017 03:18:56 GMT</pubDate><content:encoded><![CDATA[<p>Most languages that come from a C background include a single conditional ternary operator with a syntax of <code>exp ? true_val : false_val</code>. This operator is often maligned and it is common to see its use prohibited in coding standards. Like all programming language features it can be abused at times but it absolutely has its place in well-written code.</p>
<h1 id="other-languages">Other Languages</h1>
<p>The idea of conditional operator is not unique to C and is common in functional programming languages. Some of the dislike for the conditional operator stems from preferring statement-based programs over expression ones. So the &quot;if&quot; statement feels just right and simple to someone thinking step-by-step when writing a procedural program. However, a conditional operator feels right at home to someone writing in a functional language. This is actually a good argument to avoid it in C code. C programmers don&apos;t generally write code doing a lot of complex work in expressions.</p>
<p>It is important to realize that dislike for this operator is a stylistic and background preference and not something inherently bad about its use. In this post, I provide an example of the use of the ternary operator that I think should both be comfortable to procedural programs as well as fitting an important need that other C constructs don&apos;t handle well.</p>
<h2 id="lisp">Lisp</h2>
<p>In Lisp, the equivalent of the conditional operator is the &quot;if construct&quot; <code>(if (exp) (true_action) (false_action))</code>. Lisp isn&apos;t a pure functional language so this is often used in the same way the C &quot;if statement&quot; is. The major difference is that this is actually an expression so the true and false condition values are what the expression is evaluated to. This means it can be assigned to variables or passed to functions exactly the same way the C conditional operator can. So while it is named &quot;if&quot;, it has way more in common with the conditional operator than a C &quot;if&quot; statement.</p>
<h2 id="f">F#</h2>
<p>F# continues the trend of having &quot;if&quot; be an expression.</p>
<pre><code>if exp then true_value  
else false_value
</code></pre>
<p>Like lisp this is often used like an &quot;if&quot; statement is, however it has a value and can be used like any other value or expression.</p>
<h1 id="bad-usage-patterns">Bad Usage Patterns</h1>
<p>C expressions can be quite powerful and contain things that can be confusing and unexpected. People learning C for the first time all run into the &quot;=&quot; being an expression. This means you can have code like <code>if (a = 1)</code> be completely valid but totally the wrong. Also, the ability for integers and pointers to be treated as boolean can cause for confusing expressions. This allows for some nice terse usage patterns but runs the risk of getting too clever and being confusing. Of course operator precedence is also a common trap. When combined with these other behaviors of C expressions, conditional operators can be used to make them even harder to understand.</p>
<p>When trying to fix non-working code, it is easy to just slip in a conditional operator to try to fix it in as few changes as possible.</p>
<pre><code>int count = strlen(a);
</code></pre>
<p>Later on becomes</p>
<pre><code>int count = a ? strlen(a) : 0;
</code></pre>
<p>Which later on becomes</p>
<pre><code>int count = a ? (strcmp(a, &quot;undefined&quot;) ? strlen(a) : -1) : 0;
</code></pre>
<p>It isn&apos;t hard to see how this can quickly slip in everywhere in the code making things a mess. Keep in mind, this is just bad usage of the ternary operator. Anything can be abused and it isn&apos;t intrinsically bad. As mentioned above, it is often used in other programming languages without issues.</p>
<h1 id="lets-do-this-right">Let&apos;s Do This Right!</h1>
<p>Ok so how do we use the conditional operator in a way that isn&apos;t confusing and fits in well with C-derived languages? The conditional operator can help with some usage patterns where other language features don&apos;t work as well or have limitations. I&apos;m going to present an example of how this operator can be used as a better alternative to a switch statement.</p>
<h2 id="switch-case">Switch / Case</h2>
<p>The switch statement is one of the odder programming language constructs in C. Being able to map one value to another one or to an action is a common need. But the switch suffers from odd syntax, needs lots of &quot;break&quot; statements and is a little tricky and error-prone.</p>
<p>Here is a simple example of a switch statement</p>
<pre><code>int result;
switch (val) 
{  
   case 0 :
     result = 5;
     break;
   case 1 :
     result = 20;
     break;
   case 2 :
     result = 100;
     break;
}
</code></pre>
<p>This has a myriad of issues:</p>
<ul>
<li>It is verbose; the extra &quot;break&quot; statements, the curly braces all make a simple numeric mapping large.</li>
<li>It is easy to miss a &quot;break&quot; statement. This is such a common mistake that C# goes to far as to require a &quot;break&quot; statement or the code won&apos;t compile.</li>
<li>The type of variable you switch on must be integral or an enum. This rules out doing string comparisons or comparing on other common data types. This is very constraining when coming from other programming languages that don&apos;t have these limitations.</li>
<li>The values you compare with case must be constants.</li>
<li>In this example, it isn&apos;t possible to make the &quot;result&quot; variable const. Not everyone values using &quot;const&quot; as much as I do, but for those of us who do, this is a big deal.</li>
<li>There are no compiler checks that &quot;result&quot; has been defined by one of the case blocks. Omitting the default block is fully allowed. It is also possible to have the case blocks forget to assign a value to &quot;result&quot;.</li>
</ul>
<p>So here is a nice alternative</p>
<pre><code>const int result = val == 0 ? 5 :
                   val == 1 ? 20 :
                   val == 2 ? 100 :
                   (assert(false), 0);
</code></pre>
<ul>
<li>This code is much smaller than the switch statement</li>
<li>The formatting clearly shows it is a mapping from the left to the right value. One can view it as <code>0 =&gt; 5</code>, <code>1 =&gt; 20</code>, <code>2 =&gt; 100</code> and it isn&apos;t too far off from the actual code syntax.</li>
<li>The code can use const if desired (yes please!)</li>
<li>You will get a compile-time error if you don&apos;t specify a default value.</li>
<li>This pattern works with types other than integers and works with comparisons other than simple value equality.</li>
</ul>
<p>The formatting of this code is critical. Without the spacing and alignment this can be formatted to look confusing. I have also seen people format something similar except with the &quot;:&quot; on the start of the following line rather than at the end of the current line. This is just as clear but I, personally, prefer it on the end of the same line.</p>
<p>I can understand objections to the use of the comma operator with the assert. It is a bit of a trade-off. For those who don&apos;t know, the assert will be evaluated and the &quot;result&quot; expression will get the value of 0. This is just my little touch and isn&apos;t required. It is possible to simply have a valid default value. Another nice option (in C++) is to call a templated function that throws an exception. The template is needed to be able to write one function to match any expression type. Just keep in mind that the comma trick isn&apos;t required and shouldn&apos;t be an objection to the overall pattern; I wanted to show how flexible it can be.</p>
<p>One downside of this pattern compared to the switch statement is usually compilers can use a jump table to optimize the switch statement. This is why the switch only supports integers. In theory, a compiler could use one here as well, but it is a harder optimization to make. So this is a case where performance could be slightly impacted in exchange for code clarity.</p>
<p>Unlike switch statements, this doesn&apos;t have the ability to fall through the case blocks. I don&apos;t think this is usually a problem. As noted, the C# language requires &quot;break&quot; statements as fall-through isn&apos;t supported. It isn&apos;t something that I usually miss but am noting it as it is something switch has the upper-hand on &#x2014; when done intentionally at least.</p>
<h1 id="conclusion">Conclusion</h1>
<p>While not perfect, I think the example I show is a good use of the conditional operator. It is clear, flexible, and reasonably simple. I don&apos;t remember where I have seen code similar to this before but there aren&apos;t a lot of examples of it online. I think this is a great use of the conditional operator and encourage it to be used instead of switch statements or &quot;if&quot; chains where it makes sense. Even for the unconvinced, hopefully this at least showed some merit for this technique and that conditional operators don&apos;t have to be contributing to confusing code.</p>
]]></content:encoded></item></channel></rss>