Somehow, I didn’t have the source code for ffcollection under version control.
No idea how I managed that, since it’s usually the first thing I do. Stranger
still that I didn’t notice I wasn’t occasionally committing—I don’t use any
kind of automatic committing tool, so I’m usually typing ‘hg commit’ after
pretty much any little change. Version numbers are free, after all. Anyway, I
remedied that, and made some more progress. I need to make some minor changes to
the database schema, and the whole thing needs some serious refactoring, but
it’s coming along pretty nicely. Certainly it’s useful for me. Now, if only I
could make an interface that wasn’t horrible, I’d be pretty happy with things.
Well, some day.
I mentioned previously that I was working on a fanfiction database. Well, time
for an update: it’s in a functional state, though quite basic. I can feed it a
FanFiction.Net ID and it will download the fanfic and put it in the database
with some very basic metadata (author, ID, summary). Most recently, I’ve hacked
together an HTTP server using http.server
so that I can accept commands over
HTTP. Currently, the only command it accepts is ‘add the fanfic at this URL’,
and it just responds with a status page and a copy of the form to add the fic to
favoritestracker. I really should use something a little more powerful than just
http.server.BaseHTTPRequestHandler
for this—I really ought to create a
full-fledged web interface, instead of just a commands-over-http hack. But, for
the moment, that’s what I’ve got.
I did a little cleanup on the code for 750-to-org, so I went ahead and called it
0.2. I did some more testing, so unless 750 Words does something quite
unexpected, 750-to-org should just work.
I should probably set 750-to-org up so you can give it filenames as arguments,
but other than that, I can’t think of much else I’d want it to do. I could have
it verify that it’s putting entries in the right places, in case the exports are
processed out of order, but that just seems like more work than is necessary.
Unless someone complains about it, I’m just going to leave it.
I’ve neglected this blog, which I really shouldn’t have done. Well:
I must reiterate what I said in my last post: when adding tags, I should
definitely specify the revision I want to tag, because I keep making stupid
mistakes, tagging the wrong revisions.
That said, new project:
750-to-org. It’s just a
little python script to convert my 750 Words exports into a suitable format for
emacs org-mode. Nothing special, but I wanted it, so I figured I’d put it out
there in case anyone else might have a use for it. I did learn a little more
about datetime by doing it, too. I doubt I’ll ever remember the meanings of the
tokens for strftime, but at least I know it exists, now. It’s much cleaner that
the way I was going to produce the date strings.
I’ve got a python/sqlalchemy fanfiction database thing I’m making for my
personal use, but it’s far from being in a fit state for public consumption.
More on that later, perhaps.
I just wasted half a dozen revisions trying to tag a release. Perhaps it’d be
better to just always specify the revision you’re tagging, just to avoid that problem.
Written by Tracy Poff in misc on Sun 16 May 2010. Tags: wordspy,
As of the most recent revision (r18:6453f11b96e6), WordsPy functions as a (bad)
game. The dictionary is hooked up, and it only lets you remove letters if they
form a word in the dictionary (That’s a rule. Games have rules. Ergo, game. Right?).
Other features:
- Selected letters are highlighted
- Backspace support
- Nonstop key-pressing action!
Next steps will be arranging it so the letter generator provides useful letters
rather than just random ones (probably just analyze the dictionary for letter
frequencies and use that), creating some kind of status display, and additional
nice things (score? list of words you made in that session? difficulty levels?
the possibilities are endless!)
Edit: and a screenshot for posterity.
Well, the bad news is that wordspy still does nothing other than scroll new
lines onto the screen. The good news is that it does it in a better way.
In order to deal with letters dropping (due to letters below them being removed)
at the same time as a new line was scrolling up, it was necessary to re-engineer
the whole thing. Now letters store their current location, and it’s modified
whenever necessary by the newlinescroll and drop actions. This does have some
other benefits, too. For example, it simplifies drawing the new line onto the
screen somewhat. Before, I was doing:
for col in range(10):
screen.blit(Game.letters[6][col].image, (64*col, 481))
Now, since I initialize the letters with their location, I can just do:
for letter in Game.letters[6]:
screen.blit(letter.image, letter.rect)
Which is rather more readable.
Lesson learned, though: don’t forget to empty the dirty rectangles list after
updating the screen. Once it grows to 64 items or so, it noticeably slows down
the game. I’m fairly sure it shouldn’t contain more than a dozen or so items
under normal usage, but I’ll have to remember to keep an eye on it.
Written by Tracy Poff in misc on Sat 15 May 2010. Tags: wordspy,
I found that I wanted to play Word Zap/Word Jolt/Bookworm/whatever word
construction game, but I didn’t seem to have one on hand, and the version of
Bookworm I found was far from
satisfying. So, I did what anyone would do: set out to make my own.
I’ve been wanting to learn to use pygame for a while, and this seemed like a
good opportunity. I’ve had my fair share of trouble so far, but I think I’m
beginning to get a handle on how to use it. It’s
here for now, though it’s not playable
yet—it only generates the letters and scrolls them onto the screen. Still, it’s
a start.
My greasemonkey script for filling in a bid on eBay started out fairly horrible,
referencing element IDs that seemed to differ based on the phase of the moon.
It was terribly difficult to maintain and did not function well.
Epiphany: I discovered an element ID I could safely use that seems constant.
Also, discovered that document.getElementsByName
seems to work in (at least
recent versions of) firefox—wasn’t there some recommendation against using that
a while back? My knowledge of javascript is poor. Anyway, between those two, it
became much simpler to maintain the script, and it worked much better, to boot.
Epiphany the second (third?): Javascript arrays let you do array.push(value)
,
so now I push the patterns into an array, which means I can divide them up by
language and add new ones without worrying about which index the new pattern
should use. Super. Now adding a new currency/language pair is as simple as
adding a single line pushing the pattern into the array.
Unfortunately, I can’t safely (for my paranoid definition of safe) just run the
regex on the whole document–if a sneaky auctioneer inserted “Enter US $500.00 or
more” in the auction description, and the auction was actually in another
currency, then the English/USD pattern would pick up that $500 text before the
other-currency patterns ran, and the bid box would be filled with that value. Of
course, the user would still have to click the button to place the bid, and then
confirm it, but remember: paranoid. As long as eBay doesn’t decide to remove the
table IDs or something, though, this shouldn’t be an issue.
Next up is to try to get the script to work on the outbid pages that present
themselves immediately after entering a bid that’s too low. Magic 8-Ball says:
outlook good.
I’ve sorted out the BASIC version of Awari I’m porting into the ‘draw the board’
routine, the ‘make a move’ routine and the ‘incomprehensible AI’ routine. The AI
seems to first sow from the first nonempty pit, then makes some weird comparison
and modifies a value:
860 FOR I=0 TO N-1:IF F(N)*6+K=INT(F(I)/6^(7-C)+.1) THEN Q=Q-2
The reason for that is fairly inscrutable. F is some array, and the program
claims to have a learning mechanism to improve the AI, so I suspect this is that
mechanism, but I’m not at all sure how it’s meant to work. I think I’ll have to
make a flow chart or something to decipher this thing. This would be easier if
the variables had meaningful names. I remember once, when I was first learning
to program, I thought that using meaningful names was a big waste of time, since
after all the code should be pretty self-evident, right? A second look at my
code after some weeks disabused me of that notion, and this serves to reinforce
that: code should be self-evident, but it won’t be if you don’t work at it.
Oh well. With any luck, I’ll be able to sort this out with an hour or so of
concerted effort–it’s just that reading BASIC is giving me a headache and I
haven’t yet put in the requisite time. I must persevere!