Query
Balance.objects.filter(~Q(fax_date=F('paused_date')))
returns empty qs even though I do have objects that fit the condition "fax date field not equal to paused date". Is it possible to use ~Q and F together like that?
ran a test like this:
deals = Deal.objects.all()
balance_pre = Balance.objects.filter(~Q(fax_date=F('paused_date')), fax_date__isnull=False, reserved=False)
agr_nums = list(deals.filter(agr_name__isnull=False).values_list('agr_name', flat=True).distinct())
agrs_with_fax = 0
for agr_num in agr_nums:
try:
balance_agr = Balance.objects.get(number__icontains=agr_num)
if balance_agr.fax_date is not None and balance_agr.fax_date != balance_agr.paused_date and not balance_agr.reserved:
agrs_with_fax += 1
except Balance.DoesNotExist:
pass
agrs_with_fax2 = 0
for agr_num in agr_nums:
try:
balance_pre.get(number__icontains=agr_num)
agrs_with_fax2 += 1
except Balance.DoesNotExist:
pass
r = [agrs_with_fax, agrs_with_fax2, balance_agr.fax_date, balance_agr.paused_date, balance_agr.reserved]
r returned is
[55, 0, datetime.date(2018, 7, 11), None, False]
I don't see my error, both cycles should return same result.
I created a Balance model in a fresh project just to test that print(qs.query) will show you the generated query(not in all cases) in this case. I used also exclude as #daniel-roseman suggested to prove that they were equivalent. I hope this help you.
>>> from django.db.models import F, Q
>>> qs = Balance.objects.filter(~Q(fax_date=F('paused_date')))
>>> print(qs.query)
SELECT "so_balance"."id", "so_balance"."fax_date", "so_balance"."paused_date"
FROM "so_balance" WHERE NOT ("so_balance"."fax_date" =
("so_balance"."paused_date"))
>>> qs = Balance.objects.exclude(fax_date=F('paused_date'))
>>> print(qs.query)
SELECT "so_balance"."id", "so_balance"."fax_date", "so_balance"."paused_date"
FROM "so_balance" WHERE NOT ("so_balance"."fax_date" =
("so_balance"."paused_date"))
Related
import urllib.request
import json
from collections import Counter
def count_coauthors(author_id):
coauthors_dict = {}
url_str = ('https://api.semanticscholar.org/graph/v1/author/47490276?fields=name,papers.authors')
respons = urllib.request.urlopen(url_str)
text = respons.read().decode()
for line in respons:
print(line.decode().rstip())
data = json.loads(text)
print(type(data))
print(list(data.keys()))
print(data["name"])
print(data["authorId"])
name = []
for lines in data["papers"]:
for authors in lines["authors"]:
name.append(authors.get("name"))
print(name)
count = dict()
names = name
for i in names:
if i not in count:
count[i] = 1
else:
count[i] += 1
print(count)
c = Counter(count)
top = c.most_common(10)
print(top)
return coauthors_dict
author_id = '47490276'
cc = count_coauthors(author_id)
top_coauthors = sorted(cc.items(), key=lambda item: item[1], reverse=True)
for co_author in top_coauthors[:10]:
print(co_author)
This is how my code looks this far, there are no error. I need to get rid of the rest of the text when I run it, so it should look like this:
('Diego Calvanese', 47)
('D. Lanti', 28)
('Martín Rezk', 21)
('Elem Güzel Kalayci', 18)
('B. Cogrel', 17)
('E. Botoeva', 16)
('E. Kharlamov', 16)
('I. Horrocks', 12)
('S. Brandt', 11)
('V. Ryzhikov', 11)
I have tried using rstrip and split on my 'c' variable but it doesn't work. Im only allowed importing what I already have imported and must use the link which is included.
Tips on simplifying or bettering the code is also appreciated!
("Extend the program below so that it prints the names of the top-10 coauthors together with the numbers of the coauthored publications")
From what I understand you are not quite sure where your successful output originates from. It is not the 5 lines at the end.
Your result is printed by the print(top) on line 39. This top variable is what you want to return from the function, as the coauthors_dict you are currently returning never actually gets any data written to it.
You will also have to slightly adjust your sorted(...) as you now have a list and not a dictionary, but you should then get the correct result.
If I understand correctly you are wanting this function to return a count of each distinct co-author (excluding the author), which it seems like you already have in your count variable, which you don't return. The variable you DO return is empty.
Instead consider:
import urllib.request
import json
from collections import Counter
def count_coauthors(author_id):
url_str = (f'https://api.semanticscholar.org/graph/v1/author/{author_id}?fields=name,papers.authors')
response = urllib.request.urlopen(url_str)
text = response.read().decode()
data = json.loads(text)
names = [a.get("name") for l in data["papers"] for a in l["authors"] if a['authorId'] != author_id]
#The statement above can be written long-hand like:
#names=[]
#for l in data["papers"]:
# for a in l["authors"]:
# if a['authorId'] != author_id:
# names.append(a.get("name"))
return list(Counter(names).items())
author_id = '47490276'
cc = count_coauthors(author_id)
top_coauthors = sorted(cc, key=lambda item: item[1], reverse=True)
for co_author in top_coauthors[:10]:
print(co_author)
('Diego Calvanese', 47)
('D. Lanti', 28)
('Martín Rezk', 21)
('Elem Güzel Kalayci', 18)
('B. Cogrel', 17)
('E. Botoeva', 16)
('E. Kharlamov', 16)
('I. Horrocks', 12)
('S. Brandt', 11)
('V. Ryzhikov', 11)
You might also consider moving the top N logic into the function as an optional paramter:
import urllib.request
import json
from collections import Counter
def count_coauthors(author_id, top=0):
url_str = (f'https://api.semanticscholar.org/graph/v1/author/{author_id}?fields=name,papers.authors')
response = urllib.request.urlopen(url_str)
text = response.read().decode()
data = json.loads(text)
names = [a.get("name") for l in data["papers"] for a in l["authors"] if a['authorId'] != author_id]
name_count = list(Counter(names).items())
top = top if top!=0 else len(name_count)
return sorted(name_count, key=lambda x: x[1], reverse=True)[:top]
author_id = '47490276'
for auth in count_coauthors(author_id, top=10):
print(auth)
in view.py
Id = [2,3,4,5,6,7,8]
for w in Id:
A = w
Pending = pending(A)
data = {
'Pending': Pending,
}
return render_to_response('dialer_campaign/campaign/list.html', data, context_instance=RequestContext(request))
def pending(campaign_id):
A = Campaign_phonebook.objects.values_list('phonebook_id').filter(campaign_id = campaign_id)
B = Contact.objects.filter(phonebook_id__in=A).count()
C = Subscriber.objects.filter(campaign_id = campaign_id).exclude(status = 1).count()
Result = B - C
return Result
When i add manual value instead of A it gives result,but now i want to give value by for loop it is not working.Why ? Can anybody Help me ?
Want changes should i do in templates ?
Thanks in Advance..
Take your data object in list and render to the template
Refer following code
Id = [2,3,4,5,6,7,8]
pending_list = []
for w in Id:
pending = pending(w)
pending_list.append({'pending': pending})
return render_to_response('dialer_campaign/campaign/list.html', pending_list, context_instance=RequestContext(request))
def pending(campaign_id):
A = Campaign_phonebook.objects.values_list('phonebook_id').filter(campaign_id = campaign_id)
B = Contact.objects.filter(phonebook_id__in=A).count()
C = Subscriber.objects.filter(campaign_id = campaign_id).exclude(status = 1).count()
Result = B - C
return Result
Use pending_list in your template. In pending_list list you get all the pending objects.
I have query with dynamic conditions,i.e.
select (lambda obj:obj.A = 'a' and obj.B = 'b' and ...)
So i write code for this:
def search(self,**kwargs):
q = unicode('lambda obj:', 'utf-8')
for field,value in kwargs.iteritems():
value = unicode(value, 'utf-8')
field = unicode(field, 'utf-8')
q+=u" obj.%s == '%s' and" % (field,value
q = q[0:q.rfind('and')]
res = select(q.encode('utf-8'))[:]
But i have this error during execution of function:
tasks.search(title='Задача 1',url='test.com')
res = select(q.encode('utf-8'))[:]
File "<string>", line 2, in select
File ".../local/lib/python2.7/site-packages/pony/utils.py", line 96, in cut_traceback
return func(*args, **kwargs)
File ".../local/lib/python2.7/site-packages/pony/orm/core.py", line 3844, in select
if not isinstance(tree, ast.GenExpr): throw(TypeError)
File "...local/lib/python2.7/site-packages/pony/utils.py", line 123, in throw
raise exc
TypeError
While it is possible to use strings in order to apply conditions to a query, it can be unsafe, because of the risk of SQL injection. The better way for applying conditions to a query is using the filter() method. You can take the latest version of Pony ORM from https://github.com/ponyorm/pony repository and try a couple of examples provided below.
First we define entities and create a couple of objects:
from decimal import Decimal
from pony.orm import *
db = Database('sqlite', ':memory:')
class Product(db.Entity):
name = Required(unicode)
description = Required(unicode)
price = Required(Decimal)
quantity = Required(int, default=0)
db.generate_mapping(create_tables=True)
with db_session:
Product(name='iPad', description='Air, 16GB', price=Decimal('478.99'), quantity=10)
Product(name='iPad', description='Mini, 16GB', price=Decimal('284.95'), quantity=15)
Product(name='iPad', description='16GB', price=Decimal('299.00'), quantity=10)
Now we'll apply filters passing them as keyword arguments:
def find_by_kwargs(**kwargs):
q = select(p for p in Product)
q = q.filter(**kwargs)
return list(q)
with db_session:
products = find_by_kwargs(name='iPad', quantity=10)
for p in products:
print p.name, p.description, p.price, p.quantity
Another option is to use lambdas in order to specify the conditions:
def find_by_params(name=None, min_price=None, max_price=None):
q = select(p for p in Product)
if name is not None:
q = q.filter(lambda p: p.name.startswith(name))
if min_price is not None:
q = q.filter(lambda p: p.price >= min_price)
if max_price is not None:
q = q.filter(lambda p: p.price <= max_price)
return list(q)
with db_session:
products = find_by_params(name='iPad', max_price=400)
for p in products:
print p.name, p.description, p.price, p.quantity
As you can see filters can be applied dynamically. You can find more information about using filters following by this link: http://doc.ponyorm.com/queries.html#Query.filter
If you still want to filter using strings, you have to apply new filter for each key/value pair.
Something like this:
def search(self,**kwargs):
q = select(m for m in Product)
for field,value in kwargs.iteritems():
value = unicode(value, 'utf-8')
field = unicode(field, 'utf-8')
flt = u"m.{0} == {1}".format(value, field)
q = q.filter(flt)
# return q # return Query which can be further modified (for ex. paging, ordering, etc.)
return q[:] # or return found products
HTH, Tom
What is the best solution to pivot/cross-tab tables in Python 3? Is there a built-in function that will do this? Ideally, I'm looking for a Python 3 solution that does not have external dependencies. For example, given a nested list:
nl = [["apples", 2 "New York"],
["peaches", 6, "New York"],
["apples", 6, "New York"],
["peaches", 1, "Vermont"]]
I would like to be able to rearrange rowed data and groupby fields:
apples peaches
New York 2 6
Vermont 6 1
The above is a trivial example, but is there a solution that would be easier than using itertools.groupby everytime a pivot is desired? Ideally, the solution would allow rowed data to be pivoted on any column. I was debating about using pandas, but it is an external library and only has limited Python 3 support.
Here is some simple code. Providing row/column/grand totals is left as an exercise for the reader.
class CrossTab(object):
def __init__(
self,
missing=0, # what to return for an empty cell.
# Alternatives: '', 0.0, None, 'NULL'
):
self.missing = missing
self.col_key_set = set()
self.cell_dict = {}
self.headings_OK = False
def add_item(self, row_key, col_key, value):
self.col_key_set.add(col_key)
try:
self.cell_dict[row_key][col_key] += value
except KeyError:
try:
self.cell_dict[row_key][col_key] = value
except KeyError:
self.cell_dict[row_key] = {col_key: value}
def _process_headings(self):
if self.headings_OK:
return
self.row_headings = list(sorted(self.cell_dict.keys()))
self.col_headings = list(sorted(self.col_key_set))
self.headings_OK = True
def get_col_headings(self):
self._process_headings()
return self.col_headings
def generate_row_info(self):
self._process_headings()
for row_key in self.row_headings:
row_dict = self.cell_dict[row_key]
row_vals = [
row_dict.get(col_key, self.missing)
for col_key in self.col_headings
]
yield row_key, row_vals
if __name__ == "__main__":
data = [["apples", 2, "New York"],
["peaches", 6, "New York"],
["apples", 6, "New York"],
["peaches", 1, "Vermont"]]
ctab = CrossTab(missing='uh-oh')
for s in data:
ctab.add_item(row_key=s[2], col_key=s[0], value=s[1])
print()
print('Column headings:', ctab.get_col_headings())
for row_heading, row_values in ctab.generate_row_info():
print(repr(row_heading), row_values)
Output:
Column headings: ['apples', 'peaches']
'New York' [8, 6]
'Vermont' ['uh-oh', 1]
See also this answer.
And this one, which I'd forgotten about.
itertools.groupby was exactly made for this problem. You will be hard-pressed to find something better, especially within the standard library.
I'm getting prices in different currencies and want to display Brazilian R$
My formatting doesn't work and the display looks like this:
Price: 1.15..000.,00 R$
For good flexibility I've stored the price as a string: price=db.StringProperty(verbose_name="price")
I tried to implement my own filter and it didn't work:
{{ ad.price|separate }} R$
def separate(n, sep='.'):
ln = list(str(n))
ln.reverse()
newn = []
while len(ln) > 3:
newn.extend(ln[:3])
newn.append(sep)
ln = ln[3:]
newn.extend(ln)
newn.reverse()
return "".join(newn)
Can you help me? Should I just remove the filter? Should I enforce some regex to the input instead? A link to my site is http://www.koolbusiness.com/servead/4252196
UPDATE: I'm considering using something like one of these filters:
import locale
locale.setlocale(locale.LC_ALL, '')
def currency(value): # doesn't work
locale.setlocale(locale.LC_ALL, '')
return locale.currency(value, grouping=True)
register.filter(currency)
def currencyWithoutUsingLocale(value): # needs adjustment
value=float(value)
symbol = '$'
thousand_sep = ''
decimal_sep = ''
# try to use settings if set
try:
symbol = settings.CURRENCY_SYMBOL
except AttributeError:
pass
try:
thousand_sep = settings.THOUSAND_SEPARATOR
decimal_sep = settings.DECIMAL_SEPARATOR
except AttributeError:
thousand_sep = ','
decimal_sep = '.'
intstr = str(int(value))
f = lambda x, n, acc=[]: f(x[:-n], n, [(x[-n:])]+acc) if x else acc
intpart = thousand_sep.join(f(intstr, 3))
return "%s%s%s%s" % (symbol, intpart, decimal_sep, ("%0.2f" % value)[-2:])
register.filter(currencyWithoutUsingLocale)
Storing the price as a string is the first problem. It should be a Decimal. If you look at the Python standard library documentation for Decimal, you will see this http://docs.python.org/library/decimal.html#recipes
That moneyfmt recipe should do what you want
Currency formatting is a feature of locale.
http://docs.python.org/library/locale.html#locale.currency
You can use locale._override_localeconv dict to set your own overwrites:
>>> import locale
>>> locale.setlocale(locale.LC_MONETARY, 'pt_BR.UTF-8')
>>> locale.currency(1234.56)
'1234,56 R$'
>>> locale._override_localeconv.update({'p_cs_precedes': 1, 'n_cs_precedes': 1})
>>> locale.currency(1234.56)
'R$ 1234,56'
You can use this locale._override_localeconv.update({'p_cs_precedes': 1, 'n_cs_precedes': 1}) line right after the import locale, if you want.