Comptebon.py

Soyez le premier à donner votre avis sur cette source.

Vue 3 800 fois - Téléchargée 226 fois

Description

Encore un "le compte est bon". Mais dans ce cas une classe permet
- de genérer aléatoirement le tirage, le but à atteindre
- de contrôler les opérations d'un utilisateur (élève du primaire).
Au lancement, une aide (succinte) est fournie.
Le développement utilisant pygame est en cours.

Source / Exemple :


#!/usr/bin/env python
# -*- coding: UTF-8 -*-

__author__ = u"André Connes <andre.connes at wanadoo.fr>"
__version__ = "10.02.12" # cad 12 février 2010
__copyright__ = "GPL le terrier <AbulEdu.org> "

# Usage : python compteBon.py
#   une aide initiale (succinte) indique ce qu'il faut faire.
# Cette classe génére une liste de nombres, un but et contrôle les réponses d'un
#   utilisateur (élève du primaire).
#   Cette classe sera utilisée dans une version graphique en préparation sous pygame

from random import randint
# from config import MIN, MAX, AUCHOIX, OPS
# ATTENTION : bien adapter MIN, MAX, AUCHOIX et OPS
MIN = 567	# but > MIN
MAX = 5678	# but < MAX
AUCHOIX = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 25, 50, 75, 100]
OPS = ["+", "-", "*", "/"]
#MIN = 234	# but > MIN
#MAX = 999	# but < MAX
#AUCHOIX = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 25, 50, 75, 100]
#OPS = ["+", "-", "*"]

class CompteBon:
	
	# le constructeur
	def __init__(self):
		self.tirage = []		# le tirage a lieu dans cette liste, sans doublon
		self.but = 0			# le nombre à trouver
		self.expressions = []	# calculs successifs générés pour définir le but

	# générer tirage, but et expressions
	def generer(self):		
		while 1:
			self.auChoix = AUCHOIX[:]
			self.tirage, self.but, self.expressions = [], 0, []			
			self._tirage()
			t = self._sous_tirage()
			while len(t) != 1:
				self._utiliser2nombres(t)	# calculs réalisés : met-à-jour expressions et t
			if MIN <= t[0] < MAX: break 
		self.but = t[0]

	# contrôler les réponses de l'élève-utilisateur		
	def resoudre(self):
		nombres = self.tirage[:]
		print "** ** ** ** ** But = %s ** ** ** ** **" % self.but

		while 1:
			print "Nombres à utiliser : %s" % nombres	
			try:
				ne = raw_input("    nouveau calcul : ")
				if ne == "n": break
				if ne == "h": help(); continue
				if ne == "s": print self.expressions; continue
				if   ne.find("+") >= 0: s = ne.split("+")
				elif ne.find("-") >= 0: s = ne.split("-")
				elif ne.find("*") >= 0: s = ne.split("*")
				elif ne.find("/") >= 0: s = ne.split("/")						
				m = map(int, s)
			except:
				print u"aîe, 'entier op entier' attendu"
				continue
		
			if not ((m[0] in nombres) and (m[1] in nombres)):
				print "Nombres dans la liste attendus"
				continue 
			 
			nombres.remove(m[0])
			nombres.remove(m[1])
			nombres.append(eval(ne))
	
			if self.but in nombres:
				print "Bravo, %s atteint !\n" % self.but
				break
			if len(nombres) == 1:
				print "Hélàs, c'est faux. Voici une solution : %s\n" % self.expressions
				break	
		
	#
	# méthodes protégées
	#
		
	# créer la liste 'tirage' des nombres à utiliser, sans doublon
	def _tirage(self):
		p = randint(6, 8)		# nombre de nombres proposés		
		for i in xrange(p):
			a = randint(0, len(self.auChoix)-1)	# tirage de l'index d'un nombre
			t = self.auChoix[a]					# valeur du tirage
			self.auChoix.remove(t)				# pour éviter les doublons
			self.tirage.append(t)				# un tirage de plus
		self.tirage.sort()	

	# sous_tirage pour générer le but (tous les nombres de cette liste seront utilisés)
	def _sous_tirage(self):
		t = self.tirage[:]
		for i in xrange(randint(1,3)):
			a = t[randint(0,len(t)-1)]
			t.remove(a)
		return t

	# choix d'une opération	
	def _op(self):
		n = randint(0,len(OPS)-1)
		return OPS[n]
		
	# vérifier que le calcul proposé est satisfisant (positif et entier)
	def _verification(self, n, op, ta, tb):
		if n <= 0: return False
		if op == "*": return (ta != 1) and (tb != 1)
		if op == "/":
			if tb == 1: return False
			else: return ta == tb * n
		return True

	# choisir 2 nombres du sous_tirage, effectuer le calcul
	def _utiliser2nombres(self,t):
		ok = False
		while not ok:
			op = self._op()
			a, b = 0, 0
			while a == b:
				a, b = randint(0, len(t)-1), randint(0, len(t)-1)
			ta, tb = t[a], t[b]				
			expression = str(ta)+op+str(tb)
			try:
				n = eval(expression)
			except:
				continue
			if self._verification(n, op, ta, tb):
				#print expression				
				t.remove(ta)
				t.remove(tb)
				t.append(n) 
				self.expressions.append(expression)
				ok = True
		return t		
	
def help():
	print "usage :"
	print ""
	print "  n pour un nouveau tirage"
	print "  s pour une solution (celle qui a engendré le but)"
	print "  h pour cette aide (help)"
	print ""
	print "  calculs successifs de la forme 'nombre opérateur nombre' puis valider"
	print ""
	print "Opérateurs disponibles : %s" % OPS
	print ""

############
# main
############
		
if __name__ == "__main__":
	
	help()
	onBoucle = True

	c = CompteBon()
	while onBoucle:	
		c.generer()
		c.resoudre()
		r = raw_input("On continue (O/n) ? ")
		onBoucle = not(r == "n" or r == "N")

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.