Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2004
    Location
    FL
    Posts
    19
    Rep Power
    0

    trouble with classes


    what's wrong with this? when trying to run the log i get unbound method parseng() must be called with StormNetParseEng instance as first argument (got nothing instead):

    here's the code for each:
    Code:
    class StormNetParseEng:
        """contains methods to parse dps for Everquest2 log files"""
    
        # not going to use __init__ for anything, but it needs to be here /shrug
        def __init__(self):
            pass
    
    
        def convertTS(self,ts1,ts2):
    	    """takes 2 time stamps and finds the difference in seconds"""
    	    # convert t1,t2 to integers
    	    h1,m1,s1 = (string.atoi(t1.group(1)),string.atoi(t1.group(2)),\
            	       string.atoi(t1.group(3)))
    	    h2,m2,s2 = (string.atoi(t2.group(1)),string.atoi(t2.group(2)),\
            	       string.atoi(t2.group(3)))
    
    	    scnt1 = h1 * (60**2) + m1*60 + s1
    	    scnt2 = h2 * (60**2) + m2*60 + s2
    
    	    # check if the fight went past midnight
    	    if scnt1 > scnt2:
            	scnt1 = h1 * (24 * (60**2)) + m1*60 + s1
        
    	    ftime = scnt2 - scnt1
    	    return float(ftime)
    
    
        def parseng(self,log):
    	    """Does most of the dirty work.
    	    Takes log as a list.
    
    	    returns a fight data"""
                import re
    
    	    initv = (0, 0, 0, 0, 0, 0, 0.0)
    	    missCnt, fdmg, primary, secondary, scndDmg, primDmg, dps = initv
    	    fightCnt, endCnt = 0
    
    	    flist = []
    	    for i in log:
            	if 'You start fighting' in i:
    	            stTime = re.match('^.*(\d{2}):(\d{2}):(\d{2})',i)
            	    fightCnt += 1
    
    	        dmgPrm = re.match('^.*(YOU).*(hit).*(\d+)',i)   # primary dmg (auto attack hits)
            	dmgScnd = re.match('^.*(YOUR).*(hits).*(\d+)',i)# secondary dmg (special moves)
    	        miss = re.match('^.*(YOU?).*(miss.*)',i)
    
            	if dmgPrm:
    	            fdmg += string.atoi(dmgPrm.group(3))
            	    primary += 1
    	            primDmg += string.atoi(dmgPrm.group(3))
    
            	if dmgScnd:
    	            fdmg += string.atoi(dmgScnd.group(3))
            	    secondary += 1
    	            scndDmg += string.atoi(dmgScnd.group(3))
    
            	if miss:
    	            missCnt += 1
    
            	if 'You stop fighting' in i:
    	            endTime = re.match('^.*(\d{2}):(\d{2}):(\d{2})',i)
            	    endCnt += 1
    
    	        # test for incomplete fights. incomplete fights are not added to list
            	if endCnt < fightCnt:
    	            fightCnt -= 1
            	elif endCnt > fightCnt:
    	            fightCnt -= 1
            	elif endCnt == fightCnt:
    	            # calculate dps
            	    dps = fdmg / convertTS(stTime,endTime)
    
    	            # store values
            	    fData = {'damage':fdmg,'prm':primary,'scn':secondary,'misscnt':missCnt,\
            	    'dps':dps,'pdmg':primDmg,'sdmg':scndDmg}
    	            flist.append(fData)
    
            	    # prepare values for next cycle
    	            missCnt, fdmg, primary, secondary, scndDmg, primDmg, dps, = initv
    
    
            	return flist
    and here's the script that calls the class:
    Code:
    import sys
    sys.path.append('c:\\StormNet\cls')
    from StormNetParseEng import * 
    
    f = open('c:\\StormNet\log.txt','r')
    EQ2log = f.readlines()
    f.close
    
    fightList = StormNetParseEng.parseng(EQ2log)
    
    def matrix():
        """Prints fightList's data in a matrix"""
        for i in FightList:
            print ' %d\t(%d/%d)\t(%d/%d)\t%d\t%.2f'% \
            (fightList.index(i),i['damage'],i['prm'],i['pdmg'], \
            i['scn'],i['sdmg'],i['misscnt'],i['dps'])
    
    def output():
        """Prints output of parsed data
    
           returns multiple strings"""
        from datetime import date
        
        today = date.today()
        logdate = today.strftime('Log created on %m.%d.%y')
    
        header = '::StormNet.Parser::\n \
        ::0.2 Beta ::\n\n \
        [ %s ]\n\n \
        Number of fights logged: [ %d ]\n\n \
        FightID\tPrim. Dmg(hits/dmg)\tScnd. Dmg(hits/dmg)\tMisses\tDps'% \
        (logdate, len(fightList))
    
        tdmg, tprim, tscnd, tmiss, tmpf, tpdmg, tsdmg, tdps = (0, 0, 0, 0, 0.0, 0, 0, 0.0)
    
        for i in fightList:
            tdmg += i['damag']
            tprim += i['prm']
            tscnd += i['scn']
            tmiss += i['misscnt']
            tpdmg += i['pdmg']
            tsdmg += i['sdmg']
            tmpf = i['dps']
    
        tdps = tmpf / len(fightList)
    
        footer = '\nOverall damage : [ %d ]\n \
        OverAll hits   : [ %d ]\n \
        OverAll primary damag: [ %d ]\n \
        OverAll secondary damage: [ %d ]\n \
        OverAll misses : [ %d ]\n\n \
        \tAverage dps : [ %.2f ]'% \
        (tdmg, tprim + tscnd, tpdmg, tsdmg, tmisses, tdps)
        
        fightMatrix = matrix()
    
        print header
        print fightMatrix
        print footer
    
    if __name__ == "__main__":
        output()
  2. #2
  3. Mini me.
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2003
    Location
    Cambridge, UK
    Posts
    783
    Rep Power
    14
    You need to create an instance of StormNetParseEng as the error report sort of suggests

    Instead of:
    fightList = StormNetParseEng.parseng(EQ2log)

    use:
    Code:
    snpe = StormNetParseEng() #To create an instance of the class
    fightList = snpe.parseng(EQ2log) #Now you can call the methods
    grim
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2004
    Location
    FL
    Posts
    19
    Rep Power
    0
    Excellent thanks. I was doign something like that but kept trying to make an instance of the method instead :bonks self: .
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2004
    Location
    FL
    Posts
    19
    Rep Power
    0
    Another problem now /sigh . The parseng() method is now returning an error that convertTS() is not defined...its not a syntax error. ARgh!
  8. #5
  9. Mini me.
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2003
    Location
    Cambridge, UK
    Posts
    783
    Rep Power
    14
    Because convertTS is a method in the same class it would be referred to as:

    self.convertTS

    so it becomes:

    dps = fdmg / self.convertTS(stTime,endTime)

    grim
  10. #6
  11. Mini me.
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2003
    Location
    Cambridge, UK
    Posts
    783
    Rep Power
    14
    You don't need an __init__ method unless you are actually going to intitialise something
    This works fine:
    Code:
    class test: 
        def hello(self): 
            print "hello"
    
    c = test()
    c.hello()
    grim
  12. #7
  13. Mini me.
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2003
    Location
    Cambridge, UK
    Posts
    783
    Rep Power
    14
    If the version of python is 2.0 or newer it's easier to use:
    num = int("123")
    which is equivalent to
    num= string.atoi("123")
    but shorter.

    grim
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2004
    Location
    FL
    Posts
    19
    Rep Power
    0
    You're my hero grim . I appreciate all the help. Alot of little things keep tripping me up ^^;
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2004
    Location
    FL
    Posts
    19
    Rep Power
    0
    Another annoying hitch and I'm not sure at all as to how it's comming up. stTime isn't getting assigned for some reason. When the script gets to calling converTS(stTime, endTime) it's saying that stTime is being referenced before assignment. I don't know why though, since the test:
    Code:
    if 'You start fighting' in i:
    part works fine >< .
  18. #10
  19. Mini me.
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2003
    Location
    Cambridge, UK
    Posts
    783
    Rep Power
    14
    Any of these might be the problem:

    1. Your convertTS function is called when fightcnt == endcnt == 0 which will always be true at the begining of a log file unless the first line contains 'You start fighting' .

    2. if the log file has a line with 'You stop fighting' before a 'You start fighting' turns up the script will fail. To handle this I suggest you initially define stime outside of the for loop to be None. Then you can test if stime is not None before doing the convertTS call (you only want paired start/ end times I guess).

    3. If by chance the if test 'You start fighting' passes but there is no text matching your regular expression then stime will also be set to None. This will generate a different failure mode.


    So three ways I think it could fail but 1 being the likely cause of this particular error


    grim
    Last edited by Grim Archon; October 16th, 2004 at 08:31 PM.
  20. #11
  21. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2004
    Location
    FL
    Posts
    19
    Rep Power
    0
    Thanks alot once again. I think it has to do with that conditional about fightcnt and endcnt, will gvie a look in a bit and let you know . i need only paired start/stop fighting because otherwise it will throw the numbers off.
  22. #12
  23. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2004
    Location
    FL
    Posts
    19
    Rep Power
    0
    I did a few tests in the shell to see where the problem may lie, since commenting out the conditionals before the dps calculation didn't work. found that the following works:
    Code:
    for i in log:
        stTime = re.match('^.*(\d{2}):(\d{2}):(\d{2})',i)
        if stTime:
            print 'yo'
    gave me back a bunch of yo's .

    this also worked:
    Code:
    def quicky(arg):
           log = arg
           for i in log:
            if 'You start fighting' in i:
                print 'yo'
    yet, this spits out the same error as i've mentioned:
    Code:
    def quicky(arg):
        log = arg
        for i in log:
            if 'You start fighting' in i:
                stime = re.match('^.*(\d{2}):(\d{2}):(\d{2})',i)
            if stime:
                print stime
    error:
    Code:
    Traceback (most recent call last):
      File "<input>", line 1, in ?
      File "<input>", line 6, in quicky
    UnboundLocalError: local variable 'stime' referenced before assignment
    I just don't see how it can be if the above 2 examples worked. and before i split this app up into the class for the parser and a script to display the data, it worked >< .

    this also didn't work ><
    Code:
    stime = None
    stime
    def quicky(arg):
        log = arg
        for i in log:
            if 'You start fighting' in i:
                stime = re.match('^.*(\d{2}):(\d{2}):(\d{2})',i)
            if stime:
                print stime
  24. #13
  25. Mini me.
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2003
    Location
    Cambridge, UK
    Posts
    783
    Rep Power
    14
    How about attaching a zip of the logfile to a reply?

    As I suggested before, I suspect that the first line(s) of your log file do not contain 'You start fighting'.
    Try this ...
    Code:
    def quicky(arg):
        log = arg
        for i in log:
            if 'You start fighting' in i:
                stime = re.match('^.*(\d{2}):(\d{2}):(\d{2})',i)
            try: 
                if stime:
                    print stime
            except:
                print "Failed with log line: ", `i`

    Code:
    [001] stime = None
    [002] stime
    [003] def quicky(arg):
    [004]     log = arg
    [005]     for i in log:
    [006]         if 'You start fighting' in i:
    [007]             stime = re.match('^.*(\d{2}):(\d{2}):(\d{2})',i)
    [008]         if stime:
    [009]             print stime
    In the above code you do not need line [002] and line [008] is only True if stime is not None. So stime will only be printed if the regular expression gets a match. What error do you get?

    grim
  26. #14
  27. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2004
    Location
    FL
    Posts
    19
    Rep Power
    0
    I did a quick copy paste of the code from the shell, so line 002 was just me testing to make sure stime was set to null . The error I got is in my last post:
    Code:
    Traceback (most recent call last):
      File "<input>", line 1, in ?
      File "<input>", line 6, in quicky
    UnboundLocalError: local variable 'stime' referenced before assignment
    I'll give your code snip a shot, and since eq2's nda has been lifted i'll post a zip file of the log i'm working with.
  28. #15
  29. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2004
    Location
    FL
    Posts
    19
    Rep Power
    0
    that code snippet worked flawlessly grim.
    Now, how to use it in the parseng() method.
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo