Modernize Support Logs Using Simple Python Commands

PATTABHIRAMAN SRINIVASAN 28 Oct, 2020 • 6 min read

This article was published as a part of the Data Science Blogathon.

Introduction

In this blog, I will explain how using simple machine learning concepts we can enrich our call centers/support division activities in our own organization or customer organization. The blog only gives an insight into what and how we can make a difference to the current environment using ML in giving better service time in resolution of customer calls and avoiding repetition of the same issues being raised by multiple users of the same customer with slight variation thus adding the issues backlog count.

The Blog primarily focuses on the use of data science tools and techniques and assumes the reader is aware of concepts. In the first part of this blog, let’s see how we can start creating a useful issue resolution log which is very handy for call center/support L1, L2 (Level 1 and Level 2) guys as they have to constantly face the customers once the product is put in Production /live environment.

But before we get to the resolution log, let’s first quickly look at the tools and techniques required and refresh our learnings again.

 

Power of Python Dictionary Object

A dictionary is a key, value pair of the collection which is unordered, changeable, and indexed. In Python, dictionaries are written with curly brackets. Dictionaries themselves are mutable, so entries can be added, removed, and changed at any time. however, because entries are accessed by their key, we can’t have two entries with the same key.

Some examples of the dictionary are-

empty_dictionary { }
person_age_dictionary {'Mahesh' : '21','Suresh' : '34', 'Naresh' : '16'}
vehicle_names_dictionary {'Tata' : ('Nexson','Harrier'),'Maruti' :('Ciaz','Alto','800')}

to access the dictionary, we can use the .items() method like

person_age_dictionary.items()

Output:

dict_items([('Mahesh','21'),('Suresh','34'),('Naresh','16')])

likewise in order to access the keys and values separately, we can make use of the .key(),.values() method.

we can also create a nested dictionary like-

nested = {'Person_mobile' : {'Mahesh' : 'Samsung', 'Suresh' :'iPhone', 'Naresh' : 'Nakia'},

'mobile_model' : {'samsung' : 'note20','iphone' : '11 pro', 'Nakia' : '7.1'}

}

In the above code, nested[‘Person_mobile’][‘Mahesh’] will give ‘samsung’ and  nested[‘mobile_model’][‘samsung’] will return ‘note20’.

To append/add a new element to the dictionary, we can just do

person_age_dictionary['Ramesh'] = '40'

To delete the specific element from the dictionary-

person_age_dictionary.pop(i)

where i is the element index to be removed. The .clear() method removes all the element.

Now that we know what all we can do with a python dictionary object, let’s see how we can put this to good use in our day to day work to evolve our support wing in our own organization.

For this article, I am using my private data and you can similar way use the data pertaining to your work.

For this article, I am taking a past banking domain product (product name masked), that is live at various nationalized and private sector banks. Before proceeding further, a typical support center/data center runs on a 24×7 basis and ensures the mission-critical business never halts.

The customers using the product will reach out to the call centers in case of any issue and depending on the nature of the issue, the resolution needs to be provided within the service level agreement. Once the product gets stabilized, most of the calls are handled by the L1 (level 1) team and if any new issues are encountered that need fix, L2 (level 2 team) also gets involved.

Historic issue dataset of one particular customer will consist of the following details-

  • Product
  • Version
  • Issue No / Ticket No
  • Issue Description
  • Priority (1/2/3/4) -P1, P2 calls needs immediate resolution as they halt the operations in someway
  • Release Date (when a fix was given)
  • Final Status (Open / Closed / Roadmap / Customization)
  • Action (Release plan to be mentioned for all Open issues)
  • company Remarks (Remarks for all roadmap issues)
  • Test Date (bank team testing date)
  • Bank Comments (For customization as well as final closure /acceptance remarks)
  • Resolution (what was done to address the issue, to be mentioned here)

These data can be extracted in excel or CSV from tools like Siebel or Jira also which most companies use nowadays

For now, I will be using only Issue Description and Resolution columns

Let us create all the necessary dictionaries using the above

  1. create a customer-product dictionary from CSV file (python code) using the below code
    import csv
    reader = csv.reader(open('filename.csv', 'r'))
    
    d = {}
    
    for row in reader:
       k, v = row
       d[k] = v

    Customer-product dictionary sample structure

    {C1:pv1,C2:pv2,C3:pv8,...C10:pv20 -> cdict(Customer name - key, Product Version - value.

    (for instance Punjab National Bank xyz product version 1.0)

    sample result :

    {
    
    'Punjab National Bank': 'xyz1.0',
    
    'Union Bank of India': 'xyz2.0',
    
    'Oriental Bank of Commerce': 'xyz2.5',
    
    'ICICI Bank': 'xyz2.5',
    
    'Axis Bank': 'xyz2.5',
    
    'Bank of Baroda': 'xyz2.5'
    
    …..
    
    }

    The above dictionary can be easily created with customers List : C1,C2,C3 ….C10 and product version List : pv1,pv2,pv25,pv3,pv8,pv20 which will be available with support team. Next,

  2. create version- issues dictionary from csv file (refer code above)

    Product version Issues dictionary sample structure

    verISS = { pv11 : I1, pv2 : I2 ….pv20300 : I300 }

    Here pv11 would mean version 1 and ticket no 1 and I1 likewise is the issue /ticket raised

    sample result :

    {
    
    'xyz2.0tkt1': 'In sales tax scheme of Tax collection the field meant for capturing the details of
    PAN/GIR no /Reg. No? others are allowing to enter 14 digits only. Whereas space needs to be
    increased to 16 digits.',
    'xyz2.0tkt2': 'Provision for equal payment of family pension to more than
    one wife be provided.',
    'xyz1.0tkt3': 'In enquiry of Transfer-out, the system is displaying the error
    : 404 NOT FOUND ; /xyz/jsp/bond/xyz_bond_transfer_out_selecting_jsp was not found on this server'
    .....
    }

 

  1. create Issues Resolution dictionary from CSV file (refer code above)

    Product Issues resolution dictionary sample structure

    issRES = { I11 : R1,I12:R2 .........I20300 :R300}

    Here I11 would mean version 1 and ticket no 1 and R1 likewise is the issue resolution provided

    sample result :

    {
    
    'In sales tax scheme of Tax collection the field meant for capturing the details of PAN/GIR no /Reg. No? others
    
    are allowing to enter 14 digits only. Whereas space needs to be increased to 16 digits.': 'Execute
    
    the ABC script in your UAT environment and validate if the Sales Tax can accept 16 digits. Execute the
    
    same in the production environment. Services need to be stopped and restarted. System downtime needs to be
    
    planned.',
    
    'Provision for equal payment of family pension to more than one wife be provided.':
    
    'Currently, this needs to be handled in the core system as a workaround. XYZ will allow the payment to one
    
    spouse. The share as specified by the pensioner needs to be created as two credit transactions
    
    ( or as specified by the pensioner) in the core system. This feature of multiple spouse family pension
    
    will be made available in xyz8.0',
    
    'In inquiry of Transfer-out, the system is displaying the error
    
    : 404 NOT FOUND ; /xyz/jsp/bond/xyz_bond_transfer_out_selecting_jsp was not found on this server':
    
    'copy the xyz_bond_transfer_out_selecting_jsp from UAT environment to production. Kindly note resin
    
    web server needs to be restarted. This can be performed after the business hours as it is only an inquiry
    
    screen'
    
    ........
    
    }
    
    finally will create a customer_resolution_log as a nested dictionary

 

  1. create a nested dictionary like ( combine all issues of Product LTD -Life to date from all customers/versions)

    custIR = {'pvdict' : {'pv11' : 'I1', 'pv12' : 'I2' .......'pv20300' : 'I300' } .
                     'irdict' : {'I11' : 'R1','I12':'R2' .........'I20300' :'R300'}}

    This dictionary now contains all the issues of all the customers using this product across the geographical locations, across all versions. Now whenever any new production tickets are raised, to check if there is any resolution already exists,

    following commands needs to execute,

    tktdesc = custIR['verISS']['xyz2.0tkt1']
    
    print(tktdesc)

    sample output: ‘In sales tax scheme of Tax collection the field meant for capturing the details of

    PAN/GIR no /Reg. No? others are allowing to enter 14 digits only. Whereas space needs to be

    increased to 16 digits.’

    1. b) tktres = custIR[‘issRES’][tktdesc]

    sample output: ‘Execute the ABC script in your UAT environment and validate if the Sales Tax can accept 16 digits. Execute the same in the production environment. Services need to be stopped and restarted. System downtime needs to be planned.’

    now when a new ticket is raised in order to check if any resolution already provided for this ticket,

    directly step b) can be executed. if resolution does exist, that is the issue key exists then we can avoid

    the same ticket being raised again as well as the resolution can be provided on the fly (very less time).

    now we can combine all these in a simple python program (<10-12 lines of code) to prompt ticket description as string input and pass it to the customer_resolution_log dictionary to get the desired output. The code here is pretty ordinary but creates quite an impact in terms of resolution service time as well as avoiding duplicate tickets from multiple users.

 

Finally, we can bundle it as an executable file that can be run from terminal or command line

code for creating a python executable file

Linux

from the terminal

$ chmod +x myscript.py

$ ./myfile.py

Windows 10 (create standalone exefile)

1.pip install pyinstaller (if not already installed)

2.Go to the folder where .py is present

3.Go to anaconda powershell terminal4.

4.execute.\pyinstaller –onefile -w ‘filename.py’

5.it will create a dist folder and inside that the exe file will be created

(in case any error is encountered on maximum recursion depth exceeded, then follow the below steps)

pyinstaller filename.py (creates .spec file)

import sys ( add at the beginning of .spec file)

sys.setrecursionlimit(5000)

pyinstaller filename. Spec

Did I mention Machine Learning at the beginning of this blog? But throughout this blog, I have used only a python dictionary. In the next part of this blog, I will blog on how using NLP can help in identifying similar Tickets being raised across customer locations and how ticket prioritization can be automated.

Frequently Asked Questions

Lorem ipsum dolor sit amet, consectetur adipiscing elit,

Responses From Readers

Clear