Main
|
Numbers
|
Concept |
Python |
Chicken |
Numerical Tower?
Does the language support the full numerical tower?
|
Yes (with module: numbers?)
The Python Standard Library - numbers
PEP: 3141
|
Yes (with egg: numbers)
Chicken FAQ
R5RS
|
Integer
A whole number
|
a = 42
type(a)
===> <type 'int'>
|
(define a 42)
(integer? a)
===> #t
|
Floating Point
A binary decimal number, this is not the same as a decimal.
|
a = 41.99
type(a)
===> <type 'float'>
|
(define a 41.99)
(flonum? a)
===> #t
|
Rational Numbers
A rational number is a fraction of two integers.
|
Yes (with module: numbers)
The Python Standard Library - numbers
PEP: 3141
PEP: 239 (Rejected)
PEP: 240 (Rejected)
PEP: 327
|
Yes (with egg: numbers)
numbers documentation
|
Real Numbers
Real numbers include all the rational numbers plus the irrational numbers.
|
import numbers
isinstance(3.14, numbers.Real)
===> True
Python Library Reference - numbers
|
(real? 3.14)
===> #t
Chicken Wiki - Deviations from the standard [6.2.5]
numbers documentation
|
Complex Numbers
Complex numbers are an extension of real numbers obtained by adding an imaginary unit.
|
|
|
Infinity and Negative Infinity
|
float('inf')
===> inf
float('-inf')
===> -inf
Python Library Reference - Built-in types
Rejected PEP-754
|
+inf
===> +inf
-inf
===> -inf
Chicken Wiki - Extensions to the standard
|
Not A Number
|
float('nan')
===> nan
float('-nan')
===> nan
Python Library Reference - Built-in types
Rejected PEP-754
|
+nan
===> +nan
-nan
===> +nan
Chicken Wiki - Extensions to the standard
|
|
Numeral Systems
Numeral systems describe ways to express numbers in writing.
|
|
|
Decimal
Decimal is a base 10 number system.
|
Decimal is default and doesn't have to be specified.
101
===> 101
|
Decimal is default and doesn't have to be specified.
#d101
===> 101
101
===> 101
Chicken Wiki
|
Binary
Binary is a base 2 number system.
|
int('101', 2)
===> 5
New in 2.6
0b101
===> 5
What's new in Python 2.6
PEP: 3127
|
#b101
===> 5
Chicken Wiki
|
Octal
Octal is a base 8 number system.
|
0101
===> 65
New in 2.6
0o101
===> 65
PEP: 3127
|
#o101
===> 65
Chicken Wiki
|
Hexadecimal
Hexadecimal is a base 16 number system.
|
0x101
===> 257
|
#x101
===> 257
Chicken Wiki
|
|
|
Math
|
Concept |
Python |
Chicken |
Addition
|
3 + 5
===> 8
3 + 5 + 8
===> 16
Python Library Reference - Numeric Types
|
(+ 3 5)
===> 8
(+ 3 5 8)
===> 16
|
Subtraction
|
8-5
===> 3
8 - 5 - 3
===> 0
Python Library Reference - Numeric Types
|
(- 8 5)
===> 3
(- 8 5 3)
===> 0
|
Multiplication
|
8 * 5
===> 40
8 * 5 * 3
===> 120
Python Library Reference - Numeric Types
|
(* 8 5)
===> 40
(* 8 5 3)
===> 120
|
Division
|
Currently in the process of changing the division operators. Best to use the new ones to avoid maintaining backward compatibility, do that by importing division from the __future__ module (2 underscores before and after future)
from __future__ import division
8 / 5
===> 1.6000000000000001
8 / 5 / 3
===> 0.53333333333333333
Python Gotchas
|
(/ 8 5)
===> 1.6
(/ 8 5 3)
===> 0.533333333333333
|
Quotient
The integer part of the result of dividing two numbers.
|
from __future__ import division
8 // 5
===> 1
|
(quotient 8 5)
===> 1
|
Remainder
|
8 % 5
3
Python Library Reference - Numeric Types
|
(modulo 8 5)
===> 3
|
Exponent
|
2**3
===> 8
pow(2, 3)
===> 8
Python Library Reference - Numeric Types
|
(expt 2 3)
===> 8
|
Square Root
|
import math
math.sqrt(4)
===> 2.0
|
(sqrt 4)
===> 2.0
|
Absolute Value
|
abs(-42)
===> 42
Python Library Reference - Numeric Types
Python Library Reference - Built-In Functions
|
(abs -42)
===> 42
|
Sum
|
sum([1, 2, 3])
===> 6
Python Library Reference - Numeric Types
|
(define (sum aList) (apply + aList))
(sum '(1 2 3))
===> 6
|
Max
|
max(3, 7, 42)
===> 42
|
(max 3 7 42)
===> 42
|
Min
|
min(3, 7, 42)
===> 3
|
(min 3 7 42)
===> 3
|
|
Comparison Operators
|
|
|
Equal
|
2 == 1+1
===> True
Python Library Reference - Comparisons
|
(= 2 (+ 1 1))
===> #t
|
Not Equal
|
2 != 10
===> True
2 <> 10
===> True
Python Library Reference - Comparisons
|
(not (= 2 10))
===> #t
|
Less Than
|
2 < 10
===> True
Python Library Reference - Comparisons
|
(< 2 10)
===> #t
|
Greater Than
|
2 > 10
===> False
Python Library Reference - Comparisons
|
(> 2 10)
===> #f
|
Less Than or Equal To
|
5 <= 5
===> True
Python Library Reference - Comparisons
|
(<= 5 5)
===> #t
|
Greater Than or Equal To
|
3 >= 5
===> False
Python Library Reference - Comparisons
|
(>= 3 5)
===> #f
|
Is
Compare identity
|
2 is 2
===> True
Python Library Reference - Comparisons
|
(eqv? 2 2)
===> #t
|
Is Not
Compare identity
|
2 is not 2
False
Python Library Reference - Comparisons
|
(not (eqv? 2 2))
===> #f
|
|
Constants
|
|
|
Pi
|
import math
math.pi
===> 3.1415926535897931
|
(define pi 3.1415926535897931)
pi
===> 3.14159265358979
|
e
e
|
import math
math.e
===> 2.7182818284590451
|
(define e 2.7182818284590451)
e
===> 2.71828182845905
|
|
Advanced Math
More advanced mathematical functions.
|
|
|
Sine
|
import math
math.sin(5)
===> -0.95892427466313845
|
(sin 5)
===> -0.958924274663138
|
Cosine
|
import math
math.cos(5)
===> 0.28366218546322625
|
(cos 5)
===> 0.283662185463226
|
Tangent
|
import math
math.tan(5)
===> -3.3805150062465859
|
(tan 5)
===> -3.38051500624659
|
|
|
Variables, Symbols and Names
|
Concept |
Python |
Chicken |
Case Sensitive?
Are names/symbols in the language case sensitive?
|
Yes
|
Yes
|
Names must start with a letter?
|
Yes (or an underscore '_')
|
No
Names must not start with a '#'
|
Allowed Characters in Names
|
a-z, 0-9, _
|
Names cannot contain '(' or ')'
|
|
Variables
|
|
|
Assigning Variables
|
a = 42
a
===> 42
|
(define a 42)
a
===> 42
|
Assigning Multiple Variables
|
a, b, c = 1, 2, 3
[a, b, c]
===> [1, 2, 3]
|
(define-values (a b c) (values 1 2 3))
(list a b c)
===> (1 2 3)
Chicken Wiki - Non-standard Macros and Special Forms
|
Local Variables (Lexical Scoping)
|
def test():
a = 7
return a + 35
test()
===> 42
a
===> NameError: name 'a' is not defined
|
(define (test)
(define a 7)
(+ a 35))
(test)
===> 42
a
===> Error: unbound variable: a
(define (test3)
(let ((a 7))
(+ a 35)))
(test3)
===> 42
a
===> Error: unbound variable: a
|
Global Variables
|
Variables defined at the top-level are global.
a = 5
def printGlobalVar():
print a
printGlobalVar()
===> 5
Set a global variable, this is usually considered bad form:
def setGlobalVar():
global b
b = 5
setGlobalVar()
b
===> 5
|
Variables defined at the top-level are global
(define a 5)
(define (printGlobalVar)
(print a))
(printGlobalVar)
===> 5
Set a global variable, this is usually considered bad style:
(define (setGlobalVar)
(set! b 5))
(setGlobalVar)
b
===> 5
|
Constants
A constant is a special type of variable that is immutable.
|
Python has no way to declare constants, however it is convention that constant variables are named with all caps.
A_CONSTANT = 5
A_CONSTANT
===> 5
A_CONSTANT = 10
A_CONSTANT
===> 10
Message Boards
ActiveState - Constants in Python
|
NOTE: define-constant does not create an "immutable variable". Constants are local to the current compilation unit and are not available outside of the source file in which they are defined.
(define-constant A_CONSTANT 5)
A_CONSTANT
===> 5
(set! A_CONSTANT 10)
A_CONSTANT
===> 10
Chicken Wiki - Non-standard Macros and Special Forms
|
Named Lets
Named lets are a powerful feature, useful for emulating a number of constructs.
|
|
This form is syntactic sugar for a letr
(let countdown ((n 3))
(if (= n 0) (print "Liftoff")
(begin
(print n)
(countdown (- n 1)))))
===> 3
===> 2
===> 1
===> Liftoff
Teach Yourself Scheme in Fixnum Days
|
|
Modifying Variables
|
|
|
Setting Variables
|
a = 1
a
===> 1
a = "hello"
a
===> "hello"
|
Unlike most Schemes set! is allowed to set an undefined variable. However it is usually good practice to define your variables with define and change them with set! as set! is more explicit.
(define a 1)
a
===> 1
(set! a "hello")
a
===> "hello"
Chicken Wiki - Extensions to the Standard
|
Setting Multiple Variables
|
a, b, c = 1, 2, 3
[a, b, c]
===> [1, 2, 3]
a, b, c = 5, 10, 15
[a, b, c]
===> [5, 10, 15]
|
(define-values (a b c) (values 1 2 3))
(list a b c)
===> (1 2 3)
(set!-values (a b c) (values 5 10 15))
(list a b c)
===> (5 10 15)
Chicken Wiki - set!-values
|
Incrementing
|
a = 1
a += 1
a
===> 2
a += 2
a
===> 4
|
(define a 1)
(set! a (add1 a))
a
===> 2
(set! a (+ a 2))
a
===> 4
Chicken Wiki - Unit Library
|
Decrementing
|
a = 4
a -= 1
a
===> 3
a -= 2
a
===> 1
|
(define a 4)
(set! a (sub1 a))
a
===> 3
(set! a (- a 2))
a
===> 1
Chicken Wiki - Unit Library
|
|
Environment Variables
|
|
|
|
|
Comments and Docstrings
|
Concept |
Python |
Chicken |
Inline Comment
|
# This is a comment
def test():
#print "hello"
return 35 + 7 # the answer to everything
test()
===> 42
|
; This is a comment
(define (test)
;(print "hello")
(+ 35 7) ;The answer to everything
(test)
===> 42
|
Block Comment
Syntax for multi-line comments.
|
# Python does not support block comments
#
# just separate paragraphs with one '#'
|
#| This is a block comment
It might be better form not to use these. |#
Chicken Wiki - Non-standard Read Syntax
|
Expression Comment
Syntax for commenting out an entire expression.
|
This is not possible in Python
|
(define (test)
#;(print
"No")
"Yes")
(test)
===> "Yes"
Chicken Wiki - Non-standard read syntax
|
|
Docstrings
A docstring is a comment on a segment of code that is retained during the runtime of a program.
|
|
|
Function and Class Docstrings
|
def add(x, y):
"""return result of X+Y
Docstrings are placed immediately after
function/class definitions and must use
triple quotes. Python style recommends
a one line description followed by a blank
line then a detailed description."""
return x+y
add(3, 8)
===> 11
|
|
Module Docstrings
|
Include a triple quoted string as the first non-comment line in a module.
|
|
Retrieve Docstring
|
> def test(x):
"""Print x
This documentation will show up
when you use help(test)"""
print x
help(test)
===> Help on function test in module __main__:
===>
===> test(x)
===> Print x
===>
===> This documentation will show up
===> when you use help(test)
|
|
|
|
Identity and Equality
|
Concept |
Python |
Chicken |
Identity
|
a = "hello"
id(a)
===> 136954848
|
|
Equivalence
|
a = [1,2]
b = [1,2]
a == b
===> True
a is b
===> False
|
(define a (list 1 2))
(define b (list 1 2))
(equal? a b)
===> #t
(eqv? a b)
===> #f
|
General Equality
|
a = [1,2]
b = [1,2]
a == b
===> True
|
(define a (list 1 2))
(define b (list 1 2))
(equal? a b)
===> #t
|
|
|
Boolean Logic
|
Concept |
Python |
Chicken |
Convert to Boolean
Convert an object to a boolean value (true or false) using standard equality.
|
bool(42)
===> True
bool([])
===> False
Python Library Reference - Built-in Types
|
(define (->bool object) (not (not object)))
(->bool 42)
===> #t
(->bool '())
===> #t
|
True
What evaluates to 'true'.
|
Anything that is not False
bool(42) == True
===> True
Python Library Reference - Built-in Types
|
Everything except #f evaluates to True
(define (->bool object) (not (not object)))
(->bool 42)
===> #t
|
False
What evaluates to 'false'.
|
bool(False)
===> False
bool(None)
===> False
bool([])
===> False
bool('')
===> False
bool({})
===> False
bool(())
===> False
Python Library Reference - Built-in Types
PEP-285
Mailing Lists
|
(define (->bool object) (not (not object)))
(->bool #f)
===> #f
(->bool (void))
===> #t
(->bool '())
===> #t
(->bool "")
===> #t
(->bool (make-hash-table))
===> #t
(->bool (vector))
===> #t
|
None, Nil and Void
|
None
|
(void)
|
|
Boolean Operations
|
|
|
And
Test if all elements are true.
|
1 and 2
===> 2
False and 1
===> False
1 and 2 and 3
===> 3
Python Library Reference - Boolean Operations
|
(and 1 2)
===> 2
(and #f 1)
===> #f
(and 1 2 3)
===> 3
Scheme Tutorial - Logical Composition Operators
|
Or
Test if at least one element evaluates to true.
|
1 or 2
===> 1
False or 1
===> 1
False or False
===> False
False or False or 1
===> 1
Python Library Reference - Boolean Operations
|
(or 1 2)
===> 1
(or #f 1)
===> 1
(or #f #f)
===> #f
(or #f #f 1)
===> 1
Scheme Tutorial - Logical Composition Operators
|
Not
Test if arguments evaluate to not true.
|
not 5 == 4
===> True
Python Library Reference - Boolean Operations
|
(not (= 5 4))
===> #t
Scheme Tutorial - Logical Composition Operators
|
XOR
XOR returns true if one, and only one, of the arguments are true.
|
def xor(a, b):
return bool(a) ^ bool(b)
xor(42, [])
===> True
xor(35, 7)
===> False
xor(False, False)
===> False
Mailing List
def xor(a, b):
return (a and not b) or (b and not a)
xor(42, False)
===> True
xor(35, 7)
===> False
xor(False, False)
===> False
Mailing List
def xor(a, b):
if bool(a) ^ bool(b):
if a: return a
else: return b
else:
return False
xor(3, 5)
===> False
xor(False, 42)
===> 42
xor("hi", [])
===> "hi"
xor([], 0)
===> False
|
(define (xor a b) (if (and a b) #f (or a b)))
(xor 42 #f)
===> 42
(xor 35, 7)
===> #f
(xor #f #f)
===> #f
|
Any
Return true if any argument evaluates to true.
|
any([False, False, 3])
===> True
any([False, False, False])
===> False
Python Library Reference - Built-in Functions
Any odd numbers?
any(x%2 for x in [1, 2, 3])
===> True
any(x%2 for x in [2, 4, 6])
===> False
|
(use srfi-1)
(any (lambda (x) (if x #t #f)) (list #f #f 3))
===> #t
(any (lambda (x) (if x #t #f)) (list #f #f #f))
===> #f
SRFI-1
(use srfi-1)
(any odd? (list 1 2 3))
===> #t
(any odd? (list 2 4 6))
===> #f
|
All
Return true if all arguments evaluate to true.
|
all([1, 2, 3])
===> True
all([1, False, 3])
===> False
Python Library Reference - Built-in Functions
All odd numbers?
all(x%2 for x in [1, 3, 5])
===> True
all(x%2 for x in [1, 2, 3])
===> False
|
(use srfi-1)
(every (lambda (x) (if x #t #f)) (list 1 2 3))
===> #t
(every (lambda (x) (if x #t #f)) (list 1 #f 3))
===> #f
SRFI-1
(use srfi-1)
(every odd? (list 1 3 5))
===> #t
(every odd? (list 1 2 3))
===> #f
|
|
|
Conditionals
|
Concept |
Python |
Chicken |
If
|
if 1 < 2: 'Yes'
===> 'Yes'
if 1 < 2:
'Yes'
else:
'No'
===> 'Yes'
|
(if (< 1 2) "Yes")
===> "Yes"
(if (< 1 2)
"Yes"
;;else
"No")
===> "Yes"
The ;;else line is not required and is almost never used.
|
Unless
Equivalent to 'if not test'.
|
|
Chicken Wiki - Non-standard macros and special forms
Teach Yourself Scheme in Fixnum Days
|
When
Equivalent to 'if test'.
|
a = 1
if a < 5:
print a
a+1
===> 1
===> 2
|
(define a 1)
(when (< a 5)
(print a)
(+ a 1))
===> 1
===> 2
Chicken Wiki - Non-standard macros and special forms
Teach Yourself Scheme in Fixnum Days
|
Multiple Conditions (elif, cond, switch, case)
|
def olderYoungerSame(myAge, yourAge):
if yourAge < myAge:
return "I'm older"
elif yourAge == myAge:
return "We're the same age"
else:
return "You're older"
olderYoungerSame(24, 42)
===> 'You're older'
olderYoungerSame(42, 42)
===> 'We're the same age'
olderYoungerSame(42, 24)
===> 'I'm older'
|
(define (olderYoungerSame myAge yourAge)
(cond
((< yourAge myAge)
"I'm older")
((= yourAge myAge)
"We're the same age")
(else
"You're older"))))
(olderYoungerSame 24 42)
===> "You're older"
(olderYoungerSame 42 42)
===> "We're the same age"
(olderYoungerSame 42 24)
===> "I'm older"
|
|
Pattern Matching
Pattern matching compares arguments by their structure.
|
|
|
|
|
Input and Output
|
Concept |
Python |
Chicken |
String Input
Get a string from the user from standard input.
|
a = raw_input()
hello
a
===> 'hello'
> raw_input()
a
===> 'a'
|
(define a (read-line))
hello
a
===> "hello"
(read-line)
a
===> "a"
Chicken Wiki - Unit extras
|
Expression Input
Evaluate an expression given as input.
|
a = 42
input()
a
===> 42
input()
hello
===> NameError: name 'hello' is not defined
|
(define a 42)
(eval (read))
a
===> 42
(eval (read))
hello
===> Error: unbound variable: hello
|
|
Printing
Writing a string to standard output.
|
|
|
Print
|
print 'hello'
===> hello
|
print both writes to std out and returns its argument.
(print "hello")
===> hello
===> "hello"
|
String Formatting
Write a formatted string to standard output, with the arguments inserted into the string.
|
first = "Jack"
last = "Trades"
print "My name is %s %s." % (first, last)
===> My name is Jack Trades.
Python Library Reference - String Formatting Operations
|
(define first 'Jack)
(define last 'Trades)
(printf "My name is ~S ~S.\n" first last)
===> My name is Jack Trades.
|
String Formatting by Key
|
d = {'first':'Jack', 'last':'Trades'}
print "My name is %(first)s %(last)s." % d
===> My name is Jack Trades.
|
|
Human Readable Output
|
a = "Hello\nWorld\n"
print a
===> Hello
===> World
===>
str(a)
===> 'Hello\nWorld\n'
Newsgroups
Python Library Reference - Data model
An Introduction to Python
|
(define a "Hello\nWorld\n")
(display a)
===> Hello
===> World
Drinkable Chicken
|
Machine Readable Output
|
a = "Hello\nWorld\n"
repr(a)
===> "'Hello\\nWorld\\n'"
a.__repr__()
===> "'Hello\\nWorld\\n'"
Newsgroups
Python Library Reference - Data model
An Introduction to Python
|
(define a "Hello\nWorld\n")
(write a)
===> "Hello\nWorld\n"
Drinkable Chicken
|
Pretty Printing
Given an expression, return a neatly formatted string of that expression.
|
Python Library Reference - Data pretty printer
|
(pretty-print '(define (first sequence) (cond
((list? sequence) (car sequence))
((vector? sequence) (vector-ref sequence 0))
((string? sequence) (string-ref sequence 0)))))
===> (define (first sequence)
===> (cond ((list? sequence) (car sequence))
===> ((vector? sequence) (vector-ref sequence 0))
===> ((string? sequence) (string-ref sequence 0))))
Chicken Wiki - Unit extras
Schematics Cookbook
|
|
|
Functions
|
Concept |
Python |
Chicken |
Defining Functions
|
def someFunc():
print "Hello"
|
(define (someFunc)
(print "Hello"))
|
Passing Arguments
|
def someFunc(a):
print a
someFunc("Hello World")
===> Hello World
|
(define (someFunc a)
(print a))
(someFunc "Hello World")
===> Hello World
|
Returning Values
|
def someFunc(a):
return a
v = someFunc(42)
v
===> 42
|
(define (someFunc a)
a)
(define v (someFunc 42))
v
===> 42
|
Returning Multiple Values
|
def multiValues():
return 1, 2
multiValues()
===> (1, 2)
stackoverflow
stackoverflow
stackoverflow
|
(define (multi-values)
(values 1 2))
(multi-values)
===> 1
===> 2
Scheme FAQ
|
Calling Functions
|
def add(x, y):
return x + y
add(35, 7)
===> 42
add(35, -42)
===> -7
|
(define (add x y)
(+ x y))
(add 35 7)
===> 42
(add 35 -42)
===> -7
|
Calling Functions With Multiple Values
|
def add(x,y): return x+y
def multiValues():
return 1, 2
apply(add, multiValues())
===> 3
|
(define (multi-values)
(values 1 2))
(call-with-values multi-values +)
===> 3
(call-with-values multi-values (lambda (x y) (- x y)))
===> -1
Scheme FAQ
|
|
Arguments
|
|
|
Evaluation Order
|
Left to right.
def p(a): print a
def test(a,b,c,d):
return 3 + -10
test(p(1), p(2), p(3), p(4))
===> 1
===> 2
===> 3
===> 4
===> -7
Python Library Reference - Expressions
|
Unspecified
(define (test a b c d)
(+ 3 -10))
(test (print "1") (print "2") (print "3") (print "4"))
===> 1
===> 2
===> 3
===> 4
===> -7
|
Argument Binding
Early or late binding.
|
Arguments are bound at definition, therefore this function will always return 42.
import random
def r(a=random.randrange(1, 100)):
return a
r()
===> 42
r()
===> 42
r()
===> 42
|
Arguments are bound at runtime, therefore this function will return a random number.
(define (r #!optional (a (random 100)))
a)
(r)
===> 35
(r)
===> 92
(r)
===> 58
|
All Arguments Must Be Supplied?
If you specify a number of arguments to a function must you call that function with the exact number of arguments?
|
def testArgs(a, b, c):
print "Successful"
testArgs(1, 2)
===> TypeError: testArgs() takes exactly 3 arguments (2 given)
|
(define (testArgs a b c)
(print "Successful"))
(testArgs 1 2)
===> Error: Bad argument count - received 2 but expected 3
|
Arbitrary Number of Positional Arguments
|
def arbArgs(a, b, *args):
return [a, b, args]
arbArgs(1, 2, 3, 4, 5)
===> [1, 2, (3, 4, 5)]
arbArgs(1,2)
===> [1, 2, ()]
Python Library Reference - More on Defining Functions
|
(define (arbArgs a b #!rest args)
(list a b args)
(arbArgs 1 2 3 4 5)
===> (1 2 (3 4 5))
(arbArgs 1 2)
===> (1 2 ())
Drinkable Chicken
Scheme FAQ
Chicken Wiki - Extensions to the standard
|
Optional Arguments
|
Behavior emulated by using default arguments that return False
def optionalArgs(a, b=False, c=False):
return [a, b, c]
optionalArgs(1, 2):
===> [1, 2, False]
Python Library Reference - More on Defining Functions
|
If an argument is not given Chicken returns #f for that argument.
(define (optionalArgs a #!optional b c)
(list a b c)
(optionalArgs 1 2)
===> (1 2 #f)
Drinkable Chicken
Scheme FAQ
Chicken Wiki - Extensions to the standard
|
Default Arguments
|
def defaultArgs(a, b="World"):
print a,b
defaultArgs('Hello')
===> Hello World
Python Library Reference - More on Defining Functions
|
To specify additional default arguments enclose each var/value pair in parenthesis.
(define (defaultArgs a #!optional (b "World"))
(print a " " b))
(defaultArgs "Hello")
===> Hello World
Drinkable Chicken
Scheme FAQ
Chicken Wiki - Extensions to the standard
|
Keyword Arguments
|
Keyword arguments can be passed by both key and position.
def keyArgs(a, b=2, c=3):
return [a, b, c]
keyArgs(1, 5)
===> [1, 5, 3]
keyArgs(1, b=10, c=100)
===> (1, 10, 100)
Python Library Reference - More on Defining Functions
|
If #!rest is used with #!key the arguments caught by #!key will also appear in #!rest, there is currently no workaround that I know of.
(define (keyArgs a #!key (b 2) (c 3))
(list a b c))
(keyArgs 1 5)
===> (1 2 3)
(keyArgs 1 b: 10 c: 100)
===> (1 10 100)
Drinkable Chicken
Scheme FAQ
Chicken Wiki - Extensions to the standard
|
Arbitrary Number of Keyword Arguments
|
def keyArgs(a, **kwargs):
return [a, kwargs]
keyArgs(1)
===> [1, {}]
keyArgs(1, y=2, z=3)
===> [1, {'z':3, 'y':2}]
|
#!rest could be used here but it would need some additional logic to associate keys and values.
|
|
Anonymous, Nested and Curried Functions
|
|
|
Anonymous Functions (lambda)
|
a = lambda x: x + 35
a(7)
===> 42
|
(define a (lambda (x) (+ x 35)))
(a 7)
===> 42
The links below describe using case-lambda to handle optional arguments within a lambda form.
Chicken Wiki - Non-standard macros and special forms
SRFI-16
Schematics Cookbook
|
Nested Functions
|
def addn(n):
def add(x, n=n):
return x+n
return add(x)
a = addn(5)
a(2)
===> 7
a(6)
===> 11
|
(define (addn n)
(lambda (x)
(+ x n)))
(define a (addn 5))
(a 2)
===> 7
(a 6)
===> 11
|
Curried Functions
|
curry = lambda func, *args, **kw:\
lambda *p, **n:\
func(*args + p, **dict(kw.items() + n.items()))
def add(a, b, c): return a+b+c
curry(curry(curry(add, 3), 2), 1)()
===> 6
a = curry(add, 3)
b = curry(a, 2)
c = curry(b, 1)
c()
===> 6
dzone snippets
|
Ripped from the Scheme FAQ.
(define (curry f n)
(if (zero? n)
(f)
(lambda args
(curry (lambda rest
(apply f (append args rest)))
(- n (length args))))))
(define foo (curry + 4))
((((foo 1) 2) 3) 4)
===> 10
((foo 1 2 3) 4)
===> 10
(foo 1 2 3 4)
===> 10
Scheme FAQ
(define ((make-adder x) y)
(+ x y))
((make-adder 35) 7)
===> 42
Chicken Wiki - Extensions to the standard
|
|
|
Classes
|
Concept |
Python |
Chicken |
|
|
Modules
|
Concept |
Python |
Chicken |
Import Module Into Current Namespace
Import all identifiers from the module into the current namespace.
|
from math import *
pi
===> 3.1415926535897931
|
(use srfi-1)
(take '(a b c) 2)
===> (a b)
Chicken Wiki - Non-standard macros and special forms
(require-extension srfi-1)
(take '(a b c) 2)
===> (a b)
Chicken Wiki - Non-standard macros and special forms
(require-library srfi-1)
(take '(a b c) 2)
===> (a b)
Chicken Wiki - Non-standard macros and special forms
While inside a (module ...) definition
(module test ()
(import scheme))
Chicken Wiki - Modules and macros
|
Import Module
|
import math
math.pi
===> 3.1415926535897931
|
(module math (pi)
(import scheme)
(define pi 3.14159265358979))
(import (prefix math math.))
math.pi
===> 3.14159265358979
Chicken Wiki - Modules and Macros
|
Import Module as
|
import math as m
m.pi
===> 3.1415926535897931
|
(module math (pi)
(import scheme)
(define pi 3.14159265358979))
(import (prefix math m.))
m.pi
===> 3.14159265358979
Chicken Wiki - Modules and Macros
|
From Module Import
Import only specific identifiers from module.
|
from math import pi
pi
===> 3.1415926535897931
|
(module math (pi)
(import scheme)
(define pi 3.14159265358979))
(import (only math pi))
pi
===> 3.14159265358979
Chicken Wiki - Modules and Macros
|
From Module Import as
|
from math import pi as PIE
PIE
===> 3.1415926535897931
|
(module math (pi a)
(import scheme)
(define pi 3.14159265358979)
(define a 42))
(import (rename (only math pi) (pi PIE)))
PIE
===> 3.14159265358979
a
===> Error: unbound variable: a
Chicken Wiki - Modules and Macros
|
Executing a Module as a Script
|
if __name__ == "__main__":
print "Code here will run as a program"
Python Library Reference - Modules
|
|
|
Creating a Module
|
|
|
Create a Module
|
A python module is any .py file. Save the following line in a file test.py
def add(x, y): return x + y
Then fire up the interpreter
import test
test.add(35, 7)
===> 42
|
(module name (add)
(import scheme)
(define (add x y) (+ x y)))
(import (prefix name name.))
(name.add(35 7))
===> 42
|
Exporting Identifiers
|
All identifiers in a module are exported by default. To export only specific identifiers use the __all__ special method.
Python Library Reference - Modules
stackoverflow
|
Only specified identifiers will be exported. The list directly after the module name specifies these identifiers, in this case it exports only (a b).
(module test (a b)
(import scheme)
(define a 42)
(define b "hello")
(define c "world"))
(import (prefix test test.))
test.a
===> 42
test.b
===> "hello"
test.c
===> Error: unbound variable: test.c
|
|
|
Errors and Exceptions
|
Concept |
Python |
Chicken |
Example Error
|
1+'a'
===> Traceback (most recent call last):
===> File "<stdin>", line 1, in <module>
===> TypeError: unsupported operand type(s) for +: 'int' and ^^-> 'str'
|
(+ 1 "a")
===> Error: (+) bad argument type: "a"
===>
===> Call history:
===>
===> <eval> (+ 1 "a") <--
|
Default Exceptions
|
Exception Base Classes:
BaseException, Exception, StandardError, ArithmeticError, LookupError, EnvironmentError
Built-in Exceptions:
AssertionError, AttributeError, EOFError, FloatingPointError, GeneratorExit, IOError, ImportError, IndexError, KeyError, KeyboardInterrupt, MemoryError, NameError, NotImplementedError, OSError, OverflowError, ReferenceError, RuntimeError, StopIteration, SyntaxError, SystemError, SystemExit, TypeError, UnboundLocalError, UnicodeError, UnicodeEncodeError, UnicodeDecodeError, UnicodeTranslateError, ValueError, VMSError, WindowsError, ZeroDivisionError
Warnings:
Warning, UserWarning, DeprecationWarning, PendingDeprecationWarning, SyntaxWarning, RuntimeWarning, FutureWarning, ImportWarning, UnicodeWarning
Python Library Reference - Built-in Exceptions
|
arity, type, arithmetic, i/o, i/o file, i/o net, bounds, runtime, runtime limit, match, syntax, breakpoint
|
|
Catching Errors
|
|
|
Catch Any Exception
|
def add(x, y):
try:
return x+y
except:
return 'Error'
add(3, 4)
===> 7
add('3', 'a')
===> Error
|
(define (add x y)
(condition-case (+ x y)
((exn) 'Error)))
(add 3 4)
===> 7
(add "3" "a")
===> 'Error
Chicken Wiki - Unit library
|
Catch a Specific Exception
|
from __future__ import division
def div(x, y):
try:
return x / y
except TypeError:
return "type error"
div(9, 3)
===> 3.0
div("3", "a")
===> 'type error'
div(7, 0)
===> ZeroDivisionError: float division
Python Library Reference - Errors and Exceptions
|
(define (div x y)
(condition-case (/ x y)
((exn type) 'typeError)))
(div 9 3)
===> 3
(div "3" "a")
===> 'typeError
(div 7 0)
===> Error: (/) division by zero
Chicken Wiki - Unit library
|
Catch a Specific Exception and Any Other Exception
|
from __future__ import division
def div(x, y):
try:
return x / y
except TypeError:
return "type error"
except:
return "some other error"
div(9, 3)
===> 3.0
div("3", "a")
===> 'type error'
div(7, 0)
===> 'some other error'
Python Library Reference - Errors and Exceptions
|
(define (div x y)
(condition-case (/ x y)
((exn type) 'typeError)
((exn) "some other error")))
(div 9 3)
===> 3
(div "3" "a")
===> 'typeError
(div 7 0)
===> "some other error"
Chicken Wiki - Unit library
|
Try Allows Multiple Expressions?
|
a = 0
b = 0
try:
a += 1
b = 5
except:
False
a
===> 1
b
===> 5
|
(define a 0)
(define b 0)
(condition-case
(begin
(set! a (+ a 1))
(set! b 5))
((exn) 'False))
a
===> 1
b
===> 5
|
|
Throwing Errors
|
|
|
Signal an Error
|
Python Library Reference - Errors and Exceptions
|
Chicken Wiki - Unit library
|
|
|
Looping
|
Concept |
Python |
Chicken |
|
For
|
|
|
For
For loop controlled by a count.
|
Python's range() function actually produces a list of integer values, so this is actually a 'For Each' loop.
for ii in range(3):
print ii
===> 0
===> 1
===> 2
An Introduction to Python - range() Function
Python Library Reference - More Control Flow Tools
Dive Into Python - for loops
|
SRFI-1's iota function actually produces a list of integers which we then iterate over like a 'For Each'.
(use srfi-1)
(define-syntax for
(syntax-rules (in)
((for element in alist body ...)
(for-each (lambda (element) body ...) alist))))
(for ii in (iota 3)
(print ii))
===> 0
===> 1
===> 2
A Scheme Syntax-Rules Primer
R5RS - Control Features
Mailing Lists
|
For Each
For loop that iterates over each item in a collection.
|
for ii in [0, 1, 2]:
print ii
===> 0
===> 1
===> 2
Python Library Reference - More Control Flow Tools
Dive Into Python - for loops
|
(for-each (lambda (ii) (print ii)) '(0 1 2))
===> 0
===> 1
===> 2
R5RS - Control Features
(define-syntax for
(syntax-rules (in)
((for element in alist body ...)
(for-each (lambda (element) body ...) alist))))
(for ii in '(0 1 2)
(print ii))
===> 0
===> 1
===> 2
A Scheme Syntax-Rules Primer
R5RS - Control Features
Mailing Lists
|
|
While
|
|
|
While
|
ii = 0
while ii < 5:
ii += 1
print ii
===> 1
===> 2
===> 3
===> 4
===> 5
Python Library Reference - Compound Statements
|
(define-syntax while
(syntax-rules ()
((while condition body ...)
(let loop ()
(if condition
(begin
body ...
(loop))
(void))))))
(define ii 0)
(while (< ii 5)
(set! ii (+ ii 1))
(print ii))
===> 1
===> 2
===> 3
===> 4
===> 5
A Scheme Syntax-Rules Primer
Teach Yourself Scheme in Fixnum Days
Schematics Cookbook
|
|
Recursion
|
|
|
Support for Tail-Call Optimization?
Will the language properly transform tail recursive functions into iterative ones?
|
No
|
Yes, TCO is required for compliance with the Scheme standard.
|
Are Recursive Functions Supported?
|
Yes
def recursiveFunction(x):
if x == 3:
print x
else:
print x
recursiveFunction(x+1)
recursiveFunction(1)
===> 1
===> 2
===> 3
|
Yes, recursion and TCO are part of the Scheme standard
(define (recursiveFunction x)
(if (= x 3)
(print x)
(begin
(print x)
(recursiveFunction (+ x 1)))))
(recursiveFunction 1)
===> 1
===> 2
===> 3
|
|
|
Comprehensions
|
Concept |
Python |
Chicken |
Comprehensions Part of the Core Language?
|
Yes
|
No
SRFI-42 is not installed by default, to install it use the chicken-install program from the command line:
$ sudo chicken-install srfi-42
|
|
List Comprehensions
|
|
|
List Comprehensions
Iterate over each item in a sequence performing an operation with that item and accumulating the result in a list.
|
The Python entries for List Comprehension should probably be moved to Vector Comprehensions, as Python Lists are more like Vectors in most other languages.
[ii for ii in range(5)]
===> [0, 1, 2, 3, 4]
[ii*2 for ii in range(5)]
===> [0, 2, 4, 6, 8]
Python Library Reference - Data Structures
An Introduction to Python - List Comprehensions
|
SRFI-42 is not installed by default, to install it use the chicken-install program from the command line:
$ sudo chicken-install srfi-42
(use srfi-42)
(list-ec (: x 5) x)
===> (0 1 2 3 4)
(list-ec (: x 5) (* x 2))
===> (0 2 4 6 8)
Drinkable Chicken - Simple List Comprehensions
Drinkable Chicken - Cool listcomp, revisited
SRFI-42
SRFI-42 Reference Implementation
Eager Comprehensions for Black Belts
Eager Comprehensions in Scheme (PDF)
Newsgroups
|
Conditional Comprehensions
Iterate over each item in a sequence, if it satisfies a condition, perform an operation with that item and accumulate the results in a list.
|
[ii for ii in range(10) if x % 2 == 0]
===> [0, 2, 4, 6, 8]
words = ['hi', 'hello', 'bye', 'cya', 'goodbye']
[word for word in words if len(word) <= 3]
===> ['hi', 'bye', 'cya']
Python: List Comprehensions
|
(use srfi-42)
(list-ec (: ii 10) (if (even? ii)) ii)
===> (0 2 4 6 8)
(define words '("hi" "hello" "bye" "cya" "goodbye"))
(list-ec (: ii words) (if (< (string-length ii) 4)) ii)
===> ("hi" "bye" "cya")
|
Nested Comprehensions
|
[[(x,y) for y in range(2)] for x in range(3)]
===> [[(0, 0), (0, 1)], [(1, 0), (1, 1)], [(2, 0), (2, 1)]]
|
(list-ec (: x 3) (list-ec (: y 2) (list x y)))
===> (((0 0) (0 1)) ((1 0) (1 1)) ((2 0) (2 1)))
|
|
Vector Comprehensions
|
|
|
Vector Comprehensions
|
|
(vector-ec (: ii 3) ii)
===> #(0 1 2)
|
|
String Comprehensions
|
|
|
String Comprehensions
|
|
(string-append-ec (: ii 3) ii)
===> "123"
(string-ec (: ii '(#\a #\b #\c)) ii)
===> "abc"
|
|
Hash Table Comprehensions
|
|
|
|
|
Types
|
Concept |
Python |
Chicken |
Find Type of Object
|
a = 42
type(a)
===> <type 'int'>
b = 'hello'
type(b)
===> <type 'str'>
|
(define (type s)
(cond
((boolean? s) 'boolean)
((symbol? s) 'symbol)
((char? s) 'char)
((vector? s) 'vector)
((null? s) 'null)
((pair? s) 'pair)
((number? s) 'number)
((string? s) 'string)
((procedure? s) 'procedure)))
(type 42)
===> number
(type "hello")
===> string
(type 's)
===> symbol
|
Make New Type
|
|
|
|
Numeric Types
|
|
|
Integer
|
a = 42
type(a)
===> <type 'int'>
b = int("42")
type(b)
===> <type 'int'>
Python Library Reference - Built-in Types
|
(define a 42)
(integer? a)
===> #t
R5RS - Numbers
|
Floating Point
|
a = 41.99
type(a)
===> <type 'float'>
b = float("41.99")
type(b)
===> <type 'float'>
Python Library Reference - Built-in Types
|
(define a 41.99)
(real? a)
===> #t
R5RS - Numbers
|
Long Integer
|
2,147,483,648 and above are considered long integers.
a = 2147483648
type(a)
===> <type 'long'>
b = long("42")
type(b)
===> <type 'long'>
Python Library Reference - Built-in Types
|
R5RS - Syntax of Numerical Constants
|
Complex Number
|
Python Library Reference - Built-in Types
|
R5RS - Numbers
|
|
Sequence Types
|
|
|
Linked List
|
|
(define a (list 1 2 3))
(list? a)
===> #t
|
Array or Vector
|
a = [1, 2, 3]
type(a)
===> <type 'list'>
b = list((1, 2, 3))
type(b)
===> <type 'list'>
|
(define a (vector 1 2 3))
(vector? a)
===> #t
a
===> #(1 2 3)
|
String
|
a = "abc"
type(a)
===> <type 'str'>
b = str(42)
type(b)
===> <type 'str'>
|
(define a "abc")
(string? a)
===> #t
|
Hash Table or Dictionary
|
a = {'a':1, 'b':2, 'c':3}
type(a)
===> <type 'dict'>
b = dict([['a', 1], ['b', 2], ['c', 3]])
type(b)
===> <type 'dict'>
|
(define a (alist->hash-table '((x . 1) (y . 2) (z . 3))))
(hash-table? a)
===> #t
|
|
Other Types
|
|
|
Boolean
|
a = True
type(a)
===> <type 'bool'>
b = False
type(b)
===> <type 'bool'>
c = bool("hi")
type(c)
===> <type 'bool'>
Python Library Reference - Built-in Types
|
(define a #t)
(boolean? a)
===> #t
(define b #f)
(boolean? b)
===> #t
(define (->bool arg) (not (not arg)))
(define c (->bool "Hi"))
(boolean? c)
===> #t
|
Character
|
Python does not have a character type, just use the string type.
a = "c"
type(a)
===> <type 'str'>
|
(define a #\c)
(char? a)
===> #t
|
|
|
OS Integration
|
Concept |
Python |
Chicken |
OS Type
What Operating System is running?
|
import os
os.name
===> 'posix'
import sys
sys.version
===> '2.6.2 (release26-maint...'
Python Library Reference - Misc. OS Interfaces
|
(software-type)
===> unix
(software-version)
===> linux
Chicken Wiki - Unit library
|
|
Working with the Language
|
|
|
Get a List of Command Line Arguments
|
sys.argv
===> ['']
Dive Into Python
|
(argv)
===> ("csi")
Chicken Wiki - Unit library
|
Get and Set the Search Space for Importing Modules
|
sys.path()
===> ['/usr/lib/python2.5', ...]
sys.path.append(newSearchPath)
sys.path()
===> ['/usr/lib/python2.5', newSearchPath, ...]
Python Library Reference - sys
|
|
Run Function Before Exit
Run a function before the program exits.
|
Only one function, without arguments, can be run.
sys.exitfunc(funcName)
Python Library Reference - sys
|
|
Exit Program
|
sys.exit()
Python Library Reference - sys
|
(exit)
Chicken Wiki - Unit library
|
Get Language Version
|
import sys
sys.subversion
===> ('CPython', 'branches/release26-maint', '')
Python Library Reference - sys
|
(chicken-version)
===> "4.0.0"
(chicken-version #t)
===> "Version 4.0.0 - SVN rev. 13887..."
Chicken Wiki - Unit library
|
|
Shell Access, Processes and Forking
|
|
|
Execute a Shell Command
|
import os
os.system("ls")
Python Library Reference - os
|
(system "ls")
Chicken Wiki - Unit library
|
|
Working with the Filesystem
|
|
|
Get Current Working Directory
|
import os
os.getcwd()
===> '/home/trades'
Python Library Reference - os
|
(use posix)
(current-directory)
"/home/trades"
Chicken Wiki - Unit posix
|
Change Current Working Directory
|
import os
os.getcwd()
===> '/home/trades'
os.chdir('..')
os.getcwd()
===> '/home'
os.chdir('trades')
os.getcwd()
===> '/home/trades'
Python Library Reference - os
|
(use posix)
(current-directory)
===> "/home/trades"
(change-directory "..")
(current-directory)
===> "/home"
(change-directory "trades")
(current-directory)
===> "/home/trades"
Chicken Wiki - Unit posix
|
List Contents of Directory
|
import os
os.listdir(os.getcwd())
===> ['Desktop', 'Articles', 'scripts']
os.listdir('/home/trades/test')
===> ['doc1', 'doc2', 'doc3']
Python Library Reference - os
|
(use posix)
(directory (current-directory))
===> ("Desktop" "Articles" "scripts")
(directory "/home/trades/test")
===> ("doc1" "doc2" "doc3")
Chicken Wiki - Unit posix
|
Make Directory
|
import os
os.mkdir(PATH)
Python Library Reference - os
|
(use posix)
(create-directory PATH)
Chicken Wiki - Unit posix
|
Remove Directory
|
import os
os.rmdir(PATH)
Python Library Reference - os
|
Directory must be empty to delete.
(use posix)
(delete-directory PATH)
Chicken Wiki - Unit posix
|
Remove Directory (Recursive)
|
import os
os.removedirs(PATH)
Python Library Reference - OS
|
testing
|
Rename File or Directory
|
import os
os.rename(OLD, NEW)
Python Library Reference - os
|
(rename-file OLD NEW)
Chicken Wiki - Unit library
|
Remove File
|
import os
os.remove(PATH)
Python Library Reference - os
|
(delete-file PATH)
Chicken Wiki - Unit library
Will not signal an error.
(delete-file* PATH)
Chicken Wiki - Unit files
|
Copy File
|
|
(use files)
(file-copy OLD NEW)
Chicken Wiki - Unit files
|
Move File
|
|
(use files)
(file-move OLD NEW)
Chicken Wiki - Unit files
|
File Exists?
|
import os
os.path.exists(PATH)
Python Library Reference - os.path
|
(file-exists? PATH)
Chicken Wiki - Unit library
|
|
|
Eval
|
Concept |
Python |
Chicken |
Eval
Evaluate arbitrary expressions.
|
eval("2 + 3")
===> 5
Python Library Reference - Built-in Functions
|
Evaluates quoted expressions, not strings.
(eval '(+ 2 3))
===> 5
R5RS - Eval
Chicken Wiki - Unit eval
|
Exec
Evaluate arbitrary statements.
|
exec "a = 42"
a
===> 42
exec("b = 7")
b
===> 7
Python Language Reference
|
Evaluates quoted expressions, not strings.
(eval '(define a 42))
a
===> 42
R5RS - Eval
Chicken Wiki - Unit eval
|
|
|
Compiling
|
Concept |
Python |
Chicken |
Compiled or Interpreted?
Is the current program compiled or interpreted?
|
|
(test-feature? 'csi)
===> #t
(test-feature? 'script)
===> #f
(test-feature? 'compiling)
===> #f
Chicken Wiki - Tips and Tricks
Mailing List - Chicken-users
|
Compile a Source File
|
|
Drinkable Chicken - Compiling Chicken Code (part 1)
Drinkable Chicken - Compiling Chicken Code (part 2)
|
|
|
Interfacing with C
|
Concept |
Python |
Chicken |
|
|
Data Structures
Strings, lists, arrays, vectors, hash maps and more...
|
Strings
A string is an ordered sequence of letters, numbers and/or symbols.
|
Concept |
Python |
Chicken |
String Literals
A string literal is a representation of a string within the source of a program.
|
aString = "World"
bString = 'World'
Multi-line string
cString = """Hello
World"""
cString
===> Hello\nWorld
Discover Python
The Python Tutorial
|
(define aString "Hello")
Multi-line string
(define bString "Hello
World")
bString
===> Hello\nWorld
Multi-line string constant. Anything up to a line equal to TAG (or other specified value, or end of file) will be returned as a single string.
(define s #<<TAG
"Hello World!" is the standard
intro program.
TAG
)
s
===> "\"Hello World!\" is the standard\nintro program."
Chicken Wiki - Non-standard read syntax
|
String?
Is the object a string?
|
type('hello') == type(' ')
===> True
|
(string? "hello")
===> #t
R5RS
|
Escape Character
An escape character changes the meaning of the subsequent character.
|
a = "Escape the \" \" in a string"
a
===> 'Escape the "" in a string'
print a
===> Escape the "" in a string
|
(define a "Escape the \" \" in a string")
a
===> "Escape the \" \" in a string"
(print a)
===> Escape the " " in a string
===> "Escape the \" \" in a string"
R5RS
|
Length
Get the length of a string in number of characters.
|
len("myString")
===> 8
|
(string-length "myString")
===> 8
R5RS
Drinkable Chicken
|
|
Conversion
Converting a string into another type, or another type into a string.
|
|
|
ASCII
|
ASCII is the default character encoding
a = str(unicode('hello'))
a
===> 'hello'
|
|
Unicode
|
a = unicode('hello')
a
===> u'hello'
|
Chicken FAQ
|
Number To String
Convert a numeric type to a string.
|
str(42)
===> '42'
|
(->string 42)
===> "42"
(number->string 42)
===> "42"
Chicken Wiki
|
String To Integer
|
a = "42"
b = int(a)
b
===> 42
type(b)
===> <type 'int'>
|
(define a "42")
(define b (string->number a))
b
===> 42
(integer? b)
===> #t
|
String To Float
Convert a string to a floating point number.
|
a = "42.01"
b = float(a)
b
===> 42.009999999999998
type(b)
===> <type 'float'>
|
(define a "42.01")
(define b (string->number a))
b
===> 42.01
(flonum? b)
===> #t
|
Characters To String
Convert a sequence of characters to a string.
|
Python does not have a character type.
''.join(['h', 'e', 'l', 'l', 'o'])
===> 'hello'
|
(string #\h #\e #\l #\l #\o)
===> "hello"
R5RS
|
String To Characters
Convert a string to a sequence of characters.
|
[ii for ii in 'hello']
===> ['h', 'e', 'l', 'l', 'o']
|
(string->list "hello")
===> (#\h #\e #\l #\l #\o)
|
List To String
Convert a list of values to a string.
|
''.join(['b', 'y', 'e'])
===> 'bye'
''.join([1, 2, 3])
===> TypeError: sequence item 0: expected string, int found
|
(list->string '(#\b #\y #\e))
===> "bye"
(list->string '(1 2 3))
===> Error: (list->string) bad argument type - not a character: 1
R5RS
SRFI-13
|
String To List
Convert a string to a list of values.
|
[ii for ii in 'hello']
===> ['h', 'e', 'l', 'l', 'o']
[ii for ii in 'hello'[1:3]]
===> ['e', 'l']
|
(string->list "hello")
===> (#\h #\e #\l #\l #\o)
To specify a substring you must import srfi-13
(use srfi-13)
(string->list "hello" 1 3)
===> (#\e #\l)
R5RS
SRFI-13
|
Arbitrary Object to String
|
str(42)
===> '42'
|
(->string 42)
===> "42"
Chicken Wiki
|
Integer To Character (ASCII)
Given an integer value, return the ASCII character associated with that value.
|
chr(80)
===> 'P'
Python Library Reference
|
(integer->char 80)
===> #\P
Schematics Cookbook
|
Character To Integer
Given a character, return the ASCII integer value of that character.
|
ord('P')
===> 80
Python Library Reference
|
(char->integer #\P)
===> 80
Schematics Cookbook
|
|
Indexing, Splitting and Joining
|
|
|
Character Indexing
Obtaining a single character from a string by its position.
|
"Sample"[1]
===> 'a'
"Sample"[-1]
===> 'e'
|
(string-ref "Sample" 1)
===> #\a
(string-ref "Sample" -1)
===> Error: (string-ref) out of range
The next entry has a version of string-ref that supports negative indexing
R5RS
(define (neg-string-ref aString index)
(if (< index 0)
(string-ref aString (+ (string-length aString) index))
(string-ref aString index)))
(neg-string-ref "Sample" -1)
===> #\e
|
Substring (Slice)
Get a portion of the string.
|
"Sample"[1:3]
===> 'am'
"Sample"[-2:]
===> 'le'
|
Python's behavior can be emulated by writing a new function 'pysubstring' that simply subtracts the negative numbers from the length of the string to get the index.
(substring "Sample" 1 3)
===> "am"
(substring "Sample" -2 -1)
===> Error: (substring) index out of bounds
R5RS
Drinkable Chicken
|
Chop String
Return a list of substrings cut at a given interval.
|
def chopString(s, i):
return [s[x:x+i] for x in xrange(0, len(s), i)]
chopString("hello", 2)
===> ['he', 'll', 'o']
ActiveState
|
(string-chop "hello" 2)
===> ("he" "ll" "o")
Chicken Wiki
|
Split String
Split a string at the given character(s).
|
'a sample string'.split()
===> ['a', 'sample', 'string']
'abcabcabc'.split('a')
===> ['bc', 'bc', 'bc']
|
(string-split "a sample string")
===> ("a" "sample" "string")
(string-split "abcabcabc" "a")
===> ("bc" "bc" "bc")
(use srfi-13)
(string-tokenize "a sample string")
===> ("a" "sample" "string")
Chicken Wiki
Drinkable Chicken
|
Split String At Line Breaks
|
"""just a
multi lined
string""".splitlines()
===> ['just a', 'multi lined', 'string']
|
(define a "just a
multi lined
string")
(string-split a "\n")
===> ("just a" "multi lined" "string")
|
Concatenation
Adding two or more Strings together end-to-end.
|
"Hello" + " " + "World"
===> "Hello World"
"".join('Hello', 'World')
===> "Hello World"
|
(conc "Hello" " " "World")
===> "Hello World"
(string-append "Hello" " " "World")
===> "Hello World"
R5RS
|
Join Strings
Join two or more Strings with another String
|
" ".join(["Goodbye", "Cruel", "World"])
===> 'Goodbye Cruel World'
Using the .join() method of strings is the most efficient
'Goodbye' + ' ' + 'Cruel' + ' ' + 'World'
===> 'Goodbye Cruel World'
Python Library Reference
Efficient String Concatenation in Python
import string
string.join(['Goodbye', 'Cruel', 'World'], " ")
===> "Goodbye Cruel World"
|
(conc "a" 1 "b")
===> "a1b"
(string-intersperse '("1" "2") " ")
===> "1 2"
(use srfi-13)
(string-join '("Goodbye" "Cruel" "World") " ")
===> "Goodbye Cruel World"
Chicken Wiki - conc
Chicken Wiki - string-intersperse
SRFI-13 - string-join
Drinkable Chicken
|
Strip String
Remove characters from left, right or both sides.
|
" sample string ".strip()
===> "sample string"
" sample string ".lstrip()
===> "sample string "
" sample string ".rstrip()
===> " sample string"
Python Library Reference
|
(use srfi-13)
(string-strip-both " sample string ")
===> "sample string"
(string-strip " sample string ")
===> "sample string "
(string-strip-right " sample string ")
===> " sample string"
Drinkable Chicken
|
|
Comparisons
|
|
|
Equality
|
|
|
Case-Insensitive Equality
Are two strings equal, disregarding case. Example: 'Hi' is equal to 'hi'.
|
"abc".lower() == "abc".lower()
===> True
"abc".lower() == "ABC".lower()
===> True
Python Library Reference
Message Boards
Message Boards
|
(string-ci=? "abc" "abc")
===> #t
(string-ci=? "abc" "ABC")
===> #t
R5RS
|
Greater or Less Than
Is one string greater than or less than another.
|
'a' < 'b'
===> True
'a' > 'b'
===> False
'aa' > b"
===> False
|
(string<? "a" "b")
===> #t
(string>? "a" "b")
===> #f
(string>? "aa" "b")
===> #f
R5RS
Drinkable Chicken
|
Case-Insensitive Greater or Less Than
Is one string greater or less than another, disregarding case.
|
'A'.lower() < 'b'.lower()
===> True
'a'.lower() > 'B'.lower()
===> False
'AA'.lower() > 'b'.lower()
===> False
Message Boards
Message Boards
|
(string-ci<? "A" "b")
===> #t
(string-ci>? "a" "B")
===> #f
(string-ci>? "AA" "b")
===> #f
R5RS
|
Greater|Less Than Or Equal To
|
"a" >= "a"
===> True
"a" <= "b"
===> True
"aa" >= "b"
===> False
|
(string>=? "a" "a")
===> #t
(string<=? "a" "b")
===> #t
(string>=? "aa" "b")
===> #f
R5RS
|
Case-Insensitive Greater|Less Than Or Equal To
|
"A".lower() >= "a".lower()
===> True
"A".lower() <= "b".lower()
===> True
"AA".lower() >= "b".lower()
===> False
Message Boards
Message Boards
|
(string-ci>=? "A" "a")
===> #t
(string-ci<=? "A" "b")
===> #t
(string-ci>=? "AA" "b")
===> #f
R5RS
|
Prefix And Suffix Equality
Is the beginning/end of a string equal to a given string.
|
"myString".startswith("my")
===> True
"myString".startswith("hi")
===> False
Python Library Reference
|
(use srfi-13)
(string-prefix? "Sa" "Sample")
===> #t
(string-suffix? "no" "Sample")
===> #f
Drinkable Chicken
|
All Characters Upper Case?
Are all characters in a given string upper case?
|
"ABC".isupper()
===> True
"ABc".isupper()
===> False
Python Library Reference
|
(use srfi-1)
(define (string-upper-case? aString)
(every char-upper-case? (string->list aString)))
(string-upper-case? "ABC")
===> #t
(string-upper-case? "ABc")
===> #f
R5RS
|
All Characters Lower Case?
Are all characters in a given string lower case?
|
"abc".islower()
===> True
"Abc".islower()
===> False
Python Library Reference
|
(use srfi-1)
(define (string-lower-case? aString)
(every char-lower-case? (string->list aString)))
(string-lower-case? "abc")
===> #t
(string-lower-case? "Abc")
===> #f
R5RS
|
All Characters Alphanumeric?
Are all characters in a given string alphanumeric?
|
"a1c".isalnum()
===> True
"hello world".isalnum()
===> False
Python Library Reference
|
(use srfi-1)
(define (string-alphanumeric? aString)
(every (lambda (c)
(or (char-alphabetic? c) (char-numeric? c)))
(string->list aString)))
(string-alphanumeric? "a1c")
===> #t
(string-alphanumeric? "hello world")
===> #f
R5RS
|
All Characters Alphabetic?
Are all characters in a given string alphabetic (a-Z)?
|
"abc".isalpha()
===> True
"hello world".isalpha()
===> False
Python Library Reference
|
(use srfi-1)
(define (string-alphabetic? aString)
(every char-alphabetic? (string->list aString)))
(string-alphabetic? "abc")
===> #t
(string-alphabetic? "hello world")
===> #f
R5RS
|
All Characters Numbers?
Are all characters in a given string numbers?
|
"123".isdigit()
===> True
"1a2".isdigit()
===> False
Python Library Reference
|
(use srfi-1)
(define (string-numeric? aString)
(every char-numeric? (string->list aString)))
(string-numeric? "123")
===> #t
(string-numeric? "1a3")
===> #f
R5RS
|
All Characters White Space?
Are all characters in a given string white space?
|
" ".isspace()
===> True
" a ".isspace()
===> False
Python Library Reference
|
(use srfi-1)
(define (string-whitespace? aString)
(every char-whitespace? (string->list aString)))
(string-whitespace? " ")
===> #t
(string-whitespace? " a ")
===> #f
R5RS
(define (string-whitespace? aString)
(let loop ((loc (string->list aString)))
(cond
((null? loc) #t)
((not (char-whitespace? (car loc))) #f)
(else (loop (cdr loc))))))
(string-whitespace? " ")
===> #t
(string-whitespace? " a ")
===> #f
|
|
String Case
Operations that deal with the case of strings.
|
|
|
All To Lower Case
Convert all characters in a string to their lower case equivalent.
|
'Sample STRING'.lower()
===> 'sample string'
Python Library Reference
|
(use srfi-13)
(string-downcase "sample STRING")
===> "sample string"
SRFI-13
Drinkable Chicken
|
All To Upper Case
|
'sample string'.upper()
===> 'SAMPLE STRING'
Python Library Reference
|
(use srfi-13)
(string-upcase "sample string")
===> "SAMPLE STRING"
SRFI-13
Drinkable Chicken
|
Capitalize
Capitalize the first character in a string.
|
'sample string. and more.'.capitalize()
===> 'Sample string. and more.'
Python Library Reference
|
|
Title Case
Capitalize the first character of each word in a string.
|
'sample string'.title()
===> 'Sample String'
Python Library Reference
|
(use srfi-13)
(string-titlecase "sample string")
===> "Sample String"
SRFI-13
Drinkable Chicken
|
|
Searching And Replacing
|
|
|
Search For Character From Left
Return the index of the first occurrence of a character, starting from the left.
|
'sample string'.find('s')
===> 0
'sample string'.find('z')
===> -1
Python Library Reference
|
(use srfi-13)
(string-index "sample string" #\s)
===> 0
(string-index "sample string" #\z)
===> #f
Drinkable Chicken
|
Search For Character From Right
Return the index of the first occurrence of a character, starting from the right.
|
'sample string'.rfind('s')
===> 7
'sample string'.rfind('z')
===> -1
Python Library Reference
|
(use srfi-13)
(string-index-right "sample string" #\s)
===> 7
(string-index-right "sample string" #\z)
===> #f
Drinkable Chicken
|
Search for Substring
Search for a substring in a given string and return its position.
|
'sample string'.find('pl')
===> 3
Python Library Reference
|
(use srfi-13)
(string-contains "sample string" "pl")
===> 3
(string-contains "sample string" "xyz")
===> #f
Case-insensitive
(string-contains-ci "Sample String" "str")
===> 7
srfi-13
|
Substring In String?
Is substring present in a given string?
|
'amp' in 'sample string'
===> True
'xyz' in 'sample string'
===> False
Case Insensitive
'str'.lower() in 'Sample String'.lower()
===> True
|
(use srfi-13)
(string-contains "sample string" "amp")
===> 1
(string-contains "sample string" "xyz")
===> #f
Case Insensitive
(string-contains-ci "Sample String" "str")
===> 7
SRFI-13
|
Change Character At Index!
Destructively modify a character in the string.
|
Strings are immutable so any example of this will likely only be an emulation.
def stringSet(aString, n, val):
s = [ii for ii in aString]
s[n] = val
return ''.join(s)
aString = "hello"
aString = stringSet(aString, 1, "a")
aString
===> 'hallo'
|
This is usually considered bad style
(define a "hello")
(string-set! a 1 #\a)
a
===> "hallo"
R5RS
|
Replacing Substrings
|
'sample string'.replace('sample', 'replaced')
===> 'replaced string'
Python Library Reference
|
Note the dotted pair, it's important!
(string-translate* "sample string"
'(("sample" . "replaced")))
===> "replaced string"
Drinkable Chicken
|
Reverse
Return a new reversed string.
|
"hello"[::-1]
===> 'olleh'
"hello"[1:4][::-1]
===> 'lle'
ActiveState Recipe
|
(use srfi-13)
(string-reverse "hello")
===> "olleh"
(string-reverse "hello" 1 4)
===> "lle"
SRFI-13
|
Reverse!
Reverse the string in-place.
|
Strings are immutable so any example of this will likely only be an emulation.
a = 'hello'
a = a[::-1]
a
===> 'olleh'
|
(use srfi-13)
(define a "hello")
(string-reverse! a)
a
===> "olleh"
(define b "hello")
(string-reverse! b 1 4)
b
===> "hlleo"
SRFI-13
|
Copy
|
Strings are immutable, therefore copying them in the standard way results to a reference to the 'same' string. This method creates a 'new' (id) string. Note some strings will always have the same identity (like the empty string).
a = 'hello'
b = ''.join(a)
a == b
===> True
a is b
===> False
c = ''.join(a[1:3])
c
===> 'el'
|
(define a "hello")
(define b (string-copy a))
(equal? a b)
===> #t
(eqv? a b)
===> #f
(define c (string-copy a 1 3))
c
===> "el"
|
String Interpolation
Given a string containing valid expressions, evaluate those expressions and return the modified string.
|
|
Schematics Cookbook
|
|
More Documentation
|
|
|
Cookbooks
Collections of example code.
|
|
Schematics Cookbook
|
Books
|
|
An Introduction to Scheme and its Implementation
Teach Yourself Scheme in Fixnum Days
The Scheme Programming Language
|
|
|
Linked Lists
|
Concept |
Python |
Chicken |
Overview
|
Python does not have a built-in linked list datatype. An implementation of one is below, however for the examples in this section we'll use the 'list' datatype, which is more like an array or vector in other languages.
class Node:
def __init__(self, data=None, next=None):
self.data = data
self.next = next
def __repr__(self):
return repr(self.data)
|
|
The Empty List
|
a = []
a
===> []
|
(define a '())
a
===> ()
|
Does the Empty List Equal False?
|
a = []
a == False
===> False
not a
===> True
|
(define a '())
(equal? a #f)
===> #f
(not a)
===> #f
|
Creating a Populated List
|
a = [1, 2, 3]
a
===> [1, 2, 3]
|
(define a (list 1 2 3))
a
===> (1 2 3)
(define b '(1 2 3))
b
===> (1 2 3)
|
Is Object a List?
|
a = [1, 2, 3]
type(a) == type([])
===> True
|
(define a (list 1 2 3))
(list? a)
===> #t
|
|
List Functions
|
|
|
First
|
a = [1, 2, 3]
a[0]
===> 1
|
(define a (list 1 2 3))
(car a)
===> 1
|
Rest
|
a = [1, 2, 3]
a[1:]
===> [2, 3]
|
(define a (list 1 2 3))
(cdr a)
===> (2 3)
|
Length
|
a = [1, 2, 3]
len(a)
===> 3
|
(define a (list 1 2 3))
(length a)
===> 3
|
Flatten
|
Blog - Flattening lists in Python
Blog - More on python flatten
|
(define b '((1) (2 3) (4)))
(flatten b)
===> (1 2 3 4)
Chicken Wiki - Unit data-structures
|
Make a List of Integers
|
range(5)
===> [0, 1, 2, 3, 4]
range(start, stop, step)
range(0, 10, 2)
===> [0, 2, 4, 6, 8]
|
(use srfi-1)
(iota 5)
===> (0 1 2 3 4)
(iota count start step)
(iota 5 0 2)
===> (0 2 4 6 8)
SRFI-1
(define (range start stop step)
(let loop ((n start) (r '()))
(if (>= n stop)
(reverse r)
;else
(loop (+ n step) (cons n r)))))
(range 0 10 2)
===> (0 2 4 6 8)
|
|
Indexing
|
|
|
Index
|
a = [1, 2, 3, 4, 5, 6]
a[0]
===> 1
a[3]
===> 4
|
(define a '(1 2 3 4 5 6))
(list-ref a 0)
===> 1
(list-ref a 3)
===> 4
|
Slice or Sublist
|
testList = [1, 2, 3, 4, 5, 6, 7, 8, 9]
testList[3:6]
===> [4, 5, 6]
testList[:3]
===> [1, 2, 3]
testList[6:]
===> [7, 8, 9]
testList[-3:]
===> [7, 8, 9]
def schemeSlice(aList, start, sliceLength):
return aList[start:start+sliceLength]
testList = [1, 2, 3, 4, 5, 6, 7, 8, 9]
schemeSlice(testList, 2, 3)
===> [3, 4, 5]
|
Even with srfi-1 there doesn't seem to be a built-in method of obtaining a sublist from a list. However the two functions defined here (slice and pyslice) should be a good start.
(use srfi-1)
(define testList (list 1 2 3 4 5 6 7 8 9))
(define (slice aList start sliceLength)
(take (drop aList start) sliceLength))
(slice testList 3 3)
===> (4 5 6)
The pyslice function could easily be extended to provide colon notation like Python.
(use srfi-1)
(define (slice aList start sliceLength)
(take (drop aList start) sliceLength))
(define (pyslice l start stop)
(slice l start (- stop start)))
(define testList (list 1 2 3 4 5 6 7 8 9))
(pyslice testList 3 6)
(4 5 6)
|
|
Append
|
|
|
Append Element to List
|
a = [1, 2, 3]
b = a + [4]
a
===> [1, 2, 3]
b
===> [1, 2, 3, 4]
c = a + [[4, 5]]
c
===> [1, 2, 3, [4, 5]]
|
(define (append-element aList element)
(append aList (list element)))
(define a (list 1 2 3))
(define b (append-element a 4))
a
===> (1 2 3)
b
===> (1 2 3 4)
(define c (append-element a (list 4 5)))
c
===> (1 2 3 (4 5))
|
Append Element to List!
|
a = [1, 2]
a.append(3)
a
===> [1, 2, 3]
a.append([4, 5])
a
===> [1, 2, 3, [4, 5]]
|
(define (append-element! aList value)
(if (null? (cdr aList))
(set-cdr! aList (list value))
;else
(append-element! (cdr aList) value)))
(define a (list 1 2))
(append-element! a 3)
a
===> (1 2 3)
(append-element! a (list 4 5))
a
===> (1 2 3 (4 5))
|
Append List to List
|
a = [1, 2]
b = [3,4]
a+b
===> [1, 2, 3, 4]
a
===> [1, 2]
b
===> [3, 4]
|
(define a (list 1 2))
(define b (list 3 4))
(append a b)
===> (1 2 3 4)
a
===> (1 2)
b
===> (3 4)
|
Append List to List!
|
a = [1, 2]
a.extend([3, 4])
a
===> [1, 2, 3, 4]
|
(define (append! aList value)
(if (null? (cdr aList))
(set-cdr! aList value)
;else
(append! (cdr aList) value)))
(define a (list 1 2))
(append! a (list 3 4))
a
===> (1 2 3 4)
|
Join Lists (Concatenate)
|
['a', 'b'] + ['c'] + ['d', 'e']
===> ['a', 'b', 'c', 'd', 'e']
['a', 'b'] + ['c'] + [['d'], ['e']]
===> ['a', 'b', 'c', ['d'], ['e']]
|
(join '((a b) (c) (d e)))
===> (a b c d e)
(join '((a b) (c) ((d) (e))))
===> (a b c (d) (e))
Chicken Wiki - Unit data-structures
|
|
Modifying
|
|
|
Set Value at Index!
|
a = [1, 2, 3, 4, 5]
a[3] = "abc"
a
===> [1, 2, 3, 'abc', 5]
|
(define (set-index! aList index value)
(let loop ((c 0) (l aList))
(if (= c index)
(set-car! l value)
;else
(loop (add1 c) (cdr l)))))
(define l '(1 2 3 4 5))
(set-index! l 3 "a")
l
===> (1 2 3 "a" 5)
(use srfi-1)
(define (list-set! list index new)
(set-car! (drop list index) new))
(define l '(1 2 3 4 5))
(list-set! l 3 "a")
l
Chicken-users - John Cowan
|
Insert!
|
a = [1, 2, 3, 4, 5]
a.insert(3, "abc")
a
===> [1, 2, 3, 'abc', 4, 5]
|
(define (insert! aList index value)
(if (= index 0) (cons value aList)
(let loop ((c 1) (l aList))
(if (= c index)
(set-cdr! l (cons value (cdr l)))
;else
(loop (+ c 1) (cdr l))))))
(define a '(1 2 3 4 5))
(insert! a 3 "abc")
a
===> (1 2 3 "abc" 4 5)
(use srfi-1)
(define (list-insert! aList index new)
(append (take aList index) (list new) (drop aList index)))
(define a '(1 2 3 4 5))
(set! a (list-insert! a 3 "abc"))
a
===> (1 2 3 "abc" 4 5)
Chicken-users - John Cowan
|
Remove by Value!
|
a = [1, 2, 3, 4, 5]
a.remove(1)
a
===> [2, 3, 4, 5]
a.remove(5)
a
===> [2, 3, 4]
|
Note: remove-by-value! will produce an error if given a list of length 1.
(define (remove-by-value! aList value)
(if (equal? (car aList) value)
(begin
(set-car! aList (cadr aList))
(set-cdr! aList (cddr aList)))
;else
(if (equal? (cadr aList) value)
(set-cdr! aList (cddr aList))
(remove-by-value! (cdr aList) value))))
(define a '(1 2 3 4 5))
(remove-by-value! a 1)
a
===> (2 3 4 5)
(remove-by-value! a 5)
a
===> (2 3 4)
delete! removes all occurrences of a value from a list
Note: srfi-1's delete! will remove the value from the original list, except when the value is the first element in that list. See examples below.
(use srfi-1)
(define a '(1 2 3 4 5))
(delete! 3 a)
===> (1 2 4 5)
a
===> (1 2 4 5)
(delete! 1 a)
===> (2 4 5)
a
===> (1 2 4 5)
SRFI-1
|
Remove by Index!
|
a = [1, 2, 3, 4, 5]
del a[2]
a
===> [1, 2, 4, 5]
|
(define (remove-by-index! aList index)
(if (= index 0)
(begin
(set-car! aList (cadr aList))
(set-cdr! aList (cddr aList)))
;else
(let loop ((c 1) (l aList))
(if (= c index)
(set-cdr! l (cddr l))
(loop (+ c 1) (cdr l))))))
(define a '(1 2 3 4 5))
(remove-by-index! a 2)
a
===> (1 2 4 5)
(remove-by-index! a 3)
a
===> (1 2 4)
|
Reverse List
|
Reverse the original list in place.
a = [1, 2, 3]
a.reverse()
a
===> [3, 2, 1]
|
(define a '(1 2 3 4 5))
(reverse a)
===> (5 4 3 2 1)
|
Sort List
|
Sort the list in place.
a = [3, 1, 2]
a.sort()
a
===> [1, 2, 3]
|
(define a '(2 3 1))
(sort a <)
===> (1 2 3)
(sort a >)
===> (3 2 1)
|
Intersperse
|
|
(intersperse '(a b c) 1)
===> (a 1 b 1 c)
(intersperse '(1 2 3) "a")
===> (1 "a" 2 "a" 3)
Chicken Wiki - Unit data-structures
|
Chop
|
def chop(l, i):
return [l[x:x+i] for x in xrange(0, len(l), i)]
a = [1, 2, 3, 4, 5]
chop(a, 2)
===> [[1, 2], [3, 4], [5]]
|
|
Set car
Set the value of a node in a list.
|
class Node:
def __init__(self, data=None, next=None):
self.data = data
self.next = next
def __repr__(self):
return repr(self.data)
a = Node(1)
a
===> 1
a.data = "abc"
a
===> 'abc'
|
(define a '(1 2 3))
(set-car! a "xyz")
a
===> ("xyz" 2 3)
|
Set cdr
Set the pointer of a node in a list.
|
class Node:
def __init__(self, data=None, next=None):
self.data = data
self.next = next
def __repr__(self):
return repr(self.data)
a = Node(1)
b = Node(2)
a.next = b
a
===> 1
a.next
===> 2
|
(define a '(1 2 3))
(set-cdr! a (list "b" "c"))
a
===> (1 "b" "c")
|
|
Find
|
|
|
Is Value in List? (Return Boolean)
|
a = [1, 2, 3, 4, 5]
3 in a
===> True
10 in a
===> False
|
(define (in-list? aList value)
(if (member value aList) #t #f))
(define a '(1 2 3 4 5))
(in-list? a 3)
===> #t
(in-list? a 10)
===> #f
|
Index by Value
|
a = [1, 2, 3, 4, 5]
a.index(3)
===> 2
a.index('xyz')
===> ValueError: list.index(x): x not in list
|
(use srfi-1)
(define (index-by-value aList value)
(list-index (lambda (x) (equal? x value)) aList))
(define a '(1 2 3 4 5))
(index-by-value a 3)
===> 2
|
Search for First Value in List (Return Value)
|
|
(use srfi-1)
(define a '(1 2 3 4 5))
(find even? a)
===> 2
(find (lambda (x) (equal? x 3)) a)
===> 3
(find (lambda (x) (equal? x 42)) a)
===> #f
|
Is Value in List? (Return Rest of List)
|
def findTailByValue(aList, value):
return aList[aList.index(value):]
a = [1, 2, 3, 4, 5]
findTailByValue(a, 3)
===> [3, 4, 5]
findTailByValue(a, 'z')
===> ValueError: list.index(x): x not in list
|
(define a '(1 2 3 4 5))
(member 3 a)
===> (3 4 5)
(member "xyz" a)
===> #f
|
|
Copying
|
|
|
Copy
|
import copy
a = [1, 2, 3]
b = a
b is a
===> True
c = copy.copy(a)
c is a
===> False
|
(define (copy aList)
(let loop ((l aList) (new '()))
(if (null? l)
(reverse new)
;else
(loop (cdr l) (cons (car l) new)))))
(define a '(1 2 3 4 5))
(define b a)
(eqv? a b)
===> #t
(define c (copy a))
(eqv? a c)
===> #f
|
Deep Copy
|
import copy
a = [[1, 2], [3, 4], 5]
b = copy.copy(a)
a[0] is b[0]
===> True
c = copy.deepcopy(a)
c[0] is a[0]
===> False
|
(define (tree-copy x)
(if (pair? x)
(cons (tree-copy (car x)) (tree-copy (cdr x)))
x))
(define a '(1 2 (3 4) 5))
(define b (tree-copy a))
(eqv? (list-ref b 2) (list-ref a 2))
===> #f
Chicken-users - John Cowan
|
|
Conversion
|
|
|
String to List
|
[ii for ii in 'abc']
===> ['a', 'b', 'c']
|
(string->list "abc")
===> (#\a #\b #\c)
|
List to String
|
''.join(['a', 'b', 'c'])
===> 'abc'
|
(list->string '(#\a #\b #\c))
===> "abc"
|
Vector to List
|
In this case we're going to demonstrate Python's tuple data-structure.
a = (1, 2, 3)
list(a)
===> [1, 2, 3]
|
(vector->list (vector 1 2 3))
===> (1 2 3)
|
List to Vector
|
<c>In this case we're going to demonstrate Python's tuple
data-structure.</c>
a = [1, 2, 3]
tuple(a)
===> (1, 2, 3)
|
(list->vector '(1 2 3))
===> #(1 2 3)
|
List to Hash Table
|
a = [['a', 1], ['b', 2]]
dict(a)
===> {'a': 1, 'b': 2}
|
(alist->hash-table '((a 1) (b 2)))
===> #<hash-table>
|
Hash Table to List
|
a = {'a':1, 'b':2}
a.items()
===> [('a', 1), ('b', 2)]
|
(hash-table->alist (alist->hash-table '((a 1) (b 2))))
===> ((b 2) (a 1))
|
|
|
Arrays and Vectors
|
Concept |
Python |
Chicken |
Overview
|
Python's list data type is similar to vectors or arrays in most other languages, and is what we will use here.
EDIT: Should we take the opportunity to illustrate Python's tuple data structure here? The only downside is that it is immutable so a few concepts here wouldn't apply.
|
Scheme's vector data type is comparable to arrays in other languages.
Some examples here will use vector-lib which is not installed by default. To install it use chicken-install from the shell as outlined below:
$ sudo chicken-install vector-lib
|
The Empty Array
|
a = []
a
===> []
|
(define a (vector))
a
===> #()
(define c (make-vector 0))
c
===> #()
|
Does the Empty Array Equal False?
|
a = []
a == False
===> False
not a
===> True
|
(equal? (vector) #f)
===> #f
(not (vector))
===> #f
|
Creating a Populated Array
|
a = [1, 2, 3]
a
===> [1, 2, 3]
|
(define a (vector 1 2 3))
a
===> #(1 2 3)
(make-vector 3 7)
===> #(7 7 7)
|
Is Object a Vector?
|
a = [1, 2, 3]
type(a) == type([])
===> True
b = (1, 2, 3)
type(b) == type(())
===> True
|
(define a (vector 1 2 3))
(vector? a)
===> #t
|
|
General Functions
|
|
|
First
|
a = [1, 2, 3]
a[0]
===> 1
|
(define a (vector 1 2 3))
(vector-ref a 0)
===> 1
|
Rest
|
a = [1, 2, 3]
a[1:]
===> [2, 3]
|
(use vector-lib)
(define a (vector 1 2 3))
(vector-copy a 1 (vector-length a))
===> #(2 3)
|
Length
|
a = [1, 2, 3]
len(a)
===> 3
|
(define a (vector 1 2 3))
(vector-length a)
===> 3
|
Flatten
|
Blog - Flattening lists in Python
Blog - More on python flatten
|
|
Make an Array of Integers
|
range(5)
===> [0, 1, 2, 3, 4]
range(start, stop, step)
range(0, 10, 2)
===> [0, 2, 4, 6, 8]
|
(define (vector-range number)
(let loop ((v (make-vector number)) (n 0))
(if (= n number)
v
;else
(begin (vector-set! v n n)
(loop v (+ n 1))))))
(vector-range 3)
===> #(0 1 2)
|
|
Indexing
|
|
|
Index
|
a = [1, 2, 3, 4, 5, 6]
a[0]
===> 1
a[3]
===> 4
|
(define a (vector 1 2 3 4 5 6))
(vector-ref a 0)
===> 1
(vector-ref a 3)
===> 4
|
Slice or Sublist
|
testList = [1, 2, 3, 4, 5, 6, 7, 8, 9]
testList[3:6]
===> [4, 5, 6]
testList[:3]
===> [1, 2, 3]
testList[6:]
===> [7, 8, 9]
testList[-3:]
===> [7, 8, 9]
|
(use vector-lib)
(define a (vector 1 2 3 4 5 6 7 8 9))
(vector-copy a 3 6)
===> #(4 5 6)
(vector-copy a 0 3)
===> #(1 2 3)
(vector-copy a 6 (vector-length a))
===> #(7 8 9)
(vector-copy a (- (vector-length a) 3) (vector-length a))
===> #(7 8 9)
|
|
Append
|
|
|
Append Element to Array
|
a = [1, 2, 3]
b = a + [4]
a
===> [1, 2, 3]
b
===> [1, 2, 3, 4]
c = a + [[4, 5]]
c
===> [1, 2, 3, [4, 5]]
|
(define (vector-append-elem vec elem)
(vector-resize vec (+ 1 (vector-length vec)) elem))
(vector-append-elem a 4)
===> #(1 2 3 4)
(vector-append-elem a (vector 7 8 9))
===> #(1 2 3 #(7 8 9))
|
Append Element to Array!
|
a = [1, 2]
a.append(3)
a
===> [1, 2, 3]
a.append([4, 5])
a
===> [1, 2, 3, [4, 5]]
|
|
Append Array to Array
|
a = [1, 2]
b = [3,4]
a+b
===> [1, 2, 3, 4]
a
===> [1, 2]
b
===> [3, 4]
|
(use vector-lib)
(define a (vector 1 2 3))
(define b (vector 4 5 6))
(vector-append a b)
===> #(1 2 3 4 5 6)
a
===> #(1 2 3)
b
===> #(4 5 6)
|
Append Array to Array!
|
a = [1, 2]
a.extend([3, 4])
a
===> [1, 2, 3, 4]
|
|
Join Arrays (Concatenate)
|
['a', 'b'] + ['c'] + ['d', 'e']
===> ['a', 'b', 'c', 'd', 'e']
['a', 'b'] + ['c'] + [['d'], ['e']]
===> ['a', 'b', 'c', ['d'], ['e']]
|
(use vector-lib)
(define a (vector 1 2))
(define b (vector 3 4))
(define c (vector 5 6))
(vector-concatenate (list a b c))
===> #(1 2 3 4 5 6)
|
|
Modifying
|
|
|
Set Value at Index!
|
a = [1, 2, 3, 4, 5]
a[3] = "abc"
a
===> [1, 2, 3, 'abc', 5]
|
(define a (vector 1 2 3 4 5))
(vector-set! a 3 "abc")
a
===> #(1 2 3 "abc" 5)
|
Insert!
|
a = [1, 2, 3, 4, 5]
a.insert(3, "abc")
a
===> [1, 2, 3, 'abc', 4, 5]
|
|
Remove by Value!
|
a = [1, 2, 3, 4, 5]
a.remove(1)
a
===> [2, 3, 4, 5]
a.remove(5)
a
===> [2, 3, 4]
|
|
Remove by Index!
|
a = [1, 2, 3, 4, 5]
del a[2]
a
===> [1, 2, 4, 5]
|
|
Reverse Array
|
Reverse the original list in place.
a = [1, 2, 3]
a.reverse()
a
===> [3, 2, 1]
|
Reverse a vector in-place.
(use vector-lib)
(define a (vector 1 2 3))
(vector-reverse! a)
a
===> #(3 2 1)
|
Sort Array
|
Sort the list in place.
a = [3, 1, 2]
a.sort()
a
===> [1, 2, 3]
|
|
Intersperse
|
|
|
Chop
|
def chop(l, i):
return [l[x:x+i] for x in xrange(0, len(l), i)]
a = [1, 2, 3, 4, 5]
chop(a, 2)
===> [[1, 2], [3, 4], [5]]
|
|
Resize
|
|
Chicken Wiki - Unit library
|
|
Find
|
|
|
Is Value in Array? (Return Boolean)
|
a = [1, 2, 3, 4, 5]
3 in a
===> True
10 in a
===> False
|
(use vector-lib)
(define a (vector 1 2 3 4 5))
(define (val-in-vector vector value)
(if (vector-index (lambda (x) (equal? x value)) vector)
#t
#f))
(val-in-vector a 3)
===> #t
|
Index by Value
|
a = [1, 2, 3, 4, 5]
a.index(3)
===> 2
a.index('xyz')
===> ValueError: list.index(x): x not in list
|
(use vector-lib)
(define a (vector 1 2 3 4 5))
(vector-index (lambda (x) (equal? x 3)) a)
===> 2
(vector-index (lambda (x) (equal? x "abc")) a)
===> #f
SRFI-43
|
Search for First Value in Array (Return Value)
|
|
|
Is Value in Array? (Return Rest of Array)
|
def findTailByValue(aList, value):
return aList[aList.index(value):]
a = [1, 2, 3, 4, 5]
findTailByValue(a, 3)
===> [3, 4, 5]
findTailByValue(a, 'z')
===> ValueError: list.index(x): x not in list
|
|
|
Copying
|
|
|
Copy
|
import copy
a = [1, 2, 3]
b = a
b is a
===> True
c = copy.copy(a)
c is a
===> False
|
(define a (vector 1 2 3))
(define b (make-vector (vector-length a)))
(vector-copy! a b)
b
===> #(1 2 3)
(equal? a b)
===> #t
(eqv? a b)
===> #f
|
Deep Copy
|
import copy
a = [[1, 2], [3, 4], 5]
b = copy.copy(a)
a[0] is b[0]
===> True
c = copy.deepcopy(a)
c[0] is a[0]
===> False
|
|
|
Conversion
|
|
|
String to Array
|
[ii for ii in 'abc']
===> ['a', 'b', 'c']
|
(define (string->vector string)
(list->vector (string->list string)))
(string->vector "abc")
===> #(#\a #\b #\c)
|
Array to String
|
''.join(['a', 'b', 'c'])
===> 'abc'
|
(define (vector->string vec)
(list->string (vector->list vec)))
(define a (vector #\a #\b #\c))
(vector->string a)
===> "abc"
|
Linked List to Array
|
In this case we're going to demonstrate Python's tuple data-structure.
a = [1, 2, 3]
tuple(a)
===> (1, 2, 3)
|
(define a (list 1 2 3))
(list->vector a)
===> #(1 2 3)
|
Array to Linked List
|
In this case we're going to demonstrate Python's tuple data-structure.
a = (1, 2, 3)
list(a)
===> [1, 2, 3]
|
(define a (vector 1 2 3))
(vector->list a)
===> (1 2 3)
|
Hash Table to Array
|
a = {'a':1, 'b':2}
a.items()
===> [('a', 1), ('b', 2)]
|
|
Array to Hash Table
|
a = [['a', 1], ['b', 2]]
dict(a)
===> {'a': 1, 'b': 2}
|
|
|
|
Hash Tables, Hash Maps and Dictionaries
|
Concept |
Python |
Chicken |
Overview
EDIT: The sub-sections here need to be renamed and reorganized.
|
|
|
The Empty Hash Table
|
d = {}
d
===> {}
|
(define d (make-hash-table))
d
===> #<hash-table>
|
Does the Empty Hash Table Equal False?
|
d = {}
d == False
===> False
not d
===> True
|
(define d (make-hash-table))
(equal? d #f)
===> #f
(not d)
===> #f
|
Constructing a Populated Hash Table
|
d = {'x':1, 'y':3, 'z':5}
d
===> {'y': 3, 'x': 1, 'z': 5}
|
(define d (alist->hash-table '((x . 1) (y . 3) (z . 5))))
d
===> #<hash-table>
(hash-table->alist d)
===> ((z . 5) (y . 3) (x . 1))
|
|
Hash Table Functions
|
|
|
Length
|
d = {'x':1, 'y':3, 'z':5}
len(d)
===> 3
|
(define d (alist->hash-table '((x . 1) (y . 3) (z . 5))))
(hash-table-size d)
===> 3
Chicken Wiki - SRFI-69
|
|
Inserting and Removing
|
|
|
Inserting Elements!
|
d = {}
d['boy'] = 'Frank'
d
===> {'boy': 'Frank'}
|
(define d (make-hash-table))
(hash-table-set! d 'boy 'Frank)
(hash-table->alist d)
===> ((boy . Frank))
Chicken Wiki - SRFI-69
|
Remove Element by Key!
|
d = {'x':1, 'y':3, 'z':5}
del d['y']
d
===> {'x': 1, 'z': 5}
|
(define d (alist->hash-table '((x . 1) (y . 3) (z . 5))))
(hash-table-delete! d 'y)
===> #t
(hash-table->alist d)
===> ((z . 5) (x . 1))
Chicken Wiki - SRFI-69
|
Merge
Merge two hash-tables together.
|
Any existing keys in 'd' will be overwritten with the values from 'e'. For instance the value of d['x'] changes from 1 to 7.
d = {'x':1, 'y':3, 'z':5}
e = {'x':7, 'a':20}
d.update(e)
===> {'a': 20, 'y': 3, 'x': 7, 'z': 5}
Python Library Reference - Built-in Types
|
Existing keys in 'd' will not be overwritten by key/values in 'e'. For example (hash-table-ref 'x) will return 1 before and after the merge.
(define d (alist->hash-table '((x . 1) (y . 3) (z . 5))))
(define e (alist->hash-table '((x . 7) (a . 10))))
(hash-table-merge! d e)
===> #<hash-table>
(hash-table->alist d)
===> ((z . 5) (y . 3) (x . 1) (a . 10))
Chicken Wiki - SRFI-69
This version creates a new hash-table that is the result of the merging of two other hash-tables.
(define d (alist->hash-table '((x . 1) (y . 3) (z . 5))))
(define e (alist->hash-table '((x . 7) (a . 10))))
(hash-table->alist (hash-table-merge d e))
===> ((z . 5) (y . 3) (x . 1) (a . 10))
Chicken Wiki - SRFI-69
|
|
Modifying and Accessing
|
|
|
Retrieving Elements by Key
|
d = {'x':10, 'y':50, 'z':100}
d['x']
===> 10
d['a']
===> KeyError: 'a'
|
(define d (alist->hash-table '((x . 1) (y . 3) (z . 5))))
(hash-table-ref d 'x)
===> 1
(hash-table-ref d 'a)
===> Error: (hash-table-ref) hash-table does not contain key
===> a
Chicken Wiki - SRFI-69
|
Has Key?
|
d = {'x':1, 'y':3, 'z':5}
d.has_key('y')
===> True
'y' in d
===> True
|
(define d (alist->hash-table '((x . 1) (y . 3) (z . 5))))
(hash-table-exists? d 'y)
===> #t
Chicken Wiki - SRFI-69
|
Set Value of Element by Key!
|
d = {'x':1, 'y':3, 'z':5}
d['x'] = 20
d
===> {'y': 3, 'x': 20, 'z': 5}
|
(define d (alist->hash-table '((x . 1) (y . 3) (z . 5))))
(hash-table-set! d 'x 20)
(hash-table->alist d)
===> ((z . 5) (y . 3) (x . 20))
(set! (hash-table-ref d 'x) 7)
(hash-table->alist d)
===> ((z . 5) (y . 3) (x . 7))
Chicken Wiki - SRFI-69
|
|
Keys and Values
|
|
|
Get a List of (key, value) Pairs
Get a list of all (key, value) pairs in a given hash-table.
|
d = {'x':1, 'y':3, 'z':5}
d.items()
===> [('y', 3), ('x', 1), ('z', 5)]
|
(define d (alist->hash-table '((x . 1) (y . 3) (z . 5))))
(hash-table->alist d)
===> ((z . 5) (y . 3) (x . 1))
Chicken Wiki - SRFI-69
|
Get a List of Keys
|
d = {'x':1, 'y':3, 'z':5}
d.keys()
===> ['y', 'x', 'z']
|
(define d (alist->hash-table '((x . 1) (y . 3) (z . 5))))
(hash-table-keys d)
===> (z y x)
Chicken Wiki - SRFI-69
|
Get a List of Values
|
d = {'x':1, 'y':3, 'z':5}
d.values()
===> [3, 1, 5]
|
(define d (alist->hash-table '((x . 1) (y . 3) (z . 5))))
(hash-table-values d)
===> (5 3 1)
Chicken Wiki - SRFI-69
|
|
Copying
|
|
|
Copy
|
d = {'x':1, 'y':3, 'z':5}
c = d.copy()
c == d
===> True
c is d
===> False
|
Note: These hash-tables do not even compare 'equal?' even though they have identical keys and values.
EDIT: Is there a hash-table equality function?
(define d (alist->hash-table '((x . 1) (y . 3) (z . 5))))
(define c (hash-table-copy d))
(eqv? c d)
===> #f
Chicken Wiki - SRFI-69
|
|
Conversion
|
|
|
Hash Table to List
|
d = {'x':1, 'y':3, 'z':5}
d.items()
===> [('y', 3), ('x', 1), ('z', 5)]
|
(define d (alist->hash-table '((x . 1) (y . 3) (z . 5))))
(hash-table->alist d)
===> ((z . 5) (y . 3) (x . 1))
|
List to Hash Table
|
a = [['x', 1], ['y', 3], ['z', 5]]
d = dict(a)
d
===> {'y': 3, 'x': 1, 'z': 5}
|
(define a '((x . 1) (y . 3) (z . 5)))
(define d (alist->hash-table a))
d
===> #<hash-table>
(hash-table->alist d)
===> ((z . 5) (y . 3) (x . 1))
|
|
|
Sets
|
Concept |
Python |
Chicken |
Overview
|
|
We'll be using lists to implement sets, however lists are not efficient when using large sets. It is better to use trees, bitsets or hash-tables for large sets.
SRFI-1 - Set Operations on Lists
|
Empty Set
|
a = set()
a
===> set([])
|
(define a '())
a
===> ()
|
Does the Empty Set Equal False?
|
a = set()
a == False
===> False
not a
===> True
|
(define a '())
(equal? a #f)
===> #f
(not a)
===> #f
|
Constructing a Populated Set
|
a = set([1, 2, 3, 3])
a
===> set([1, 2, 3])
|
(use srfi-1)
(define (make-set aList)
(delete-duplicates aList))
(define a (make-set '(1 2 3 3)))
a
===> (1 2 3)
|
Length
|
a = set([1, 2, 3])
len(a)
===> 3
|
(define a '(1 2 3))
(length a)
===> 3
|
Equality
|
a = set([1, 2, 3])
b = set([3, 2, 1])
a == b
===> True
|
(use srfi-1)
(define a '(1 2 3))
(define b '(3 2 1))
(lset= equal? a b)
===> #t
|
|
Inserting and Deleting
|
|
|
Add Element!
|
a = set([1, 2, 3])
a.add(4)
a
===> set([1, 2, 3, 4])
Python Library Reference - Standard Types
|
(use srfi-1)
(define a '(1 2 3))
(lset-adjoin equal? a 2 3 4 5)
===> (5 4 1 2 3)
SRFI-1 - Set operations on lists
|
Remove Element!
|
a = set([1, 2, 3])
a.remove(3)
a
===> set([1, 2])
a.remove('a')
===> KeyError: 'a'
Python Library Reference - Built-in Types
Remove element without signalling an error.
a = set([1, 2, 3])
a.discard(3)
a
===> set([1, 2])
a.discard('a')
a
===> set([1, 2])
Python Library Reference - Built-in Types
|
(use srfi-1)
(define a '(1 2 3))
(define a (delete 3 a))
a
===> (1 2)
SRFI-1
|
Clear Set!
|
a = set([1, 2, 3])
a.clear()
a
===> set([])
Python Library Reference - Built-in Types
|
(define a '(1 2 3))
(define a '())
a
===> ()
|
|
Membership
|
|
|
Element in Set
|
a = set([1, 2, 3])
1 in a
===> True
|
(define a '(1 2 3))
(member 2 a)
===> (2 3)
|
Element Not in Set
|
a = set([1, 2, 3])
1 not in a
===> False
|
(define a '(1 2 3))
(not (member 1 a))
===> #f
|
Subset of?
|
a = set([1, 2, 3])
b = set([5, 3, 1, 2, 4])
a.issubset(b)
===> True
Python Library Reference - Built-in Types
|
(use srfi-1)
(define a '(1 2 3))
(define b '(5 3 1 2 4))
(lset<= eqv? a b)
===> #t
SRFI-1 - Set operations on lists
|
Superset of?
|
a = set([1, 2, 3])
b = set([5, 3, 1, 2, 4])
a.issuperset(b)
===> False
b.issuperset(a)
===> True
Python Library Reference - Built-in Types
|
(use srfi-1)
(define a '(1 2 3))
(define b '(5 3 1 2 4))
(lset<= eqv? b a)
===> #f
(lset<= eqv? a b)
===> #t
SRFI-1 - Set operations on lists
|
|
Set Functions
|
|
|
Union
|
a = set(['a', 'b', 'c', 'd'])
b = set(['c', 'd', 'e', 'f'])
a.union(b)
===> set(['a', 'c', 'b', 'e', 'd', 'f'])
Python Library Reference - Built-in Types
|
(use srfi-1)
(define a '(a b c d))
(define b '(c d e f))
(lset-union eqv? a b)
===> (f e a b c d)
SRFI-1 - Set operations on lists
|
Intersection
|
a = set(['a', 'b', 'c', 'd'])
b = set(['c', 'd', 'e', 'f'])
a.intersection(b)
===> set(['c', 'd'])
Python Library Reference - Built-in Types
|
(use srfi-1)
(define a '(a b c d))
(define b '(c d e f))
(lset-intersection eqv? a b)
===> (c d)
SRFI-1 - Set operations on lists
|
Difference
|
a = set(['a', 'b', 'c', 'd'])
b = set(['c', 'd', 'e', 'f'])
a.difference(b)
===> set(['a', 'b'])
b.difference(a)
===> set(['e', 'f'])
Python Library Reference - Built-in Types
|
(define a '(a b c d))
(define b '(c d e f))
(lset-difference eqv? a b)
===> (a b)
(lset-difference eqv? b a)
===> (e f)
SRFI-1 - Set operations on lists
|
Symmetric Difference
|
a = set(['a', 'b', 'c', 'd'])
b = set(['c', 'd', 'e', 'f'])
a.symmetric_difference(b)
===> set(['a', 'b', 'e', 'f'])
Python Library Reference - Built-in Types
|
(define a '(a b c d))
(define b '(c d e f))
(lset-xor eqv? a b)
===> (f e a b)
SRFI-1 - Set operations on lists
|
|
Conversion
|
|
|
Set to List
|
a = set([1, 2, 3])
list(a)
===> [1, 2, 3]
|
Our implementation of sets are already stored as lists.
|
List to Set
|
a = [1, 2, 3, 3]
set(a)
===> set([1, 2, 3])
|
(use srfi-1)
(define (make-set aList)
(delete-duplicates aList))
(define a (make-set '(1 2 3 3)))
a
===> (1 2 3)
|
|
Copying
|
|
|
Copy
|
import copy
a = set([1, 2, 3])
b = copy.copy(a)
b == a
===> True
b is a
===> False
|
(define (copy aList)
(let loop ((l aList) (new '()))
(if (null? l)
(reverse new)
;else
(loop (cdr l) (cons (car l) new)))))
(define a '(1 2 3 4 5))
(define b a)
(eqv? a b)
===> #t
(define c (copy a))
(eqv? a c)
===> #f
|
|
|
Stacks and Queues
|
Concept |
Python |
Chicken |
|
|
Trees and Graphs
|
Concept |
Python |
Chicken |
|
|
Streams
|
Concept |
Python |
Chicken |
|
|
Data Persistence
|
Files
|
Concept |
Python |
Chicken |
File Exists?
|
import os
os.path.exists('/home/trades/')
===> True
Python Library Reference - os.path
|
(file-exists? "/home/trades/")
===> "/home/trades/"
Chicken Wiki - Unit library
|
|
Reading
|
|
|
Open File for Reading
|
f = open("filename", 'r')
The Python Tutorial - Input and Output
|
(define f (open-input-file "filename"))
(close-input-file f)
R5RS - Input and output
|
Read Entire File
|
f = open("filename", 'r')
data = f.read()
Python Library Reference - Built-in Types
|
|
Readlines
Read entire file and return a list of lines.
|
f = open("filename", 'r')
data = f.readlines()
Python Library Reference - Built-in Types
xreadlines() creates a generator object that returns one line at a time.
f = open("filename", 'r')
data = f.xreadlines()
Python Library Reference - Built-in Types
|
|
Read Single Line
|
f = open("filename", "r")
line = f.readline()
Python Library Reference - Built-in Types
|
(define f (open-input-file "filename"))
(define d (read f))
(close-input-file f)
R5RS - Input
|
Seek
Set the current position in a file.
|
Python Library Reference - Built-in Types
|
|
Tell
Get the current position in a file.
|
Python Library Reference - Built-in Types
|
|
Read Binary File
|
|
|
|
Writing
|
|
|
Open File for Writing
|
f = open("filename", 'w')
Python Library Reference - Built-in Functions
|
(define f (open-output-file "filename"))
(close-output-port f)
R5RS - Input and output
|
Write to File
|
f = open("filename", 'w')
f.write("hello")
f.close()
Python Library Reference - Built-in Types
|
This method also writes the quotes.
(define f (open-output-file "filename"))
(write "hello" f)
(close-output-port f)
R5RS - Input and output
|
Write Lines
Write a sequence of strings to a file.
|
f = open("filename", 'w')
f.writelines(SEQUENCE)
f.close()
Python Library Reference - Built-in Types
|
|
Append to File
|
f = open("filename", 'a')
f.write("hello")
f.close()
Python Library Reference - Built-in Functions
|
|
Create a Temporary File
|
Python Library Reference - tempfile
|
Chicken Wiki - Unit files
|
Write to Binary File
|
Linux By Examples
|
|
Append to Binary File
|
|
|
|
|
Serialization
|
Concept |
Python |
Chicken |
Documentation
|
The Python Standard Library - pickle
|
s11n has not yet been ported to Chicken 4.
s11n
|
|
|
DBM
dbm and its successors are database engines that allow data retrieval by key.
|
Concept |
Python |
Chicken |
|
|
Object-Oriented Programming
|
Advanced Concepts
|
Closures
|
Concept |
Python |
Chicken |
|
|
Continuations
|
Concept |
Python |
Chicken |
|
|
Generators
|
Concept |
Python |
Chicken |
|
|
Decorators
|
Concept |
Python |
Chicken |
|
|
Macros
|
Concept |
Python |
Chicken |
|
|
Monads
|
Concept |
Python |
Chicken |
|
|
Libraries
|
Packages
|
Concept |
Python |
Chicken |
|
|
Time and Date
|
Concept |
Python |
Chicken |
Overview
|
|
Chicken supports 'date literals' which are a convenient syntax for writing dates. Date literals have not been ported to Chicken 4 yet.
Chicken Wiki - Date Literals
SRFI-19 provides utilities for working with dates. SRFI-19 has not been ported to Chicken 4 yet.
SRFI-19
|
|
Timing
|
|
|
Seconds
|
from Unix Epoch (1970-1-1)
import time
time.time()
===> 1225410783.9220109
Python Library Reference - time
|
(current-seconds)
===> 1225410776.0
Chicken Wiki - Unit library
|
Milliseconds
|
import time
time.time() * 1000
===> 1224671324177.7361
Python Library Reference - time
|
Since process or machine startup.
(current-milliseconds)
===> 994624
Chicken Wiki - Unit library
|
Timing Code
|
import timeit
timeit.Timer('2+2').timeit()
===> 0.19053411483764648
Python Library Reference - timeit
|
(time '(+ 2 2))
===> 0 seconds elapsed
===> 0 seconds in (major) GC
===> 10 mutations
===> 1 minor GCs
===> 0 major GCs
===> (+ 2 2)
Chicken Wiki - Non-standard macros and special forms
|
|
Date
|
|
|
Today's Date
|
import datetime
d = datetime.datetime.today()
d
===> datetime.datetime(2008, 11, 21, 16, 44, 57, 106388)
Python Library Reference - datetime
pleac - Python - Dates and Times
|
(use posix)
(seconds->local-time (current-seconds))
===> #(9 44 22 30 4 109 6 149 #t 18000)
Chicken Wiki - Unit posix
|
Today's Day, Month and Year
|
import datetime
d = datetime.datetime.today()
d.day
===> 30
d.month
===> 5
d.year
===> 2009
Python Library Reference - datetime
pleac - Python - Dates and Times
|
Note: Month is 0 based so you must add 1, and year is the number of years from 1900 so you must add 1900.
(use posix)
(define d (seconds->local-time (current-seconds)))
(vector-ref d 3) ;; Day
===> 30
(+ 1 (vector-ref d 4) ;; Month
===> 4
(+ 1900 (vector-ref d 5)) ;; Year
===> 2009
Chicken Wiki - Unit posix
|
Today's Day of The Week
|
weekday(): Monday = 0 to Sunday = 6
isoweekday(): Monday = 1 to Sunday = 7
import datetime
d = datetime.datetime.today()
d.weekday()
===> 5
d.isoweekday()
===> 6
Python Library Reference - datetime
pleac - Python - Dates and Times
|
Sunday = 0 to Saturday = 6
(use posix)
(define d (seconds->local-time (current-seconds)))
(vector-ref d 6)
6
Chicken Wiki - Unit posix
|
ISO Calendar
|
import datetime
d = datetime.datetime.today()
d.isocalendar()
===> (2009, 22, 6)
Python Library Reference - datetime
pleac - Python - Dates and Times
|
|
Get Date in ISO Format
|
import datetime
d = datetime.datetime.today()
d.isoformat()
===> '2008-11-21T16:48:29.511640'
Python Library Reference - datetime
pleac - Python - Dates and Times
|
|
Get a String Representation of the Date
|
import datetime
d = datetime.datetime.today()
print d.strftime('Day of the Year: %j')
===> Day of the Year: 326
print d.strftime("The year is %Y")
===> The year is 2008
print d.strftime("Today is %A, in the month of %B"
===> Today is Friday, in the month of November
Python Library Reference - datetime
pleac - Python - Dates and Times
|
Chicken Wiki - Unit posix
|
|
|
Random
|
Concept |
Python |
Chicken |
Set Seed
|
Restarting the program/interpreter will cause random.randint(0,100) to return a different value.
import random
random.seed(1)
random.randint(0, 100)
===> 42
random.seed(1)
random.randint(0, 100)
===> 42
Python Library Reference - random
|
(random-seed 1)
(random 100)
===> 83
(random-seed 1)
(random 100)
===> 83
Chicken Wiki - Unit extras
|
Random Integer
|
random.randint(0, 100)
===> 85
Python Library Reference - random
|
(random 100)
42
Chicken Wiki - Unit extras
|
Random Float 0-1
|
import random
random.random()
===> 0.82075347698782164
Python Library Reference - random
|
|
Random Real Number
|
import random
random.uniform(0,10)
===> 3.030502699001032
Python Library Reference - random
|
|
|
Sequences
|
|
|
Random List Choice (Shallow)
Return a random element of a list.
This function is 'shallow' meaning that if a list is an element of the given list it will return that list (see examples).
|
aList = ['a', 'b', 'c']
random.choice(aList)
===> 'c'
random.choice([[1,2], [3,4], [5,6]])
===> [5, 6]
Python Library Reference - random
|
(define (choice aList)
(list-ref aList (random (length aList))))
(define aList '(a b c))
(choice aList)
===> b
(choice '((1 2) (3 4) (5 6)))
===> (3 4)
|
Random List Choice (Deep)
Choose a random element of a list. If a list is chosen recursively run the function until the chosen element is not a list.
|
This implementation may hit recursion limits on deeply nested lists.
import random
def deepchoice(aList):
c = random.choice(aList)
if type(c) != type([]):
return c
else:
deepchoice(c)
deepchoice([[1,2], [3,4], [5, 6]])
===> 5
|
(define (choice aList)
(list-ref aList (random (length aList))))
(define (deepchoice aList)
(let ((c (choice aList)))
(if (not (list? c))
c
;else
(deepchoice c))))
(deepchoice '((1 2) (3 4) (5 6)))
===> 4
|
Shuffle
Randomly shuffle a sequence.
|
|
(shuffle '(1 2 3 4 5) random)
===> (4 5 2 1 3)
(shuffle '(1 2 3 4 5) random)
===> (3 4 2 1 5)
Chicken Wiki - Unit data-structures
|
Shuffle!
Randomly shuffle a sequence in-place.
|
a = [0, 1, 2, 3]
random.shuffle(a)
a
===> [2, 1, 3, 0]
Python Library Reference - random
|
|
Sample
Return a list of N randomly selected elements from a given list.
|
random.sample([0, 1, 2, 3, 4, 5], 3)
===> [0, 4, 3]
Python Library Reference - random
|
|
|
|
Sockets
|
Concept |
Python |
Chicken |
Overview
|
Python Library Reference - socket
Socket Programming HOWTO
Dev Shed - Sockets in Python
Python Socket Programming
|
Chicken Wiki - Unit tcp
|
|
|
Concepts, Design and Implementation
|
Keywords, Scope and Namespaces
|
Concept |
Python |
Chicken |
Keywords
|
import keyword
keyword.kwlist
['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 'with', 'yield']
Guide to Python Introspection
|
Scheme doesn't really have the concept of reserved keywords. However redefining core functions is usually a bad idea.
|
Can Redefine Keywords?
|
No
|
Yes, but usually not a good idea.
|
Single or Multiple Namespace
Multiple namespaces allow a function and variable to share the same name. The language determines the correct usage depending on the context of the code.
|
Single
|
Single
|
Static or Dynamic Scope
With static scope, a variable always refers to its top-level environment. With dynamic scope, each identifier has a global stack of bindings.
|
Static.
|
Static.
Chicken Wiki - Old Manual
|
Symbol Lookup Order
|
LEGB - Local, Enclosing function locals, Global, Built-in.
Learning Python - Scopes and Arguments
|
|
|
|
Type System
|
Concept |
Python |
Chicken |
Base Types
|
|
boolean symbol char vector null pair number string procedure
|
Strong or Weak Typing
Strong: Objects may not be 'cast' onto an object with another type, "a"+1 returns error
Weak: The language may silently coerce a type into another type so, "a"+1 could work.
|
Strong
|
Strong
Scheme for C Programmers
|
Static or Dynamic Typing
Static: Types of variables are declared by the programmer.
Dynamic: The language decides the type of the variables.
|
Dynamic.
|
Dynamic.
|
Latent or Manifest Typing
Latent: Types are associated with values
Manifest: Types are associated with variables
|
Latent
|
Latent
|
|
|
Recursion
|
Concept |
Python |
Chicken |
Supported?
|
Yes
|
Yes
|
Recursion Limit
|
import sys
sys.getrecursionlimit()
===> 1000
sys.setrecursionlimit(2000)
sys.getrecursionlimit()
===> 2000
|
|
Properly Tail Recursive?
|
Not in Standard Python available in Stackless (and pypy?)
|
Yes
|
Encouraged?
|
Not usually
|
Yes, recursion is the main looping method.
|
|
|
Functional Programming
Haskell Wiki - Functional Programming
Wikipedia - Functional Programming
|
Concept |
Python |
Chicken |
Pure?
Does the language prohibit side-effects?
|
No
|
No
|
Pure Subset?
Does the language have a substantial subset that offers pure functional programming?
|
No
|
Yes
|
Referential Transparency?
Wikipedia - Referential Transparency
|
Yes, but standard coding style is not referentially transparent.
|
Yes, if code is written with it in mind.
|
Eager Evaluation
|
Eager evaluation is the default model.
|
Eager evaluation is the default model.
Functional Programming in Scheme
|
Lazy Evaluation
|
Charming Python
|
Built-ins (delay expression) and (force expression)
SRFI-45
Simple lazy programming in Scheme
|
More Documentation
More resources on functional programming topics.
|
Stupid lambda tricks
|
|
|
|
Memory Management
|
Concept |
Python |
Chicken |
Type of Memory Management
|
Reference Counting
|
Garbage Collected
|
Objects have Unlimited Extent
Objects will remain in memory until it can be proven they will no longer be needed.
|
Yes
|
Yes
|
Run Garbage Collector
|
Python does not have a garbage collector, it uses reference counting.
|
Returns the number of free bytes.
(gc)
===> 149308
#t runs a Major Collection (Default behavior)
(gc #t)
===> 149308
#f runs a Minor Collection.
(gc #f)
===> 148680
Chicken Wiki - Unit library
|
|
|
Code Formatting
|
Concept |
Python |
Chicken |
Indentation Significant?
|
Yes
|
No (Yes with SRFI-49)
SRFI-49
|
Where is Whitespace Significant?
|
Indentation is used to group code.
Whitespace is used to separate keywords (def, if, etc...).
Aside from indentation, whitespace is not significant.
|
Whitespace is used to separate elements of a list.
Additional whitespace is insignificant.
|
Source Code Character Set
|
ASCII
|
ASCII
|
|
|
Compiler, Interperter and IDE Notes
|
Interperter
|
Concept |
Python |
Chicken |
Interpreter Available?
|
Linux Shell: Yes Command: python
Idle
And many more.
|
Linux Shell: Yes Command: csi
|
Command History?
rlwrap is a general solution to command history and editing.
|
Linux Shell: Yes
|
No, but can be added.
Chicken Wiki - FAQ
|
Command Autocomplete?
|
Linux Shell: No
See links for adding autocompletion.
Blog
Blog
|
No, but can be added.
Chicken Wiki - FAQ
|
Get Result of Last Expression
|
21 * 2
===> 42
_
===> 42
_ + 5
===> 47
|
(* 21 2)
===> 42
#
===> 42
(+ # 5)
===> 47
Chicken Wiki - Using the interpreter
|
Interpreter Commands
|
|
,?
===> Toplevel commands:
===> ,? Show this text
===> ,p EXP Pretty print evaluated expression EXP
===> ... and many more!
|
Easter Eggs
|
from __future__ import braces
===> SyntaxError: not a chance
import this
===> The Zen of Python, by Tim Peters
===>
===> Beautiful is better than ugly.
===> Explicit is better than implicit.
===> Simple is better than complex.
===> Complex is better than complicated.
===> ... (See link below for the Zen of Python)
PEP-20 - The Zen of Python
|
|
|
|
Total Sections: 47