Helkarth

TD2

Nov 14th, 2018
752
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 17.66 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2.  
  3. ####################
  4. #
  5. # Travail 2
  6. # Réalisé par: Caroline Beauchamp
  7. # Remise: 13/11/2018
  8. #
  9. ####################
  10.  
  11. import csv
  12. from math import radians, sin, cos, sqrt, asin
  13.  
  14. #fonction de base pour calculer la distance en KM entre 2 point
  15. def haversine(lat1, lon1, lat2, lon2):
  16.  
  17.     R = 6372.8  # diamètre de la Terre en KM
  18.  
  19.     dLat = radians(float(lat2) - float(lat1))
  20.     dLon = radians(float(lon2) - float(lon1))
  21.     lat1 = radians(float(lat1))
  22.     lat2 = radians(float(lat2))
  23.  
  24.     a = sin(dLat / 2) ** 2 + cos(float(lat1)) * cos(float(lat2)) * sin(dLon / 2) ** 2
  25.     c = 2 * asin(sqrt(a))
  26.  
  27.     return R * c
  28.  
  29.  
  30. class Company: #classe permettant de gérer l'entité "Company"
  31.  
  32.     # constructeur de Company, permet la création des listes de chauffeurs(listDrivers) et la liste des voitures(listCars)
  33.     def __init__(self, name):
  34.         self.name = name #name est le nom que l'on veut donner à la compagnie
  35.         self.listCars = []
  36.         self.listDrivers = []
  37.  
  38.  
  39.     #méthode pour ajout manuel d'une voiture à listCars
  40.     def addCar(self, car): #où car est la voiture à ajouter
  41.         self.listCars.append(car)
  42.  
  43.  
  44.     #méthode pour un ajout en "batch" de voitures, via un fichier CSV
  45.     def addCarByCSV(self, csvCars): #où csvCars est le chemin du fichier csv contenant les informations sur les voitures
  46.         with open(csvCars, 'rb') as csvfile:
  47.             csvreader = csv.reader(csvfile, delimiter=',')#importance de valider de délimitateur du fichier CSV
  48.             for row in csvreader:
  49.                 self.listCars.append(row)
  50.  
  51.  
  52.     # méthode pour ajout manuel d'un chauffeur à la liste listDrivers
  53.     def addDriver(self, driver): #où driver est le conducteur à ajouter
  54.         self.listDrivers.append(driver)
  55.  
  56.  
  57.     # méthode pour un ajout en "batch" de conducteurs , via un fichier CSV
  58.     def addDriverByCSV(self, csvDriver): #où csvCars est le path du fichier csv des voiture
  59.         with open(csvDriver, 'rb') as csvfile:
  60.             csvreader = csv.reader(csvfile, delimiter=',')#importance de valider de délimitateur du fichier CSV
  61.             for row in csvreader:
  62.                 self.listDrivers.append(row)
  63.  
  64.  
  65.     #méthode pour trouver une voiture en fonction de son identifiant(id)
  66.     def getCarById(self, id):  #où id est l'id de la voiture
  67.         for c in self.listCars: #on parcours la liste de voiture
  68.             if c.id == id : #pour trouver un identifiant correspondant et on le retourne
  69.                 return c
  70.  
  71.  
  72.     # méthode pour trouver le conducteur d'une voiture en fonction de l'identifiant de la voiture(id)
  73.     def getDriverByCarId(self, id):  #où id est l'id de la voiture
  74.         for d in self.listDrivers:  #on parcours la liste des conducteurs
  75.             if d.carId == id: #pour trouver les informations du conducteur associé à l'id de la voiture et on le retourne
  76.                 return d
  77.  
  78.  
  79.     #méthode pour la création d'un CSV qui indique l'état actuelle des voitures de la compagnies
  80.     #ce n'est fort probablement pas optimal, mais c'est fonctionnel
  81.     def CSVstatus(self):
  82.         with open(r'csvstatus.csv', 'wb') as file: #création du fichier CSV
  83.             csvwriter = csv.writer(file, delimiter=',')
  84.             status = [] #liste des éléments à inclure par ligne du CSV
  85.             csvline= [] #fusion des éléments de status pour l'ajout d'une rangée simple
  86.             for d in self.listDrivers:
  87.                 for c in self.listCars: #on parcours la liste des conducteurs et des voitures
  88.                     if d[3] == c[0]: #si le id de la voiture correspond à l'id de voiture du chauffeur
  89.                         status.append(c[0]) #ajout de l'id
  90.                         status.append(c[5]) #ajout de la longitude
  91.                         status.append(c[6]) #ajout de la latitude
  92.                         status.append(d[0]) #ajout du prénom du conducteur
  93.                         status.append(d[1]) #ajout du nom du chauffeur
  94.                         status.append(c[1]) #ajout de la marque de la voiture
  95.                         status.append(c[2]) #ajout du modèle de la voiture
  96.                         status.append(c[7]) #ajout du status d'occupation de la voiture
  97.                         csvline.append(status)  #ajout de l'ensemble des informations en une seule liste
  98.                         csvwriter.writerow(csvline) #ajout de cette ligne dans le csv
  99.                         del status[:]   #on supprime status et csvline afin que les informations ne se répète pas à chaque nouvelle ligne
  100.                         del csvline[:]
  101.  
  102.  
  103.     #méthode permettant le traitement des appels des clients de la compagnie
  104.     def CallClient(self,appel): #où appel est le numéro initial de l'appel. On le met à 1 par défaut ou si c'est le début d'une nouvelle journée
  105.  
  106.         print "*****APPEL CLIENT ENTRANT*****"  #message pour indiquer le début du processus
  107.  
  108.         lat_client = raw_input("Latitude de l'emplacement du client (ex.45.3936): ") #on demande à l'employé d'entrer l'emplacement du client
  109.         long_client = raw_input("Longitude de l'emplacement du client (ex.-71.9041): ")
  110.         adapt = raw_input("Besoin adapté (oui/non)?: ") #on demande si le transport doit être adapté
  111.         car_dispo = [] #liste des voitures actuellement dispoble
  112.         distclient = {} #dictionnaire qui a pour clé l'identifiant de la voiture et comme valeur de distance entre la voiture et le client
  113.  
  114.         #pour déterminer les voitures disponibles
  115.         for d in self.listCars: #en parcourant la liste des voitures
  116.             if int(d[7]) == 0: # on recherche le status d'occupation, où 0 stipule que la voiture n'est pas occupée
  117.                 if adapt.lower() == 'oui' and int(d[8]) == 1: #si le client indique que la voiture doit être adaptée, où 1 est le code indiquant une voiture adaptable
  118.                     car_dispo.append(d)#on l'ajoute à la liste des voitures disponibles
  119.  
  120.                 else:
  121.                     car_dispo.append(d) #si la voiture est libre et il n'y a pas de besoin d'adaptabilité, on fait simplement l'ajouter à la liste
  122.  
  123.         #pour établir la distance entre le client et une voiture
  124.         for r in car_dispo:
  125.             latCar = r[6] #emplacement de la voiture
  126.             longCar = r[5]
  127.             distclient[r[0]] = (haversine(lat_client, long_client, latCar, longCar)) #on inclue dans la formule de distance les paramètres entrés pour l'emplacement du client et celle de la voiture
  128.  
  129.         closestCar=sorted(distclient.iteritems(), key=lambda (k,v): (v,k)) #tri la distances des voitures de la plus près à la plus éloignée
  130.  
  131.         print " "
  132.         print "Id des trois voitures les plus proches (dans l'ordre):" #indique à l'employé les id des trois voitures les plus près du client
  133.         for i in closestCar[0:3]:
  134.             print i[0]
  135.  
  136.         action=raw_input("Id de la voiture à envoyer:") #l'employé peut sélectionné la voiture à envoyer
  137.  
  138.         #pour générer le message de confirmation de l'envoie de la voiture
  139.         for i in closestCar:
  140.             for y in self.listCars:
  141.                 for z in self.listDrivers:
  142.                     if action == y[0] and y[0] == z[3] and i[0]==y[0]:
  143.                         y[7] = 1 #pour convertir le status d'occupation de libre (0) à occupé (1) afin de ne pas resélectionner la voiture
  144.                         temps= float(i[1])*(50.0/60) #pour calculer le temps d'arrivée si on considère la vitesse moyenne de 50km/h
  145.                         print "Appel #%s: voiture %s %s, conduite par %s %s (distance à parcourir: %.2f km, arrivée dans %.1f minutes." % (appel, str(y[1]), str(y[2]), str(z[0]), str(z[1]), float(i[1]), float(temps))
  146.  
  147.         nextCall=raw_input("Autre appel à traiter (oui/non):") #on demande à l'employé s'il veut poursuivre
  148.  
  149.         while nextCall.lower() == 'oui':
  150.             print " "
  151.             appel+=1 #incrémentation du numéro de l'appel si on poursuit le traitement
  152.             self.CallClient(appel)  #on appelle à nouveau la méthode pour recommencer le traitement
  153.  
  154.         else:
  155.             print "Merci de travailler pour THE COMPANY!"  #message de cloture du programme d'appel
  156.             exit()
  157.  
  158.  
  159.     #méthode pour obtenir le nombre de voiture par model
  160.     def CarbyModel(self):
  161.         listModel= [] #liste des modèles de voiture
  162.         countdict={} #pour compter le nombre de voitures par modèle
  163.         for i in self.listCars:
  164.             if i[2] not in listModel:
  165.                 listModel.append(str(i[2])) #on ajoute le nom du modèle si celui-ci n'est pas déjà dans la liste de modèle
  166.  
  167.         for y in listModel:
  168.             for z in self.listCars:
  169.                 if y not in countdict:
  170.                     countdict[y] = 0 #si le modèle n'est pas déjà présent, on l'ajoute en tant que clé avec la valeur de 0
  171.  
  172.                 if y in z[2]:
  173.                     countdict[y] += 1 #si le modèle est présent à nouveau dans la liste de voiture, on ajoute 1 au compteur du modèle
  174.  
  175.         #message d'impression du résultat
  176.         print "Le nombre de voitures selon les modèles:"
  177.         for x in countdict:
  178.             print "%s : %d" % (x, countdict[x])
  179.         print " " #pour aérer les réponses
  180.  
  181.  
  182.     #méthode pour obtenir le nombre de voiture datant de chaque année
  183.     def CarbyYear(self):
  184.         listyear= [] #liste des années
  185.         countdict={} #pour compter le nombre d'année
  186.         for i in self.listCars:
  187.             if i[3] not in listyear:
  188.                 listyear.append(str(i[3])) #on ajoute l'année si celle-ci n'est pas dans la liste
  189.  
  190.         for y in listyear:
  191.             for z in self.listCars:
  192.                 if y not in countdict:
  193.                     countdict[y] = 0 #si l'année de la voiture n'est pas déjà présente, on l'ajoute en tant que clé avec la valeur de 0
  194.  
  195.                 if y in z[3]:
  196.                     countdict[y] += 1 #si l'année est présente à nouveau dans la liste , on ajoute 1 au compteur de l'année
  197.  
  198.         # message d'impression du résultat
  199.         print "Le nombre de voitures selon les années:"
  200.         for x in countdict:
  201.             print "%s : %d" % (x, countdict[x])
  202.         print " "  # pour aérer les réponses
  203.  
  204.  
  205.     #méthode pour obtenir le nombre de voitures libres ou occupées
  206.     def StatusCar(self):
  207.         libre=0
  208.         occupe=0
  209.         for i in self.listCars:
  210.             if int(i[7]) == 0:
  211.                 libre += 1
  212.             if int(i[7]) == 1:
  213.                 occupe+= 1
  214.  
  215.         #message d'impression du résultat
  216.         print "Il y a actuellement %d voitures libres et %d voitures occupées." % (libre, occupe)
  217.         print " "  # pour aérer les réponses
  218.  
  219.  
  220.     #méthode pour obtenir le nombre de voiture conduites par des femmes selon le modèle
  221.     def CarFemme(self):
  222.         listModel = []
  223.         countdict = {}
  224.         for i in self.listCars:
  225.             if i[2] not in listModel:
  226.                 listModel.append(str(i[2])) #on ajoute le modèle s'il n'est pas déjà présent dans la liste
  227.  
  228.         for y in listModel:
  229.             for z in self.listCars:
  230.                 for w in self.listDrivers:
  231.                     if y not in countdict:
  232.                         countdict[y] = 0  #si le modèle de la voiture n'est pas déjà présent, on l'ajoute en tant que clé avec la valeur de 0
  233.  
  234.                     if y == z[2] and z[0] == w[3] and w[2] == 'F':
  235.                         countdict[y] += 1  #si le modèle est dans la liste, que l'id de la voiture correspond à celle du conducteur et que le conducteur est une femme, on incrémente le compteur
  236.  
  237.         # message d'impression du résultat
  238.         print "Le nombre de voiture conduites par des femmes selon le modèle:"
  239.         for x in countdict:
  240.             print "%s : %d" % (x, countdict[x])
  241.         print " "  # pour aérer les réponses
  242.  
  243.  
  244.     # méthode pour obtenir le nombre de voiture conduites par des hommes selon le modèle
  245.     def CarHomme(self):
  246.         listModel = []
  247.         countdict = {}
  248.         for i in self.listCars:
  249.             if i[2] not in listModel:
  250.                 listModel.append(str(i[2]))#on ajoute le modèle s'il n'est pas déjà présent dans la liste
  251.  
  252.         for y in listModel:
  253.             for z in self.listCars:
  254.                 for w in self.listDrivers:
  255.                     if y not in countdict:
  256.                         countdict[y] = 0  #si le modèle de la voiture n'est pas déjà présent, on l'ajoute en tant que clé avec la valeur de 0
  257.  
  258.                     if y == z[2] and z[0] == w[3] and w[2] == 'M':
  259.                         countdict[y] += 1 #si le modèle est dans la liste, que l'id de la voiture correspond à celle du conducteur et que le conducteur est un homme, on incrémente le compteur
  260.  
  261.         # message d'impression du résultat
  262.         print "Le nombre de voiture conduites par des hommes selon le modèle:"
  263.         for x in countdict:
  264.             print "%s : %d" % (x, countdict[x])
  265.         print " "  # pour aérer les réponses
  266.  
  267.  
  268.     #méthode qui permet d'appeler d'un coup l'ensemble des méthodes statistiques, pour chaque méthode appelée, voir description ci-haut
  269.     def StatsCars(self):
  270.         print "**********STATISTIQUES:**********"
  271.         self.CarbyModel()
  272.         self.CarbyYear()
  273.         self.StatusCar()
  274.         self.CarFemme()
  275.         self.CarHomme()
  276.  
  277.  
  278.  
  279.  
  280. class Car: #classe qui permet de gérer l'entité Car et qui va permettre de gérer l'information des voitures
  281.  
  282.     def __init__(self, id, brand, model): #contructeur de Car pour créer une voiture
  283.         self.id = id #id de la voiture
  284.         self.brand = brand #marque
  285.         self.model = model #modèle de la voiture
  286.         self.year = 1900 #année
  287.  
  288.  
  289.  
  290. class Driver: #classe qui permet de gérer l'entité Driver et qui va permettre de gérer l'information des conducteurs
  291.  
  292.     def __init__(self, firstName, lastName, sex): #contructeur de Driver pour créer un conducteur
  293.         self.firstName = firstName #prénom
  294.         self.lastName = lastName #nom de famille
  295.         self.sex = sex #sexe (F/H)
  296.  
  297.  
  298.     #méthode qui permet l'assignation d'un id de voiture à un conducteur
  299.     def setCarId(self, id):
  300.         self.carId = id #où id est l'identifiant de la voiture
  301.  
  302.  
  303.  
  304.  
  305.  
  306. #################### EXEMPLE D'EXÉCUTION #######################
  307.  
  308. thecompany = Company("THE COMPANY")    #le nom que l'on attribue à la compagnie, ici très originalement inspiré de la série télévisé Heroes
  309. thecompany.addCarByCSV('C:\\Users\\mydar\\Downloads\\cars.csv') # où le chemin peut être modifié en fonction de l'emplacement du csv des voitures
  310. thecompany.addDriverByCSV('C:\\Users\\mydar\\Downloads\\drivers.csv') #où le chemin peut être modifié en fonction de l'emplacement du csv des conducteurs
  311. thecompany.StatsCars() #pour afficher d'un coup l'ensemble des statistiques
  312. thecompany.CallClient(1)    #où on appelle la méthode pour traiter les appels
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319. #RÉSULTATS DES APPELS DU TD
  320. '''
  321. *****APPEL CLIENT ENTRANT*****
  322. Latitude de l'emplacement du client (ex.45.3936): 45.542969
  323. Longitude de l'emplacement du client (ex.-71.9041): -73.610119
  324. Besoin adapté (oui/non)?: non
  325. Id des trois voitures les plus proches (dans l'ordre):
  326. 295
  327. 152
  328. 67
  329.  
  330. Id de la voiture à envoyer:295
  331. Appel #1: voiture Toyota Camry hybrid, conduite par Laurence Poulin (distance à parcourir: 1.53 km, arrivée dans 1.3 minutes.
  332. Autre appel à traiter (oui/non):oui
  333.  
  334. *****APPEL CLIENT ENTRANT*****
  335. Latitude de l'emplacement du client (ex.45.3936): 45.538280
  336. Longitude de l'emplacement du client (ex.-71.9041): -73.670715
  337. Besoin adapté (oui/non)?: non
  338. Id des trois voitures les plus proches (dans l'ordre):
  339. 253
  340. 219
  341. 88
  342.  
  343. Id de la voiture à envoyer:253
  344. Appel #2: voiture Honda Accord, conduite par Arthur Nelson (distance à parcourir: 0.62 km, arrivée dans 0.5 minutes.
  345. Autre appel à traiter (oui/non):oui
  346.  
  347. *****APPEL CLIENT ENTRANT*****
  348. Latitude de l'emplacement du client (ex.45.3936): 45.542367
  349. Longitude de l'emplacement du client (ex.-71.9041): -73.638443
  350. Besoin adapté (oui/non)?: oui
  351. Id des trois voitures les plus proches (dans l'ordre):
  352. 194
  353. 347
  354. 121
  355.  
  356. Id de la voiture à envoyer:194
  357. Appel #3: voiture Honda Accord, conduite par Olivia Simard (distance à parcourir: 0.82 km, arrivée dans 0.7 minutes.
  358. Autre appel à traiter (oui/non):oui
  359.  
  360. *****APPEL CLIENT ENTRANT*****
  361. Latitude de l'emplacement du client (ex.45.3936): 45.551744
  362. Longitude de l'emplacement du client (ex.-71.9041): -73.606514
  363. Besoin adapté (oui/non)?: oui
  364. Id des trois voitures les plus proches (dans l'ordre):
  365. 152
  366. 123
  367. 108
  368.  
  369. Id de la voiture à envoyer:152
  370. Appel #4: voiture Hyundai Elantra, conduite par Édouard Collins (distance à parcourir: 0.85 km, arrivée dans 0.7 minutes.
  371.  
  372. *****APPEL CLIENT ENTRANT*****
  373. Autre appel à traiter (oui/non):oui
  374. Latitude de l'emplacement du client (ex.45.3936): 45.570975
  375. Longitude de l'emplacement du client (ex.-71.9041): -73.636726
  376. Besoin adapté (oui/non)?: non
  377. Id des trois voitures les plus proches (dans l'ordre):
  378. 171
  379. 232
  380. 87
  381.  
  382. Id de la voiture à envoyer:171
  383. Appel #5: voiture Kia Cerato, conduite par Naomie Pérez (distance à parcourir: 0.85 km, arrivée dans 0.7 minutes.
  384. Autre appel à traiter (oui/non):oui
  385.  
  386. *****APPEL CLIENT ENTRANT*****
  387. Latitude de l'emplacement du client (ex.45.3936): 45.547176
  388. Longitude de l'emplacement du client (ex.-71.9041): -73.666595
  389. Besoin adapté (oui/non)?: non
  390. Id des trois voitures les plus proches (dans l'ordre):
  391. 88
  392. 121
  393. 64
  394.  
  395. Id de la voiture à envoyer:88
  396. Appel #6: voiture Kia Rondo, conduite par Ariane Lee (distance à parcourir: 1.22 km, arrivée dans 1.0 minutes.
  397. Autre appel à traiter (oui/non):non
  398.  
  399. Merci de travailler pour THE COMPANY!
  400.  
  401. Process finished with exit code 0
  402. '''
Advertisement
Add Comment
Please, Sign In to add comment