{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a href=\"https://colab.research.google.com/github/RecoHut-Projects/recohut/blob/master/tutorials/preprocessing/T859611_Preprocessing_Music_Sessions_Dataset.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Preprocessing Music Session Dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "from datetime import timezone, datetime, timedelta\n",
    "import random\n",
    "import time\n",
    "import sys"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "preprocessing method [\"info\",\"org\",\"days_test\",\"slice\"]\n",
    "    info: just load and show info\n",
    "    org: from gru4rec (last day => test set)\n",
    "    days_test: adapted from gru4rec (last N days => test set)\n",
    "    slice: new (create multiple train-test-combinations with a sliding window approach  \n",
    "'''\n",
    "# METHOD = \"slice\"\n",
    "METHOD = input('Preprocessing method (info/org/days_test/slice):') or 'slice'\n",
    "assert(METHOD in 'info/org/days_test/slice'.split('/')), 'Invalid Preprocessing method.'\n",
    "\n",
    "'''\n",
    "data config (all methods) // change dataset here\n",
    "'''\n",
    "#30music/nowplaying/aotm\n",
    "# PATH = './30music/raw/' \n",
    "# PATH_PROCESSED = './30music/slices/'\n",
    "DATASET_CODE = input('Dataset (30music/nowplaying/aotm):') or '30music'\n",
    "assert(DATASET_CODE in '30music/nowplaying/aotm'.split('/')), 'Invalid dataset.'\n",
    "\n",
    "PATH = './{}/raw/'.format(DATASET_CODE)\n",
    "PATH_PROCESSED = './{}/slices/'.format(DATASET_CODE)\n",
    "_filenames = {'30music':'30music-200ks','nowplaying':'nowplaying','aotm':'playlists-aotm'}\n",
    "FILE = _filenames[DATASET_CODE]\n",
    "\n",
    "'''\n",
    "filtering config (all methods)\n",
    "'''\n",
    "#filtering config (all methods)\n",
    "MIN_SESSION_LENGTH = 5\n",
    "MIN_ITEM_SUPPORT = 2\n",
    "\n",
    "'''\n",
    "days test default config\n",
    "'''\n",
    "DAYS_FOR_TEST = 4\n",
    "\n",
    "'''\n",
    "slicing default config\n",
    "'''\n",
    "NUM_SLICES = 5 #offset in days from the first date in the data set\n",
    "DAYS_OFFSET = 0 #number of days the training start date is shifted after creating one slice\n",
    "DAYS_SHIFT = 60\n",
    "#each slice consists of...\n",
    "DAYS_TRAIN = 90\n",
    "DAYS_TEST = 5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "if DATASET_CODE=='30music':\n",
    "    !wget -q --show-progress https://github.com/RecoHut-Datasets/30music/raw/v1/30music.zip\n",
    "    !unzip 30music.zip\n",
    "elif DATASET_CODE=='nowplaying':\n",
    "    !wget -q --show-progress https://github.com/RecoHut-Datasets/nowplaying/raw/v2/nowplaying.zip\n",
    "    !unzip nowplaying.zip\n",
    "elif DATASET_CODE=='aotm':\n",
    "    !wget -q --show-progress https://github.com/RecoHut-Datasets/aotm/raw/v1/aotm.zip\n",
    "    !unzip aotm.zip"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def load_data( file ) : \n",
    "    \n",
    "    #load csv\n",
    "    data = pd.read_csv( file+'.csv', sep='\\t' )\n",
    "    \n",
    "    #data.sort_values( by=['Time'], inplace=True )\n",
    "    #data['SessionId'] = data.groupby( [data.SessionId] ).grouper.group_info[0]\n",
    "    \n",
    "    data.sort_values( by=['SessionId','Time'], inplace=True )\n",
    "    \n",
    "    #output\n",
    "    data_start = datetime.fromtimestamp( data.Time.min(), timezone.utc )\n",
    "    data_end = datetime.fromtimestamp( data.Time.max(), timezone.utc )\n",
    "    \n",
    "    print('Loaded data set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}\\n\\tSpan: {} / {}\\n\\n'.\n",
    "          format( len(data), data.SessionId.nunique(), data.ItemId.nunique(), data_start.date().isoformat(), data_end.date().isoformat() ) )\n",
    "    \n",
    "    return data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def filter_data( data, min_item_support, min_session_length ) : \n",
    "    \n",
    "    #filter session length\n",
    "    session_lengths = data.groupby('SessionId').size()\n",
    "    data = data[np.in1d(data.SessionId, session_lengths[ session_lengths>1 ].index)]\n",
    "    \n",
    "    #filter item support\n",
    "    item_supports = data.groupby('ItemId').size()\n",
    "    data = data[np.in1d(data.ItemId, item_supports[ item_supports>= min_item_support ].index)]\n",
    "    \n",
    "    #filter session length\n",
    "    session_lengths = data.groupby('SessionId').size()\n",
    "    data = data[np.in1d(data.SessionId, session_lengths[ session_lengths>= min_session_length ].index)]\n",
    "    \n",
    "    #output\n",
    "    data_start = datetime.fromtimestamp( data.Time.min(), timezone.utc )\n",
    "    data_end = datetime.fromtimestamp( data.Time.max(), timezone.utc )\n",
    "    \n",
    "    print('Filtered data set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}\\n\\tSpan: {} / {}\\n\\n'.\n",
    "          format( len(data), data.SessionId.nunique(), data.ItemId.nunique(), data_start.date().isoformat(), data_end.date().isoformat() ) )\n",
    "    \n",
    "    return data;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def split_data_org( data, output_file ) :\n",
    "    \n",
    "    tmax = data.Time.max()\n",
    "    session_max_times = data.groupby('SessionId').Time.max()\n",
    "    session_train = session_max_times[session_max_times < tmax-86400].index\n",
    "    session_test = session_max_times[session_max_times >= tmax-86400].index\n",
    "    train = data[np.in1d(data.SessionId, session_train)]\n",
    "    test = data[np.in1d(data.SessionId, session_test)]\n",
    "    test = test[np.in1d(test.ItemId, train.ItemId)]\n",
    "    tslength = test.groupby('SessionId').size()\n",
    "    test = test[np.in1d(test.SessionId, tslength[tslength>=2].index)]\n",
    "    print('Full train set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}'.format(len(train), train.SessionId.nunique(), train.ItemId.nunique()))\n",
    "    train.to_csv(output_file + '_train_full.txt', sep='\\t', index=False)\n",
    "    print('Test set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}'.format(len(test), test.SessionId.nunique(), test.ItemId.nunique()))\n",
    "    test.to_csv(output_file + '_test.txt', sep='\\t', index=False)\n",
    "    \n",
    "    tmax = train.Time.max()\n",
    "    session_max_times = train.groupby('SessionId').Time.max()\n",
    "    session_train = session_max_times[session_max_times < tmax-86400].index\n",
    "    session_valid = session_max_times[session_max_times >= tmax-86400].index\n",
    "    train_tr = train[np.in1d(train.SessionId, session_train)]\n",
    "    valid = train[np.in1d(train.SessionId, session_valid)]\n",
    "    valid = valid[np.in1d(valid.ItemId, train_tr.ItemId)]\n",
    "    tslength = valid.groupby('SessionId').size()\n",
    "    valid = valid[np.in1d(valid.SessionId, tslength[tslength>=2].index)]\n",
    "    print('Train set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}'.format(len(train_tr), train_tr.SessionId.nunique(), train_tr.ItemId.nunique()))\n",
    "    train_tr.to_csv( output_file + '_train_tr.txt', sep='\\t', index=False)\n",
    "    print('Validation set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}'.format(len(valid), valid.SessionId.nunique(), valid.ItemId.nunique()))\n",
    "    valid.to_csv( output_file + '_train_valid.txt', sep='\\t', index=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def split_data( data, output_file, days_test ) :\n",
    "    \n",
    "    data_end = datetime.fromtimestamp( data.Time.max(), timezone.utc )\n",
    "    test_from = data_end - timedelta( days_test )\n",
    "    \n",
    "    session_max_times = data.groupby('SessionId').Time.max()\n",
    "    session_train = session_max_times[ session_max_times < test_from.timestamp() ].index\n",
    "    session_test = session_max_times[ session_max_times >= test_from.timestamp() ].index\n",
    "    train = data[np.in1d(data.SessionId, session_train)]\n",
    "    test = data[np.in1d(data.SessionId, session_test)]\n",
    "    test = test[np.in1d(test.ItemId, train.ItemId)]\n",
    "    tslength = test.groupby('SessionId').size()\n",
    "    test = test[np.in1d(test.SessionId, tslength[tslength>=2].index)]\n",
    "    print('Full train set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}'.format(len(train), train.SessionId.nunique(), train.ItemId.nunique()))\n",
    "    train.to_csv(output_file + '_train_full.txt', sep='\\t', index=False)\n",
    "    print('Test set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}'.format(len(test), test.SessionId.nunique(), test.ItemId.nunique()))\n",
    "    test.to_csv(output_file + '_test.txt', sep='\\t', index=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def slice_data( data, output_file, num_slices, days_offset, days_shift, days_train, days_test ): \n",
    "    \n",
    "    for slice_id in range( 0, num_slices ) :\n",
    "        split_data_slice( data, output_file, slice_id, days_offset+(slice_id*days_shift), days_train, days_test )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def split_data_slice( data, output_file, slice_id, days_offset, days_train, days_test ) :\n",
    "    \n",
    "    data_start = datetime.fromtimestamp( data.Time.min(), timezone.utc )\n",
    "    data_end = datetime.fromtimestamp( data.Time.max(), timezone.utc )\n",
    "    \n",
    "    print('Full data set {}\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}\\n\\tSpan: {} / {}'.\n",
    "          format( slice_id, len(data), data.SessionId.nunique(), data.ItemId.nunique(), data_start.isoformat(), data_end.isoformat() ) )\n",
    "    \n",
    "    \n",
    "    start = datetime.fromtimestamp( data.Time.min(), timezone.utc ) + timedelta( days_offset ) \n",
    "    middle =  start + timedelta( days_train )\n",
    "    end =  middle + timedelta( days_test )\n",
    "    \n",
    "    #prefilter the timespan\n",
    "    session_max_times = data.groupby('SessionId').Time.max()\n",
    "    greater_start = session_max_times[session_max_times >= start.timestamp()].index\n",
    "    lower_end = session_max_times[session_max_times <= end.timestamp()].index\n",
    "    data_filtered = data[np.in1d(data.SessionId, greater_start.intersection( lower_end ))]\n",
    "    \n",
    "    print('Slice data set {}\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}\\n\\tSpan: {} / {} / {}'.\n",
    "          format( slice_id, len(data_filtered), data_filtered.SessionId.nunique(), data_filtered.ItemId.nunique(), start.date().isoformat(), middle.date().isoformat(), end.date().isoformat() ) )\n",
    "    \n",
    "    #split to train and test\n",
    "    session_max_times = data_filtered.groupby('SessionId').Time.max()\n",
    "    sessions_train = session_max_times[session_max_times < middle.timestamp()].index\n",
    "    sessions_test = session_max_times[session_max_times >= middle.timestamp()].index\n",
    "    \n",
    "    train = data[np.in1d(data.SessionId, sessions_train)]\n",
    "    \n",
    "    print('Train set {}\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}\\n\\tSpan: {} / {}'.\n",
    "          format( slice_id, len(train), train.SessionId.nunique(), train.ItemId.nunique(), start.date().isoformat(), middle.date().isoformat() ) )\n",
    "    \n",
    "    train.to_csv(output_file + '_train_full.'+str(slice_id)+'.txt', sep='\\t', index=False)\n",
    "    \n",
    "    test = data[np.in1d(data.SessionId, sessions_test)]\n",
    "    test = test[np.in1d(test.ItemId, train.ItemId)]\n",
    "    \n",
    "    tslength = test.groupby('SessionId').size()\n",
    "    test = test[np.in1d(test.SessionId, tslength[tslength>=2].index)]\n",
    "    \n",
    "    print('Test set {}\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}\\n\\tSpan: {} / {} \\n\\n'.\n",
    "          format( slice_id, len(test), test.SessionId.nunique(), test.ItemId.nunique(), middle.date().isoformat(), end.date().isoformat() ) )\n",
    "    \n",
    "    test.to_csv(output_file + '_test.'+str(slice_id)+'.txt', sep='\\t', index=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#preprocessing from original gru4rec\n",
    "def preprocess_org( path=PATH, file=FILE, path_proc=PATH_PROCESSED, min_item_support=MIN_ITEM_SUPPORT, min_session_length=MIN_SESSION_LENGTH ):\n",
    "    \n",
    "#    data = load_data( path+file )\n",
    "    #for listening logs\n",
    "    data = load_data( path+file )\n",
    "    data = filter_data( data, min_item_support, min_session_length )\n",
    "    split_data_org( data, path_proc+file )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#preprocessing adapted from original gru4rec\n",
    "def preprocess_days_test( path=PATH, file=FILE, path_proc=PATH_PROCESSED, min_item_support=MIN_ITEM_SUPPORT, min_session_length=MIN_SESSION_LENGTH, days_test=DAYS_TEST ):\n",
    "    \n",
    "#    data = load_data( path+file )\n",
    "    data = load_data( path+file )\n",
    "    data = filter_data( data, min_item_support, min_session_length )\n",
    "    split_data( data, path_proc+file, days_test )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#preprocessing to create data slices with a sliding window\n",
    "def preprocess_slices( path=PATH, file=FILE, path_proc=PATH_PROCESSED, min_item_support=MIN_ITEM_SUPPORT, min_session_length=MIN_SESSION_LENGTH,\n",
    "                       num_slices = NUM_SLICES, days_offset = DAYS_OFFSET, days_shift = DAYS_SHIFT, days_train = DAYS_TRAIN, days_test=DAYS_TEST ):\n",
    "    \n",
    "    data = load_data( path+file )\n",
    "    data = filter_data( data, min_item_support, min_session_length )\n",
    "    slice_data( data, path_proc+file, num_slices, days_offset, days_shift, days_train, days_test )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#just load and show info\n",
    "def preprocess_info( path=PATH, file=FILE, path_proc=PATH_PROCESSED, min_item_support=MIN_ITEM_SUPPORT, min_session_length=MIN_SESSION_LENGTH ):\n",
    "    \n",
    "    data = load_data( path+file )\n",
    "    data = filter_data( data, min_item_support, min_session_length )     "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "START preprocessing  slice\n",
      "Loaded data set\n",
      "\tEvents: 3707857\n",
      "\tSessions: 200000\n",
      "\tItems: 1203432\n",
      "\tSpan: 2014-01-20 / 2015-01-20\n",
      "\n",
      "\n",
      "Filtered data set\n",
      "\tEvents: 2887349\n",
      "\tSessions: 169576\n",
      "\tItems: 449037\n",
      "\tSpan: 2014-01-20 / 2015-01-20\n",
      "\n",
      "\n",
      "Full data set 0\n",
      "\tEvents: 2887349\n",
      "\tSessions: 169576\n",
      "\tItems: 449037\n",
      "\tSpan: 2014-01-20T09:24:25+00:00 / 2015-01-20T09:23:17+00:00\n",
      "Slice data set 0\n",
      "\tEvents: 682013\n",
      "\tSessions: 38617\n",
      "\tItems: 223276\n",
      "\tSpan: 2014-01-20 / 2014-04-20 / 2014-04-25\n",
      "Train set 0\n",
      "\tEvents: 648300\n",
      "\tSessions: 36620\n",
      "\tItems: 216054\n",
      "\tSpan: 2014-01-20 / 2014-04-20\n",
      "Test set 0\n",
      "\tEvents: 23718\n",
      "\tSessions: 1794\n",
      "\tItems: 16305\n",
      "\tSpan: 2014-04-20 / 2014-04-25 \n",
      "\n",
      "\n",
      "Full data set 1\n",
      "\tEvents: 2887349\n",
      "\tSessions: 169576\n",
      "\tItems: 449037\n",
      "\tSpan: 2014-01-20T09:24:25+00:00 / 2015-01-20T09:23:17+00:00\n",
      "Slice data set 1\n",
      "\tEvents: 646004\n",
      "\tSessions: 36539\n",
      "\tItems: 216903\n",
      "\tSpan: 2014-03-21 / 2014-06-19 / 2014-06-24\n",
      "Train set 1\n",
      "\tEvents: 615759\n",
      "\tSessions: 34759\n",
      "\tItems: 210736\n",
      "\tSpan: 2014-03-21 / 2014-06-19\n",
      "Test set 1\n",
      "\tEvents: 21021\n",
      "\tSessions: 1642\n",
      "\tItems: 14026\n",
      "\tSpan: 2014-06-19 / 2014-06-24 \n",
      "\n",
      "\n",
      "Full data set 2\n",
      "\tEvents: 2887349\n",
      "\tSessions: 169576\n",
      "\tItems: 449037\n",
      "\tSpan: 2014-01-20T09:24:25+00:00 / 2015-01-20T09:23:17+00:00\n",
      "Slice data set 2\n",
      "\tEvents: 601423\n",
      "\tSessions: 34754\n",
      "\tItems: 207331\n",
      "\tSpan: 2014-05-20 / 2014-08-18 / 2014-08-23\n",
      "Train set 2\n",
      "\tEvents: 570682\n",
      "\tSessions: 32985\n",
      "\tItems: 200469\n",
      "\tSpan: 2014-05-20 / 2014-08-18\n",
      "Test set 2\n",
      "\tEvents: 21226\n",
      "\tSessions: 1615\n",
      "\tItems: 14472\n",
      "\tSpan: 2014-08-18 / 2014-08-23 \n",
      "\n",
      "\n",
      "Full data set 3\n",
      "\tEvents: 2887349\n",
      "\tSessions: 169576\n",
      "\tItems: 449037\n",
      "\tSpan: 2014-01-20T09:24:25+00:00 / 2015-01-20T09:23:17+00:00\n",
      "Slice data set 3\n",
      "\tEvents: 626304\n",
      "\tSessions: 36088\n",
      "\tItems: 214571\n",
      "\tSpan: 2014-07-19 / 2014-10-17 / 2014-10-22\n",
      "Train set 3\n",
      "\tEvents: 592511\n",
      "\tSessions: 34116\n",
      "\tItems: 207245\n",
      "\tSpan: 2014-07-19 / 2014-10-17\n",
      "Test set 3\n",
      "\tEvents: 22796\n",
      "\tSessions: 1779\n",
      "\tItems: 15146\n",
      "\tSpan: 2014-10-17 / 2014-10-22 \n",
      "\n",
      "\n",
      "Full data set 4\n",
      "\tEvents: 2887349\n",
      "\tSessions: 169576\n",
      "\tItems: 449037\n",
      "\tSpan: 2014-01-20T09:24:25+00:00 / 2015-01-20T09:23:17+00:00\n",
      "Slice data set 4\n",
      "\tEvents: 691191\n",
      "\tSessions: 41576\n",
      "\tItems: 227125\n",
      "\tSpan: 2014-09-17 / 2014-12-16 / 2014-12-21\n",
      "Train set 4\n",
      "\tEvents: 645868\n",
      "\tSessions: 38666\n",
      "\tItems: 218665\n",
      "\tSpan: 2014-09-17 / 2014-12-16\n",
      "Test set 4\n",
      "\tEvents: 32786\n",
      "\tSessions: 2689\n",
      "\tItems: 20318\n",
      "\tSpan: 2014-12-16 / 2014-12-21 \n",
      "\n",
      "\n",
      "END preproccessing  19.099936723709106 c  19.099937915802002 s\n"
     ]
    }
   ],
   "source": [
    "if __name__ == '__main__':\n",
    "    '''\n",
    "    Run the preprocessing configured above.\n",
    "    '''\n",
    "    \n",
    "    print( \"START preprocessing \", METHOD )\n",
    "    sc, st = time.time(), time.time()\n",
    "    \n",
    "    if METHOD == \"info\":\n",
    "        preprocess_info( PATH, FILE, MIN_ITEM_SUPPORT, MIN_SESSION_LENGTH )\n",
    "    \n",
    "    elif METHOD == \"org\":\n",
    "        preprocess_org( PATH, FILE, PATH_PROCESSED, MIN_ITEM_SUPPORT, MIN_SESSION_LENGTH )\n",
    "        \n",
    "    elif METHOD == \"days_test\":\n",
    "        preprocess_days_test( PATH, FILE, PATH_PROCESSED, MIN_ITEM_SUPPORT, MIN_SESSION_LENGTH, DAYS_FOR_TEST )\n",
    "    \n",
    "    elif METHOD == \"slice\":\n",
    "        preprocess_slices( PATH, FILE, PATH_PROCESSED, MIN_ITEM_SUPPORT, MIN_SESSION_LENGTH, NUM_SLICES, DAYS_OFFSET, DAYS_SHIFT, DAYS_TRAIN, DAYS_TEST )\n",
    "    else: \n",
    "        print( \"Invalid method \", METHOD )\n",
    "        \n",
    "    print( \"END preproccessing \", (time.time() - sc), \"c \", (time.time() - st), \"s\" )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# !apt-get -qq install tree\n",
    "# !rm -r sample_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ".\n",
      "├── [256M]  30music\n",
      "│   ├── [137M]  raw\n",
      "│   │   └── [137M]  30music-200ks.csv\n",
      "│   └── [118M]  slices\n",
      "│       ├── [899K]  30music-200ks_test.0.txt\n",
      "│       ├── [796K]  30music-200ks_test.1.txt\n",
      "│       ├── [804K]  30music-200ks_test.2.txt\n",
      "│       ├── [863K]  30music-200ks_test.3.txt\n",
      "│       ├── [1.2M]  30music-200ks_test.4.txt\n",
      "│       ├── [ 24M]  30music-200ks_train_full.0.txt\n",
      "│       ├── [ 23M]  30music-200ks_train_full.1.txt\n",
      "│       ├── [ 21M]  30music-200ks_train_full.2.txt\n",
      "│       ├── [ 22M]  30music-200ks_train_full.3.txt\n",
      "│       └── [ 24M]  30music-200ks_train_full.4.txt\n",
      "└── [ 27M]  30music.zip\n",
      "\n",
      " 282M used in 3 directories, 12 files\n"
     ]
    }
   ],
   "source": [
    "# !tree -h --du ."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Author: Sparsh A.\n",
      "\n",
      "Last updated: 2021-12-04 15:27:08\n",
      "\n",
      "Compiler    : GCC 7.5.0\n",
      "OS          : Linux\n",
      "Release     : 5.4.104+\n",
      "Machine     : x86_64\n",
      "Processor   : x86_64\n",
      "CPU cores   : 2\n",
      "Architecture: 64bit\n",
      "\n",
      "IPython: 5.5.0\n",
      "numpy  : 1.19.5\n",
      "pandas : 1.1.5\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# !pip install -q watermark\n",
    "# %reload_ext watermark\n",
    "# %watermark -a \"Sparsh A.\" -m -iv -u -t -d"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**END**"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
