In [1]:
%reset -f
In [2]:
%matplotlib inline
In [3]:
import pandas as pd
In [4]:
import matplotlib.pyplot as plt
import helpers as h
import numpy as np
import scipy as sp
import json
In [5]:
import os
In [6]:
_requiredPaths = ['tab', 'tex', 'img']
for p in _requiredPaths:
    if not os.path.exists(p):
        os.mkdir(p)
In [7]:
joined = pd.read_csv('cleaned.csv',index_col=0)
In [8]:
pd.options.display.max_columns=400
pd.options.display.max_colwidth= 100
In [ ]:
 
In [9]:
with open("descriptions.json", 'r') as f:
    descriptions = json.load(f)
In [10]:
joined['TimeInterview'].plot(kind="hist");
In [ ]:
 
In [11]:
import re
In [12]:
def descriptiveValueCounts(series, caption = "", reference = "", header=[], isFloat=True, save=True, folder="tab", 
                           reorder = []):
    t = h.Table("lc", "lc")
    t.isFloat = isFloat
    if caption: 
        t.setCaption(caption)
    if reference:
        t.reference = reference
    if header:
        t.setHeader(header)
    vc = series.value_counts()
    for k, v in vc.iteritems():
        t.addRow([k,"$%d$" %v])
    if reorder: 
        t.rows = [t.rows[i] for i in reorder]
    if save:
        t.writeLatexToFile(path=folder)
    return t
    
In [13]:
descriptiveValueCounts(joined.DemoEducation, caption = "Educational Demogprahics", reference="demoEducation",
                      header=["Highest Qualification", "Count"])
Out[13]:
Educational Demogprahics
Highest QualificationCount
Degree / Graduate education (e.g., BSc, BA)$92$
Postgraduate education (e.g., MSc, MA, MBA, PhD)$40$
Some undergraduate education (e.g., No completed degree)$36$
A-Level education (e.g., A, AS, S-Levels, Highers)$34$
GCSE Level education (e.g., GCSE, O-Levels or Standards) or lower$24$
Vocational education (e.g., NVQ, HNC, HND)$15$
In [ ]:
 
In [ ]:
 
In [39]:
mf = h.figuresToLaTeX(columns=1,basename='demoAge',path='',
                      caption='Histogram of our participant\'s age')
a = plt.figure(figsize=(8,5), dpi=80)
ax = joined.DemoAge.plot(kind="hist",bins=np.arange(10,80,5))
plt.setp(ax.patches, 'facecolor', '0.3','edgecolor', '0.15', 'alpha', 0.75)
locs, labels = plt.xticks()
plt.xticks(locs,[r'$%g$' %x for x in locs],size='large')
locs, labels = plt.yticks()
plt.yticks(locs,[r'$%g$' %x for x in locs],size='large')
plt.xlabel('Age')
plt.ylabel('Frequency')
h.rstyle(ax)
mf.addFigure(a,describeText=h.describe(joined.DemoAge.values))
print h.describe(joined.DemoAge.values)
mf.writeLaTeX() 
Size: 241, min: 18, max: 71, mean: 31.1867, variance: 110.277, skewness: 1.0712
In [15]:
descriptiveValueCounts(joined.DemoEmployment,caption="Employment Demogpraphics of the participants", 
                       reference="demoEmployment", header=["Employment Status", "Count"])
Out[15]:
Employment Demogpraphics of the participants
Employment StatusCount
Employed$117$
Student$58$
Unemployed$31$
Self-employed$31$
Retired$4$
In [16]:
descriptiveValueCounts(joined.DemoGender, caption="Gender of the participants", reference="demoGender", 
                      header= ["Gender", "Count"])
Out[16]:
Gender of the participants
GenderCount
Female$148$
Male$93$
In [17]:
descriptiveValueCounts(joined.DemoLearningDiff, caption="Learning difficulty or disability of the participants", 
                       reference="demoDisability", header=["Answer", "Count"])
Out[17]:
Learning difficulty or disability of the participants
AnswerCount
No$229$
Yes$12$
In [ ]:
 
In [38]:
mf = h.figuresToLaTeX(columns=1,basename='numberCards',path='',
                      caption='Participant\'s number of payment card with PINs')
a = plt.figure(figsize=(6,3), dpi=80)
ax = joined.NumberCards.plot(kind="hist",bins=np.arange(0,11,1))

plt.setp(ax.patches, 'facecolor', '0.3','edgecolor', '0.15', 'alpha', 0.75)
locs, labels = plt.xticks()
plt.xticks(locs,[r'$%g$' %x for x in locs],size='large')
locs, labels = plt.yticks()
plt.yticks(locs,[r'$%g$' %x for x in locs],size='large')
plt.xlabel('Number of Payment Cards')
plt.ylabel('Frequency')
h.rstyle(ax)
mf.addFigure(a,describeText=h.describe(joined.NumberCards.values))
print h.describe(joined.NumberCards.values)
mf.writeLaTeX()
Size: 241, min: 1, max: 9, mean: 2.53112, variance: 2.14174, skewness: 1.18143
In [19]:
t = h.Table("l" + "c"*11, "l|" + "c"*10 + "|c")
t.setHeader([""] + range(10) +["mean"])
t.isFloat = True
t.setCaption("Distribution of Participant's PINs")
t.reference = "numPINs"
j = 4
for st in [joined.NumberPINs4.value_counts(), joined.NumberPINs5.value_counts(), joined.NumberPINs6.value_counts()]:
    ds = [st[x] if x in st else 0 for x in range(10)]
    t.addRow(["%d digits" %j]  + ["$%d$" %d for d in ds] + ["$%.2f$" %(1.0*sum(i*ds[i] for i in range(10))/241)])
    j += 1
t.writeLatexToFile(path="tab")
t
Out[19]:
Distribution of Participant's PINs
0123456789mean
4 digits$1$$88$$65$$41$$31$$8$$5$$1$$1$$0$$2.28$
5 digits$233$$5$$3$$0$$0$$0$$0$$0$$0$$0$$0.05$
6 digits$228$$8$$4$$1$$0$$0$$0$$0$$0$$0$$0.08$
In [ ]:
 
In [20]:
sp.stats.ttest_rel(joined.NumberPINs4.values,joined.NumberCards.values)
Out[20]:
Ttest_relResult(statistic=-4.377793619033806, pvalue=1.7904065297032128e-05)
In [21]:
joined.NumberCards.value_counts()
Out[21]:
2    70
1    68
3    48
4    34
5    11
6     6
7     2
9     1
8     1
Name: NumberCards, dtype: int64
In [22]:
descriptiveValueCounts(joined.FreqCash, caption="Frequency of cash withdrawal", 
                       reference="freqCash", header=["Freuency", "Count"], reorder = [4, 1, 0, 2, 3, 5, 6])
Out[22]:
Frequency of cash withdrawal
FreuencyCount
Every day$4$
Several times a week$67$
Once per week$105$
Once per month$50$
Several times per year$11$
Once per year or less$3$
Never$1$
In [23]:
#Pin use frequencies:
In [24]:
import itertools
In [ ]:
 
In [25]:
keys = joined["FreqP4#1"].value_counts().keys()
keys = [keys[i] for i in [2, 0, 1, 3, 4, 6 ,5]]
t = h.Table(["l"]+["c"]*(9+3+4), ["l|cccccccc|c|cc|c|ccc|c"])
t.header = [""] + ["#%d" %(i+1) for i in range(8)] + ["Sum"] + ["#%d" %(i+1) for i in range(2)] + \
         ["Sum"] + ["#%d" %(i+1) for i in range(3)] + ["Sum"]
cols4 = [joined["FreqP4#%d" %(i+1)].value_counts() for i in range(8)]
cols5 = [joined["FreqP5#%d" %(i+1)].value_counts() for i in range(2)]
cols6 = [joined["FreqP6#%d" %(i+1)].value_counts() for i in range(3)]

for k in keys:
    c4 = [col[k] if k in col else 0 for col in cols4]
    c4 += [sum(c4)]
    c5 = [col[k] if k in col else 0 for col in cols5]
    c5 += [sum(c5)]
    c6 = [col[k] if k in col else 0 for col in cols6]
    c6 += [sum(c6)]
    t.addRow([k] + ["$%d$" %x for x in itertools.chain(c4, c5, c6)])
t.setCaption("Frequency of usage of all PINs of the participants")
t.latexComment = r"&\multicolumn{9}{c|}{4-digit PINs}&\multicolumn{3}{c|}{5-digit PINs}&\multicolumn{4}{c}{6-digit PINs}\\"
t.reference = "freqPINs"
t.writeLatexToFile(path="tab")
t
Out[25]:
&\multicolumn{9}{c|}{4-digit PINs}&\multicolumn{3}{c|}{5-digit PINs}&\multicolumn{4}{c}{6-digit PINs}\\
Frequency of usage of all PINs of the participants
#1#2#3#4#5#6#7#8Sum#1#2Sum#1#2#3Sum
Every day$34$$0$$0$$1$$0$$0$$0$$0$$35$$0$$0$$0$$1$$1$$0$$2$
Several times a week$117$$30$$3$$3$$0$$0$$0$$1$$154$$1$$0$$1$$5$$2$$1$$8$
Once per week$59$$35$$12$$3$$0$$0$$0$$0$$109$$2$$1$$3$$0$$0$$0$$0$
Once per month$21$$37$$24$$8$$3$$0$$0$$0$$93$$4$$2$$6$$3$$2$$0$$5$
Several times per year$6$$24$$24$$12$$2$$2$$1$$0$$71$$1$$0$$1$$3$$0$$0$$3$
Once per year or less$1$$14$$10$$10$$4$$1$$0$$0$$40$$0$$0$$0$$1$$0$$0$$1$
Never$2$$12$$14$$9$$6$$4$$1$$0$$48$$0$$0$$0$$0$$0$$0$$0$
In [26]:
keys = joined["OrigP4#1"].value_counts().keys()
keys = [keys[i] for i in [1, 0, 2]]
t = h.Table(["l"]+["c"]*(9+3+4), ["p{2.8cm}|cccccccc|c|cc|c|ccc|c"])
t.header = [""] + ["#%d" %(i+1) for i in range(8)] + ["Sum"] + ["#%d" %(i+1) for i in range(2)] + \
         ["Sum"] + ["#%d" %(i+1) for i in range(3)] + ["Sum"]
cols4 = [joined["OrigP4#%d" %(i+1)].value_counts() for i in range(8)]
cols5 = [joined["OrigP5#%d" %(i+1)].value_counts() for i in range(2)]
cols6 = [joined["OrigP6#%d" %(i+1)].value_counts() for i in range(3)]
t.latexComment = r"&\multicolumn{9}{c|}{4-digit PINs}&\multicolumn{3}{c|}{5-digit PINs}&\multicolumn{4}{c}{6-digit PINs}\\"
for k in keys:
    c4 = [col[k] if k in col else 0 for col in cols4]
    c4 += [sum(c4)]
    c5 = [col[k] if k in col else 0 for col in cols5]
    c5 += [sum(c5)]
    c6 = [col[k] if k in col else 0 for col in cols6]
    c6 += [sum(c6)]
    t.addRow([k] + ["$%d$" %x for x in itertools.chain(c4, c5, c6)])
t.setCaption("Source of PINs of the participants")
t.reference = "originPINs"
t.writeLatexToFile(path="tab")
t
Out[26]:
&\multicolumn{9}{c|}{4-digit PINs}&\multicolumn{3}{c|}{5-digit PINs}&\multicolumn{4}{c}{6-digit PINs}\\
Source of PINs of the participants
#1#2#3#4#5#6#7#8Sum#1#2Sum#1#2#3Sum
I chose it myself$75$$56$$28$$15$$3$$3$$1$$0$$181$$4$$2$$6$$10$$4$$1$$15$
The bank assigned it to me and decided not to change it$161$$94$$56$$31$$11$$3$$1$$0$$357$$3$$0$$3$$2$$1$$0$$3$
The bank assigned it to me and I am not allowed to change it$4$$2$$3$$0$$1$$1$$0$$1$$12$$1$$1$$2$$1$$0$$0$$1$
In [ ]:
 
In [ ]:
 
In [ ]:
 
In [ ]:
 
In [27]:
keys = [u'Card', u'Slip', u'Desk', u'Wallet', u'Diary', u'File', u'Phone']
base = 'PinWritten'
t = h.Table(["l"]+["c"]*(4), ["l|ccc|c"])
t.header = [""] + ["%d-digit" %(i+4) for i in range(3)] + ["Sum"] 
t.latexComment = "Two people mentioned that they store their Pins in lastpass"
for k in keys:
    d = [joined['%s#%d%s' %(base, i+4,k)].value_counts()['Yes'] if ('%s#%d%s' %(base,i+4,k) in descriptions.keys()
           and 'Yes' in joined['%s#%d%s' %(base,i+4,k)].value_counts()) else 0 for i in range(3)]
    dNo = [joined['%s#%d%s' %(base, i+4,k)].value_counts()['No'] if ('%s#%d%s' %(base,i+4,k) in descriptions.keys()
           and 'No' in joined['%s#%d%s' %(base,i+4,k)].value_counts()) else 0 for i in range(3)]
    desc = descriptions['%s#%d%s' %(base,5,k)].split("[")[1][:-1]
    t.addRow([desc] + ["$%.0f\%%$" %(100.0*y/(y+n) if y else 0.0) for y,n in zip(d, dNo)] + \
             ["$%.0f\%%$" %(100.0*sum(d)/(sum(d)+sum(dNo) if d else d))])
writtenCounts = [joined["%s#%d" %(base,i+4)].value_counts() for i in range(3)]
subs = [y for x in writtenCounts for y in [x['Yes'] if 'Yes' in x else 0, 0 if 'Yes' not in x else 
                                           100.0*(1.0*x['Yes'] / (x['Yes']+(x['No'] if 'No' in x else 0)))]]
t.setCaption("Location of written down PINs by participants. %d (%.1f%%), %d (%.1f%%), %d (%.1f%%) " %tuple(subs) + \
             "wrote down their 4-, 5-, 6-digit PINs respectively.")
t.reference = "pinsWritten"
t.writeLatexToFile(path="tab")
t
Out[27]:
Two people mentioned that they store their Pins in lastpass
Location of written down PINs by participants. 79 (32.9%), 4 (50.0%), 0 (0.0%) wrote down their 4-, 5-, 6-digit PINs respectively.
4-digit5-digit6-digitSum
On the card$1\%$$0\%$$0\%$$1\%$
I kept the original PIN slip$0\%$$0\%$$0\%$$0\%$
On paper - kept in desk$16\%$$25\%$$0\%$$17\%$
On paper - kept in wallet$10\%$$0\%$$0\%$$10\%$
In a notebook/diary/planner etc$41\%$$25\%$$0\%$$40\%$
File on computer$10\%$$25\%$$0\%$$11\%$
File on phone$42\%$$25\%$$0\%$$41\%$
In [28]:
keys = ["WithdrawCash", "ReUse", "ReUseOther"]
t = h.Table(["l"]+["c"]*(3), ["p{9cm}|ccc"])
t.header = [""] + ["%d-digit" %(i+4) for i in range(3)]# + ["Sum"] 
for k in keys:
    #d = [joined['%s#%d' %(k,i+4)].value_counts()['Yes'] if ('%s#%d' %(k,i+4) in newColumnNames 
    #       and 'Yes' in joined['%s#%d' %(k,i+4)].value_counts()) else 0 for i in range(3)]
    writtenCounts = [joined["%s#%d" %(k,i+4)].value_counts() for i in range(3)]
    subs = [0 if 'Yes' not in x else 100.0*(1.0*x['Yes'] / (x['Yes']+(x['No'] if 'No' in x else 0))) for x in writtenCounts]
    desc = descriptions['%s#%d' %(k,4)]
    t.addRow([desc] + ["$%.0f%s$" %(x,"\%") for x in subs])# + ["$%d$" %sum(d)])

t.setCaption("Participants card sharing statistics")
t.reference = "withdrawCash"
t.writeLatexToFile(path="tab")
t
Out[28]:
Participants card sharing statistics
4-digit5-digit6-digit
Do you use any of your 4-digit PINs to pay or withdraw cash?$98\%$$50\%$$54\%$
Do you use any of your 4-digit PINs for more than one payment card?$16\%$$0\%$$0\%$
Do you use any of your 4-digit PINs anywhere else, such as mobile phones, home security, online banking, bike locks?$23\%$$0\%$$8\%$
In [29]:
mf = h.figuresToLaTeX(columns=1,basename='reUseNumber',path='',
                      caption='Frequency of reuse of PINs, 16% of participants reuse at least one of their PINs.')
a = plt.figure(figsize=(8,5), dpi=80)
ax = joined["ReUse#4Num"].plot(kind="hist",bins=np.arange(0,11,1))

plt.setp(ax.patches, 'facecolor', '0.3','edgecolor', '0.15', 'alpha', 0.75)
locs, labels = plt.xticks()
plt.xticks(locs,[r'$%g$' %x for x in locs],size='large')
locs, labels = plt.yticks()
plt.yticks(locs,[r'$%g$' %x for x in locs],size='large')
plt.xlabel('Number of Payment Cards per PIN')
plt.ylabel('Frequency')
h.rstyle(ax)
mf.addFigure(a,describeText=h.describe(joined["ReUse#4Num"].dropna().values))
print h.describe(joined["ReUse#4Num"].dropna().values)
mf.writeLaTeX()
Size: 38, min: 2, max: 9, mean: 2.81579, variance: 2.3165, skewness: 2.45956
In [ ]:
 
In [30]:
keys = [u'PhoneUnlock', u'Burglar', u'Voicemail', u'SIMUnlock', u'Computer']
base = 'ReUseOther'
t = h.Table(["l"]+["c"]*(4), ["l|ccc|c"])
t.header = [""] + ["%d-digit" %(i+4) for i in range(3)] + ["Sum"] 
t.latexComment = "comments for 4 digits only: Online banking : 14, kindle: 1"
for k in keys:
    d = [joined['%s#%d%s' %(base, i+4,k)].value_counts()['Yes'] if ('%s#%d%s' %(base,i+4,k) in descriptions.keys() 
           and 'Yes' in joined['%s#%d%s' %(base,i+4,k)].value_counts()) else 0 for i in range(3)]
    dNo = [joined['%s#%d%s' %(base, i+4,k)].value_counts()['No'] if ('%s#%d%s' %(base,i+4,k) in descriptions.keys()
           and 'No' in joined['%s#%d%s' %(base,i+4,k)].value_counts()) else 0 for i in range(3)]
    desc = descriptions['%s#%d%s' %(base,5,k)].split("[")[1][:-1]
    t.addRow([desc] + ["$%.0f\%%$" %(100.0*y/(y+n) if y else 0.0) for y,n in zip(d, dNo)] + \
             ["$%.0f\%%$" %(100.0*sum(d)/(sum(d)+sum(dNo) if d else d))])
writtenCounts = [joined["ReUseOther#%d" %(i+4)].value_counts() for i in range(3)]
subs = [y for x in writtenCounts for y in [x['Yes'] if 'Yes' in x else 0, 0 if 'Yes' not in x else 
                                           100.0*(1.0*x['Yes'] / (x['Yes']+(x['No'] if 'No' in x else 0)))]]

t.setCaption("Location of reuse of PINs by participants. %d (%.1f%%), %d (%.1f%%), %d (%.1f%%) " %tuple(subs) + \
             "reused their 4-, 5-, 6-digit PINs, respectively.")
t.reference = "pinReUseLocations"
t.writeLatexToFile(path="tab")
t
Out[30]:
comments for 4 digits only: Online banking : 14, kindle: 1
Location of reuse of PINs by participants. 55 (22.9%), 0 (0.0%), 1 (7.7%) reused their 4-, 5-, 6-digit PINs, respectively.
4-digit5-digit6-digitSum
Unlocking mobile phone$49\%$$0\%$$0\%$$48\%$
Burglar alarm$2\%$$0\%$$0\%$$2\%$
Voicemail$15\%$$0\%$$0\%$$14\%$
SIM card unlock$7\%$$0\%$$0\%$$7\%$
Unlocking computer$5\%$$0\%$$100\%$$7\%$
In [ ]:
 
In [31]:
keys = [u'Stranger', u'Family', u'Flatmate', u'Spouse', u'Casual', u'Friend']
base = 'Shared'
t = h.Table(["l"]+["c"]*(4), ["l|ccc|c"])
t.header = [""] + ["%d-digit" %(i+4) for i in range(3)] + ["Sum"] 
t.latexComment = "No Comments/other"
for k in keys:
    d = [joined['%s#%d%s' %(base, i+4,k)].value_counts()['Yes'] if ('%s#%d%s' %(base,i+4,k) in descriptions.keys() 
           and 'Yes' in joined['%s#%d%s' %(base,i+4,k)].value_counts()) else 0 for i in range(3)]
    dNo = [joined['%s#%d%s' %(base, i+4,k)].value_counts()['No'] if ('%s#%d%s' %(base,i+4,k) in descriptions.keys() 
           and 'No' in joined['%s#%d%s' %(base,i+4,k)].value_counts()) else 0 for i in range(3)]
    desc = descriptions['%s#%d%s' %(base,5,k)].split("[")[1][:-1]
    t.addRow([desc] + ["$%.0f\%%$" %(100.0*y/(y+n) if y else 0.0) for y,n in zip(d, dNo)] + \
             ["$%.0f\%%$" %(100.0*sum(d)/(sum(d)+sum(dNo) if d else d))])
writtenCounts = [joined["%s#%d" %(base,i+4)].value_counts() for i in range(3)]
subs = [y for x in writtenCounts for y in [x['Yes'] if 'Yes' in x else 0, 0 if 'Yes' not in x else 
                                           100.0*(1.0*x['Yes'] / (x['Yes']+(x['No'] if 'No' in x else 0)))]]

t.setCaption("Sharing of PINs by participants. %d (%.1f%%), %d (%.1f%%), %d (%.1f%%) " %tuple(subs) + \
             "shared their 4-, 5-, 6-digit PINs respectively.")
t.reference = "pinSharing"
t.writeLatexToFile(path="tab")
t
Out[31]:
No Comments/other
Sharing of PINs by participants. 102 (42.5%), 2 (25.0%), 1 (7.7%) shared their 4-, 5-, 6-digit PINs respectively.
4-digit5-digit6-digitSum
Stranger$0\%$$0\%$$0\%$$0\%$
Family member$37\%$$0\%$$100\%$$37\%$
Flatmate (if accommodation shared)$3\%$$0\%$$0\%$$3\%$
Spouse/partner$75\%$$100\%$$0\%$$74\%$
Casual acquaintance$1\%$$0\%$$0\%$$1\%$
Close friend$14\%$$0\%$$0\%$$13\%$
In [ ]:
 
In [32]:
keys = [u'Myself', u'Issued', u'ReqRem', u'Bank']
base = 'Forgot'
t = h.Table(["l"]+["c"]*(4), ["p{8cm}|ccc|c"])
t.header = [""] + ["%d-digit" %(i+4) for i in range(3)] + ["Sum"] 
t.latexComment = "6 people stopped using their payment card"
for k in keys:
    d = [joined['%s#%d%s' %(base, i+4,k)].value_counts()['Yes'] if ('%s#%d%s' %(base,i+4,k) in descriptions.keys() 
           and 'Yes' in joined['%s#%d%s' %(base,i+4,k)].value_counts()) else 0 for i in range(3)]
    dNo = [joined['%s#%d%s' %(base, i+4,k)].value_counts()['No'] if ('%s#%d%s' %(base,i+4,k) in descriptions.keys() 
           and 'No' in joined['%s#%d%s' %(base,i+4,k)].value_counts()) else 0 for i in range(3)]
    desc = descriptions['%s#%d%s' %(base,5,k)].split("[")[1][:-1]
    t.addRow([desc] + ["$%.0f\%%$" %(100.0*y/(y+n) if y else 0.0) for y,n in zip(d, dNo)] + \
             ["$%.0f\%%$" %(100.0*sum(d)/(sum(d)+sum(dNo) if d else d))])
writtenCounts = [joined["%s#%d" %(base,i+4)].value_counts() for i in range(3)]
subs = [y for x in writtenCounts for y in [x['Yes'] if 'Yes' in x else 0, 0 if 'Yes' not in x else 
                                           100.0*(1.0*x['Yes'] / (x['Yes']+(x['No'] if 'No' in x else 0)))]]

t.setCaption("Forgetting of PINs by participants. %d (%.1f%%), %d (%.1f%%), %d (%.1f%%) " %tuple(subs) + \
             "forgot their 4-, 5-, 6-digit PINs respectively. Additionally, 6 participants stated that they stopped using" +\
            " the payment card after forgetting the PIN.")
t.reference = "pinForgot"
t.writeLatexToFile(path="tab")
t
Out[32]:
6 people stopped using their payment card
Forgetting of PINs by participants. 61 (25.4%), 0 (0.0%), 4 (30.8%) forgot their 4-, 5-, 6-digit PINs respectively. Additionally, 6 participants stated that they stopped using the payment card after forgetting the PIN.
4-digit5-digit6-digitSum
I remembered it myself$48\%$$0\%$$0\%$$45\%$
I was issued a new PIN number$25\%$$0\%$$25\%$$25\%$
I requested a PIN reminder and was able to remember it afterwards$8\%$$0\%$$75\%$$12\%$
I used the banks services to retrieve the PIN$15\%$$0\%$$0\%$$14\%$
In [ ]:
 
In [33]:
keys = [u'Number', u'Shape', u'Date', u'Change']
base = 'Pattern'
t = h.Table(["l"]+["c"]*(4), ["l|ccc|c"])
t.header = [""] + ["%d-digit" %(i+4) for i in range(3)] + ["Sum"] 
t.latexComment = "Additionally, 6 participants stated that they associated numbers with letters and spell out a word."
for k in keys:
    d = [joined['%s#%d%s' %(base, i+4,k)].value_counts()['Yes'] if ('%s#%d%s' %(base,i+4,k) in descriptions.keys() 
           and 'Yes' in joined['%s#%d%s' %(base,i+4,k)].value_counts()) else 0 for i in range(3)]
    dNo = [joined['%s#%d%s' %(base, i+4,k)].value_counts()['No'] if ('%s#%d%s' %(base,i+4,k) in descriptions.keys() 
           and 'No' in joined['%s#%d%s' %(base,i+4,k)].value_counts()) else 0 for i in range(3)]
    desc = descriptions['%s#%d%s' %(base,5,k)].split("[")[1][:-1]
    t.addRow([desc] + ["$%.0f\%%$" %(100.0*y/(y+n) if y else 0.0) for y,n in zip(d, dNo)] + \
             ["$%.0f\%%$" %(100.0*sum(d)/(sum(d)+sum(dNo) if d else d))])
writtenCounts = [joined["%s#%d" %(base,i+4)].value_counts() for i in range(3)]
subs = [y for x in writtenCounts for y in [x['Yes'] if 'Yes' in x else 0, 0 if 'Yes' not in x else 
                                           100.0*(1.0*x['Yes'] / (x['Yes']+(x['No'] if 'No' in x else 0)))]]

t.setCaption("Use of patterns to remember PINs. %d (%.1f%%), %d (%.1f%%), %d (%.1f%%) " %tuple(subs) + \
             "use patterns to remember their 4-, 5-, 6-digit PINs respectively.")
t.reference = "pinPattern"
t.writeLatexToFile(path="tab")
t
Out[33]:
Additionally, 6 participants stated that they associated numbers with letters and spell out a word.
Use of patterns to remember PINs. 31 (12.9%), 1 (12.5%), 4 (30.8%) use patterns to remember their 4-, 5-, 6-digit PINs respectively.
4-digit5-digit6-digitSum
Generate PINs from account or card number$6\%$$0\%$$0\%$$6\%$
The PINs represent a shape on the keypad$29\%$$100\%$$50\%$$33\%$
Generate PINs from a specific date$45\%$$0\%$$50\%$$44\%$
Change one digit from a number common to all PINs$0\%$$0\%$$0\%$$0\%$
In [ ]:
 
In [34]:
descriptiveValueCounts(joined.Longest,caption="The age of participant's oldest PIN",reference="pinAge",header=["Age", "Freq"],
                      reorder=[4,3,1,2,0])
Out[34]:
The age of participant's oldest PIN
AgeFreq
1-6 months$14$
6 months - 1 year$17$
1-3 years$78$
3-5 years$38$
5+ years$94$
In [35]:
keys = [u'ChangedAsked', u'ChangedWant', u'ChangedCompromised', u'ChangedRegular']
base = ''
t = h.Table(["l"]+["c"]*(1), ["l|c"])
t.header = [""] + ["Percentage"] 
t.latexComment = ""
totalChanged = sum(joined[k].value_counts()['Yes'] for k in keys)
for k in keys:
    d = [joined['%s%s' %(base, k)].value_counts()['Yes'] if ('%s%s' %(base,k) in descriptions.keys() 
           and 'Yes' in joined['%s%s' %(base,k)].value_counts()) else 0]
    desc = descriptions['%s%s' %(base,k)].split("[")[1][:-1]
    t.addRow([desc] + ["$%.0f\%%$" %(100.0*y/totalChanged if y else 0.0) for y in d])

t.setCaption("Participant's reasons for changing their most used PIN")
t.reference = "pinChanged"
t.writeLatexToFile(path="tab")
t
Out[35]:
Participant's reasons for changing their most used PIN
Percentage
I changed this PIN when I first received it, because my bank asked me to.$28\%$
I changed this PIN when I first received it, because I wanted to.$43\%$
I change this PIN when I feel it is compromised.$23\%$
I change this PIN on a regular basis.$6\%$
In [ ]:
 
In [36]:
joined.ChangedAsked.value_counts()
Out[36]:
No     228
Yes     13
Name: ChangedAsked, dtype: int64
In [37]:
mf = h.figuresToLaTeX(columns=1,basename='numberChanges',path='',
                      caption='Participant\'s number of PIN changes')
a = plt.figure(figsize=(8,5), dpi=80)
ax = joined.ChangedNum.plot(kind="hist",bins=np.arange(0,9,1))

plt.setp(ax.patches, 'facecolor', '0.3','edgecolor', '0.15', 'alpha', 0.75)
locs, labels = plt.xticks()
plt.xticks(locs,[r'$%g$' %x for x in locs],size='large')
locs, labels = plt.yticks()
plt.yticks(locs,[r'$%g$' %x for x in locs],size='large')
plt.xlabel('Number of PIN changes')
plt.ylabel('Frequency')
h.rstyle(ax)
mf.addFigure(a,describeText=h.describe(joined.ChangedNum.values))
print h.describe(joined.ChangedNum.values)
mf.writeLaTeX()
Size: 241, min: 0, max: 7, mean: 0.26971, variance: 0.622787, skewness: 4.53085
In [ ]:
 
In [ ]:
 
In [ ]:
 
In [ ]: