fig example programs 2017

##########  arrlen.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

function re(z p)
    f = z ; split(f p) ; join(f "") ; return(f)
    fig

forin (p stdin)
    cr = 13 ; chr
    lf = 10 ; chr
    z = p ; re(z cr) ; re(z lf)
    p = z ; len ; prints ; " " ; prints
    p = z ; print
    next


##########  az.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

x : arr  : times 5
y : arr  : times 2
x : plus : y print
## arrays dont auto-zero


##########  c.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

python 
    def figpset(z, x, y, c): 
        figlocate(0, y, x)
        figcolortext(0, c)
        figprints("*")
    fig

for co 1 51 1
    xx randint 1 800
    yy randint 1 600
    c randint 9 14 

    for p -314 314 1
        xs p cos times 40 int plus xx
        ys p sin times 40 int plus yy 
        z pset xs ys c
        next
    next

x lineinput
##########  cat.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

python 
    def figpset(z, x, y, c): 
        figlocate(0, y, x)
        figcolortext(0, c)
        figprints("*")
    fig

function draw oldx oldy x y c
    z pset oldx oldy 0
    z pset x y c
    fig
x
y

function ri u l
    z randint u l return z
    fig

python
    draw(1,1,1,1,0)
    while 1:
        bx = x ; by = y
        d = [(1,1), (1,-1), (-1,1), (-1,-1)][ri(0, 3)]
        x += d[0] ; y += d[1]
        
        if x < 1: x = 1
        if y < 1: y = 1         if y > 80: y = 80
        if y > 80: y = 80
        draw(bx,by,x,y,10)
        figsleep(0,0.1)
    fig


##########  center.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 
width = 80
 text = "this text will center"
 quot = 34  chr
  txt = split text "'"  join txt quot  split txt " "

## center each ##
forin p txt
    half = p  len  times -1  plus width  divby 2  int  
      sp = " "  times half  prints
     now = p  print
    next
##########  dec.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

z : "type multiple lines of text, then ctrl-d to quit." print
z : "(windows users may need to use ctrl-c)" print
z : arrstdin
z : print


##########  dt.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

z "waiting 5 seconds..." print sleep 5
z "the date is: " prints date print
z "there are: " prints timer prints " sec. elapsed since 12:00:00 am" print
z "the time is: " prints time print


##########  edarr.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

ed arr plus 5
ed plus 7
ed print
ed arropen "edarr.fig" print


##########  efig1.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 
#
for cb 0 7 1

    for f 0 15 1
        z colortext f
        z f highlight cb prints
        next

    z "" highlight 0 print
    next 







##########  f.fig  ##########

# diagram may 2015
#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 
function spr p
    px get p #### http://creativecommons.org/publicdomain/zero/1.0/
    forin t px
    ifequal t "*"
        z " " highlight 5 prints highlight 0  
        else
        ifequal t "="
            z " " highlight 1 prints highlight 0
            else 
                s "'"
                ifequal t " "
                    z t prints
                else
                    z t split z "_" join z " " swap z t 
                    q 34 chr colortext 15
                    z t split z "'" join z q highlight 5 prints highlight 0
                    z colortext 7
                    fig
            fig
        fig
    nextin
    z "" print
    fig

p "  **********         *********************         *************    " spr p
p "  *_________**       *____________________**       *____________**  " spr p
p "  *____p______**=====*___'hello_world'______**=====*___print______**" spr p
p "  *_________**       *____________________**       *____________**  " spr p
p "  **********         *********************         *************    " spr p

#p "mtpaint -s # grab screencap" shell

#p "hello" mid 2 1 print
#p "HELLO" mid 2 2 print
#pppp print lineinput prints prints print print 
#p1 "okay" print













##########  figcolor.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

p 5.7  print  colortext 2 
t -12  print  
black        0 
blue         1 
green        2 
cyan         3 
red          4 
magenta      5 
brown        6 
white        7 
gray         8 
lightblue    9 
lightgreen  10 
lightcyan   11 
lightred    12 
pink        13 
yellow      14 
brightwhite 15 

p 5  colortext pink  print

while                                
    rcol  randint 1 15                   
    now "hello "  colortext rcol  prints 
    wend 


##########  figg.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

#!./fig
p "hello, world!" left 5 ucase locate 5 7 prints # comment
x int plus 5 times 7 colortext 11 highlight 1 prints 
y 32 highlight 0 colortext 10 chr prints 

while 

    y 10 print # these indents are optional, they don't do anything 

    iftrue y 
        # this command breaks from while, never from if:
        break 
        fig 

    wend 


##########  figp.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

function printhello
    #z cls # clear screen
    z "hello world" print
    fig
python
    # inline python feature
    for p in range(5):
        printhello()
    fig
z = "hello world, how are you today?" ; split(z, " ") ; print
z "hello world, how are you today?" split z " " print


##########  file.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

john "/tmp/readme" plus ".txt" open "w"
cleese "/tmp/readme2.txt" lcase open "w"

x john #open "w"
x cleese #open "w"

for z 1 5 1
    x z fprint john
    x z times 10 fprint "/tmp/readme2.txt"
    next

x john close prints ":closed" print
x cleese close prints ":closed" print

x "ok" print
x cleese open "r" 
z flineinput cleese prints "*" print
z flineinput cleese prints "*" print
z flineinput cleese prints "*" print
z flineinput cleese prints "*" print
z flineinput cleese prints "*" print
z flineinput cleese prints "*" print
x cleese close prints ":closed" print
x lineinput cls print







##########  funcs.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

function cheese x
    z x minus 1
    for r 0 z 1
        p r print 
        next
    fig

z cheese 5


##########  ge.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

x arr
x arrset 1 "hi"
z arrget x 1 print


##########  hello.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

forin x "hello!"
    z x print
    nextin


##########  hw.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

    # fig
    m = "hello, world!" ; print ; right(12)
    forin x, m
    z = x ; print
    next


##########  ins.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

x : "hey" : instr x "e" print


##########  meh.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

x = "hello, world" : left(2) : plus("y") : ucase : print


##########  mrk.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

p 50 print
p "hello" print 
p 5 arr plus 7 plus 12 print # array of [5, 7, 12]

function p
    z return 7
    fig

x p print # prints 7
p 256 print # and is a numeric again


##########  mtp.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 
p "mtpaint -s" shell
##########  nstr.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 
z : "ls" : arrshell
forin p z
    ck : instr p ".fig"
    iftrue ck 
        x : p : print
        fig
    nextin


##########  p3.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

function ckp ckfp
    ck get ckfp lcase
    b ""  ## leave only alpha
    forin l ck  

        forin a "abcdefghijklmnopqrstuvwxyz"
            ifequal l a
                z b plus l swap z b
                fig
            next

        next
    z b print
    d b reverse 

    ifequal b d 
        z ck print "is a palindrome" print 32 chr print
    else
        z ck print "is not a palindrome" print 32 chr print
        fig

    fig

p ckp "do nine men INTERPRET? nine men, i nod!"












##########  pix.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

python 
    def figpset(z, x, y, c): 
        figlocate(0, y, x)
        figcolortext(0, c)
        figprints("*")
    fig

while
    x randint 0 799
    y randint 0 768
    c randint 0 15
    z pset x y c sleep 0.0001
    wend


##########  rfig.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

cheese "hello" : ucase : left 2 : plus "y" # pipeline

for n 0 1 .1
    throwaway n prints # print has newline; prints, no.
    throwaway 32 chr prints # " " works too
    next # or fig; fig command unindents, next is alias

forin cheddar cheese
    c randint 9 14 colortext c # color uses ansi escapes
    z cheddar print
    next

python
    for p in range(5):
        print "last color value was:", c
fig

x "set x to the following: " prints lineinput 











##########  rs.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

while

    x "type in file to open - " prints lineinput
    ifequal x "quit"
        break
        fig

    p arropen x

    forin lines p
        words split lines " "

        forin z words
            x z sleep .15 print
            nextin

        nextin 

    fig


##########  slow.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

forin p stdin
    now p rtrim print sleep .05
    next


##########  tr.fig  ##########

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

# this is a working fig program
function printhello
    z cls # clear screen
    z "hello world" print
    fig

python
    # inline python feature
    for p in range(5):
        printhello()
    fig

 

 

functions in fig

this is part 7 of an introductory series on fig programming. for part 6, go here.

 

part 7: functions in fig

 

in the previous chapter, we put together some code that asks for (and insists upon) a number.

if youve ever been to a website that rejected some input because it wasnt suitable, the code that does that is very similar. (its likely written in javascript or php though, because those are still very common languages for websites.)

we have learned several fig commands, and there are several more to learn in this chapter– but for the moment we are going to learn how to make new ones. first here is the code from before:

while
    x "please enter a number: " prints lineinput
    try
        y x val
        break
        except
        now "" print "thats not a number." print
        resume
    wend
now y print # this is the number we know is numeric

 

see the now y print at the bottom? the variable y is the one we get when things go right. keep that in mind.

to create a function (a new fig command) called thisthing which uses one parameter: x and converts it to the cosine of x radians, do this:

function  thisthing x
    now  x  cos  return now
    fig

 

ok, but thats not what we are doing. we are going to create a function called asknumeric with zero parameters.

we define our function using a function block:

function asknumeric
    # we really need the pass command here.
    fig

 

and the code inside the block will produce a variable called y, so lets ask the function to return that value (as the functions own value)

function asknumeric
    # our code will go here
    now return y
    fig

 

lets put the two together:

function asknumeric

while
    x "please enter a number: "  prints  lineinput
    try
        y x  val
        break
        except
        now ""  print  "thats not a number." print 
        resume
    wend
now y print # this is the number we know is numeric

    now return y
    fig

 

we can get rid of the “now y print” line:

function asknumeric
while
    x "please enter a number: "  prints  lineinput
    try
        y x  val
        break
        except
        now ""  print  "thats not a number." print 
        resume
    wend
    now return y
    fig

 

okay, run the program…

what? it doesnt do anything. congrats! its your first custom-made fig command.

youve defined it using function but you havent used it yet!

your new function is called asknumeric and always returns a number, so you can use it like this:

x  asknumeric  times 1000  print

 

any time you want to use your asknumeric command, just use it like you would any other fig command. (it will only be available in programs that contain the definition before you use it.)

you can even create a user-defined function that calls another user-defined function:

function doitagain
    x  asknumeric  times 1000  print
    fig
now doitagain

 

lets run this and see what happens…

please enter a number: okay

thats not a number.
please enter a number: yes it is!

thats not a number.
please enter a number: a number

thats not a number.
please enter a number: 5.78
5780

 

one of the more interesting things about writing programs is coming up with names for the different variables (and functions.)

if you pick a name that is too short or not very descriptive– x for example, is really only “descriptive” if youre describing a point on a horizontal axis– then you cause anyone reading your code to suffer a little.

if you pick a name that_is_too_absurdly_long then you cause anyone re-using (referencing) that name to suffer. people dont seem to mind this as much (i do, so i tend not to use very long names.)

if youre writing a manual, it matters somewhat less because people know “x” is always a variable.

but coming up with names is “work” sometimes.

whats more, is coming up with names can get in the way of more pressing or important matters; anything that helps reduce the amount of “overhead” in terms of organizing used and unused variable names is an idea worth considering.

one handy thing about functions is “scope.” if you are defining a function, the name you use to call (reference, refer to) the function– its name– is a thing you have to put some thought into. you want to give it a name that explains what it does, and preferably will also be easy to think of later.

everything inside the function is more or less isolated. this isolation is called “scope,” and it can be viewed as an inconvenience or an enormous help.

if youre writing a large, complicated program, organizing everything into functions is the best thing you can do. (you can also use objects, which are more complicated, and then “functions” will be called “methods” as far as terminology goes. but fig doesnt really get into objects.)

because of this “scope” isolating the stuff inside the function block, you (usually) need a way to get information from the program into the function.

in our first example, information gets into the function by way of the lineinput command. but if you refer to a program variable thats outside of a function youve created, the function will not know anything about it.

put another way: a variable called “cheese” outside the function block is going to have a totally different value / significance / relevance as a variable with the same name inside the function.

this is great because when youre creating a function, you dont have to know what variables are used in the program that calls it. for all you know, “x” is the most important variable in the whole program– so if you need a variable named “x” in your function, its completely separate; the two dont interfere. every function can have its very own “x” variable with its own value.

and every function does get its own variables. but what if you want to get some information from the program into the function? this is done with parameters.

lets name a couple of parameters thing1 and thing2. (you can have 0 or more parameters, even 20 of them. however the smaller the number, the better.) parameters dont need numbers by the way: we are using numbers in the name purely for fun.

function inthehat thing1 thing2
    pass
    fig

 

is a valid definition. lets have it print the number of characters in each parameter:

function inthehat thing1 thing2
    q 34  chr
    now q  plus thing1  plus q  plus " has " prints
    now thing1  len  str plus " characters." print

    now q  plus thing2  plus q  plus " has " prints
    now thing2  len  str plus " characters." print
    fig

 

and lets call the function, with two strings:

now  inthehat "hello" "mike"

 

outputs this:

“hello” has 5 characters.
“mike” has 4 characters.

 

one of the fun things about this code is it adds ascii 34 (a computer code for a double quote) to the string, so the output can display the string in quotes. that would be a useful function, actually:

function quote qstring
q 34  chr
withquotes q  plus  qstring  plus q  print
fig
now "this will be printed in quotes"  quote now

 

it works perfectly, but all it does is build the quotes into the string and print it. wouldnt it be cool if like other built-in functions, it could change the value of the main variable?

well, thats what return is for. lets change one line:

function quote qstring
q 34  chr
withquotes q plus qstring plus q  return withquotes
fig

 

now we have a function we can use anywhere in our program– so long as its after the function definition. lets fix up our other function with it. it does the same as before, with cleaner lines:

function quote qstring
q 34  chr
withquotes q plus qstring plus q  return withquotes
fig

function inthehat thing1 thing2
    now  quote thing1  plus " has " prints
    now thing1  len  str plus " characters." print

    now  quote thing2  plus " has " prints
    now thing2  len  str plus " characters." print
    fig

 

and call it:

now  inthehat "hello" "mike"

 

“hello” has 5 characters.
“mike” has 4 characters.

 

and it works! our function uses the len function (built in) to figure out how many characters the strings have– len will also find the length of an array, but not a numeric. so if you do this:

now  inthehat "hello" 5

 

your function will not work. you can fix this by putting the line that has len in a try / except / resume conditional block, and deciding what to say if it trips the except section.

you can also reword the ” characters.” string so that it says something like “ characters (or array elements).” thats up to your preference, obviously.

hopefully from these examples you can practice writing and editing functions. they are very powerful: half the job of creating your own programming language could be writing functions. fig has more functions built-in, so lets see them:

x  y  lcase  # copy y to x and make all-lowercase


x  y  ucase  # copy y to x and make all-uppercase


x  y  str  # copy y to x and convert num to string 


x  "dir"  shell  # run commands in bash/sh or dos 


x  "hello"  asc  # convert first character in a string to 
                 # numeric ascii code


x  "50.537"  val # convert string number to numeric


x  "hello there"  len  # length of string or array


x  52  not  # return -1 for zero and 0 for non-zero


x  "  space from left"  ltrim # cut lefthand space


x  "space from right  " rtrim # cut righthand space


x  10  chr  # convert integer to ascii / unicode
x  "dir"  arrshell  # load an array with command line output


x  arreverse  # reverse the order of an array


x  y  reverse  # copy string y to x and reverse


x  arrsort  # sort an array


x "hello"  left 2  # get leftmost 2 characters


x "hello"  right 2  # get rightmost 2 characters
    

x  arrget rr 5  # set x to 5th item of array rr


rr arrset 5 "hello" # set 5th item in rr to "hello"


x  y  mid 5 1  # copy y to x, and set x to a range/section of 1 
               # character(s) or item(s) starting with the 
               # 5th. (works on strings and arrays.)


p  string 12 104  # string of 12 x  ascii 104


p  string 12 "h"  # string of 12 x  "h"


x  instr "hello" "e"   # finds the first instance of "e” in 
                       # "hello” and returns the position; which 
                       # in this case is 2 (0 if not found.)


x  "/"  chdir  # changes the folder the program is working in.


now  end  # quits the program (closes files too)


now  system  # exactly the same as end


now  swap x y  # switches the values of x and y


now  get parametername  # earlier versions of fig required this 
                        # to copy parameters inside functions; 
                        # it is no longer required, but can still 
                        # be used to copy variables into the main
                        # variable.


x  split "hello" "e"  # split string by "e" into array ['h', 'llo']


e  join x "a"  # join array using "a" in between items

 

splitting by “e” and joining by “a” will change all instances of “e” to “a” in a string. you can create a function called replace like this:

function replace changewhat chfrom chto
    p  split changewhat chfrom  join p chto 
    now  return p     
    fig

 

then you can call it this way:

phrase "hello there"  replace phrase "he" "a"

 

here are a couple more functions you can use; basic and python (therefore fig) use radians for angles in trig functions. perhaps you would like to use degrees:

(all the code in this book is in the public domain / has its copyright waived under cc0, so feel free to use these functions in your programs)

function degrees2radians dg
    pi 1  atn  times 4   
    rd dg  times pi  divby 180  return rd    
    fig
function radians2degrees rd
    pi 1  atn  times 4   
    dg rd  times 180  divby pi  return dg    
    fig

 

 

 

conditionals in fig

this is part 6 of an introductory series on fig programming. for part 5, go here.

 

part 6: conditionals in fig

 

weve covered a couple kinds of block so far:

  • python marks lines written in python, then fig ends the block
  • while marks lines that will loop, then wend marks the bottom of the lines that will repeat
  • forin and for mark the beginning of a loop through numbers or arrays, and nextin or next marks the bottom of those loops

 

now we have another kind of block:

  • a condition describes part of the state of the running program, and:
  • the lines inside the block only run if the condition is satisfied / true

 

normally the “part of the state” is just the value of a variable.

like with python these blocks will end with the fig command. here is a very simple example:

iftrue 1
    now "that is true"  print
    fig

 

an iftrue conditional has one parameter, and if the parameter is “true” (non-zero) then it will run the code inside the block (between the conditional and the fig command.)

in the previous example, 1 is non-zero so it runs the code in the block:

now "that is true"  print

 

what isnt true? a zero, or a zero-length string:

iftrue ""
    now "this will not print"  print
    fig

 

so what about iffalse? for that, fig has a command that will invert a conditional, but first lets talk about blocks without code inside:

iftrue ""
    fig

 

will give you an error message when it runs. use pass as your placeholder for actual code:

iftrue ""
    pass
    fig

 

the ifequal conditional will compare two parameters, and is true if they are equal:

x "when is your birthday?"  print lineinput
d date

ifequal x d
    pass
else
    x "a very happy un-birthday to you!"  print
    fig

 

this program (assuming you type the date in using mm/dd/yyyy format) asks you to type in your birthday, and if the date is not today’s date, it wishes you a happy un-birthday.

the else command separates a conditional block into a two-part conditional block:

  • if the first part is true, it runs the code between the condition, and else
  • if the first part is NOT true, it runs the code between else and the bottom of the conditional

 

lets use the randint function with its “lowest” and “highest” parameters to product a number between 1 and 10. then ask the user to guess the number:

x randint 1 10
y  "guess a number from 1 to 10: "  print  lineinput

ifequal x y
    now "you guessed correctly!"  print
else
    now "good try, but you didnt guess it."  print
    fig

 

something is wrong with this program, and it will never work the way its intended to. but we can fix it!

the randint command returns an integer, but lineinput returns a string. when ifequal compares an integer and a string, it will NOT detect a match even when one is string “5” and the other is numeric 5!

we can fix this by making the value from randint into a string using str, or making the output from lineinput into a numeric using val. since we dont know what to expect from lineinput (the user could type anything) we will convert the randint:

x randint 1 10  str
y  "guess a number from 1 to 10: "  print  lineinput
ifequal x y
    now "you guessed correctly!"  print
else
    now "good try, but you didnt guess it."  print
    fig

 

by adding str to the end of the randint output, we ensure that when ifequal compares it to the number the user types in, at least a string is being compared to a string.

there are other improvements worth making, but for now this is good enough. (which commmands will compensate for extra spaces on either side of what the user types in?)

this is a great time to add a while loop. currently the user has one guess, and we could give an exact number of guesses with a for loop, but that wouldnt demonstrate a while loop doing something truly functional, would it? lets give unlimited guesses, so you can see how to do that:

while
    x randint 1 10  str
    y  "guess from 1 to 10: "  print  lineinput

    ifequal x y
        now "you guessed correctly!"  print
        break
    else
        now "good try, though."  print
        fig
    wend

 

4 things to notice here: the while at the top– the wend at the bottom– plus, a correct guess stops the loop using break after telling you that you guessed correctly.

but perhaps the most important thing is the line with randint on it. because once again, it will not work (exactly) the way that we intend it to:

while
    x randint 1 10  str
    y  "guess from 1 to 10: "  print  lineinput

 

do you see whats happening? it gets a random number and gets the user to input a guess. ok… when it loops, it gets another random number!

since the number is always 1-10, the user can just keep guessing 5 (or any other number in range) until the computer picks the users number randomly! so lets have it pick the number ONCE:

    x randint 1 10  str
while
    y  "guess from 1 to 10: "  print  lineinput

    ifequal x y
        now "you guessed correctly!"  print
        break
    else
        now "good try, though."  print
        fig
    wend

 

now it works the way it is designed to: the user has to keep guessing a different number until they can guess the one the computer picked.

but now that youve seen the while loop work in a way that the program can get out with a conditional break, lets replace it with a for loop so we can limit the number of guesses the user gets:

guesses 4
x randint 1 10  str
for r  1 guesses 1
    y  "guess from 1 to 10: "  print  lineinput

    ifequal x y
        now "you guessed correctly!"  print
        break
    else
        now "good try, though."  print
        fig
    next

 

we didnt have to change wend to next, it just looks more reasonable that way. also we didnt have to make a variable called guesses, we couldve just put a 4 between the 1 and 1. but this is clearer.

lets take a look at the output this program will show the user, along with the numbers the user might type in:

guess from 1 to 10:
5
good try, though.
guess from 1 to 10:
2
good try, though.
guess from 1 to 10:
8
you guessed correctly!

 

how about another condition to say the user ran out of guesses? the for loop keeps track of which guess the user is on, in the r variable, right? we can use that:

guesses 4
    x randint 1 10  str
for r  1 guesses 1
    gsss guesses  minus r  plus 1  str
    y "you have " plus gsss  plus " guesses."  print
    y  "guess from 1 to 10: "  print  lineinput

    ifequal x y
        now "you guessed correctly!"  print
        break
    else
        now "good try, though."  print
        ifequal guesses r
            now "sorry, no more guesses."  print
            fig
        fig
    next

 

here are the relevant lines of the changes we made:

guesses 4
    x randint 1 10  str
for r  1 guesses 1
    gsss guesses  minus r  plus 1  str
    y "you have " plus gsss  plus " guesses."  print

 

also:

        now "good try, though."  print
        ifequal guesses r
            now "sorry, no more guesses."  print
            fig

 

these two changes dont need each other; the second change would still work by itself, and the stuff at the top could work without the bottom part.

lets go over what we know:

  • the for loop will repeat guesses times, which in this case is 4.
  • the loop tracks which repeat (which guess) its on, in the variable r.
  • so if r is the same number as guesses, it is on the last guess (in this case, it was already used.)

 

that pretty much explains the part at the bottom. it doesnt run until after the program tells the user they guessed wrong, so if guesses is the same number as r, the last guess was used.

what about the top part? this is just addition and subtraction:

    gsss guesses  minus r  plus 1  str
    y "you have " plus gsss  plus " guesses."  print

 

  • gsss is set to the limited number of guesses (4.)
  • then r (which guess user is on: 1 or 2 or 3 or 4) is subtracted, so if guesses is 4 and r is 1 (first guess) then there are 3 guesses left.
  • but… the user hasnt guessed yet! so we add 1 more:  “plus 1” since guess 1 is still in play.
  • then we convert that number to str and put it in a string between “you have ” and ” guesses.”
  • then we print it.

 

from the top, it looks really complicated. but if you want this functionality, its just:

gsss guesses  minus r  plus 1  str
y "you have " plus gsss  plus " guesses."  print

 

you may find with logic like this, that the
stricter syntax in python is easier to work with.

here is what that looks like:

guesses = 4
from random import randint
x = str( randint(1, 10) )

for r in range(1, guesses + 1, 1):
    gsss = str(guesses – r + 1)
    y = "you have " + gsss + " guesses." ; print y
    y = "guess from 1 to 10: " ; print y
    y = raw_input()

    if x == y:
        print "you guessed correctly!"
        break
    else:
        print "good try, though."
        if guesses == r:
            print "sorry, no more guesses."

 

some of the differences between fig and python:

  • python cares what case you use (normally all-lower. but the same variable name, capitalized differently, counts as two different variables.)
  • parentheses are not usually optional (in fig they are.)
  • you must use = to set a variable, and == to compare (fig requires neither; = can set variables.)
  • functions(are(parenthetical + str(that) + can())) #### become complicated.
  • instead of starting blocks with one command marking the bottom with fig or another command, you have to indent (in fig, this is optional) everything after a block starter. when you are done with the block, you un-indent.
  • colons at the end of a block-starter are generally required, in python.
  • python 3 and python 2 differ from each other in how they use the print command.
  • many commands, like randint, have to be imported.

 

believe it or not, this isnt meant to discourage you from using python. if youre comfortable with mandatory indentation, it can be very beautiful (i wrote fig in python, so i know its a great language.)

but when i try to teach python to people, i noted what gripes came up the most. mandatory indentation is good for some and terrible to others. fig doesnt have it. case-sensitivity is fine for most coders– i preferred basic when it was not case-sensitive (in some dialects it is now.)

if you love python, here is an approximation of the same code in fig, using optional () and = and : and such:

# a program in pure fig code
guesses = 4
x = randint(1, 10) ; str()

for r (1, guesses, 1):
    gsss = guesses ; minus r ; plus 1 ; str()
    y= "You have ";plus gsss;plus " guesses.";print()
    y = "Guess from 1 to 10: " ; print()
    y = lineinput()

    ifequal x, y:
        now = "You guessed correctly!" ; print()
        break
    else:
        now = "Good try, though." ; print()
        ifequal guesses, r:
            now = "Sorry, no more guesses." ; print
            fig
        fig
    fig

 

obviously you cant dress up fig exactly like python (without putting it between python and fig commands, that is) but you can dress up fig, if you want to.

whatever you consider “simple” is what you should stick to code-wise, until you are ready and interested in getting more complicated. when youre ready, there are lots of things to try, including making new fig commands using function and/or inline python. and there are more conditionals!

to review: else inverts a conditional, and pass is a placeholder (in case you dont want to run code for every condition, but you do want to run code for some.)

using a comment # instead of pass will not work in loop and conditional blocks. python is the same way– the pass command does exactly the same thing in python code.

ifequal  x y
    now print "yes"
    fig
ifmore  x y
    now print "yes"
    fig
ifless  x y
    now print "yes"
    fig

 

the ifmore (x, y) conditional is true only if x is more than y.

the ifless (x, y) conditional is true only if x is less than y.

substitute x with some other variable or value; and/or substitute y with some other variable or value.

once you feel confident that you understand conditionals, else and pass, there is a very useful conditional-like block that is very special: the “condition” it handles is an error.

it works like this:

try
    pass
    # try to do this
except
    pass
    # run this code if there was an error before
    resume

 

resume is another substitute / alias for fig which you can use instead (as usual) if you prefer.

try
    x 5  divby 0
except
    x "you cant divide numbers by zero."  print
resume

 

catches a real error. of course no one thats paying attention is going to write “divby 0” in their program, but with divby y the y could be anything; so this example is more useful in a real program than it may first appear.

you dont need to use error catching on every use of the divby command, but its quite often worth it in situations where user input (or even input from a file) is involved.

you can use a try / except / resume to try opening a file that isnt available (or that the user didnt spell the name of correctly,) or you could put it in a loop that tries to convert user input to a numeric, and asks again if it cant:

while
    x "please enter a number: "  prints  lineinput
    try
        y x  val
        # if that didnt trip except, break loop
        break
    except
        now ""  print  "thats not a number."  print
        resume
    wend
now y  str  plus " times 5 is: "  prints
now y  times 5  print

 

that functionality we just created could be used more than once in a program that asks for numbers. lets simplify it before getting into functions:

while
    x "please enter a number: "  prints  lineinput
    try
        y x  val
        break
    except
        now ""  print  "thats not a number."  print
        resume
    wend


now y print # this is the number we know is numeric.

 

 

loops in fig

this is part 5 of an introductory series on fig programming. for part 4, go here. for the next part, go here.

 

part 5: loops in fig

 

this is really the first chapter about “program blocks.”

so far, weve covered one type of block– a snippet of inline python:

python
    y = (5 + 12) * 3  # 51; different than:
    y = 5  + 12  * 3  # 41; (order of ops)
fig

 

this block begins with the python command, and the end is marked with the fig command.

the defining characteristic of a block is probably that it starts and ends with a pair of commands.

in fig, you can end any block with the fig command. but semantically it makes the most sense when it ends a python block, because python means: “here is some python code” and fig means: “get back to the fig code.”

all loops are program blocks, also known as “command blocks.”

between the start and end of the loop blocks are the lines of code that will “loop.”

fig has three kinds of loop: for, while and forin.

the simplest loop is the while loop. lets make a single line of code to print a zero:

x  print

 

now lets start a while block by putting it on the line before the one we just wrote:

while
x  print

 

we need to mark the end of a loop, or fig will loop every line that comes after the while command:

while
x  print
fig

 

there is nothing wrong with this block; its perfectly formed. however, while blocks have their own end marker, which you can optionally use in place of the standard fig command. it does exactly the same thing, but helps note which block it ends:

while
x  print
wend

 

so you can end a while block using the fig command, or you can end it using wend (it stands for while-end.) the choice is up to you, they are interchangeable.

the while command exists in basic, python and even c. in basic and python, you can use while true: or while 1: to keep looping until the loop breaks with break or (in basic) exit while.

since for more than half a decade, ive used while 1 in python instead of worrying about setting up the loop with a condition, fig is designed this way for simplicity.

while
x  print
wend

 

prints 0 (or an array stored in x, where applicable) repeatedly until the user breaks with ctrl-c on the keyboard.

besides ctrl-c, the other way to break out of a while loop is using the break command (same as in python,) but without a conditional (covered in the next chapter) a break command will either prevent the loop itself, or prevent the lines inside it from running:

while
x  "this only runs once-- no loop"  print
break
wend

 

the break command stops the loop right after it runs the code inside it once, so it is as if the while command isnt there at all; only the line that prints.

while
break
x  "this line doesnt run at all"  print
wend

 

moving the break command to before the other line inside the loop exits before the lines after it can even run– so this entire block does nothing other than waste a tiny amount of time.

in order to make a while loop do something useful, you probably want to put the break command inside a conditional block. we will get to those in the next chapter.

a forin loop will loop through the items in an array, running the same code inside the block for each one. these items can be lines of a file, lines in a website, letters of a string, pieces of a string made into an array by split– any array.

lets do words in a string, by splitting the string into an array by spaces:

names "ady susan kerry morgan lori"  split names " "
forin p names
    now p  print
    fig

 

fig will split the string by ” ” to make an array called names, and print each one:

ady
susan
kerry
morgan
lori

 

we end the forin loop using fig again, but just as while has wend for (optional) semantic use, forin has nextin (or next). use whichever you prefer.

forin p names
    now p  print
    nextin

 

if you want to loop through numbers, you can use a for loop. a forin loop will run the same code repeatedly, once per array item– and a for loop once per number in a range– for has 4 parameters:

  • the variable for will set with the value of the current item (just like a forin loop)
  • the number to start with
  • the number to stop at
  • the “step”; the number to increase on each loop

 

in other words:

for v start stop step

 

suppose we want to bring variable size from 5 to 12, doing every whole number in that range:

for size  5 12 1
    now size  prints " " prints
    next

 

will output: 5 6 7 8 9 10 11 12

odd numbers from 33 to 17?

for s 33 17  -2
    now s  prints " " prints
    next

 

33 31 29 27 25 23 21 19 17

one quirk of python is that it insists on integer (whole number) steps in numeric ranges. in python (which is what fig translates its code to,) a for (range) loop isnt going to do a decimal step.

for v start stop step # step has to be integer
    now v  print
    next

 

however, if you use a constant for the step instead of a variable, fig will let you do a float step:

start 5
stop 10
for v start stop 2.5 # step is constant 2.5
    now v  prints " " prints
    next

 

outputs: 5.0 7.5 10.0

this builds a different kind of loop (actually a custom while loop) in the python translation, instead of a genuine for loop.

in the next chapter, while loops will become more useful when they can start and stop based on conditions. certainly you can use them anyway, in any situation where using ctrl-c on the keyboard to stop looping is suitable.

 

 

basic math in fig

this is part 4 of an introductory series on fig programming. for part 3, go here. for the next part, go here.

 

part 4: basic math in fig

 

y 5  plus 12  times 3

 

adds 12 to 5, then multiplies times 3.

fig always goes left to right. if you want to do parentheses and order of operations, use python:

y 0  # most important part right here
python
y = (5 + 12) * 3 # 51; different than:
y = 5  + 12  * 3 # 41; (order of ops)
fig

 

set y in python, to 5 + 12… then * 3

then reset y as 5… + (12 * 3) or: 5 + 36

inline python, unlike the rest of the fig language, requires specific indentation. lines begin at 4 spaces from the left, and each indent increases by 4 spaces.

python is not really part of the fig language; but fig allows you to include snippets of python in your fig programs. since fig translates to python, those sections will be included un-translated.

notice that before y is used in the python code, fig sets y to 0 before switching to inline python.

y 0

 

ensures that fig knows y is a valid variable in use, so that after python uses it fig already has it registered. after the inline python runs, fig will use the value python left it with.

you can avoid this extra step if you know that y is already:

  • used as a main variable in fig at least once
  • has a value that the python code can use or reset

 

y 0
python
y = 5
fig
x y  minus 2.5  print

 

sets y to 0, uses python to change it 5, sets x to y  minus 2.5, (which is 2.5) and prints x.

plus and times also work on strings and arrays.

x  minus 5

 

sets x to -5. does this by setting x to 0 and subtracting 5 from x.

y 200
x y  divby .5

 

sets y to 200, copies y to x and divides by .5

x 25  oct print

 

why do programmers mix up halloween and christmas?

because oct 31 is dec 25.

decimal        octal        hex
0     16       0   20       0 10
1     17       1   21       1 11
2     18       2   22       2 12
3     19       3   23       3 13
4     20       4   24       4 14
5     21       5   25       5 15
6     22       6   26       6 16
7     23       7   27       7 17
8     24       10  30       8 18
9     25 <--   11  31 <--   9 19
10    26       12  32       a 1a
11    27       13  33       b 1b
12    28       14  34       c 1c
13    29       15  35       d 1d
14    30       16  36       e 1e
15    31       17  37       f 1f
x 255  hex

 

sets x to “0xff”

x 50
y 70
r 40
x2 3.14  cos  times r  plus x  int
y2 3.14  sin  times r  plus y  int

 

sets x2 to the cosine of 3.14 radians, multiplies
that by r, and adds x then converts to an integer.

then sets y2 to the sine of 3.14 radians, multiplies that by r, and adds y then converts to an integer.

if instead of 3.14, you use another variable that starts at -3.14 and increases in value until it is equal to 3.14, this will plot a circle on points (x2, y2).

x 1  atn  times 4

 

sets x to the arctangent of 1 and multiplies that by 4, which gives pi to at least 11 decimal places.

x 3.14  tan

 

sets x to the tangent of 3.14 radians.

x 2.5  int

 

sets x to 2.5 and converts to an integer.

x -5  sgn

 

changes x to either -1 (if the value is below 0) or 1 if the value is above 0. if the value is 0, it stays the same.

in this case, x becomes -1.

x 25  sqr

 

sets x to 25, and then to the square root (5).

x 255  mod 7

 

sets x to 255, then to 255 modulus 7.

x 1024  topwr 2

 

sets x to 1024, then 1024 to the power of 2.

 

 

output commands in fig

this is part 3 of an introductory series on fig programming. for part 2, go here. for the next part, go here.

 

part 3: output commands in fig

 

while input commands get information from a device (or file, or connection, or from some part of the computer,) output commands send information to a device, or file, connection, or to some part of the computer.

obvious output devices are the screen and speakers. sending files to the printer counts as output, although the printer itself also sends information back to the computer, making it an input/output device.

a touchscreen is a separate device than the screen itself and an input device, although the display directly behind it is for output. these are technical distinctions and not always important, but are sometimes relevant to programming.

x  "hello there"  print

 

sets x to a string and sends x to stdout, which generally means the screen (or window.)

x  "hello there"  prints

 

like the previous line using print, except prints stays on the same line instead of advancing.

x   "text.txt"  open "w"
y   "ok"        fprint x
now x           close

 

you would normally find these used separately.

the first line sets x to a string containing the path and filename of the file to save information to; then it opens the file for writing (the “w”.)

the fprint command writes the value of the main variable to x, which is still holding the filename. in this case, the string “ok” is saved.

the close command will update / save / stop writing to a file that was opened before. it closes whatever file is specified by the main variable. dont close the file until youre done fprinting (each and every line you want to save) to it.

each time you open a file for writing, it starts writing at the beginning. python lets you “append” or add to a file, which could even be added as a feature to fig.

(it doesnt have that feature yet. if it did, you would open “a” for append, instead of “r” for read or “w” for write.)

if you need to, you can already add to a file this way:

  • open to an array using arropen
  • open again using open “w”
  • write the array with the existing information using fprint, before adding to it.

 

writing an array using fprint is possible by using a loop, or by turning the array into a string, using join. both loops and the join command are covered in later chapters.

most languages use a filenumber or handle to track an open file; which is a different thing than a string or a numeric variable. ive always thought that is weird or unfriendly for beginners.

for python coders and the extra curious: fig keeps the handles in a special type of array called a dictionary, with strings as the key to each handle. fig coders dont need to worry about any of that, so long as they make certain to use the same string (contents) to close or fprint that they used to open it.

in other words, if you use the string “../text.htm” with the open command, you will need exactly the string “../text.htm” to read or write or close that
file. it doesnt matter if it’s a constant (written out) or two variables holding the same value, as long as theres a perfect match.

for what its worth, ending the program with end or system (or just letting the program stop normally) is supposed to close all the files that are still open.

x  cls

 

clears (and goes to the top left of) the screen.

x  display

 

the first time this is called, it turns off graphics auto-updating (the default is to update every time you use a graphics command.)

if already called once, display updates the screen with any graphics that were drawn to it. this only affects the graphics windows, not “text-mode” graphics.

textmode

 

forces text-mode graphics– or dont try to display graphics commands in a graphics window; display them using ansi and unicode text codes.

graphics

 

the default mode; open a graphics window when any graphics commands are used. if the graphics window fails (perhaps pygame is not installed) then fig falls back to text-mode graphics.

if textmode was used explicitly, the graphics command turns real graphics back on.

x  line 5 7  10 20  14

 

draws a line from point (5, 7) to point (10, 20) in yellow– where (5, 7) is the 5th dot horizontally and the 7th pixel vertically.

x  pset 5 7 10

 

draws a point at (5, 7) in light green.

x  locate row column

 

move to (row, column) on text screen.

x  colortext 5

 

changes text color to magenta:

0 black         8 grey
1 blue          9 l. blue
2 green         10 l. green
3 cyan          11 l. cyan
4 red           12 l. red
5 magenta       13 pink
6 brown         14 yellow
7 white         15 b. white

 

x highlight 0

 

changes text background to black:

0 black         4 red
1 blue          5 magenta
2 green         6 brown
3 cyan          7 white