Making a variable name to check if it's defined in Python - python

I have a form where you have the option to add upload inputs. I want the images that will be uploaded with every input to be grouped together (there will be text in between). Every time an upload button is added it get's the name "upload_image1", "upload_image2", ...
I want to check if these names are defined so i can then loop through them later. I am trying to combine upload_image and an integer that is counting up together but it looks like he is trying to add that integer to the value of upload_image which is not defined.
if len(form["upload_image1"]) > 0:
while 1:
field_count = 1
if len(form["upload_image" + str(field_count)]) == 0: break
upload_field = form["upload_image" + str(field_count)]
upload_image += upload_field
article_content += """
<p>%s</p>
""" % (description[field_count].value)
for item in upload_field:
article_content += '<img src="http://www.******.com/images/%s/%s">' % (link_title, item.filename)
field_count = field_count + 1

Here is how to avoid the KeyError:
If form["upload_image1"] is a string, then use form.get("upload_image1", "") instead.
If form["upload_image1"] is a sequence (e.g. list or tuple), then use form.get("upload_image1", ()) instead.

I fixed the Memory Error. I accidentally put field_count = 1 inside my loop so it kept resetting itself.
The rest apparently works just fine. Thanks for the help!

Related

Dataframe Is No Longer Accessible

I am trying to make my code look better and create functions that do all the work from running just one line but it is not working as intended. I am currently pulling data from a pdf that is in a table into a pandas dataframe. From there I have 4 functions, all calling each other and finally returning the updated dataframe. I can see that it is full updated when I print it in the last method. However I am unable to access and use that updated dataframe, even after I return it.
My code is as follows
def data_cleaner(dataFrame):
#removing random rows
removed = dataFrame.drop(columns=['Unnamed: 1','Unnamed: 2','Unnamed: 4','Unnamed: 5','Unnamed: 7','Unnamed: 9','Unnamed: 11','Unnamed: 13','Unnamed: 15','Unnamed: 17','Unnamed: 19'])
#call next method
col_combiner(removed)
def col_combiner(dataFrame):
#Grabbing first and second row of table to combine
first_row = dataFrame.iloc[0]
second_row = dataFrame.iloc[1]
#List to combine columns
newColNames = []
#Run through each row and combine them into one name
for i,j in zip(first_row,second_row):
#Check to see if they are not strings, if they are not convert it
if not isinstance(i,str):
i = str(i)
if not isinstance(j,str):
j = str(j)
newString = ''
#Check for double NAN case and change it to Expenses
if i == 'nan' and j == 'nan':
i = 'Expenses'
newString = newString + i
#Check for leading NAN and remove it
elif i == 'nan':
newString = newString + j
else:
newString = newString + i + ' ' + j
newColNames.append(newString)
#Now update the dataframes column names
dataFrame.columns = newColNames
#Remove the name rows since they are now the column names
dataFrame = dataFrame.iloc[2:,:]
#Going to clean the values in the DF
clean_numbers(dataFrame)
def clean_numbers(dataFrame):
#Fill NAN values with 0
noNan = dataFrame.fillna(0)
#Pull each column, clean the values, then put it back
for i in range(noNan.shape[1]):
colList = noNan.iloc[:,i].tolist()
#calling to clean the column so that it is all ints
col_checker(colList)
noNan.iloc[:,i] = colList
return noNan
def col_checker(col):
#Going through, checking and cleaning
for i in range(len(col)):
#print(type(colList[i]))
if isinstance(col[i],str):
col[i] = col[i].replace(',','')
if col[i].isdigit():
#print('not here')
col[i] = int(col[i])
#If it is not a number then make it 0
else:
col[i] = 0
Then when I run this:
doesThisWork = data_cleaner(cleaner)
type(doesThisWork)
I get NoneType. I might be doing this the long way as I am new to this, so any advice is much appreciated!
The reason you are getting NoneType is because your function does not have a return statement, meaning that when finishing executing it will automatically returns None. And it is the return value of a function that is assigned to a variable var in a statement like this:
var = fun(x)
Now, a different thing entirely is whether or not your dataframe cleaner will be changed by the function data_cleaner, which can happen because dataframes are mutable objects in Python.
In other words, your function can read your dataframe and change it, so after the function call cleaner is different than before. At the same time, your function can return a value (which it doesn't) and this value will be assigned to doesThisWork.
Usually, you should prefer that your function does only one thing, so expect that the function changes its argument and return a value is usually bad practice.

Assigning a variable from a different file with a string

In the file values there are a bunch of lists and I want to assign gun_type to a value depending on what my current_gun_name is plus the string _Iron.
How do I do this? This is my current code but it doesnt work
current_gun_name = string_assigned_above
iron = win32api.GetAsyncKeyState(0x67)
if iron < KeyMin and win32api.GetAsyncKeyState(0x11) < 0:
gun_type = values.(current_gun_name + "_Iron")
So, on the last line there I am trying to pull a list from another file called values. But the list that I am trying to pull depends on the current_gun_name string. For example:
current_string = "test"
list_from_values = values.(current_gun_name + "ing")
print(list_from_values)
In this code it should find a list in the file called values. The list it will find and print will be called "testing" as I am asking it to use the variable plus "ing" Except this doesnt work

Multiple Filtering DataFrame in Python to Use PyQt5 app

self.myDataFrame = pd.read_csv("myCSV.csv")
def filterValues(self):
if self.h02_1_lineEdit != "":
self.h02_1_flag = 1
self.filter_h02_1 = (self.myDataFrame['H:02-1'] == self.h02_1_lineEdit.text())
else:
self.h02_1_flag = 0
if self.h02_x_lineEdit != "":
self.h02_x_flag = 1
self.filter_h02_x = (self.myDataFrame['H:02-X'] == self.h02_x_lineEdit.text())
else:
self.h02_x_flag = 0
# it will take 6 filters in here
print(self.myDataFrame[self.filter_h02_1 & self.filter_h02_x])
Hello fellas, I've basic application in Python with DF to use on PyQt5 application. As you can see, I read some datas from csv files. And I want to filter some values according to text written on QLineEdit. However, If QLineEdit is empty, I dont want to filter it. But I couldnt figure out how to. On other applications, I can (and I did) solve this issue by using flags. i.e Sql apps. But in that apps, we use query as strings. So that was easy to use.
My real problem here is MULTIPLE FILTERING, again if every line edit (6 line edit I used) or one line edit filtered there is no problem. But, For example, I dont want to use self.filter_h02_x and leave it as empty. Now this is where I stuck. If needed I can upload all code, but I guess you understand the problem.
To clearify my question;
If we can use self.myDataFrame as string I can use
self.mainFilter = "self.myDataFrame[" # for definition
...
self.filter_h02_1 = "(self.myDataFrame['H:02-1'] == self.h02_1_lineEdit.text())"
...
if self.h02_1_flag = 1:
self.myDataFrame += self.filter_h02_1 + "]"
print(self.mainFilter)
But this is not string, this is definition. If I try to define it one by one there are 6! options...
In case you don't want to filter you can use a mask of all Trues
if self.h02_1_lineEdit.text() != "":
self.filter_h02_1 = (self.myDataFrame['H:02-1'] == self.h02_1_lineEdit.text())
else:
self.filter_h02_1 = [True] * len(myDataFrame)

Python - Perform file check based on format of 3 values then perform tasks

All,
I am trying to write a python script that will go through a crime file and separate the file based on the following items: UPDATES, INCIDENTS, and ARRESTS. The reports that I generally receive either show these sections as I have previously listed or by **UPDATES**, **INCIDENTS**, or **ARRESTS**. I have already started to write the following script to separate the files based on the following format with the **. However, I was wondering if there was a better way to check the files for both formats at the same time? Also, sometimes there is not an UPDATES or ARRESTS section which causes my code to break. I was wondering if there is a check I can do for this instance, and if this is the case, how can I still get the INCIDENTS section without the other two?
with open('CrimeReport20150518.txt', 'r') as f:
content = f.read()
print content.index('**UPDATES**')
print content.index('**INCIDENTS**')
print content.index('**ARRESTS**')
updatesLine = content.index('**UPDATES**')
incidentsLine = content.index('**INCIDENTS**')
arrestsLine = content.index('**ARRESTS**')
#print content[updatesLine:incidentsLine]
updates = content[updatesLine:incidentsLine]
#print updates
incidents = content[incidentsLine:arrestsLine]
#print incidents
arrests = content[arrestsLine:]
print arrests
You are currently using .index() to locate the headings in the text. The documentation states:
Like find(), but raise ValueError when the substring is not found.
That means that you need to catch the exception in order to handle it. For example:
try:
updatesLine = content.index('**UPDATES**')
print "Found updates heading at", updatesLine
except ValueError:
print "Note: no updates"
updatesLine = -1
From here you can determine the correct indexes for slicing the string based on which sections are present.
Alternatively, you could use the .find() method referenced in the documentation for .index().
Return -1 if sub is not found.
Using find you can just test the value it returned.
updatesLine = content.find('**UPDATES**')
# the following is straightforward, but unwieldy
if updatesLine != -1:
if incidentsLine != -1:
updates = content[updatesLine:incidentsLine]
elif arrestsLine != -1:
updates = content[updatesLine:arrestsLine]
else:
updates = content[updatesLine:]
Either way, you'll have to deal with all combinations of which sections are and are not present to determine the correct slice boundaries.
I would prefer to approach this using a state machine. Read the file line by line and add the line to the appropriate list. When a header is found then update the state. Here is an untested demonstration of the principle:
data = {
'updates': [],
'incidents': [],
'arrests': [],
}
state = None
with open('CrimeReport20150518.txt', 'r') as f:
for line in f:
if line == '**UPDATES**':
state = 'updates'
elif line == '**INCIDENTS**':
state = 'incidents'
elif line == '**ARRESTS**':
state = 'arrests'
else:
if state is None:
print "Warn: no header seen; skipping line"
else
data[state].append(line)
print data['arrests'].join('')
Try using content.find() instead of content.index(). Instead of breaking when the string isn't there, it returns -1. Then you can do something like this:
updatesLine = content.find('**UPDATES**')
incidentsLine = content.find('**INCIDENTS**')
arrestsLine = content.find('**ARRESTS**')
if incidentsLine != -1 and arrestsLine != -1:
# Do what you normally do
updatesLine = content.index('**UPDATES**')
incidentsLine = content.index('**INCIDENTS**')
arrestsLine = content.index('**ARRESTS**')
updates = content[updatesLine:incidentsLine]
incidents = content[incidentsLine:arrestsLine]
arrests = content[arrestsLine:]
elif incidentsLine != -1:
# Do whatever you need to do to files that don't have an arrests section here
elif arreststsLine != -1:
# Handle files that don't have an incidents section here
else:
# Handle files that are missing both
Probably you'll need to handle all four possible combinations slightly differently.
Your solution generally looks OK to me as long as the sections always come in the same order and the files don't get too big. You can get real feedback at stack exchange's code review https://codereview.stackexchange.com/

Python: Multiple instances seem to be sharing properties (or something?!)

Python is my first language, and I am very new to it, so the answer may be very clear, but after many hours looking and experimenting, I am not sure what is causing the problem.
An overview of the module:
The DicePool module is meant to manage collections of "dice", stored as dictionary items. Each dictionary key (herein poolKey) has a list containing information about one "type" of dice, most importantly, a tuple describing its faces and an integer representing the quantity of "dice" type 'x' in the "pool."
My specific question regards the Transfer method, which used to be two methods (send and receive, basically), but which I thought I could combine into one method. When the test code at the bottom runs, I'd like it to leave dp.dictPool[poolKey][1] == 0 and dp2.dictPool[poolKey][1] == 2. But in every attempt I've made, the values come out the same. Sorry I can't categorize this question better . . . I don't really know what the problem is.
Anyway, one half of the Transfer method is supposed to run for the "sender" instance, and one half is supposed to run for the "receiver" instance.
import random
class DicePool(object):
def __init__(self):
self.dictPool = {}
def AddDice(self, poolKey, faces = 6, quant = 1, color = "white"):
'''faces must be int or items 'a,b,c'; count must be int or def to 1'''
try: #if count is not an integer, it defaults to 1
quant = int(quant)
except:
print("Quant is not an integer, defaulting to 1")
quant = 1
try: #if faces is can be int, a list is built of numbers 1 to faces
faces = int(faces)
if faces < 2: #a 1 or 0-sided die breaks the program
faces = 2
tempList = []
for i in range(1, faces+1):
tempList.append(i)
faces = tempList
except: #if faces is not an integer, it is split into list items by ","
faces = faces.split(",")
if poolKey in self.dictPool.keys(): #if the key already exists in pool
self.dictPool[poolKey][1] += quant #add to the quantity,
else: #if the key does not already exist, set all attributes
self.dictPool[poolKey] = [faces, quant, color]
def Transfer(self, poolKey, targetPool, sendQuant, senderPool = None):
'''targetPool must be DicePool instance'''
if targetPool:
self.dictPool[poolKey][1] -= sendQuant
targetPool.Transfer(poolKey, None, sendQuant, self)
else:
try:
self.dictPool[poolKey][1] -= sendQuant
except:
self.dictPool[poolKey] = senderPool.dictPool[poolKey]
self.dictPool[poolKey][1] = sendQuant
dp = DicePool()
dp2 = DicePool()
dp.AddDice("d6")
dp.AddDice("d6")
dp.Transfer("d6",dp2,2)
print(dp.dictPool,dp2.dictPool)
The problem is in this line:
self.dictPool[poolKey] = senderPool.dictPool[poolKey]
The values in your dictPools are lists. Here, you set one object's dictPool value to the same list as in the other one. Not a copy of the list, but the same list. So later if you add or subtract from that list, it will affect the other as well, because they are sharing one list object.
Try doing self.dictPool[poolKey] = senderPool.dictPool[poolKey][:]. The [:] grabs the contents of the list rather than the list object iself.
In both parts of the if/else in Transfer you're subtracting the quantity. Don't you want to subtract it in one case but add it in the other?
Is else: try: self.dictPool[poolKey][1] -= sendQuant supposed to be += sendQuant instead?
Might be a semantic issue, not a Python syntax issue.
Here is a version of the Transfer() method that seems to work as intended (more or less), although it's very clumsy looking:
def Transfer(self, poolKey, targetPool, sendQuant, senderPool = None):
'''targetPool must be DicePool instance'''
if isinstance(targetPool, DicePool):
#valid target, so subtract dice here, then call Transfer on target
temp = self.dictPool[poolKey][1:2][0] - sendQuant
print("sent",sendQuant,"leaving",temp)
targetPool.Transfer(poolKey, "Receiver", sendQuant, self)
elif targetPool == "Receiver":
#this executes if a DicePool is named as the targetPool of Transfer
if poolKey in self.dictPool.keys():
self.dictPool[poolKey][1:2][0] += sendQuant
else:
self.dictPool[poolKey] = senderPool.dictPool[poolKey]
self.dictPool[poolKey][1:2] = [sendQuant]
print("now have",self.dictPool[poolKey][1:2][0])
pass
else:
print("Not a valid targetPool, apparently")

Categories