Shallow Thoughts : : Aug

Akkana's Musings on Open Source Computing and Technology, Science, and Nature.

Tue, 27 Aug 2019

Plane Fishing

[plane fishing] White Rock has a "glider port", which is just an informal spot along the edge of the canyon where sometimes people fly R/C sailplanes. On days when the winds are right, gliders can get some pretty good lift.

Last Sunday wasn't one of those days. The wind was coming from every direction but east, so the gliders were having to use their motors periodically to climb back up to altitude.

I was mostly trying to stay above the canyon rim, but I noticed all the other pilots were flying down below, so I decided maybe it wasn't that dangerous to let my plane get a little below the edge for a while before starting the motor. Wrong! Below the edge of the canyon, there's a risk of catching some evil rotors off the cliffs. One of those rotors caught my glider's wing and tossed it into a spiral. I was able to recover and get the plane flying straight again -- straight toward the cliff. It smacked hard -- I saw parts flying everywhere.

I didn't expect that the plane itself was salvageable -- it's only styrofoam, after all -- though it looked surprisingly intact. In any case, Dave and I hoped to recover the components: battery, motor, receivers, servos. Hiking to the plane proved difficult: you can get fairly near there on the Blue Dot trail, but then you need to climb three levels of cliff to reach the place where the plane sat. Coming down from above definitely would have required rapelling gear.

But Dave had an idea: let's go fishing!

It took some experimenting to figure out what sort of hook, line and pole you need to fish for a thirty-ounce plane that's fifty feet down a sheer cliff out of sight from the cliff above it. Dave did the fishing and I acted as the caller, sitting some hundred feet away where I could spot the plane through binoculars and shout out which direction he needed to move the line. But we got it in the end! I shot some quick snapshots while I wasn't busy spotting, which you can see here: Plane Fishing (photos).

[plane on the hook] Amazingly, the plane was almost undamaged. The plastic spinner was destroyed, but the motor seems fine. The nose of the plane is very slightly askew but not broken. The battery, after being plugged in to the receiver for 48 hours, was down to zero volts, but when we charged it carefully, it took a charge. The canopy went flying off at the moment of impact and is down there in the rocks somewhere, so I have a new canopy, spinner and collet on backorder, but in the meantime, the plane is probably flyable. I'll find out this weekend -- but if we fly at the gliderport, I'm not letting it get lower than cliff level, ever!

Tags:
[ 16:57 Aug 27, 2019    More misc | permalink to this entry | comments ]

Tue, 06 Aug 2019

Update on my Rescued Nestlings

Last month I wrote about the orphaned nestlings I found on the ground off the back deck, and how I took them to a rehabilitator when the parents didn't come back to feed them.

Here's the rest of the story. Warning: it's only half a happy ending.

[Nestlings starting to feather out] Under the good care of our local bird rehabilitator, they started to feather out and gain weight quickly. She gave me some literature on bird rescue and let me visit them and help feed them. There's a lot of work and responsibility involved in bird rehabilitation!

[Nestlings starting to feather out] I'd sometimes thought I wanted to be a rehabilitator; now I'm not so sure I'm up to the responsibility. Though the chicks sure were adorable once they started to look like birds instead of embryos, sitting so trustingly in Sally's hand.

[Looking more like a bird] The big mystery was what species they were. Bird rehabilitators have charts where you can look up bird species according to weight, mouth color, gape color, skin color, feather color, and feet and leg size. But the charts only have a few species; they're woefully incomplete, and my babies didn't match any of the listings. We were thinking maybe robin or ash-throated flycatcher, but nothing really matched.

Fortunately, you can feed the same thing to anything but finches: Cornell makes a mixture of meat, dog food, vitamins and minerals that's suitable for most baby birds, though apparently it's dangerous to feed it to finches, so we crossed our fingers and guessed that they were too big to be house finches.

As they grew more feathers, Sally increasingly suspected they were canyon towhees (a common bird in White Rock), and although they still didn't have adult plumage by the time they left the cage, that's still what we think.

[Hopping alertly around the cage now] By about twenty days after the rescue, they were acting almost like adult birds, hopping restlessly around the cage, jumping up to the perch and fluttering back down. They were eating partly by themselves at this point, a variety of foods including lettuce, blueberries, cut up pea pods, and dried mealworms, though they weren't eating many seeds like you'd expect from towhees. They still liked being fed the Cornell meat mixture, and ate more of that than anything else.

I Get to be a Bird Mom For a While

At this point, Sally needed to go out of town, and I offered to babysit them so she didn't have to take them on her trip. (One of the big downsites of being a rehabilitator: while you're in charge of babies, they need constant care.) I took them back to my place, where I hoped I'd be able to release them: partly because they'd been born here, and partly because the towhees here in White Rock aren't so territorial as they apparently are in Los Alamos.

With the chicks safely stashed in the guest bedroom, I could tell they were getting restless and wanted out of the cage. When I opened the cage to feed them and change their water and bedding, they escaped out into the room a couple of times and I had to catch them and get them back in the cage. So I knew they could fly and wanted out. (I'm sure being moved from Sally's house to mine didn't help: the change in surroundings probably unnerved them.)

Sally advised me to leave the cage outside during the day for a couple of days prior to the releasing, so the birds can get used to the environment. The first day I put them outside, they immediately seemed much happier and calmer. It seemed they liked being outside.

I Fail as a Bird Mom

On their second morning outdoors, I left them with new food and water, then came back to check on them an hour later. They seemed much more agitated than before, flying madly from one side of the cage to the other. Sally had described her last tenant, a sparrow, doing that just before release; she had released the sparrow a bit earlier than planned because the bird seemed to want out so badly. I wondered if that was the case here, but decided to wait one more day.

But the larger of the two babies had other ideas. When I unzipped the top of the cage to re-fill the water dish, it was in the air immediately, and somehow shot through the tiny opening next to my arm.

It flew about thirty feet, landed in a clearing -- and was immediately taken by a Cooper's hawk that came out of nowhere.

The hawk flew off, the baby towhee squeaking pathetically in its talons, leaving me and the other baby in shock.

What a blow! The bird rescue literature Sally loaned me stresses that bad things can happen. There are so many things that can go wrong with a nestling or a release. They tell you how poor the odds are for baby birds in general. They remind you that the birds would have had no chance of survival if you hadn't rescued them; rescued, at least they have some chance.

While I know that's all true, I'm not sure it makes me feel much better.

In hindsight, Sally said the chicks' agitation that day might have been because they knew the hawk was there, though neither of us though about that possibility at the time. She thinks the hawk must have been "stalking them", hanging out nearby, aware that there was something delectable inside the cage. She's had chicks taken by hawks too. Still ... sigh.

The Next Release Goes Better

But there was still the remaining chick to think about. Sally and I discussed options and decided that I should bring the chick back inside, and then drive it back up to her house. The hawk would probably remain around my place for a while,and the area wouldn't be safe for a new fledgling. Indeed, I saw the hawk again a few days later. (Normally I love seeing Cooper's hawks!)

The chick was obviously unhappy, whether because of being brought back inside, loneliness, or remaining trauma from hearing the attack -- even if it didn't understand exactly what had happened, I'm sure the chick heard the "towhee in mortal peril" noises just as I did.

So the chick (whom Dave dubbed "Lucky") had to wait another several days before finally being released.

The release went well. Lucky, less bold than its nestmate, was initially reluctant to leave the cage, but eventually fluttered out and flew to the shade of a nearby bush, where we could see it pecking at the ground and apparently eating various unidentifiable bits. It looked like it was finding plenty to eat there, it was mostly hidden from predators and competetors, and it had shade and shelter -- a good spot to begin a new life.

(I tried to get a video of the release but that didn't work out.)

Since then the chick has kept a low profile, but Sally thinks she saw a towhee fledgling a couple of days later. So we have our fingers crossed!

More photos: Nestling Rescue Photos.

Tags: ,
[ 09:50 Aug 06, 2019    More nature/birds | permalink to this entry | comments ]

Thu, 01 Aug 2019

Silly Moon Names: a Nice Beginning Python Project

Every time the media invents a new moon term -- super blood black wolf moon, or whatever -- I roll my eyes.

[Lunar Perigee and Apogee sizes] First, this ridiculous "supermoon" thing is basically undetectable to the human eye. Here's an image showing the relative sizes of the absolute closest and farthest moons. It's easy enough to tell when you see the biggest and smallest moons side by side, but when it's half a degree in the sky, there's no way you'd notice that one was bigger or smaller than average.

Even better, here's a link to an animation of how the moon changes size and "librates" -- tilts so that we can see a little bit over onto the moon's far side -- during the course of a month.

Anyway, the media seem to lap this stuff up and every month there's a new stupid moon term. I'm sure nearly every astronomer was relieved to see the thoroughly sensible Gizmodo article yesterday, Oh My God Stop It With the Fake Moon Names What the Hell Is a 'Black Moon' That Isn't Anything. Not that that will stop the insanity.

If You Can't Beat 'Em, Join 'Em

And then, talking about the ridiculous moon name phenom with some friends, I realized I could play this game too. So I spent twenty minutes whipping up my own Silly Moon Name Generator.

It's super simple -- it just uses Linux' built-in dictionary, with no sense of which words are common, or adjectives or nouns or what. Of course it would be funnier with a hand-picked set of words, but there's a limit to how much time I want to waste on this.

You can add a parameter ?nwords=5 (or whatever number) if you want more or fewer words than four.

How Does It Work?

Random phrase generators like this are a great project for someone just getting started with Python. Python is so good at string manipulation that it makes this sort of thing easy: it only takes half a page of code to do something fun. So it's a great beginner project that most people would probably find more rewarding than cranking out Fibonacci numbers (assuming you're not a Fibonacci geek like I am). For more advanced programmers, random phrase generation can still be a fun and educational project -- skip to the end of this article for ideas.

For the basics, this is all you need: I've added comments explaining the code.

import random


def hypermoon(filename, nwords=4):
    '''Return a silly moon name with nwords words,
       each taken from a word list in the given filename.
    '''
    fp = open(filename)
    lines = fp.readlines()

    # A list to store the words to describe the moon:
    words = []
    for i in range(nwords):    # This will be run nwords times
        # Pick a random number between 0 and the number of lines in the file:
        whichline = random.randint(0, len(lines))

        # readlines() includes whitespace like newline characters.
        # Use whichline to pull one line from the file, and use
        # strip() to remove any extra whitespace:
        word = lines[whichline].strip()

        # Append it to our word list:
        words.append(word)

    # The last word in the phrase will be "moon", e.g.
    # super blood wolf black pancreas moon
    words.append("moon")

    # ' '.join(list) combines all the words with spaces between them
    return ' '.join(words)


# This is called when the program runs:
if __name__ == '__main__':
    random.seed()

    print(hypermoon('/usr/share/dict/words', 4))

A More Compact Format

In that code example, I expanded everything to try to make it clear for beginning programmers. In practice, Python lets you be a lot more terse, so the way I actually wrote it was more like:

def hypermoon(filename, nwords=4):
    with open(filename, encoding='utf-8') as fp:
        lines = fp.readlines()

    words = [ lines[random.randint(0, len(lines))].strip()
              for i in range(nwords) ]
    words.append('moon')
    return ' '.join(words)

There are three important differences (in bold):

Opening a file using "with" ensures the file will be closed properly when you're done with it. That's not important in this tiny example, but it's a good habit to get into.

I specify the 'utf-8' encoding when I open the file because when I ran it as a web app, it turned out the web server used the ASCII encoding and I got Python errors because there are accented characters in the dictionary somewhere. That's one of those Python annoyances you get used to when going beyond the beginner level.

The way I define words all in one line (well, it's conceptually one long line, though I split it into two so each line stays under 72 characters) is called a list comprehension. It's a nice compact alternative to defining an empty list [] and then calling append() a bunch of times, like I did in the first example.

Initially they might seem harder to read, but list comprehensions can actually make code clearer once you get used to them.

A Python Driven Web Page

Finally, to make it work as a web page, I added the CGI module. That isn't really a beginner thing so I won't paste it here, but you can see the CGI version at hypermoon.py on GitHub.

I should mention that there's some debate over CGI in Python. The movers and shakers in the Python community don't approve of CGI, and there's a plan to remove it from upcoming Python versions. The alternative is to use technologies like Flask or Django. while I'm a fan of Flask and have used it for several projects, it's way overkill for something like this, mostly because of all the special web server configuration it requires (and Django is far more heavyweight than Flask). In any case, be aware that the CGI module may be removed from Python's standard library in the near future. With any luck, python-cgi will still be available via pip install or as Linux distro packages.

More Advanced Programmers: Making it Funnier

I mentioned earlier that I thought the app would be a lot funnier with a handpicked set of words. I did that long, long ago with my Star Party Observing Report Generator (written in Perl; I hadn't yet started using Python back in 2001). That's easy and fun if you have the time to spare, or a lot of friends contributing.

You could instead use words taken from a set of input documents. For instance, only use words that appear in Shakespeare's plays, or in company mission statements, or in Wikipedia articles about dog breeds (this involves some web scraping, but Python is good at that too; I like BeautifulSoup).

Or you could let users contribute their own ideas for good words to use, storing the user suggestions in a database.

Another way to make the words seem more appropriate and less random might be to use one of the many natural language packages for Python, such as NLTK, the Natural Language Toolkit. That way, you could control how often you used adjectives vs. nouns, and avoid using verbs or articles at all.

Random word generators seem like a silly and trivial programming exercise -- because they are! But they're also a fun starting point for more advanced explorations with Python.

Tags: , , ,
[ 14:24 Aug 01, 2019    More humor | permalink to this entry | comments ]