C. Keith Ray

C. Keith Ray writes about and develops software in multiple platforms and languages, including iOS® and Macintosh®.
Keith's Résumé (pdf)

Tuesday, December 23, 2014

myGraph is free for Christmas

myGraph by Sizeography, the app that prints graph paper, is free for Christmas and from now (Dec 23, 2014) until the end of the year. Free!

Besides printing standard kinds of grids and graph paper, you can customize the colors, spacing, and line-width. Do you want green and red? You can have it.

Check it out!


Monday, December 8, 2014

Readable Code

Recently, I needed to change a scalar variable into a stack, as I modified my code to handle a new feature. Here's what I did.

First, I looked to see if the libraries I had access to contained a Stack class. (Apple's Foundation framework, etc.) I didn't find one. Nor did I find 'push' and 'pop' methods.

I could have changed the variable to an NSMutableArray and used these two methods instead of 'push' and 'pop':

- (void)addObject:(id)anObject;  // adds to the end of the array
- (void)removeLastObject;  // removes from the end of the array

Functionally, those two method would serve as 'push' and 'pop', but it would be easy for future-me, or another member of the developer team, to forget that the object is supposed to be used like a stack.

One option would be to add methods to the NSMutableArray class via a class category. That would allow my code to call 'push' or 'pop' but still doesn't clearly express my intent for this variable (which would still be declared as an NSMutableArray.

Since a basic stack is very easy to construct, I built one very quickly with just the API that I wanted. This is a common enough "demo" of Test-Driven-Development that I'm not going to reproduce it hear.

One thing did come up: I will sometimes want to display the contents of the entire stack, and I don't want to push/pop everything to do so. So I added another stack test and another method to my stack class.  Since I know the stack will be small (less than 30 objects), I return a copy the internal array storage, rather than returning an enumerator for the caller to access elements one-at-a-time.


-(void) testContents
{
    [stack push: @"a"];
    [stack push: @"b"];
    [stack push: @"c"];
    AssertEqual(3, [stack count]);
    NSArray *arr = [stack contents];
    AssertEqual(3, [arr count]); // calling contents doesn't pop.
    AssertObjectsEqual(@"a", arr[0]); // oldest
    AssertObjectsEqual(@"b", arr[1]);
    AssertObjectsEqual(@"c", arr[2]); // newest - top of stack

}

...
-(NSArray *) contents
{
    return [_storage copy];

}
...

Getting the data in this order (from the bottom of stack to the top of stack, is precisely what I want, since I be displaying the contents horizontally in the UI. 

But... I think 'contents' isn't clear enough. So I renamed the method:

-(NSArray *) contentsBottomUp
{
    return [_storage copy];

}

And, for symmetry, I added another method (and test) to return stack contents top-down instead of bottom-up. While not strictly needed for the current UI. I might want to display the stack contents vertically, and then I'd want the display the top first, and the bottom last.

-(NSArray *) contentsTopDown;

Since I didn't find a 'reverse' method in the Foundation framework either, I needed to implement a way to reverse the contents being returned from 'contentsTopDown'. While looking for examples of code using Apple's 'Fast Enumeration' implementation, I found this one-liner in NSHipster's blog:

-(NSArray *) contentsTopDown;
{
    return _storage.reverseObjectEnumerator.allObjects;
}

The end.

Monday, November 17, 2014

Mocking

The question: "I encountered an issue when I try to mock 3rd-party library functions.  The MOCK_METHOD_i macro supports i = 1 to 10 arguments, but 3rd-party library has functions with 11 arguments. Should I alter the scripts that build the MOCK_METHOD_i macros?"

My answer:

Yes and no.

Yes: so go ahead and rebuild the mocking framework by setting "n = 12 or so" in the script the generates the MOCK_METHOD_i macros. Make the tools do the work you want them to do.


No: it's often better to only mock code that you own. If you make that a rule, then what you have to mock is code that you wrote, code which hides and (hopefully) simplifies access to the external code. Your own code will likely NOT need 11 arguments, since you can hide unnecessary parts of the external code. 


There's a nice wrap-up of this concept here: http://www.davesquared.net/2011/04/dont-mock-types-you-dont-own.html

Using test doubles for types we don’t own can end up with fragile tests that don’t actually test much of value, or can even compromise our design and the effectiveness of the abstractions we use. Even when mocking a library we know really well we can end up with compromised abstractions and fragile tests due to relying on implementation details or assumptions based on previous versions of the library.

Friday, October 3, 2014

iPhone and iPad Models and Screen Resolutions

iPhone and iPad models and screen resolutions in the context of Apple's Xcode launch image xcassets view.


Tuesday, August 26, 2014

I and Me

If you're wondering whether to say "Bob and I" or "Bob and me," here's the trick: Take "Bob and" out of the sentence, correct the number implied by other words, if necessary, and judge whether the sentence sounds right.


Example 1: "Bob and I just want the best for you."

Drop Bob: "I just want the best for you."

The rewritten sentence sounds right, so "Bob and I" is correct in this example. The sentence should be, "Bob and I just want the best for you."


Example 2: "That award belongs to Bob and I."

Drop Bob: "That award belongs to I."

That doesn't sound right. So this example should be "That award belongs to Bob and me."

And you can test that again by changing "I" to "me" and leaving out Bob. "That award belongs to me." (But don't say that to Bob!)


Example 3: "We want to create the same experience you would have if you had called both Bob and I into your office for a meeting."

Drop Bob: "I want to create the same experience you would have if you had called I into your office  for a meeting."

That doesn't sound right. Let's try "me."  "I want to create the same experience you would have if you called me to your office  for a meeting." Better.

So, the better sentence is: "We want to create the same experience you would have if you had called both Bob and me into your office for a meeting."


That's it. Those of us who speak English as a native tongue, already know the unspoken rules of grammar; we just get confused when we try to follow the artificial rules we were taught in schools or by well-meaning friends.

Wednesday, August 13, 2014

Two Weird 'Tricks' For Testing Graphical Code

Before I do a bunch of "Extract Method" refactorings, I looked over the code and wrote this comment:

    // creates pdf context.
    // computes rowCount and columnCount from paper_size
    //    and major_grid_distance.
    // computes margin sizes (and thus origin.)
    // draws graph paper into context.
    // close context.
    -(void) drawMajorMinorGridAt: (CGPoint) origin
                     andRowCount: (int32_t) numberOfRows
                  andColumnCount: (int32_t) numberOfColumns

                       inContext: (CGContextRef) context;

What the extract methods will do, is let me draw while not in a pdf context. Code-reuse: yay!

Another way to achieve the same goal: copy & paste. While copy & paste may be quicker,  it bulks up the code and potentially doubles the number of defects that may "bug" us in the future. Technical debt.

One could argue that planning ahead would have created a better design. But... I didn't need to draw while not in a pdf context, a half-year ago.

One reason this code is so bad, is that I didn't exactly test-drive it. I ran some calculations, wrote the code, and looked at the output. In some early iterations, it produced grids with lines poking too far through other lines: I had to reduce the length of some lines, by the thickness of other lines. Similar glitches provoked a few other changes. And then it was done. I haven't touched the code in quite a while. 

Could I write some automated tests for this code? Yes. 

I could save some manually-verified pdf output as "Golden Data" and do file comparison in tests that are supposed to produce the same output. I have done something like this before. The only time the test failed in my project (without my changing code to cause the failure) was when a graphics library that my code depended on changed. 

So... few "false" failures. Drawbacks: slow tests, manual verification needed if the test fails. And manual intervention to re-create the "Golden Data" when the code is fixed or the failure is identified as not a bug. I also had to write a custom file-comparison routine in order to ignore parts of the file that change all the time (a time-stamp in the file itself.)

You do not want to do "Golden Data" test data when false failures are frequent. (Or any kind of manual intervention is frequent.)

Mocking. Yes, I could mock out the drawing code. It's a bit difficult because the drawing code below this Objective-C class consists of C functions. I would have to create a "seam" to allow compile-time, link-time, or run-time switching out of the drawing library. 

Mocking can create fragile tests. Since mocking works by verifying that the code-under-test executes an expected sequence of function-calls, and checks that the parameters passed into those functions have expected values, any change to the order of calls or the parameters passed in will cause the test to fail. This depends on how picky you configure the mock objects to be.

With some work, depending on the mocking framework, you could ignore the exact sequence of function calls, but still check that all of the calls have been made. Make the mocks too "loose" and then you're not testing anything. Make the mocks too strict, and you not only open yourself up to the possibility of frequent false failures, you also inhibit refactoring the drawing code.

There is also the danger that the functions you're avoiding calling will someday change their behavior, but the mock functions don't reflect that change. Instead of false test failures, you get false test successes. Some redundancy in testing helps avoid this problem: have some tests using mocks, have other tests using the real functions and some other form of verification, like Golden Data.)

Learn about Golden Data, mocks, and other xUnit Test Patterns here: xUnit Test Patterns: Refactoring Test Code



Test-drive safely, everyone!


Tuesday, August 12, 2014

When Your Brain Freezes Up

Some time ago, I was part of team for a trivia contest. There was no internet or computer access at that location, so no chance of cheating. I took the lead on some of the questions and got them wrong!

Why did that happen? I expected the questions to be hard. I expected the trivia questions to have non-obvious answers. It turned out that the obvious answers were the correct ones.

Go to this you-tube "video" (it's audio only) where a radio disk-jockey is posing a question to someone they randomly called. If the person they called gets the question right, they could win a motorcycle worth around $8,000 (US).



DJ: We've got to ask you a question before we put your name in the barrel. Spell AC/DC.
Mark: AD AC
DJ: I'm going to ask you again.
Mark: Hang on.
DJ: How do you spell AC/DC?
Mark: A… D… A… C
There's some overlapping dialog, and we hear Mark say "ACDC" in that noise. But his answer when asked a third time is still ADAC, until they call him an idiot and tell him it's AC/DC!

It could be this guy had other issues, but under stress, our body is preparing for flight or fight. The neocortex is only a recent invention. "Flight or fight" has been around for billions of years.


Friday, July 18, 2014

Function Pointer Syntax Cheat-Sheet-By-Example

#include <stdio.h>

// Using * to indicate the parameter is a pointer to a function.

void functionTakingFunctionPointerOldStyle(int (*pf)(int))
{
    printf("\nold style pf = %p\n", pf);
    if (pf != NULL)
    {
        int x = (*pf)(12); // Using * to deref function pointer.
        printf("pf(12) = %d\n", x);
    }
}

// We don't need * to indicate that a parameter is a function pointer.

void functionTakingFunctionPointerNewStyle(int pf(int))
{
    printf("\nnew style pf = %p\n", pf);
    if (pf != NULL)
    {
        int x = pf(12); // Don't need * to deref function pointer, either.
        printf("pf(12) = %d\n", x);
    }
}

// Blocks. Like old-style function pointer, using ^ instead of *.

void functionTakingBlock(int (^pf)(int)) // like old-style function pointer.
{
    printf("\nblock pf = %p\n", pf);
    if (pf != NULL)
    {
        int x = pf(12); // Same syntax as calling function or function-pointer.
        printf("pf(12) = %d\n", x);
    }
}

/*

If we use a typedef, then the syntax for parameter declaration is simple:

     typedef int (*funcPtr)(int);

     void functionTakingFunctionPointer(funcPtr fp);

 But now we need to remember how to declare the function-pointer typedef!

 This is how I create a typedef for a function pointer type:

 1. Start with the function declaration itself.

     int functionTakingIntReturningInt(int i);

 2. Remove parameter names.

     int functionTakingIntReturningInt(int);

 3. Change the function name to a name appropriate for this function-pointer type, maybe suffixed with "FuncPtr" if you can't think of something more meaningful. Don't suffix "Type" to the name—like "FuncPtrType"—it makes you look like a newby. (I stopped doing that last week.)

     int funcPtr(int);

 4. Wrap name with (* and )

     int (*funcPtr)(int);

 5. Add typedef

     typedef int (*funcPtr)(int);

 6. Profit!

*/

int functionTakingIntReturningInt(int i)
{
    return i + 1;
}

int main(int argc, char *argv[]) 
{
    // "old" style C code - using "&" take address of the function.
    functionTakingFunctionPointerOldStyle( NULL );
    functionTakingFunctionPointerOldStyle( & FuncionTakingIntReturningInt );

    // "new" style C code - don't need "&" for function type.
    functionTakingFunctionPointerNewStyle( NULL );
    functionTakingFunctionPointerNewStyle( FuncionTakingIntReturningInt );

    // blocks
    functionTakingBlock( NULL );
    functionTakingBlock( ^(int i){ return i + 1; } );
}


Output:


old style pf = 0x0

old style pf = 0x1004aa980
pf(12) = 13

new style pf = 0x0

new style pf = 0x1004aa980
pf(12) = 13

block pf = 0x0

block pf = 0x1004ab0f0
pf(12) = 13



Wednesday, April 30, 2014

myGraph 1.0.3 is Now Available on the Apple Store

myGraph 1.0.3 is Now Available on the Apple Store

myGraph lets you design fully-customizable graph paper, save it, share it, and print it on any AirPrint™-enabled printer. You have your choice of unlimited colors, line widths, and line spacing, so you can always have graph paper perfectly designed to your specific needs.

myGraph is perfect for interior designers or landscape designers, crafters, engineers, students, teachers, and more.

In myGraph you may select from predefined graph-papers or create your own. You may choose from an unlimited spectrum of colors. And, set grid spacing in fractions or decimals, in English or metric units.

Your graph-paper’s line-width and primary and alternate colors are under your full control. Want green instead of blue? Thick lines or thin? You can make it so!

Printing requires a printer supporting AirPrint™. You can share myGraph’s graph-paper through email, DropBox and other apps on your iPhone or iPad. Import myGraph’s graph-paper into painting or drawing programs.

Supports standard paper sizes for US and metric printers.


What's New in myGraph version: 1.0.3:


  • Fix issue with scrolling in the information view. It wasn't allowing the user to scroll to the end of the text. Now, it allows scrolling.
  • Performs faster.
  • Fixed memory leaks.

View in iTunes

Download myGraph in the App Store

Tuesday, April 22, 2014

myGraph 1.0.3 Beta Testing

Would you like to beta test for the iOS app myGraph by Sizeography™?

myGraph lets you design and print grids or graph paper, and save your designs so you can print them again. Create or select a grid, choose the color, spacing, and line-width of the grid, and optionally specify an alternate color and line-width for accent lines. Then you can print, share, or open a grid in another iOS app on your device.

PS: While we are trying to be as careful as possible, there are risks in running beta software on your iOS device. While we have not seen any problems other than myGraph freezing up or crashing, there is always a risk of data loss. Please be careful to backup your iDevice before testing.

If you decide to help us test, please try the following after you get the beta app installed:


  1. Try creating different designs of graph paper -- choosing colors, spacing, line-width and so on. If you really like a grid or graph paper that you designed, you can note the settings that you used to create that design and send me the notes and the pdf output for that design -- and I could feature that on our website, with a link to your homepage, if you so desire.
  2. Please try all the features that you can see. Check out the Help text and see if it makes sense. If you experience a hang or crash, please report the steps that you took to get that to happen. You can make screen-captures and send those to me.
  3. myGraph supports "Open In..." and "Share..." as well as "Print...". One of the "Open In..." choices is eMail, so go ahead and send me ONE email as part of your testing.


To sign up for testing CLICK HERE!

(Sizeography™ is a division of Upstart Technology™, CEO Cynthia Wunsch, CTO Keith Ray.)

Wednesday, April 2, 2014

Links

http://feedly.com/e/-sUatCMU birth of the light-saber


http://feeds.boingboing.net/~r/boingboing/iBag/~3/_6-Tz9H199E/story01.htm Rigged stock-trading? Also see Daily Show interview




http://feedproxy.google.com/~r/failblog/~3/er2CdGTxGdA/8130370560 Snakes in toilets -- we need devices to keep them out -- (kickstarter, anyone?) 








quotes:

"So I went back to Things, a program that’s so simple, it doesn’t have a manual. (It’s also Mac only; sorry.) I had the basics down in under two minutes. You click on the Projects button and give the project a name–You Again, Kitchen, Chores, Car, whatever. Under that you click on the Add button and you get a line in your To List so you can break down the job into small parts: Synopsis, Hang Shelf, Wash Dishes, Call Toyoto, whatever. 

"Then you assign a due date for each To Do. That’s it. It does other things–you can assign tags and add notes, etc.–but it does the one thing I need–generate daily to-do lists–and it does it really well."  

"My first to do lists weren’t broken down into small enough tasks, so I’d look at my list for a day and realized it would take forty hours to do what I’d scheduled in twelve. Back to revising the lists, stretching out the time periods for getting things done, making the tasks smaller. My second to-do lists were much better, until I realized that scheduling sixteen-hour work days wasn’t a good idea, either. I can do that for one or two, even three days, but week after week? No. So I went back in and reassigned due dates again, which is easy to do in the program."


Quote: 

"As the day of our first release planning event grew closer, I noticed that there were some blank faces among my extended leadership team when I referred to various aspects of what we needed to do. My heart sank as I asked the team, “Who has read the book?“. A couple of hands were raised. “Who has finished the book?“. Only one hand (and yes he still works with me!). “Who doesn’t own the book?“. At least four or five hands were sheepishly raised. “OK” I said “Change of plan. We are all going to buy the book. If you cannot afford the book, let me know and I will arrange a book for you. Then we are going to read the book together. We are going to form a book club!” As Deming said, “without theory there is no learning”. 
"For the next 3 months I met with my extended leadership team for an hour a week. Each week one member of the team lead a discussion on a chapter or two. We would discuss the concepts covered, how they might apply to our situation and agreed on the ideas we wanted to implement. Book club was compulsory and if one team member had something more important to do then book club was rescheduled. Shared understating and agreement was paramount if we were going to be successful. 
"Visitors to the EDW Release Train are often shocked when they hear that I called a mandatory weekly meeting to read a book. I am always quick to remind them that no one would hesitate to call a “business” meeting, so why wouldn’t we want to make time for a meeting focused on learning ways to improve our “business”."



Quote 
"If you buy an ebook from anyone other than Amazon, you’re buying an EPUB file. Apple and Google, in particular, have aggressively supported EPUB 3 in their iBooks and Google Play stores. As an ebook author, iBooks and the Google Play reader are a dream come true: I can write the book, style it as I please with modern CSS, and be confident that readers will see the text as I intended. 
"For sales on the Kindle Store, I need to generate a KF8 with kindlegen. I have to painstakingly craft my EPUB files so as not to conflict with the limitations in Amazon’s undocumented subset of EPUB3."

http://feedly.com/k/19JcS1I "quartoOpen source ebook formatter (under development) 


Quote 
"Fear of success, just like fear of failure, can paralyze you. Can you find a way to create an experiment that will allow you to succeed, in one small way? Then, use the results to learn from that experiment? 
"If you have the growth mindset, it’s not about you as a boxed-in person. It’s about you as an experiment. You build your emotional resilience and your experiences to help you along the way."


Monday, March 31, 2014

Link Blogging

http://www.niemanlab.org/2014/03/whats-new-in-digital-and-social-media-research-how-editors-see-the-news-differently-from-readers-and-the-limits-of-filter-bubbles/ “Shares, Pins, and Tweets: News Readership From Daily Papers to Social Media”: From Duke University, published in Journalism Studies. By Marco Toledo Bastos. "Social media users tend to favor hard news over soft news, especially on Twitter." "news items about arts, science, technology, and opinion pieces, which are on average more frequent on social networking sites than on newspapers.“The Structural Virality of Online Diffusion,”  "analyze a billion links [...] shared on Twitter. One of out every 3,000 links produced a “large event,” or a sharing phenomenon that reached 100 additional persons [...] truly viral events (many multiple generations of sharing, several thousand adoptions at least) occurred only about once in a million instances."

http://www.vox.com/charles-kenny/#b03g31t20w14 How is the world getting better? Ezra: When I read some of the American decline literature [...] Charles: I think that we’re running out of "others" in a really positive way. We’re not allowed to discriminate against many people we used to discriminate against and so who are we going to have as the threat? Maybe what we’re left with is China. I hope we discover Martians because China is a really bad other. We really need to be cooperating with China. Treating them as a threat is going to be really counterproductive to our own quality of life.

http://proseand.co.nz/2014/02/17/type-programming-shifting-from-values-to-types/ Type programming: Shifting from values to types by Joe Barnes "I need to understand a lot more about the type system in Scala. So as of this morning, I have decided it is time for me to actually learn type programming in Scala [...] I find that all of the resources out there thrust the reader so quickly into the deeper areas of the pool, that reading them is akin to flailing for my life until the lifeguard rescues me and the only lesson I’ve learned is how to not die while in the pool. In this post, I will gently break us into type programming in the kiddie pool."

Link Blogging

http://feeds.boingboing.net/~r/boingboing/iBag/~3/l6Rl-x22u3c/story01.htm "developers who worked on Ultima Online [...] are creating a game called Shards Online over which players will have enormous control. Players will be able to run their own servers, change the code that the game runs on, and add their own challenges. The internal logic of this is a game set in a multiverse[...]"

http://feeds.boingboing.net/~r/boingboing/iBag/~3/yVN83zKFBA4/story01.htm "re-re-launched Amazing Stories, the very first science fiction magazine, founded 88 years ago by Hugo Gernsback. Through the month of April, they'll publish fiction and features, which will be collected as an ezine at the end of the month."

http://matociquala.tumblr.com/post/81284926274/everythingsbetterwithbisexuals-lucymontero "Mary Bowser, former slave of the Van Lew family, infiltrated [...] the household of Jefferson Davis. Bowser was assumed to be illiterate, and as a black woman was below suspicion. Practically invisible, she was able to listen to conversations between Confederate officials and read sensitive documents, gathering information that she handed over to the Union. (From National Woman’s History Museum Facebook Page)"

funny http://cheezburger.com/8129159936?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+SetPhasersToLol+%28Set+Phasers+To+LoL%29 "It's a Love/Rob Situation..." "He used to rob me three times a week, now I'm lucky if I get it once a month..."


Link Blogging

http://www.neat.io/blog/app-developer-vs-seo.html "[three pages] shared the same common template and content." "these three pages (the most important pages to rank for due to their specificity), were not being ranked very highly on Google. Turns out search engines don't like duplicate content and heavily penalise your site for it" "Links which are in bold are also given more weight so each link to a service page is wrapped in strong tags" "Understanding how search engines crawl pages and how they interpret the semantic structure of your pages was eye-opening."

Two "Magnificent Seven" blogs today:

  1.  http://feeds.boingboing.net/~r/boingboing/iBag/~3/iFXG2dI8ueA/story01.htm "Podcast: Collective Action - the Magnificent Seven anti-troll business-model" "The reason the victims [of patent trolls] don’t get together to fight back is that they don’t know each other and have no way to coordinate among each other. In economists’ jargon, they have a ‘‘collective action problem.’’"
  2.  http://agiletng.org/2014/03/21/the-seven-samurai/ "A pattern language for enterprise agile transformation" "Continuous Assessment: Motivate Agile in terms of bottom line metrics." etc.
http://boingboing.net/2014/03/31/google-maps-spam-problem-pre.html "Google Maps' spam problem presents genuine security issues" "a Microsoft Engineer demonstrated an attack against Google Maps through which he was able to set up fake Secret Service offices in the company's geo-database, complete with fake phone numbers that rang a switch under his control and then were forwarded to real Secret Service offices, allowing him to intercept and record phone-calls made to the Secret Service" "this is a higher-stakes version of a common spam-attack on Google Maps practiced by locksmith, carpet cleaning, and home repair services" "Google’s basically getting a not insignificant amount of their income from scammers—if you look at locksmiths, 99 percent of them are scammers,” says Austin"



Repels the Cable-Chewing Cat

American Terminal SL250-100 1/4-Inch Split Loom Tubing, 100 feet "One of my cats likes to chew on cables -- particularly expensive ones belonging to Apple products. I've used this product to cover many of my cables, starting at least a year ago, and I haven't seen any evidence that my cat has chewed on them. So, I guess they work!"

Getting this tubing over the cables isn't easy, but you only have to do it once (per cable)."

Link Blogging

I am going to post links to "interesting" articles I encounter, with a short quote and/or tiny amount of explanation. Sometimes a short quote or explanation will be too long to tweet, and I don't want to fill my tweet streams with a hundred links per week.

http://letsworkshop.com "Workshop is a daily newsletter and community delivering the best freelance opportunities to your inbox" "100% freelance-friendly leads" 10 leads/day = $64/month 5 leads/day = $99/month

http://www.cheryl-morgan.com/?p=18787 "Origins of Feminist Transphobia" by Cheryl Morgan "Back in the 1970s, being a radical feminist often meant being a lesbian separatist..." "read Suzy McKee Charnas’s Holdfast Chronicles [which goes into lesbian separatism in depth]" "for lesbian separatists the idea of a lesbian trans woman can be even more horrifying, because it leads to thoughts of people who are “really men” stealing their girlfriends."

http://qualitycoding.org/xcode51-code-coverage/ "Code Coverage Fixed for Xcode 5.1" "The Xcode 5.1 update proved to be more exciting than I anticipated. And I mean “exciting” in the sense of “breaking the tools I use.” xctool stopped working, and so did my code coverage scripts." "go get the latest XcodeCoverage to get up & running again on Xcode 5.1. Enjoy"

http://buzzsumo.com/blog/pitch-journalist-tips-techcrunch-ny-times/?utm_source=hootsuite&utm_campaign=hootsuite "How To Pitch to Journalists: Expert Tips From Techcrunch, NYT and more" "I am appalled by how lazy PR people are and completely fed up with the BS they keep sending me."
"Pitching to a journalist isn’t rocket science. Assuming you have a compelling story, make sure you follow these simple tips:
  • Don’t use buzzwords like “disruptive”
  • Don’t write long introduction – cut to the chase.
  • Make sure it’s relevant to the journalist.
  • Make it short and sweet (lean and impactful)
  • Tailor your pitch to each journalist
  • Answer the question: Why does this matter today?"



Wednesday, March 5, 2014

Microblogged on Twitter

By the way, I recently micro-blogged a series of "straw-man" arguments against, and rebuttals for, unit-testing and TDD. Here they are somewhat expanded. Rebuttals are italic. 

I am NOT making up these straw-men arguments. I’ve even heard them from people who should, 14 years after Extreme Programming Explained was published, have some understanding of incremental design and development, who should know both the differences and similarities between TDD and unit testing, and how refactoring fits into both small and big design activities.

1. straw-man: OO means you can't know what modified something's state.

That sounds like a global var bug. Objects can guard their state. Most people could learn a bit more about designing non-mutable classes, but OO doesn’t prevent you from knowing an object’s state.

2. straw-man: Always-passing tests are useless. 

Yes, tautological tests are useless. Don't do that. You learn something when a rarely-failing unit test fails: something unexpected happened! Either some code (or data) has changed and it now violates a test’s description of how that code (or data) is supposed to work, or the programmers forgot to update their tests. If a test that has been passing for 10 months suddenly fails, you know something is wrong. The worser condition is that no problem is detected until 20 months have passed, and you have to trace changes back to 10-month old code to find out what code-change caused the problem.

Tests that fail frequently or seemingly randomly, indicate a “people” problem: members of the team don’t understand the requirements, or requirements keep changing due to activity outside of the team, or coding or testing not done well and better training is needed.

3. straw-man: without testing-hooks in code, you can't do white-box tests.

Try mock objects.

4. straw-man: to test a for-loop, you need as many tests as there are iterations in the loop. 

Heard of boundary testing? See my Testing on the Toilet entry.

5. straw-man: changing code requires changing tests. 

This isn't a big burden if DRY (“Don’t Repeat Yourself”) is applied to both code & tests. (See also “Once and Only Once.)

5. straw-man: you can't have nice OO because TDD tests are "procedural". 

So not having no tests is required for nice OO?

6. straw-man: TDDing classes = bad design, because incrementally designing a class or classes while writing tests can’t be done well.  And, refactoring the structure of the code (to improve the design) is can’t be done, either.

Really? refactoring is supported by TDD-tests. Do well-designed classes pop out of your head fully-formed?

6. straw-man: when implementing features one-at-a-time, user experience is a  mess.

Before BDD, did you design entire UX in one second? It was incremental then, too.

7. straw-man: the object's state-space is big number (like 2**32) so we can't write enough unit tests, so don't even try.

Heard of boundary testing? See my Testing on the Toilet entry.

OTHER issues with Signed SSLVerifySignedServerKeyExchange ("goto fail" bug)

Mike Bland, whom I worked with at Google, teaching and spreading the word on how to write fast unit tests, find code smells and refactor them away, continuous integration, and TDD, has commented on the "goto fail" bug - and wants to direct your attention to other aspects of that code: the copy-paste code duplication that probably created the problem that the lack of unit tests didn't find:

Mike wrote:
I still haven’t found any other articles that suggest, as mine did, that the same block of code cut-and-pasted six times in the same file was a problem, that it was ripe for factoring out, and that the resulting function was straightforward to test in isolation. That’s curious to me; it’s like people got stuck on the one stupid goto fail; line and started drawing conclusions without looking at the surrounding code, seeing the same algorithm copied immediately above it, and suspecting, as I did, that there was a classic code duplication problem which fixing would’ve likely avoided the bug to begin with, test or no.
(Go read his whole blog entry, it is worth it, and lengthy. So much blogging is too short these days.)

He also wrote:

What’s more, if memory serves, Keith even wrote the Testing on the Toilet article that advocated for breaking larger chunks of logic into smaller, more testable functions to avoid having a combinatorial explosion of test inputs—the very concern that Bellovin had mentioned as rendering exhaustive system-level testing infeasible.5


My response to Mike is:

Hi Mike. Yes I did write a Testing on the Toilet article titled "Too Many Tests", which was posted inside Google as well as on the public Google Testing blog. On of the commenters said "Good example of equivalence class partioning."
In the movie Amadeus, the Austrian Emperor criticizes Mozart's music as having “too many notes.” How many tests are “too many” to test one function?

My personal blogging on the "goto fail" issue did just stick to the testable aspect of the code, because many people were saying it could not be tested at the unit level.

I could have also pointed out the need for code review and/or pair programming and the need for refactoring, based on a foundation of well-tested code, but I kept that blog entry focused only on the 'testable' topic.

[PS: Check out the "Real Programmers Write Tests" merchandise on my blog's home page.]

Tuesday, March 4, 2014

Next Product For Sizeography

As CTO and chief programmer of UpstartTechnology and the Sizeography division, I'd like announce our next product, already in progress.

hands holding tape-measure to find size of unknown object


This new app will allow you to place a common object on, or neat, another object, and find the approximate size of the unknown object. For example, if you place a quarter on a small table, snap a picture of it in our app, the app will compute the size of the table.

While the app won’t be ready right away, we want everyone to have a say, so after we get suggestions for the name, we’ll hold a vote to see which of the names wins.

Nominate a name for app in the comments to this blog (or our main company blog), and look for the poll to be put up after we’ve gotten some good suggestions for names. (G-rated names only, please).

How to enter: Leave a comment with your app name suggestion[s] and make sure we have your email so we can contact you if you win. We’ll take the best names and put up a poll, and the winner of the poll will get the prize.

The prize will probably be an Easter-egg hidden in the app, but if you’ve got a prize suggestion, be sure to let us know in the comments (G-rated only, please).


Sunday, February 23, 2014

TDD and Signed SSLVerifySignedServerKeyExchange

Test-driven development (TDD) done consistently throughout a project results in near-100% logic coverage. That's better than just statement coverage. It also results in testable code, better modularity, better design (if you pay attention to code smells), and faster software development.

The heart of TDD is:


  1. Write a test. Running that test should fail. (Tests are often simpler than the code they test, so usually this step is pretty easy.)
  1. Make the test pass by writing just enough code. (All other tests should pass as well.) 
  1. Refactor. (Not done every time through this loop; remove duplicate logic and look for other code smells.)
  1. Repeat until desired feature is implemented. 
  1. NOTE: Checking into source-code-control can be done whenever all tests are passing. (A Continuous Integration (CI) server can also run tests: the "fast tests" created by TDD and slower system tests.)


Badly-designed code is hard to test. Most developers who try to use TDD in a badly-designed, not-unit-tested project will find TDD is hard to do in this environment, and will give up. If they try to do "test-after" (the opposite of TDD's test-first practice), they will also find it hard to do in this environment and give up. And this creates a vicious cycle: untested bad code encourages more untested bad code.

If code is only written to make a test pass (as in TDD), you can't write an if statement until you have a test that requires it. You should end up with a test for the if statement being true, and a test for the if statement being false, possibly more than one test for each branch.

TDD in C is not terribly hard. I've taught people how to TDD in C and other languages. And the suites of tests created by TDD makes it possible to refactor with more confidence.

If one or more TDD tests (and other tests, like system tests) fail, someone broke something. The fine-grain testing that is part of TDD will usually pin-point where the new bug is. Undo the changes that broke the test, or fix things before doing anything else.

(Tests that fail unpredictably indicate something is non-deterministic either in the code-under-test or the test itself. That also needs to be fixed.)

landonf demonstrated that SSLVerifySignedServerKeyExchange() is unit-testable in isolation. See his code on github. I copied his unit test for a bad signature here:

@interface TestableSecurityTests : XCTestCase @end

@implementation TestableSecurityTests {
    SSLContext _ctx;
}

- (void) setUp {
    memset(_ctx.clientRandom, 'A', sizeof(_ctx.clientRandom));
    memset(_ctx.serverRandom, 'B', sizeof(_ctx.serverRandom));
}

- (void) tearDown {
    [super tearDown];
}


/* Verify that a bogus signature does not validate */
- (void) testVerifyRSASignature {
    SSLBuffer signedParams;
    SSLAllocBuffer(&signedParams, 32);
    uint8_t badSignature[128];
   
    memset(badSignature, 0, sizeof(badSignature));
    OSStatus err;
    err = SSLVerifySignedServerKeyExchange(&_ctx, true, signedParams, badSignature, sizeof(badSignature));
    XCTAssertNotEqual(err, 0, @"SSLVerifySignedServerKeyExchange() returned success on a completely bogus signature");
}

@end

Friday, February 14, 2014

A Key Aspect of Successful Projects

Rapid responses to questions is often a key to successful projects. Extreme Programming and other agile methods like Scrum consider this to be so important as to require the domain expert / product manager / business analyst / "product owner" / "Customer" to be co-located with the developers/testers. 

Obviously some projects can be successful without co-location, but odds against success rise whenever developers can't quickly and easily communicate with the Customer.

Tuesday, January 28, 2014

myGraph Initial View

Let this picture serve as a 1000 words. More to come...




Thanks to a lot of hard work

Thanks to a lot of hard work, Sizeography's first iOS app, myGraph, is now live in the app store. This app allows you to print completely customized grid or graph paper from your iPhone or iPad to any compatible AirPrint printer. For a 99¢ one-time purchase (no ads, ever), you will have as many or as few sheets of graph paper to your exact specifications, at home or away. 

You can also use myGraph to send a pdf of your custom or predefined grid or graph paper to:
  • AirDrop
  • DropBox
  • Evernote
  • Message
  • Mail
  • Save an image to your photo library.
  • Copy an image to be pasted in another app.
  • myGraph can send pdf files to apps that accept pdf files.
  • and, myGraph can send png files to apps that accept png files.


We're working on a list of 101 uses for this app. Here are a few we have thought up so far:
  1. Planning and designing woodworking projects.
  2. Print a grid to help with sewing patterns.
  3. Tailoring.
  4. Scrap-booking.
  5. Science class: plotting lab results.
  6. Math class: graphing equations.
  7. Geometry class.
  8. Trigonometry class.
  9. Practicing writing Chinese, Japanese, Korean, and other languages.
Have another use for custom graph paper in mind? Comment here or on our sizeography.com site.


Monday, January 27, 2014

Some thoughts on C, OO, ObjC, C++

C allows structs to be copied "by value" but C doesn't allow array types to be copied—directly. The following code will not compile:

typedef int FiveIntsArray[5];

FiveIntsArray function5ints( FiveIntsArray arrIn )
{
    FiveIntsArray ret:
    ret = arrIn;
    return ret;
}

int main(int argc,char*argv[])
{
    FiveIntsArray arr = {1,2,3,4,5};
    FiveIntsArray bar;
    bar = function5ints(arr);
    printf("%d, %d, %d, %d, %d\n", bar[0], bar[1], bar[2], bar[3], bar[4]);
}

Yes, it does not compile:



But put all this inside a struct, and it all works!

typedef struct FiveIntsStruct {
    int arr[5];
} FiveIntsStruct;

FiveIntsStruct function5ints( FiveIntsStruct arrIn )
{
    FiveIntsStruct ret;
    ret = arrIn;
    return ret;
}

int main(int argc,char*argv[])
{
    FiveIntsStruct arr = {{1,2,3,4,5}};
    FiveIntsStruct bar;
    bar = function5ints(arr);
    printf("%d, %d, %d, %d, %d\n", bar.arr[0], bar.arr[1], bar.arr[2], bar.arr[3], bar.arr[4]);
}

And I get this output:

1, 2, 3, 4, 5
Program ended with exit code: 0

Ta-da!

However, struct-copying, at least in the early days of C, was thought to be not very efficient, and was often avoided in C code. This tradition is so ingrained in C programmers that I have met 
some programmers who didn't know that struct-copying is allowed in C.

For small structs, and under modern compilers, struct-copying can be just as efficient as passing a single value, and more efficient than passing a pointer to a struct, which requires dereferencing the pointer to access its members. A 64-bit CPU can hold an entire FiveiIntsStruct in a single register.

If you want to do object-oriented programming in C, one way to do that is to start with structs. We can associate functions and structs, and we already have an example of something object-like in the C standard library: the file io functions.

typedef struct FILE { 
    // we don't care what's in here--consider it private.
} FILE;

FILE * fopen(const char *restrict filename, const char *restrict mode);
// fopen allocates & initializes, kind of like a C++ constructor.

int fprintf(FILE * restrict stream, const char * restrict format, …);
// functions taking a FILE* arguments are methods of the FILE "class".

int fclose(FILE *stream);
// cleans up and deallocates, kind of like a C++ destructor.

But a big part of OO is polymorphism. How can we accomplish that? Let's say we want a file-writer, and a network-writer, but the majority of the code should work with both kinds of writer. We can do it a bit like this:

struct Writer;

typedef int (* PrintFunc)(struct Writer * w, char const * format, ...);
// pointer to function that returns int
// and has Writer* as the type of its first argument.

typedef void (* CloseWriterFunc)(struct Writer * w);
// close and de-allocate

typedef struct Writer {
    PrintFunc Print;
    // ...other function pointers
    CloseWriterFunc Close;
} Writer;

Writer * NewFileWriter(const char *restrict filename);
Writer * NewNetworkWriter(const char *restrict serverName);

int main(int argc, char*argv[])
{
    Writer * w;
    int useFile = 1;
    
    if ( useFile )
        w = NewFileWriter("someFile.txt");
    else
        w = NewNetworkWriter("someServer");

    w->Print(w, "etc.");
    w->Close(w);
    w = NULL;
}

Implementing this in one or more .c files:

typedef struct {
    Writer wpart;
    // file-writer specific data members go here.
} FileWriter;

typedef struct {
    Writer wpart;
    // network-writer specific data members go here.
} NetworkWriter;

// must match function-pointers...

static int FileWriterPrint(Writer * w, char const * format, ...)
{
    FileWriter * fw = (FileWriter *) w;
    // real code goes here.
    return 0;
}

static void FileWriterClose(struct Writer * w)
{
    FileWriter * fw = (FileWriter *) w;
    // real code goes here.
    free(fw);
}

static int NetworkWriterPrint(Writer * w, char const * format, ...)
{
    NetworkWriter * fw = (NetworkWriter *) w;
    // real code goes here.
    return 0;
}

// other NetworkWriter functions...

static void NetworkWriterClose(struct Writer * w)
{
    NetworkWriter * fw = (NetworkWriter *) w;
    // real code goes here.
    free(fw);
}

Writer * NewFileWriter(const char *restrict filename)
{
    FileWriter * fw = malloc( sizeof( FileWriter) );
    fw->wpart.Print = FileWriterPrint;
    fw->wpart.Close = FileWriterClose;
    // real code goes here.
    return (Writer *) fw;
}

Writer * NewNetworkWriter(const char *restrict filename)
{
    NetworkWriter * nw = malloc( sizeof(NetworkWriter) );
    nw->wpart.Print = NetworkWriterPrint;
    nw->wpart.Close = NetworkWriterClose;
    // real code goes here.
    return (Writer *) nw;
}

The syntax isn't that nice, but a preprocessor could automate much of this.

And, in fact, both Objective-C and C++ started out as preprocessors generating C code.

There is one problem with this implementation besides its awkward syntax. Each instance of this struct contains copies of the function-pointers. This overhead can be eliminated by another level of indirection.

// there will be one instance of this struct per "class"
typedef struct WriterFunctions {
    PrintFunc Print;
    // ...other function pointers
    CloseWriterFunc Close; // close and de-allocate
} WriterFunctions;

typedef struct Writer {
    // writer data
    WriterFunctions* methods;
} Writer;

static WriterFunctions FileWriterFunctions = {
    FileWriterPrint, FileWriterClose
};

static WriterFunctions NetworkWriterFunctions = {
    NetworkWriterPrint, NetworkWriterClose
};

Writer * NewFileWriter(const char *restrict filename)
{
    FileWriter * fw = malloc( sizeof(FileWriter) );
    fw->methods = FileWriterFunctions;
    // real code goes here.
    return (Writer *) fw;
}

Writer * NewNetworkWriter(const char *restrict filename)
{
    NetworkWriter * nw = malloc( sizeof(NetworkWriter) );
    nw->methods = NetworkWriterFunctions;
    // real code goes here.
    return (Writer *) nw;
}

This is probably not that far from the implementation that C++ uses, where polymorphic ("virtual") function-pointers are kept in "vtables".

C++ contorts the C language into pretending classes are just "special" structs. But a C++ class or struct may have many hidden things: a vtable pointer, an implicitly-defined default constructor calling constructors on its member variables, an implicitly-defined copy constructor calling copy constructors of its member variables, an implicit-defined assignment operator calling assignment-operators on its member variables, and an implicitly-defined non-virtual destructor calling the destructors of its member variables.

And C++ has some gotchas: if the base class in a class hierarchy has an implicitly-defined non-virtual destructor, calling delete on a pointer of the base-class type (but it is pointing to a derived-class object), the derived-class destructor does not get called, which may destroy the correctness of the system.

Objective-C adds classes and objects as something different from structs, adding some pretty self-contained Smalltalk-like syntax to C. Without operator overloading and other contortions of syntax, what you see in Objective-C code is generally what you get. Not much invisible or implicit stuff in the language itself (though the implementation of method-lookup isn't normally invisible). With ARC, retain, release, and autorelease are mostly invisible/implicit, and I'm pretty sure Apple has done some very interesting things at run-time for certain technologies like Core Data.

If you know where the sharp edges are, C++ can be pretty cool. And you can blend C++ and Objective-C if you want to. C++ constructors and destructors will be invoked (invisibly/implicitly) for you in Objective-C's equivalents of constructors and destructors. 

Most of the functionality of ARC could have been implemented with appropriate C++ smart pointer template classes, but I'm sure most Objective-C programmers would not want to sweat the details of the required syntax.

So there it is.