2017-06-23 12:03:52

Ahoy all.

I am making my slow way across python,and this time better than I have previously.
Perhaps its the better material I'm refering to, or all the scripting I have tried has helped me in understand certain things which I wasn't able to before.
This is kind of game related,and kind of not. Its more of how would I go about doing x in python or any programming language type of question more than anything else.

I have Written a utility in python that reads a file,which contains settlement logs from core-exiles
a abbreviated output of which is as follows

Jun 15th 08:55 pm
» Dragon: Wesbec Delivery (192) to Magnia / Set Fee: 103697 CR 
Jun 15th 06:47 pm
» Achilleos: Wesbec Delivery (102) to Daray / Set Fee: 4776 CR 
Jun 15th 06:43 pm
» Achilleos: Wesbec Delivery (152) to Quettin / Set Fee: 6340 CR 
Jun 15th 06:43 am
» Dragon: Wesbec Delivery (200) to Furia Station / Set Fee: 105039
Jun 14th 05:54 pm
» Korth: Wesbec Delivery (183) to Rosotika / Set Fee: 46576 CR 
Jun 14th 05:54 pm
» Korth: Wesbec Delivery (180) to Sul-Rodet / Set Fee: 45812 CR 

There's a reason why I have the log as that long,bare with me.
So far I have managed to make it take input of a filename,read lines in the file,determine which we want,discard which are not needed.
the lines beginning with the symble » are the ones we are interested in.
the word 1 or the second word as they'd say in python and other languages is the word in the lines we are interested in,along with the second last word.
I.E Dragon,and the numbers before CR
So far I have managed to get the first word and the second last from each line and have the utility get second last words  percentage and print it out.

What I'd like to do is, have the code read each line,and give me the total of the percentages of all dragons hauls,korths and so on.
They won't be in order,as can be seen from the log above,I.E dragon appears once,then twice with another in between.
I'm thinking I could achieve something like this with dictionaries, any ideas? suggestions?
Thanks!
grryf

Of all sad words of tongue or pen, the saddest are these, ‘It might have been.
Follow me on twitter

2017-06-23 12:41:34

Hi,
that's it. Just use a dictionary with entries with keys of the name of the creatures you're matching here and the value will be the amount of the units, end when your parsing ends, you can calculate the collected values against each other.
Best Regards.
Hijacker

2017-06-23 14:33:54 (edited by Kyleman123 2017-06-23 14:35:45)

An easier way to do it if you know regular expressions is to use a regex on the blocks of text you want to match. you can then loop through all of the matches saving values to a running total and print out the result.

I don’t believe in fighting unnecessarily.  But if something is worth fighting for, then its always a fight worth winning.
check me out on Twitter and on GitHub

2017-06-23 15:14:33

That's related to the way he parses the text, which he didn't tell us. He just told us that he parses the text, which is nice and can be done in several elegant and fast ways, but also several dumb ways which might work, but need alot of calculation time. Regex is a nice and fast way to parse the lines and get the content you want, but it needs time to learn and not everyone knows about them. His question related to the way of saving the numbers and calculating the percentage out of them, this can be done easily by using dictionaries.

2017-06-23 16:27:21

Hello there,
Thank you both for your replys and suggestions.

Right now I use the for to loop through line,split them into words and then use slicing to find the words. I have yet to learn regex,but aye, when I do, I might see if I can make that work.

Here's the code I have written,no dictionary so far,though.

inp = input('enter the name of the file to be opened\n') #asks for a file,opens it,a guard to handle misspelled or files that don't exist
try:
    fhand = open(inp)
except:
    print('Are you on medications? there is no',inp)
    exit()
per = input('Enter the percentage you would like to calculate from,percentage of the fees recieved')
perc = float(per)
for line in fhand:
    if not line.startswith('»') or  line.startswith('» Falconner:'): continue
    words = line.rstrip().split() #stripping the right spaces and splitting into words
    feesrecieved = words[-2]
    actam = float(feesrecieved)*perc/100 #actual amount the answer per haul based on percentage
    print(words[1], actam)

Now how would I go about doing actam(actual amount)'s total for each person,instead of just printing actam for each person.
look at the log in the first post, looking for a way to make it so that korths 2 actams are totaled and printed,and same for rest. dragon and so on.
Thanks!
grryf

Of all sad words of tongue or pen, the saddest are these, ‘It might have been.
Follow me on twitter

2017-06-23 20:02:34

Unrelated to the question, but figured I'd comment.
Instead of trying and excepting everything, then insisting the file doesn't exist, you might want a more straight forward method, such as os.path.isfile, alternatively just print error. Really small thing, but it could prevent a lot of pissed off users trying to remember if they used there medication that day. big_smile

2017-06-23 21:01:52

In fact, it's probably the better way to try and except in languages which support it, this reduces huge amounts of file system calls and such stuff in this case which are actually unnecessary if the file path is correct, but the if would do it in any case, even if the path is correct. But the actually wrong idea here is to except everything. That isn't a good way of code. You should only except the exceptions which are relevant for this special error you want to handle. In your case that would be the IOError, which raises each time you want to open a file which doesn't actually exist.
Best Regards.
Hijacker

2017-06-24 02:15:39 (edited by cartertemm 2017-06-24 02:17:16)

correct me if I'm wrong, but if you try opening a file, an IOError for something that doesn't exist is not the only thing that can happen, therefore what I said before still stands

2017-06-24 02:24:05

All good suggestions here.

As far as counting how many times a specific person is seen (or doing something with a specific value for that person's entry), you would either want a dictionary with the person's name as the entry, and the key being the number of times that name has been encountered, or the key being a list of some values.
Remember to check to see if a dictionary key with the current person's name exists, like this:

names_dict = {}
name = "some name here"
if names_dict.get(name, None) == None: # if we don't have a key in the dict for person yet
    # if you are just counting the occurrences
    names_dict[name] = 0
names_dict[name] += 1 # add 1 to the value

As mentioned above, if you want to keep track of specific numbers for each name, you'll probably want to use a list for the dict value rather than an integer; instead of setting names_dict[name] to 0, make it a list by using [].

If you want to sort your dict (and all you are doing is counting the occurrences of names), you can do the following, continuing from the example above:

from operator import itemgetter

# this returns a list of tuples; the name from the dict is the first item, the value is the second

# from least to greatest
sorted_dict = sorted(names_dict.items(), key=itemgetter(1))

# from greatest to least
sorted_dict = sorted(names_dict.items(), key=itemgetter(1), reverse=True)

Hope this helps smile

Regards,
Blademan
Twitter: @bladehunter2213

2017-06-30 19:08:16 (edited by grryfindore 2017-07-01 12:55:09)

Ahoy all,
Thanks for your answers.
That didn't really work, that is that's not what I was aiming for.but I don't have time just atm,so can't try it out,but I guess with experemantation I should be able to do something. if it doesn't work,I'll pop back in here. and if it does work,I'll write back saying so.

Blademan and others,sending you guys forum mail,could use your help with something.
edit ignore the mail,have it sorted.
Grryf

Of all sad words of tongue or pen, the saddest are these, ‘It might have been.
Follow me on twitter