SAÉ15 – Traitement de données

Tout au long de la SAE 15, nous avons utilisé Python pour créer un projet. Ce projet consiste à réaliser des traitements de données sur un agenda de l’IUT, incluant le nombre de cours, de professeurs, de classes et d’élèves, ainsi que la gestion de l’emploi du temps. Nous avons donc importé les résultats stockés dans un fichier CSV pour les analyser.

01

Voici le code de notre projet dans l’interpreteur

02

Voici un extrait de l’execution du programme

03

Voici l’arborescence de notre projet


"""
Script: SAE-15/projet7
Création: pecoutl, le 16/11/2021
"""

# Imports
import tools_sae
from tools_sae import *  # Calls from the tools_sae function
from tools import tools_constantes  # import of the tools_constantes function
from datetime import datetime
from tools_date import *


# Fonctions
def extract_events(ics):
    calend = ics
    liste = []
    x = calend.split("\n")
    code = -1
    valeur = False
    for i in range(len(x)):
        caractere = x[i]
        if caractere == "END:VEVENT":
            valeur = False
        if valeur:
            liste[code] += caractere + "\n"
        if caractere == "BEGIN:VEVENT":
            valeur = True
            code += 1
            liste.append("")
    return liste


def conversion_date(date):
    aa = date[:4]
    mm = date[-4:6]
    jj = date[6:]
    re = "{}-{}-{}".format(jj, mm, aa)
    return re


def conversion_heure(heure):
    h = heure[:2]
    m = heure[-4:4]
    re = "{}:{}".format(h, m)
    return re


def calcul_duree(heure_debut, heure_fin):
    heure1 = int(heure_debut[:2])
    minute1 = int(heure_debut[-2:5])

    heure2 = int(heure_fin[:2])
    minute2 = int(heure_fin[-2:5])

    difference = (heure2 * 60 + minute2) - (heure1 * 60 + minute1)
    heure_str = str(difference // 60)
    minutes_str = str(difference % 60)

    return "{}:{}".format(heure_str.zfill(2), minutes_str.zfill(2))


def parse_event(event):
    splitevent = event.split("\n") # split all elements of the list
    uid = get_event_by_id(splitevent, 'UID').split(":")[1]
    # search for the UID section then slpit to retrieve only the uid
    date = get_event_by_id(splitevent, "DTSTART").split(":")[1]
    # search for the DTSTART section then slpit to retrieve only the date
    date1 = date.split("T")[0]
    date2 = conversion_date(date1)
    heure = get_event_by_id(splitevent, "DTSTART").split(":")[1]
    h1 = heure.split('T')[1]
    heure1 = conversion_heure(h1.split("Z")[0])
    heure2 = get_event_by_id(splitevent, "DTEND").split(":")[1]
    h2 = heure2.split("T")[1]
    heure22 = conversion_heure(h2.split("Z")[0])
    duree = calcul_duree(heure1, heure22)
    cal_ressource = get_event_by_id(splitevent, "SUMMARY").split(":")[1]

    if '-' not in cal_ressource:
        ressource = "Autre"
    else:
        ressource = cal_ressource.split("-")[0]

    if '-' not in cal_ressource:
        tdds = ""
    else:
        tdds = cal_ressource.split("-")[1]
    # condition to display if there are td's or ds or return other if there is something else
    resume = get_event_by_id(splitevent, "SUMMARY").split(":")[1]

    salle = get_event_by_id(splitevent, "LOCATION")
    if salle:
        salle = salle.split(":")[1]
        salle = salle.replace(",", "|")
    # condition to display several rooms
    profs = get_event_by_id(splitevent, "DESCRIPTION")
    if profs:
        profs = profs.split(":")[1]
        profs = profs.replace(",", "|")
    # condition for displaying multiple professors
    groupe = get_event_by_id(splitevent, "CATEGORIES").split(":")[1]
    groupe = groupe.replace(",", "|")

    liste_event = uid + ';' + date2 + ';' + heure1 + ';' + duree + ';' + ressource + ';' + tdds + ';' + resume + ';' + (
        salle if salle else "") + ';' + (
                      profs if profs else "") + ';' + groupe

    return liste_event


def parse_fichier_ics(fichier_ics):
    parsed_events = []
    file = lecture_fichier(fichier_ics)
    events = extract_events(file)
    for event in events:
        parsed_events.append(parse_event(event))

    return parsed_events


def nombre_minutes(heure):
    h1 = int(heure[:2])
    m1 = int(heure[-2:5])
    h11 = h1 * 60
    minute = h11 + m1
    return minute


def calcul_heure_fin(heure_debut, duree):
    total_heures = heure_debut.split(":")
    total_duree = duree.split(":")

    totalheure = nombre_minutes("{}:{}".format(total_heures[0], total_heures[1]))
    totalduree = nombre_minutes("{}:{}".format(total_duree[0], total_duree[1]))

    final = totalheure + totalduree

    if final < 0:
        nombre = -final
    else:
        nombre = final
    heuretoto = str(nombre // 60)
    minutetoto = str(nombre % 60)
    print('{}:{}'.format(heuretoto.zfill(2), minutetoto.zfill(2)))
    return '{}:{}'.format(heuretoto.zfill(2), minutetoto.zfill(2))


def compare_dates(date1, date2):
    d1 = datetime.datetime.strptime(date1, "%d-%m-%Y").date()
    # creating a format for the date
    d2 = datetime.datetime.strptime(date2, "%d-%m-%Y").date()
    # creating a format for the date
    if d1 < d2:
        return -1
    if d1 > d2:
        return 1
    if d1 == d2:
        return 0


def date_dans_intervalle(date, debut, fin):
    a = compare_dates(date, debut) #
    b = compare_dates(fin, date) #
    if a >= 0 and b >= 0:
        return True
    return False


def clean(liste):
    result = []

    for e in liste:
        if not e in result:
            result.append(e)

    return result


def liste_jours_travailles(events, groupe):
    results = []

    for event in events:
        if groupe in event.split(';')[-1] and is_in_semestre1(event.split(';')[1]):
            results.append(event.split(';')[1])

    return clean(results)


def nb_jours(liste_dates):
    liste = [0, 0, 0, 0, 0]
    for i in range(len(liste_dates)):

        splitdate = liste_dates[i].split("-") #
        numero = get_numero_jour_semaine(int(splitdate[0]), int(splitdate[1]), int(splitdate[2]))
        if numero == 1:
            liste[0] += 1
        elif numero == 2:
            liste[1] += 1
        elif numero == 3:
            liste[2] += 1
        elif numero == 4:
            liste[3] += 1
        elif numero == 5:
            liste[4] += 1

    return liste


def nb_heures_travaillees_par_jour(events, groupe):
    liste = [0.0, 0.0, 0.0, 0.0, 0.0]

    for event in events:
        if groupe in event and is_in_semestre1(event.split(";")[1]):
            splitted_event = event.split(';')
            date_ = splitted_event[1]
            duration = splitted_event[3]
            splitted_date = date_.split("-")
            numero = get_numero_jour_semaine(int(splitted_date[0]), int(splitted_date[1]), int(splitted_date[2]))

            index = 0
            if numero == 1:
                index = 0
            elif numero == 2:
                index = 1
            elif numero == 3:
                index = 2
            elif numero == 4:
                index = 3
            elif numero == 5:
                index = 4

            heure = int(duration.split(":")[0]) * 60
            minutes = int(duration.split(":")[1])

            liste[index] += (heure + minutes) / 60

    return liste


def is_in_semestre1(date_to_check):
    semestre1 = tools_constantes.BUT1_SEMESTRE1
    # we call the function BUT1_semestre which indicates the start and end date of the semester
    return date_dans_intervalle(date_to_check, semestre1[0], semestre1[1])
    # return the results if the date is within the semester interval

def traitement(events, groupe):
    result = []  # creation of a variable with a list as parameter

    moyennes_heure = [0.00, 0.00, 0.00, 0.00, 0.00]
    # creation of the format and a variable for the average time (for a list parameter)
    moyennes_heure_ouvrees = [0.0, 0.0, 0.0, 0.0, 0.0]
    # creation of a variable and format by average working hours (for a list parameter)
    jours = ["lundi", "mardi", "mercredi", "jeudi", "vendredi"]
    # creation of a variable for days with the list of days of the week

    heures_jour = nb_heures_travaillees_par_jour(events, groupe)  #
    jours_travailles = liste_jours_travailles(events, groupe)  #
    jours_ouvres = tools_sae.get_jours_ouvres()  #
    jours_ouvres = [i for i in jours_ouvres if is_in_semestre1(i)]
    nb_jours_ouvres = nb_jours(jours_ouvres)
    nb_jours_travailles = nb_jours(jours_travailles)

    for i in range(len(moyennes_heure)):
        # creation of a loop with the number of characters in the average time variable as a parameter
        moyennes_heure[i] += (heures_jour[i] / nb_jours_travailles[i])
        # calculates the average hour by dividing the hours by the number of days worked

    for i in range(len(moyennes_heure_ouvrees)):
        # creation of a loop with the number of characters in the average time variable as a parameter
        moyennes_heure_ouvrees[i] += (heures_jour[i] / nb_jours_ouvres[i])
        # calculates the average hour by dividing the hours by the number of hours worked
    for i in range(len(jours)):
        result.append("{};{};{};{};{}".format(jours[i], nb_jours_travailles[i], "%.2f" % round(moyennes_heure[i], 2),
                                              nb_jours_ouvres[i], "%.2f" % round(moyennes_heure_ouvrees[i], 2)))
        # on ajoute dans notre liste vide les valeurs de retour de nos 3 boucle

    return result  # return of the result variable which displays our list with all the elements


def export_markdown(events):
    markdown = ""  # creation of the markdown variable for a string parameter
    markdown += "|Jour de la semaine | Nombre de jours travaillés |Moyenne horaire par jour travaillé | " \
                "Nombre de jours ouvrés | Moyenne horaire par jour ouvré|" "\n"
    # added the title of the markdown table
    markdown += "| :--------: | :-------------:|:----:| :--------: | :-------------:|\n"
    # adding markdown format parameters

    for i in range(len(events)):  # creation of a loop as parameter the number of characters of the event
        events1 = events[i].split(";")  # cutting of the return the processing function
        markdown += "|" + events1[0] + " | " + events1[1] + " | " + events1[2] + " | " + events1[3] + " | " \
                    + events1[4] + "|" + "\n"  # calls return values for the creation of the table markdown

    print(markdown)
    print(events)
    return markdown  # return of our markdown variable
# Programme principal


def main():
    print(parse_event(lecture_fichier("data/S1G4.ics")))
    # extract_events(lecture_fichier("data/calendrier_3evts_UFA.ics"))
    # parse_event(lecture_fichier("data/S1G4.ics"))
    # conversion_date("20211119")
    # conversion_heure("111212")
    # date_dans_intervalle("11-10-2021","15-12-2021","17-12-2021")
    # calcul_duree("08:00", "12:00")
    # nombre_minutes("01:25")
    # calcul_heure_fin("01:00", "02:30")
    # compare_dates("22-03-2003","30-12-2021")
    # nb_jours("04-11-2003")
    file = tools_sae.lecture_fichier("tests/data/data.csv")
    # print(traitement(file.split("\n"), "S1G2"))
    export_markdown(traitement(file.split("\n"), "S1G2"))


if __name__ == '__main__':
    main()
# Fin