Parse received variables from python flask - python

How do i parse my received variables into arrays. I receive them from a site and i want to insert them into my firebird database but it would be a lot faster if i could do that through parsing it into a list.
This is how my flask code looks:
#app.route('/fddatumupdate', methods=['GET'])
def fddatumupdate():
datums = request.args.get('datums')
IDS1 = request.args.get('ids1')
IDS2 = request.args.get('ids2')
IDS3 = request.args.get('ids3')
print datums
print IDS1
print IDS2
print IDS3
#cur.execute("UPDATE OR INSERT INTO T_FOOD_DUTY (F_FD_DATE, F_US_ID1, F_US_ID2, F_US_ID3) values(%s, %s, %s) matching (F_FD_DATE)")
return("great succes")
This is the printing output so you can see how my data looks:
2017-5-15,2017-5-16,2017-5-17,2017-5-18,2017-5-19,2017-5-20,2017-5-21
27,36,26,435,26,30,31
27,28,30,435,27,28,26
30,28,30,28,29,28,27
I always get the error when i try to parse them from an NoneType to a string or array:
TypeError: unsupported operand type(s) for +: 'NoneType' and ...

You can split your string by , character and you will get a list:
print datums.split(',')
Alternatively, you can use list comprehensions to construct your list with some extra checking:
# example code
if datums: # this will check if 'datums' is None
print [i if i > 0 for i in datums.split(',')] # include element in list only if it is larger than 0

Found the answer, I parsed my received variables while i was receiving them en putthing them into my local variables. It needs to be like this then:
datums = request.args.get('datums')
IDS1 = request.args.get('ids1')
IDS2 = request.args.get('ids2')
IDS3 = request.args.get('ids3')
datumArray = str(datums).split(',')
IDS1Array = str(IDS1).split(',')
IDS2Array = str(IDS2).split(',')
IDS3Array = str(IDS3).split(',')

Related

Parse plaintext API response

Im getting plaintext responses from an API like these:
So i would like to parse or pass those values to variables.
Example:
If the response is:
TD_OK
3213513
I would like to convert this to:
TD_Result = TD_OK
TD_Number = 3213513
I tried something like this, but did not work:
result = """
TD_EXISTS
23433395"""
result2 = []
for r in result:
result2.append(r)
TD_Result = result2[1]
TD_Number = result2[2]
print (TD_Result)
print (TD_Number)
Any idea about how to do that?
for r in result: -> for r in result.splitlines():
or
as #Matmarbon said, below will be better
result = """
TD_EXISTS
23433395
"""
td_result, td_number = result.split()
print(td_result)
print(td_number)
get rid of unnecessary dict
use Extended Iterable Unpacking
use snake_case to comply with its naming convention
You can do this using the split method as follows.
Also note that list indexes in Python start at zero instead of one.
result = """
TD_EXISTS
23433395"""
result2 = result.split()
TD_Result = result2[0]
TD_Number = result2[1]
print (TD_Result)
print (TD_Number)

int() argument must be a string, a bytes-like object or a number, not 'tuple'

so baiscally my code in this section is supposed to get a value from a sql database and add the tkinter value onto it then put the value back into the sql database
with sqlite3.connect('aircraft.db') as db:
c = db.cursor()
self.flightcount4 = self.flightcount5.get()
self.flightcount3 = int(self.flightcount4)
c.execute("SELECT flightcount FROM aircraft WHERE Arrive = ?",(self.travelselect.get(),))
self.total3 = c.fetchone()
total2 = int(self.total3)
self.total = total2 + self.flightcount3
c.execute('UPDATE aircraft SET flightcount = :flightcount WHERE Arrive = :Arrive',{'flightcount':self.flightcount3, 'aircraftpilot':self.pilotname5 })
db.commit()
ms.showinfo('Success!', 'its saved!')
this is my code.
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\adam\AppData\Local\Programs\Python\Python36-
32\lib\tkinter\__init__.py", line 1702, in __call__
return self.func(*args)
File "C:\A LEVELS\Computing\atom\actual results\working\Customer.py",
line 40, in addtocount
total2 = int(self.total3)
TypeError: int() argument must be a string, a bytes-like object or a
number, not 'tuple'
[Finished in 30.761s]
this is the error.
since then i have came up with this with your help:
def addtocount(self):
with sqlite3.connect('aircraft.db') as db:
c = db.cursor()
self.flightcount4 = self.flightcount5.get()
self.flightcount3 = int(self.flightcount4)
c.execute("SELECT flightcount FROM aircraft WHERE Arrive = ?",(self.travelselect.get(),))
self.total3 = c.fetchone()[0]
print(self.total3)
if self.total3 == "None":
self.total2 == int("0")
print(self.total2)
else:
self.total2 = self.total3
self.total = self.total2 + self.flightcount3
c.execute('UPDATE aircraft SET flightcount = :flightcount WHERE Arrive = :Arrive',{'flightcount':self.flightcount3, 'aircraftpilot':self.pilotname5 })
db.commit()
ms.showinfo('Success!', 'its saved!')
but now the error is:
File "C:\A LEVELS\Computing\atom\actual results\working\Customer.py", line 46, in addtocount
self.total = self.total2 + self.flightcount3
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
[Finished in 15.573s]
thanks in advance
As far as I know c.fetchone() fetches the whole row. Even if you only specify one value in the SQL-statement it will be wrapped in a tuple. Syntax wise it will look something like this if you tried to print it:
('flightcount value')
Pay notice those pesky parentheses around the value.
The reason you get the error is because int(self.total3) tries to parse the whole tuple (row) from c.fetchone(). Instead you need to select the specific column from the row, like this:
int(self.total3[0])
The error is exactly what Python tells you: int() can only accept strings, bytes (another kind of string), or numbers, and you are passing a tuple. This means that self.total3 is some set of values wrapped like this: (x,y,z).
Looking at sqlite's Python docs, it seems that it returns database rows as tuples, with each tuple slot representing a column of the database. You can unwrap the tuple with assignment or indexing:
col1, col2, col3 = row # where row is (col1, col2, col3)
col1 = row[0] # indexed from 0
When you encounter an issue like this, my first step is to always find the offensive value in question (here the "int() argument" that the compiler points out to us, self.total3) and simply print() it in order to see what looks wrong.
You probably don't need to be introducing all of these class state variables (self.xyz) if you aren't using them outside of this context. It would be simpler to use local variables for anything that is only used in this context.
self.total3 = c.fetchone()
total2 = int(self.total3)
Here, self.total3 is the whole row. Even if you selected a single value, the return value is wrapped in a tuple. You need to get your value from the tuple.
self.total3 = c.fetchone()[0]
total2 = int(self.total3)
fetchone() returns a tuple, since it supports retrieving a row of multiple things. In your case you selected a single thing (flightcount), but you still have to treat the return value as a tuple. So it should be:
self.total3 = c.fetchone()[0]
int() can only parse one value, not a tuple. What you can do is:
total2 = [int(value) for value in self.total3]
then, you have the tuple values in a list of integers.
Try accessing the first element:
int(self.total3[0])
or
self.total3 = cursor.fetchone()[0]

Tuple object has no attribute text

I am writing a code to get specific information from yahoo finance website
page = requests.get('http://finance.yahoo.com/q/pr?s=%s')
tree=html.fromstring(page.text)
annual_report = tree.xpath('//td[#class="yfnc_datamoddata1"]/text()')
annual_report
Where %s is a name of a stock. If I manually input a name of a stock everything works great. But if I try to run a for loop for a list that I made,
for x in my_list:
page = requests.get('http://finance.yahoo.com/q/pr?s=%s'),(x,)
tree=html.fromstring(page.text)
annual_report = tree.xpath('//td[#class="yfnc_datamoddata1"]/text()')
print annual_report
I get an error on tree line 'tuple' object has no attribute 'text'
Your mistake is:
page = requests.get('http://finance.yahoo.com/q/pr?s=%s'),(x,)
Instead of formatting the string, you made 'page' a tuple.
This should work:
page = requests.get('http://finance.yahoo.com/q/pr?s=%s' % (x,))
page = requests.get('http://finance.yahoo.com/q/pr?s=%s'),(x,)
This is not how to define a format string. You accidentally created a tuple ('http://finance.yahoo.com/q/pr?s=%s', x)
To incorporate x into the string write it like this:
page = requests.get('http://finance.yahoo.com/q/pr?s=%s' % x)
Or even better because not needing specifiers:
page = requests.get('http://finance.yahoo.com/q/pr?s={0}'.format(x))
page = requests.get('http://finance.yahoo.com/q/pr?s=' + x)

Converting tuple into list does not work

I query my SQlite Database with a loop to retrieve data from it.
connector = sqlite3.connect("somedb.db")
selecter = connector.cursor()
selecter.execute(''' SELECT somedata FROM somedb''')
for row in selecter:
l = list(row)
print (l)
print (type(l))
Then I try do use formatting to append the retrieved data to something else
this = detect.that( "{}", pick, summary).format(l)
But it comes back with this:
AttributeError: 'tuple' object has no attribute 'format'
I also tried this
s = " ".join(str(row) for row in selecter)
for the l = list(row) statement but it comes back with the same errormessage and it seems that it converts all my 50 separate selections into one string what I dont want.
However, when I run this
print (type(l))
or
print (type(s))
it returns me list or stringas a type. So the converting worked, but the .format does not take it because it thinks it is a tuple.
How comes?
Change your detect.that line to this:
this = str(detect.that("{}", pick, summary)).format(1)

What Might Cause Python Error 'str' object does not support item assignment

I'm trying to debug some Python 2.7.3 code to loop through a list of items and convert each to a string:
req_appliances = ['9087000CD', 'Olympus', 185]
for i in range(0, len(req_appliances)):
req_appliances[i] = str(req_appliances[i])
print req_appliances
The output is as follows:
['9087000CD', 'Olympus', '185']
In the example above, I've set the value of req_appliances explicitly to test the loop. In the actual code, req_appliances is an argument to a function. I do not know the type of the argument at runtime, but it appears to be a list of scalar values. I do know that when I invoke the function, I see the following error message:
File ".../database.py", line 8277, in get_report_appliance_list
req_appliances[i] = str(req_appliances[i])
TypeError: 'str' object does not support item assignment
I'm trying to deduce for what values of argument req_appliances it would be possible for this error condition to arise. It seems to me that all of the values are scalar and each (even if immutable) should be a valid LHS expressions in an assignment. Is there something I'm missing here? Here is the code in context, in the function in which it is defined:
def get_report_appliance_list(self, req_appliances, filter_type=None):
appliances = {}
appliance_list = []
if filter_type != None:
if filter_type not in ('appliances', 'servers'):
raise ValueError("appliance filter_type must be one of 'appliances' or 'servers'")
active_con = self.get_con()
if active_con is None:
raise Exception('No database connections are available.')
con = None
in_expr_items = ''
if req_appliances != None:
# Create a string like '(%s, %s, ...)' to represent
# the 'in' expression items in the SQL.
print(req_appliances)
for i in range(0, len(req_appliances)):
req_appliances[i] = str(req_appliances[i])
in_expr_items += '%s,'
in_expr_items = '(' + in_expr_items[:-1] + ') '
An str acts like a sequence type (you can iterate over it), but strings in Python are immutable, so you can't assign new values to any of the indices.
I expect what's happening here is that you're trying to run this when req_appliances is a str object.
I came up with two ways to fix this:
First, just check if it's a str before you iterate over it:
if isinstance(req_appliances, basestring):
return req_appliances
Second, you could check each item to see if it's already a string before trying to assign to it.
req_appliances = ['9087000CD', 'Olympus', 185]
for i in range(0, len(req_appliances)):
if req_appliances[i] != str(req_appliances[i]):
req_appliances[i] = str(req_appliances[i])
print req_appliances
Here, I'm actually checking whether the member is equal to its string representation. This is true when you iterate over strings.
>>> a = 'a'
>>> a[0] == str(a[0])
True
This is not really an answer to your question, but a style advise. If you happen to use for i in range(0, len(something)) a lot you should either use for i, obj in enumerate(something), map(func, something) or a list comprehension [func(x) for x in something].
Another red flag is the use of string += inside a loop. Better create an array and join it. This also eliminates the need to do stuff like [-1] in order to get rid of trailing commas.
Regarding your code you could simplify it a lot:
def get_report_appliance_list(self, req_appliances, filter_type=None):
appliances = {}
appliance_list = []
if filter_type not in (None, 'appliances', 'servers'):
raise ValueError("appliance filter_type must be one of 'appliances' or 'servers'")
active_con = self.get_con()
if active_con is None:
raise Exception('No database connections are available.')
# Create a string like '(%s, %s, ...)' to represent
# the 'in' expression items in the SQL.
in_expr_items = ','.join(['%s'] * len(req_appliances)
req_appliances = map(str, req_appliances)
...
Apart from that I would recommend that get_con() throws so you do not have to check for None in your code.

Categories