Search code examples
pythondjangopython-3.xcounterpython-collections

Restricting a Counter Collection in Python


I am currently extracting data from a web API and I am trying to filter some values based on the following condition: Count the number of times that a user appears between two given dates but only if he/she has bought items raspberry pi, banana pi and raspberry pi2 and not item raspberry pi3

The JSON object that I receive has the following structure:

[{
user_id : 0001
CreatedOn: "2017-02-16 15:54:48",
item: "raspbery pi",
VIP: "YES",
Vendor_CODE: "XYZ12345",
},
{
user_id : 0001
CreatedOn: "2017-02-15 13:49:16",
item: "raspbery pi2",
VIP: "YES",
Vendor_CODE: "XYZ67890",
},
{
user_id : 0001
CreatedOn: "2017-02-10 15:54:48",
item: "raspbery pi",
VIP: "YES",
Vendor_CODE: "RST171820",
},
{
user_id : 0001
CreatedOn: "2017-01-01 21:51:13",
item: "raspbery pi3",
VIP: "YES",
Vendor_CODE: "XOL002321",
},
{
user_id : 0005
CreatedOn: "2017-01-30 17:34:18",
item: "raspbery pi",
VIP: "YES",
Vendor_CODE: "RST171820",
},
{
user_id : 0005
CreatedOn: "2017-05-30 09:04:08",
item: "banana pi",
VIP: "YES",
Vendor_CODE: "ITI342027",
}]

Currently I have the following code that counts the number of times a user appears given two dates.

from django.shortcuts import render
from django.http import JsonResponse
from rest_framework.views import APIView
from rest_framework.response import Response
from collections import Counter
from datetime import datetime, timedelta
import json, urllib.request, dateutil.parser, urllib.parse,

#Request a response to the Web API
def get_data(request, *args, **kwargs):
    # YYYY-MM-DD
    start_date = datetime.now() - timedelta(days=7)
    end_date = datetime.now() - timedelta(days=1) 

    with urllib.request.urlopen("http://10.61.202.98:8081/T/ansdb/api/rows/dev/ect",timeout=15) as url:
    response_data = json.loads(url.read().decode())

    #count the number of times the user appears when he bought the 4 items in two given dates
    count_user_01 = Counter([k['user_id'] for k in response_data if
         start_date_week < dateutil.parser.parse(k.get('CreatedOn')) < end_date_week])

My approach is to add some extra "condition" to count all items except the item raspberry pi3, something like:

count_user_01 = Counter([k['user_id'] for k in response_data if
     start_date_week < dateutil.parser.parse(k.get('CreatedOn')) < end_date_week] and k['item']!='raspberry pi3')

but if I do this then I encounter the error bool object is not iterable and I assume I receive this error because the collection Counter does not allow me to do this.

My questions are:

  1. How can I implement this extra condition into the list so I can count all the items except raspberry pi3 that were bought by one user?

  2. Currently, I am counting the items that were bought for specific users but how could I count all the items that were bought by all the users?

All comments, answers and suggestions are welcome.

Update

For question 1 the solution was to fix the problem in brackets.

count_user_01 = Counter([k['user_id'] for k in response_data if
 start_date_week < dateutil.parser.parse(k.get('CreatedOn')) < end_date_week and k['item']!='raspberry pi3'])

Solution

  • I think you have a problem with your brackets. Try this:

    count_user_01 = Counter([k['user_id'] for k in response_data if
         start_date_week < dateutil.parser.parse(k.get('CreatedOn')) < end_date_week and k['item']!='raspberry pi3'])