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
spankweasel
Jan 4, 2006

Thermopyle posted:

Class :words:

When you're just starting with classes, think small. Don't think about all the crazy stuff they can do and just go with a basic yet functional struct replacement.

Typical example you see in a textbook:

code:
class PersonalData ():

    def __init__ (self, name, age, address):
        self.name = name
        self.age = age
        self.address = address

    def get_name (self):
        return self.name

    def set_name (self, new_name):
        self.name = newname

    def get_age (self)
        return self.age

    def set_age (self, new_age):
        self.age = new_age

    def get_address (self);
        return self.address
 
    def set_address (self, new_address):
        self.address = new_address
All I did here was make a new class object called "PersonalData" which has 3 attributes (name, age, address). I wrote 6 get/set methods which allow the user of the object to access the attributes inside (note, you DO NOT have to code like this. Python is extremely flexible and this is a very rigid OO / Java way of dealing with instantiated objects).


In order to use this class, you would simply make a new variable:

code:
 
Tom = PersonalData (name="Tom", age=18, address="123 Fake St.")
Now, you can access Tom's attributes with get / set methods:

code:
print Tom.get_name ()
print Tom.get_address ()
Tom.set_age (21)
etc. etc.

Once you get the hang of it, you can augment the class very very quickly to do fun things.

Adbot
ADBOT LOVES YOU

tef
May 30, 2004

-> some l-system crap ->

spankweasel posted:

Typical example you see in a textbook:

:argh:

It's an example of exactly how not to use object orientation in python.


Don't re-invent existing collection structures (list/hash), and getters and setters are pretty much the root of all evil.

If you are doing stuff in an OO style, you're meant to encapsulate the process entirely and expose it through actions, rather than poking around with the internals.

inveratulo
May 14, 2002
wat
Yea I thought getters/setters were bad form in Python. Keep that java nonsense outta here son!

duck monster
Dec 15, 2004

spankweasel posted:


Ignore this post newbies.

Coding like this will cause you brain damage and make you think like a java programmer. Before long you will be editing XML based configuration files and your wife will leave you and your dog will bite you.

Heres the better way of doing it.

Class definition.

code:
class PersonalData ():

    def __init__ (self, name="unknown", age=0, address="unknown"):
        self.name = name
        self.age = age
        self.address = address
    #Thats it bitches.
Using it.
code:
Tom = PersonalData (name="Tom", age=18, address="123 Fake St.")

print tom.name
print tom.address
print tom.age
Or even (Study my syntax on the constructor)

code:
Tom = PersonalData()
Tom.name = "Tom"
Tom.age = 18
Tom.address = "123 Fake St"
Unless you need them, getters and setters are unpythonic. There are of course exceptions to this, but the code posted was not one of those.

Sorry spankweazle. Dont teach other people bad habits.

Also rampant public property useage is sometimes considered bad OO by (non pythonic) puritans (since how do you concieve of it as 'message exchanges' without complete brainhurt), but OO purism is for smalltalk users but this is python and python programmers specialize in silly walks. Essentially the idea is that you (ab)use the class as a implicit struct. Its not true OO, but its a perfectly acceptable use of objects in python world.

duck monster fucked around with this message at 19:59 on May 25, 2009

TOO SCSI FOR MY CAT
Oct 12, 2008

this is what happens when you take UI design away from engineers and give it to a bunch of hipster art student "designers"
code:
>>> from collections import namedtuple
>>> Person = namedtuple("Person", "name age address")
>>> tom = Person ("Tom", 18, "123 Fake St.")
>>> tom.name
"Tom"
2.6 supremacy

MononcQc
May 29, 2007

Janin posted:

code:
>>> from collections import namedtuple
>>> Person = namedtuple("Person", "name age address")
>>> tom = Person ("Tom", 18, "123 Fake St.")
>>> tom.name
"Tom"
2.6 supremacy

It seems the phrase "There's only one way to do it" has more to do with style than anything with python.

That's kind of nice, still. I find the syntax for it slightly bizarre, but maybe that's just me.

tef
May 30, 2004

-> some l-system crap ->

MononcQc posted:

It seems the phrase "There's only one way to do it" has more to do with style than anything with python.

That's kind of nice, still. I find the syntax for it slightly bizarre, but maybe that's just me.

code:
class struct(object):
    def __init__(self,**args):
        self.__slots__ = args
:toot:

Habnabit
Dec 30, 2007

lift your skinny fists like
antennas in germany.

tef posted:

code:
class struct(object):
    def __init__(self,**args):
        self.__slots__ = args
:toot:

Weell, except that __slots__ is a sequence that has to be present when the class is created. You could make a function that creates a new class with __slots__ and returns that, though.

code:
def struct(**defaults):
    class _struct(object):
        __slots__ = defaults.keys()
        def __init__(self, **kwargs):
            attrs = defaults.copy()
            attrs.update(kwargs)
            for k, v in attrs.iteritems():
                setattr(self, k, v)
    return _struct

MononcQc posted:

It seems the phrase "There's only one way to do it" has more to do with style than anything with python.

That's kind of nice, still. I find the syntax for it slightly bizarre, but maybe that's just me.

Not really. namedtuples are immutable, so you can't use the two interchangeably.

Habnabit fucked around with this message at 21:18 on May 25, 2009

TOO SCSI FOR MY CAT
Oct 12, 2008

this is what happens when you take UI design away from engineers and give it to a bunch of hipster art student "designers"
There's never any reason to create a generic struct type. Python already has a type for unstructured associated data -- it's called `dict`.

tbradshaw
Jan 15, 2008

First one must nail at least two overdrive phrases and activate the tilt sensor to ROCK OUT!
Ignore me. I read the flow of the thread wrong.

tbradshaw fucked around with this message at 23:40 on May 25, 2009

spankweasel
Jan 4, 2006

duck monster posted:

:words:

I agree with what you wrote 100%. I don't use getters and setters in my own code, however if the guys is asking about some basic class poo poo, I thought it would be mildly useful to see a lovely java implementation in python -for reference-.

As people said, there's a million ways to do what he wants and since we don't know exactly what he wanted (other than "Classes are hard. hurr."), I went with a simple, stupid, java-based text book bullshit class as a silly example. One that might show up online when looking for class information.

My mistake. I apologize for stepping out of line. Won't do any of that silly java poo poo again. (I even work for Sun^H^H^HOracle and I won't do it again ;) )

Go with what Duck said. Be simple. It'll get the job done a thousand times faster than my bullshit java example.

duck monster posted:

Heres the better way of doing it.

Class definition.

code:
class PersonalData ():

    def __init__ (self, name="unknown", age=0, address="unknown"):
        self.name = name
        self.age = age
        self.address = address
    #Thats it bitches.

jupo
Jun 12, 2007

Time flies like an arrow, fruit flies like a banana.

Thermopyle posted:

I'm kind of a beginner, and this is my story.

I don't get classes. Every time I start a project I think: "Damnit, I'm going to learn what these are good for now." Except, once I start, I end up not using them because I'm comfortable with the way I do things. Basically I worked all the way through Think Python up to the Files chapter. When I got to "Classes and objects" I started reading and then thought "I don't need this poo poo." and then went out and wrote a bunch of scripts.

I want to learn them, but similar to how many people need a project to learn to program, I need a reason to use them before I'll learn them.

Basically, I want someone to talk me into thinking they're useful for something.

From what you've said it's safe to assume that the kind of things you're programming are fairly small in scale. For simple scripts that are smaller than a few hundred lines of code the benefits of classes really aren't obvious. Once you start getting into some more meatier projects the benefits classes will provide in structuring your data in a modular way will become much more apparent.

Some OO zealots will apply classes to *everything* when really it's about using the right tool for the right job, classes aren't always the answer.

What might also be beneficial to your understand is trawling through the source code for the standard library and seeing how OO is applied to various tasks there.

Seth Turtle
May 6, 2007

by Tiny Fistpump

jupo posted:

From what you've said it's safe to assume that the kind of things you're programming are fairly small in scale. For simple scripts that are smaller than a few hundred lines of code the benefits of classes really aren't obvious. Once you start getting into some more meatier projects the benefits classes will provide in structuring your data in a modular way will become much more apparent.

This is the correct answer. Code examples aren't needed to make this point.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

jupo posted:

From what you've said it's safe to assume that the kind of things you're programming are fairly small in scale. For simple scripts that are smaller than a few hundred lines of code the benefits of classes really aren't obvious. Once you start getting into some more meatier projects the benefits classes will provide in structuring your data in a modular way will become much more apparent.

Some OO zealots will apply classes to *everything* when really it's about using the right tool for the right job, classes aren't always the answer.

What might also be beneficial to your understand is trawling through the source code for the standard library and seeing how OO is applied to various tasks there.

This is true. Largest of my scripts are around 150 lines. Most of them are automation scripts like scraping something from a website and doing something with that, or organizing files, etc...

I guess I'll have to think of a "meatier" projects.

MononcQc
May 29, 2007

Habnabit posted:

Not really. namedtuples are immutable, so you can't use the two interchangeably.

It's more about one string used to name 3 fields:
code:
>>> Person = namedtuple("Person", "name age address")
>>> tom = Person ("Tom", 18, "123 Fake St.")
>>> tom.name
which sounds abnormal. I would have found it fine with both of these:
code:
>>> Person = namedtuple("Person", "name", "age", "address")
>>> Person = namedtuple("Person", ("name", "age", "address"))
But using a single string for the three of them, I don't remember seeing that in any other place before. I'm not sure sending a string with 3 spaces and getting a named tuple is anything I'd expect from anyone.

It was a bit harsh to go against the "there's only one way to do it", but the collections module is one kind of big contradiction to the motto. From the docs:

http://docs.python.org/library/collections.html posted:

The specialized containers provided in this module provide alternatives to Python’s general purpose built-in containers, dict, list, set, and tuple.

Can't deviate more explicitely from "there's one way to do it" than that. Maybe it's just me.

TOO SCSI FOR MY CAT
Oct 12, 2008

this is what happens when you take UI design away from engineers and give it to a bunch of hipster art student "designers"

MononcQc posted:

It's more about one string used to name 3 fields:
code:
>>> Person = namedtuple("Person", "name age address")
>>> tom = Person ("Tom", 18, "123 Fake St.")
>>> tom.name
which sounds abnormal. I would have found it fine with both of these:
code:
>>> Person = namedtuple("Person", "name", "age", "address")
>>> Person = namedtuple("Person", ("name", "age", "address"))

You can use any iterable for the second parameter, if it's not a string it'll be treated as an iterable yielding strings.

MononcQc posted:

It was a bit harsh to go against the "there's only one way to do it", but the collections module is one kind of big contradiction to the motto. From the docs:

Can't deviate more explicitely from "there's one way to do it" than that. Maybe it's just me.
I think you're misunderstanding "one way to do it". It's a reaction against multiple incompatible implementations of the same concept, not multiple compatible implementations of different concepts.

MononcQc
May 29, 2007

Janin posted:

You can use any iterable for the second parameter, if it's not a string it'll be treated as an iterable yielding strings.

I think you're misunderstanding "one way to do it". It's a reaction against multiple incompatible implementations of the same concept, not multiple compatible implementations of different concepts.
Makes more sense. I still don't get why anyone would or should use a string as the second parameter. That sounds like something even PHP wouldn't do. Is there any advantage to that?

TOO SCSI FOR MY CAT
Oct 12, 2008

this is what happens when you take UI design away from engineers and give it to a bunch of hipster art student "designers"

MononcQc posted:

Makes more sense. I still don't get why anyone would or should use a string as the second parameter. That sounds like something even PHP wouldn't do. Is there any advantage to that?
You type "" instead of ["", "", "", ""]. Since the set of characters that field names may contain is restricted to Python identifiers, the string can be unambiguously converted to a list. PHP uses strings even where they're inappropriate and cause information loss (dynamic function calling), so that's not an appropriate comparison.

MononcQc
May 29, 2007

Janin posted:

You type "" instead of ["", "", "", ""]. Since the set of characters that field names may contain is restricted to Python identifiers, the string can be unambiguously converted to a list. PHP uses strings even where they're inappropriate and cause information loss (dynamic function calling), so that's not an appropriate comparison.

Seems to go against the idea of least astonishment or wanting to be explicit as much as possible. If you want a list, ask for a list.

Anyway, I won't push this any further, I got the answers I asked for. The rest is more or less opinions on my end. Thanks for your time.

Sylink
Apr 17, 2004

I think of classes as simply collections of functions and variables that are sort of centered around a common purpose , or a library.

Say you want to a do a lot of different math thingies, rather than writing a bunch of individual functions outside of a class you put them in a class so you can keep them in a certain collection of names.

So you have a normal function get_dongs() and a class Dong with its own function get_dongs() called like so

code:

butt = Dong
butt.get_dongs()

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

Sylink posted:

So you have a normal function get_dongs() and a class Dong with its own function get_dongs() called like so

code:

butt = Dong
butt.get_dongs()


There is an important thing to be learned from K&R and that is that motivating examples should be as un-contrived as possible so as to illustrate why something is necessary (or useful, etc) instead of just illustrating what it is.

supster
Sep 26, 2003

I'M TOO FUCKING STUPID
TO READ A SIMPLE GRAPH

Sylink posted:

Say you want to a do a lot of different math thingies, rather than writing a bunch of individual functions outside of a class you put them in a class so you can keep them in a certain collection of names.
That's what a module is for. Not a class.

edit: generally.

nonathlon
Jul 9, 2004
And yet, somehow, now it's my fault ...
Something so obvious that I'm sure there must be an obvious solution that I'm missing: lexicographic sorting in Python.

I have a set of menu options that should be sorted, which look like

Set 1
Set 2
Set 3
...
Set 10
Set 11

And of course the standard Python source is giving me:

Set 1
Set 10
Set 11
Set 2
...

Any favoured solutions?

No Safe Word
Feb 26, 2005

outlier posted:

Something so obvious that I'm sure there must be an obvious solution that I'm missing: lexicographic sorting in Python.

I have a set of menu options that should be sorted, which look like

Set 1
Set 2
Set 3
...
Set 10
Set 11

And of course the standard Python source is giving me:

Set 1
Set 10
Set 11
Set 2
...

Any favoured solutions?
Actually what Python does is lexicographic sorting, you want "natural sort"

http://code.activestate.com/recipes/285264/

I don't know of any "standard" solution but that was the first hit for "python natural sort" and it looks okay enough :v:

Scaevolus
Apr 16, 2007

outlier posted:

Beaten, but here's what I have:

code:
import re
numfind = re.compile(r'(\D*)(\d*)').findall

def num_split(inp):
    return map(lambda x: (x[0], int(x[1]) if x[1] else None), numfind(inp))

books = 'Set1 Set3 Set20 Look09'.split()
books.sort(num_split)
After looking at the other one, you could just simplify it to the following, and use the key methods on sorts yourself.

code:
import re

def try_int(s):
    try: return int(s)
    except ValueError: return s

def natsort_key(s):
    return map(try_int, re.findall(r'(\d+|\D+)', s))
code:
somelist.sort(natsort_key)

Scaevolus fucked around with this message at 16:33 on May 26, 2009

nonathlon
Jul 9, 2004
And yet, somehow, now it's my fault ...

No Safe Word posted:

Actually what Python does is lexicographic sorting, you want "natural sort"

Mea culpa, you are right. Thanks to both of you - that simplification looks like just the ticket.

duck monster
Dec 15, 2004

Sylink posted:

I think of classes as simply collections of functions and variables that are sort of centered around a common purpose , or a library.

Say you want to a do a lot of different math thingies, rather than writing a bunch of individual functions outside of a class you put them in a class so you can keep them in a certain collection of names.

So you have a normal function get_dongs() and a class Dong with its own function get_dongs() called like so

code:

butt = Dong
butt.get_dongs()


Kinda. but not quite. This is more a name space than a class, and you can use class singletons as name spaces, kinda.

Really the best way to think of objects is as little black box's that represent a particular thing or concept. In effect a tiny self contained program with multiple entry points. The program is defined in the class, and is made active as an object.

So a class might be "Employee", and it holds data for a single employee, can save or retrieve itself from a database, and has functions like "Set pay rate". You might then make 20 employee objects, one for each employee, then have another object called "Payroll" which is a singleton that encapsulates a bunch of data about banks and money and poo poo, and perhaps an instance of a "ledger" object.

When you want to pay an employee, you might send a message to that employee object something like john.pay_employee(john.weekly_rate) , note that this is a method call, but its best to think of methods as messages sent to that object. This becomes even more explicit (as message sending) in languages like smalltalk and Objective C.

So after you send john.pay_employee(john.weekly_rate), the pay_employee method then sends a message to the payroll object, something like payroll.transfer(450.00 , self.account_number , "Weekly pay for John") which means pay john $450 via the enclosed account_number [extracted from my own properties] and put "Weekly pay for john" into the methods. The payrol might then poo poo out a bunch of data over the net to the bank , then send a message to the ledger recording the transaction.

Basically this is modelling the ways a real payroll department might do it IRL. The "john" object is a record in a filing cabinet, and the methods are things you can do with the 'john' object. There might also be a payroll clerk, who you ask (call a method) to do the payroll for john, and the payroll clerk then interacts with both the bank and the general ledger (or whatever the gently caress payroll clerks do).

So by converting the entities and processes into objects with methods and properties, you convert a physical process into a computer program.

Have a study of the way UML works, its a loving great tool for thrashing out OO designs.

Once you start programming OO, you can never turn back. Its a loving great methodology.

deedee megadoodoo
Sep 28, 2000
Two roads diverged in a wood, and I, I took the one to Flavortown, and that has made all the difference.


I wanted to contribute to this thread because I use python a ton. I was reading a few pages back and saw there was some confusion about how to implement decorators so I figured I'd post two that I've used fairly recently:

The first example wraps a function in some log messages that will tell you when a function starts and when it ends and what values it took as arguments. I've used this quite a bit in a threaded application to track down some bugs I encountered and changed the "print" statements to logging calls when it went into production. Just add "@log" above your function declaration to make it work.

code:
def log(function):
    from itertools import chain
    def wrappedFunction(*v, **k):
        name = function.__name__
        print "starting %s(%s)" % (name, ", ".join(map(repr, chain(v, k.values()))))
        output = function(*v, **k)
        print "finished %s(%s)" % (name, ", ".join(map(repr, chain(v, k.values()))))
        return output
    return wrappedFunction

This is a very simple decorator I used the other day to track the execution time of a bunch of functions to figure out where the bottleneck was in a piece of code. At the end of execution you can inspect the "timeTable" variable and it will contain a list of execution times for every call to each decorated function.

code:
timeTable = {}

def functionTimer(function):
    def timedFunction(*v, **k):
        start = time.time()
        output = function(*v, **k)
        stop = time.time()
        try:
            timeTable[function.__name__].append(stop - start)
        except KeyError:
            timeTable[function.__name__] = [stop - start]
        return output
    return timedFunction

Hopefully somebody learns something or gets some use out of these.

Captain Capacitor
Jan 21, 2008

The code you say?

dustgun posted:

If I want to make a site that's basically only index.py, what's the best way to do that? I'm honestly not quite sure what magic words I should be searching for.

Little bit late to the party, but I just discovered this project not long ago. It's essentially a filesystem based blog written in Python, with a mess of plugins and "flavours" (style and look, etc). Fairly easy to set up.

http://pyblosxom.sourceforge.net/

Also, I love having Python on my iPhone so I can script my way around anything, even apps. Plus it's handy to be able to run Django on my phone. Not that it's practical in any way, but was really, really fun to get working.

nonathlon
Jul 9, 2004
And yet, somehow, now it's my fault ...

Captain Capacitor posted:

Little bit late to the party, but I just discovered this project not long ago. It's essentially a filesystem based blog written in Python, with a mess of plugins and "flavours" (style and look, etc). Fairly easy to set up.

http://pyblosxom.sourceforge.net/

I used this a number of years ago before moving on to a fully blown CMS. Pros: it's just like the original Blosxom, except saner and written better. The plugins are a nice idea. Cons: it's just like the original Blosxom, which - despite any number of plugins - always acts just like and only a blog.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Mechanize is giving me fits.

Basically, it doesn't recognize that there are any forms on this page.

Here's some demonstration code:

code:
from mechanize import Browser

url = 'https://steamcommunity.com'

br = Browser()
br.open(url)

br.select_form(name="loginForm")
print br.form
br["steamAccountName"] = "ACCT"
br["steamPassword"] = "PASS"
response2 = br.submit()
print response2.read()
This results in:

code:
Traceback (most recent call last):
  File "C:\Users\Therms\Documents\programming\python\mechanize experiments\mech_
test.py", line 11, in <module>
    br.select_form(name="loginForm")
  File "build\bdist.win32\egg\mechanize\_mechanize.py", line 505, in select_form

  File "build\bdist.win32\egg\mechanize\_html.py", line 546, in __getattr__
  File "build\bdist.win32\egg\mechanize\_html.py", line 559, in forms
  File "build\bdist.win32\egg\mechanize\_html.py", line 228, in forms
mechanize._html.ParseError
This is on Windows with python2.6, but I get the same error on linux with python 2.5.

Other Browser methods will follow links on that page, but forms just won't work. I can get forms on other sites to work fine.

I'm trying to write a script that will invite to our Steam Group anyone who ranks above a certain rank on our Psychostats. This requires logging in and maintaining cookies and whatnot...thus the use of mechanize.

Captain Capacitor
Jan 21, 2008

The code you say?

Thermopyle posted:

Mechanize is giving me fits.

Basically, it doesn't recognize that there are any forms on this page.

Here's some demonstration code:

code:
from mechanize import Browser

url = 'https://steamcommunity.com'

br = Browser()
br.open(url)

br.select_form(name="loginForm")
print br.form
br["steamAccountName"] = "ACCT"
br["steamPassword"] = "PASS"
response2 = br.submit()
print response2.read()
This results in:

code:
Traceback (most recent call last):
  File "C:\Users\Therms\Documents\programming\python\mechanize experiments\mech_
test.py", line 11, in <module>
    br.select_form(name="loginForm")
  File "build\bdist.win32\egg\mechanize\_mechanize.py", line 505, in select_form

  File "build\bdist.win32\egg\mechanize\_html.py", line 546, in __getattr__
  File "build\bdist.win32\egg\mechanize\_html.py", line 559, in forms
  File "build\bdist.win32\egg\mechanize\_html.py", line 228, in forms
mechanize._html.ParseError

I ran this on OSX and had no problems (did install mechanize using easy_install, tho). I would suggest skipping the whole browser parsing nonsense, since this module seems to choke on certain HTML (try running br.forms() ). Try using urllib2 and just making the HTTP requests yourself. Use Firebug to monitor the request/response while you send out an invite manually and just replicate the process.

good jovi
Dec 11, 2000

'm pro-dickgirl, and I VOTE!

Captain Capacitor posted:

I ran this on OSX and had no problems (did install mechanize using easy_install, tho). I would suggest skipping the whole browser parsing nonsense, since this module seems to choke on certain HTML (try running br.forms() ). Try using urllib2 and just making the HTTP requests yourself. Use Firebug to monitor the request/response while you send out an invite manually and just replicate the process.

I ran it on OSX, python2.6, mechanize 0.1.11 and got some weird poo poo. I just called br.open(), and then br.forms() and got:
code:
<type 'str'>: (<type 'exceptions.AttributeError'>, AttributeError("'ParseError' object has no attribute 'msg'",))
It's strange though, I tried loading the page in twill, which is really just a wrapper for mechanize, and it worked fine. Maybe that might work better for you?

m0nk3yz
Mar 13, 2002

Behold the power of cheese!

Sailor_Spoon posted:

I ran it on OSX, python2.6, mechanize 0.1.11 and got some weird poo poo. I just called br.open(), and then br.forms() and got:
code:
<type 'str'>: (<type 'exceptions.AttributeError'>, AttributeError("'ParseError' object has no attribute 'msg'",))
It's strange though, I tried loading the page in twill, which is really just a wrapper for mechanize, and it worked fine. Maybe that might work better for you?

I vaguely remember twill using an old and modified version of mechanize, I don't remember though

good jovi
Dec 11, 2000

'm pro-dickgirl, and I VOTE!

m0nk3yz posted:

I vaguely remember twill using an old and modified version of mechanize, I don't remember though

This was using trunk, which has 0.1.11

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Sailor_Spoon posted:

I ran it on OSX, python2.6, mechanize 0.1.11 and got some weird poo poo. I just called br.open(), and then br.forms() and got:
code:
<type 'str'>: (<type 'exceptions.AttributeError'>, AttributeError("'ParseError' object has no attribute 'msg'",))
It's strange though, I tried loading the page in twill, which is really just a wrapper for mechanize, and it worked fine. Maybe that might work better for you?

This is odd.

I get the same errors I mention in my post on linux with python 2.5 and windows with python 2.6. Twill also gives me the same errors.

Guess I'll dig in to it more.

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.

supster
Sep 26, 2003

I'M TOO FUCKING STUPID
TO READ A SIMPLE GRAPH
Anyone having problems using distutils install under Windows 7 64bit? I am getting the following when running "python setup.py install" on the Twisted source.

code:
Twisted-8.2.0>python setup.py install
running install
running build
running build_py
running build_ext
Traceback (most recent call last):
  File "setup.py", line 97, in <module>
    main(sys.argv[1:])
  File "setup.py", line 92, in main
    setup(**setup_args)
  File ".\twisted\python\dist.py", line 47, in setup
    return core.setup(**get_setup_args(**kw))
  File "C:\Python26\lib\distutils\core.py", line 152, in setup
    dist.run_commands()
  File "C:\Python26\lib\distutils\dist.py", line 975, in run_commands
    self.run_command(cmd)
  File "C:\Python26\lib\distutils\dist.py", line 995, in run_command
    cmd_obj.run()
  File "C:\Python26\lib\distutils\command\install.py", line 577, in run
    self.run_command('build')
  File "C:\Python26\lib\distutils\cmd.py", line 333, in run_command
    self.distribution.run_command(command)
  File "C:\Python26\lib\distutils\dist.py", line 995, in run_command
    cmd_obj.run()
  File "C:\Python26\lib\distutils\command\build.py", line 134, in run
    self.run_command(cmd_name)
  File "C:\Python26\lib\distutils\cmd.py", line 333, in run_command
    self.distribution.run_command(command)
  File "C:\Python26\lib\distutils\dist.py", line 995, in run_command
    cmd_obj.run()
  File "C:\Python26\lib\distutils\command\build_ext.py", line 346, in run
    self.build_extensions()
  File ".\twisted\python\dist.py", line 327, in build_extensions
    self.prepare_extensions()
  File ".\twisted\python\dist.py", line 318, in prepare_extensions
    if x.condition(self)]
  File "twisted\runner\topfiles\setup.py", line 14, in <lambda>
    condition=lambda builder: builder._check_header("rpc/rpc.h")),
  File ".\twisted\python\dist.py", line 360, in _check_header
    return self._compile_helper("#include <%s>\n" % header_name)
  File ".\twisted\python\dist.py", line 346, in _compile_helper
    self.compiler.compile(["conftest.c"], output_dir='')
  File "C:\Python26\lib\distutils\msvc9compiler.py", line 448, in compile
    self.initialize()
  File "C:\Python26\lib\distutils\msvc9compiler.py", line 358, in initialize
    vc_env = query_vcvarsall(VERSION, plat_spec)
  File "C:\Python26\lib\distutils\msvc9compiler.py", line 274, in query_vcvarsal
l
    raise ValueError(str(list(result.keys())))
ValueError: [u'path']
I do have Visual Studio 2008 (MSVC9) installed if that makes a difference.

deimos
Nov 30, 2006

Forget it man this bat is whack, it's got poobrain!

supster posted:

Anyone having problems using distutils install under Windows 7 64bit? I am getting the following when running "python setup.py install" on the Twisted source.

I do have Visual Studio 2008 (MSVC9) installed if that makes a difference.

Windows Server 2008 x64 shits itself on virtualenv, easy_install and pip.

Adbot
ADBOT LOVES YOU

ahobday
Apr 19, 2007

What is the "accepted" way of implementing a simple substring search for plain text? I think it's called that. Basically a user types in a search term and it searches for those exact characters, so it also shows them if they're within a word.

I've thought about it, and I figured this might be the way to do it:

1. Get input
2. Find length of input
3. Step through text in these lengths, one character at a time
4. Return when string is found

But there might be a better way?

Also, if I wanted to highlight all instances of the found string, would I have to store the locations in a list or something? I want to highlight them in the text, but on a command line, so I need the locations of the specific characters.

  • Locked thread