Skip to main content

The World's Biggest Citizen Science Project

2 weeks 3 days ago
eBird, now the world's largest citizen science project with over 2 billion bird observations, is transforming ornithology by turning casual birders (and even TikTok-using kids) into vital contributors to global research and conservation. Slashdot reader alternative_right shares a report from Phys.org: The Cornell Lab of Ornithology has been one of the most influential organizations in the world when it comes to encouraging people to engage in natural history projects. While some form of amateur involvement in science projects has been around since 1900, when the Audubon Society organized the first Christmas Bird Count, it was the Cornell Lab that formalized citizen science as a sound and reliable means of collecting data on birds. It didn't take much thought to realize that one of the richest sources of information about birds resided in the notebooks virtually every birder has kept, often from childhood. It's a given that birdwatchers list everything. The problem is that zillions of such notebooks sit forgotten in drawers or in dusty boxes in the attic. If only all of that information could be gathered together, organized in sensible ways and then made available to anyone who wanted to use it. What a resource that would be! After lots of trials and discussion, a small team at the Lab came up with the idea of eBird. It started in a humble way back in 2002, as simply somewhere birders could store their records in a central location. Today, "humble" is no longer an appropriate description. In 2022, its 20th anniversary year, a total of more than 1.3 billion records had been received from more than 820,000 participants. In the month of August this year, reports eBird, 123,000 birders submitted 1.6 million lists of sightings. It has now hit a total of 2 billion bird observations since inception.

Read more of this story at Slashdot.

BeauHD

CodeSOD: A JSON Serializer

2 weeks 3 days ago

Carol sends us today's nasty bit of code. It does the thing you should never do: serializes by string munging.

public string ToJSON() { double unixTimestamp = ConvertToMillisecondsSinceEpoch(time); string JSONString = "{\"type\":\"" + type + "\",\"data\":{"; foreach (string key in dataDict.Keys) { string value = dataDict[key].ToString(); string valueJSONString; double valueNumber; bool valueBool; if (value.Length > 2 && value[0].Equals('(') && value[value.Length - 1].Equals(')')) //tuples { char[] charArray = value.ToCharArray(); charArray[0] = '['; charArray[charArray.Length - 1] = ']'; if (charArray[charArray.Length - 2].Equals(',')) charArray[charArray.Length - 2] = ' '; valueJSONString = new string(charArray); } else if ((value.Length > 1 && value[0].Equals('{') && value[value.Length - 1].Equals('}')) || (double.TryParse(value, out valueNumber))) //embedded json or numbers { valueJSONString = value; } else if (bool.TryParse(value, out valueBool)) //bools { valueJSONString = value.ToLower(); } else //everything else is a string { valueJSONString = "\"" + value + "\""; } JSONString = JSONString + "\"" + key + "\":" + valueJSONString + ","; } if (dataDict.Count > 0) JSONString = JSONString.Substring(0, JSONString.Length - 1); JSONString = JSONString + "},\"time\":" + unixTimestamp.ToString() + "}"; return JSONString; }

Now, it's worth noting, C# already has some pretty usable JSON serialization built-ins. None of this code needs to exist in the first place. It's parsing across a dictionary, but that dictionary is itself constructed by copying properties out of an object.

What's fun in this is because everything's shoved into the dictionary and then converted into strings (for the record, the dictionary stores objects, not strings) the only way they have for sniffing out the type of the input is to attempt to parse the input.

If it starts and ends with a (), we convert it into an array of characters. If it starts and ends with {} or parses as a double, we just shove it into the output. If it parses as a boolean, we convert it to lower case. Otherwise, we throw ""s around it and put that in the output. Notably, we don't do any further escaping on the string, which means strings containing " could do weird things in our output.

The final delight to this is the realization that their method of handling appending will include an extra comma at the end, which needs to be removed. Hence the if (dataDict.Count > 0) check at the end.

As always, if you find yourself writing code to generate code, stop. Don't do it. If you find you actually desperately need to start by building a syntax tree, and only then render it to text. If you find yourself needing to generate JSON specifically, please, I beg you, just get a library or use your language's built-ins.

[Advertisement] Plan Your .NET 9 Migration with Confidence
Your journey to .NET 9 is more than just one decision.Avoid migration migraines with the advice in this free guide. Download Free Guide Now!
Remy Porter