Cyclic fractions

Somewhere along the way you may have noticed that the digits in the decimal expansion of multiples of 1/7 are all rotations of the same digits:

1/7 = 0.142857142857…
2/7 = 0.285714285714…
3/7 = 0.428571428571…
4/7 = 0.571428571428…
5/7 = 0.714285714285…
6/7 = 0.857142857142…

We can make the pattern more clear by vertically aligning the sequences of digits:

1/7 = 0.142857142857…
2/7 =   0.2857142857…
3/7 =  0.42857142857…
4/7 =     0.57142857…
5/7 =      0.7142857…
6/7 =    0.857142857…

Are there more cyclic fractions like that? Indeed there are. Another example is 1/17. The following shows that 1/17 is cyclic:

 
 1/17 = 0.05882352941176470588235294117647…
 2/17 =           0.1176470588235294117647…
 3/17 =            0.176470588235294117647…
 4/17 =     0.2352941176470588235294117647…
 5/17 =        0.2941176470588235294117647…
 6/17 =      0.352941176470588235294117647…
 7/17 =          0.41176470588235294117647…
 8/17 =               0.470588235294117647…
 9/17 =       0.52941176470588235294117647…
10/17 =  0.5882352941176470588235294117647…
11/17 =              0.6470588235294117647…
12/17 =                0.70588235294117647…
13/17 =             0.76470588235294117647…
14/17 =    0.82352941176470588235294117647…
15/17 =   0.882352941176470588235294117647…
16/17 =         0.941176470588235294117647…

The next denominator to exhibit this pattern is 19. After finding 17 and 19 by hand, I typed “7, 17, 19” into the Online Encyclopedia of Integer Sequences found a list of denominators of cyclic fractions: OEIS A001913. These numbers are called “full reptend primes” and according to MathWorld “No general method is known for finding full reptend primes.”

Related: Applied number theory

“Hello world” is the hard part

Kernighan and Ritchie’s classic book The C Programming Language began with a sample C program that printed “hello world.” Since then “hello world” has come describe the first program you write with any technology, even if it doesn’t literally print “hello world.”

Hello-world programs are often intimidating. People think “I must be a dufus because I find hello-world hard. At this rate I’ll never get to anything interesting.”

The problem is that we confuse the first task with the easiest task. Hello-world programs are almost completely arbitrary. You can’t deduce what a compiler is named, where files must be located, how they must be formatted, etc. You have to be told. The amount of arbitrary material you need to learn is greatest up-front and slowly decreases.

When I started programming I thought I’d quickly get past the hello-world stage and only write substantial programs from then on. Instead, it seems I’ve spent a good chunk of my career writing hello-world programs with no end in sight.

* * *

No discussion of hello-world programs would be complete without mentioning possibly the most intimidating hello-world program: the first Windows program in Charles Petzold’s Programming Windows book. I was only able to find the program from the Windows 98 edition of his book. I don’t recall how it differs much from the program in his first edition, but I vaguely remember the original being worse.

/*------------------------------------------------------------
HELLOWIN.C -- Displays "Hello, Windows 98!" in client area
(c) Charles Petzold, 1998
------------------------------------------------------------*/

#include <windows.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT ("HelloWin") ;
    HWND hwnd ;
    MSG msg ;
    WNDCLASS wndclass ;

    wndclass.style = CS_HREDRAW | CS_VREDRAW ;
    wndclass.lpfnWndProc = WndProc ;
    wndclass.cbClsExtra = 0 ;
    wndclass.cbWndExtra = 0 ;
    wndclass.hInstance = hInstance ;
    wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
    wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
    wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
    wndclass.lpszMenuName = NULL ;
    wndclass.lpszClassName = szAppName ;

    if (!RegisterClass (&wndclass))
    {
        MessageBox (NULL, TEXT ("This program requires Windows NT!"),
        szAppName, MB_ICONERROR) ;
        return 0 ;
    }

    hwnd = CreateWindow (szAppName, // window class name
    TEXT ("The Hello Program"), // window caption
        WS_OVERLAPPEDWINDOW, // window style
        CW_USEDEFAULT, // initial x position
        CW_USEDEFAULT, // initial y position
        CW_USEDEFAULT, // initial x size
        CW_USEDEFAULT, // initial y size
        NULL, // parent window handle
        NULL, // window menu handle
        hInstance, // program instance handle
        NULL) ; // creation parameters

    ShowWindow (hwnd, iCmdShow) ;
    UpdateWindow (hwnd) ;

    while (GetMessage (&msg, NULL, 0, 0))
    {
        TranslateMessage (&msg) ;
        DispatchMessage (&msg) ;
    }
    return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC hdc ;
    PAINTSTRUCT ps ;
    RECT rect ;

    switch (message)
    {
        case WM_CREATE:
            PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
            return 0 ;

        case WM_PAINT:
            hdc = BeginPaint (hwnd, &ps) ;

            GetClientRect (hwnd, &rect) ;

            DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,
            DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;

            EndPaint (hwnd, &ps) ;
            return 0 ;

        case WM_DESTROY:
            PostQuitMessage (0) ;
            return 0 ;
    }
    return DefWindowProc (hwnd, message, wParam, lParam) ;
}

Help wanted

I’m looking for people to help with some miscellaneous tasks. I don’t expect one person to do everything, but if you’re excellent at any of the following and interested in small projects please let me know.

  • CSS / responsive design
  • WordPress customization
  • Emacs customization
  • Advanced LaTeX
  • Data cleaning and visualization
  • Python (miscellaneous automation scripts)

I don’t have an immediate project to outsource, but these tasks come up occasionally and I’d like to have someone to contact when they do. Mostly these would be small self-contained projects, though data cleaning and visualization could be larger.

People want Swiss Army Knives

I ran across this graphic this morning on Twitter:

comparing a scalpel and a swiss army knife

Obviously the intended message is that scalpels are better than Swiss Army Knives. Certainly the scalpel looks simpler.

But most people would rather have a Swiss Army Knife than a scalpel. Many people, myself included, own a Swiss Army Knife but not a scalpel. (I also have a Letherman multi-tool that the folks at Snow gave me and I like it even better than my Swiss Army Knife.)

People like simplicity, at least a certain kind of simplicity, more in theory than in practice. Minimalist products that end up in the MoMA generally don’t fly off the shelves at Walmart.

The simplicity of a scalpel is superficial. The realistic alternative to a Swiss Army Knife, for ordinary use, is a knife, two kinds of screwdriver, a bottle opener, etc. The Swiss Army Knife is the simpler alternative in that context.

A surgeon would rightfully prefer a scalpel, but not just a scalpel. A surgeon would have a tray full of specialized instruments, collectively more complicated than a Swiss Army Knife.

I basically agree with the Unix philosophy that tools should do one thing well, but even Unix doesn’t follow this principle strictly in practice. One reason is that “thing” and “well” depend on context. The “thing” that a toolmaker has in mind may not exactly be the “thing” the user has in mind, and the user may have a different idea of when a tool has served well enough.