Extracting the value from SQLite query as integer in Python - python

I made a SQLite query in Python like that:
SharesOwned = db.execute("SELECT SUM(Shares) FROM transactionTable WHERE Share='FB'")
print(SharesOwned)
if sharesOwned < sharesToSell:
return errorMessage("You don't own that many shares of FB")
It prints:
[{'SUM(Shares)':10}]
Then it gives me this error:
TypeError: "List indices must be integers or slices not str"
How can I extract the number as an integer?

It looks like SharesOwned is a list of dictionaries. To return the number of shares you need to do the following in this particular case:
SharesOwned[0]['SUM(Shares)']
SharesOwned[0] accesses the first element of the list, in this case a dictionary {'SUM(Shares)':10}. Now you just need to lookup the value by key - 'SUM(Shares)' in this case.
Additionally, it looks like you have a typo in sharesOwned, s should be capitalized.

Try below changes :
Update your query:
SELECT SUM(Shares) AS total FROM transactionTable WHERE Share='FB'
Then access SharedOwned:
if SharedOwned[0]['total']<sharesToSell:

Related

populating sqlite3 db with links in python

I'm trying to populate a database with a single column with a list of strings (links). I scraped the list and I must modify every single link before sending it to the database. This is the code:
for event in events:
link_url = "https://www.website.com"+event+"#all"
c.execute("INSERT INTO table (links) VALUES(?)", link_url)
I can get it working if I modify the variables and send a tuple, like this:
for event in events:
link_url = "https://www.website.com"+event+"#all"
link = (link_url,)
c.execute("INSERT INTO seriea (links) VALUES(?)", link_url)
but I don't want to use this solution since I want to get a list of strings back out later:
c = connection.execute('select links from table')
list_of_urls = c.fetchall()
But this gives me a list of tuples.
This is the error I have: ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 80 supplied.
I think that's because the string characters are counted (actually more but I noticed that the number before "supplied" changes with the link fed)
I don't want to use this solution since I want to get a list of strings back out later:
c = connection.execute('select links from table')
list_of_urls = c.fetchall()
But this gives me a list of tuples.
The list of tuples you're getting when you do a select have nothing to do with the way you insert data. Remember, tables have two dimensions:
id
links
something
else
1
"foo"
"bar"
"baz"
2
"quux"
"herp"
"derp"
When you do a select you get a list that corresponds to the rows here. But each row has multiple fields: id, links, something, and else. Each tuple in the list contains the values for each of the fields in the table.
If you just want the URLs as a list of strings you can use a list comprehension or similar:
c = connection.execute('select links from table')
list_of_rows = c.fetchall()
list_of_strings = [row[0] for row in list_of_rows]
# ^ index of first element in
# ^^^ the tuple of values for each row
Note that you do have to provide a tuple or other sequence when you insert the data:
For the qmark style, parameters must be a sequence. For the named style, it can be either a sequence or dict instance. The length of the sequence must match the number of placeholders, or a ProgrammingError is raised. If a dict is given, it must contain keys for all named parameters.
You might be thinking of the tuple part of it the wrong way. You don't need to pass in a tuple of URLs, you need to pass in a tuple of parameters. You're not saying "the links column should contain this tuple" but rather "this tuple contains enough values to fill in the placeholders in this query".
I'd rewrite that like so:
for event in events:
link_url = "https://www.website.com"+event+"#all"
c.execute("INSERT INTO seriea (links) VALUES(?)", (link_url,))
This is so you can have multiple parameters, e.g.
c.execute(
"INSERT INTO seriea (links, some, other) VALUES(?, ?, ?)",
(link_url, foo, bar),
)
The current statement uses 1, and there are 80 supplied.
I think that's because the string characters are counted
Yes, that's most likely what's happening. c.execute() expects to receive a sequence, and strings are a sequence of characters.

Slicing a dictionary's value isn't working properly

So I have a json file which contains role ids (a dictionary named roles),with a key (which is the name of the role) and each key has the role's id as it's value
Looks something like this:
{"Ban": ["694175790639743076"], "Muted": ["692863646543380590"]}
I mostly just need the ids from the json
using something like roles['Muted'] or roles.get('Muted') gives me ['692863646543380590']:
Muted=roles.get('Muted')
print(Muted)
the functions take integers,so I have to remove [' from the output and get this: 692863646543380590
slicing just gives me [] no matter what slicing I use:
work=boost1[2:20] *or any other slice*
print(work)
gives out "[]"
why is slicing just not working here? and how do I fix this??
first of all roles['Muted'] is a list, if you want just first element then get it with 0 index then try using int() for converting it to Integer:
Muted=int(roles.get('Muted')[0]) # or Muted=int(roles['Muted'][0])
Muted will be:
692863646543380590
Try this -
work = int(boost1[0]) #fetching the first element of list and converting it into int

TypeError: tuple indices must be integers or slices, not str

I need to make a function that updates tuples in a list of tuples. The tuples contain transactions, which are characterised by ammount, day, and type. I made this function that should completely replace a tuple with a new one, but when I try to print the updated list of tuples I get the error:
TypeError: tuple indices must be integers or slices, not str
The code:
def addtransaction(transactions, ammount, day, type):
newtransactions = {
"Ammount": ammount,
"Day": day,
"Type": type
}
transactions.append(newtransaction)
def show_addtransaction(transactions):
Ammount = float(input("Ammount: "))
Day = input("Day: ")
Type = input("Type: ")
addtransaction(transactions, ammount, day, type)
def show_all_transaction(transactions):
print()
for i, transaction in enumerate(transactions):
print("{0}. Transaction with the ammount of {1} on day {2} of type: {3}".format(
i + 1,
transaction['Ammount'], ; Here is where the error occurs.
transaction['Day'],
transaction['Type']))
def update_transaction(transactions): ; "transactions" is the list of tuples
x = input("Pick a transaction by index:")
a = float(input("Choose a new ammount:"))
b = input("Choose a new day:")
c = input("Choose a new type:")
i = x
transactions[int(i)] = (a, b, c)
addtransaction(transactions, 1, 2, service)
show_all_transaction(transactions)
update_transaction(transactions)
show_all_transaction(transactions)
A tuple is basically only a list, with the difference that in a tuple you cannot overwrite a value in it without creating a new tuple.
This means you can only access each value by an index starting at 0, like transactions[0][0].
But as it appears you should actually use a dict in the first place. So you need to rewrite update_transaction to actually create a dict similar to how addtransaction works. But instead of adding the new transaction to the end you just need to overwrite the transaction at the given index.
This is what update_transaction already does, but it overwrites it with a tuple and not a dict. And when you print it out, it cannot handle that and causes this error.
Original answer (Before I knew the other functions)
If you want to use strings as indexes you need to use a dict. Alternatively you can use namedtuple which are like tuples but it also has an attribute for each value with the name you defined before. So in your case it would be something like:
from collections import namedtuple
Transaction = namedtuple("Transaction", "amount day type")
The names given by the string used to create Transaction and separated by spaces or commas (or both). You can create transactions by simply calling that new object. And accessing either by index or name.
new_transaction = Transaction(the_amount, the_day, the_type)
print(new_transaction[0])
print(new_transaction.amount)
Please note that doing new_transaction["amount"] will still not work.
This is not a generic answer, I'll just mention it if someone bumps into the same problem.
As stated before, tuples are addressed by integer e.g. my_tuple[int] or slice my_tuple[int1:int2].
I ran into trouble when I ported code from Python2 to Python3. The original code used somthing like my_tuple[int1/int2], this worked in Python2 since division int/int results in int.
in Python3 int/int results in a floating point number.
I had to fix the code to my_tuple[int1//int2] to get the python2 behavior.

Web2py comparing part of a request.vars element

I have a form with a table with rows containing SELECTs with _names with IDs attached, like this:
TD_list.append(TD(SELECT(lesson_reg_list, _name='lesson_reg_' + str(student[4]))))
When the form is submitted I want to extract both the student[4] value and the value held by request.vars.lesson_reg_student[4].
I've tried something like:
for item in request.vars:
if item[0:9] == "lesson_reg":
enrolment_id = int(item[10:])
code = request.vars.item
I also tried treating request.vars like a dictionary by using:
for key, value in request.vars:
if key[0:9] == "lesson_reg":
enrolment_id = int(key[10:])
code = value
but then I got 'too many values to unpack'. How do I retrieve the value of a request.vars item when the last part of its name could be any number, plus a substring of the item name itself?
Thanks in advance for helping me.
In Python, when slicing, the ending index is excluded, so your two slices should be 0:10 and 0:11. To simplify, you can also use .startswith for the first one:
for item in request.vars:
if item.startswith('lesson_reg'):
enrolment_id = int(item[11:])
code = request.vars.item

Accessing and extracting a dictionary set within my dictionary

I have a dictionary within a dictionary like below:
My code looks for todays date and if it exists in dict it should print “found a match at” + dict(name)
today = datetime.datetime.now()
if today in dict[name]:
print "Found a bday for " + str(dict[name])
#here i need a variable that will hold the email from that name so I can use to somewhere else
If I excuse print dict
It looks like this:
{'name1': set(['01-25', 'name1#company.com']), 'name2': set(['name2#company.com', '11-29']), 'name3': set(['08-15', 'name3#company.com']), 'name4': set(['01-24', 'name4#company.com'])}
My questions is how do I access the email. I understood the hard way that the values in my dictionary are currently a ‘set’ that I can’t access by indexing. Once I do print dict[name][1] then I get the error TypeError:
'set' object does not support indexing
Sets are unordered data structures, so you cannot access them with the index.
Even if you typecast them to a list, and then use a index,i.e. list(dict[name])[1] it is not guaranteed to return correct element, as the order of the list is not defined.
Your way to pick out matching element can be to iterate the set, and select the element which matches conditions like type and any possible regex, but that is also prone to error, unless your sets have few elements of different types.
You are using a set when you create the dict, where you should be using a list or a tuple.
dict.setdefault(name, [emails,bdays])
You could use something like this:
date = today.strftime('%m-%d')
for names in var.keys():
if date in var[names]:
for x in var[names]:
if x != date:
email = x
print "Found a bday for " + email
But there are better options to store this information.

Categories

Resources