Permalink
Browse files

ajout d'un exercice sur scratch pour construire une pyramide

  • Loading branch information...
sdpython committed Apr 5, 2015
1 parent 262665e commit 751e4ba2bb147ca04f46080a27d412f583c9515f
@@ -1,4 +1,4 @@
.. blogpost::
.. blogpost::
:title: Expériences manuelles avec les enfants (Tinkerlab, Artful Parent)
:keywords: expérience, tinkerlab
:date: 2015-04-04
@@ -1,4 +1,4 @@
.. _l-glossary:
@@ -18,6 +18,8 @@ s'agit de manipuler, est accessible dès 6 ans (voir :ref:`l-difficulte`).
L'intégralité de ce contenu est accessible via
`github <https://github.com/sdpython/code_beatrix/>`_.
D'autres informations sont disponibles via le
:ref:`blog <ap-main-0>`.
Patchworks
@@ -124,6 +126,7 @@ Annexes
FAQ
index_et_autre
all_notebooks
blog/blogindex
Pour les plus chevronnés, certains bouts de codes en python
pourront être réutilisés via
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,94 @@
.. issue.
.. index:: énoncé, dessin, pyramide, scratch, programmation
.. _l-prog_dessin_pyramide:
Construire une pyramide de balles
=================================
A partir de 7 ans.
L'objectif de l'exercice est de dessin un motif, une pyramide dans ce cas, avec un programme.
Il faut bien comprendre comme le motif se répète.
Mise en scène
-------------
L'objectif est de dessiner la pyramide suivante avec Scratch :
.. image:: pyramide.png
Bien sûr, on ne veut pas le faire à la main.
Comme on n'est pas magicien, on n'a pas le pouvoir de les faire
apparaître tout en même temps mais une par une.
**Q1 ::** Est-il plus facile de commencer par en haut (la pointe)
ou par en bas (la base ?)
**Q2 :** Si on fait apparaître les balles une à une,
comment les numéroter ?
**Q3 :** Après coup, on s'aperçoit que numéroter les billes comme ça n'est pas évident pour la suite.
On préfèrerait les numéroter avec deux nombres qui indiquerait plus facilement leur position
dans l'image ? Que proposez-vous ?
Quelques précisions sur Scratch
-------------------------------
Pour faire appraître autant de balles qu'on veut comme par magie,
il faut utiliser les clones :
.. image:: clonesc.png
L'instruction de droite fait apparaître un clone, celle de gauche dit
ce qu'il faut faire lorsqu'elle celui-ci apparaît. L'inconvénient
majeur de ce système est qu'après plusieurs exécutions,
l'écran contient une multitude de clones. Il faut donc les supprimer
au début de chaque exécution. Pour ce faire, on envoie un message
*supprime_clone* à tous les clones qui doivent disparaître lorsqu'ils le reçoivent.
.. image:: clonemes.png
Ensuite, afin de ne pas trop hésiter au début du programme, il paraît
difficile d'éviter l'utilisation des variables.
.. image:: pyramide_debut.png
Parmi les six variables créées, deux ne changent jamais *sx*, *sy*,
elles représentent la taille des balles.
**Q4 :** Mais pourquoi avoir créé deux variables *i*, *j* qui augmentent de 1 en 1
et deux autres *x*, *y* qui augmente de *sx* et *sy* ?
Exercice 1
----------
Il ne reste plus qu'à terminer le programme avec Scratch. On pourra compléter
le projet suivant :
:download:`echiquier0.sb2 <../../../../src/code_beatrix/scratchs/example_echiquier/echiquier0.sb2>`.
Solution
--------
Voir :ref:`l-prog_dessin_pyramide_sol`.
A quoi ça sert ?
----------------
Cet exercice est assez semblable à celui proposé dans
:ref:`l-prog_parcours_echiquier`. Il faut décrire de façon précise
le parcours d'une pyramide.
Ces façons de faire nous paraissent plutôt évidente.
Pourtant, leur traduction en un programme informatique
l'est un peu moins. A quoi pensait `Descartes <http://fr.wikipedia.org/wiki/Ren%C3%A9_Descartes>`_
quand il a inventé le `système cartésien <http://fr.wikipedia.org/wiki/Coordonn%C3%A9es_cart%C3%A9siennes>`_ ?
Programmer, c'est un peu penser en cartésien et un peu moins en géométrique.
@@ -0,0 +1,75 @@
.. issue.
.. index:: solution, dessin, pyramide, scratch, programmation
.. _l-prog_dessin_pyramide_sol:
Construire une pyramide de balles (solution)
============================================
**Q1 :**
Il est plus facile de commencer par le haut et de fait grandir la pyramide
jusqu'en bas. De cette façon, on peut créer des pyramides aussi grandes qu'on veut.
Dans l'autre sens, la taille de la base détermine la taille finale de la pyramide
avant qu'on l'ait terminée.
**Q2 :**
D'après la question précédente, il est préférable de commencer par le haut.
La premier balle porte le numéro 1 et est celle du haut. Ensuite,
un continue la numérotation en parcourant chaque ligne.
.. image:: pyramide_num.png
De cette façon, on peut toujours agrandir la pyramide.
Ce n'est pas le cas si on part vers le bas pour numéroter.
**Q3 :**
Le numéro de chaque balle n'indique pas sur quelle ligne elle se
trouve. On va s'en changer cela.
.. image:: pyramide_num2.png
**Q4 :**
Lorsqu'on regarde la seconde numérotation de chaque balle, on s'aperçoit
que le premier numéro indique la ligne, le second la position de la balle
sur cette ligne. Le problème est que ces deux nombres simples n'ont aucun
rapport avec la position de la balle dans l'écran de Scratch.
C'est pour cela qu'on fait la distinction entre la numérotation à deux chiffres
de la balle et ses coordonnées sur l'écran de Scratch.
Si on note :math:`x_0` et :math:`y_0`, on obtient comme relation entre les deux :
.. math::
x = x_0 + j * sx + i * sx/2
y = y_0 - i * sy
Passer d'un système de numérotation (donc des coordonnées) au système
de coordonnées de l'écran n'est pas toujours évident.
Exercice 1
----------
L'astuce est de remarquer que, sur la ligne 1, il y a une balle,
sur la ligne 2, il y a deux balles, et ainsi de suite :
sur la ligne *i*, il y *i* balles.
La solution est illustrée par :
.. image:: pyramide_solution.png
Et le programme à exécuter est le suivant :
:download:`echiquier.sb2 <../../../../src/code_beatrix/scratchs/example_echiquier/echiquier.sb2>`.
@@ -1,5 +1,5 @@
.. issue.
.. _l-programmation:
@@ -47,6 +47,7 @@ Sujets
:maxdepth: 1
parcours_echiquier
dessin_pyramide
tri_scratch
@@ -57,9 +58,9 @@ Indices et solutions
:maxdepth: 1
parcours_echiquier_correction
dessin_pyramide_correction
tri_scratch_correction
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,93 @@
"""
@brief test log(time=4s)
@author Xavier Dupre
"""
import sys
import os
import unittest
from docutils.parsers.rst import directives
try:
import src
except ImportError:
path = os.path.normpath(
os.path.abspath(
os.path.join(
os.path.split(__file__)[0],
"..",
"..")))
if path not in sys.path:
sys.path.append(path)
import src
try:
import pyquickhelper
except ImportError:
path = os.path.normpath(
os.path.abspath(
os.path.join(
os.path.split(__file__)[0],
"..",
"..",
"..",
"pyquickhelper",
"src")))
if path not in sys.path:
sys.path.append(path)
import pyquickhelper
from pyquickhelper import fLOG, get_temp_folder
from pyquickhelper.helpgen import BlogPost, BlogPostList, BlogPostDirective
class TestBlogHelper(unittest.TestCase):
def test_post_parse(self):
fLOG(
__file__,
self._testMethodName,
OutputPrint=__name__ == "__main__")
directives.register_directive("blogpost", BlogPostDirective)
path = os.path.abspath(os.path.split(__file__)[0])
file = os.path.join(path, "..", "..", "_doc", "sphinxdoc",
"source", "blog", "2015", "2015-04-04_tinkerlab.rst")
p = BlogPost(file)
fLOG(p.title)
assert len(p.title) > 0
assert p.date == "2015-04-04"
assert isinstance(p.Fields, dict)
def test_post_list(self):
fLOG(
__file__,
self._testMethodName,
OutputPrint=__name__ == "__main__")
directives.register_directive("blogpost", BlogPostDirective)
path = os.path.abspath(os.path.split(__file__)[0])
fold = os.path.join(
path, "..", "..", "_doc", "sphinxdoc", "source", "blog")
assert os.path.exists(fold)
out = get_temp_folder(__file__, "temp_post_list")
p = BlogPostList(fold)
cats = p.get_categories()
fLOG(cats)
months = p.get_months()
fLOG(months)
assert len(p) > 0
assert len(cats) > 0
assert len(months) > 0
res = p.write_aggregated(out)
assert len(res) >= 4
for r in res:
assert os.path.exists(r)
if __name__ == "__main__":
unittest.main()
View
@@ -85,8 +85,9 @@
packages = find_packages('src', exclude='src')
package_dir = {k: "src/" + k.replace(".", "/") for k in packages}
package_data = {project_var_name + ".scratch.example_echiquier": ["*.sc2"],
project_var_name + ".scratch.example_tri": ["*.sc2"],
package_data = {project_var_name + ".scratch.example_echiquier": ["*.sb2"],
project_var_name + ".scratch.example_tri": ["*.sb2"],
project_var_name + ".scratch.example_pyramide": ["*.sb2"],
}
if os.path.exists(readme):
@@ -6,6 +6,7 @@
from .example_echiquier import check_echiquier
from .example_tri import check_tri
from .example_pyramide import check_pyramide
def check():
@@ -14,3 +15,4 @@ def check():
"""
check_echiquier()
check_tri()
check_pyramide()
@@ -0,0 +1,16 @@
"""
basic checking
"""
def check_pyramide():
"""
basic checkings
"""
dirname = os.path.dirname(__file__)
f1 = os.path.exists(dirname, "pyramide.sb2")
if not os.path.exists(f1):
raise FileNotFoundError(f1)
f0 = os.path.exists(dirname, "pyramide0.sb2")
if not os.path.exists(f0):
raise FileNotFoundError(f0)
Binary file not shown.
Binary file not shown.

0 comments on commit 751e4ba

Please sign in to comment.