## Moodle'i logide analüüs¶

##### Autor: Nora Anete Müller¶

### Eeltöötlus¶

In [1]:

    import pandas as pd
    import matplotlib.pyplot as plt
    plt.rcParams["font.family"] = 'serif'
    plt.rcParams['font.size'] = 12
    import numpy as np
    from numpy import mean
    from numpy import std
    from numpy import cov
    from scipy.stats import pearsonr
    from scipy.stats import spearmanr
    import matplotlib.patches as mpatches
    from scipy import stats

In [2]:

    # Logide fail
    logs = pd.read_csv('logs.csv')

In [3]:

    # Eemaldatakse nende kasutajate logid, keda ei uurita
    logs.drop(logs.index[logs['Kasutaja täisnimi'] == 'Nora Anete Müller'], inplace=True)
    logs.drop(logs.index[logs['Kasutaja täisnimi'] == 'Tauno Palts'], inplace=True)
    logs.drop(logs.index[logs['Kasutaja täisnimi'] == 'Moodle admin'], inplace=True)
    logs.drop(logs.index[logs['Kasutaja täisnimi'] == '-'], inplace=True)
    logs.drop(logs.index[logs['Kasutaja täisnimi'] == 'xxx xxx'], inplace=True)
    logs.drop(logs.index[logs['Kasutaja täisnimi'] == 'xx xxxx'], inplace=True)
    logs.drop(logs.index[logs['Kasutaja täisnimi'] == 'xxx xx'], inplace=True)

In [4]:

    # hinne_vs_logid.csv on autori koostatud fail
    hin_log = pd.read_csv("Hinded_logid.csv")

In [5]:

    # Nimede asendamine logide failis -> nimetäht + m/f
    asendamine = {}
    for i in logs['Kasutaja täisnimi'].unique():
        nimi = i.split()
        eesnimi = nimi[0]
        perenimi = nimi[1]
        for index, row in hin_log.iterrows():
            if (eesnimi == row['Eesnimi'] and perenimi == row['Perenimi']):
                if (row['Sugu'] == 'f'):
                    uusNimi = eesnimi[0] + 'f'
                    k = 1
                    while uusNimi in asendamine.values() and k < len(eesnimi):
                        uusNimi = eesnimi[k] + 'f'
                        k += 1
                    if uusNimi not in asendamine.values():
                        asendamine[i] = uusNimi
                    else:
                        k = 1
                        uusNimi = perenimi[0] + 'f'
                        while uusNimi in asendamine.values() and k < len(perenimi):
                            uusNimi = perenimi[k] + 'f'
                            k += 1
                        asendamine[i] = uusNimi
                elif (row['Sugu'] == 'm'):
                    uusNimi = eesnimi[0] + 'm'
                    k = 1
                    while uusNimi in asendamine.values() and k < len(eesnimi):
                        uusNimi = eesnimi[k] + 'm'
                        k += 1
                    if uusNimi not in asendamine.values():
                        asendamine[i] = uusNimi
                    else:
                        k = 1
                        uusNimi = perenimi[0] + 'm'
                        while uusNimi in asendamine.values() and k < len(perenimi):
                            uusNimi = perenimi[k] + 'm'
                            k += 1
                        asendamine[i] = uusNimi

    logs['Kasutaja täisnimi'].replace(asendamine, inplace=True)

In [6]:

    # Nimede asendamine failis 'hinned_vs_logid.csv'
    hin_log.insert(0, 'Nimi', '')
    nimed = []
    for index, row in hin_log.iterrows():
        nimi = row['Eesnimi'] + ' ' + row['Perenimi']
        # Kui osaleja on teinud 0 logi
        if nimi not in asendamine:
            kood = '-'
        else:
            kood = asendamine[nimi]
        nimed.append(kood)

    hin_log['Nimi'] = nimed
    hin_log.drop('Eesnimi', axis=1, inplace=True)
    hin_log.drop('Perenimi', axis=1, inplace=True)

### Seos logide arvu ja lõpphinde vahel¶

In [7]:

    x1 = []
    y1 = []

    x2 = []
    y2 = []

    for index, row in hin_log.iterrows():
        if (hin_log['Kursuse lõpphinne'].iloc[index] == 'arvestatud'):
            x1.append(hin_log['Hinne (Punktid)'].iloc[index])
            y1.append(hin_log['Logide arv'].iloc[index])
        else:
            x2.append(hin_log['Hinne (Punktid)'].iloc[index])
            y2.append(hin_log['Logide arv'].iloc[index])

    plt.scatter(x1, y1, c='green', label='arvestatud')
    plt.scatter(x2, y2, c='red', label='mitte arvestatud')
    plt.legend()
    plt.xlabel('Punktid')
    plt.ylabel('Logide arv')
    plt.savefig('Diagrammid/LogideArv_punktid.png', format='png', dpi=100)

### Korrelatsioonanalüüs¶

In [8]:

    logid = hin_log['Logide arv'].tolist()
    punktid = hin_log['Hinne (Punktid)'].tolist()
    # Mean and standard deviation
    print('logid: mean=%.3f stdv=%.3f' % (mean(logid), std(logid)))
    print('punktid: mean=%.3f stdv=%.3f' % (mean(punktid), std(punktid)))

    logid: mean=303.979 stdv=170.578
    punktid: mean=31.260 stdv=13.536

In [9]:

    # calculate covariance matrix
    covariance = cov(logid, punktid)
    print(covariance)

    [[29715.85062057  1769.28213652]
     [ 1769.28213652   187.12754876]]

In [10]:

    # caluclate Pearson's correlation
    corr, _ = pearsonr(logid, punktid)
    print('Pearsons correaltion: %.3f' % corr)

    Pearsons correaltion: 0.750

#### positiivne korrelatsioon => 0.75¶

### T-test¶

In [11]:

    stats.ttest_ind(logid, punktid)

Out[11]:

    Ttest_indResult(statistic=10.926432683324903, pvalue=2.0088847999402385e-18)

#### p-väärtus < 0.01¶

### Millistel päevadel on osalejad kõige aktiivsemad?¶

In [12]:

    # Kuupäeva veeru lisamine andmetesse
    logs.insert(1, 'Kuupäev', '')
    logs = logs.reset_index(drop=True)

    kuupäevad = []
    for index, row in logs.iterrows():
        if index == len(logs):
            break
        else:
            kuupäev = row['Aeg'][0:10]
            if kuupäev[-1] == ' ':
                kuupäev = kuupäev.replace(' ','')
                kuupäev = '0' + kuupäev
                row['Aeg'] = '0' + row['Aeg']
            kuupäevad.append(kuupäev)
    logs['Kuupäev'] = kuupäevad

In [13]:

    def tagastaKp(el):
        return el['Kuupäev']

    def sortKp(data):

        oktoober = []
        november = []
        detsember = []
        jaanuar = []

        # Kuupäevade sort kuu järgi
        for index, row in data.iterrows():
            if (row['Kuupäev'][3:5] == '10'):
                oktoober.append(row)
            elif (row['Kuupäev'][3:5] == '11'):
                november.append(row)
            elif (row['Kuupäev'][3:5] == '12'):
                detsember.append(row)
            elif (row['Kuupäev'][3:5] == '01'):
                jaanuar.append(row)

        # Kuupäevade sort päeva järgi
        oktoober = sorted(oktoober, key=lambda x: tagastaKp(x))
        november = sorted(november, key=lambda x: tagastaKp(x))
        detsember = sorted(detsember, key=lambda x: tagastaKp(x))
        jaanuar = sorted(jaanuar, key=lambda x: tagastaKp(x))

        values = oktoober + november + detsember + jaanuar
        return values

    def newDf(values):
        df = pd.DataFrame(data = values, columns = logs.columns)
        return df

In [14]:

    # Logide sort kuupäevade kaupa
    newLogs = newDf(sortKp(logs))

In [15]:

    # Logide arv erinevatel kuupäevadel
    kp = newLogs['Kuupäev'].unique()
    valueCounts = []
    for el in kp:
        count = 0
        for index, row in newLogs.iterrows():
            if row['Kuupäev'] == el:
                count += 1
        valueCounts.append([el[:5], count])

In [16]:

    # Novembri kuupäevad
    kursus = []
    for i in valueCounts:
        if (i[0][3:5] == '11'):
            kursus.append(i)

In [17]:

    fig = plt.figure(figsize=(15,5))
    ax = fig.add_subplot(111)
    ax.plot([i[0] for i in kursus], [i[1] for i in kursus])
    ax.set_xlabel('Kuupäevad')
    ax.xaxis.label.set_size(12)
    ax.set_ylabel('Logide arv')
    ax.yaxis.label.set_size(12)
    ax.set_xticks(['01.11','03.11','05.11','07.11','09.11','11.11','13.11','15.11','17.11','19.11','21.11','23.11','25.11',
                  '27.11','29.11'])
    fig.savefig('Diagrammid/LogideArv_Kuupäev.png', format='png', dpi=100)

In [18]:

    # Lisanädalate kuupäevad
    muu = []
    for i in valueCounts:
        if (i[0][3:5] == '12'):
            muu.append(i)

In [19]:

    fig = plt.figure(figsize=(15,5))
    ax = fig.add_subplot(111)
    ax.plot([i[0] for i in muu], [i[1] for i in muu])
    ax.set_xlabel('Kuupäevad')
    ax.xaxis.label.set_size(12)
    ax.set_ylabel('Logide arv')
    ax.yaxis.label.set_size(12)
    fig.savefig('Diagrammid/LogideArv_Kuupäev_vol2.png', format='png', dpi=100)

### Millistel kellaaegadel on osalejad kõige aktiivsemad?¶

In [20]:

    # Kellaaja veeru lisamine andmetesse
    newLogs.insert(2, 'Kellaaeg', '')

    # Lisatakse ainult tunni osa kellaajast ehk '09:44:44' tuleb veergu kujul '09'
    kellaajad = []
    for index, row in newLogs.iterrows():
        kellaajad.append(row['Aeg'][11:13])

    newLogs['Kellaaeg'] = kellaajad

In [21]:

    # Logide arv erinevatel kellaaegadel
    kl = newLogs['Kellaaeg'].unique()
    valueCounts = []
    for el in kl:
        count = 0
        for index, row in newLogs.iterrows():
            if row['Kellaaeg'] == el:
                count += 1
        valueCounts.append([el, count])

In [22]:

    def takeTime(el):
        return el[0]
    valueCounts.sort(key=takeTime)

    fig = plt.figure(figsize=(10,5))
    ax = fig.add_subplot(111)
    ax.plot([i[0] for i in valueCounts], [i[1] for i in valueCounts])
    ax.set_xlabel('Kellaajad')
    ax.xaxis.label.set_size(12)
    ax.set_ylabel('Logide arv')
    ax.yaxis.label.set_size(12)
    fig.savefig('Diagrammid/LogideArv_Kellaaeg.png', format='png', dpi=100)

### Millistel nädalatel olid (arvestatud) osalejad aktiivsed?¶

In [23]:

    # Nädala veeru lisamine andmetesse
    newLogs.insert(3, 'Nädal', '')
    nadal1 = ['01.11.2021', '02.11.2021', '03.11.2021', '04.11.2021', '05.11.2021', '06.11.2021', '07.11.2021']
    nadal2 = ['08.11.2021', '09.11.2021', '10.11.2021', '11.11.2021', '12.11.2021', '13.11.2021', '14.11.2021']
    nadal3 = ['15.11.2021', '16.11.2021', '17.11.2021', '18.11.2021', '18.11.2021', '19.11.2021', '20.11.2021', '21.11.2021']
    nadal4 = ['22.11.2021', '23.11.2021', '24.11.2021', '25.11.2021', '26.11.2021', '27.11.2021', '28.11.2021']

    nadalad = []
    for index, row in newLogs.iterrows():
        if row['Kuupäev'] in nadal1:
            nadalad.append('1. nädal')
        elif row['Kuupäev'] in nadal2:
            nadalad.append('2. nädal')
        elif row['Kuupäev'] in nadal3:
            nadalad.append('3. nädal')
        elif row['Kuupäev'] in nadal4:
            nadalad.append('4. nädal')
        else:
            nadalad.append('muu')

    newLogs['Nädal'] = nadalad

In [24]:

    # Osalejate logid, kes said lõpphinde arvestatud
    arvestatud = hin_log.loc[hin_log['Kursuse lõpphinne'] == 'arvestatud']
    arvestatud = arvestatud['Nimi'].tolist()

    arvestatud_logs = newLogs[newLogs['Kasutaja täisnimi'].isin(arvestatud)]

#### Logide koguarv nädalates¶

In [25]:

    x = ['1. nädal', '2. nädal', '3. nädal', '4. nädal', 'muu']
    y = [arvestatud_logs['Nädal'].value_counts().sort_index()[0], arvestatud_logs['Nädal'].value_counts().sort_index()[1],
        arvestatud_logs['Nädal'].value_counts().sort_index()[2], arvestatud_logs['Nädal'].value_counts().sort_index()[3],
        arvestatud_logs['Nädal'].value_counts().sort_index()[4]]

    fig = plt.figure(figsize=(15,10))
    ax = fig.add_subplot(111)
    ax.bar(x, y)
    ax.bar_label(ax.containers[0])
    ax.set_ylabel('Logide arv')
    ax.yaxis.label.set_size(12)

In [26]:

    kasutajad = []
    nimed = []
    for i, row in arvestatud_logs.iterrows():
        if (row['Nädal'] == '1. nädal'):
            nimed.append(row['Kasutaja täisnimi'])
    kasutajad.append(len(list(set(nimed))))

    nimed = []
    for i, row in arvestatud_logs.iterrows():
        if (row['Nädal'] == '2. nädal'):
            nimed.append(row['Kasutaja täisnimi'])
    kasutajad.append(len(list(set(nimed))))

    nimed = []
    for i, row in arvestatud_logs.iterrows():
        if (row['Nädal'] == '3. nädal'):
            nimed.append(row['Kasutaja täisnimi'])
    kasutajad.append(len(list(set(nimed))))

    nimed = []
    for i, row in arvestatud_logs.iterrows():
        if (row['Nädal'] == '4. nädal'):
            nimed.append(row['Kasutaja täisnimi'])
    kasutajad.append(len(list(set(nimed))))

    nimed = []
    for i, row in arvestatud_logs.iterrows():
        if (row['Nädal'] == 'muu'):
            nimed.append(row['Kasutaja täisnimi'])
    kasutajad.append(len(list(set(nimed))))

#### Unikaalsete kasutajate arv nädalates¶

In [27]:

    x = ['1. nädal', '2. nädal', '3. nädal', '4. nädal', 'muu']

    fig = plt.figure(figsize=(15,8))
    ax = fig.add_subplot(111)
    ax.bar(x, kasutajad)
    ax.bar_label(ax.containers[0])
    ax.set_ylabel('Kasutajate arv')
    ax.yaxis.label.set_size(12)

In [28]:

    # Keskmise logide arvu leidmine
    new_y = []
    for i in y:
        for k in kasutajad:
            new_y.append(i / k)
            break

#### Keskmine logide arv nädalates¶

In [29]:

    x = ['1. nädal', '2. nädal', '3. nädal', '4. nädal', 'muu']
    fig = plt.figure(figsize=(15,8))
    plt.bar(x, new_y)

    labels = []
    for i in new_y:
        labels.append(str(round(i,2)).replace('.', ','))

    for i in range(len(x)):
        plt.text(i, new_y[i]+0.02, labels[i], ha='center', va='bottom', fontsize=12)

    plt.ylabel('Keskmine logide arv', fontsize=12)
    fig.savefig('Diagrammid/LogideArv_Nädalad_keskmine.png', format='png', dpi=100)

### Automaatkontrollidega ülesannete analüüs¶

In [30]:

    vpl = ['VPL harjutus: Kontrollülesanne 1.1. Kuldnokk (tähtaeg: 7. november)',
        'VPL harjutus: Kontrollülesanne 2.1. Valikulause (tähtaeg: 14. november)',
        'VPL harjutus: Kontrollülesanne 2.2. Sõned (tähtaeg: 14. november)',
        'VPL harjutus: Kontrollülesanne 3.1. Tsükkel (tähtaeg 21. november)',
        'VPL harjutus: Kontrollülesanne 3.2. Regulaaravaldis (tähtaeg: 21. november)',
        'VPL harjutus: Kontrollülesanne 4.1. Funktsioonid (tähtaeg: 28. november)',
        'VPL harjutus: Lisaülesanne. Küpsisetort (ei ole kohustuslik)',
        'VPL harjutus: Lisaülesanne: Nädalapalk (ei ole kohustuslik)',
        'VPL harjutus: Lisaülesanne: Eurod ja sendid (ei ole kohustuslik)',
        'VPL harjutus: Lisaülesanne: Supp (ei ole kohustuslik)',
        'VPL harjutus: Lisaülesanne: Autonumber (ei ole kohustuslik)',
        'VPL harjutus: Lisaülesanne: Pere sissetulek 2017 (ei ole kohustuslik)']

In [31]:

    lisa = ['Lisaülesanne. Küpsisetort',
        'Lisaülesanne: Nädalapalk',
        'Lisaülesanne: Eurod ja sendid',
        'Lisaülesanne: Supp',
        'Lisaülesanne: Autonumber',
        'Lisaülesanne: Pere sissetulek 2017']

In [32]:

    vpl_data = newLogs.loc[newLogs['Sündmuse kontekst'].isin(vpl)]

In [33]:

    # Uued nimetused ülesannetele, et oleks diagrammilt kergem lugeda
    vpl_uus = [
        'Kontrollülesanne 1.1. Kuldnokk', 'Lisaülesanne. Küpsisetort',
        'Kontrollülesanne 2.2. Sõned','Kontrollülesanne 2.1. Valikulause',
        'Lisaülesanne: Eurod ja sendid','Lisaülesanne: Nädalapalk', 'Kontrollülesanne 3.1. Tsükkel',
        'Lisaülesanne: Autonumber', 'Lisaülesanne: Supp','Kontrollülesanne 3.2. Regulaaravaldis',
        'Kontrollülesanne 4.1. Funktsioonid','Lisaülesanne: Pere sissetulek 2017'
    ]

In [34]:

    kontekst = vpl_data['Sündmuse kontekst'].unique().tolist()
    for i in kontekst:
        indeks = kontekst.index(i)
        vpl_data['Sündmuse kontekst'].replace({i: vpl_uus[indeks]}, inplace=True)

    C:\Users\Nora\anaconda3\lib\site-packages\pandas\core\generic.py:6619: SettingWithCopyWarning:
    A value is trying to be set on a copy of a slice from a DataFrame

    See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
      return self._update_inplace(result)

In [35]:

    x = []
    y = []
    nimi = []
    kasutajad = []
    tegevus = 'mod_vpl: submission uploaded'
    for v in vpl_uus:
        harjutus = v
        if (harjutus not in lisa):
            x.append(harjutus)
            count = 0
            for i, row in vpl_data.iterrows():
                if (row['Sündmuse kontekst'] == harjutus and row['Sündmuse nimi'] == tegevus):
                    count += 1
                    nimi.append(row['Kasutaja täisnimi'])
            kasutajad.append(len(list(set(nimi))))
            y.append(count)
            nimi = []

In [36]:

    x2 = []
    y2 = []
    nimi = []
    kasutajad2 = []
    tegevus = 'mod_vpl: submission uploaded'
    for v in vpl_uus:
        harjutus = v
        if (harjutus in lisa):
            x2.append(harjutus)
            count = 0
            for i, row in vpl_data.iterrows():
                if (row['Sündmuse kontekst'] == harjutus and row['Sündmuse nimi'] == tegevus):
                    count += 1
                    nimi.append(row['Kasutaja täisnimi'])
            kasutajad2.append(len(list(set(nimi))))
            y2.append(count)
            nimi = []

In [37]:

    a, b = x.index('Kontrollülesanne 2.2. Sõned'), x.index('Kontrollülesanne 2.1. Valikulause')
    x[b], x[a] = x[a], x[b]
    y[b], y[a] = y[a], y[b]

#### Üleslaadimiste koguarv¶

In [38]:

    fig = plt.figure(figsize=(25,10))
    ax = fig.add_subplot(111)
    ax.bar(x, y)
    ax.bar_label(ax.containers[0])
    ax.set_ylabel('Üleslaadimiste arv')

Out[38]:

    Text(0, 0.5, 'Üleslaadimiste arv')

#### Lisaülesannetes üleslaadimiste koguarv¶

In [39]:

    fig = plt.figure(figsize=(22,8))
    ax = fig.add_subplot(111)
    ax.bar(x2, y2)
    ax.bar_label(ax.containers[0])
    ax.set_ylabel('Üleslaadimiste arv')

Out[39]:

    Text(0, 0.5, 'Üleslaadimiste arv')

In [40]:

    kasutajad[b], kasutajad[a] = kasutajad[a], kasutajad[b]

#### Kontrollülesandeid lahendanud kasutajad¶

In [41]:

    fig = plt.figure(figsize=(27, 8))
    ax = fig.add_subplot(111)
    ax.bar(x, kasutajad)
    ax.bar_label(ax.containers[0])
    ax.set_ylabel('Kasutajate arv')

Out[41]:

    Text(0, 0.5, 'Kasutajate arv')

#### Lisaülesandeid lahendanud kasutajad¶

In [42]:

    fig = plt.figure(figsize=(22, 8))
    ax = fig.add_subplot(111)
    ax.bar(x2, kasutajad2)
    ax.bar_label(ax.containers[0])
    ax.set_ylabel('Kasutajate arv')

Out[42]:

    Text(0, 0.5, 'Kasutajate arv')

In [43]:

    # Keskmise arvutamine (kontrollülesanded)
    new_y = []
    for i in y:
        for k in kasutajad:
            new_y.append(i / k)
            break

    # Keskmise arvutamine (lisaülesanded)
    new_y2 = []
    for i in y2:
        for k in kasutajad2:
            new_y2.append(i / k)
            break

In [44]:

    new_y[b], new_y[a] = new_y[a], new_y[b]

#### Keskmine üleslaadimiste arv¶

In [45]:

    fig = plt.figure(figsize=(16,8))
    plt.bar(x, new_y)

    labels = []
    for i in new_y:
        labels.append(str(round(i,2)).replace('.', ','))

    for i in range(len(x)):
        plt.text(i, new_y[i]+0.02, labels[i], ha='center', va='bottom')

    labels = ['1.1. Kuldnokk','2.1. Valikulause','2.2. Sõned','3.1. Tsükkel','3.2. Regulaaravaldis','4.1. Funktsioonid']
    plt.xticks(x, labels)
    plt.xlabel('Kohustuslikud kontrollülesanded', labelpad=20)
    plt.ylabel('Keskmine üleslaadimiste arv', labelpad=10)
    fig.savefig('Diagrammid/VPL_keskmine.png', format='png', dpi=100)

#### Keskmine üleslaadimiste arv (lisaülesanded)¶

In [46]:

    import locale
    locale.setlocale(locale.LC_NUMERIC, "de_DE")
    plt.rcParams['axes.formatter.use_locale'] = True

    fig = plt.figure(figsize=(15,8))
    plt.bar(x2, new_y2)

    labels = []
    for i in new_y2:
        labels.append(str(round(i,2)).replace('.', ','))

    for i in range(len(x2)):
        plt.text(i, new_y2[i]+0.02, labels[i], ha='center', va='bottom', fontsize=12)

    labels = ['Küpsisetort','Eurod ja sendid','Nädalapalk','Autonumber', 'Supp','Pere sissetulek 2017']
    plt.xticks(x2, labels)
    plt.xlabel('Lisaülesanded', labelpad=10)
    plt.ylabel('Keskmine üleslaadimiste arv', labelpad=10)

    fig.savefig('Diagrammid/VPL_keskmine_lisa.png', format='png', dpi=100)