Procedures
J. Cliff Dyer
jcd at sdf.lonestar.org
Tue Jun 23 10:59:50 EDT 2009
Please keep the discussion on-list. (Reply-all, rather than just
replying to me.)
On Mon, 2009-06-22 at 15:36 -0700, Greg Reyna wrote:
> It's not the error that concerned me. The fact that there is an
> error of this type makes clear that there's something wrong with the
> way the scripts are structured. I was trying to communicate that I
> recognized this fact. Clearly, I was not successful. Thought I'd
> try to save bandwidth, too.
> ...
> I had tried running this previously with only one Class header:
> "LineReader", the others were just defs. I changed the short defs
> into sub-classes out of desperation, since I don't understand why the
> main script is not recognizing functions that are in the same file.
>
> First is the shell input/output, then "ParseWork.py", the entire text
> file that contains the scripts.
>
> Thanks for your interest, Cliff,
> Greg
> ---
> >>> import ParseWork
> >>> avar = ParseWork.LineReader()
> >>> xstring = 'scene 1, pnl 1, 3+8, pnl 2, 1+12, pnl 3, 12, pnl 4, 2+4,'
> >>> avar.parseLine(xstring)
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> File "ParseWork.py", line 13, in parseLine
> xreturn = advanceSearch(xstring) #shorten the part of string to
> be searched
> NameError: global name 'advanceSearch' is not defined
> >>>
> ---
> class LineReader:
> def parseLine(self, xstring):
> global sc_info,scnum,pnlnum,prev_pos,cur_pos
> sc_info = { 'sc':{0:0}} #dict to store scene num; pnl num(s), ftge
> prev_pos = 0
> cur_pos = xstring.find(',') #defaults to length of string
> while xstring.find(',',(prev_pos+1)) != -1:
> temp = xstring[prev_pos:cur_pos] #pull out the part btwn commas
> section = temp.strip()
> if section[0:1] == 's':
> scnum = int(section[5:]) #get the number(s) off the
> end of scene block
> sc_info['sc',scnum] = scnum #store scnum-which is
> both key and value
> xreturn = advanceSearch(xstring) #shorten the part
> of string to be searched
> continue
> if section[0:1] == 'p':
> pnlnum = int(section[3:])
> sc_info['sc',scnum,pnlnum] = pnlnum #store pnlnum &
> temp value for pnlnum
> xreturn = advanceSearch(xstring) #the return value
> is to move flow back here
> continue
> if section[0:1] != 's' or 'p':
> xnum = section[0:] #section must contain the footage
> if section.find('+'): #the + exists
> ftge = parseFtge(section)
> sc_info['sc',scnum,pnlnum] = ftge #store ftge in pnlnum
> xreturn = advanceSearch(xstring)
> continue
> else:
> ftge = (section/16.0) #section is frames-convert
> to decimal
> sc_info['sc',scnum,pnlnum] = ftge #store ftge in pnlnum
> xreturn = advanceSearch(xstring)
> continue
> else:
> print sc_info
>
> class ContRead(LineReader):
> def advanceSearch(xstring):
> prev_pos = (cur_pos +1)
> cur_pos = xstring.find(',',prev_pos) #find the next comma
> return
>
> class Footage(LineReader):
> def parseFtge(section):
> xplus = section.find('+') #find position of '+'
> xfeet = int(section[0:xplus])
> xframes = int(section[(xplus + 1):-1])
> xframes_d = (xframes/16.0)
> return (xfeet + xframes_d)
>
>
>From what I can see you have no need for classes in your code. This is
probably what is causing you trouble at the moment, so I would say just
remove them.
def parse_line(line):
"""splits a line on commas"""
return line.split(',')
def parse_footer(line):
"""Strips off leading four characters (maybe 'Ftr:'), and then
parses the rest as above"""
return parse_line([4:])
That should solve your problem. Below I illustrate some of how classes
work, in case you are dead set on using them. Learning Python should
address all of this as well. I haven't read it, so I can't be more
specific.
To call a method from another method within a class, you need to prefix
it with self. That looks like this:
class Spam(object): ## {1}
def parse_line(self, line): ## {2}
return line.split(',')
def parse_footer(self, line):
return self.parse_line(line[4:]) ## {3}
# {1} always subclass 'object' to use newstyle classes
# {2} Note that method declarations have an extra first argument,
# usually called "self", which refers to your instance of the class.
# {3} "self" finds parse_line within the current class
# or superclasses of the current class. Note that self has
# moved from inside the parentheses to before the method name.
To call a method from another class you need to instantiate that class
first.
class Spam(object):
def parse_line(self, line):
return line.split(',')
class Eggs(object):
def parse_footer(self, line):
parser = Spam()
parser.parse_line(line[4:]) ## {4}
# {4} The Spam instance "parser" is fed to the method "parse_line" as
# its first argument (as "self").
If a class subclasses another class (by, e.g., replacing 'object' with
'Spam' in the class declaration of 'Eggs'), then methods in Eggs can
reference methods in Spam using 'self'.
class Spam(object):
def parse_line(self, line):
return line.split(',')
class Eggs(Spam): ## {5}
def parse_footer(self, line):
return self.parse_line(line[4:]) ## {6}
# {5} Now Eggs is a subclass of Spam
# {6} "self" looks for a method called parse_line in Eggs, and
# when it fails to find it, looks in Eggs' superclass, Spam
# and finds it there.
Hope that helps
Cheers,
Cliff
> >On Mon, 2009-06-22 at 12:13 -0700, Greg Reyna wrote:
> >> Learning Python (on a Mac), with the massive help of Mark Lutz's
> >> excellent book, "Learning Python".
> >>
> >> What I want to do is this:
> >> I've got a Class Object that begins with a def. It's designed to be
> >> fed a string that looks like this:
> >>
> >> "scene 1, pnl 1, 3+8, pnl 2, 1+12, pnl 3, 12, pnl 4, 2+4,"
> >>
> >> I'm parsing the string by finding the commas, and pulling out the
> >> data between them.
> >> No problem so far (I think...) The trouble is, there is a place
> >> where code is repeated:
> >>
> >> 1. Resetting the start & end position and finding the next comma
> >>in the string.
> > >
> >
> >Have you looked at the split() method on string objects. It works kind
> >of like this:
> >
> >>>> s = "scene 1, pnl 1, 3+8, pnl 2, 1+12, pnl 3, 12, pnl 4, 2+4,"
> >>>> s.split(",")
> >['scene 1', ' pnl 1', ' 3+8', ' pnl 2', ' 1+12', ' pnl 3', ' 12', ' pnl
> >4', ' 2+4', '']
> >>>> elements = s.split(",")
> >>>> elements
> >['scene 1', ' pnl 1', ' 3+8', ' pnl 2', ' 1+12', ' pnl 3', ' 12', ' pnl
> >4', ' 2+4', '']
> >>>> elements[2]
> >' 3+8'
> >
> >
> >
> >> In my previous experience (with a non-OOP language), I could create a
> >> 'procedure', which was a separate function. With a call like:
> >> var=CallProcedure(arg1,arg2) the flow control would go to the
> >> procedure, run, then Return back to the main function.
> >>
> >
> >Python doesn't have procedures quite like this. It has functions (the
> >things starting with "def"), which generally speaking take arguments and
> >return values. For the most part, you do not want your functions to
> >operate on variables that aren't either defined in the function or
> >passed in as arguments. That leads to difficult-to-debug code.
> >
> >
> >> In Python, when I create a second def in the same file as the first
> >> it receives a "undefined" error. I can't figure out how to deal with
> >> this. How do I set it up to have my function #1 call my function #2,
> >> and return?
> >
> >Your problem description is confusing. First of all, no class starts
> >with 'def'. They all start with 'class'. Perhaps you are talking about
> >a module (a python file)?
> >
> >Also, telling us that you get an undefined error is not particularly
> >helpful. Every Exception that python raises is accompanied by an
> >extensive stack trace which will help you (or us) debug the problem. If
> >you don't show us this information, we can't tell you what's going
> >wrong. It will tell you (in ways that are crystal clear once you have a
> >bit of practice reading them) exactly what went wrong.
> >
> >Can you show your code, as well as the complete error message you are
> >receiving?
> >
> >My suggestions here, are essentially a paraphrasing of Eric Raymond's
> >essay, "How to Ask Smart Questions." It is freely available on the web,
> >and easily found via google. I recommend reading that, in order to get
> >the most mileage out this news group.
> >
> >Cheers,
> >Cliff
>
More information about the Python-list
mailing list