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
Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.

Ugg boots posted:

Thanks for the help, but it's not quite that applicable for my problem, because I'm dealing with collisions between two different objects (of different types.)

Google for "multimethods in python". You probably won't want as many indirections and searches as most of the implementations would likely have, but it should give you an idea of how to structure some well-thought out look up tables or whatever solution you decide upon.

Adbot
ADBOT LOVES YOU

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
code:
def dec(f):
    def inner(*a,**k):
        return f(*a,**k)
    inner.func_name = f.func_name
    #setting this in f.func_dict does not work for some reason
    inner.func_dict['clowns'] = 1
    return inner

@dec
def foo():
    print foo.clowns

foo()
It prints 1. Booyah.

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
code:
decorator_with_args = lambda decorator: lambda *args, **kwargs: \
                            lambda func: decorator(func, *args, **kwargs)
@decorator_with_args
def func_dict(f,**d):
    def inner(*a,**k):
        return f(*a,**k)
    inner.func_name = f.func_name
    for k, v in d.items():
        inner.func_dict[k] = v
    return inner

@func_dict(clowns=0, lemons="now:")
def foo():
    foo.clowns += 1
    print foo.lemons, foo.clowns

for _ in range(10):
    foo()
You know, this could be generally useful.

e: the decorator with args decorator is the first hit from google, an old ASPN classic. Quite useful.
e2: of course this means you can modify these function properties outside of the function call foo.lemons = "soup";foo(), which may or may not be desirable, but just because you have a scab doesn't mean you have to pick at it.

Lonely Wolf fucked around with this message at 20:34 on Jan 9, 2008

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
There are few cases I can think of where the decorator would be useful. If you need a C-style static variable or a simple singleton, it's your man. Otherwise a class is certainly more useful.

I don't think it seems too magical or hackish, but then again half the fun I have in python (or any language) is just playing around with the internals and making it do things it wasn't meant to, so my point of view is a bit skewed.

I couldn't recommend using it in a large project where its behavior may come as a surprise, or a multithreaded one where its behavior could degrade randomly, but for something small or one-off it's definitely less verbose; and, at any rate, easily refactored into a proper class come maintenance time.

At the very least, it's something we can drop into our stupid python tricks bag.

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
(Seperate issue, so seperate post)

Has anyone had any experience with Pylons? I haven't done any web work, and I have some time off and lessened work load, so I'd like to play around with something. Django et al seem too straight-jackety. I don't really want to do anything with it, and am happy to just play around in its undocumented internals for fun, but if anyone has comments, criticisms, or tips about it I'd be happy to hear them.

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
Bonus is right. To modify a global in a local namespace you need to use the global statement.

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.

Scaevolus posted:

(I'm not yet sure how I feel about the [expr] if [cond] else [expr] syntax).

I prefer it because it's easier and more natural to read, which is one of the major reasons I prefer to python.

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
I'm working on a metaclass that builds a lot of repetitious code from a class attribute. No problems there. But I also want it to generate some automatic documentation for the class and the class's __init__. It seems wasteful and error prone to do this repetious documentation by hand.

Unfortunately __doc__ is immutable. There seem to be a number of messy ways around this.

This is for a hobby library and I'm trying to simplify it for people who want to extend the library as well as people who just want to use code by them or me.

What I want to know is if there's a 'proper' way to deal with this, or at least a clean way. I'd rather stick to the standard library.

I can post the code if necessary, but it's a dirty sketch as I play around with possible designs, filled with numerous stanzas irrelevant to the discussion, and I basically just want to know how to use a metaclsass to alter docstrings.

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
I'm sorry. I was unclear. I am using __new__, the problems is updating the docstring of the __init__ method of the class being created. Note that I'm using attrs where Milde used dct and that the gross assumptions my code makes about how the class's __init__ method operated are valid in context, and that I've tried to cutaway code and comments that don't apply to the questions at hand.

code:
        #if they don't define an __init__ we have to so we can tag it with docs
        def __init__(self, **file_info):
            self.__dict__.update(formatted_dict)

        #see if they have an init otherwise use ours
        init = getattr(attrs, '__init__', __init__)
        #grab its docstring or the empty string
        idoc = getattr(init, '__doc__', '')
        #append our generated documentation
        idoc += '\n' + init_docstrings

        #FIXME won't let me write to this, need a way around this
        setattr(init, '__doc__', idoc)

        setattr(attrs, '__init__', init)

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
Awesome! Thanks for the help. Where in the documentation would I find more about these abstrusely named properties?

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.

ATLbeer posted:

code:

class MenuItem:
	def __init__(self, Text = "", URL="", Current=False):
		self.Text = ""
		self.URL = ""
		self.Current = False
class PageMenu:
	def __init__(self, Enabled=False, Items=[]):
		self.Enabled = False
		self.Items = []


You're throwing all your parameters away and even with the scope issuse resolved it's not going to do anything. It should be self.Text = Text, etc.

Also, the official and idiomatic style is to only start names with capitals iff they are the names of classes.

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
I often find something like this useful:

code:
>>> dispatcher = {}

>>> def dispatch(table):
...     def decorator(f):
...         table[f.__name__] = f
...         return f
...     return decorator

>>> @dispatch(dispatcher)
>>> def foo(x):
...     print 'haha', x

>>> dispatcher['foo']('blah')
haha blah

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
You're not instantiating your room objects. It needs to be room1 = room(), etc. However, you're going to have far more problems than that. You should probably read up on classes and objects in the Python tutorial.

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.

chemosh6969 posted:

I do it when I expect an error to happen but don't care about logging it because I know what it is, or don't care, and want to program to do whatever it's doing.

If I need to know what the error is, then I don't need to use it.

It has it's uses and there's nothing wrong with using it if you know what you're doing.

Even if you don't care about logging it do something like except OSError: pass so you can be like wtf TypeError? in the rare case that something truly, you know, exceptional happens.

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
Right, why have a computer do something automatically that you can do manually :confused:

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
I don't think we're disagreeing as much as you think we are. I'm okay with ignoring exceptions, even not logging them. (In very simple shell script like programs, of course).

I'm just saying only ignore the exceptions that you know will happen and don't care about so that when something subtle or uncommon happens your script terminates with a stack trace saying hey I'm broken, broken right here, and broken in this way. It beats what the gently caress why isn't this piece of poo poo working?

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
The whole logging thing seems to be leading to tangents so here's the core summation:

except: pass is always troublesome, even if not immediately so or if not apparently so.

However, ignoring exceptions that you want to safely ignore is fine, just use except IgnorableException: pass instead, so that you are in fact always safely ignoring them.

That said, feel free to ignore the above advice and any exceptions if you realize that it is a bad practice and a potential source of bugs but you guage the likelihood of such bugs to be close enough to never to not give a drat.

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
Well, I'm glad he showed us that, since it means we can discount his opinions and arguments wholesale and move on with our lives.

Lonely Wolf fucked around with this message at 03:55 on Nov 15, 2008

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.

duck monster posted:

code:
try:
  x = y[z]
except:
  x = 0

code:
x = getattr(y, z, 0)

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.

chemosh6969 posted:

I'm interested it learning how to use python to search for and download movie info from places like imdb.com and allmovie.com.

Where's the best place to go to start learning?

I know you mean using Python to collect the information, but http://www.imdb.com/interfaces#plain

It's free for personal use, but you have to work it out with them if you want to use it on a web site. I assume that means a lot of money.

As far as using Python google "python screen scraping"

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
I don't know anything about macs, but it looks like you don't have libreadline installed.

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
host=website, post=80

I assume that should be port

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
Are you asking how to bang him? . . . If not, do you have a question?

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
that's because type, et al, are class variables not instance variables. Also, help(str.split).

e: et all? Am I retarded?

Lonely Wolf fucked around with this message at 02:47 on Jan 15, 2009

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
You need to set them in the body of init not the class body.

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
I think for his purposes something more like
code:
english, german = random.choice[english2german.items()]
But otherwise I'm with you, m0nk3yz

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
But us doing your homework will help you on the midterm?

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.

fnordcircle posted:

code:
    new_word=raw_input("Gimme a word: ")

    for i in range(len(new_word)):
        print new_word[i]
        i=i+1

You think that's cool?
code:
for letter in new_word:
    print letter

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
Maybe you could try something, which I normally wouldn't suggest, like this:
code:
def error_trap():
  try:
    mainLoop() #all the Console stuff
  except: #this is the part I'd normally howl at
    #print stacktrace and exit
I'd recommend wrapping it in a function like that so you don't have to strip that nonsense off when you're done debugging.

edit: Beaten. That's what I get for typing this while watching TV. Good point about ctrl+c, that extra clause gets rid of my concerns.

Lonely Wolf fucked around with this message at 18:34 on Mar 9, 2009

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
the new matrix has a different id but check the ids of its elements vs the ids of the old matrix's elements to see what what was said.

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
I hope this helps or whatever:
code:
if robot or some_shit:
    do_some_shit()

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
He's clearly simplified it, for pedagogic reasons.

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
The only time I've seen a decorator return a non-callable is to return a property type in a class body.

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.

Clanpot Shake posted:

pre:
def getHigh(self, event):
	"""Called when high score list is to be displayed"""
	filename = "high.txt"
	scores = []
	message = ""
	FILE = open(filename,"r")
	while FILE:
		line = FILE.readline()		# format: '[name]_[score]' where _ = space
		s = line.split()
		n = len(s)
		if n == 0:
			break
		scores.append(s)
	# assemble the list to be readable
	for i in range(len(scores)):
>>		message += str(i),".   %s   %s\n" % (scores[i][0], scores[i][1])
	dialog = wx.MessageDialog(None, message, "Biggest Losers", wx.OK)
        dialog.ShowModal()
Or you could just use message += "%s. %s %s\n" (str(i), scores[i], scores[i][1])

also you can loop over a file with
code:
FILE = open(filename, 'r')
for line in FILE:
    scores.append(line.split())
And if you need the index of an iterable during iteration you can use enumerate, along with some tuple unpacking to do
code:
for i, (name, score) in enumerate(scores):
   message += "%s.\t%s\t%s\n" % (i, name, score)

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.

spankweasel posted:

Why would you cast i to a string?

message += "%d. %s %s\n" % (i, scores[i], scores[i][1])

Just go with the printf-esque replacement strings and don't waste time casting.

I was just keeping it close to his code there. If you'll notice the second time I didn't, though I did keep it as %s in the format string, implicitly casting it to repr, because I was far too lazy to remember that it was supposed to be %d.

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
Since the almost univeral answer to "I want to learn how to program what should I learn?" on these forums is Python, it might not be a bad idea to at least have a section of first-time friendly links.

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.

dancavallaro posted:

I used py2exe to make an executable of a Python script I wrote. It works great on the Windows XP computer that I created it on, and it works great on my Windows Vista laptop at home. But it doesn't work on my boss's Vista computer, and fails with the error "the application has failed to start because its side-by-side configuration is incorrect. Please see application event log for more details". Any ideas what could be wrong?

Did you check the log?

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
It's throwing a string as an exception and the exception handler is trying to access the msg attribute.

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
Likewise I don't see why auto-registering a class is so problematic and impossible. It is semi-magicy but looks reasonably straightforward and less work than defining a plugin system that feels less Pythonic than the metaclass approach to me. What problems have you had with such things?

To answer the original question, re metaclasses, the metaclass is called when the new classes are instantiated (versus when the class's objects are instantiated) and just adds each plugin class to a list that you can get to easily.

Adbot
ADBOT LOVES YOU

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.

Janin posted:

There's no way to separate the definition and registration of a plugin. This makes testing difficult -- do you want all your test classes showing up as plugins?

There's no way to know what plugins are available without invoking their definitions, which may depend on libraries that aren't installed. Rather than displaying a helpful error message ("FooPlugin requires libfoo >= 1.7"), plugin scanning will barf with an ImportError.

Both of these seem like implementation details that could be handled by the metaclass either letting you put a sentienel to determine a test case or catching errors and passing them to the application to handle.

quote:

Violates "explicit is better than implicit" -- registration is hidden in a magic class, and is difficult to discover except through grepping through the source for "__metaclass__".

This is definitely a valid concern. I see it as a tradeoff. You're providing a little magic to make it easier for someone to worry about writing a plugin for your app without having to do a lot of boilerplate config files.

quote:

Violates the principles of duck-typing -- merely implementing a prescribed interface is no longer sufficient, as only classes inheriting from the registration class will be found.

This is the worst part of the metaclass scheme, but the simplicity is worth it in my opinion. Maybe I've spent too much time playing in metaprogramming land to have a sane perspective though.

quote:

Multiple applications can't share plugins without a separate, shared registration library.

I don't see how that isn't true for any plugin system.

  • Locked thread