I'm really excited about model validation, in Django circa 1.2. It's going to save me from the disastrous hack of ModelForms I've used so far. One wants something to validate data before saving it, since validating it by saving it is apparently a Bad Idea, since you may have already made changes to the database by the time the error is thrown.
I wanted this done automatically, and Django only had form validation until 1.2, so I hacked forms into some sort of all-purpose wrapper for models. I've since learned to program Django like an adult, and model validation came around just in time anyway. But there's a problem I have with it.
First I should point out that there's a few different things that get validated, but the two I'll point out are A) checking that required fields are set and B) whatever I put into the clean() function. Judging by some errors I've gotten while debugging/testing, Django seems to be checking B before A.
Now, when I use a ModelForm, sometimes I want to use the commit=False option when I save. This returns a model that hasn't been committed to the database. Sometimes there's extra data I want to add to the model that the form didn't supply. Sometimes that data is in fact necessary for the model to be valid. So clearly Django shouldn't check A, and it doesn't. Here's the funny thing though: it does check B. Why would it do that? I can understand checking when I call is_valid(), I can control when that's called, making sure I added everything first.
So far the consequences of checking B early have been trying to access members that haven't yet been set, in my clean() function. So in clean() I just check for those items, and just let it pass if they don't exist. I figure, yeah, it'll pass certain tests when it shouldn't. But if it's really running through validation (not just B as in the save (commit=False) case) that means it'll catch the missing members on the A pass anyway.
Maybe I got something wrong, but I thought it was a weird design decision.
Wednesday, October 27, 2010
Tuesday, October 5, 2010
Significant Whitespace in Python Data Structures
I recently wrote a program in Python for parsing files. I'm pretty naive still when it comes to functional programming, but I'm still excited about it, so I wanted it to be more functional in style. It had a complicated data structure representing the file structure, instead of a loop with bunch of if-thens. By Python standards I may have gone a bit overboard. Guido probably would not have approved of my code (not to mention what follows in this blog post).
So as a result, most of the program became whitespace irrelevant. Huge dicts of lists of tuples, etc. It made me think that relevant whitespace might become handy for data too. And while talking on IRC about it this morning I realized I could sortof hack it using decorators and generators. So here's what it looks like:
http://gist.github.com/611646
So I have two examples:
Any thoughts?
So as a result, most of the program became whitespace irrelevant. Huge dicts of lists of tuples, etc. It made me think that relevant whitespace might become handy for data too. And while talking on IRC about it this morning I realized I could sortof hack it using decorators and generators. So here's what it looks like:
http://gist.github.com/611646
So I have two examples:
- example.py - This shows how you can define a more complicated structure with whitespace instead of a bunch of ){(}[].
- inlinefunc.py - This demonstrates a sort of side-effect benefit. You can have multi-line functions inline in a list (or tuple or dict). Usually you're stuck with lambdas, and of course that starts to look confusing too.
Any thoughts?
Saturday, March 13, 2010
A useful script: copytoclipboard
Another quick tool I figure I'd share. Made this one a while ago. When you're doing stuff on the command line and you need to copy something for a desktop app, you end up having to select text on your terminal screen. Well if it's a big text file, you have to copy, paste, scroll to the next part, copy (make sure you didn't copy any part twice), paste, etc.
Well, copytoclipboard takes standard input and puts it into the gtk clipboard (haven't tried this on KDE).
#!/usr/bin/env python
import sys
import pygtk
pygtk.require('2.0')
import gtk
c = gtk.Clipboard()
c.set_text(''.join(sys.stdin.read()))
c.store()
For instance, to paste this code, I went into my terminal and typed:
cat copytoclipboard | copytoclipboard
and pasted the results here. For a less confusing example:
uptime | copytoclipboard
lets me paste this:
17:42:14 up 3:23, 2 users, load average: 0.35, 0.39, 0.41
EDIT: Or I could just do a google search and find that xclip already exists. Oh well.
EDIT2: No, xclip seems to be its own thing. I just tried it, doesn't seem to work with gtk. I guess I still win!
Well, copytoclipboard takes standard input and puts it into the gtk clipboard (haven't tried this on KDE).
#!/usr/bin/env python
import sys
import pygtk
pygtk.require('2.0')
import gtk
c = gtk.Clipboard()
c.set_text(''.join(sys.stdin.read()))
c.store()
For instance, to paste this code, I went into my terminal and typed:
cat copytoclipboard | copytoclipboard
and pasted the results here. For a less confusing example:
uptime | copytoclipboard
lets me paste this:
17:42:14 up 3:23, 2 users, load average: 0.35, 0.39, 0.41
EDIT: Or I could just do a google search and find that xclip already exists. Oh well.
EDIT2: No, xclip seems to be its own thing. I just tried it, doesn't seem to work with gtk. I guess I still win!
Thursday, February 25, 2010
"New Music" script
I just thought of a script (can't test it at work so I'll actually write it later, but it'd be only a few lines long). Would work thusly:
Maybe it could be made into a Nautilus script or something, but that seems a bit more tricky if you're dealing with drag n drops.
Desktop>newmusic britney_spears_leak_trance_remix.ogg ~/music/various/It would act like mv, just move the song over to the "various" directory, but it would also add a symlink to
~/music/new/That way, I'll remember to give it a listen. And when it's no longer novel I can just delete the symlink. Otherwise this crap gets accumulated on my Desktop. Maybe happens to you too.
Maybe it could be made into a Nautilus script or something, but that seems a bit more tricky if you're dealing with drag n drops.
Sunday, February 14, 2010
Making new twitter followers marginally more convenient
Well, one tiny annoyance that I just randomly decided I felt like itching - I get a handful of emails from twitter saying so-and-so is following me. Usually it's somebody I'm not interested in, but on occasion it's a friend. What annoys me is that I have to open their profile to see. I'd prefer to see the bio and their last few tweets in the email itself. Would help me decide much faster. Well, I've started on a real hack of a solution. It should make it a little less annoying:
http://gist.github.com/304335
Look it over. If you trust it, run it on a command prompt (works on Linux, all I can say). It asks for your gmail password. It opens browser tabs for all the twitter accounts that have followed you that are still in your gmail inbox.
Now, I'm making some wild assumptions about the emails that Twitter is sending us (namely that the first Twitter url is the profile in question), so this may not open up everything correctly. Especially if Twitter changes the email. So, I also open up a tab with a gmail search for all those emails. You can look it over and confirm that it opened up the right tabs, plus this helps you archive them right away.
If it doesn't work, do this first:
https://www.google.com/accounts/DisplayUnlockCaptcha
I guess it tells Google that your computer isn't engaging in any anti-human activities. I had to do it.
I may eventually have it generate an html page with all the useful info right there, so you can look it over quicker. I'll also look for a way to have a GUI password entry thing, so you won't need a cmd prompt. Or, you know, if any of you Open Sourcerers want to do it yourself and send back the update, that would be great too.
http://gist.github.com/304335
Look it over. If you trust it, run it on a command prompt (works on Linux, all I can say). It asks for your gmail password. It opens browser tabs for all the twitter accounts that have followed you that are still in your gmail inbox.
Now, I'm making some wild assumptions about the emails that Twitter is sending us (namely that the first Twitter url is the profile in question), so this may not open up everything correctly. Especially if Twitter changes the email. So, I also open up a tab with a gmail search for all those emails. You can look it over and confirm that it opened up the right tabs, plus this helps you archive them right away.
If it doesn't work, do this first:
https://www.google.com/accounts/DisplayUnlockCaptcha
I guess it tells Google that your computer isn't engaging in any anti-human activities. I had to do it.
I may eventually have it generate an html page with all the useful info right there, so you can look it over quicker. I'll also look for a way to have a GUI password entry thing, so you won't need a cmd prompt. Or, you know, if any of you Open Sourcerers want to do it yourself and send back the update, that would be great too.
Wednesday, October 28, 2009
Ping!
Pinging is the act of sending ICMP packets to another device, and waiting for a response. It's a good way of seeing if we're online, or if the hopeful recipient is online. It is prevalent enough that it's become slang for contacting someone, to see if they're around and listening. And it's gone beyond that; I just realized that Google Wave's use of "Pinging" someone makes it official in a way.
But even in the ICMP packet sense, it was in a sense a slang usage. From Wikipedia:
"Mike Muuss wrote the program in December, 1983, as a tool to troubleshoot odd behavior on an IP network. He named it after the pulses of sound made by a sonar, since its operation is analogous to active sonar in submarines, in which an operator issues a pulse of sound at the target, which then bounces from the target and is received by the operator. (The pulse of sound in sonar is analogous to a network packet in ping)."
Here's the other half of the story. I always feel inclined to theme my computer. Really put some life into it. I thought of a really silly idea, and a great way how to do this today while sitting at the Skylark.
So here's where it all comes together: Noisy Ping (for lack of better name)
When you set this up, ping will emit a sonar sound. And if you get a response, you will hear a subdued version of the same sound.
Code licensed under WTFPL, sound was from a creative commons site, so it's under Sampling Plus 1.0. Don't sue me if a whale tries to mate with your computer. Or if my program does something bad (though I promise I didn't mean to do anything bad, and that I'm running this on my own computer).
This was sortof hacked together, because frankly I have better things to do than to do this "properly", but I did my best to make sure that the python script relayed ping's inputs and outputs and kill signals faithfully (though I have a failsafe SIGTERM, followed by SIGKILL, at the end). if you have any suggestions on how to make this more safe, less crash prone, more portable, etc, please feel free to send me a better version.
And hell, it's sortof useful too. If you're pinging something and you don't want to watch the terminal to see if you get anything back.
So there you go.
But even in the ICMP packet sense, it was in a sense a slang usage. From Wikipedia:
"Mike Muuss wrote the program in December, 1983, as a tool to troubleshoot odd behavior on an IP network. He named it after the pulses of sound made by a sonar, since its operation is analogous to active sonar in submarines, in which an operator issues a pulse of sound at the target, which then bounces from the target and is received by the operator. (The pulse of sound in sonar is analogous to a network packet in ping)."
Here's the other half of the story. I always feel inclined to theme my computer. Really put some life into it. I thought of a really silly idea, and a great way how to do this today while sitting at the Skylark.
So here's where it all comes together: Noisy Ping (for lack of better name)
When you set this up, ping will emit a sonar sound. And if you get a response, you will hear a subdued version of the same sound.
Code licensed under WTFPL, sound was from a creative commons site, so it's under Sampling Plus 1.0. Don't sue me if a whale tries to mate with your computer. Or if my program does something bad (though I promise I didn't mean to do anything bad, and that I'm running this on my own computer).
This was sortof hacked together, because frankly I have better things to do than to do this "properly", but I did my best to make sure that the python script relayed ping's inputs and outputs and kill signals faithfully (though I have a failsafe SIGTERM, followed by SIGKILL, at the end). if you have any suggestions on how to make this more safe, less crash prone, more portable, etc, please feel free to send me a better version.
And hell, it's sortof useful too. If you're pinging something and you don't want to watch the terminal to see if you get anything back.
So there you go.
Saturday, March 7, 2009
What about a "rabbithole" paradigm for all GUIs?
I'm watching a presentation on Zimbra, and I'm noticing that the interface is really busy. I can begin to see why it must be a pain in the ass to set up and maintain (as I've heard). I know I'd hate to have to use it. Where I currently work, as I would imagine is the case at most large businesses, you have a million different services that you can use, a couple of which you have to use, and a couple which you may want to use (the latter group will vary by person or group). A whole lot of things just don't get used by your group, but you keep hearing about it from the company above, it keeps showing up in your web interfaces, and it's just annoying.
A couple posts ago I mentioned an idea of a "rabbithole paradigm" for configurations. What if you did the same thing for your whole GUI?
You start with a big button that says Zimbra. You click on it and get three buttons called Communication, Collaboration, and Settings. You click Communication and you get your email, chat. Click Collaboration you get file sharing, Wiki, etc. Settings gives you GUI settings and Account Settings, each of which gives you more things. Everything is completely straightforward, if cumbersome, as to where you should find them. Certainly no settings or shortcuts that you don't need are in your main interface.
Well, that would make things a lot less confusing, and a pain to get to the services you need, because you have to go all the way down the rabbit hole to get to them. But, as you decide to use them, they would get added to your front page. This includes configuration too, I suppose, as I mentioned in my other post. That way, you always have exactly the services and settings you need and know how to use on your front page and in your menus.
A couple posts ago I mentioned an idea of a "rabbithole paradigm" for configurations. What if you did the same thing for your whole GUI?
You start with a big button that says Zimbra. You click on it and get three buttons called Communication, Collaboration, and Settings. You click Communication and you get your email, chat. Click Collaboration you get file sharing, Wiki, etc. Settings gives you GUI settings and Account Settings, each of which gives you more things. Everything is completely straightforward, if cumbersome, as to where you should find them. Certainly no settings or shortcuts that you don't need are in your main interface.
Well, that would make things a lot less confusing, and a pain to get to the services you need, because you have to go all the way down the rabbit hole to get to them. But, as you decide to use them, they would get added to your front page. This includes configuration too, I suppose, as I mentioned in my other post. That way, you always have exactly the services and settings you need and know how to use on your front page and in your menus.
Subscribe to:
Posts (Atom)