Partage
  • Partager sur Facebook
  • Partager sur Twitter

Mini-Projet ISN - Canon

Aide pour le code et avis sur la lisibilité du code

    9 janvier 2017 à 19:46:25

    Bonjour, bonsoir,

    Pour mon cours d'ISN, j'ai dû réaliser un programme qui représentait le tir d'un canon en fonction de l'angle alpha et de la vitesse initiale v0. Le canon est à 2 mètres de haut et tire un boulet.

    Le programme fonctionne mais il y a des bugs d'affichage. Par exemple, si on exécute le code (il est après), les messages d'erreur ne s'effacent pas, tout comme la trajectoire du boulet de canon ou comme les messages d'information. Donc à chaque tir, il y a une nouvelle trajectoire qui s'affiche sans effacer l'autre, même chose pour les messages d'informations (et éventuellement les messages d'erreurs, s'il y a une erreur).

    J'aimerais bien un code, ou des pistes de codes, pour pouvoir enlever les messages.

    De plus, la trajectoire du boulet est symbolisée par deux segments, un partant de l'origine de mon repère et allant jusqu'au sommet, et l'autre du sommet jusqu'à la zone d’atterrissage. Y aurait-il un moyen pour réaliser une parabole au lieu de deux segments ?

    Enfin, si vous avez des suggestions pour améliorer le code en lui-même, c'est-à-dire sa lisibilité, d'autres moyens plus courts et/ou plus efficace pour faire ce projets, n'hésitez pas !

    Voilà mon code :

    from math import *
    from random import *
    from tkinter import *
    
    def OnValidate(action, index, value_if_allowed, prior_value, text, validation_type, trigger_type, widget_name):
    	if (action == '1'):
    		if text in '0123456789.':
    			try:
    				float(value_if_allowed)
    				return True
    			except ValueError:
    				return False
    		else:
    			return False
    	else:
    		return True
    
    def dessiner():
    	"""Fonction traçant un repère et des cadres"""
    	
    	#On crée des lignes avec des fleches qui representent les axes d'un repère
    	abscisse = canvas.create_line(5, 345, 1095, 345, arrow="last")
    	ordonne = canvas.create_line(5, 5, 5, 345, arrow="first")
    	
    	#On fait des traits pour indiquer les coordonnées
    	for i in range(10):
    		#Axe des ordonnées
    		trait_ordonne = canvas.create_line(105+i*100, 350, 105+i*100, 340)
    		texte_ordonne = canvas.create_text(105+i*100, 335, text=str(100+i*100))
    		
    		#Axe des abscisse
    		trait_abscisse = canvas.create_line(0, 345-i*100, 10, 345-i*100)
    		texte_abscisse = canvas.create_text(20, 345-i*100, text=str(i*100))
    	
    	
    	#commande pour vérifier l'entrée de nombre
    	validatecmd = (fenetre.register(OnValidate), '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
    	
    	
    	#Création d'un cadre
    	frame1 = Frame(fenetre, borderwidth=2, relief=GROOVE)
    	frame1.pack(side=LEFT, padx=30, pady=30)
    	#Création d'un label
    	label_alpha = Label(frame1, text="Saisir alpha (entre 0 et 90) :")
    	label_alpha.pack(side=TOP)
    	
    	#Création d'une saisie de texte
    	global entree_alpha
    	#on vérifie que l'utilisateur entre bien un chiffre
    	entree_alpha = Entry(frame1, validate="key", vcmd=validatecmd)
    	entree_alpha.pack()
    	
    	#Même chose
    	frame2 = Frame(fenetre, borderwidth=2, relief=GROOVE)
    	frame2.pack(side=LEFT, padx=30, pady=30)
    	label_entree = Label(frame2, text="Saisir v0 (entre 0 et 100) :")
    	label_entree.pack(side=TOP)
    	
    	global entree_v0
    	entree_v0 = Entry(frame2, validate="key", vcmd=validatecmd)
    	entree_v0.pack()
    
    def message_erreur(message):
    	message_erreur = Label(fenetre, text=message, fg="red")
    	message_erreur.pack(side="bottom")
    		
    def Feu():
    	"""Fonction utilisée par le bouton Feu"""
    	
    	#Variables
    	try:
    		alpha = float(entree_alpha.get())
    		assert alpha > 0 and alpha < 90
    	except AssertionError:
    		#On vérifie que le caractère saisi ne soit pas trop grand ou trop petit, sinon on redemande
    		if alpha <= 0:
    			message_erreur("La valeur de alpha est trop petite")
    		elif alpha >= 90:
    			message_erreur("La valeur de alpha est trop grande")
    	else:
    		try:
    			v0 = float(entree_v0.get())
    			assert v0 > 0 and v0 <= 100
    		except AssertionError:
    			if v0 <= 0:
    				message_erreur("La valeur de v0 est trop petite")
    			elif v0 > 100:
    				message_erreur("La valeur de v0 est trop grande")
    		else:
    			alpha_rad = radians(alpha)
    			g = 9.81
    			
    			#Equation d'une parabole : y = ax² + bx + c
    			a = -(g / (pow(v0, 2) * pow(cos(alpha_rad), 2) ))/2
    			b = tan(alpha_rad)
    			c = 2		
    	
    			#Calcul de la racine positive
    			delta = pow(b, 2) - 4*a*c
    			x2 = (-b - sqrt(delta))/(2*a)
    
    			#Calcul des coordonnées du sommet
    			sommet_alpha = (-b)/(2*a)
    			sommet_beta = a*pow(sommet_alpha, 2) + b*sommet_alpha + c
    
    			# 'Parabole' avec deux traits
    			ligne1 = canvas.create_line(5, 345, 5 + sommet_alpha, 345 - sommet_beta, fill="red")
    			ligne2 = canvas.create_line(5 + sommet_alpha, 345 - sommet_beta, x2, 345, fill="red")
    			
    			#Cordonnée de l'atterrissage
    			atterrissage = canvas.create_text(x2 + 5, 345 - 20, text=str(int(x2)))
    			
    			ToucherCible(int(x2), d_cible)
    			
    def DistanceCible():
    	d = randint(1,1000) 
    	canvas.create_line(5 + d, 325, 5 + d, 340, arrow="last")
    	canvas.create_text(5 + d, 320, text="cible")
    		
    	return d		
    	
    def ToucherCible(atterrissageBoulet=0, d=0):
    	#Création de texte d'information
    	texte_atterissage = Label(cadre_info, text=("Le boulet est arrivé à {} mètres".format(atterrissageBoulet)))
    	texte_info_d = Label(cadre_info, text=("La cible est à {} mètres".format(d)))
    	texte_info_e = Label(cadre_info, text="")
    	
    	#Apparition des informations
    	texte_atterissage.pack()
    	texte_info_d.pack()
    	texte_info_e.pack()
    	
    	#Disparition des informations
    	#texte_atterissage.pack_forget()
    	#texte_info_d.pack_forget()
    	#texte_info_e.pack_forget()
    		
    	if atterrissageBoulet > d:
    		texte_info_e["text"] = "Vous avez tiré trop loin ! Saisissez une valeur d'angle de tir alpha et/ou une vitesse initiale plus petite !\nVous êtes a {} metres plus loin de la cible".format(abs(atterrissageBoulet - d))
    		
    		
    		
    	elif atterrissageBoulet < d:
    		texte_info_e["text"] = "Vous avez tiré trop près ! Saisissez une valeur d'angle de tir alpha et/ou une vitesse initiale plus grande !\nVous êtes a {} metres plus loin de la cible".format(abs(atterrissageBoulet - d))		
    	else:
    		texte_info_e["text"] = "Vous avez touché la cible !"
    		gagner = Button(fenetre, text="Fin", command=fenetre.quit)
    		gagner.pack()
    		
    		
    				
    			
    			
    #On crée une fenetre
    fenetre = Tk()
    
    #Configuration fenetre : taille, redimensionnabilité, titre
    fenetre.configure(width=1200, height=700)
    fenetre.resizable(width=False, height=False)
    fenetre.wm_title("Mini Projet Canon")
    
    #On crée un widget canvas d'une certaine taille et de couleur de fond ivoire
    canvas = Canvas(fenetre, width=1100, height=350, bg="ivory")
    #On affiche le canvas
    canvas.pack()			
    	
    #Dessine un repère
    dessiner()
    
    #Création d'un bouton de lancer
    bouton_mise_a_feu = Button(text='Feu !', command=Feu)
    bouton_mise_a_feu.pack()	
    
    #Recupère une valeur aléatoire
    d_cible = DistanceCible()
    
    #On crée un cadre d'information
    cadre_info = Frame(fenetre, borderwidth=2, relief=GROOVE)
    cadre_info.pack(side=LEFT, padx=30, pady=30)
    
    
    #dernière instruction du programme : enclenche la réception d'événements
    fenetre.mainloop()
    • Partager sur Facebook
    • Partager sur Twitter

    Mini-Projet ISN - Canon

    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
    • Editeur
    • Markdown