# ARRAYS

assert.notOk = def(val): assert.ok(not val)

# immutables
none_1st = [ None, 1, 'x']
a = [4,5,6,7]
aa = [1,
        2,
        3]

# mutables
class Item:
    pass
i0 = Item()
i1 = Item()
i2 = Item()
b = [i0, i1]

# access and slicing
assert.equal(len(a), 4)
assert.equal(a[-1], 7)
assert.equal(a[-2], 6)
assert.deepEqual(a[1:3], [5,6])
assert.deepEqual(a[:3], [4,5,6])
assert.deepEqual(a[2:], [6,7])
assert.ok(7 in a)
assert.ok(i1 in b)
assert.ok(i2 not in b)
assert.ok(3 in aa)

# assignment
a[-1] = 9
assert.equal(a[-1], 9)

# extended slices
b = [0 to 10]
s = 'abcde'
assert.deepEqual(b[::2], [0, 2, 4, 6, 8, 10])
assert.deepEqual(b[::-1], range(10,-1,-1))
assert.deepEqual(b[7:0:-1], [7, 6, 5, 4, 3, 2, 1])
assert.deepEqual(b[7:1:-2], [7, 5, 3])
assert.equal(s[::2], 'ace')
assert.equal(s[::-1], 'edcba')
assert.equal(s[4:0:-1], 'edcb')
assert.equal(s[4:1:-2], 'ec')

# strings
assert.ok("tes" in "this is a test")

one = "one"
two = "two"
one, two = two, one
[x, y, z] = 'x', 'y', 'z'
(t, u, v) = 1, 2, 3
assert.equal(one, "two")
assert.equal(two, "one")
assert.equal(x, 'x')
assert.equal(y, 'y')
assert.equal(z, 'z')
assert.deepEqual([v, u, t], [3, 2, 1])


# DICTIONARIES
d0 = {'a':'b','c':2, d:		'd',}
d1 = {
	'foo': 1,
	"bar": "baz",
	"fun1": def():
		return 5
	,
	fun2: def(c):
		return c+1
}
# arbitrary indentation inside
{a:1, 1:
 1
   }
# pound sign in comments and strings
d2 = {
    'aaa': 'bbb',   # with comments
    'ccc': '#fff'
}

# access
assert.ok('foo' in d1)
assert.equal(d0.a, d0['a'])
assert.equal(d1['fun1'](), 5)
assert.equal(d1.fun2(3), 4)
assert.equal(len(d0), 3)
assert.deepEqual(d2, {'aaa': 'bbb', 'ccc': '#fff'})

# assignment
d1["bar"] += "!"
assert.equal(d1.bar, "baz!")

# nested comparisons
x = 3
assert.ok(1 < x <= 3)
assert.ok(1 < x*x > 3)
assert.ok(1 < (x+=1) < 5) # check that only one increment occurs
assert.equal(x, 4)

# list comprehensions
e0 = [i*i for i in [0,1,2,3]]
e1 = [x+y for x, y in enumerate(range(5,0,-1))]
e2 = [e0+1 for e0 in range(6) if e0%3]
assert.deepEqual(e0, [0,1,4,9])
assert.deepEqual(e1, [5,5,5,5,5])
assert.deepEqual(e2, [2,3,5,6])
hash = {
    "foo": 1,
    "bar": 1,
    "baz": 1,
}
assert.deepEqual(Object.keys(hash), [k for k in hash])

# dict comprehensions
alphabet = ['A', 'B', 'C', 'D', 'E', 'F']
d2 = {key: key.charCodeAt(0) for key in alphabet}
assert.deepEqual(d2, {
    'A': 65,
    'B': 66,
    'C': 67,
    'D': 68,
    'E': 69,
    'F': 70
})
# not supported yet
d3 = {String.fromCharCode(n): n for n in [65 to 70]}
assert.deepEqual(d3, d2)

# common collection methods
collection = [1 til 50]

assert.equal(sum(collection), collection.reduce(def(a, b): return a + b;))

remap = def(a): return a**2-1
assert.deepEqual(map(remap, collection), collection.map(remap))

grep = def(a): return a%3
assert.deepEqual(filter(grep, collection), collection.filter(grep))

# identity vs equality
func = def(): pass
list1 = [1,3,7, 'foo', [1 to 10], {'a': 1, 'b': None, 'c': func, 'd': {'bar': [4 to 12]}}, 'baz']
list2 = [1,3,7, 'foo', [1 to 10], {'a': 1, 'b': None, 'c': func, 'd': {'bar': [4 to 12]}}, 'baz']
list3 = [1,3,7, 'foo', [1 to 10], {'a': 1, 'b': None, 'c': func, 'd': {'bar': [4 til 12]}}, 'baz']
list4 = list1
assert.ok(list1 is list4)
assert.ok(list1 == list2)
assert.notOk(list1 is list2)
assert.notOk(list1 == list3)

# SETS
s0 = Set(['foo', 'bar', 'baz'])
assert.ok('baz' in s0)
assert.notOk('qux' in s0)
s1 = Set()
s1.add('baz')
s1.add('foo')
assert.notOk(s0 == s1)
s1.add('bar')
assert.ok(s0 == s1)
list5 = [x for x in s0].sort()
assert.ok(['bar', 'baz', 'foo'] == list5)
