3

I'm working with Splunk, but this seems to be a python-related problem I'm having.

By an API call, I'm receiving a list of dictionaries, and I'm iterating through the individual dictionaries to print out a specific field. It looks like this:

with open(lobFileName, "w+") as LOBs: #read/write, truncates file!
        for item in reader:
            for key in item: # iterate through the dictionary
                if key == 'cost_center':
                    print item[key] # TODO: Replace this with however I display it on the webpage.
                    LOBs.write(item[key]) # write the LOBs to the file, one LOB per line
                    LOBs.write("\n")

reader is the list, item is the individual dictionary.

The print call works perfectly. It prints out the lines of businesses as I want it to, as it should. So I don't give out personal information (the real words are English, similar in length, if that matters... one word no spaces), the output looks like:

Alpha

Bravo

Charlie

However, when I write() the same thing (item[key]), I get an: "expected a character buffer object" error.

So, I change it to LOBs.write(str(item[key]). But when I write the file, instead of getting the above output, I get (A,B,C bolded for ease of sight):

Alpha~1116~7F4F9983-72F8-48C8-BFAD-82C0F713CA34 1116:18886924 1437770160 1 07-24-2015 16:35:59.888 -0400 INFO Metrics - group=per_index_thruput, series="clo", kbps=3.596555, eps=13.129038, kb=111.493164, ev=407, avg_age=2.422604, max_age=27 199 ['ksplidx4c', '_internal'] splunkd .888 2015-07-24T16:35:59.888-04:00

Bravo

psplfwd1a _internal 1 clo /opt/splunk/var/log/splunk/metrics.log splunkd ksplidx4c _internal~1116~7F4F9983-72F8-48C8-BFAD-82C0F713CA34 1116:18886931 1437770160 1 07-24-2015 16:35:59.888 -0400 INFO Metrics - group=per_index_thruput, series="cos", kbps=564.982992, eps=1387.129659, kb=17514.464844, ev=43001, avg_age=2.232622, max_age=11 198 ['ksplidx4c', '_internal'] splunkd .888 2015-07-24T16:35:59.888-04:00

Charlie

psplfwd1a _internal 1 cos /opt/splunk/var/log/splunk/metrics.log splunkd ksplidx4c _internal~1116~7F4F9983-72F8-48C8-BFAD-82C0F713CA34 1116:18886952 1437770160 1 07-24-2015 16:35:59.888 -0400 INFO Metrics - group=per_index_thruput, series="issofim", kbps=1.250410, eps=12.193554, kb=38.762695, ev=378, avg_age=1.738095, max_age=8 195 ['ksplidx4c', '_internal'] splunkd .888 2015-07-24T16:35:59.888-04:00

Now, I know that looks huge and you have no idea what that means Just hear me out :). Obviously there's a difference in how write() works vs. how print() works. Now that this is explained, my question:

  • Does anybody know how I can mimic the way print() works into how write() works, so that I get the clean A, B, C output on each line?

Thank you so much. I think this^ is the best way to approach the problem, if possible.

Reciever80
  • 105
  • 1
  • 1
  • 10
  • 2
    What is the type of the object at `item[key]` that you are trying to print? – Two-Bit Alchemist Jul 24 '15 at 21:00
  • For that matter what's `reader`, a list of dicts? – Adam Smith Jul 24 '15 at 21:03
  • @Two-BitAlchemist I printed() out 'type([key])' when I was trying to debug it myself. Each time it printed (literally) 'str' on each line. instead of Alpha, Bravo, Charlie. So it should be returning strings, which is one of the reasons this is so confusing – Reciever80 Jul 24 '15 at 21:05
  • @AdamSmith yep! Also: thanks for editing the tags, I'm rather awful at thinking of them :) – Reciever80 Jul 24 '15 at 21:05
  • That is odd because a normal string would not show any difference in this case. What is the output of `repr(item[key])`? – Two-Bit Alchemist Jul 24 '15 at 21:10
  • @Reciever80 are you maybe calling `print(key)` instead of `print(item[key])`? It may be that `type(key)` is str, but `type(item[key])` certainly isn't based on the error message. – dsh Jul 24 '15 at 21:13
  • @dsh So I ran it again, and ensured that it printed "print type(item[key])". It's different than last time, before it didn't have the > or < symbols. The output is (on their own lines): – Reciever80 Jul 24 '15 at 21:16
  • @Two-BitAlchemist Replaced it, and the file is the same but there are now single quotes surrounding each line of text. :/ – Reciever80 Jul 24 '15 at 21:19
  • Is there a difference in delimiters for print vs. write(). Specifically, does print stop at the newline and will write() continue until completed? Maybe that's it. If so, does someone know how to mimic that in my write statement? Or would that not matter with how I wrote the print and write statements? – Reciever80 Jul 24 '15 at 21:21

2 Answers2

0

https://docs.python.org/3/library/functions.html#print

All non-keyword arguments are converted to strings like str() does and written to the stream,

As the error message indicates, you need to convert your objects to strings (however that is appropriate for your purpose) before you can write it to a stream.


Link to Python 2.7 docs: https://docs.python.org/release/2.7/library/functions.html#print

dsh
  • 12,037
  • 3
  • 33
  • 51
  • Alas, when I do that the second half of the problem occurs (all that crap gets written to the file, and I don't know why). – Reciever80 Jul 24 '15 at 21:06
  • So that is entirely dependent on the object you have. Some classes define `__str__` to define a default way they are converted to strings. Perhaps you want to write just one attribute of the object (name, title, id, or something) instead of the result of `str()`. There is also the `repr()` function that is similar to str() (but probably not what you want, just might be relevant to understand). – dsh Jul 24 '15 at 21:09
  • Hmm.. sounds like a good idea. The problem is, I know I should be getting 'Alpha' when I get the first item[key]. That makes sense. It's just have no idea why python is writing the rest of the dictionary fields when it's working for print(). Thus, i have no idea how to write just one attribute of the object, even moreso since python is reporting the value object as a string :/ – Reciever80 Jul 24 '15 at 21:14
0

Can you try again with this code instead and provide us the output?

with open(lobFileName, "w+") as LOBs: #read/write, truncates file!
        for item in reader:
            for key in item: # iterate through the dictionary
                if key == 'cost_center':
                    print "%s\n" % (item[key]) # TODO: Replace this with however I display it on the webpage.
                    LOBs.write("%s\n" % (item[key])) # write the LOBs to the file, one LOB per line

Now you should see the same in the print as in the file

Sergio Ayestarán
  • 5,590
  • 4
  • 38
  • 62
  • No change in file output :(. – Reciever80 Jul 24 '15 at 21:20
  • 1
    Try again with the updated code and give us some feedback – Sergio Ayestarán Jul 24 '15 at 21:25
  • 1
    IT WORKED AND I HAVE NO IDEA HOW BUT THANK YOU (capital letters on purpose, I spent 6 hours trying to fix this). Edit: If reader is a buffer or a stream (I honestly don't remember the difference right now), would that explain why the extra crap was there for the write, and that's why changing the print worked? – Reciever80 Jul 24 '15 at 21:34
  • 1
    If the item is not a string that can explain the extra characters there, specially if it comes from a buffer/stream. But honestly IDK what reader is. All the magic here should come from the old Python formatting method: "%s" % (somevariable) will automatically convert somevariable to string and give you the result. – Sergio Ayestarán Jul 24 '15 at 21:50
  • I'm just surprised that the write() function only worked when you changed the working Print() statement before it. Seems odd, but i'm just glad it works now! – Reciever80 Jul 24 '15 at 21:54