# PyLogo

# Exemple de primitives logo imlémentées

\- https://turing.cs.hbg.psu.edu/LOCAL/ucblogo/ucbl\_7.htm  
\- https://fmslogo.sourceforge.io/manual/workspace-control.html  
\- https://www.calormen.com/jslogo/language.html

The section numbers are per the [Berkeley Logo Reference Manual](https://www.cs.berkeley.edu/~bh/v2ch14/manual.html) in Brian Harvey's <cite>Computer Science Logo Style volume 2: Advanced Techniques</cite> for ease of comparison.

<div id="bkmrk-data-types-and-synta">1. [Data Types and Syntax](https://www.calormen.com/jslogo/language.html#types)
2. [Data Structure Primitives](https://www.calormen.com/jslogo/language.html#sec2)
3. [Communication](https://www.calormen.com/jslogo/language.html#sec3)
4. [Arithmetic](https://www.calormen.com/jslogo/language.html#sec4)
5. [Logical Operations](https://www.calormen.com/jslogo/language.html#sec5)
6. [Graphics](https://www.calormen.com/jslogo/language.html#sec6)
7. [Workspace Management](https://www.calormen.com/jslogo/language.html#sec7)
8. [Control Structures](https://www.calormen.com/jslogo/language.html#sec8)

</div>### Data Types and Syntax

<div id="bkmrk-%22word-%27word-number-w"><dl><dt>`"<var>word</var>`</dt><dt>`'<var>word</var>`</dt><dt>`<var>number</var>`</dt><dd>Word. (Quoted words are terminated by \[\](){} or whitespace, \\ to escape.)</dd><dd class="example" title="Click to try this example">show "hello</dd><dd class="example" title="Click to try this example">show "hello\\ logo</dd><dd class="example" title="Click to try this example">show 12.34</dd><dt>`:<var>variable</var>`</dt><dd>Input definition/variable reference</dd><dd class="example" title="Click to try this example">show :name</dd><dt>`[ <var>word ...</var> ]`</dt><dd>List of words or lists, whitespace separated</dd><dd class="example" title="Click to try this example">show \[1 2 3\]</dd><dt>`{ <var>word ...</var> }`</dt><dt>`{ <var>word ...</var> }@<var>origin</var>`</dt><dd>Array of words, whitespace separated</dd><dd class="example" title="Click to try this example">show {1 2 3}</dd><dt>` ( <var>expression</var> )`</dt><dd>Parenthesis can be used to group expressions</dd><dd class="example" title="Click to try this example">show ( 1 + 2 ) \* 3</dd><dt>`<var>procedure</var> <var>input</var> ...`</dt><dd>Call procedure with default number of inputs</dd><dd class="example" title="Click to try this example">show "hello</dd><dt>` ( <var>procedure</var> <var>input</var> ... )`</dt><dd>Call procedure with an arbitrary number of inputs</dd><dd class="example" title="Click to try this example">(show "hello :name)</dd></dl></div>### 2. Data Structure Primitives

#### 2.1 Constructors

<div id="bkmrk-word-expr-expr-%28word"><dl><dt>`word <var>expr</var> <var>expr</var>`</dt><dt>`(word <var>expr</var> <var>...</var>)`</dt><dd>Concatenate two (or more) words into one word</dd><dd class="example" title="Click to try this example">show (word "a "b "c)</dd><dt>`list <var>thing1</var> <var>thing2</var>`</dt><dt>`(list <var>thing1</var> <var>thing2</var> ...)`</dt><dd>Create a new list from the inputs</dd><dd class="example" title="Click to try this example">show (list 1+2 2+3 3+4)</dd><dt>`sentence thing1 thing2`</dt><dt>`(sentence thing1 thing2 ...)`</dt><dt>`se thing1 thing2`</dt><dt>`(se thing1 thing2 ...)`</dt><dd>Create a new list from the inputs (if non-lists) or members of the inputs (if lists)</dd><dd class="example" title="Click to try this example">show sentence \[1 2 3\] \[and so on\]</dd><dt>`fput <var>thing</var> <var>list</var>`</dt><dt>`lput <var>thing</var> <var>list</var>`</dt><dd>Outputs list, but with thing added as a new first/last item; if list is a word, concatenates</dd><dd class="example" title="Click to try this example">show fput 0 \[ 1 2 3 \]</dd><dd class="example" title="Click to try this example">show fput "a "bcd</dd><dd class="example" title="Click to try this example">show lput 4 \[ 1 2 3 \]</dd><dd class="example" title="Click to try this example">show lput "e "bcd</dd><dt>`array <var>size</var>`</dt><dt>`(array <var>size</var> <var>origin</var>)`</dt><dd>Create a new array. The default origin is 1.</dd><dd class="example" title="Click to try this example">show array 10</dd><dt>`mdarray [<var>dimensions</var> ...]`</dt><dt>`(mdarray [<var>dimensions</var> ...] <var>origin</var>)`</dt><dd>Create a new multi-dimensional array. The default origin is 1.</dd><dd class="example" title="Click to try this example">show mdarray \[2 2\]</dd><dt>`listtoarray <var>list</var>`</dt><dt>`(listtoarray <var>list</var> <var>origin</var>)`</dt><dd>Create a new array populated by members of a list</dd><dd class="example" title="Click to try this example">show listtoarray \[ 1 3 5 7 \]</dd><dt>`arraytolist <var>array</var>`</dt><dd>Create a new list populated by members of a array</dd><dd class="example" title="Click to try this example">show arraytolist { 2 4 6 8 }</dd><dt>`combine thing1 thing2`</dt><dd>If thing2 is a word, like `word`; otherwise, like `fput`</dd><dd class="example" title="Click to try this example">show combine "a \[b c\]</dd><dt>`reverse <var>list</var>`</dt><dd>Outputs a list with the items in reverse order; if input is a word, reverses characters</dd><dd class="example" title="Click to try this example">show reverse \[ 1 2 3 \]</dd><dd class="example" title="Click to try this example">show reverse "abc</dd><dt>`gensym`</dt><dd>Outputs a unique string, e.g. <samp>G1</samp>, <samp>G2</samp>, etc.</dd><dd class="example" title="Click to try this example">show gensym</dd></dl></div>#### 2.2 Data Selectors

<div id="bkmrk-first-list-last-list"><dl><dt>`first <var>list</var>`</dt><dt>`last <var>list</var>`</dt><dd>Outputs the first or last item (or character) from the list (or word), respectively</dd><dd class="example" title="Click to try this example">show first \[ 1 2 3 \]</dd><dd class="example" title="Click to try this example">show first "abc</dd><dd class="example" title="Click to try this example">show last \[ 1 2 3 \]</dd><dd class="example" title="Click to try this example">show last "abc</dd><dt>`firsts <var>listoflists</var>`</dt><dd>Outputs a list of the first item (or character) of each sublist (or word)</dd><dd class="example" title="Click to try this example">show firsts \[ \[1 2 3\] \[a b c\] \]</dd><dd class="example" title="Click to try this example">show firsts \[ abc def \]</dd><dt>`butfirst <var>list</var>`</dt><dt>`bf <var>list</var>`</dt><dt>`butlast <var>list</var>`</dt><dt>`bl <var>list</var>`</dt><dd>Outputs the list (or word), except for the first/last item (or character)</dd><dd class="example" title="Click to try this example">show butfirst \[ 1 2 3 \]</dd><dd class="example" title="Click to try this example">show butfirst "abc</dd><dd class="example" title="Click to try this example">show butlast \[ 1 2 3 \]</dd><dd class="example" title="Click to try this example">show butlast "abc</dd><dt>`butfirsts <var>listoflists</var>`</dt><dt>`bfs <var>listoflists</var>`</dt><dd>Outputs a list of sublists (or words) without the first item (or characters)</dd><dd class="example" title="Click to try this example">show butfirsts \[ \[ 1 2 3 \] \[ a b c \] \]</dd><dd class="example" title="Click to try this example">show butfirsts \[ abc def \]</dd><dt>`item <var>index</var> <var>thing</var>`</dt><dd>Outputs the indexth item of the list or array or word</dd><dd class="example" title="Click to try this example">show item 2 \[ 1 2 3 \]</dd><dd class="example" title="Click to try this example">show item 2 "abc</dd><dt>`mditem [<var>index</var> ...] <var>thing</var>`</dt><dd>Outputs an item from a multi-dimensional array</dd><dd class="example" title="Click to try this example">show mditem \[2 1\] {{a b} {c d}}</dd><dt>`pick <var>list</var>`</dt><dd>Outputs one item from a list (or word), at random</dd><dd class="example" title="Click to try this example">show pick \[ 1 2 3 \]</dd><dd class="example" title="Click to try this example">show pick "abc</dd><dt>`remove <var>thing</var> <var>list</var>`</dt><dd>Outputs the list (or word) with any occurences of thing removed</dd><dd class="example" title="Click to try this example">show remove "b \[ a b c \]</dd><dd class="example" title="Click to try this example">show remove "a "banana</dd><dt>`remdup <var>list</var>`</dt><dd>Outputs the list (or word) with duplicates removed</dd><dd class="example" title="Click to try this example">show remdup \[ 1 2 3 2 3 4 3 4 5 \]</dd><dd class="example" title="Click to try this example">show remdup "banana</dd><dt>`quoted <var>thing</var>`</dt><dd>Outputs thing with " prepended if a word, or just thing otherwise.</dd><dd class="example" title="Click to try this example">show quoted "abc</dd><dt>`split <var>thing</var> <var>list</var>`</dt><dd>Outputs the list split into a list of lists (or list of words) wherever thing appears.</dd><dd class="example" title="Click to try this example">show split "a "banana</dd><dd class="example" title="Click to try this example">show split 3 \[1 2 3 4 1 2 3 4\]</dd></dl></div>#### 2.3 Data Mutators

<div id="bkmrk-setitem-index-array-"><dl><dt>`setitem <var>index</var> <var>array</var> <var>value</var>`</dt><dd>Sets the indexth item of the array to value (circular arrays prevented)</dd><dd class="example" title="Click to try this example">make "a { 1 2 3 } setitem 2 :a "x show :a</dd><dt>`mdsetitem [<var>index</var>...] <var>array</var> <var>value</var>`</dt><dd>Sets an item in a multi-dimensional array to value (circular arrays prevented)</dd><dd class="example" title="Click to try this example">make "a {{1 2} {3 4}} mdsetitem \[2 1\] :a "x show :a</dd><dt>`.setfirst <var>list</var> <var>value</var>`</dt><dd>Sets the first item of the list to value</dd><dd class="example" title="Click to try this example">make "a \[ 1 2 3 \] .setfirst :a "7 show :a</dd><dt>`.setbf <var>list</var> <var>value</var>`</dt><dd>Sets the 'butfirst' of the list to the items in value (a list)</dd><dd class="example" title="Click to try this example">make "a \[ 1 2 3 \] .setbf :a \[ 4 9 \] show :a</dd><dt>`.setitem <var>index</var> <var>array</var> <var>value</var>`</dt><dd>Sets the indexth item of the array to value (circular arrays allowed)</dd><dd class="example" title="Click to try this example">make "a { 1 2 3 } setitem 2 :a "x show :a</dd><dt>`push <var>stackname</var> <var>thing</var>`</dt><dt>`pop <var>stackname</var>`</dt><dd>Push to/pop from a stack i.e. list variable. Stacks grow from the front. Works on words.</dd><dd class="example" title="Click to try this example">make "s \[ 2 1 \] push "s 3 show :s show pop "s</dd><dd class="example" title="Click to try this example">make "s "ba push "s "c show :s show pop "s</dd><dt>`queue <var>stackname</var> <var>thing</var>`</dt><dt>`dequeue <var>stackname</var>`</dt><dd>Add/remove from a queue i.e. list variable, Queues grow from the end. Works on words.</dd><dd class="example" title="Click to try this example">make "q \[ 1 2 \] queue "q 3 show :q show dequeue "q</dd><dd class="example" title="Click to try this example">make "q "ab queue "q "c show :q show dequeue "q</dd></dl></div>#### 2.4 Predicates

Predicates return 1 (true) or 0 (false)

<div id="bkmrk-wordp-thing-word%3F-th"><dl><dt>`wordp <var>thing</var>`</dt><dt>`word? <var>thing</var>`</dt><dt>`listp <var>thing</var>`</dt><dt>`list? <var>thing</var>`</dt><dt>`arrayp <var>thing</var>`</dt><dt>`array? <var>thing</var>`</dt><dt>`numberp <var>thing</var>`</dt><dt>`number? <var>thing</var>`</dt><dd>Test if thing is a word, list, array, or number respectively.</dd><dt>`emptyp <var>expr</var>`</dt><dt>`empty? <var>expr</var>`</dt><dd>Test if thing is an empty list or empty string.</dd><dt>`equalp <var>expr</var> <var>expr</var>`</dt><dt>`equal? <var>expr</var> <var>expr</var>`</dt><dt>`<var>expr</var> = <var>expr</var>`</dt><dt>`notequalp <var>expr</var> <var>expr</var>`</dt><dt>`notequal? <var>expr</var> <var>expr</var>`</dt><dt>`<var>expr</var> <> <var>expr</var>`</dt><dd>Equality/inequality tests. Compares strings, numbers, or lists (equal if length and all members are equal).</dd><dt>`beforep <var>thing1</var> <var>thing2</var>`</dt><dt>`before? <var>thing1</var> <var>thing2</var>`</dt><dd>Test string collation order.</dd><dt>`.eq <var>thing1</var> <var>thing2</var>`</dt><dd>Test if things have the same identity.</dd><dt>`memberp <var>thing</var> <var>list</var>`</dt><dt>`member? <var>thing</var> <var>list</var>`</dt><dd>Test if thing is equal to any member of list.</dd><dt>`substringp <var>thing1</var> <var>thing2</var>`</dt><dt>`substring? <var>thing1</var> <var>thing2</var>`</dt><dd>Test if thing1 is a substring of thing2.</dd></dl></div>#### 2.5 Queries

<div id="bkmrk-count-thing-outputs-"><dl><dt>`count <var>thing</var>`</dt><dd>Outputs length of a list or number of characters in a string</dd><dd class="example" title="Click to try this example">show count \[ 1 2 3 \]</dd><dd class="example" title="Click to try this example">show count "hello</dd><dt>`ascii <var>expr</var>`</dt><dd>Outputs ASCII (actually, Unicode) code point for first character of string</dd><dd class="example" title="Click to try this example">show ascii "abc</dd><dt>`char <var>expr</var>`</dt><dd>Outputs Unicode character at specified code point</dd><dd class="example" title="Click to try this example">show char 97</dd><dt>`member <var>thing</var> <var>list</var>`</dt><dd>Outputs the list (or word) from the first occurence of thing to the end, or empty list (or word)</dd><dd class="example" title="Click to try this example">show member "a "banana</dd><dd class="example" title="Click to try this example">show member 2 \[1 2 3 4\]</dd><dt>`uppercase <var>expr</var>`</dt><dt>`lowercase <var>expr</var>`</dt><dd>Outputs string converted to upper/lowercase</dd><dd class="example" title="Click to try this example">show uppercase "abc</dd><dd class="example" title="Click to try this example">show lowercase "ABC</dd><dt>`standout <var>expr</var>`</dt><dd>Outputs string with alphanumeric characters in bold</dd><dd class="example" title="Click to try this example">show standout "ABCabc123</dd><dt>`parse <var>word</var>`</dt><dd>Outputs word parsed as a list.</dd><dd class="example" title="Click to try this example">show parse "1+2</dd><dt>`runparse <var>word</var>`</dt><dd>Outputs word parsed as instructions.</dd><dd class="example" title="Click to try this example">show runparse "1+2</dd></dl></div>### 3. Communication

#### 3.1 Transmitters

<div id="bkmrk-print-thing-pr-thing"><dl><dt>`print <var>thing</var>`</dt><dt>`pr <var>thing</var>`</dt><dt>(`print <var>thing1</var> <var>thing2</var> ...)`</dt><dt>(`pr <var>thing1</var> <var>thing2</var> ...)`</dt><dd>Print inputs to the text screen, separated by spaces, and followed by a newline. Square brackets are only put around sublists.</dd><dd class="example" title="Click to try this example">print "hello</dd><dt>`type <var>thing</var>`</dt><dt>(`type <var>thing1</var> <var>thing2</var> ...)`</dt><dd>Like `print` but with no trailing newline.</dd><dd class="example" title="Click to try this example">type "hel type "lo</dd><dt>`show <var>thing</var>`</dt><dt>(`show <var>thing1</var> <var>thing2</var> ...)`</dt><dd>Like `print` but with square brackets around list inputs.</dd><dd class="example" title="Click to try this example">show "hello</dd></dl></div>#### 3.2 Receivers

<div id="bkmrk-readlist-%28readlist-p"><dl><dt>`readlist`</dt><dt>`(readlist <var>promptstr</var>)`</dt><dd>Prompt the user for a line of input. The result is a list of words.</dd><dd class="example" title="Click to try this example">show readlist</dd><dd class="example" title="Click to try this example">make "colors (readlist \[Type some colors:\]) show :colors</dd><dt>`readword`</dt><dt>`(readword <var>promptstr</var>)`</dt><dd>Prompt the user for a line of input. The result (including spaces) is the single word output.</dd><dd class="example" title="Click to try this example">show readword</dd><dd class="example" title="Click to try this example">make "name (readword \[What is your name?\]) show :name</dd></dl></div>#### 3.4 Terminal Access

<div id="bkmrk-cleartext-ct-clear-t"><dl><dt>`cleartext`</dt><dt>`ct`</dt><dd>Clear the text screen.</dd><dt>`settextcolor <var>color</var>`</dt><dd>Change the text color.</dd><dt>`textcolor`</dt><dd>Output the current text color.</dd><dt>`increasefont`</dt><dt>`decreasefont`</dt><dd>Increase/decrease the text size.</dd><dt>`settextsize <var>height</var>`</dt><dd>Change the text size (in pixels).</dd><dt>`textsize`</dt><dd>Output the current text size (in pixels).</dd><dt>`setfont <var>name</var>`</dt><dd>Change the text font.</dd><dt>`font`</dt><dd>Output the current text font.</dd></dl></div>### 4. Arithmetic

#### 4.1 Numeric Operations

Inputs are numbers or numeric expressions, output is a number.

<div id="bkmrk-sum-expr-expr-%28sum-e"><dl><dt>`sum <var>expr</var> <var>expr</var>`</dt><dt>`(sum <var>expr</var> <var>...</var>)`</dt><dt>`<var>expr</var> + <var>expr</var>`</dt><dt>`difference <var>expr</var> <var>expr</var>`</dt><dt>`<var>expr</var> - <var>expr</var>`</dt><dt>`product <var>expr</var> <var>expr</var>`</dt><dt>`(product <var>expr</var> <var>...</var>)`</dt><dt>`<var>expr</var> * <var>expr</var>`</dt><dt>`quotient <var>expr</var> <var>expr</var>`</dt><dt>`(quotient <var>expr</var>)`</dt><dt>`<var>expr</var> / <var>expr</var>`</dt><dt>`power <var>expr</var> <var>expr</var>`</dt><dt>`<var>expr</var> ^ <var>expr</var>`</dt><dd>Add, subtract, multiply, divide, and raise-to-the-power-of respectively. A single input to quotient returns the reciprocal.</dd><dt>`remainder <var>expr</var> <var>expr</var>`</dt><dt>`<var>expr</var> % <var>expr</var>`</dt><dt>`modulo <var>expr</var> <var>expr</var>`</dt><dd>Outputs the remainder (modulus). For `remainder` and `%` the result has the same sign as the first input; for `modulo` the result has the same sign as a the second input.</dd><dt>`minus <var>expr</var>`</dt><dt>`- <var>expr</var>`</dt><dd>Unary minus sign must begin a top-level expression, follow an infix operator, or have a leading space and no trailing space.</dd><dt>`abs <var>num</var>`</dt><dd>Absolute value</dd><dt>`int <var>num</var>`</dt><dt>`round <var>num</var>`</dt><dd>Truncate or round a number, respectively.</dd><dt>`sqrt <var>expr</var>`</dt><dt>`exp <var>expr</var>`</dt><dt>`log10 <var>expr</var>`</dt><dt>`ln <var>expr</var>`</dt><dd>Square root, *e* to the power of, common logarithm, and natural logarithm, respectively.</dd><dt>`arctan <var>expr</var>`</dt><dt>`(arctan <var>x</var> <var>y</var>)`</dt><dt>`sin <var>expr</var>`</dt><dt>`cos <var>expr</var>`</dt><dt>`tan <var>expr</var>`</dt><dd>The usual trig functions. Angles are in degrees.</dd><dt>`radarctan <var>expr</var>`</dt><dt>`(radarctan <var>x</var> <var>y</var>)`</dt><dt>`radsin <var>expr</var>`</dt><dt>`radcos <var>expr</var>`</dt><dt>`radtan <var>expr</var>`</dt><dd>The usual trig functions. Angles are in radians.</dd><dt>`iseq <var>first</var> <var>last</var>`</dt><dd>Outputs a list with integers from <var>first</var> to <var>last</var>, inclusive</dd><dd class="example" title="Click to try this example">show iseq 1 10</dd><dt>`rseq <var>first</var> <var>last</var> <var>count</var>`</dt><dd>Outputs a list of <var>count</var> numbers from <var>first</var> to <var>last</var>, inclusive</dd><dd class="example" title="Click to try this example">show rseq 1 9 5</dd></dl></div>#### 4.2 Numeric Predicates

<div id="bkmrk-lessp-expr-expr-less"><dl><dt>`lessp <var>expr</var> <var>expr</var>`</dt><dt>`less? <var>expr</var> <var>expr</var>`</dt><dt>`<var>expr</var> < <var>expr</var>`</dt><dt>`greaterp <var>expr</var> <var>expr</var>`</dt><dt>`greater? <var>expr</var> <var>expr</var>`</dt><dt>`<var>expr</var> > <var>expr</var>`</dt><dt>`lessequalp <var>expr</var> <var>expr</var>`</dt><dt>`lessequal? <var>expr</var> <var>expr</var>`</dt><dt>`<var>expr</var> <= <var>expr</var>`</dt><dt>`greaterequalp <var>expr</var> <var>expr</var>`</dt><dt>`greaterequal? <var>expr</var> <var>expr</var>`</dt><dt>`<var>expr</var> >= <var>expr</var>`</dt><dd>Less than, greater than, less than or equal to, greater than or equal to, respectively. Inputs are numbers or numeric expressions, output is 1 (true) or 0 (false).</dd></dl></div>#### 4.3 Random Numbers

<div id="bkmrk-random-expr-%28random-"><dl><dt>`random <var>expr</var>`</dt><dt>`(random <var>start</var> <var>end</var>)`</dt><dd>Outputs a random number from 0 through one less than <var>expr</var>, or from start to end inclusive.</dd><dd class="example" title="Click to try this example">show random 10</dd><dd class="example" title="Click to try this example">show (random 1 6)</dd><dt>`rerandom`</dt><dt>(`rerandom <var>expr</var>)`</dt><dd>Reseeds the random number generator, either to a fixed value or the specified seed.</dd></dl></div>#### 4.4 Print Formatting

<div id="bkmrk-form-expr-width-prec"><dl><dt>`form <var>expr</var> <var>width</var> <var>precision</var>`</dt><dd>Outputs a formatted string with the result of a numeric expression with <var>precision</var> decimal places and padded on the left with spaces (if necessary) to be at least <var>width characters long. </var></dd><dd class="example" title="Click to try this example">show form 1/3 10 3</dd></dl></div>#### 4.5 Bitwise Operations

<div id="bkmrk-bitand-expr-expr-%28bi"><dl><dt>`bitand <var>expr</var> <var>expr</var>`</dt><dt>`(bitand <var>expr</var> ...)`</dt><dt>`bitor <var>expr</var> <var>expr</var>`</dt><dt>`(bitor <var>expr</var> ...)`</dt><dt>`bitxor <var>expr</var> <var>expr</var>`</dt><dt>`(bitxor <var>expr</var> ...)`</dt><dt>`bitnot <var>expr</var>`</dt><dd>Bitwise and, or, exclusive-or, and not, respectively.</dd><dt>`ashift <var>expr</var> <var>bitcount</var>`</dt><dd>Arithmetic bit shift. If bitcount is negative, shifts to the right, preserving sign.</dd><dt>`lshift <var>expr</var> <var>bitcount</var>`</dt><dd>Logical bit shift. If bitcount is negative, shifts to the right, zero-filling.</dd></dl></div>### 5. Logical Operations

<div id="bkmrk-true-outputs-1-false"><dl><dt>`true`</dt><dd>Outputs 1</dd><dt>`false`</dt><dd>Outputs 0</dd><dt>`and <var>expr</var> <var>expr</var>`</dt><dt>`(and <var>expr</var> <var>...</var>)`</dt><dt>`or  <var>expr</var> <var>expr</var>`</dt><dt>`(or <var>expr</var> <var>...</var>)`</dt><dt>`xor <var>expr</var> <var>expr</var>`</dt><dt>`(xor <var>expr</var> <var>...</var>)`</dt><dt>`not <var>expr</var>`</dt><dd>Logical "and", "or", "exclusive-or", and "not", respectively. Inputs are numbers or numeric expressions, output is 1 (true) or 0 (false).</dd></dl></div>### 6. Graphics

An introduction to [Turtle Geometry](https://www.cs.berkeley.edu/~bh/v1ch10/turtle.html).

#### 6.1 Turtle Motion

<div id="bkmrk-forward-expr-fd-expr"><dl><dt>`forward <var>expr</var>`</dt><dt>`fd <var>expr</var>`</dt><dd>Move turtle forward <var>expr</var> pixels</dd><dd class="example" title="Click to try this example">fd 100</dd><dt>`back <var>expr</var>`</dt><dt>`bk <var>expr</var>`</dt><dd>Move turtle backward <var>expr</var> pixels</dd><dd class="example" title="Click to try this example">bk 100</dd><dt>`left <var>expr</var>`</dt><dt>`lt <var>expr</var>`</dt><dd>Rotate <var>expr</var> degrees counterclockwise</dd><dd class="example" title="Click to try this example">lt 90</dd><dt>`right <var>expr</var>`</dt><dt>`rt <var>expr</var>`</dt><dd>Rotate <var>expr</var> degrees clockwise</dd><dd class="example" title="Click to try this example">rt 90</dd><dt>`setpos [ <var>expr</var> <var>expr</var> ]`</dt><dt>`setxy <var>expr</var> <var>expr</var>`</dt><dt>`setx <var>expr</var>`</dt><dt>`sety <var>expr</var>`</dt><dd>Move turtle to the specified location</dd><dd class="example" title="Click to try this example">setpos \[ 100 -100 \]</dd><dd class="example" title="Click to try this example">setxy -100 100</dd><dt>`setheading <var>expr</var>`</dt><dt>`seth <var>expr</var>`</dt><dd>Rotate the turtle to the specified heading</dd><dd class="example" title="Click to try this example">setheading 45</dd><dt>`home`</dt><dd>Moves the turtle to center, pointing upwards</dd><dt>`arc <var>angle</var> <var>radius</var>`</dt><dd>Without moving the turtle, draws an arc centered on the turtle, starting at the turtle's heading.</dd><dd class="example" title="Click to try this example">arc 180 100</dd></dl></div>#### 6.2 Turtle Motion Queries

<div id="bkmrk-pos-xcor-ycor-output"><dl><dt>`pos`</dt><dt>`xcor`</dt><dt>`ycor`</dt><dd>Outputs the current turtle position as \[ x y \], x or y respectively</dd><dd class="example" title="Click to try this example">show pos</dd><dt>`heading`</dt><dd>Outputs the current turtle heading</dd><dd class="example" title="Click to try this example">show heading</dd><dt>`towards [ <var>expr</var> <var>expr</var> ]`</dt><dd>Outputs the heading towards the specified \[ x y \] coordinates</dd><dd class="example" title="Click to try this example">show towards \[ 0 0 \]</dd><dt>`scrunch`</dt><dd>Outputs the current graphics scaling factors</dd><dd class="example" title="Click to try this example">show scrunch</dd><dt>`bounds`</dt><dd>Outputs the current graphics screen bounds \[ xmin xmax ymin ymax \]</dd><dd class="example" title="Click to try this example">show bounds</dd></dl></div>#### 6.3 Turtle and Window Control

<div id="bkmrk-showturtle-st-show-t"><dl><dt>`showturtle`</dt><dt>`st`</dt><dd>Show the turtle</dd><dt>`hideturtle`</dt><dt>`ht`</dt><dd>Hide the turtle</dd><dt>`clean`</dt><dd>Clear the drawing area</dd><dt>`clearscreen`</dt><dt>`cs`</dt><dd>Same as clean and home together</dd><dt>`wrap`</dt><dd>If the turtle moves off the edge of the screen it will continue on the other side. (default)</dd><dt>`window`</dt><dd>The turtle can move past the edges of the screen, unbounded.</dd><dt>`fence`</dt><dd>If the turtle attempts to move past the edge of the screen it will stop.</dd><dt>`fill`</dt><dd>Does a paint bucket flood fill at the turtle's position.</dd><dd class="example" title="Click to try this example">arc 360 100 fill</dd><dt>`filled <var>fillcolor</var> [ <var>statements ...</var> ]`</dt><dd>Execute <var>statements</var> without drawing but keeping track of turtle movements. When complete, fill the region traced by the turtle with <var>fillcolor</var> and outline the region with the current pen style.</dd><dd class="example" title="Click to try this example">filled "red \[ repeat 5 \[ fd 100 rt 144 \] \]</dd><dt>`label <var>expr</var>`</dt><dd>Draw a word (same logic as `print`) on the graphics display at the turtle location</dd><dd class="example" title="Click to try this example">repeat 8 \[ label "Logo rt 45 \]</dd><dt>`setlabelheight <var>expr</var>`</dt><dd>Set the height for text drawn by `label`, in pixels</dd><dd class="example" title="Click to try this example">setlabelheight 100 label "Logo</dd><dt>`setlabelfont <var>expr</var>`</dt><dd>Set the font for text drawn by `label`</dd><dd class="example" title="Click to try this example">setlabelfont "Times\\ New\\ Roman label "Logo</dd><dt>`setscrunch <var>sx</var> <var>sy</var>`</dt><dd>Set the graphics scaling factors</dd><dd class="example" title="Click to try this example">setscrunch 1 2 arc 360 100</dd><dt>`setturtle <var>index</var>`</dt><dd>Switch to the turtle numbered <var>index</var> (starting from 1 for the default turtle present at start). If the turtle has not been used yet, it will be created at the center, facing upwards, visible, with the pen down.</dd><dd class="example" title="Click to try this example">setturtle 2 rt 90 fd 100</dd><dt>`ask <var>turtleindex</var> [ <var>statements ...</var> ]`</dt><dd>Execute <var>statements</var> as turtle number <var>turtleindex</var>.</dd><dd class="example" title="Click to try this example">ask 2 \[ rt 90 fd 100 \]</dd><dt>`clearturtles`</dt><dd>Remove all turtles, keeping the current one as index 1.</dd><dd class="example" title="Click to try this example">fd 50 setturtle 2 rt 90 fd 100 clearturtles</dd></dl></div>#### 6.4 Turtle and Window Queries

<div id="bkmrk-shownp-shown%3F-output"><dl><dt>`shownp`</dt><dt>`shown?`</dt><dd>Outputs 1 if the turtle is shown, 0 if the turtle is hidden</dd><dt>`turtlemode`</dt><dd>Outputs `WRAP`, `WINDOW` or `FENCE`</dd><dt>`labelsize`</dt><dd>Outputs the height of text drawn by `label`, in pixels</dd><dt>`labelfont`</dt><dd>Outputs the name of the font drawn by `label`</dd><dt>`turtle`</dt><dd>Outputs the index of the currently-active turtle</dd><dt>`turtles`</dt><dd>Outputs the largest index that has been passed to `setturtle`</dd></dl></div>#### 6.5 Pen and Background Control

<div id="bkmrk-pendown-pd-turtle-re"><dl><dt>`pendown`</dt><dt>`pd`</dt><dd>Turtle resumes leaving a trail</dd><dt>`penup`</dt><dt>`pu`</dt><dd>Turtle stops leaving a trail</dd><dt>`penpaint`</dt><dt>`ppt`</dt><dt>`penerase`</dt><dt>`pe`</dt><dt>`penreverse`</dt><dt>`px`</dt><dd>Change the turtle drawing mode - *paint* (the default) leaves a colored trail, *erase* restores the background, *reverse* inverts the background.</dd><dd class="example" title="Click to try this example">setpw 10 px repeat 5 \[ fd 100 rt 144 \]</dd><dt>`setpencolor <var>logocolor</var>`</dt><dt>`setpencolor <var>csscolor</var>`</dt><dt>`setpencolor [<var>r</var> <var>g</var> <var>b</var>]`</dt><dd>Set pen/text color. Color can be a standard Logo color number (0-15), CSS color string ([CSS color names or #rrggbb](https://www.w3.org/TR/css3-color/)), or in the list version, r/g/b values in 0...99.</dd><dd>The standard Logo colors are: <table id="bkmrk-0black-1blue-2green-"><tbody><tr><td style="background-color:#000000;color:#FFFFFF;">0  
black</td><td style="background-color:#0000FF;">1  
blue</td><td style="background-color:#00FF00;">2  
green</td><td style="background-color:#00FFFF;">3  
cyan</td></tr><tr><td style="background-color:#FF0000;">4  
red</td><td style="background-color:#FF00FF;">5  
magenta</td><td style="background-color:#FFFF00;">6  
yellow</td><td style="background-color:#FFFFFF;">7  
white</td></tr><tr><td style="background-color:#A52A2A;">8  
brown</td><td style="background-color:#D2B48C;">9  
tan</td><td style="background-color:#008000;">10  
green</td><td style="background-color:#7FFFD4;">11  
aqua</td></tr><tr><td style="background-color:#FA8072;">12  
salmon</td><td style="background-color:#800080;">13  
purple</td><td style="background-color:#FFA500;">14  
orange</td><td style="background-color:#808080;">15  
gray</td></tr></tbody></table>

</dd><dd class="example" title="Click to try this example">setpencolor 4</dd><dd class="example" title="Click to try this example">setpencolor "red</dd><dd class="example" title="Click to try this example">setpencolor "#ff0000</dd><dd class="example" title="Click to try this example">setpencolor \[ 99 0 0 \]</dd><dt>`setpalette <var>colornumber</var> <var>csscolor</var>`</dt><dt>`setpalette <var>colornumber</var> [<var>r</var> <var>g</var> <var>b</var>]`</dt><dd>Change one of the standard color entries (8 or above) to the given color.</dd><dd class="example" title="Click to try this example">setpalette 8 "pink setbg 8</dd><dd class="example" title="Click to try this example">setpalette 8 "#ff4f00 setbg 8</dd><dd class="example" title="Click to try this example">setpalette 8 \[ 99 31 0 \] setbg 8</dd><dt>`setpensize <var>expr</var>`</dt><dd>Set pen width in pixels. If <var>expr</var> is a list, the first member is used.</dd><dt>`setbackground <var>color</var>`</dt><dt>`setscreencolor <var>color</var>`</dt><dt>`setsc <var>color</var>`</dt><dd>Set the background color; same options as `setpencolor`</dd><dd class="example" title="Click to try this example">setbackground "red</dd></dl></div>#### 6.6 Pen Queries

<div id="bkmrk-pendownp-pendown%3F-ou"><dl><dt>`pendownp`</dt><dt>`pendown?`</dt><dd>Outputs 1 if the pen is down, 0 otherwise</dd><dd class="example" title="Click to try this example">show pendown?</dd><dt>`penmode`</dt><dd>Outputs `PAINT`, `ERASE` or `REVERSE`</dd><dd class="example" title="Click to try this example">show penmode</dd><dt>`pencolor`</dt><dt>`pc`</dt><dd>Outputs the current pen color. This will be a CSS color string, not necessarily the value passed in.</dd><dd class="example" title="Click to try this example">show pencolor</dd><dt>`palette <var>colornumber</var>`</dt><dd>Outputs the a palette entry. This will be a CSS color string, not necessarily the value passed in.</dd><dd class="example" title="Click to try this example">show palette 8</dd><dt>`pensize`</dt><dd>Outputs a two element list with the pen width and height (usually the same).</dd><dd class="example" title="Click to try this example">show pensize</dd><dt>`background`</dt><dt>`bg`</dt><dt>`getscreencolor`</dt><dt>`getsc`</dt><dd>Outputs the background color. This will be a CSS color string, not necessarily the value passed in.</dd><dd class="example" title="Click to try this example">show background</dd></dl></div>#### 6.7 Bitmap Operations

<div id="bkmrk-bitcut-width-height-"><dl><dt>`bitcut <var>width</var> <var>height</var>`</dt><dd>Copy a bitmap, from the turtle's position <var>width</var> by <var>height</var> pixels.</dd><dt>`bitpaste`</dt><dd>Paste the previously copied bitmap at the current turtle position.</dd><dd class="example" title="Click to try this example">repeat 4 \[ rt 90 fd 40 \] bitcut 50 50 pu fd 100 bitpaste</dd></dl></div>#### 6.8 Mouse/Touch Queries

<div id="bkmrk-mousepos-outputs-a-l"><dl><dt>`mousepos`</dt><dd>Outputs a list of the x, y coordinates of the last mouse position</dd><dd class="example" title="Click to try this example">forever \[setpos mousepos\]</dd><dt>`clickpos`</dt><dd>Outputs a list of the x, y coordinates of the last mouse press</dd><dd class="example" title="Click to try this example">forever \[setpos clickpos\]</dd><dt>`buttonp`</dt><dt>`button?`</dt><dd>Outputs 1 if any mouse button is down, 0 otherwise.</dd><dd class="example" title="Click to try this example">forever \[ifelse button? \[pd\] \[pu\] setpos mousepos\]</dd><dt>`button`</dt><dd>Outputs a number indicating the pressed mouse buttons (`1` = left, 2 = right, etc) or 0 for none.</dd><dt>`touches`</dt><dd>Outputs a list of current touch coordinates</dd><dd class="example" title="Click to try this example">forever \[ifelse count touches \[setpos first touches pendown\] \[penup\]\]</dd></dl></div>### 7. Workspace Management

#### 7.1 Procedure Definition

<div id="bkmrk-to-procname-inputs-."><dl><dt>`to <var>procname</var> <var>inputs ...</var> <var>statements ...</var> end`</dt><dd>Define a new named procedure. Inputs can be: - Required: `:a :b`
- Optional (with default values): `[:c 5] [:d 7]`
- Rest (remaining inputs as a list): `[:r]`
- Default number of inputs: `3`

</dd><dd class="example" title="Click to try this example">to star :n repeat 5 \[ fd :n rt 144 \] end</dd><dt>`define <var>procname</var> [[<var>inputs</var> ...][<var>statements</var> ...]]`</dt><dd>Define a new named procedure with optional inputs</dd><dd class="example" title="Click to try this example">define "star \[\[n\]\[repeat 5 \[fd :n rt 144\]\]\]</dd><dt>`def <var>procname</var>`</dt><dd>Outputs the definition of a named procedure as a string</dd><dd class="example" title="Click to try this example">show def "star</dd><dt>`text <var>procname</var>`</dt><dd>Outputs the definition of a named procedure as a list, suitable for use with `DEFINE`</dd><dd class="example" title="Click to try this example">show text "star</dd><dt>`copydef <var>newname</var> <var>oldname</var>`</dt><dd>Copy a procedure. If a procedure <var>newname</var> already existed it will be overridden. Primitive procedures can't be overridden unless `REDEFP` is `TRUE`.</dd><dd class="example" title="Click to try this example">copydef "new "old</dd></dl></div>#### 7.2 Variable Definition

<div id="bkmrk-make-varname-expr-up"><dl><dt>`make <var>varname</var> <var>expr</var>`</dt><dd>Update a variable or define a new global variable. The variable name must be quoted</dd><dd class="example" title="Click to try this example">make "myvar 5</dd><dt>`name <var>expr</var> <var>varname</var>`</dt><dd>Like `make` but with the inputs reversed</dd><dd class="example" title="Click to try this example">name 5 "myvar</dd><dt>`local <var>varname</var>`</dt><dt>`(local <var>varname</var> ...)`</dt><dd>A subsequent `make` will create the variable(s) in the local scope instead of the global scope</dd><dd class="example" title="Click to try this example">local "myvar</dd><dt>`localmake <var>varname</var> <var>expr</var>`</dt><dd>Define a variable in the local scope (shortcut for `local` then `make`</dd><dd class="example" title="Click to try this example">localmake "myvar 5</dd><dt>`thing <var>varname</var>`</dt><dd>Outputs the value of variable. `:foo` is a shortcut for `thing "foo`</dd><dd class="example" title="Click to try this example">show thing "myvar</dd><dt>`global <var>varname</var>`</dt><dd>Reserve the variable at the global scope. This doesn't do anything useful.</dd><dd class="example" title="Click to try this example">global "myvar</dd></dl></div>#### 7.3 Property Lists

<div id="bkmrk-pprop-plistname-prop"><dl><dt>`pprop <var>plistname</var> <var>propname</var> <var>value</var>`</dt><dd>Set the property <var>propname</var> in the property list <var>plistname</var> to value <var>value. </var></dd><dt>`gprop <var>plistname</var> <var>propname</var>`</dt><dd>Get the value of the property <var>propname</var> in the property list <var>plistname</var>, or the empty list if no such property.</dd><dt>`remprop <var>plistname</var> <var>propname</var>`</dt><dd>Remove the property <var>propname</var> in the property list <var>plistname</var>.</dd><dt>`plist <var>plistname</var>`</dt><dd>Return a list of properties in the property list <var>plistname</var>, alternating property name, property value.</dd></dl></div>#### 7.4 Workspace Predicates

Predicates return 1 (true) or 0 (false)

<div id="bkmrk-procedurep-name-proc"><dl><dt>`procedurep <var>name</var>`</dt><dt>`procedure? <var>name</var>`</dt><dd>Test if there is a procedure with the given name.</dd><dt>`primitivep <var>name</var>`</dt><dt>`primitive? <var>name</var>`</dt><dd>Test if there is a built-in procedure with the given name.</dd><dt>`definedp <var>name</var>`</dt><dt>`defined? <var>name</var>`</dt><dd>Test if there is a user-defined procedure with the given name.</dd><dt>`namep <var>name</var>`</dt><dt>`name? <var>name</var>`</dt><dd>Test if there is a variable with the given name.</dd><dt>`plistp <var>name</var>`</dt><dt>`plist? <var>name</var>`</dt><dd>Test if there is a property list with the given name.</dd></dl></div>#### 7.5 Workspace Queries

<div id="bkmrk-contents-outputs-a-l"><dl><dt>`contents`</dt><dd>Outputs a list with three members. The first is a list of user-defined procedure names. The second is a list of defined variables. The third is a list of non-empty property list names. Only non-buried procedures, variables, and property lists are included.</dd><dt>`buried`</dt><dd>Outputs a list with three members. The first is a list of user-defined procedure names The second is a list of defined variables. The third is a list of non-empty property list names. Only buried procedures, variables, and property lists are included.</dd><dt>`procedures`</dt><dd>Outputs a list of user-defined non-buried procedure names.</dd><dt>`primitives`</dt><dd>Outputs a list of primitive non-buried procedure names.</dd><dt>`globals`</dt><dd>Outputs a list of defined non-buried global variables.</dd><dt>`names`</dt><dd>Outputs a list with two members. The first is an empty list. The second is a list of defined non-buried variables.</dd><dt>`plists`</dt><dd>Outputs a list with three members. The first is an empty list. The second is an empty list. The third is a list of non-empty non-buried property list names.</dd><dt>`namelist <var>name</var>`</dt><dt>`namelist <var>namelist</var>`</dt><dd>Return a `contents`-style list with the given variable names.</dd><dt>`pllist <var>plname</var>`</dt><dt>`pllist <var>plnamelist</var>`</dt><dd>Return a `contents`-style list with the given property lists.</dd><dt>`arity <var>procname</var>`</dt><dd>Return a list with the procedure's minimum, default, and maximum number of inputs; maximum is -1 if unlimited.</dd></dl></div>#### 7.7 Workspace Control

<div id="bkmrk-erase-contentslist-t"><dl><dt>`erase <var>contentslist</var>`</dt><dd>Takes a three member list, where the first is a list of user-defined procedure names to erase, the second is a list of defined variables to erase, the third is a list of property lists to erase. Primitive procedures can't be erased unless `REDEFP` is `TRUE`.</dd><dd class="example" title="Click to try this example">erase \[ \[myproc\] \[myvar\] \[\] \]</dd><dt>`erall`</dt><dd>Erase all non-buried user-defined procedures, variables and property lists.</dd><dt>`erps`</dt><dd>Erase all non-buried user-defined procedures.</dd><dt>`erns`</dt><dd>Erase all non-buried variables.</dd><dt>`erpls`</dt><dd>Erase all non-buried property lists.</dd><dt>`ern <var>varname</var>`</dt><dt>`ern <var>varnamelist</var>`</dt><dd>Erase the named variable(s).</dd><dt>`epl <var>plname</var>`</dt><dt>`epl <var>plnamelist</var>`</dt><dd>Erase the named property list(s).</dd><dt>`bury <var>contentslist</var>`</dt><dd>Takes a three member list, where the first is a list of user-defined procedure names to bury, the second is a list of defined variables to bury, the third is a list of property lists to bury.</dd><dt>`buryall`</dt><dd>Bury all user-defined procedures, variables, and property lists.</dd><dt>`buryname <var>varname</var>`</dt><dt>`buryname <var>varnamelist</var>`</dt><dd>Bury the given variable (or list of variables).</dd><dt>`unbury <var>contentslist</var>`</dt><dd>Takes a three member list, where the first is a list of user-defined procedure names to unbury, the second is a list of defined variables to unbury, the third is a list of property lists to unbury.</dd><dt>`unburyall`</dt><dd>Unbury all user-defined procedures, variables, and property lists.</dd><dt>`unburyname <var>varname</var>`</dt><dt>`unburyname <var>varnamelist</var>`</dt><dd>Unbury the given variable (or list of variables).</dd><dt>`buriedp <var>contentslist</var>`</dt><dt>`buried? <var>contentslist</var>`</dt><dd>Return 1 if the first named user-defined procedure, variable, or property list exists and is buried, 0 otherwise.</dd></dl></div>### 8. Control Structures

#### 8.1 Control

<div id="bkmrk-run-%5B-statements-..."><dl><dt>`run [ <var>statements ...</var> ]`</dt><dd>Run the specified statements once</dd><dd class="example" title="Click to try this example">run \[ fd 100 rt 90 \]</dd><dt>`runresult [ <var>statements ...</var> ]`</dt><dd>Run the specified statements once. If the statements return a value, the result is a list with the value as a single member. Otherwise, the result is an empty list.</dd><dt>`repeat <var>expr</var> [ <var>statements ...</var> ]`</dt><dd>Repeat statements <var>expr</var> times</dd><dd class="example" title="Click to try this example">repeat 4 \[ fd 100 rt 90 \]</dd><dt>`forever [ <var>statements ...</var> ]`</dt><dd>Repeat statements forever. Used inside a user-defined procedure that terminates with `output`, `stop` or `bye`</dd><dd class="example" title="Click to try this example">forever \[ make "n random 100 show :n if :n == 0 \[ bye \] \]</dd><dt>`repcount`</dt><dt>`#`</dt><dd>Outputs the current iteration number of the current `repeat` or `forever`</dd><dd class="example" title="Click to try this example">repeat 10 \[ show repcount \]</dd><dd class="example" title="Click to try this example">repeat 10 \[ show # \]</dd><dt>`if <var>expr</var> [ <var>statements ...</var> ]`</dt><dt>`if [<var>expr</var>] [ <var>statements ...</var> ]`</dt><dd>Execute statements if the expression is non-zero</dd><dd class="example" title="Click to try this example">if 2 &gt; 1 \[ show "yep \]</dd><dt>`ifelse <var>expr</var> [ <var>statements ...</var> ] [ <var>statements ...</var> ]`</dt><dt>`ifelse [<var>expr</var>] [ <var>statements ...</var> ] [ <var>statements ...</var> ]`</dt><dd>Execute first set of statements if the expression is non-zero, otherwise execute the second set</dd><dd class="example" title="Click to try this example">ifelse 1 &gt; 2 \[ show "yep \] \[ show "nope \]</dd><dt>`test <var>expr</var>`</dt><dt>`test [<var>expr</var>]`</dt><dd>Test the specified expression, save the result in the local scope for subsequent use by `iftrue` or `iffalse`</dd><dt>`iftrue [ <var>statements ...</var>]`</dt><dt>`ift [ <var>statements ...</var>]`</dt><dt>`iffalse [ <var>statements ...</var>]`</dt><dt>`iff [ <var>statements ...</var>]`</dt><dd>Run the statements if the result of the last local `test` was non-zero (true) or zero (false) respectively.</dd><dd class="example" title="Click to try this example">test 1 &gt; 2 iftrue \[ show "yep \] iffalse \[ show "nope \]</dd><dt>`stop`</dt><dd>End the running procedure with no output value.</dd><dt>`output <var>expr</var>`</dt><dt>`op <var>expr</var>`</dt><dd>End the running procedure and output the specified value.</dd><dt>`catch tag instructionlist`</dt><dd>Run instructions, but if an error with matching tag is thrown, return the thrown value (if any). Use `"ERROR` to catch errors from regular procedures.</dd><dd class="example" title="Click to try this example">catch "t \[ show "before throw "t show "after \]</dd><dd class="example" title="Click to try this example">catch "error \[ show 1 / 0 \] show error</dd><dt>`throw tag`</dt><dt>`(throw tag value)`</dt><dd>Throw an error with the given tag which may be caught. An optional return value can be passed.</dd><dd class="example" title="Click to try this example">show catch "t \[ show "hello (throw "t "world) \]</dd><dt>`error`</dt><dd>Outputs a list describing the last error caught: an error number, an error message message, and the procedure name where the error occurred.</dd><dd class="example" title="Click to try this example">catch "error \[ show 1 / 0 \] show error</dd><dt>`wait <var>time</var>`</dt><dd>Pauses execution. <var>time</var> is in 60ths of a second.</dd><dt>`bye`</dt><dd>Terminate the program</dd><dt>`.maybeoutput <var>expr</var>`</dt><dd>Like `output` if <var>expr</var> returns a value, like `stop` otherwise</dd><dt>`ignore <var>expr</var>`</dt><dd>Evaluate and ignore results of the expression</dd><dd class="example" title="Click to try this example">make "q \[ 1 2 3 \] ignore dequeue "q</dd><dt>`` <var>list</var>`</dt><dd>Outputs the list with substitutions: - `, <var>instructionlist</var>` replaced by output
- `,@ <var>instructionlist</var>` replaced by output list members
- `",<var>instruction</var>` replaced by output prefixed with "
- `,@<var>instruction</var>` replaced by output prefixed with :

</dd><dd class="example" title="Click to try this example">show `\[a b ,\[bf \[c d e\]\] f ,@\[bf \[g h i\]\]\]</dd><dd class="example" title="Click to try this example">make "v "x show `\[",:v :,:v\]</dd><dt>`for <var>controllist</var> [ <var>statements ...</var>]`</dt><dd>Typical `for` loop. The <var>controllist</var> specifies three or four members: the local <var>varname</var>, <var>start</var> value, <var>limit</var> value, and optional <var>step</var> size.</dd><dd class="example" title="Click to try this example">for \[ a 1 10 \] \[ show :a \]</dd><dd class="example" title="Click to try this example">for \[ a 0 20 2 \] \[ show :a \]</dd><dt>`dotimes [<var>varname</var> <var>times</var>] [ <var>statements ...</var>`</dt><dd>Run the statements the specified number of <var>times</var>. The variable <var>varname</var> is set to the current iteration number.</dd><dd class="example" title="Click to try this example">dotimes \[ i 5 \] \[ show :i \* :i \]</dd><dt>`do.while [ <var>statements ...</var>] <var>expr</var>`</dt><dt>`do.while [ <var>statements ...</var>] [<var>expr</var>]`</dt><dd>Runs the specified statements at least once, and repeats while the expression is non-zero (true).</dd><dd class="example" title="Click to try this example">do.while \[ make "a random 10 show :a \] :a &lt; 8</dd><dt>`while <var>expr</var> [ <var>statements ...</var>]`</dt><dt>`while [<var>expr</var>] [ <var>statements ...</var>]`</dt><dd>Runs the specified statements only while the expression remains non-zero (true).</dd><dd class="example" title="Click to try this example">while (random 2) = 0 \[ show "zero \] show "one</dd><dt>`do.until [ <var>statements ...</var>] <var>expr</var>`</dt><dt>`do.until [ <var>statements ...</var>] [<var>expr</var>]`</dt><dd>Runs the specified statements at least once, and repeats while the expression is zero (false).</dd><dd class="example" title="Click to try this example">do.until \[ make "a random 10 show :a \] :a &lt; 8</dd><dt>`until <var>expr</var> [ <var>statements ...</var>]`</dt><dt>`until [<var>expr</var>] [ <var>statements ...</var>]`</dt><dd>Runs the specified statements only while the expression remains zero (false).</dd><dd class="example" title="Click to try this example">until (random 2) = 0 \[ show "one \] show "zero</dd><dt>`case <var>value</var> [ <var>clauses ...</var> ] `</dt><dd>For each clause in order: If the clause is of the form `[ ELSE <var>expr</var> ]` then <var>expr</var> is evaluated and returned. Otherwise, if the clause is of the form `[ [ <var>matches</var> ] <var>expr</var> ]` and <var>value</var> is a member of <var>matches</var> then <var>expr</var> is evaluated and returned.</dd><dd class="example" title="Click to try this example">show case :var \[ \[ \["a\] "AAA \] \[ \["b\] "BBB \] \[ else "other \] \]</dd><dt>`cond [ <var>clauses ...</var> ] `</dt><dd>For each clause in order: If the clause is of the form `[ ELSE <var>expr</var> ]` then <var>expr</var> is evaluated and returned. Otherwise, if the clause is of the form `[ [ <var>expr1</var> ] <var>expr2</var> ]` and <var>expr1</var> evaluates to non-zero (true) then <var>expr2</var> is evaluated and returned.</dd><dd class="example" title="Click to try this example">show cond \[ \[ \[:var = 1\] "one\] \[ \[:var = 2\] "two\] \[ else "other \] \]</dd></dl></div>#### 8.2 Template-based Iteration

These higher-level procedures support only the *named procedure* form of template. The first input is the name of a procedure to call.

<div id="bkmrk-apply-procname-list-"><dl><dt>`apply <var>procname</var> <var>list</var>`</dt><dd>Call <var>procname</var> with the members of <var>list</var> as inputs</dd><dt>`invoke <var>procname</var> <var>input1</var>`</dt><dt>`(invoke <var>procname</var> <var>input1</var> ...)`</dt><dd>Call <var>procname</var> with the specified inputs as inputs</dd><dd class="example" title="Click to try this example">invoke "show "hello</dd><dt>`foreach <var>list</var> <var>procname</var>`</dt><dd>call <var>procname</var> for each item in the list</dd><dd class="example" title="Click to try this example">foreach \[1 2 3\] "show</dd><dt>`map <var>procname</var> <var>list</var>`</dt><dd>Outputs a list composed of the results of calling <var>procname</var> for each item in the list</dd><dd class="example" title="Click to try this example">to double :n output :n \* 2 end show map "double \[1 2 3\]</dd><dt>`filter <var>procname</var> <var>list</var>`</dt><dd>Outputs a list composed of the input list where procname called on the item returns non-zero (true)</dd><dd class="example" title="Click to try this example">to oddp :n output bitand :n 1 end show filter "oddp \[ 1 2 3 4 5 \]</dd><dt>`find <var>procname</var> <var>list</var>`</dt><dd>Outputs the first item in <var>list</var> for which calling <var>procname</var> on it returns non-zero (true). If not found, the empty list is returned.</dd><dd class="example" title="Click to try this example">to oddp :n output bitand :n 1 end show find "oddp \[ 2 8 4 7 10 9 \]</dd><dt>`reduce <var>procname</var> <var>list</var>`</dt><dt>`(reduce <var>procname</var> <var>list</var> <var>initial</var>)`</dt><dd>Call <var>procname</var> repeatedly with two inputs - the current value and the next list item. If <var>initial</var> is not specified, the first list element is used instead.</dd><dd class="example" title="Click to try this example">show reduce "sum \[ 1 2 3 4 5 \]</dd><dt>`crossmap <var>procname</var> <var>listlist</var>`</dt><dt>`(crossmap <var>procname</var> <var>list</var> <var>list</var> ...)`</dt><dd>Call <var>procname</var> repeatedly with inputs from the lists, in all possible combinations.</dd><dd class="example" title="Click to try this example">show crossmap "word \[\[a b\] \[x y\]\]</dd><dd class="example" title="Click to try this example">show (crossmap "word \[a b c\] \[1 2 3 4\])</dd></dl></div>

# sortie discussions et commentaire avec Claude

#### version 0.03

\- https://turing.cs.hbg.psu.edu/LOCAL/ucblogo/ucbl\_7.htm  
\- https://fmslogo.sourceforge.io/manual/workspace-control.html  
\- https://www.calormen.com/jslogo/language.html

● Le fichier PyLogo\_0.03.py est créé et prêt. Voici le résumé :

 Modifications apportées

 1. En-tête de version (lignes 11-28)

 Historique des versions ajouté en début de fichier.

 2. Classe Workspace (lignes 447-639)

 Nouvelle classe pour gérer les procédures :  
\- define() / get() / exists() / erase()  
\- bury() / unbury() / is\_buried()  
\- list\_visible() / list\_buried() / list\_all()  
\- get\_source() - reconstruit le code source d'une procédure  
\- save() - sauvegarde dans un fichier .logo

 3. Nouvelles commandes Logo  
 ┌──────────────────┬──────────────────┬─────────────────────────────────┐  
 │ Commande │ Alias │ Description │  
 ├──────────────────┼──────────────────┼─────────────────────────────────┤  
 │ LISTEPROCEDURES │ PROCEDURES, POCS │ Liste les procédures │  
 ├──────────────────┼──────────────────┼─────────────────────────────────┤  
 │ MONTREPROCEDURE │ PO, PRINTOUT │ Affiche le code d'une procédure │  
 ├──────────────────┼──────────────────┼─────────────────────────────────┤  
 │ ENTERREPROCEDURE │ BURY │ Protège une procédure │  
 ├──────────────────┼──────────────────┼─────────────────────────────────┤  
 │ DETERREPROCEDURE │ UNBURY │ Déprotège une procédure │  
 ├──────────────────┼──────────────────┼─────────────────────────────────┤  
 │ SAUVEPROCEDURES │ SAVE │ Sauvegarde dans un fichier │  
 ├──────────────────┼──────────────────┼─────────────────────────────────┤  
 │ CHARGEPROCEDURES │ LOAD │ Charge depuis un fichier │  
 └──────────────────┴──────────────────┴─────────────────────────────────┘  
 4. Intégration

\- LogoInterpreter utilise maintenant self.workspace au lieu de self.procedures  
\- Méthode load\_procedures() ajoutée pour charger les fichiers

 La syntaxe est validée. Tu peux tester avec des commandes comme :  
 POUR CARRE :taille  
 REPETE 4 \[AVANCE :taille DROITE 90\]  
 FIN  
 SAUVEPROCEDURES "mes\_dessins  
 LISTEPROCEDURES

 Brewed for 7m 7s

❯ C'est un profond remaniement du code qui va permettre d'être plus solide et cohérent pour la suite.   
 Je testerais, mais la lecture du code généré est satisfaisante !

● Merci. Effectivement, cette refactorisation apporte plusieurs avantages :

 Architecture plus propre :  
\- Séparation des responsabilités : Workspace gère les procédures, LogoInterpreter exécute  
\- Encapsulation : toute la logique de gestion des procédures est centralisée  
\- Code plus testable unitairement

 Préparation pour la suite :  
\- Ajout facile de nouvelles fonctionnalités (bibliothèques, modules)  
\- Base solide pour l'IDE enfants  
\- Le système BURY/UNBURY permet de protéger des procédures "système" que tu pourrais fournir

 Points à tester en priorité :  
 1. POUR ... FIN → définition de procédure  
 2. LISTEPROCEDURES → vérifier qu'elle apparaît  
 3. SAUVEPROCEDURES "test → vérifier le fichier généré  
 4. CHARGEPROCEDURES "test → après un redémarrage  
 5. ENTERREPROCEDURE / DETERREPROCEDURE → protection

 N'hésite pas à revenir si tu rencontres des soucis lors des tests ou pour continuer sur d'autres aspects du projet.

# Interface à l'interpréteur

# Discussions préalables

Discussion Mistral :

Je comprends parfaitement ! À ce stade, il est crucial de **clarifier les cas d’usage** pour affiner l’architecture et éviter les choix techniques prématurés. Voici une synthèse des **scénarios clés** à valider, organisés par priorité et impact sur la conception. Ces cas d’usage serviront de base pour les décisions architecturales finales.

---

### **1. Cas d’Usage Principaux (Priorité Haute)**

#### **A. Utilisation en Classe (Collaboratif)**

**Scénario** :

- **5 à 10 enfants** travaillent simultanément sur leurs postes (tablettes/PC).
- Ils **partagent des morceaux de code** (ex. : une procédure `POUR MAISON`) et voient les modifications en temps réel.
- L’enseignant peut **projeté la tortue virtuelle** sur un mur/écran pour que tous voient le résultat collectif.

**Questions clés** :

1. **Partage de code** :
    
    
    - Les enfants peuvent-ils **modifier le même code simultanément** (comme un Google Doc) ? → *Si oui* : Nécessite un système de synchronisation fine (CRDT ou WebSockets + verrouillage). → *Si non* : Un système de "copier-coller partagé" suffit (plus simple).
    - Faut-il un **historique des modifications** (pour revenir en arrière) ?
2. **Projection centrale** :
    
    
    - La tortue projetée doit-elle **afficher qui a envoyé la dernière commande** (ex. : "Alice a fait AVANCE 50") ?
    - Faut-il un **mode "présentation"** où l’enseignant peut geler l’affichage pour expliquer un concept ?
3. **Rôle de l’enseignant** :
    
    
    - Peut-il **bloquer l’envoi de commandes** pendant une explication ?
    - Peut-il **sauvegarder les projets** de tous les enfants en une fois ?

---

#### **B. Intégration avec la Tortue-Robot**

**Scénario** :

- La classe dispose d’**1 ou 2 tortues-robot** (MicroPython) qui se déplacent sur une feuille au sol.
- Les enfants envoient des commandes depuis leurs postes, et la tortue-robot **exécute les mêmes mouvements** que la tortue virtuelle projetée.

**Questions clés** :

1. **Synchronisation virtuel/physique** :
    
    
    - La tortue-robot doit-elle **suivre exactement** la tortue virtuelle (même position, même vitesse) ? → *Si oui* : Nécessite un système de calibration précis (ex. : 1 pas virtuel = 1 cm physique). → *Si non* : La tortue-robot exécute les commandes **indépendamment**, avec ses propres contraintes (ex. : elle bute sur un obstacle).
2. **Feedback physique** :
    
    
    - Si la tortue-robot est bloquée, faut-il **afficher un message d’erreur** sur tous les écrans (ex. : "La tortue ne peut pas avancer !") ?
    - Peut-on **envoyer des commandes "spéciales"** à la tortue-robot (ex. : allumer une LED, émettre un son) ?
3. **Logistique** :
    
    
    - Combien de tortues-robot seront utilisées **simultanément** ?
    - Faut-il prévoir un **système de réservation** (ex. : "C’est au tour de Bob d’utiliser la tortue") ?

---

#### **C. Utilisation Individuelle (À la Maison)**

**Scénario** :

- Un enfant utilise l’interpréteur **seul sur son poste**, sans tortue-robot ni projection.
- Il peut **sauvegarder ses projets** et les retrouver en classe.

**Questions clés** :

1. **Sauvegarde** :
    
    
    - Les projets sont-ils sauvegardés **localement** (fichier sur l’ordinateur) ou **sur un serveur** (compte utilisateur) ?
    - Faut-il un système de **synchronisation** entre la maison et l’école ?
2. **Compatibilité** :
    
    
    - L’interface doit-elle fonctionner sur **mobile/tablette** (ex. : iPad) ?
    - Faut-il une **version hors ligne** (pour les zones sans internet) ?

---

### **2. Cas d’Usage Secondaires (Priorité Moyenne)**

#### **A. Collaboration À Distance**

**Scénario** :

- Deux classes (ou un enfant à la maison et un autre en classe) collaborent sur le même projet.

**Questions** :

- Faut-il un système d’**invitation par lien** (comme Google Docs) ?
- Comment gérer les **décalages horaires** ou les connexions instables ?

---

#### **B. Extensions Pédagogiques**

**Scénario** :

- L’enseignant veut **créer des défis** (ex. : "Dessine un hexagone") ou **limiter les commandes disponibles** pour les débutants.

**Questions** :

- Faut-il un **mode "défi"** où certaines commandes sont désactivées ?
- Peut-on **enregistrer des séquences** pour les rejouer plus tard (ex. : pour montrer une solution) ?

---

#### **C. Accessibilité**

**Scénario** :

- Un enfant malvoyant ou avec des troubles dys utilise l’outil.

**Questions** :

- Faut-il prévoir un **mode haute contraste** ou une **saisie vocale** ?
- Peut-on **agrandir la taille du texte** ou des boutons ?

---

### **3. Cas d’Usage Exclus (Priorité Basse)**

- **Intégration avec d’autres outils** (ex. : exporter un dessin vers un logiciel de dessin).
- **Compétitions entre classes** (ex. : "Qui dessine le plus beau motif ?").
- **Utilisation par des adultes** (ex. : pour des ateliers de programmation créative).

---

### **4. Synthèse des Impacts Architecturaux**

<div id="bkmrk-cas-d%E2%80%99usage-impact-t"><table><thead><tr><th>Cas d’Usage</th><th>Impact Technique Principal</th><th>Complexité</th></tr></thead><tbody><tr><td>Collaboratif en temps réel</td><td>WebSockets + gestion des conflits de code</td><td>Élevée</td></tr><tr><td>Tortue-robot synchronisée</td><td>Communication serveur/MicroPython + calibration</td><td>Moyenne</td></tr><tr><td>Projection centrale</td><td>Séparation frontend/backend + mode lecture seule</td><td>Faible</td></tr><tr><td>Sauvegarde des projets</td><td>Base de données (SQLite) ou fichiers locaux</td><td>Faible</td></tr><tr><td>Utilisation hors ligne</td><td>Service Workers (pour le web) ou app desktop</td><td>Moyenne</td></tr></tbody></table>

</div>---

### **5. Prochaines Étapes pour Toi**

1. **Valider les cas d’usage prioritaires** avec les enseignants/élèves :
    
    
    - Quels scénarios sont **indispensables** pour la rentrée 2026–2027 ?
    - Quels sont **optionnels** (peuvent attendre une V2) ?
2. **Affiner les contraintes techniques** :
    
    
    - Exemple : Si la tortue-robot doit être synchronisée avec la virtuelle, il faudra un **protocole de communication temps réel** (WebSockets + MicroPython).
    - Si le partage de code est collaboratif, il faudra choisir entre **CRDT** (complexe) ou **verrouillage** (plus simple).
3. **Prototypage léger** :
    
    
    - Une fois les cas d’usage validés, un **prototype minimal** (ex. : Flask + HTML basique) permettra de tester les flux principaux.

---

### **6. Exemple de Décisions Architecturales Découlant des Cas d’Usage**

<div id="bkmrk-d%C3%A9cision-si-cas-d%E2%80%99us"><table><thead><tr><th>Décision</th><th>Si Cas d’Usage X est validé...</th><th>Sinon...</th></tr></thead><tbody><tr><td>**Technologie backend**</td><td>Flask + WebSockets (pour le temps réel)</td><td>Flask seul (plus simple)</td></tr><tr><td>**Stockage des projets**</td><td>SQLite + système de versions (pour l’historique)</td><td>Fichiers locaux (JSON)</td></tr><tr><td>**Frontend**</td><td>Vue.js léger (pour la réactivité)</td><td>Vanilla JS (plus simple)</td></tr><tr><td>**Communication tortue-robot**</td><td>WebSockets + protocole custom</td><td>USB sériel (pour un prototype)</td></tr></tbody></table>

</div>---

**Question pour toi** : Quels sont les **3 cas d’usage prioritaires** que tu veux absolument voir implémentés pour la rentrée 2026–2027 ? Cela permettra de focaliser l’architecture sur l’essentiel. 😊

*(Exemple de réponse : "1. Collaboratif en classe avec projection, 2. Tortue-robot synchronisée, 3. Sauvegarde locale des projets.")*

### **1. Principes fondateurs de l’UI (version "puriste mais moderne")**

#### **a. Minimalisme radical**

- **Pas de blocs prédéfinis** (type Scratch) : L’enfant écrit **toujours** du code texte, mais avec des aides **optionnelles et non intrusives**.
- **Pas de surcharge visuelle** : L’écran est épuré, avec **uniquement** : 
    - Une **zone de dessin** (tortue + traces).
    - Une **console de commande** (saisie texte).
    - Une **zone de procédures** (pour sauvegarder/réutiliser du code écrit par l’enfant).

#### **b. Modernité discrète**

- **Design sobre mais actuel** :
    
    
    - **Couleurs** : Fond clair (blanc cassé ou bleu très pâle) pour éviter la fatigue oculaire, tortue et textes en noir ou couleurs vives **uniquement pour le feedback** (ex. : syntaxe correcte en vert, erreur en orange).
    - **Typographie** : Police monospace (ex. **Courier New** ou **Fira Code**) pour le code (lisibilité et alignement des commandes), et une police simple (ex. **Open Sans**) pour les menus.
    - **Formes** : Lignes épurées, pas de boutons superflus. Les éléments interactifs sont **discrets** mais identifiables (ex. : survol = léger soulignement).
- **Feedback visuel intelligent** :
    
    
    - La tortue **clignote brièvement** quand une commande est exécutée (sans son, pour éviter la distraction).
    - Les erreurs de syntaxe sont signalées par un **soulignement rouge** + message court en bas de l’écran (ex. : *"Il manque un nombre après AVANCE"*).
    - **Pas d’animations inutiles** : La tortue se déplace **immédiatement** (pas de "dance" ou d’effets de style).

#### **c. Personnalisation par l’enfant (sans assistance forcée)**

- **Boutons programmables** : 
    - L’enfant peut **créer ses propres boutons** en glissant-déposant **du code qu’il a écrit** dans une zone dédiée (ex. : un bouton "CARRÉ" exécutant sa procédure `POUR CARRE ... FIN`).
    - Ces boutons sont **des raccourcis**, pas des commandes prédéfinies. Ils apparaissent comme des **étiquettes textuelles simples** (pas d’icônes imposées).
- **Éditeur de procédures** : 
    - Une zone latérale (ou un onglet) permet de **lister les procédures définies par l’enfant**, avec un bouton "Éditer" pour les modifier.
    - **Pas de "bibliothèque" prédéfinie** : Tout doit être écrit par l’enfant ou importé depuis ses propres fichiers.

#### **d. Respect de la philosophie Logo**

- **Pas de gamification** (badges, étoiles) : L’enfant est motivé par **la création elle-même**, pas par des récompenses externes.
- **Pas de "mode découverte" guidé** : L’interface ne propose **jamais** de défis ou de tutoriels intrusifs. En revanche, un bouton "?" peut ouvrir un **manuel minimaliste** avec des exemples de code (ex. : *"Pour dessiner un carré : Répète 4 fois \[AVANCE 100 TOURNE 90\]"*).
- **Accès direct au métalangage** : 
    - L’enfant peut **voir et modifier** les primitives de base (ex. : redéfinir `AVANCE` s’il le souhaite, comme dans les versions historiques de Logo).

> <span class="whitespace-pre-wrap">On est encore en réflexion sur le sujet. J'ai aussi les idées suivante</span>  
> <span class="whitespace-pre-wrap">- permettre à plusieurs enfants de partager en temps réel des codes ou morceaux de code</span>  
> <span class="whitespace-pre-wrap">- pouvoir séparer de l'interface la zone d'exécution ou il y a la tortue : elle peut-être projetée par exemple sur un mur, et les enfants travaillent sur un/leur poste.</span>  
> <span class="whitespace-pre-wrap">- donc ou peut aussi envisager une architecture client/serveur ou un code python/flask sert l'interface ou plusieurs interfaces, dont la zone de projection tortue.</span>  
> <span class="whitespace-pre-wrap">- enfin, j'inscris ce projet dans un suite de projet ou les enfants peuvent utiliser une tortue-robot réelle, qui se déplace sur un feuille sur le sol de la classe.</span>  
> <span class="whitespace-pre-wrap">- ce projet sera porté par les enfants ados et la programmation de la tortue pourrait-être faite au travers de la bibliothèque micro-python</span>

<span class="whitespace-pre-wrap">PROPOSITION :</span>

## **1. Architecture Globale Proposée**

Ton projet combine **4 dimensions** :

1. **Interpréteur Logo collaboratif** (partage de code en temps réel).
2. **Séparation interface/exécution** (projection de la tortue sur un mur).
3. **Architecture client/serveur** (pour gérer plusieurs interfaces et la projection).
4. **Intégration avec des tortues-robot physiques** (via MicroPython).

Voici une architecture technique cohérente pour répondre à ces besoins :

+-------------------+ +-------------------+ +---------------------+  
| Client 1 | | Client 2 | | Projecteur/Écran |  
| (Enfant A) |------&gt;| (Enfant B) |------&gt;| (Tortue virtuelle) |  
| - Éditeur de code | | - Éditeur de code | | - Affichage seul |  
| - Console | | - Console | | - Pas de saisie |  
+-------------------+ +-------------------+ +---------------------+  
 \\ /  
 \\ /  
 +-------------------+ +-------------------------------+  
 | Serveur | | Tortue-Robot (MicroPython) |  
 | (Python/Flask) |&lt;-----&gt;| - Reçoit les commandes |  
 | - Gère les sessions| | - Se déplace sur le sol |  
 | - Synchronise | | - Envoie des feedbacks |  
 | le code | | (position, erreurs) |  
 +-------------------+ +-------------------------------+

Merci pour ces précisions passionnantes ! Ton projet prend une dimension **collaborative, physique et pédagogique** très riche, qui dépasse largement un simple interpréteur Logo classique. Voici une analyse structurée des enjeux et des solutions possibles, en gardant à l’esprit tes contraintes (fidélité à l’esprit Logo, modernité discrète, et intégration avec du matériel comme les tortues-robot).

---

## **2. Solutions Techniques par Dimension**

### **A. Collaboratif en temps réel**

**Objectif** : Permettre à plusieurs enfants de partager du code ou des morceaux de code. **Solutions** :

- **CRDT (Conflict-free Replicated Data Type)** : 
    - Utiliser une bibliothèque comme [Yjs](https://github.com/yjs/yjs) (pour le web) ou [Automerge](https://automerge.org/) (pour une app desktop).
    - Avantages : Synchronisation fluide, pas de conflits, historique des modifications.
    - Exemple : Si un enfant écrit `POUR CARRE`, un autre peut voir la définition en temps réel et l’utiliser.
- **WebSockets (pour une solution client/serveur)** : 
    - Le serveur Flask diffuse les mises à jour de code à tous les clients connectés.
    - Exemple avec Flask-SocketIO : <div class="relative m-0 rounded-md border border-default bg-default whitespace-break-spaces" data-testid="code-block"><div class="text-sm text-default select-text">`from flask_socketio import SocketIO, emit@socketio.on('code_update')def handle_code_update(data):    emit('code_update', data, broadcast=True)  # Envoie à tous les clients`</div></div>
- **Alternative simple** : 
    - Un système de "copier-coller partagé" via le serveur (moins fluide, mais plus simple à implémenter).

---

### **B. Séparation interface/exécution (projection)**

**Objectif** : La tortue s’affiche sur un écran/mur, tandis que les enfants codent sur leurs postes. **Solutions** :

- **Mode "Projection"** : 
    - Le serveur Flask génère une **URL dédiée** pour la projection (ex. : `/projection`).
    - Cette page n’a **que la zone de dessin** (tortue + traces), sans éditeur ni console.
    - Les enfants envoient leurs commandes au serveur, qui les exécute et met à jour l’affichage pour tous.
- **Technos** : 
    - **Frontend** : HTML/Canvas pour la projection (même code que les clients, mais en mode "lecture seule").
    - **Backend** : Flask gère les états partagés (position de la tortue, couleurs, etc.).
- **Exemple de flux** : 
    1. Un enfant tape `AVANCE 50` sur son poste.
    2. Le code est envoyé au serveur via WebSocket.
    3. Le serveur met à jour l’état de la tortue et envoie la nouvelle position à **tous les clients + la projection**.

---

### **C. Architecture Client/Serveur (Flask)**

**Objectif** : Centraliser la logique pour gérer plusieurs interfaces et la projection. **Solutions** :

- **Flask + SocketIO** : 
    - **Avantages** : 
        - Léger et facile à déployer (même sur un Raspberry Pi en classe).
        - Permet de gérer les sessions, l’historique des commandes, et la synchronisation.
    - **Exemple de routes** : <div class="relative m-0 rounded-md border border-default bg-default whitespace-break-spaces" data-testid="code-block"><div class="text-sm text-default select-text">`@app.route('/')def index():    return render_template('editeur.html')  # Interface complète pour les enfants@app.route('/projection')def projection():    return render_template('projection.html')  # Zone de dessin seule`</div></div>
- **Stockage des projets** : 
    - Utiliser une base **SQLite** (légère, sans serveur) pour sauvegarder les procédures des enfants.
    - Exemple de table : <div class="relative m-0 rounded-md border border-default bg-default whitespace-break-spaces" data-testid="code-block"><div class="text-sm text-default select-text">`CREATE TABLE projets (    id INTEGER PRIMARY KEY,    nom TEXT,    code TEXT,    date_modification DATETIME);`</div></div>

---

### **D. Intégration avec les tortues-robot (MicroPython)**

**Objectif** : Permettre aux enfants de contrôler une tortue physique via le même code Logo. **Solutions** :

- **Protocole de communication** : 
    - Le serveur Flask agit comme un **pont** entre les clients et la tortue-robot.
    - Les commandes Logo sont traduites en instructions MicroPython (ex. : `AVANCE 50` → `robot.forward(50)`).
- **Matériel** : 
    - La tortue-robot est équipée d’un **ESP32 ou Raspberry Pi Pico** (compatible MicroPython).
    - Elle se connecte au serveur via **Wi-Fi** (pour les ESP32) ou **USB** (pour un prototype simple).
- **Exemple de code MicroPython** (côté robot) : <div class="relative m-0 rounded-md border border-default bg-default whitespace-break-spaces" data-testid="code-block"><div class="text-sm text-default select-text">`from machine import Pin, PWMimport networkimport socket# Configuration Wi-Fista_if = network.WLAN(network.STA_IF)sta_if.active(True)sta_if.connect('SSID', 'password')# Moteurs (exemple simplifié)def forward(steps):    # Logique pour avancer    print(f"Avance de {steps} pas")# Serveur TCP pour recevoir les commandess = socket.socket()s.bind(('0.0.0.0', 8080))s.listen(1)while True:    conn, addr = s.accept()    data = conn.recv(1024).decode()    if data.startswith("AVANCE"):        steps = int(data.split()[1])        forward(steps)    conn.close()`</div></div>
- **Côté serveur Flask** : 
    - Quand un enfant envoie `AVANCE 50`, le serveur transmet la commande à la tortue-robot via Wi-Fi/USB.

---

## **3. Points d’Attention**

- **Latence** : 
    - Avec plusieurs enfants + une tortue physique, la latence peut devenir visible.
    - **Solution** : Utiliser des WebSockets pour minimiser les délais, et prévoir un système de "file d’attente" pour les commandes.
- **Sécurité** : 
    - Si le serveur est accessible sur le réseau de l’école, sécuriser les connexions (mot de passe simple pour la classe).
- **Pédagogie** : 
    - **Ne pas cacher la complexité** : Les enfants doivent comprendre que la tortue physique et la tortue virtuelle suivent les mêmes règles.
    - **Feedback clair** : Si la tortue-robot bute sur un obstacle, envoyer un message comme *"Attention, la tortue est bloquée !"* sur tous les écrans.

---

## **4. Exemple de Workflow Complet**

1. **En classe** : 
    - Les enfants ouvrent leur navigateur sur `http://<adresse-du-serveur>`.
    - Ils voient l’éditeur Logo et la console.
    - Le projecteur affiche `http://<adresse-du-serveur>/projection`.
2. **Collaboration** : 
    - Alice écrit `POUR CARRE ... FIN`.
    - Bob peut voir la procédure et l’utiliser dans son propre code.
3. **Exécution** : 
    - Quand un enfant exécute `CARRE`, la tortue virtuelle (projection) et la tortue-robot (si connectée) dessinent un carré.
4. **Feedback** : 
    - Si la tortue-robot rencontre un problème, un message s’affiche sur tous les écrans.

---

## **5. Technologies Recommandées**

<div id="bkmrk-composant-technologi"><table><thead><tr><th>Composant</th><th>Technologie</th><th>Pourquoi</th></tr></thead><tbody><tr><td>**Frontend**</td><td>HTML/CSS/JS (Vanilla ou Vue.js léger)</td><td>Simple, portable, pas de compilation.</td></tr><tr><td>**Backend**</td><td>Python/Flask + Flask-SocketIO</td><td>Léger, facile à déployer, compatible avec MicroPython.</td></tr><tr><td>**Base de données**</td><td>SQLite</td><td>Sans serveur, idéale pour un usage en classe.</td></tr><tr><td>**Tortue-robot**</td><td>ESP32 + MicroPython</td><td>Peu coûteux, programmable en Python, Wi-Fi intégré.</td></tr><tr><td>**Collaboration**</td><td>WebSockets (SocketIO)</td><td>Temps réel, simple à implémenter avec Flask.</td></tr></tbody></table>

</div>---

## **6. Prochaines Étapes Possibles**

1. **Prototype minimal** : 
    - Un serveur Flask basique + une page HTML avec un éditeur et un canvas.
    - Test avec 2 clients et une projection.
2. **Intégration MicroPython** : 
    - Connecter une tortue-robot (ESP32) au serveur et traduire les commandes Logo.
3. **Tests en classe** : 
    - Observer comment les enfants interagissent avec l’outil (collaboration, compréhension des feedbacks).

---

**Question pour toi** :

- Veux-tu que je te propose un **exemple de code Flask + HTML/JS** pour démarrer le prototype (avec la synchronisation basique et la projection) ?
- Ou préfères-tu approfondir un autre aspect (ex. : la communication avec la tortue-robot, ou la gestion des conflits de code) ?