Created
November 3, 2011 10:35
-
-
Save judy2k/1336226 to your computer and use it in GitHub Desktop.
IO Exercises
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Io Typing | |
========= | |
Io> 1 + 1 | |
==> 2 | |
Io> 1 + "one" | |
Exception: argument 0 to method '+' must be a Number, not a 'Sequence' | |
--------- | |
message '+' in 'Command Line' on line 1 | |
Io> "one" + 1 | |
Exception: Io Assertion 'operation not valid on non-number encodings' | |
--------- | |
message '+' in 'Command Line' on line 1 | |
It looks to me like Io is strongly typed (it didn't attempt to coerce my String | |
into a Number), and dynamically typed. The '+' operator simply refers to a | |
method on the first operand, which is executed, passing the second operand as | |
the only parameter. The only reason adding a string to a number doesn't work is | |
because the '1' object's '+' method doesn't accept a Sequence as its argument, | |
and thus throws an exception. | |
Boolean Coercion | |
================ | |
Io> 0 isTrue | |
==> true | |
Io> 1 isTrue | |
==> true | |
Io> "" isTrue | |
==> true | |
Io> nil isTrue | |
==> false | |
I think the code above pretty much speaks for itself. Took me ages to discover | |
the 'isTrue' method though! | |
Introspection | |
============= | |
Use the slotNames method to get a list of slots. | |
Assignment Operators | |
==================== | |
The = operator attempts to assign to an existing slot and raises an exception | |
if the slot has not been defined. Use this for setting the value of an | |
attribute defined on an object (or it's prototype). | |
The := Does the same, but will create the slot if it does not already exist. | |
Use this for defining 'private' attributes for an object. | |
The ::= operator creates the slot, a getter and setter for the slot, and then | |
assigns the provided value. Use this for creating 'public' values. Having | |
setFoo and getFoo methods are the Io idioms for indicating the public interface | |
for an object. | |
Ref: http://www.iolanguage.com/scm/io/docs/reference/index.html#/Core/Core/Object/newSlot |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env io | |
# Calcualate a fibonacci sequence value in IO. | |
# | |
# The first index is 0, not 1 as indicated in the book. | |
# Sequences should always be indexed from zero! | |
rfib := method(n, | |
if(n < 2, 1, rfib(n-2) + rfib(n-1)) | |
) | |
lfib := method(n, | |
t := 1 | |
a := 1 | |
b := 1 | |
for(i, 1, n-1, | |
t := a + b | |
a = b | |
b = t | |
) | |
t | |
) | |
# Ensure that we get the same values for both implementations: | |
12 repeat(n, ((rfib(n) asString) .. ": " .. (lfib(n) asString)) println) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env io | |
Number oldDiv := Number getSlot("/") | |
Number / := method(n, | |
if(n == 0, 0, self oldDiv(n)) | |
) | |
(6 /2) println | |
(6 /0) println |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env io | |
# It's easy if you know how: | |
List deepSum := method(flatten sum) | |
# This actually took me longer than the line above!: | |
nestedList := list( | |
list( 1, 2, 3 ), | |
list( 10, 20, 30 ), | |
list( 100, 200, 300 ) | |
); | |
# Prints 666: | |
nestedList deepSum println |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env io | |
# I'm avoiding the use of List average as that would pretty much defeat the | |
# purpose of this exercise! | |
# I couldn't bring myself to call it myAverage: | |
List mean := method( | |
if(select(v, (v type) != "Number") size > 0, | |
Exception raise("Contains non-numeric value(s)!")) | |
if(size == 0, 0, sum / size) | |
) | |
"Prints '7.5'" println | |
list(1,2,3,24) mean println | |
# Raises an Exception: | |
# list(1,2,3,"24") mean println | |
# Calculate the Median: Just because I felt like it | |
# ================================================= | |
# Don't know why I did this - I think I was just mildly annoyed by BT's lack | |
# of detail: | |
List median := method( | |
# Ensure List contents are numeric: | |
if(select(v, (v type) != "Number") size > 0, | |
Exception raise("Contains non-numeric value(s)!")) | |
# Empty list returns zero: | |
if(size == 0, 0, | |
middle := size / 2 | |
# Slightly more complicated for even-length lists: | |
if(size % 2 == 0) then ( | |
# Mean of middle two values: | |
return((at(middle - 1) + at(middle)) / 2) | |
) else ( | |
# Middle value: | |
return(at(middle floor)) | |
) | |
) | |
) | |
"Prints '2.5'" println | |
list(1,2,3,24) median println | |
"Prints '3'" println | |
list(1,2,3,4,24) median println | |
# Raises an Exception: | |
# list(1,2,3,"24") median println |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env io | |
TwoDList := Object clone | |
# Decided to implement this as a factory method: | |
TwoDList dim := method(x, y, | |
result := TwoDList clone | |
result rows := list() preallocateToSize(y) | |
y repeat( | |
result rows append(list() setSize(x)) | |
) | |
return result | |
) | |
# Set a cell value: | |
TwoDList set := method(x, y, value, | |
rows at(y) atPut(x, value) | |
return self | |
) | |
# Get a cell value: | |
TwoDList get := method(x, y, | |
rows at(y) at(x) | |
) | |
# Handy print method: | |
TwoDList print := method( | |
"(" println | |
rows foreach(row, | |
(" " .. row join(", ")) println | |
) | |
")" println | |
return self | |
) | |
# Always do the bonus exercise! | |
TwoDList transpose := method( | |
TwoDList result := TwoDList dim(rows size, rows at(0) size) | |
rows size repeat(y, | |
rows at(y) size repeat(x, | |
result set(y, x, get(x, y)) | |
) | |
) | |
return result | |
) | |
# Create a 4 by 5 matrix and print out: | |
matrix := TwoDList dim(4, 5) | |
matrix set(0,0, "0-0") set(3,0, "3-0") | |
matrix set(0,4, "0-4") set(3,4, "3-4") | |
matrix println | |
# Transpose the matrix, print, and ensure the requirements are met: | |
new_matrix := matrix transpose | |
new_matrix println | |
4 repeat(x, | |
5 repeat(y, | |
if (matrix get(x, y) != new_matrix get(y, x)) then ( | |
a := matrix get(x, y) | |
b := new_matrix get(y, x) | |
Exception raise("#{a} and #{b} don't match at (#{x}, #{y}) and (#{y}, #{x})" interpolate) | |
) | |
) | |
) | |
# Write to a file as a non-escaped CSV: | |
TwoDList writeToFile := method(path, | |
out := File openForUpdating(path) | |
rows foreach(row, | |
out write(row join(", ")) | |
out write("\n") | |
) | |
out close | |
return self | |
) | |
matrix writeToFile("matrix_output.txt") | |
# Read a matrix from a poor CSV file: | |
TwoDList readFromFile := method(path, | |
in := File open(path) | |
rows = list() | |
in foreachLine(line, | |
rows append(line removeSuffix("\n") split(", ")) | |
) | |
in close | |
return self | |
) | |
# Read in matrix and print to screen: | |
"Read from file:" println | |
matrix2 := TwoDList dim(0,0) readFromFile("matrix_output.txt") | |
matrix2 println | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env io | |
num := (Random value(99) floor + 1) println | |
stdin := File standardInput | |
10 repeat(i, | |
guess_num := i + 1 | |
guess := (stdin readLine( "Guess #{guess_num} of 10: " interpolate) asNumber) | |
if (guess == num) then ( | |
"Well done! You guessed it!" println | |
break | |
) else ( | |
if(i == 9) then ( | |
"Sorry, you ran out of guesses!" println | |
) elseif (guess < num) then ( | |
"Bigger" println | |
) else ( | |
"Smaller" println | |
) | |
) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment