development

A 11-post collection

Moon Phase Calculator for the Pebble Watch (C Source)

Written by Michael Earls
 programming  development

A few years ago, I bought a Pebble smartwatch. Mostly I bought it because it was cheap, but I also wanted to write my own apps for it. I wrote a few apps.

Recently, Pebble was bought by FitBit and ceased production of the Pebble smartwatch. However, they are making great progress to ensuring that the watch continues to be viable into the future.

Anyway, as part of the transition, I wanted to release my source code for my moon phase app. What sets this moon phase calculator apart from my first implementation is the ability for it to run when not connected to the phone. I implemented it as a C app.

The moon phase calculation itself was originally written in JavaScript and I had to convert it to C. Sadly, I can't remember where I got the source, so I can't give attribution.

The code is available on my GitHub Page:

pebble-moon-phase on GitHub

Here is the actual calculation for anyone searching for a moon phase calculator in C:

#include "math.h"

#define        PI  3.1415926535897932384626433832795
#define        RAD (PI/180.0)
#define         SMALL_FLOAT    (1e-12)

static double Julian(int year,int month,double day)  
{
    /*
      Returns the number of julian days for the specified day.
      */

    int a,b=0,c,e;
    if (month < 3) {
    year--;
    month += 12;
    }
    if (year > 1582 || (year  1582 && month>10) ||
    (year  1582 && month==10 && day > 15)) {
    a=year/100;
    b=2-a+a/4;
    }
    c = 365.25*year;
    e = 30.6001*(month+1);
    return b+c+e+day+1720994.5;
}

static double sun_position(double j)  
{
    double n,x,e,l,dl,v;
    //double m2;
    int i;

    n=360/365.2422*j;
    i=n/360;
    n=n-i*360.0;
    x=n-3.762863;
    if (x<0) x += 360;
    x *= RAD;
    e=x;
    do {
    dl=e-.016718*sin(e)-x;
    e=e-dl/(1-.016718*cos(e));
    } while (fabs(dl)>=SMALL_FLOAT);
    v=360/PI*atan(1.01686011182*tan(e/2));
    l=v+282.596403;
    i=l/360;
    l=l-i*360.0;
    return l;
}

static double moon_position(double j, double ls)  
{

    double ms,l,mm,n,ev,sms,ae,ec;//,z,x;//,lm,bm,ec;
    //double d;
    //double ds, as, dm;
    int i;

    /* ls = sun_position(j) */
    ms = 0.985647332099*j - 3.762863;
    if (ms < 0) ms += 360.0;
    l = 13.176396*j + 64.975464;
    i = l/360;
    l = l - i*360.0;
    if (l < 0) l += 360.0;
    mm = l-0.1114041*j-349.383063;
    i = mm/360;
    mm -= i*360.0;
    n = 151.950429 - 0.0529539*j;
    i = n/360;
    n -= i*360.0;
    ev = 1.2739*sin((2*(l-ls)-mm)*RAD);
    sms = sin(ms*RAD);
    ae = 0.1858*sms;
    mm += ev-ae- 0.37*sms;
    ec = 6.2886*sin(mm*RAD);
    l += ev+ec-ae+ 0.214*sin(2*mm*RAD);
    l= 0.6583*sin(2*(l-ls)*RAD)+l;
    return l;
}

static double moon_phase2(int year,int month,int day, double hour, int* ip)  
{
    /*
      Calculates more accurately than Moon_phase , the phase of the moon at
      the given epoch.
      returns the moon phase as a real number (0-1)
      */

    double j= Julian(year,month,(double)day+hour/24.0)-2444238.5;
    double ls = sun_position(j);
    double lm = moon_position(j, ls);

    double t = lm - ls;
    if (t < 0) t += 360;
    *ip = (int)((t + 22.5)/45) & 0x7;
    return (1.0 - cos((lm - ls)*RAD))/2;
}

One input, two different results

Written by Michael Earls
 michael  development  programming  teaching  Gaming  Memories  writing

As if to give life to itself, two separate careers started as a simple "choose your own adventure" game on early 1980's home computers.

The setting

In the early 80's, myself and my best friend Joshua had home computers. Unfortunately, they were not the same model. He had the popular Apple II with the disk drives and I had the Coleco Adam with dual high speed tape drives.

Apple II

Apple II

Coleco ADAM Home Computer

Coleco ADAM Home Computer

However, despite being different hardware, they both shared the same version of the BASIC interpreter that allowed us to write code on one computer and manually transfer it to the other.

Natural role discovery

It quickly became evident that I enjoyed writing computer programs, but I wasn't that good at coming up with ideas for games. Joshua has an enormous imagination and is a natural writer. He easily found plenty of source material in his head to write stories that we turned into games. Games were not the only product of his imagination that I would emulate. He taught me how to just "let go" and not fuss over the technical details of writing comics and developed a simple "egg based" approach to character drawing. He would start with an oval and then fill in the details for each individual character. They each had enough detail to tell them apart, but not so much that drawing them got in the way of his story. Honestly, I was very jealous of his talents and worked hard to (unsuccessfully) emulate his process.

The game development process

We worked together on our games with him writing the stories and me expanding the computer code (he was also a good BASIC developer for the "choose your own adventure" style games that we created).

He would type the game into his computer, play it through, and then print it out on his printer. The next day, he would come over to my house with his printouts and I would manually type the program into my computer while he read the lines out. Doing it this way, I got to preview the results of decisions and how they led to either a nasty death or a victory. It was fun to play the game through because it was a matter of which decisions resulted in which outcomes.

I became more and more interested in how to expand on the simple GOTO statements and learned about subroutines (GOSUB statements that returned to where you left off) to provide more advanced logic. Eventually, I learned that you can POKE binary data to memory locations and take advantage of built-in capabilities of the computer. I also learned what an array was and how to take advantage of it to store related information for easy retrieval.

As I learned new programming tricks, I would share them with Joshua and they would show up in subsequent versions of his games.

It was a great partnership that grew into even more fun as we got older.

I have a big imagination and I am naturally creative. However, my creativity and imagination are very static and technical. I use my creativity to recognize and take advantage of technical abstractions and my imagination helps me envision ways to connect the abstract ideas with a concrete implementation (usually in the form of computer code). I occasionally stretch my wings with graphic design or music composition, but my gifts, talents, and experience are mostly related to computer software design and programming.

This has been developing in me since those early days when Joshua and I would partner to create all sorts of computer creations. He was always the idea factory and I would find a way to make it happen with his help. We had a lot of overlap because he had a good grasp of computer programming and I had a somewhat workable grasp of storytelling.

In addition to learning how to program, my parents bought me the MODEM add-on for the ADAM computer. It plugged into the peripheral bus and the telephone wire came out of the top of the unit and plugged into the wall. I used it to log into the local Bulletin Board Systems (BBS) in Atlanta and met people from all over the city.

ADAMLink MODEM

ADAMLink MODEM

It was the beginnings of the online systems (AOL - originally QuantumLink for C-64 users, Compuserve, EarthLink, etc.) These online systems were in place when the well-connected techie nerds began to offer consumer access to the budding Internet, which had previously only been accessible from colleges and government agencies. I was very much into the early days of the Internet and knew it was how I was going to make a living from a very early age. I can't imagine doing anything else.

I once built a speech digitizer for my Commodore 64 computer using the schematics from a home computer magazine. Once I finished it and tested that it worked, I didn't know what to do with it. Joshua was quick to find an application and we had a big laugh at the resulting confusion it generated.

As time went on and he moved away, I lost touch with Joshua. I recently learned that he has been very busy as a college educator and frequently teaches many of the topics that we grew up exploring together. He has published multiple novels and leads a group about academia on the web.

We are still the same people we were back then, but now we get to be adults about it and follow our passion to share our discoveries with the world.

He recently wrote a great article titled Would You Rather Read or Play a Novel? that inspired me to create this post. His article reminded me of the joy I get out of playing modern video games like "Elder Scrolls: Skyrim", where you wander around in an enormous open world, meeting people, doing side jobs, dungeon crawling, casting spells, and even crafting your own armor, weapons, and spells. Within this world are numerous book shelves. Most of the books on the shelves can be opened and read in-game. They contain small bits and pieces of the game lore that give you an insight into the environment you are playing in.

Elder Scrolls: Skyrim

Elder Scrolls: Skyrim

It's just a more advanced version of the very first games that we wrote back in the 80's, fleshed out to take advantage of modern graphics, sound, and computing power.

Even though we both started out as computer programmers and authors, one of us became a college professor and author and the other of us became a professional programmer and technology hobbyist.

I think the main point of this post is to communicate that it is important to follow your desires and work hard to pursue the things you are passionate about, turning them into a career.

In short, I like to say, "To get a great job, find something you love doing and convince someone to pay you to do it for them."

Controlling a 40106 Oscillator from Raspberry Pi

Written by Michael Earls
 diy  electronics  Lunetta  programming  development  synth  raspberry pi

I have been working with electronics lately moving slowly toward my end goal of creating circuits that can "create" their own "music".

As part of that journey, I have had to establish some baby steps in order to get there. Here are the basic steps I have accomplished so far:

  • Acquire a Raspberry Pi (or other microcontroller) - I chose the Raspberry Pi zero due to its small size (and great price- $5). I recommend the Raspberry Pi starter kit from Adafruit as it has everything you need to get started
  • Acquire basic electronic components - I ordered a lot of passive components (capacitors, resistors, transistors, jumper wires, breadboard, etc.). I've found that the best place to start is Amazon.com, then head over to Mouser Electronics for the little stuff (in big quantities), then All Electronics as a last resort. Adafruit Industries is the best place to buy add-ons, full kits, and great peripherals for your electronic projects.
  • Install an operating system on the Raspberry Pi - I am using Raspbian
  • Configure the WiFi using the serial cable (I don't have a USB hub, so I only had a single USB port on the Pi. This meant that I couldn't install the WiFi adapter and a keyboard & mouse). Once I had the serial adapter, I used PuTTY (I'm on Windows) to connect to the command line and configured WiFi from there
  • Once WiFi was configured, I installed an RDP server so I could use the Remote Desktop client to log into the desktop on the Pi. I rarely use this, but it's nice to have a desktop from time-to-time.
  • Install mono (cross-platform .NET runtime) - I use the C# programming language at my day job, so I'm comfortable with it. The Raspberry Pi supports many different programming languages, so pick the one you are comfortable with.
  • Install monodevelop on the Pi - monodevelop is the IDE that runs on Linux for developing .NET applications. This was not required, but I wanted to see if it would work. It did, without any issues.
  • Once I had the .NET runtime (mono) installed on my Pi, I opened up Visual Studio 2015 Community edition on my Windows 10 machine, added the raspberry-sharp-io NuGet package, and developed a simple application that toggles pin 7 (turning it on) when it starts up, waits for the user to press the ENTER key, then toggles pin 7 again (turning it off).

Here is the source code for my application (I learned the essentials from the raspberry-sharp-io wiki page):

using Raspberry.IO.GeneralPurpose;
using System;

namespace LunettaControl
{
  class Program
  {
    static void Main(string[] args)
    {
      var led1 = ConnectorPin.P1Pin07.Output();

      using (var connection = new GpioConnection(led1))
      {
        connection.Toggle(led1);

        Console.WriteLine("Press [Enter] to quit");
        Console.ReadLine();

        connection.Toggle(led1);
      }
    }
  }
}

Now I had to set up a circuit on my breadboard that controls a 40106 oscillator so that I can turn it on or off using C# and the Raspberry Pi.

Here is my schematic:

Gated Oscillator Schematic Revision 2

The Raspberry Pi is providing +5v that drives the 40106 and the 4093.

The oscillator (pins 1 and 2 of the 40106) is cycling at a fairly low frequency, as controlled by the 1M resistor and the 470nF capacitor (I haven't timed it as I don't have measuring equipment, though I will be able to write some with C# when I get into input pin management on the raspberry-sharp-io library).

I can now use this to control each individual oscillator on the 40106 independent of one another.

The key to making this work is the NAND gate (pins 1, 2, and 3 of the 4093). When combining the signals from the Raspberry Pi (Pin 7 in this case) and the output from the oscillator on pins 1 and 2, we can control the output on pin 3 of the NAND gate.


IC 4093 Quad 2-input Schmitt trigger NAND Gate

4093 Quad 2-input Schmitt trigger NAND Gate IC


40106 Hex Schmitt trigger IC(Logic Gates)

40106 Hex Schmitt trigger IC (Logic Gates)


That means that when Pin 7 of the Pi goes high, it will raise pin 1 of the gate. Then, each time the 40106 oscillates (it is constantly oscillating as long as power is being sent to the IC), it will trigger pin 2 to go high, which causes the gate to go high on pin 3, thereby causing the transistor to pass +3v to the LED and lighting it up (I wanted to isolate the voltage of the LED from the +5v that's driving the oscillator and gate circuit as a proof of concept for managing components with different voltage requirements).

This schematic is actually bad design. I have a few errors (mostly due to using the transistor incorrectly, as well as using an NAND gate rather than an AND gate).

It seems to be working now, but I'm not sure if it's absolutely correct.

The frequency of the blinking is controlled by the oscillator (because pin 7 of the Pi is staying high based depending on whether or not the program is running). When the program stops running, pin 1 of the gate goes low and the gate remains closed, thereby stopping the blinking (oscillator output). Currently, the LED stays lit. I'm guessing this is caused by using a NAND gate rather than an AND gate.

I'd like to thank the following users for their assistance in getting this circuit working (from the electro-music.com Lunetta forum)

Also, the excellent Intro to Lunetta CMOS Synths document helped me get started. Without it, I would not have known what CMOS chips to buy initially.

Intro to Lunetta CMOS Synths

Here is the thread I created on electro-music.com for my question on gating an oscillator:

Clock signals through a Transistor

The following video is similar to my first video about blinking an LED using C#, but this time, the blinking is the result of the oscillation of the 40106, not a timer built into the program. This program simply toggles pin 7 to the "On" position until the user presses the key and then toggles it off again. This video was created before I modified the schematic and removed the indicator LED.

"Zooming" into a map element using element coordinates

Written by Michael Earls
 development  javascript  GIS  DevExtreme  DevExpress  Mapping

I am still working on a map at work and I needed to be able to zoom into a map element when a user clicks on it. Originally, I was using the dxVectorMap.zoomLevel() method, but I realized that calculating the zoom level was harder than I thought.

Note: I covered the basics of working with the dxVectorMap in a previous post titled Working with Geographical data using Dev Extreme dxVectorMap

I then noticed that each map element has a coordinates() method that you can call that will return an array of points for the boundaries of the element. It uses those points to draw the boundary lines on the map.

So, I decided to write a simple two-dimensional loop to calculate the minimum and maximum latitude and longitude points on the element.

The way this works is that you loop through each point to find the largest latitude, the smallest latitude, the largest longitude, and the smallest longitude in the array and use these to build your bounds array.

Here is a simplified image to help describe the process:

Map boundary calculation demonstration

In the picture above, all of the red colored points ([50,1],[90,20], [1,60], and [52,95]) are the max and min values for their latitude and longitude. In this simple example, there are only four points that make up the boundaries.

The remaining points are unimportant as they are within the boundary of the other four major points.

Our goal in the code is to locate the extreme edges (the red points in our picture). To do this, we have to do some comparisons during our iteration of the array of 2D points. As I loop through the array of point arrays, there will be a massive number of points for this shape. We need to have 4 variables to keep up with our min and max values (min latitude, max latitude, min longitude, and max longitude). As we loop through the array, we'll check to see if the new value is higher than our highest and lower than our lowest values and store them accordingly.

Here is the code:

 var _cerkit = {  
    getElementBounds: function (elementCoordinates) {
        // loop through the element coordinates and find the bounds for the eastern-, western-, southern-, and northern-most points
        // return them as the bounds (can be used to set the viewport) and zoom level

        // prep the min and max values (with opposite values so we can compare min and max properly)
        var minLongitude = 180;
        var maxLongitude = -180;
        var minLatitude = 90;
        var maxLatitude = -90;

        for (var i = 0; i < elementCoordinates.length; i++) {
            for (var j = 0; j < elementCoordinates[i].length; j++) {

                // retrieve the latitude and longitude from the element points array
                var lng = elementCoordinates[i][j][0];
                var lat = elementCoordinates[i][j][1];

                if (lng > maxLongitude) {
                    maxLongitude = lng;
                } else if (lng < minLongitude) {
                    minLongitude = lng;
                }

                if (lat > maxLatitude) {
                    maxLatitude = lat
                } else if (lat < minLatitude) {
                    minLatitude = lat;
                }
            }
        }

        // return bounds (with adjustments for borders)
        return [(minLongitude - 0.05), (maxLatitude + 0.05), (maxLongitude  + 0.05), (minLatitude - 0.05)];
    }
};

After running this code on the shape represented by the picture above, our boundaries will be (dxVectorMap coordinates are ordered [longitude,latitude]):

min latitude = 1
min longitude = 1
max latitude = 95
max longitude = 90

So, our bounds would be (arranged according to the requirements of dxVectorMap, which are longitude first):

Order:

[minLongitude, maxLatitude, maxLongitude, minLatitude]

Example map

var sampleImageBounds = [[1,1],[1,90],[95,1],[95,90]];

Also, I adjusted each of the values by 0.05 to allow for space between the edges of the map element and the boundary. 0.05 is an arbitrary number that I picked that works well with my map at my zoom level. You may need to adjust this value according to the zoom level and boundary needs of your map.

Then, simply pass this array to a call to viewport() on the dxVectorMap widget:

$("mapContainer").dxVectorMap("instance").viewport(_cerkit.getElementBounds(selectedDistrict.coordinates()));

See the dxVectorMap documentation for more information on using coordinates() and viewport().

"This was due last week!" - The Unicorn Software Project

Written by Michael Earls
 development  software  magic  project management

I was just perusing a forum about software jobs and the topic came up of companies expecting their software developers to work 80-100 hour work weeks as a W-2 employee (no overtime) in a right-to-work state (you can be laid off for any legal reason at any time) just to get software released "on time".

The comment was made that some software needs to "get done fast and get done yesterday".

I don't think that any software project ever needs to "get done fast and get done yesterday". In my experience, this is just the money-men pushing the workers as hard as they can to squeeze whatever profits they can out of the situation. If employees are willing to suffer for 40 extra hours in a work week for the same pay, why would management offer anything better?

If you knew that bridge engineers were cutting corners and working without sleeping to build a bridge before some arbitrary date came to pass, would you feel comfortable driving across it?

It all comes down to the fundamental question in software engineering: "How long is a piece of string?"

Using LightBox 2 with Cloudinary to generate thumbnails

Written by Michael Earls
 development  imaging  lightbox  cloudinary

Cloudinary is a cloud host for images that provides many features for manipulating images and serving them to your users in various formats. Cloudinary can transform your original images into other formats, as well as allow you to add transformations such as scaling, coloring, cropping, and many more.

Here is a simple example of what it can do when combined with a Light Box control.

cerkit off-air image thumbnail
click me!

This post uses the LightBox 2 plugin from @lokesh.

The above image has a thumbnail generated by using a different url to Cloudinary. The Light Box uses the full size image.

The link to the full size image is:

/image/upload/v1469237795/cerkit-off-air-16x9_sc0w3s.png

The link to the thumbnail is almost exactly the same, except it has the image width included as a transformation in the url, like so:

/image/upload/c_scale,w_200/v1469237795/cerkit-off-air-16x9_sc0w3s.png

There are many other transformations available from Cloudinary, this is just a small example.

In the following example, I will use Cloudinary's great scaling and zooming features to generate a series of images that will "zoom" in on the logo at the top right. I will do so by using Lightbox 2's grouping (use the same data-lightbox attribute values for all images to create a group).

Click on any of these images to see the non-transformed, full-size image
Each image group will display arrows on the right or left that you can use to navigate between them

cerkit off-air image thumbnail zoomed out

cerkit off-air image zoomed x2

cerkit Off-Air image zoomed and adjusted

The above three images were all stored on Cloudinary as a single image. The only difference was the url I used to access it. Each url has a different transformation applied to give me the desired result.

You can also apply different artistic effects. Here, I have pixelated my face:

pixelate face image

You can also apply an oil paint transformation:

Michael Earls oil painted face image

Better property names using the DataMember attribute

Written by Michael Earls
 development  json  C#  .NET  serialization

In my previous post, I demonstrated creating a class to serialize the data returned from the Lipsum.com JSON feed. I wasn't happy with the final result as it used JavaScript formatting for the property names (camel cased).

I prefer Pascal casing on my object properties in C#, so I wanted to quickly show how to change the name of the property on the class.

Here is the new LoremIpsum class definition:

public class LoremIpsum
{
    public Feed Feed { get; set; }
}

[DataContract]
public class Feed
{
    [DataMember(Name ="lipsum")]
    public string Lipsum { get; set; }

    [DataMember(Name = "generated")]
    public string Generated { get; set; }

    [DataMember(Name = "donatelink")]
    public string DonateLink { get; set; }

    [DataMember(Name = "creditlink")]
    public string CreditLink { get; set; }

    [DataMember(Name = "creditname")]
    public string CreditName { get; set; }
}

You'll first need to add a reference to System.Runtime.Serialization to your project. Then, include the System.Runtime.Serialization namespace in your using declarations.

The main() method now looks like this:

static void Main(string[] args)
{
    for (int i = 0; i < 10; i++)
    {
        // toggle between words and paragraphs
        bool isEven = (i % 2).Equals(0); // used this because markdown had trouble with double equal signs
        bool isThird = (i % 3).Equals(0);
        LipsumType lipsumType = isEven ? LipsumType.Paragraphs : LipsumType.Words;

        // only start with Lorem Ipsum every third call
        Debug.WriteLine(LoremIpsumUtil.GetNewLipsum(lipsumType, 7, isThird).Feed.Lipsum + Environment.NewLine);

        // sleep for 1 second to give the server a rest
        Thread.Sleep(1000);
    }
}

The main difference is that now, we use LoremIpsumUtil.GetNewLipsum(lipsumType, 7, isThird).Feed.Lipsum.

As you can see, our properties are now Pascal cased, so they look more in line with what you'll see throughout the other .NET libraries.

Getting filler text from the Lipsum.com REST API

Written by Michael Earls
 development  programming  C#  json  lorem ipsum

I had the need to generate some random filler text for a bunch of records today, and I wanted to use the Lorem Ipsum latin text. Normally, I use the great website Lipsum.com and fill out the form and hit submit. Then, I copy the text provided into my destination.

(This project (reusable .NET class library and sample app) can be found on GitHub at https://github.com/cerkit/LoremIpsum/)

However, I needed to automate this process, so I did a little poking around. It turns out that the lipsum.com website exposes a json feed that can be altered based on your needs.

Note: Using the Lipsum website in this manner is placing stress on their web server. As such, I highly suggest using the donate link provided within the data set that is returned to provide them with a little money to support your efforts.

I wrote my code in such a way as to limit the call rate to one call per second. It took a lot longer to insert my records than I wanted, but I felt sure I wasn't putting unneeded strain on their servers.

The main endpoint for accessing the default data set is: http://lipsum.com/feed/json.

This will give you the following results:

{
    feed: {
        lipsum: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras tristique massa eu porttitor aliquam. Vivamus sodales sit amet nulla nec volutpat. Sed accumsan iaculis turpis, maximus sagittis ipsum tincidunt et. Cras ac velit eu quam cursus lobortis sit amet vitae quam. Donec nec odio at ligula porttitor viverra nec eu est. Praesent non quam ipsum. Curabitur vitae scelerisque augue. In sed elementum velit. Donec lacinia ut leo a porttitor. Phasellus nec risus placerat, pulvinar ante euismod, tempus lacus. Nam turpis velit, accumsan eget placerat porttitor, hendrerit vitae tortor. Vivamus posuere leo elit, at pretium justo imperdiet id. Duis finibus ante vel mollis rhoncus. Donec sollicitudin sed tortor vulputate bibendum. Aenean tincidunt nisi sed libero sollicitudin, in interdum erat efficitur. Phasellus porttitor faucibus risus non consectetur. Nam a sollicitudin erat, ut lacinia leo. Praesent convallis odio orci, a iaculis lacus viverra non. Maecenas consequat, risus nec egestas consectetur, tellus tellus condimentum mi, in suscipit metus sem quis velit. In a lorem semper, tincidunt mauris a, blandit erat. Aliquam non auctor tortor, et mattis nibh. Aenean at magna at diam commodo feugiat sit amet ut erat. Nunc hendrerit tempus imperdiet. Phasellus varius id justo non vestibulum. Ut quis mollis mauris. Aliquam egestas arcu non erat congue, id ornare elit molestie. Pellentesque rutrum nunc sed arcu semper mollis. Proin malesuada tristique quam quis luctus. Nunc dignissim, orci vitae rhoncus porta, orci enim accumsan urna, ut egestas metus lectus id turpis. Sed in nisi ligula. Etiam sodales est arcu, vitae dignissim metus blandit id. Aenean leo velit, blandit sit amet ex vel, vestibulum ornare ipsum. Donec rutrum euismod velit, ac fringilla leo iaculis ornare. Duis a eros id odio aliquet vestibulum quis vel est. Sed ultricies ac sapien sed tincidunt. Integer bibendum turpis at nisl venenatis facilisis. Morbi sodales dignissim lectus, non sagittis purus cursus dignissim. Phasellus aliquam elementum venenatis. Nunc sed pharetra purus, id blandit velit. In sed massa consequat, posuere nulla non, rhoncus orci. Maecenas a consequat lorem. Morbi sit amet quam felis. Sed at posuere metus. Morbi vestibulum nisl id massa euismod malesuada. Aenean accumsan, elit eu finibus pellentesque, elit metus faucibus tellus, non interdum lacus massa ut velit. Suspendisse fermentum elit sed ipsum luctus consequat. Suspendisse potenti. Aenean sagittis lorem augue, quis condimentum velit facilisis eu. Vivamus posuere ante sed porta fringilla. Morbi pharetra lorem id urna iaculis cursus. Pellentesque at arcu vel lacus euismod accumsan. Sed pretium turpis odio, id tincidunt nisi blandit nec. Suspendisse non ornare massa. Proin facilisis porta dolor nec vestibulum. Aenean accumsan pulvinar magna, in auctor odio tempor eget. Morbi in rutrum quam. Fusce quis ipsum augue. Duis et ligula ut tellus sollicitudin rutrum sit amet eget nisi. Duis id est sit amet orci venenatis consectetur et eget ipsum.",
        generated: "Generated 5 paragraphs, 454 words, 3017 bytes of Lorem Ipsum",
        donatelink: "http://www.lipsum.com/donate",
        creditlink: "http://www.lipsum.com/",
        creditname: "James Wilson"
    }
}

I decided to take a look at the source code for the home page and get an idea of the form names that are used to set the options for the feed.

I found the following query string arguments

  • what: valid values = paras, words, bytes, and lists
  • amount: the amount of the chosen type to return (the minimum value is 5 for words)
  • start: yes or no depending on whether or not you want to start with "Lorem Ipsum". If set to no, you'll get a random return value.

So, I wrote my program to loop through the days in the current year and insert a record for each day, adding the random "lipsum" text to the record.

Here's a quick C# program that will use the Newtonsoft.Json library to deserialize the lipsum result into an object that you can use in your code.

This assumes that you're using Visual Studio (community or professional edition).

First, visit the following url: http://lipsum.com/feed/json?amount=5&start=no&what=words

Now, view the source of the results and copy them to your clipboard. Start a new project in Visual Studio (if you don't already have one open) and then create a new class. Name the file LoremIpsum.cs.

It will generate the following code:

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Threading.Tasks;

namespace LoremIpsum  
{
    class LoremIpsum
    {
    }
}

Delete the class LoremIpsum that it generated (but keep the rest of the file).

Click inside the namespace and choose Edit->Paste Special->Paste JSON as Classes from the main menu.

This will insert classes that are compatible with the lipsum data. Rename the Rootobject class to LoremIpsum. Your code should look like the following (LoremIpsum.cs):

namespace LoremIpsum  
{
    public class LoremIpsum
    {
        public Feed feed { get; set; }
    }

    public class Feed
    {
        public string lipsum { get; set; }
        public string generated { get; set; }
        public string donatelink { get; set; }
        public string creditlink { get; set; }
        public string creditname { get; set; }
    }

}

Now, we will need to fetch the data and deserialize it into an object we can use.

Before we continue, make sure you have a reference to the Newtonsoft.Json library. You can use nuGet to install it easily.

First, we'll define an enum to represent the result types:

public enum LipsumType  
{
    [Description("words")]
    Words,
    [Description("paras")]
    Paragraphs,
    [Description("bytes")]
    Bytes,
    [Description("lists")]
    Lists
}

Notice that I used the System.ComponentModel.Description attribute on each of the enum values to represent the values that need to get sent to the api. This will come in handy later.

Here is a generic extension method on enums that will return the description (this works on any enum containing values decorated with the System.ComponentModel.DescriptionAttribute class):

public static string GetDescription(this T e) where T : IConvertible  
{
    Array values = System.Enum.GetValues(e.GetType());
    string description = null;

    foreach (int val in values)
    {
        if (val == e.ToInt32(CultureInfo.InvariantCulture))
        {
            var type = e.GetType();
            var memInfo = type.GetMember(Enum.GetName(type, val));
            var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
            description = ((DescriptionAttribute)attributes[0]).Description;
        }
    }

    return description;
}

Now, let's move on to the actual web call:

public static readonly string LIPSUM_JSON_URL = "http://lipsum.com/feed/json?amount={0}&start={1}&what={2}";

public static LoremIpsum GetNewLipsum(LipsumType lipsumType, int amount, bool startWithLoremIpsum = true, ICredentials proxyCredentials = null)  
{
    string requestUrl = string.Format(LIPSUM_JSON_URL, amount, startWithLoremIpsum ? "yes" : "no", lipsumType.GetDescription());

    HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;

    if (proxyCredentials != null)
    {
        request.Proxy.Credentials = proxyCredentials;
    }

    using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
    {
        if (response.StatusCode != HttpStatusCode.OK)
            throw new Exception(String.Format(
            "Server error (HTTP {0}: {1}).",
            response.StatusCode,
            response.StatusDescription));

        StreamReader sr = new StreamReader(response.GetResponseStream());
        JsonTextReader tr = new JsonTextReader(sr);
        JsonSerializer ser = new JsonSerializer();

        return ser.Deserialize(tr);
    }
}

In the requestUrl definition, I used the LipsumType.GetDescription() extension method that I defined earlier to send the correct type based on what was chosen by the caller.

Don't forget to use the using() {} when dealing with an object that implements IDisposable. It will clean up after you and prevent you from leaving any machine resources open.

Notice the use of the ser.Deserialize<LoremIpsum>() call (GitHub source). I was able to do this because we created a class directly from the JSON data. We then use this class with the Json (de)serializer to get an instance of the LoremIpsum class containing the results of our call.

Here is the main() method of the program that ties it all together:

static void Main(string[] args)
{
    for (int i = 0; i < 10; i++)
    {
        // toggle between words and paragraphs
        bool isEven = (i % 2) == 0;
        bool isThird = (i % 3) == 0;
        LipsumType lipsumType = isEven ? LipsumType.Paragraphs : LipsumType.Words;

        // only start with Lorem Ipsum every third call
        Debug.WriteLine(LoremIpsumUtil.GetNewLipsum(lipsumType, 7, isThird).feed.lipsum + Environment.NewLine);

        // sleep for 1 second to give the server a rest
        Thread.Sleep(1000);
    }
}

This simply loops 10 times and makes a call to the lipsum.com json endpoint, toggling between paragraphs and words, as well as starting with "Lorem Ipsum" every third call. It also waits one second between each call to be friendly to the server.

Because we get back a fully populated object, we can also access the other properties on the LoremIpsum instance, like *.feed.generated and *.feed.donatelink.

Update: I've written a post that describes how to get PascalCased property names.