Python list index bizarre behavior - python

I have a section of code that somehow fails on the following list.index function:
for line in flines:
for match in bad_data_regex.findall(line):
assert line in flines
index = flines.index(line)
flines.pop(index)
# other code that does not modify flines ....
My code fails on:
ScriptEngine.execute:Error in script Traceback (innermost last):
File "<string>", line 168, in ?
ValueError: list.index(x): x not in list
If the value truly wasn't in the list, I should've gotten an AssertionError before the list.index function.
I'm using Jython 2.2.1 under Java version 1.6.0_18.
How is this possible?
EDIT:
Turns out the code that was generating that error was not what I have posted above. My Jython interpreter gave me the wrong line number, and happened to land on the line with the index function above.
The above code does work as I intended, although I realize it's not the best practice to modify a list while iterating over it. I'll try to avoid that whenever possible in the future.

This probably happens because of the flines.pop(index) part. It is always a bad idea to change the list while you iterate over it.
Consider this example:
In [1]: a = range(5)
In [2]: for i in a:
...: print a.pop()
...:
4
3
2
In [3]: a
Out[3]: [0, 1]

Related

Python list(?) sending incorrect number of values to other program

I have been trying to upload close to a thousand SVG files to a particular program (FontForge) and as such searched for a way to automate it. Unfortunately I am really unfamiliar with Python, to the extent that I'm not sure if what I changed about the code ended up changing something fundamental.
The original code you were meant to individually continue the table that the original coder left with the file name and glyph names of the SVG files. This would require doing it manually, as I realized quickly it wouldn't allow loops within the brackets itself. The original code was as follows, albeit with more items:
select = [
('null', 'null'),
('bs-info-circle', 'infoCircle'),
]
Looking at it, and with a lot of googling and experimentation, I guessed that it was a list of tuples. As such, I created various loops adding onto a toSelect list that I created. Since they are rougly the same I'll just show one here:
for x in svc:
icon="svc-"+x+"con_lang"
glyph=x
#print((icon, glyph))
toSelect.extend(((icon, glyph),)) #comma necessary to force it to add in a pair, rather than individually
The variable svc is a list of strings: ['ba', 'be', 'bi', 'bo'...] pulled from a TXT file. The variable toSelect, when printed, looks as follows:
[('svc-bacon_lang', 'ba'), ('svc-becon_lang', 'be'), ('svc-bicon_lang', 'bi'), ...]
Long story short, I now have a list that seems to be formatted the same as the contents of the original code. As such, I set it equal in a simple manner:
select = toSelect
However, running the build program that pulls from this code is giving the following error message:
Traceback (most recent call last):
File "C:\Users\*****\Downloads\ff-batch-main\ff-batch-main\build.py", line 392, in <module>
run_fontforge(config)
File "C:\Users\*****\Downloads\ff-batch-main\ff-batch-main\build.py", line 148, in run_fontforge
for key, name in config.select:
ValueError: not enough values to unpack (expected 2, got 1)
I have tried every variation of declaring select that I can, including a few that cause the following error message:
Traceback (most recent call last):
File "C:\Users\*****\Downloads\ff-batch-main\ff-batch-main\build.py", line 392, in <module>
run_fontforge(config)
File "C:\Users\*****\Downloads\ff-batch-main\ff-batch-main\build.py", line 148, in run_fontforge
for key, name in config.select:
ValueError: too many values to unpack (expected 2)
Printing the value of select[0] does seem to tell me that that error is caused by all of the entries being considered one entry on the list? So at least I know that.
Still, I can't figure out why it doesn't take my original attempt, as select[0] = ('null', 'null'). I'm worried that select isn't supposed to be a list at all, but is something different that I'm simply unfamiliar with since I do not know python. Is this some sort of function that I broke by adding items sequentially instead of all at once?
I will also show the code from the 'build' program that is flagged as the problem. The only thing that I edited was the 'config' program, as instructed by the coder, but hopefully this at least will give context?
def run_fontforge(config):
from icon_map import maps
try:
from select_cache import maps as icons
except:
icons = {}
print(f"Generating fonts => {config.build_dir}/{config.font_name}.ttf")
with open('select_cache.py', 'w') as f:
f.write("# SVG to Font Icon mapping\n")
f.write(f"# Generated: {datetime.now()}\n")
f.write("maps = {\n")
last = config.font_start_code - 1
for _,m in icons.items():
last = max(last, m['code'])
last += 1
for key, name in config.select:
icon = icons.get(key)
src = maps.get(key)
So yeah. Um, any advice or explanations would be greatly appreciated, and I'll do my best to give additional information when possible? Unfortunately I started trying to understand Python yesterday and am coming at this from a rusty knowledge of java so I am not really fluent, might not know terms and whatnot. I just wanted to import some files man...
You've gotten quite far just 1 day into Python.
My hypothesis for the bug is config.select not containing the toSelect data.
Ways to investigate:
Interactively run this to verify that toSelect is a list of pairs:
for k, n in toSelect: pass
print both variables, or interactively evaluate config.select == toSelect to compare them, or set breakpoints in the PyCharm or VSCode debugger and examine these variables.
Is this some sort of function that I broke by adding items sequentially instead of all at once?
No.
BTW, you can make:
toSelect.extend(((icon, glyph),))
easier to understand by writing it as:
toSelect.append((icon, glyph))
Bonus: The most "Pythonic" way to write that for loop is as a list comprehension:
toSelect = [("svc-"+x+"con_lang", x) for x in svc]

Problem with making a Reddit bot in python

I'm trying to program a reddit bot, but get this error message:
Traceback (most recent call last):
File "main.py", line 64, in <module>
run_bot(r, comments_replied_to)
File "main.py", line 34, in run_bot
comments_replied_to.append(comment.id)
AttributeError: 'filter' object has no attribute 'append'
Here is my code: https://pastebin.com/caz14jm7
I think I have to change append into a list, but I don't know how to do that
Part of this is a version difference. In Python 2, filter returned a list. In Python 3, filter returns a generator, which you are treating like a list. The filter generator does not have an append method.
So, you just need to turn it into a list:
comments_replied_to = list(filter(None, comments_replied_to))
Or, even better (in the opinion of many):
comments_replied_to = [k for k in comments_replied_to if k]
I have 2 potential solutions for you,
solution 1:
Line 55 You can change like this
comments_replied_to = List(filter(None, comments_replied_to))
so that, your get_saved_comments() will return a list.
This will help you use the append method and comments_replied_to.append(comment.id) should work without any error
Solution 2:
Line 60: You can change like this
comments_replied_to = list(get_saved_comments())
As long as comments_replied_to is a list type, it will allow you to append method without any issues.
check this blog to have a better understanding over append method
https://www.programiz.com/python-programming/methods/list/append

Type error that shows on console, but not on pythontutor.com

Ok, so I have a block of code that I am trying to debug, and I usually use Pythontutor.com to step through the code to see where it is going wrong. Problem is, the exact code works on the website, but not in my console.
row = []
row.append("Acid Arrow")
testList = ['Detect', 'Discern', 'Summon', 'Call', 'Binding']
nameList = row[0].split(' ')
print testList, nameList
a = list(set(testList) & set(nameList))
The error I am getting is this:
C:\Users\User\Dropbox\D&D\SpellBag>livingSpell.py
['Detect', 'Discern', 'Summon', 'Call', 'Binding'] ['Acid', 'Arrow']
Traceback (most recent call last):
File "C:\Users\User\Dropbox\D&D\SpellBag\livingSpell.py", line 121, in <module>
sb = spellBook(r'allSpells.csv')
File "C:\Users\User\Dropbox\D&D\SpellBag\livingSpell.py", line 27, in __init__
a = list(set(testList) & set(nameList))
TypeError: 'str' object is not callable
The above code works flawlessly on PythonTutor, but fails when I run it in the console. What it is intended to do is check if a word from the list is in the spell name, which if any of them are, the spell is passed over and it moves on. It should be returning an empty list, but instead I get the error.
The line that has the error is a = list(set(testList) & set(nameList)), and the error says "'str' object is not callable." This means the Python interpreter tried to call a function and found out it wasn't actually a function. This is the same error you would get if you typed "bad_code"(), since the string "bad_code" is not a function.
It's impossible to say exactly which of the two is having an issue, but either list or set has been overwritten and is now a string rather than the default functions provided in Python. That snippet of code works fine by itself in pythontutor.com because the offending line of code happens somewhere before it in your file (the error says you have 22 lines of code beforehand). In fact, if you started a blank file and only had the snippet you posted here on StackOverflow, it would run perfectly. Check for anything like list = ... or set = ... in your original source code.
It is a somewhat common convention in Python to avoid naming conflicts with reserved words (list, set, or, if, with, while, etc...) by appending an underscore to the name. In this case, that would mean writing either list_ = ... or set_ = .... A good coding practice in general though would be to come up with a specific name for your variable that describes it exactly. For example, you might use used_spell_list instead of list (just guessing...I have no idea how this was overwritten).

Python: ValueError: invalid literal for float():

I'm really new with python. So maybe my question is really basic...For my work I'm checking different parameters in a period of time. For the Beginning with Python I wanted to plot a simple List with daily measured Temperature-values for a month. In the List I've three splits like these following structure:
Day -TAB- Temperature -TAB- Nr
My Code:
import pylab as pl
import numpy as np
filename = "u_netCDF_write"
file = open(filename)
NoOfValues = 31
counter=0
data = []
for line in file:
if counter <= NoOfValues:
data.append(line.strip('\n').strip('\t').split(' '))
if len(data[-1]) == 4:
data[-1].pop(3)
counter+=1
x = np.linspace(0,30,31)
data = np.transpose(data)
for i in range(len(data[2])):
data[2][i] = float(data[2][i])-273.15
When I try to plot a Temperature-per-Day-Plot I get the Error-Message:
Traceback (most recent call last):
File ".../.../unetCDFplot.py", line 43, in <module>
data[2][i] = float(data[2][i])-273.15
ValueError: invalid literal for float(): 03.07.2014
It looks like that the Code didn't transpose the Data. Why is that so? Can anybody help me?
Thanks!
I solved my problem! So for anybody who has the same problem, here is what I did: I used
print(repr(data))
(thanks to Stephany Dionysio) to check every step in my code and understood that the problem was not the transpose-function, but the empty spaces in every line. After trying different methods to delete the empty spaces I saw that I couldn't delete an array in an array caused by 'data.append'. To get the values I needed I used pop() in the append method:
data.append(line.strip('\n').strip('\t').split(' ').pop(7))
Now my code works fine. Thank you for your good advices, they put me to the right way! :)
I don't know the content of your "u_netCDF_write" file so it is reasonably dificult to debug it. But as the other post shows, it cloud be a non-printing character that's present in the value.
See if this helps
python ValueError: invalid literal for float()
03.07.2014 cannot be a float. It looks like you're using the wrong data from your data list.

Python - KeyError while creating an index

Here is the code (it runs inside class):
if profile['profile_picture']:
profile['profile_picture_raw_path'], # Line 26
profile['profile_picture_thumbnail'],
profile['profile_picture'] = self.picture_path(profile['profile_picture'])
Keys don't exist. The typical result returned by picture_path is
('//domain.com/218971848/21924823397471f5e4e41a803da17f7c.jpg:large', '//domain.com/profile-images/218971848/21924823397471f5e4e41a803da17f7c.jpg:thumb-100', '//domain.com/profile-images/218971848/21924823397471f5e4e41a803da17f7c.jpg:exact')
As you can see the result is a tuple of 3 elements.
And I got an error:
File "/srv/rwt/production/application/rwt/profile.py", line 26, in load_profile
profile['profile_picture_raw_path'],
KeyError: 'profile_picture_raw_path'
Why does this error appear? Searched Stack Overflow for similar questions, but they seem to be asked about accessing dictionary values by not-existing keys.
profile['profile_picture_raw_path'], on a line by itself is parsed as a standalone expression (a rather useless one, though).
You need to tell the Python interpreter that the next lines are part of the expression:
profile['profile_picture_raw_path'], \
profile['profile_picture_thumbnail'], \
profile['profile_picture'] = self.picture_path(profile['profile_picture'])
use a bracket
if profile['profile_picture']:
(profile['profile_picture_raw_path'], # Line 26
profile['profile_picture_thumbnail'],
profile['profile_picture']) = self.picture_path(profile['profile_picture'])

Categories