Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Lurchington
Jan 2, 2003

Forums Dragoon
What's the easiest way to strip illegal filename characters when attempting to rename filenames?

I can explicitly strip out characters I know to be illegal, but was wondering if there was a module or other process to do that job for me.

Adbot
ADBOT LOVES YOU

bitprophet
Jul 22, 2004
Taco Defender
I'd guess there would be something in the os module (here, probably os.path. os is laid out kind of odd, in that os.path gets its own doc section, but read everything you can find about those 1 1/2 modules and hopefully you'll find something.

Failing that, look in the general stdlib directory, there's a ton other libraries, including platform-specific ones, one of those may have one as well (although then you would, of course, be tied to one specific platform).

EDIT: goddammit why can't the [ fixed ] tag be backticks like every other loving markup :mad:

Scaevolus
Apr 16, 2007

LurchDawg posted:

What's the easiest way to strip illegal filename characters when attempting to rename filenames?

I can explicitly strip out characters I know to be illegal, but was wondering if there was a module or other process to do that job for me.

On most (all?) Linux filesystems, the only characters you're not allowed to have in a filename are '/' and '\x00'.

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.

Scaevolus posted:

On most (all?) Linux filesystems, the only characters you're not allowed to have in a filename are '/' and '\x00'.

But ! will cause you lots of headache, even though it's legal. (Worse than the others actually because it'll happily create it and then the shell will interpret ! weirdly - even when you try to escape it - so it'll be hard to refer to.)

bitprophet
Jul 22, 2004
Taco Defender

JoeNotCharles posted:

But ! will cause you lots of headache, even though it's legal. (Worse than the others actually because it'll happily create it and then the shell will interpret ! weirdly - even when you try to escape it - so it'll be hard to refer to.)

Regular old quoting doesn't work with bang characters? :raise:

And, yea, obviously any character that has a special meaning in your shell (which is, unfortunately, most non-alphanumeric ones) is going to cause problems when unquoted.

ahobday
Apr 19, 2007

Just to clear something up: If defining a variable inside a class makes it a static variable of sorts (One variable shared between all instances of that class) then how do you define variables so that they're not that way?

What do I do instead of this:

code:
class ClassName:
    x = 1

    def function_name(self):
        self.x = 2
Do I have to use a def __init__(self) or something?

bitprophet
Jul 22, 2004
Taco Defender

Centipeed posted:

Do I have to use a def __init__(self) or something?

Yes! :) That's exactly it.

code:
class Foo(object): # note: never just do "class ClassName:", always inherit from object
    def __init__(self, x):
        self.x = x

    def bar(self):
        return self.x
code:
>>> foo = Foo(5)
>>> foo.bar()
5

ahobday
Apr 19, 2007

And I'm guessing inheriting from object gives me access to some functions that would otherwise not be available had I not done so? Can you give me any examples?

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.

bitprophet posted:

Regular old quoting doesn't work with bang characters? :raise:

Nope (not in bash, anyway):

code:
$ ls a!b
bash: !b: event not found
$ ls "a!b"
bash: !b: event not found
$ ls a\!b
ls: a!b: No such file or directory
So escaping works, but it's still a pain if you're iterating over a bunch of files, quoting everything correctly to take care of spaces and things, but don't realize there's a ! in one of them. (You can't just quote the entire string to get it right no matter what's in the filename, you have to manually find and escape the !.)

EDIT: well, I'll be. You can quote with single quotes. Does that do anything else different than double quotes? Can I just rewrite all my bash scripts with s/"/' and be sure that nothing will work differently except that now filenames with ! won't break anything?

JoeNotCharles fucked around with this message at 15:17 on Aug 15, 2008

tef
May 30, 2004

-> some l-system crap ->

Centipeed posted:

And I'm guessing inheriting from object gives me access to some functions that would otherwise not be available had I not done so? Can you give me any examples?

It means it is a new style class

http://www.python.org/doc/newstyle/

tef
May 30, 2004

-> some l-system crap ->

JoeNotCharles posted:

(You can't just quote the entire string to get it right no matter what's in the filename, you have to manually find and escape the !.)

code:
$ echo toot >  'a!b'
$ cat 'a!b'
toot
$
:shobon:

10011
Jul 22, 2007

JoeNotCharles posted:

EDIT: well, I'll be. You can quote with single quotes. Does that do anything else different than double quotes? Can I just rewrite all my bash scripts with s/"/' and be sure that nothing will work differently except that now filenames with ! won't break anything?

It doesn't substitute variables and things either, like single-quoting in Perl.

10011 fucked around with this message at 16:42 on Aug 15, 2008

Chin Strap
Nov 24, 2002

I failed my TFLC Toxx, but I no longer need a double chin strap :buddy:
Pillbug
Anyone here ever use leo? It is a outline oriented text editor that is quasi-literate programming: http://webpages.charter.net/edreamleo/front.html


I'm just starting it, and already it is making a lot of sense to code like this. You just have giant outline trees with chunks of code contained in their own, properly titled leaves.

Lurchington
Jan 2, 2003

Forums Dragoon

Scaevolus posted:

On most (all?) Linux filesystems, the only characters you're not allowed to have in a filename are '/' and '\x00'.

what's been killing me is windows which is a lot more restrictive. I might end up writing a low-key "Filename" class that checks when I construct it, but I was hoping there was some os.path module I was missing.

Bitprophet:
Thanks for the link to stdlib, that might have some more answers.

This is for a script that renames a file based on television showname and episode title, so : comes up occasionally, and you can't easily scrub it without remove the drive letter information.

Lurchington fucked around with this message at 07:22 on Aug 16, 2008

Stump Truck
Nov 26, 2007
Why? Yes
I'm sure something like this has been asked before. I'm following the tutorial from the Python site and I'm on the Keyword Arguments section (http://www.python.org/doc/tut/node6.html#SECTION006720000000000000000)

I'm trying to learn how to write programs in a text editor and run them either from the editor or the terminal (i'm on a mac). What I've done is copy the cheeseshop example into my editor. While I was typing this I actually just figured out that I can just enter the method name with the parameters into the same text file and run it to get the correct result. However, is there a way to give it the parameters through the terminal? I'm guessing no, since the code isn't telling it to wait for any input.

EDIT: real problem: on the same page, I was trying to do the lambda forms exercise. It looks like this in BBEdit:

code:
def make_incrementor(n):
      return lambda x: x+n
	
f=make_incrementor(42)
f(0)
f(1)
However, when I click "Run" in the menu, nothing happens. If I click "run in terminal", it just shows a bunch of random text from terminal and doesn't actually do anything. If I enter the actual code right into terminal and run it from there it works fine.

Also, is there some way to stop terminal from showing this kind of text every time I run a program from BBEdit?

code:
/var/tmp/folders.501/Cleanup\ At\ Startup/test-240639438.369.py.command; exit
Stump-Trucks-Computer:~ Stump$ /var/tmp/folders.501/Cleanup\ At\ Startup/test-240639438.369.py.command; exit

Stump Truck fucked around with this message at 05:18 on Aug 17, 2008

tef
May 30, 2004

-> some l-system crap ->

Stump Truck posted:

However, is there a way to give it the parameters through the terminal? I'm guessing no, since the code isn't telling it to wait for any input.

code:
$ cat > echo.py
import sys

for item in sys.argv:
        print item 

$ python echo.py hello 1 2 3 4
echo.py
hello
1
2
3
4

Stump Truck
Nov 26, 2007
Why? Yes
Do i enter that code in terminal or BBEdit? Sorry I haven't done a ton of command-line programming before

Scaevolus
Apr 16, 2007

Stump Truck posted:

However, when I click "Run" in the menu, nothing happens. If I click "run in terminal", it just shows a bunch of random text from terminal and doesn't actually do anything. If I enter the actual code right into terminal and run it from there it works fine.

Try adding print statements, like
code:
print f(0), f(1)

tef
May 30, 2004

-> some l-system crap ->

Stump Truck posted:

Do i enter that code in terminal or BBEdit?

In python, you can import the sys module - one of the things in the sys module is a list called argv.

This list contains all of the arguments passed into the program, including the name of the program.


So, if you were to write this in BBEdit

code:
import sys

for item in sys.argv:
        print item 
And save it as echo.py

You could run it from the terminal by typing: python echo.py

If you were to run it as python hello world

You would get
code:
$ python echo.py hello world
echo.py
hello
world
So, the first argument is argv[1], and so on.

argv is always a list of strings. If you want numbers, you will have to convert them using int() or float().

HIERARCHY OF WEEDZ
Aug 1, 2005

Okay. I'm brand new to Python, mostly. I've spent a lot of time one sole project that I'm using PyGame for. I'm doing a major refactoring and I need to get a better grasp on how Python organizes its modules and such.

My current directory structure is something like this:
code:
awesome-project/
  |
  + awesome-project.py
  |
  \- base
      |
      + __init__.py
      |
      + neatobject.py
      |
      + otherobject.py
I didn't know about __all__ at this point, so I just had from base import * and from base import neatobject, otherobject in awesome-project.py. At this point my plan is something like the following:

code:
awesomeproject/
  |
  + __init__.py (was awesome-project.py)
  |
  \- base
  |   |
  |   + __init__.py
  |   |
  |   + neatobject.py
  |
  \- other
      |
      + __init__.py
      |
      + otherobject.py
So I've split things up into two directories, and each directory will have a lot of python files in them. How does this arrange the namespaces of my project? Where would I put things I want simple, clean access to, without a whole lot of mucking about with import statements? I've tried using dir() to get a better handle on things, but it's hard to get a sense of the path relative-stuff like that.

Also at some point I realized I needed to take the hyphen out of awesome-project, since that confuses Python. But should awesome-project.py become __init__.py? At what point can I point to the whole mess and say, "All you need to do to run this is from awesomeproject import *"?

hey mom its 420
May 12, 2007

Your awesomeproject directory should have an __init__.py file, even if it's empty. That makes it a python package.
Doing from something import * is generally always considered a bad idea because you can get all kinds of name clashes. What you could do is mimic what PyGame did — you could define a file called, say, locals.py in your root package. Then in locals.py import everything you need:
code:
from base.neatobject import blah, blah2, blah3
from base.otherobject import foo, foobar, foo
from other.something import bla, bla, bla
and then you just do from awesomeproject.locals import * and everything that's been imported in locals.py will jump into your namespace. That way you can quickly import stuff you need, but the importing is still explicit, only it's tucked away in locals.py.

hey mom its 420 fucked around with this message at 20:49 on Aug 18, 2008

ahobday
Apr 19, 2007

I like to learn by doing, but now that I've made a phone book application I don't know what I'd like to accomplish next with straight Python (My eventual goal is to start playing with pygame, but I'm not there yet).

Can anyone recommend some simple programs I can make that'll reinforce the basics of Python and object oriented programming in general?

Bozart
Oct 28, 2006

Give me the finger.

Centipeed posted:

I like to learn by doing, but now that I've made a phone book application I don't know what I'd like to accomplish next with straight Python (My eventual goal is to start playing with pygame, but I'm not there yet).

Can anyone recommend some simple programs I can make that'll reinforce the basics of Python and object oriented programming in general?

I always wanted to incorporate some python with google maps... why don't you make a google map that has an icon where you live, and when you click on a link that it brings up, it plays a sound on your computer (like a doorbell)?

HIERARCHY OF WEEDZ
Aug 1, 2005

Bonus posted:


Okay. Now if I have something like this:

code:
awesomeproject/
  |
  + __init__.py (was awesome-project.py)
  |
  \- base
      |
      + __init__.py
      |
      + controller.py (contains `class Controller: ...`)
It ends up looking like this in Python:

code:
>>> import base
>>> dir(base)
['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__path__']
>>> import base.controller
>>> dir(base.controller)
['Controller', '__builtins__', '__doc__', '__file__', '__name__' ]
>>> base.controller.Controller
<class base.controller.Controller at 0x2653fc0>
Is there any way I can shortcut things so using import base.controller allows me to call
code:
 c = base.Controller()
instead of
code:
 c = base.controller.Controller()
?

hey mom its 420
May 12, 2007

Yeah, in base/__init__.py do:
code:
from controller import Controller
and then you can do import base and then stuff like base.Controller()

Basically, if you put stuff into a package's __init__.py, it acts like the package was the script. So, for instance, if you have a file foo/__init__.py and in that file you have
code:
a = 5
you can do import foo and then access foo.a to get a 5

HIERARCHY OF WEEDZ
Aug 1, 2005

Bonus posted:

Yeah, in base/__init__.py do:
code:
from controller import Controller
and then you can do import base and then stuff like base.Controller()

Basically, if you put stuff into a package's __init__.py, it acts like the package was the script. So, for instance, if you have a file foo/__init__.py and in that file you have
code:
a = 5
you can do import foo and then access foo.a to get a 5

Sweetness. Thank you so much for both of your replies!

duck monster
Dec 15, 2004

Centipeed posted:

For this exercise, can't I just store the list in a text file with simple markup? A database seems like overkill, even it is is only SQLite.

Yes, and your idea is fine. Make a base class that has a __str__ function that shits out a pickle of the data. Put the classes in a hash indexed by , I dunno, whatever you think a good scheme to key it all is, and then to save and load it, just do something like

open file ()
for each record in the hash :
print the record to the file <--- __str__() will handle the fun
end for
close file ()

(excuse the pseudocode, I'm trying to avoid shifting grammar in my head from my work atm)

and then just reverse that to load it in.

If you want you can even just pickle the hash , and it ought traverse into the objects and poo poo them into a file.

But thats probably bad form.

On a side note, you used to be able to do this really well with pascal (write an array of records directly to a file) , which made me kind of amused at the 'pascal is hard for file handling!' people (sure it was, in the 1960s!) as at least with the turbo variants, nothing came close to it.

agscala
Jul 12, 2008

to avoid confusion for centipeed (or any beginner), hash = dictionary

Flea110
Apr 3, 2006
How can I cut and paste files in Windows?
I've been using shutil.move() for a while now but it's very inefficient because it copies and pastes, then deletes the original.

Lurchington
Jan 2, 2003

Forums Dragoon

Flea110 posted:

How can I cut and paste files in Windows?
I've been using shutil.move() for a while now but it's very inefficient because it copies and pastes, then deletes the original.

I'm pretty sure that's only between different partitions, rename shouldn't have all that overhead.

http://docs.python.org/lib/module-shutil.html

Stump Truck
Nov 26, 2007
Why? Yes
So far the tutorials are pretty straightforward. I'm a little confused about some of the calls though. What exactly does it mean when you type
code:
print my_function.__doc__
If I leave out the "__doc__" it only prints the memory address of the method. What do the underscored words mean in general?

Scaevolus posted:

Try adding print statements, like
code:
print f(0), f(1)

Yeah that worked perfectly, thanks

Stump Truck fucked around with this message at 04:11 on Aug 20, 2008

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.

Stump Truck posted:

So far the tutorials are pretty straightforward. I'm a little confused about some of the calls though. What exactly does it mean when you type
code:
print my_function.__doc__
If I leave out the "__doc__" it only prints the memory address of the method. What do the underscored words mean in general?

Double-underscore is just the standard tag for methods or attributes which have a special purpose. In this case "my_function.__doc__" is the docstring which is printed when you type "help(my_function)". The special members are all described in the Python Library Reference.

The standard way to set a docstring is like this:

code:
>>> def my_function():
...    """A function that does nothing"""
...    pass
Now "print my_function.__doc__" should print "A function that does nothing" and "help(my_function)" should print the same thing, but formatted all nicely like a manual page. Since my_function.__doc__ is just a member variable of the function object like any other, you can also assign to it and do all kinds of manipulations on it, but generally it's just a behind-the-scenes thing.

dancavallaro
Sep 10, 2006
My title sucks
edit: nevermind, fixed my problem

dancavallaro fucked around with this message at 16:03 on Aug 20, 2008

HIERARCHY OF WEEDZ
Aug 1, 2005

Another module question, this is really throwing me off :-(
I have my project all laid out:

code:
proj/
  |
  + __init__.py
  |
  \- base
  |   |
  |   + __init__.py
  |   |
  |   + controller.py
  |
  \- other
      |
      + generic.py
And inside controller.py I have from other import generic. When I run python __init__.py inside ~/proj, everything works fine. However, when I try to run nosetests inside ~/proj, it borks because it tries to run import controller from within ~/projc/base, not ~/proj/, so it can't go up a tree to find generic.py. How can I placate both my root module and anything that might try to load a module in a subdirectory explicitly?

EDIT: I read about relative imports but I don't want to hard code some if-then-else to see how a module's being imported, and choose one kind of import over the other. There's got to be a general way to fix this.

HIERARCHY OF WEEDZ fucked around with this message at 16:59 on Aug 20, 2008

bitprophet
Jul 22, 2004
Taco Defender
The general way to fix it is to ensure that proj is on your PYTHONPATH and then to from proj.other import generic.

Relative imports will be a slightly more portable way to do this once they are part of the mainstream* but until that happens, you're stuck having to do an absolute import like the one I presented above.


*Right now, as far as I can tell from the PEP you linked, they're only available in a "preview" of sorts by using from __future__ import blah. In other words, it'll become part of the normal, official syntax in Python 2.6, and should generally be ignored until then.

Chin Strap
Nov 24, 2002

I failed my TFLC Toxx, but I no longer need a double chin strap :buddy:
Pillbug

bitprophet posted:

In other words, it'll become part of the normal, official syntax in Python 2.6, and should generally be ignored until then.

How far off is 2.6? Shouldn't you be writing your code in a way that it is future ready?

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.

Chin Strap posted:

How far off is 2.6? Shouldn't you be writing your code in a way that it is future ready?

Yes, which means not using things that might go away in the future. That includes syntax changes that haven't officially been finalized yet - there's always the chance that they'll strip them out at the last minute because they find some showstopper bug that's just not fixable, or change them in a way that's slightly incompatible. Using 2.6 features before 2.6 is actually out is the opposite of being future ready.

me. circa 1995
Apr 3, 2008

I've looked at a couple of Python books / resources, namely Mark Lutz - Learning Python, Swaroop C. H. - A Byte Of Python and I'm not satisfied. If anyone has ever read Kochan's Programming in C you'll know what I'm looking for. I find a lot of the stuff so far presented to me a bit too "scatty" and assuming prior knowledge of Java / C / C++, which, although I am very familiar with the C syntax, I don't want.

If anyone knows of something that satisfies the following criteria, would be great:

1) Introduction to the elements of the language chapter by chapter (as usual) with lots of exercises at the end of each, building on knowledge introduced in previous chapters. For instance, the chapter on iteration might ask for the reader to write a program to generate Fibonacci numbers, and then later, the chapter on functions might ask them to wrap it up in a function with greater abstraction / functionality.

2) A solid, informative run through of the OO approach; I am completely new to it so I don't want a book to rely on the assumption I've used Java or C++.

The examples are crucial because although I could just familiarise myself with the syntax and go and do some Project Euler or Code Golf exercises I'd be thinking from a C perspective and would totally miss features of the language I would get if the exercises are integrated deeply with the introduction of the structure of Python.

tef
May 30, 2004

-> some l-system crap ->

dense vegetation posted:

I've looked at a couple of Python books / resources, namely Mark Lutz - Learning Python, Swaroop C. H. - A Byte Of Python and I'm not satisfied. If anyone has ever read Kochan's Programming in C you'll know what I'm looking for. I find a lot of the stuff so far presented to me a bit too "scatty" and assuming prior knowledge of Java / C / C++, which, although I am very familiar with the C syntax, I don't want.

Although aimed at the beginner, Zelle's Python Programming: an introduction to computer science might be useful

Adbot
ADBOT LOVES YOU

bitprophet
Jul 22, 2004
Taco Defender

Chin Strap posted:

How far off is 2.6? Shouldn't you be writing your code in a way that it is future ready?

What JoeNotCharles said :) Using stuff that's only in __future__ isn't really being "future ready" as much as it's more like gambling.

Truly "future ready" would (in my opinion) be stuff possible in the current syntax that avoids using to-be-deprecated behavior. For example, getting in the habit of using print("foo") instead of print "foo", since IIRC that's how things are moving for Python 3.x.

  • Locked thread