This solution uses Pandas - Python Data Analysis Library for aggregating data from provided CSV files and processing the required queries.
Python Flask is used to serve the queries with REST API.
Sessionizing is done by grouping the data to chunks which are specific to a site and a visitor. For example here is the chunk, representing all visits of visitor_1 to www.s_1.com:

Now we can look at visits timestamps and find the time difference between each visit. If the difference less than 30 min we will mark those visits with the same session_id. We will change session_id (increase by 1) if the visits timestamps differ more than in 30 min.
While doing this we can also calculate a session duration.
Instead of updating existing data table (DataFrame) it's faster to create new one (sessisons_df) which has the follwoing fields:

On the picture, visitor_1002 visits are separated to 2 different sessions, marked with session_id=4 and session_id=5, starting at the index 16, as a result of the difference between visit times 1347888253 - 1347869050 = 19203 sec which is greater than 30 min. Session duration is 2770 sec for session_id=4 and 469 sec for session_id=5.
This is all we need in order to be able to efficiently answer required queries.
Supported queries examples are listed below with responses:
GET /num_sessions?site_url=www.s_5.com
> Num sessions for site www.s_5.com = 3623
GET /median_session_length?site_url=www.s_3.com
> Median session length for site www.s_3.com = 1392.5
GET num_unique_visited_sites?visitor_id=visitor_1
> Num of unique sites for visitor_1 = 3
Working solution is available here
Query it with curl or any http client. Or just open it in browser :)
docker pull aliowka/sessionizer
docker run -p 5000:5000 aliowka/sessionizer
Navigate in browser to the link http://localhost:5000
git clone http://github.com/aliowka/sessionizer`
cd sessionizer
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
flask run
export PYTHONPATH=$(pwd)
export FLASK_APP src/app.py
pytest tests -v
The server will start on http://localhost:5000/
In order to build the table of sessions sessions_df which described above, the following steps are required:
O(n) time and O(n) spaceO(nlog(n)) time and O(n) spaceO(n) and O(n)O(n) and O(n)O(n) and O(1)Finally we have a time complexity O(4n+nlogn) which bound by O(nlogn) and space complexity O(n).
Scale in terms of increasing ammount of data.
Althought the complexity of the algorithm seems to be not so awfull O(4n+nlogn). Already with 150K (145964 to be precise) input entries it becomes slow - tens of seconds to compute all sessions.
The algorithm currently makes 4 iterations over the data table and one sorting. With 150K input entries it gives us 4*150K+150K*log(150K)=1.35M iterations!
Of cause this might be improved. Below there are the steps that I would consider:
1.35M to 900K which is 66%memoization.cached decorator on create_sessions_from_input_data function to not recompute it for the same site multiple times. And I'm running a javascript on main page load event, which sends the requests to create a sessions for different sites in order to warm the cache. It's done once, at the first time the main page is visited and allows the other queries to run less then in a second.Scale in terms of increasing ammount of outside clients.
In order to support the increasing ammount of clients which will access the system with REST API I would consider the following steps:
In addition to the tests, checking the expected results, provided in the assignment, I created jupyter notebook which allowed me to slice and dice the input data and test different possible solutions.
Unfortunately, one test-case, out of 30, is falling for me.
For www.s_5.com I'm getting median session lenth equals to 1374.0 instead of expected 1375.0. Same algorithm gives me correct answers for all other sites. I'm not sure what's the problem is. It may be related to different floating point implementations on different hardware/softaware systems as described here In order to investigate this issue further, I would test both systems face-to-face, which is out of the scope of this task.
Content type
Image
Digest
Size
386.9 MB
Last updated
over 5 years ago
docker pull aliowka/sessionizer