La fonction input avec un fichier txt ou csv
Bonjour à tous,
Mon code génère plusieurs points à partir d'une source de 4 points dans une emprise définie et me récupère les coordonnées x,y dans un fichier CSV.
Je voudrais généraliser ce code en demandant avec la fonction input les paramètres du programme, à savoir :
- les 4 coordonnées sources
- l'emprise du projet (x,y) et (A,B).
Pour le moment, les 4 coordonnées sources sont dans un fichier texte et l'emprise du projet est dans un fichier texte.
Voila le code :
import matplotlib.pyplot def equdroite(x0, y0, x1, y1): a = y1 - y0 b = x0 - x1 c = -(b * y0 + a * x0) # print("verif00:",sign(x0,y0,a,b,c),sign(x1,y1,a,b,c)) return a, b, c def inside(Poly, p): for P in Poly: a, b, c, s, x, y = P[0], P[1], P[2], P[3], pp[0], pp[1] if s * sign(x, y, a, b, c) < 0: # print("outside:",a,b,c,s,x,y) return False return True def sign(x, y, a, b, c): return a * x + b * y + c # Les 4 coordonnées sources (x, y) = ([325010, 325015, 325015, 325010], [2077560, 2077560, 2077555, 2077555]) # x = [325010, 325015, 325015, 325010, 325010] # y = [2077560, 2077560, 2077555, 2077555, 2077560] sg = 5 # L'emprise du projet (A, B) = ([324989.345, 324987.133, 324987.502, 325037.452, 325035.977, 324989.345], [2077586.246, 2077553.622, 2077537.955, 2077537.402, 2077589.933, 2077586.246]) # A = [324989.345, 324987.133, 324980, 325037.452, 325035.977, 324989.345] # B = [2077586.246, 2077553.622, 2077800, 2077537.402, 2077589.933, 2077586.246] # avgA,avgB=sum(A)/len(A),sum(B)/len(B) # # print ("avg:",avgA,avgB) # A=[x-avgA for x in A] # B=[x-avgB for x in B] # x=[x-avgA for x in x] # y=[x-avgB for x in y] nc = len(A) - 1 E = [] for p0 in range(nc): p1 = (p0 + 1) % nc p2 = (p0 + int(nc / 2)) % nc a, b, c = equdroite(A[p0], B[p0], A[p1], B[p1]) s = sign(A[p2], B[p2], a, b, c) # print("inloop:",p0,a,b,c,s) E.append([a, b, c, s, p0, p1]) # print("E:",E) for p in range(nc): for C in E: if p != C[4] and p != C[5]: a, b, c, s, xp, yp = C[0], C[1], C[2], C[3], A[p], B[p] v = sign(xp, yp, a, b, c) if s * v < 0: # print("outside:",a,b,c,s,xp,yp) print("OUPS!", s, v) matplotlib.pyplot.plot(A, B) matplotlib.pyplot.scatter(x, y, color="r") matplotlib.pyplot.axis("equal") matplotlib.pyplot.grid() phg = (int(min(A) / sg) * sg, int(min(B) / sg) * sg) pbd = (int(max(A) / sg + 1) * sg, int(max(B) / sg + 1) * sg) nrow = int((pbd[0] - phg[0]) / sg) + 1 ncol = int((pbd[1] - phg[1]) / sg) + 1 # print(phg) # print(nrow,ncol) prouge = [] for row in range(nrow): for col in range(ncol): pp = (phg[0] + sg * row, phg[1] + sg * col) if inside(E, pp): prouge.append(pp) xrouge = [ppp[0] for ppp in prouge] yrouge = [ppp[1] for ppp in prouge] matplotlib.pyplot.scatter(xrouge, yrouge, color="g") matplotlib.pyplot.scatter(x, y, color="r") with open("coordout.csv", "w") as f: print("X;Y", file=f) for xrouge, yrouge in prouge: print(f"{xrouge};{yrouge}", file=f) matplotlib.pyplot.show()
D'avance merci
- La fonction input avec un fichier txt ou csv
- Comment réduire la taille d'un fichier - Guide
- Fichier bin - Guide
- Comment ouvrir un fichier epub ? - Guide
- Fonction si ou - Guide
- Fichier rar - Guide
13 réponses
Bonjour
A priori le code devrait ressembler à ceci :
from tkinter import filedialog def prompt_filename(title="Sélectionner le fichier source"): return filedialog.askopenfilename( initialdir="/", title="Sélectionner le fichier source", filetypes=( ("Fichier texte", "*.txt"), ("Fichier csv", "*.csv") ) ) def read_coords(f_coords): coords = list() for line in f_coords: print(line.strip()) # ... return coords def read_emprise(f_emprise): emprise = ... for line in f_emprise: print(line.strip()) # ... return emprise filename_coords = prompt_filename("Sélectionner le fichier de coordonnées") with open(filename_coords, "r") as f_coords: coords = read_coords(f_coords) filename_emprise = prompt_filename("Sélectionner le fichier de l'emprise") with open(filename_emprise, "r") as f_coords: coords = read_emprise(f_coords) # ...
Bonne chance
bonjour, tu te demandes comment lire des données dans un fichier?
Bonjour yb_be c'est à peu près cela. J'aimerais, en exécutant le code, voir la fonction input qui me demande de saisir le fichier du fichier texte contenant les 4 coordonnées, ainsi que celui de l'emprise du projet, puis qu'il continue l'exécution du code.
Merci
Bonjour voila le code que je voudrais inserer cependant j'arrive pas bien faire.
Ou c'est pas la bonne methode , je suis perdu
# Les 4 coordonnées sources filename = filedialog.askopenfilename(initialdir="/", title="selectionner le fichier source", filetypes=(("fichier texte", "*.txt"), ("fichier csv", "*.csv"))) (x, y) = filename # x = [325010, 325015, 325015, 325010, 325010] # y = [2077560, 2077560, 2077555, 2077555, 2077560] sg = 5
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionTous les import sont faits et je pense que le code est complet.
Quand j'ajoute la fonction os.popen(filename) le fichier s'ouvre .
Je reçois l'erreur:
TypeError: read expected 2 arguments, got 1
Le code complet:
import os from tkinter import filedialog import matplotlib.pyplot def equdroite(x0, y0, x1, y1): a = y1 - y0 b = x0 - x1 c = -(b * y0 + a * x0) # print("verif00:",sign(x0,y0,a,b,c),sign(x1,y1,a,b,c)) return a, b, c def inside(Poly, p): for P in Poly: a, b, c, s, x, y = P[0], P[1], P[2], P[3], pp[0], pp[1] if s * sign(x, y, a, b, c) < 0: # print("outside:",a,b,c,s,x,y) return False return True def sign(x, y, a, b, c): return a * x + b * y + c # Les 4 coordonnées sources filename = filedialog.askopenfilename(initialdir="/", title="selectionner le fichier source", filetypes=(("fichier texte", "*.txt"), ("fichier csv", "*.csv"))) (x, y) = filename # x = [325010, 325015, 325015, 325010, 325010] # y = [2077560, 2077560, 2077555, 2077555, 2077560] sg = 5 # L'emprise du projet (A, B) = ([324989.345, 324987.133, 324987.502, 325037.452, 325035.977, 324989.345], [2077586.246, 2077553.622, 2077537.955, 2077537.402, 2077589.933, 2077586.246]) # A = [324989.345, 324987.133, 324980, 325037.452, 325035.977, 324989.345] # B = [2077586.246, 2077553.622, 2077800, 2077537.402, 2077589.933, 2077586.246] # avgA,avgB=sum(A)/len(A),sum(B)/len(B) # # print ("avg:",avgA,avgB) # A=[x-avgA for x in A] # B=[x-avgB for x in B] # x=[x-avgA for x in x] # y=[x-avgB for x in y] nc = len(A) - 1 E = [] for p0 in range(nc): p1 = (p0 + 1) % nc p2 = (p0 + int(nc / 2)) % nc a, b, c = equdroite(A[p0], B[p0], A[p1], B[p1]) s = sign(A[p2], B[p2], a, b, c) # print("inloop:",p0,a,b,c,s) E.append([a, b, c, s, p0, p1]) # print("E:",E) for p in range(nc): for C in E: if p != C[4] and p != C[5]: a, b, c, s, xp, yp = C[0], C[1], C[2], C[3], A[p], B[p] v = sign(xp, yp, a, b, c) if s * v < 0: # print("outside:",a,b,c,s,xp,yp) print("OUPS!", s, v) matplotlib.pyplot.plot(A, B) matplotlib.pyplot.scatter(x, y, color="r") matplotlib.pyplot.axis("equal") matplotlib.pyplot.grid() phg = (int(min(A) / sg) * sg, int(min(B) / sg) * sg) pbd = (int(max(A) / sg + 1) * sg, int(max(B) / sg + 1) * sg) nrow = int((pbd[0] - phg[0]) / sg) + 1 ncol = int((pbd[1] - phg[1]) / sg) + 1 # print(phg) # print(nrow,ncol) prouge = [] for row in range(nrow): for col in range(ncol): pp = (phg[0] + sg * row, phg[1] + sg * col) if inside(E, pp): prouge.append(pp) xrouge = [ppp[0] for ppp in prouge] yrouge = [ppp[1] for ppp in prouge] matplotlib.pyplot.scatter(xrouge, yrouge, color="g") matplotlib.pyplot.scatter(x, y, color="r") with open("coordout.csv", "w") as f: print("X;Y", file=f) for xrouge, yrouge in prouge: print(f"{xrouge};{yrouge}", file=f) matplotlib.pyplot.show()
Bonjour,
filename est le nom du fichier que tu sélectionnes avec la boite de dialogue askopenfilename
donc (x,y) = filename c'est bizarre
C'est comme si on faisait (x,y) = 'toto.txt'
Bonjour,
J'espère que tu as bien compris que filename = filedialog.askopenfilename(...)
te rend le nom du fichier que tu as choisi dans la boite de dialogue ? ???
Donc une fois que tu as ce nom, il faut ouvrir le fichier en lecture (mais pas avec os.popen)
et y lire les 2 valeurs de x et y
Tu sais faire ça, au moins ?
Sinon, tu peux jeter un œil ici:
https://pythonforge.com/lire-ou-ecrire-dans-un-fichier-avec-python/
Bonsoir voila ce que j'ai fais comme code mais hélas.
J'obtient l'erreur:
(x, y) = contenu
ValueError: too many values to unpack (expected 2)
325010, 325015, 325015, 325010 2077560, 2077560, 2077555, 2077555
# Les 4 coordonnées sources Coordsources = filedialog.askopenfilename(initialdir="/", title="selectionner le fichier", filetypes=(("fichier texte", "*.txt"), ("fichier csv", "*.csv"))) # print(Coordsources) (z) = open(Coordsources, "r") contenu = z.read() print(contenu) (x, y) = contenu z.close()
Bonsoir, tu tentes de faire
>>> x, y = 'blablabla, bla, bla, bla' Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: too many values to unpack (expected 2)
Forcément, ça ne fonctionne pas.
Ton fichier contient une chaîne de liste de valeurs, du dois donc :
- Séparer chaque valeurs de ce str par la virgule pour en obtenir une liste de str
- Convertir chacune de ces valeurs en entier
Faire cela est aisé.
Bonjour,
Non seulement il faut convertir en entier, mais il faut aussi qu'il n'y ait que 2 valeurs dans la liste:
x,y = (10,20,30) ValueError: too many values to unpack (expected 2) : trop de valeurs a récupérer (2 attendues)
Bonsoir à tous,
Merci pour vos réactions. Mamiemando, votre code #19 répond à mes attente, il fonctionne très bien.
Cependant j'ai aussi trouvé cet code qui marche aussi en faisant des input :
x = [int(x) for x in input().split()]
J'ai encore une question.
Peut-on copier les valeurs de l'emprise pour ensuite les coller dans le fichier "coordout.csv" à l'emplacement "P1" de la feuille?
Bonjour LALO_5656,
Ta question #20 mériterait une nouvelle discussion car c'est un nouveau sujet. Dans les faits, ta question revient à mettre à jour un fichier CSV.
C'est un problème qui a déjà été posé sur le forum (par exemple ici, en utilisant pandas). Dans ton cas, inutile de sortir l'artillerie lourde, tu peux le faire "à la main". Il faut charger en mémoire le fichier csv (comme le fait par exemple la fonction read_coords dans #19), mettre à jour cette structure de données (dans ce que j'ai proposé, une liste), puis réécrire le fichier avec la ou les valeur(s) corrigée(s) à partir de cette structure de données.
Je n'ai pas compris ce que tu appelais les coordonnées P1 (je suppose que c'est le premier point listé dans le fichier ?). Idéalement il faudrait que tu donnes dans la discussion que tu vas ouvrir le fichier de départ et le fichier que tu aimerais obtenir.
Voici à quoi ça pourrait ressembler :
points.csv
0.0;2.2
2.2;5.5
5.5;6.6
6.6;0.0
script.py
import csv def read_points(f): reader = csv.reader(f, delimiter=';') return [[float(x) for x in point] for point in reader] def write_points(f, points): writer = csv.writer(f, delimiter=';') for point in points: writer.writerow(point) # Lecture des points with open("points.csv") as f: points = read_points(f) assert len(points) > 0 # Correction du premier point points[0] = [-1.1, -1.2] # Ecriture du fichier de points (on peut utiliser ou non le même fichier) with open("points.csv", "w") as f: write_points(f, points)
Résultat :
(mando@silk) (~) $ cat points.csv
0.0;2.2
2.2;5.5
5.5;6.6
6.6;0.0
(mando@silk) (~) $ python3 script.py
(mando@silk) (~) $ cat points.csv
-1.1;-1.2
2.2;5.5
5.5;6.6
6.6;0.0
Bonne chance