coding: math operators with strings

in basic, the way to concatenate strings could have gone like this:

p$ = concat$(a$, b$)

however, someone thought it was better to overload the addition + operator:

p$ = a$ + b$

this also works in python:

p = a + b

python took this a step further… arrays can also be concatenated:

p = a + b
# [‘a’, ‘b’] + [‘c’, ‘d’] = [‘a’, ‘b’, ‘c’, ‘d’]

and multiplied:

p = a * 2
# [‘a’, ‘b’] * 2 = [‘a’, ‘b’, ‘a’, ‘b’]

as can strings:

p = a * 2
# “allo” * 2 = “alloallo”

but thats about it.

there is a split function in python that can turn a string into an array:

“suppose you have this string”

and you want to split it by a space: ” ”

the syntax for that is:
“suppose you have this string”.split(” “)

this gives you the array:

[‘suppose’, ‘you’, ‘have’, ‘this’, ‘string’]

why doesnt it make sense to use divide for that? it probably does:

“suppose you have this string” / ” ” =
[‘suppose’, ‘you’, ‘have’, ‘this’, ‘string’]

what happens if you split “hello” with “e”?

“hello” / “e” = [‘h’, ‘llo’]

this is still what the split command in python does. we are just using division as shorthand, in the tradition of + for concatenation and * for string multiplication.

python lets you multiply an array by a number, but not an array by a string. but if we use division as shorthand for split (string -> array), what about its complement, join (array -> string)?

[‘h’, ‘llo’] * “e” = “hello”

nonsense, right? well, is this easier?

“e”.join([‘h’, ‘llo’])

thats a real python expression. if we can agree that division is an appropriate shorthand for split, then multiplication is an appropriate shorthand for join.

in basic, you can add “5” to “hello” though you cant add 5 to “hello.”

its a type issue. in js, typing is weak and you can add numeric 5 to string “hello”:

“hello5”

i think its better to return an error, in case a numeric is not expected.

python is dynamically typed, but not weakly typed. it lets the same variable hold a string or a numeric, but it doesnt let you add a string to a numeric:

TypeError: cannot concatenate str and int objects

so whether this should produce “hello5” depends on the type conventions of the language, imo.

if we are dividing “hello” with “there”, then “there” does not go into “hello” — since it cant divide it, the string should not be divided:

“hello” / “there” = “hello” (this is what split does in python as well.)

due to this convention, a string should not be able to divide itself. a number divided by itself would produce “1” — we can translate “1” as “one character”

“hello” / “hello” = “h” #### is this useful?

or as “one string”:

“hello” / “hello” = “hello”

5 / 5 = 1, but also: 1 (string) / 1 (string) = 1 (string.)

should we be able to divide a string by “” ? no, python doesnt allow that, and numbers dont either. whats the string equivalent of a divide by zero error? it already exists in python:

ValueError: empty separator

but suppose we got rid of this error. we could make “hello” / “” evaluate to:

* “hello”
* “hello” or “h”
* or “”

personally i would be inclined to say that “hello” / “” returns an error, or is “hello”

what do i base that on?

languages exist to allow the expression of ideas.

so i base it on the idea: “what would the average coder expect it to do?”

…within reason.

if you multiply “pete” times 5, you get: “petepetepetepetepete” right?

i mean thats what happens when you add “pete” to “pete” 4 times:

“pete”
“petepete”
“petepetepete”
“petepetepetepete”
“petepetepetepetepete”

so if you divide “petepetepetepetepete” by 5, what should you get?

“pete” yes, thats a logical answer.

but python can step through string bytes in a “for x in string” loop the way basic steps through numbers in a “for w = x to y step z” loop:

for x in “hello”: print x #### this is a lot like dividing a string.

for whatever reason, i think this would be useful:

“petepetepetepetepete” / 5 = [‘pete’, ‘pete’, ‘pete’, ‘pete’, ‘pete’]

and if you do “mid 1, 1” (in fig) on the resulting array:

“petepetepetepetepete” / 5 : mid 1 1

you get:

“pete”

its a thought. perhaps you like “petepetepetepetepete” / 5 = “pete” better. usefulness and expectations may go together here, or work against each other.

can you divide “hello there” by 20?

no. whether you go with:

“petepetepetepetepete” / 5 = [‘pete’, ‘pete’, ‘pete’, ‘pete’, ‘pete’]
or:
“petepetepetepetepete” / 5 = [‘pete’]

dividing “hello there” by 20 gives you bytes that are less than 1.0 in size. you could try bits, but lets not.

“hello there” / 20 =
cannot divide “hello there” by 20.

“hello ” + there = “hello there” in basic.

so what does “hello there” – “there” = ?

“hello ”

what does “hello there” – “e” = ?

in my opinion, it makes the most sense for it to result in “hllo thr” though perhaps you think it should only remove a single e. which one? up to you i guess, i went with all of them.

so there you have it, hopefully practical shorthand inspired by basics + for string concatenation.

some of these could be useful if implemented. leave a comment if theres one you like or do not like.

 

 

 

squeezing a programming introduction into 5 pages– not easy!

once not long ago, i met a person going into a computer-related field of study. she told me that she hated prorgamming “well, not programming, just the teacher.”

as it happens, i wrote fig with just such occasions in mind, and we actually sat down and went through all 7 of its concepts with examples.

i made fig for tutoring, and theres nothing like having someone on hand to answer questions. the problem with programming forums these days is theyre full of people who know “the best way” to do something, and have no idea what “the easy way” is– or theyre convinced the easy way is bad. before you comment, i am a zed shaw fan, but his works are for people interested enough to take the time to teach themselves something–

my goal is to make an introduction simple and effective enough for anyone, regardless of whether they would ever take a computer course or read a book on coding. and while zed shaw can help you learn python, i learned with allen downey and would proably still be more drawn to downey than shaw. its just my preference.

when i meet a person that i think might be interested in coding– or not– and i met another teacher today (who wants to teach art and will soon,) i often go home and spend a few hours writing an intro just for that person. i take everything i know about that person and try to imagine a class with them– and i say what i can.

the goal is not to “convey knowledge.” ive written a ten-chapter pdf for that purpose, if someone wants to teach themselves fig with a ten-chapter pdf. it needs some work, but im working on a gnu/linux distro at the moment (featuring fig, and remastered using fig.)

anyway it will end up being more than “5 pages” on wordpress, but here are the contents of the 5 pages i wrote for this teacher (it prints out to 5 pages, you can probably squeeze it down to 4):

_

coding for non-coders

_

coding is computing– it is foundational, if you learn a little about code you will gain a firmer grasp of computer use.

all software is made of code, and code is even more foundational to software than coding is to computing– all software can be represented with very few elements of code. code can even be used to simulate the function of the computer itself.

the “fig” programming language teaches code through only 7 types of command, and the 7 concepts that go with these command types:

variables – input – output – basic math

loops – conditionals – functions

_

variables usually consist of a name and a value:

this_is_a_name “this is a value”

_

the value is a “string” of characters, it can also be a number:

height_in_cm 7.5

_

to get a value from the user, they can enter it from the keyboard:

this_is_a_name lineinput

_

already that is 2 of 7 concepts (for more examples, a free book on this language exists.) lineinput is an input command– instead of setting the variable this_is_a_name with a string, it is set when the lineinput command runs and the user types a string in by hand.

input gets information from the computer to the running program, and output gets information from the program to the computer– often to the screen, printer, network or speakers.

let’s copy the variable this_is_a_name to another variable:

another this_is_a_name

_

just like when the variable on the left was set using a string or an input command, it can be set from an existing variable:

x “this is a value” # sets x to a string value

x lineinput         # sets x to a string entered as input

x y                 # sets x to the contents of variable y

_

let’s go back to copying this_is_a_name to another:

this_is_a_name lineinput

another this_is_a_name print

_

if it makes it more readable for you, add colons or semicolons or equals signs between parts of the line. in many computer languages this is not optional:

this_is_a_name = lineinput

another        = this_is_a_name : print

_

notice we’ve added a print command to the line. what the print command does is output the main variable to the screen. which variable is the main one? it’s the left-most variable on the line.

this program:

* copies user/keyboard input to a variable (1st line)

* copies that variable to a second variable (2nd line)

* outputs the data in the second variable to the screen (2nd line)

what happens if you try to use print without a main variable? you get a message:

error: shared-line function “print” cannot be used to start a line

_

one of the best things you can learn about computing is that not all error messages are bad. you didn’t break it– this message means you must add a variable to the line of code if you want the computer to understand. it even tells you which line needs one (not shown here.)

functions are the trickest concept in the fig language, and worth saving for after you understand the rest of the language. but we aren’t going to do that… we are going to cover them now and then speed through easier stuff:

function double_it double_what

    now = double_what : times 2 : return now

    fig

_

okay! let’s have an anatomy lesson:

the middle line is a “normal” line of code, and now is the main variable– it isn’t special command.

the indentation, like the colons and equals sign, is optional. the commands function and fig are special commands that go on their “own line” or in other words, there is no main variable on that line.

most commands in fig “share a line” with the main variable.

fig ends the “function definition.” that’s the thing we are going over right now. function begins the function definition– because they are used like the bread of a sandwich, and because the “sandwich” is known as a “block” of code, function and fig are known as “block commands.”

fig is the name of the language we are using, the name of the command that ends the block, and the name of the program that translates the language into something the computer already understands. (in this case a different, mainstream computer language.) as a command it means “let’s get back to fig,” which in this case idiomatically means:

“let’s get out of this command block and back to the rest of the program.”

after function we put the name of the function we are defining, in this case double_it. this is a pretty useless function but a very good function name, as you can pretty much guess what it does.

we could stop there with just function and the name of the function. but we want to send information to the function… and the stuff “inside” the block, the “filling” of our command sandwich, will not touch the rest of the program. this is not because it’s a command block, but because most modern functions isolate inside code.

so we add a “parameter” (and we can add zero, one or more) and name it double_what, so it gives some idea of what the parameter means. it’s not as good a practice (i do it all the time) but you can just call it x or y if you like:

function double_it double_what

    fig

_

there again is the bread of our sandwich. now the filling:

    now = double_what : times 2 : return now

_

we set variable now to the contents of double_what and we use the times command to multiply it by 2. we used a parameter to get the contents of double_what into the function, then we use return now to get the value of our variable back out of the function.

it is true that we have just created a brand new function, a command named double_it. you can use that function anywhere in the program, below the point where it is defined:

now : lineinput : double_it now : print

_

if you type in “allo, ” you will notice the computer responds “allo, allo,” but if you type in 5 the computer will respond with “55“. this is because lineinput creates strings, not numbers:

now : lineinput : val : double_it now : print

_

this line will give you 10 if you enter 5, and 11 if you give it 5.5, but if you give it “allo” it will simply not work. it will even stop running the program to complain how it “could not convert string to float.” (but that’s a hardware issue! to convert a string to float you have to tie a balloon to it.) oh, well.

spoiler alert: the way you fix it is to add an error-trapping conditional to a line in the double_it function using the val command, and if there’s an exception you simply return the parameter concatenated without the float conversion…

and that, friends, is why the code of a function is easier to read and write than it is to follow a single line of english, accurately describing what the function does. by the way, “float” is short for “floating-point value,” or what non-coders call “decimal numbers.”

the purpose of a function is to organize code into sections that are more manageable:

human langage … computer language

* words … commands

* sentences … lines

* paragraphs … functions

_

ok, functions aren’t exactly like paragraphs, and they’re reuseable. but just as you would rather read a book that broke the lines up into paragraphs, you would much rather read a large program that separated lines (especially redundant lines) into functions. as with paragraphs, it makes everything much easier.

having covered the most complicated part of the language, and including: variables – input – output – basic math – functions

_

we still have loops:

while

    # code goes here / repeats until it calls the break command

    wend

_

and conditionals:

iftrue variablename

    # code goes here / only runs if variable contains “non-zero”

else

    # code goes here / only runs if variable is 0 or 0-length

    fig

_

ifmore variable1 variable2

    # code runs if var1 > var2

    fig

_

ifless variable1 variable2

    # code runs if var1 < var2

    fig

ifequal variable1 variable2

    # code runs if var1 = var2

    fig

_

and in five pages, that’s “coding” summarized, or as it is also known: “computer programming!” admittedly, it might take more than a 5-page introduction to connect these concepts to applications.

_

okay, i know there are no “fun activities” here, and that would certainly help. it would also make the entire thing longer, and it is already 5 pages. if you play your cards right and wait for the right opportunity, the right introduction, you can hand someone 5 pages. they might use it, they might get a taste of the subject, but they wont just read a book until theyre ready to. at least, this was for one person who might not.

this isnt necessarily a good intro for anyone else– ive written others. i took the first two chapters of my book and converted those to a graphical summary.

certainly the best intro to computers will give someone an opportunity to try the language; thats where the realization actually comes into play. fig is designed for interaction, but like basic once was i tried to make it as much as possible a language that can be used to easily explain concepts– earlier in this blog is a work of fiction that explains those concepts as well: https://codeinfig.wordpress.com/2016/02/12/the-robot-hypnotist/

 

 

distdiff 0.1 – compare 2 .isos and squashfs contents using md5deep

usage: distdiff iso1.iso iso2.iso

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

proginf = "distdiff 0.1, aug 2016 mn"

# this program is FREE SOFTWARE and comes with NO WARRANTY

debinstall_md5deep 0

function cmd
python
    from sys import argv as figargv ; return figargv[1:]
    fig
    fig

function plusquotes st mvar
    q 34  chr  #plus "\\" reverse
    qq q  times 2
    now mvar  plus " "  plus q  plus st  plus q  split now qq  join now q  return now
    fig

function orph mvar
   ck instr mvar "/"
   iftrue ck
       mlen mvar  len  minus  ck
       now mvar  right mlen  return now
   else
       now  return mvar     
       fig
   fig

e 0
try
f1 cmd mid 1  1 
f2 cmd mid 2  1 rtrim
f3 "."
#f3 cmd mid 3 1 rtrim

pwd "pwd" arrshell mid 1 1
whoami "whoami" arrshell mid 1 1
e 1

ifequal whoami "root"

iftrue debinstall_md5deep 
    now "echo installing md5deep ; apt-get install -y md5deep 2> /dev/null > /dev/null" shell
    fig

now "mkdir  " plusquotes f3 now plus "/1 2> /dev/null" shell
now "mkdir  " plusquotes f3 now plus "/2 2> /dev/null" shell
now "mkdir -p " plusquotes f3 now plus "/1/iso/1 2> /dev/null" shell
now "mkdir -p " plusquotes f3 now plus "/2/iso/1 2> /dev/null" shell
now "mkdir  " plusquotes f3 now plus "/1/sqfs 2> /dev/null" shell
now "mkdir  " plusquotes f3 now plus "/2/sqfs 2> /dev/null" shell

now "mount " plusquotes f1 now  plus " 1/iso/1" shell
now "mount " plusquotes f2 now  plus " 2/iso/1" shell

onesq "find 1 | egrep -i '.sfs$|.squashfs'" arrshell  
sqlen onesq len minus 1
onesq left sqlen #print 

num 
forin sq onesq
inc num val  plus 1  str  swap inc num
now "mkdir 1/sqfs/"  plus num  plus " 2> /dev/null"  shell
now "mount " plusquotes sq now  plus " 1/sqfs/" plus num   shell
next

twosq "find 2 | egrep -i '.sfs$|.squashfs'" arrshell  
sqlen twosq len minus 1
twosq left sqlen #print 

num 
forin sq twosq
inc num val  plus 1  str  swap inc num
now "mkdir 2/sqfs/"  plus num  plus " 2> /dev/null"  shell
now "mount " plusquotes sq now  plus " 2/sqfs/" plus num   shell
next

#now "mount | egrep 'iso|1|2'" shell

try
o "md5deep -of -sr 1" arrshell 
except
pass
resume

try
p "md5deep -of -sr 2" arrshell 
except
pass
resume

now "umount " plusquotes f3 now plus "/1/sqfs/* 2> /dev/null" shell
now "umount " plusquotes f3 now plus "/2/sqfs/* 2> /dev/null" shell
now "umount " plusquotes f3 now plus "/1/iso/1  2> /dev/null" shell
now "umount " plusquotes f3 now plus "/2/iso/1  2> /dev/null" shell

function ckl p
plen p len
r "" arr times plen plus 2
forin each p
md5 split each " " mid 1 1   
ck pwd len plus 37
pathlen each len minus ck
iftrue ck
path each right pathlen  orph path  orph path 
else
path ""
fig
now md5  plus " "  plus path
r arrset plen now
ckplen plen minus 1 swap ckplen plen
#ckplen plen mod 250
#ifequal ckplen 0
#now plen prints " " prints
#fig
next
now return r
fig

o ckl o 
p ckl p 

xc
yc

#z "in "  plus f1  print
forin y o
yin instr p y sgn
ifequal yin 0
z "< " prints
z y print
else
z "= " prints
z y print
fig
next

z ""  print
forin x p
xin instr o x  sgn
ifequal xin 0
z "> " prints
z x  print
#else
#z "= " prints
#z x  print
fig
next
now ""  print
 
else    
    now whoami
    e 1
    now "sudo distdiff " plusquotes f1 now  plusquotes f2 now   now shell
    
    fig

except

ifequal e 0
z proginf print "usage: distdiff iso-file1 iso-file2" print "" print end
fig

resume