diff --git a/README.md b/README.md index 13204761..aa2ca977 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,11 @@ described below. Here's some places that have seen recent work + * Changed the builtin math, time and random functions to no longer + include the math., time. or random. prefixes. This makes them more + convenient to use. To retain compatibility with Python, you can + use 'from math import *' which Snek will ignore. + * [Mu](https://codewith.mu/) version 1.2.0 has Snek support built in now. Mu is an IDE designed for new Python users that offers a more polished alternative to the simple Snek IDE provide with snek. diff --git a/doc/lessons/lesson-1/lesson-1-snekboard.adoc b/doc/lessons/lesson-1/lesson-1-snekboard.adoc index f018b235..05598145 100644 --- a/doc/lessons/lesson-1/lesson-1-snekboard.adoc +++ b/doc/lessons/lesson-1/lesson-1-snekboard.adoc @@ -274,7 +274,7 @@ things in front of it: ---- > *while True:* + *print(read(A1))* -+ *time.sleep(1)* ++ *sleep(1)* + 0.3484738 0.3829738 @@ -289,7 +289,7 @@ things in front of it: *Ctrl+C* ---- -You'll need to hit kbd:[Enter] after *time.sleep(1)* to get the +You'll need to hit kbd:[Enter] after *sleep(1)* to get the program to run. Hit kbd:[Ctrl+C] when you're done testing to stop the program. diff --git a/doc/lessons/lesson-2/lesson-2-line-bug.adoc b/doc/lessons/lesson-2/lesson-2-line-bug.adoc index 6f2cbf01..46dac49d 100644 --- a/doc/lessons/lesson-2/lesson-2-line-bug.adoc +++ b/doc/lessons/lesson-2/lesson-2-line-bug.adoc @@ -80,7 +80,7 @@ light sensor using something like this (use C to stop): while True: print(read(A1)) - time.sleep(1) + sleep(1) Consider: diff --git a/doc/lessons/lesson-3/bumper-car.py b/doc/lessons/lesson-3/bumper-car.py index c07f1ca2..9070da3c 100644 --- a/doc/lessons/lesson-3/bumper-car.py +++ b/doc/lessons/lesson-3/bumper-car.py @@ -36,8 +36,8 @@ def WaitUntilCloseOtherDir(): def WaitRandom(): - wait = 0.25 + random.randrange(10) / 10 - time.sleep(wait) + wait = 0.25 + randrange(10) / 10 + sleep(wait) def Spin(): @@ -62,7 +62,7 @@ def BumperCar(): # Back up a bit and spin around MoveOneDir() - time.sleep(0.5) + sleep(0.5) SpinRandom() MoveOneDir() @@ -70,7 +70,7 @@ def BumperCar(): # Back up a bit and spin around MoveOtherDir() - time.sleep(0.5) + sleep(0.5) SpinRandom() MoveOtherDir() diff --git a/doc/lessons/lesson-3/lesson-3-bumper-car.adoc b/doc/lessons/lesson-3/lesson-3-bumper-car.adoc index 0a1b16ba..14545852 100644 --- a/doc/lessons/lesson-3/lesson-3-bumper-car.adoc +++ b/doc/lessons/lesson-3/lesson-3-bumper-car.adoc @@ -138,7 +138,7 @@ distance: ---- > *while True:* + *print(read(A8))* -+ *time.sleep(1)* ++ *sleep(1)* + 0.162149 0.1758242 @@ -197,22 +197,22 @@ do this, we'll spin in place. To make our robot less predictable, let's have it spin a random amount. Random numbers are like the roll of a die; you can't predict the value. Snek can generate random numbers using the -`random.randrange` function. `random.randrange` takes one value, and +`randrange` function. `randrange` takes one value, and will generate a random number from zero to one less than this value. So, if you want a random number from the set { 0, 1, 2, 3, 4, 5 }, -you'd use `random.randrange(6)`. We can do arithmetic on the number to +you'd use `randrange(6)`. We can do arithmetic on the number to adjust the range further. Let's explore that: [subs="verbatim,quotes"] ---- -> *random.randrange(6)* +> *randrange(6)* 3 -> *random.randrange(6)* +> *randrange(6)* 1 > *for i in range(5):* -+ *print(random.randrange(6))* ++ *print(randrange(6))* + 5 1 @@ -220,7 +220,7 @@ Let's explore that: 0 3 > *for i in range(5):* -+ *print(random.randrange(6) + 1)* ++ *print(randrange(6) + 1)* + 6 5 @@ -236,8 +236,8 @@ say between 1 and 6 seconds: [source,python,subs="verbatim,quotes"] ---- def WaitRandom(): - wait = random.randrange(6) + 1 - time.sleep(wait) + wait = randrange(6) + 1 + sleep(wait) ---- Let's figure out how to get the bumper car to spin. To go straight, we @@ -277,7 +277,7 @@ def BumperCar(): # Back up a bit and spin around MoveOneDir() - time.sleep(1) + sleep(1) SpinRandom() MoveOneDir() @@ -285,7 +285,7 @@ def BumperCar(): # Back up a bit and spin around MoveOtherDir() - time.sleep(1) + sleep(1) SpinRandom() MoveOtherDir() diff --git a/doc/snek.adoc b/doc/snek.adoc index 4a67bc17..6d1bb282 100644 --- a/doc/snek.adoc +++ b/doc/snek.adoc @@ -724,14 +724,14 @@ Digital pin 13:(((talkto)))(((on))) > *on()* ---- -Let's get a bit fancier and blink it:(((time.sleep))) +Let's get a bit fancier and blink it:(((sleep))) [subs="verbatim,quotes"] ---- > *talkto(D13)* > *while True:* + *onfor(.5)* -+ *time.sleep(.5)* ++ *sleep(.5)* ---- ==== Hooking up a digital input @@ -768,7 +768,7 @@ Analog pin 0 and make the LED track the sensor:(((read)))(((onfor))) > *talkto(D13)* > *while True:* + *onfor(1-read(A0))* -+ *time.sleep(1-read(A0))* ++ *sleep(1-read(A0))* ---- ==== Controlling motors @@ -788,9 +788,9 @@ directions with:(((setpower)))(((setleft)))(((setright))) > *on()* > *while True:* + *setleft()* -+ *time.sleep(1)* ++ *sleep(1)* + *setright()* -+ *time.sleep(1)* ++ *sleep(1)* ---- = Snek Reference Manual @@ -850,7 +850,7 @@ period. Here are some valid names:(((Name))) hello _hello _h4 -math.sqrt +sqrt ---- And here are some invalid names: @@ -870,9 +870,10 @@ Snek keywords:(((Keyword))) ---- and assert break continue def del elif else -for global if import -in is not or -pass range return while +for from global if +import in is not +or pass range return +while ---- === Punctuation @@ -1625,6 +1626,16 @@ be run using Python.(((import))) > *import curses* ---- +=== `from` _name_ `import *` + +The From statement is ignored and is part of Snek so that Snek programs can +be run using Python.(((from))) + +[subs="verbatim,quotes"] +---- +> *from random import ** +---- + === `global` _name_ _[_ `,` _name_ … _]_ The Global statement marks the names as non-local; assignment to them @@ -1799,12 +1810,12 @@ value of a number is the number's distance from 0.(((abs))) 2 ---- -=== `math.sqrt(` _number_ `)` -Compute the square root of its numeric argument.(((math.sqrt))) +=== `sqrt(` _number_ `)` +Compute the square root of its numeric argument.(((sqrt))) [subs="verbatim,quotes"] ---- -> *math.sqrt(2)* +> *sqrt(2)* 1.414214 ---- @@ -1821,51 +1832,61 @@ Posix-compatible systems, _value_ should be a number which forms the exit code for the Snek process with zero indicating success and non-zero indicating failure.(((exit))) -=== `time.sleep(` _seconds_ `)` +=== `sleep(` _seconds_ `)` Pause for the specified amount of time (which can include a fractional -part).(((time.sleep))) +part).(((sleep))) [subs="verbatim,quotes"] ---- -> *time.sleep(1)* +> *sleep(1)* > ---- -=== `time.monotonic()` +=== `monotonic()` Return the time (in seconds) since some unspecified reference point in the system history. This time always increases, even if the system clock is adjusted (hence the name). Because Snek uses single-precision floating point values for all numbers, the reference point will be close to the starting time of the Snek system, so values may be quite -small.(((time.monotonic))) +small.(((monotonic))) [subs="verbatim,quotes"] ---- -> *time.monotonic()* +> *monotonic()* 6.859814 ---- -=== `random.seed(` _seed_ `)` +=== `seed(` _seed_ `)` Re-seeds the random number generator with `seed`. The random number generator will always generate the same sequence of numbers if started -with the same `seed`.(((random.seed))) +with the same `seed`.(((seed))) [subs="verbatim,quotes"] ---- -> *random.seed(time.monotonic())* +> *seed(monotonic())* > ---- -=== `random.randrange(` _max_ `)` +=== `random()` + +Generates a random value greater than or equal to 0 and less than 1.(((random))) + +[subs="verbatim,quotes"] +---- +> *randrange(10)* +3 +---- + +=== `randrange(` _max_ `)` -Generates a random integer between 0 and max-1 inclusive.(((random.randrange))) +Generates a random integer between 0 and max-1 inclusive.(((randrange))) [subs="verbatim,quotes"] ---- -> *random.randrange(10)* +> *randrange(10)* 3 ---- @@ -1936,127 +1957,127 @@ are provided and follow the definitions here. === Number-theoretic and representation functions -math.ceil(x):: -Return the ceiling of x, the smallest integer greater than or equal to x.(((math.ceil))) -math.copysign(x,y):: -Return a number with the magnitude (absolute value) of x but the sign of y.(((math.copysign))) -math.fabs(x):: -Return the absolute value of x.(((math.fabs))) -math.factorial(x):: -Return the factorial of x.(((math.factorial))) -math.floor(x):: -Return the floor of x, the largest integer less than or equal to x.(((math.floor))) -math.fmod(x,y):: -Return the modulus of x and y: x - trunc(x/y) * y.(((math.fmod))) -math.frexp(x):: -Returns the normalized fraction and exponent in a tuple (frac, exp). 0.5 ≤ abs(frac) < 1, and x = frac * pow(2,exp).(((math.frexp))) -math.fsum(l):: -Returns the sum of the numbers in l, which must be a list or tuple.(((math.fsum))) -math.gcd(x,y):: -Return the greatest common divisor of x and y.(((math.gcd))) -math.isclose(x,y,rel_val=1e-6,abs_val=0.0):: +ceil(x):: +Return the ceiling of x, the smallest integer greater than or equal to x.(((ceil))) +copysign(x,y):: +Return a number with the magnitude (absolute value) of x but the sign of y.(((copysign))) +fabs(x):: +Return the absolute value of x.(((fabs))) +factorial(x):: +Return the factorial of x.(((factorial))) +floor(x):: +Return the floor of x, the largest integer less than or equal to x.(((floor))) +fmod(x,y):: +Return the modulus of x and y: x - trunc(x/y) * y.(((fmod))) +frexp(x):: +Returns the normalized fraction and exponent in a tuple (frac, exp). 0.5 ≤ abs(frac) < 1, and x = frac * pow(2,exp).(((frexp))) +fsum(l):: +Returns the sum of the numbers in l, which must be a list or tuple.(((fsum))) +gcd(x,y):: +Return the greatest common divisor of x and y.(((gcd))) +isclose(x,y,rel_val=1e-6,abs_val=0.0):: Returns a boolean indicating whether x and y are 'close' together. This is defined as -abs(x-y) ≤ max(rel_tol * max(abs(a), abs(b)), abs_tol).(((math.isclose))) -math.isfinite(x):: -Returns True if x is finite else False.(((math.isfinite))) -math.isinf:: -Returns True if x is infinite else False.(((math.isinf))) -math.isnan:: -Returns True if x is not a number else False.(((math.isnan))) -math.ldexp(x,y):: -Returns x * pow(2,y).(((math.ldexp))) -math.modf(x):: -Returns (x - trunc(x), trunc(x)).(((math.modf))) -math.remainder(x,y):: -Returns the remainder of x and y: x - round(x/y) * y.(((math.remainder))) -math.trunc:: -Returns the truncation of x, the integer closest to x which is no further from zero than x.(((math.trunc))) +abs(x-y) ≤ max(rel_tol * max(abs(a), abs(b)), abs_tol).(((isclose))) +isfinite(x):: +Returns True if x is finite else False.(((isfinite))) +isinf:: +Returns True if x is infinite else False.(((isinf))) +isnan:: +Returns True if x is not a number else False.(((isnan))) +ldexp(x,y):: +Returns x * pow(2,y).(((ldexp))) +modf(x):: +Returns (x - trunc(x), trunc(x)).(((modf))) +remainder(x,y):: +Returns the remainder of x and y: x - round(x/y) * y.(((remainder))) +trunc:: +Returns the truncation of x, the integer closest to x which is no further from zero than x.(((trunc))) round(x):: Returns the integer nearest x, with values midway between two integers rounding away from zero.(((round))) === Power and logarithmic functions -math.exp(x):: -Returns pow(e,x).(((math.exp))) -math.expm1(x):: -Returns exp(x)-1.(((math.expm1))) -math.exp2(x):: -Returns pow(2,x).(((math.exp2))) -math.log(x):: -Returns the natural logarithm of x.(((math.log))) -math.log1p(x):: -Returns log(x+1).(((math.log1p))) -math.log2(x):: -Returns the log base 2 of x.(((math.log2))) -math.log10(x):: -Returns the log base 10 of x.(((math.log10))) -math.pow(x,y):: -Returns x raised to the y^th^ power.(((math.pow))) +exp(x):: +Returns pow(e,x).(((exp))) +expm1(x):: +Returns exp(x)-1.(((expm1))) +exp2(x):: +Returns pow(2,x).(((exp2))) +log(x):: +Returns the natural logarithm of x.(((log))) +log1p(x):: +Returns log(x+1).(((log1p))) +log2(x):: +Returns the log base 2 of x.(((log2))) +log10(x):: +Returns the log base 10 of x.(((log10))) +pow(x,y):: +Returns x raised to the y^th^ power.(((pow))) === Trigonometric functions -math.acos(x):: -Returns the arc cosine of x in the range of 0 ≤ acos(x) ≤ π.(((math.acos))) -math.asin(x):: -Returns the arc sine of x in the range of -π/2 ≤ asin(x) ≤ π/2.(((math.asin))) -math.atan(x):: -Returns the arc tangent of x in the range of -π/2 ≤ atan(x) ≤ π/2.(((math.atan))) -math.atan2(y,x):: -Returns the arc tangent of y/x in the range of -π ≤ atan2(y,x) ≤ π.(((math.atan2))) -math.cos(x):: -Returns the cosine of x.(((math.cos))) -math.hypot(x,y):: -Returns sqrt(x*x + y*y).(((math.hypot))) -math.sin(x):: -Returns the sine of x.(((math.sin))) -math.tan(x):: -Returns the tangent of x.(((math.tan))) +acos(x):: +Returns the arc cosine of x in the range of 0 ≤ acos(x) ≤ π.(((acos))) +asin(x):: +Returns the arc sine of x in the range of -π/2 ≤ asin(x) ≤ π/2.(((asin))) +atan(x):: +Returns the arc tangent of x in the range of -π/2 ≤ atan(x) ≤ π/2.(((atan))) +atan2(y,x):: +Returns the arc tangent of y/x in the range of -π ≤ atan2(y,x) ≤ π.(((atan2))) +cos(x):: +Returns the cosine of x.(((cos))) +hypot(x,y):: +Returns sqrt(x*x + y*y).(((hypot))) +sin(x):: +Returns the sine of x.(((sin))) +tan(x):: +Returns the tangent of x.(((tan))) === Angular conversion -math.degrees(x):: -Returns x * 180/π.(((math.degrees))) -math.radians(x):: -Returns x * π/180.(((math.radians))) +degrees(x):: +Returns x * 180/π.(((degrees))) +radians(x):: +Returns x * π/180.(((radians))) === Hyperbolic functions -math.acosh(x):: -Returns the inverse hyperbolic cosine of x.(((math.acosh))) -math.asinh(x):: -Returns the inverse hyperbolic sine of x.(((math.asinh))) -math.atanh(x):: -Returns the inverse hyperbolic tangent of x.(((math.atanh))) -math.cosh(x):: -Returns the hyperbolic cosine of x: (exp(x) + exp(-x)) / 2.(((math.cosh))) -math.sinh(x):: -Returns the hyperbolic sine of x: (exp(x) - exp(-x)) / 2.(((math.sinh))) -math.tanh(x):: -Returns the hyperbolic tangent of x: sinh(x) / cosh(x).(((math.tanh))) +acosh(x):: +Returns the inverse hyperbolic cosine of x.(((acosh))) +asinh(x):: +Returns the inverse hyperbolic sine of x.(((asinh))) +atanh(x):: +Returns the inverse hyperbolic tangent of x.(((atanh))) +cosh(x):: +Returns the hyperbolic cosine of x: (exp(x) + exp(-x)) / 2.(((cosh))) +sinh(x):: +Returns the hyperbolic sine of x: (exp(x) - exp(-x)) / 2.(((sinh))) +tanh(x):: +Returns the hyperbolic tangent of x: sinh(x) / cosh(x).(((tanh))) === Special functions -math.erf(x):: -Returns the error function at x.(((math.erf))) -math.erfc(x):: -Returns the complement of the error function at x. This is 1 - erf(x).(((math.erfc))) -math.gamma(x):: -Returns the gamma function at x.(((math.gamma))) -math.lgamma(x):: -Returns log(gamma(x)).(((math.lgamma))) +erf(x):: +Returns the error function at x.(((erf))) +erfc(x):: +Returns the complement of the error function at x. This is 1 - erf(x).(((erfc))) +gamma(x):: +Returns the gamma function at x.(((gamma))) +lgamma(x):: +Returns log(gamma(x)).(((lgamma))) === Mathematical constants -math.pi:: -The mathematical constant π, to available precision.(((math.pi)))(((π))) -math.e:: -The mathematical constant e, to available precision.(((math.e)))(((e))) -math.tau:: -The mathematical constant τ, which is 2π, to available precision.(((math.tau)))(((τ))) -math.inf:: -The floating point value which represents ∞.(((math.inf)))(((∞))) -math.nan:: -The floating point value which represents Not a Number.(((math.nan)))(((NaN))) +pi:: +The mathematical constant π, to available precision.(((pi)))(((π))) +e:: +The mathematical constant e, to available precision.(((e)))(((e))) +tau:: +The mathematical constant τ, which is 2π, to available precision.(((tau)))(((τ))) +inf:: +The floating point value which represents ∞.(((inf)))(((∞))) +nan:: +The floating point value which represents Not a Number.(((nan)))(((NaN))) == GPIO Functions diff --git a/examples/badshuffle.py b/examples/badshuffle.py index 2211a5ec..330fc14c 100644 --- a/examples/badshuffle.py +++ b/examples/badshuffle.py @@ -1,9 +1,9 @@ #!/usr/bin/python3 -import random -import time +from random import * +from time import * -random.seed(time.monotonic()) +seed(monotonic()) # "Shuffle" a list, but *wrong*. @@ -15,7 +15,7 @@ for i in range(narray): a[i] = i for i in range(narray): - j = random.randrange(narray) + j = randrange(narray) tmp = a[j] a[j] = a[i] a[i] = tmp diff --git a/examples/blink.py b/examples/blink.py index c2f8ae86..73ac1a00 100644 --- a/examples/blink.py +++ b/examples/blink.py @@ -12,6 +12,8 @@ # General Public License for more details. # +from time import * + led = D13 @@ -19,9 +21,9 @@ def blink(): talkto(led) while True: on() - time.sleep(0.5) + sleep(0.5) off() - time.sleep(0.5) + sleep(0.5) blink() diff --git a/examples/goodshuffle.py b/examples/goodshuffle.py index 9b8a2c6a..ac39a240 100644 --- a/examples/goodshuffle.py +++ b/examples/goodshuffle.py @@ -1,9 +1,9 @@ #!/usr/bin/python3 -import random -import time +from random import * +from time import * -random.seed(time.monotonic()) +seed(monotonic()) # "Shuffle" a list, but *wrong*. @@ -15,7 +15,7 @@ for i in range(narray): a[i] = i for i in range(narray): - j = i + random.randrange(narray - i) + j = i + randrange(narray - i) tmp = a[j] a[j] = a[i] a[i] = tmp diff --git a/examples/hanoi.py b/examples/hanoi.py index c6730c84..51a84da4 100644 --- a/examples/hanoi.py +++ b/examples/hanoi.py @@ -12,7 +12,7 @@ # General Public License for more details. # -import time +from time import * import sys @@ -119,7 +119,7 @@ def display_towers(x, towers): def display_flush(): display_string(1, bottom_y + 1, "") sys.stdout.flush() - time.sleep(move_delay) + sleep(move_delay) return True diff --git a/examples/morse.py b/examples/morse.py index f1584e30..d8a4a54c 100644 --- a/examples/morse.py +++ b/examples/morse.py @@ -2,6 +2,8 @@ # Morse code example # +from time import * + T = 1.2 / 12 a = ( @@ -59,14 +61,14 @@ def l(c): onfor(T) else: onfor(3 * T) - time.sleep(T) - time.sleep(3 * T) + sleep(T) + sleep(3 * T) def m(t): for c in t: if c == " ": - time.sleep(6 * T) + sleep(6 * T) else: l(c) diff --git a/examples/neopixel.py b/examples/neopixel.py index c9027391..700dc190 100644 --- a/examples/neopixel.py +++ b/examples/neopixel.py @@ -16,6 +16,8 @@ # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. # +from time import * + bright = 0.1 @@ -40,7 +42,7 @@ def blink(): while True: for pos in range(0, 3, 0.01): rainbow(pos) - time.sleep(0.003) + sleep(0.003) blink() diff --git a/examples/neopixels.py b/examples/neopixels.py index 1fc0326f..e8710b93 100644 --- a/examples/neopixels.py +++ b/examples/neopixels.py @@ -19,6 +19,8 @@ # Rotate a rainbow through a set of pixels # +from time import * + DOWN = BUTTONA UP = BUTTONB @@ -67,7 +69,7 @@ def rainbow_cycle(wait): if bright < 0.99: bright += 0.01 print(bright) - time.sleep(wait) + sleep(wait) def cycles(): diff --git a/examples/pi.py b/examples/pi.py new file mode 100644 index 00000000..f3d3159b --- /dev/null +++ b/examples/pi.py @@ -0,0 +1,37 @@ +#!/usr/bin/snek +# +# Imagine a circle inscribed in a square. The ratio of their areas is +# the same as the ratio of a random point in the square also being in +# the circle +# +# We'll use a circle of radius 1, which means the square is 2x2. The +# circle has area π, the square has area 4: +# +# circle / square = π / 4 = inside / tries +# +# π = inside / tries * 4 +# + +import random +import time + + +def pi(outer): + start = time.monotonic() + inner = 100 + inside = 0 + for o in range(outer): + for i in range(inner): + # Pick a random point in the square. This point will have + # coordinates from (-1,-1) to (1,1) + x = random.random() * 2 - 1 + y = random.random() * 2 - 1 + # Check to see if the point is inside the circle + if x * x + y * y <= 1: + inside += 1 + print("inside %d pi %g" % (inside, inside / (outer * inner) * 4)) + stop = time.monotonic() + print("time %f" % (stop - start)) + + +pi(100) diff --git a/examples/servo-car.py b/examples/servo-car.py index c6867d76..8ebb5936 100644 --- a/examples/servo-car.py +++ b/examples/servo-car.py @@ -1,3 +1,19 @@ +# +# Copyright © 2019 Keith Packard +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# + +from random import * + servo = M4 motor = M1 front = A1 @@ -48,10 +64,10 @@ def right(t, d): def bounce(): - straight(random.randrange(10) / 10 + 1, True) - right(random.randrange(10) / 10 + 1, False) - left(random.randrange(10) / 10 + 1, True) - straight(random.randrange(10) / 10 + 1, False) + straight(randrange(10) / 10 + 1, True) + right(randrange(10) / 10 + 1, False) + left(randrange(10) / 10 + 1, True) + straight(randrange(10) / 10 + 1, False) while True: diff --git a/examples/snek-bsd.py b/examples/snek-bsd.py index 737931d3..4fa213f3 100644 --- a/examples/snek-bsd.py +++ b/examples/snek-bsd.py @@ -35,11 +35,11 @@ # arrow keys. You can leave at the exit any time. # -import time +from time import * import sys -import random +from random import * import curses -import math +from math import * def cashvalue(): @@ -112,7 +112,7 @@ def endwin(): def delay(t): - time.sleep(t * 0.05) + sleep(t * 0.05) you = _p(0, 0) @@ -138,7 +138,7 @@ def error(s): def main(): global penalty, loot, finish, you, money, snake, chunk - random.seed(time.monotonic()) + seed(monotonic()) penalty = 0 loot = 0 initscr() @@ -323,7 +323,7 @@ def drawbox(): def snrand(): while True: - p = _p(random.randrange(ccnt), random.randrange(lcnt)) + p = _p(randrange(ccnt), randrange(lcnt)) # make sure it's not on top of something else if _y(p) == 0 and _x(p) < 5: continue @@ -352,7 +352,7 @@ def chase(sp): global oldw, loot # this algorithm has bugs; otherwise the snake would get too good d = _p(_x(you) - _x(sp), _y(you) - _y(sp)) - v1 = math.sqrt(_x(d) ** 2 + _y(d) ** 2) + v1 = sqrt(_x(d) ** 2 + _y(d) ** 2) w = 0 max = 0 wt = [0] * 8 @@ -391,7 +391,7 @@ def chase(sp): w = 0 for i in range(8): w += wt[i] - vp = random.randrange(w) + vp = randrange(w) vpo = vp for i in range(8): if vp < wt[i]: @@ -583,7 +583,7 @@ def pushsnake(): if snake[i] == you or tmp == you: surround(you) i = (cashvalue()) % 10 - bonus = random.randrange(10) + bonus = randrange(10) mvaddstr(lcnt + 1, 0, "%d" % bonus) refresh() delay(30) diff --git a/examples/snek-car.py b/examples/snek-car.py index 19ff7bc5..eb71cbf0 100644 --- a/examples/snek-car.py +++ b/examples/snek-car.py @@ -16,6 +16,8 @@ # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. # +from time import * + # This program is for the Crickit FeatherWing board # Motor 1 is on the right side of the car @@ -117,10 +119,10 @@ def bumper(): while True: go_forw() back() - time.sleep(0.5) + sleep(0.5) stop() left() - time.sleep(0.25) + sleep(0.25) stop() go_forw() go_back() diff --git a/examples/snek.py b/examples/snek.py index afb53d48..5f4c14bc 100755 --- a/examples/snek.py +++ b/examples/snek.py @@ -12,9 +12,9 @@ # General Public License for more details. # -import random +from random import * +from time import * import curses -import time stdscr = 0 @@ -46,7 +46,7 @@ def _p(x, y): def put_snak(): global snek, snak while True: - snak = _p(random.randrange(cols - 2) + 1, random.randrange(lines - 2) + 1) + snak = _p(randrange(cols - 2) + 1, randrange(lines - 2) + 1) for s in snek: if snak == s: break @@ -122,7 +122,7 @@ def main(): curses.cbreak() stdscr.nodelay(True) stdscr.erase() - random.seed(time.monotonic()) + seed(monotonic()) snek = [_p(1, 1)] put_snak() for x in range(1, cols - 1): @@ -135,7 +135,7 @@ def main(): while True: stdscr.move(_y(snek[0]), _x(snek[0])) stdscr.refresh() - time.sleep(0.1) + sleep(0.1) c = getch() ndx = dx ndy = dy @@ -155,7 +155,7 @@ def main(): done("quit") elif c == "p": while getch() != "p": - time.sleep(0.1) + sleep(0.1) if ndx != -dx or ndy != -dy: dx = ndx dy = ndy diff --git a/ports/duemilanove/Makefile b/ports/duemilanove/Makefile index 0dde1c5f..3d209bd4 100644 --- a/ports/duemilanove/Makefile +++ b/ports/duemilanove/Makefile @@ -25,6 +25,7 @@ BAUD?=115200 INSTALLER?=1 ATMEGA_FLASH_SIZE?=0x7e00 MCU?=m328p +SNEK_GLOBAL_ALIAS?=n include $(SNEK_ATMEGA)/snek-atmega.defs diff --git a/ports/snekboard/snek-board-test.py b/ports/snekboard/snek-board-test.py index 7c697150..736b7d45 100644 --- a/ports/snekboard/snek-board-test.py +++ b/ports/snekboard/snek-board-test.py @@ -17,7 +17,7 @@ import serial import sys import threading -import time +from time import * port = None @@ -27,7 +27,7 @@ def sync(): global port # wait for the device to get started - time.sleep(1) + sleep(1) port.write(b"\x0eprint(chr(37))\n") while True: data = port.read(1) diff --git a/snek-builtin.py b/snek-builtin.py index 64a33ae2..c1078d2a 100644 --- a/snek-builtin.py +++ b/snek-builtin.py @@ -27,22 +27,35 @@ def fprint(msg="", end="\n", file=sys.stdout): class SnekBuiltin: - def __init__(self, name, param, value, condition=None): + def __init__(self, name, param, value, globals=None, condition=None): self.name = name self.value = None self.init = None + self.alias = None self.condition = condition - if value and value[0] == "=": - self.init = value[1:] - else: - self.value = value self.id = -1 + self.full_name = name.replace(".", "_") + self.global_alias = False if param[0].isalpha(): self.keyword = param self.nformal = -3 else: self.keyword = False self.nformal = int(param) + if value and value[0] == "=": + if self.nformal == -2: + self.init = value[1:] + else: + self.alias = value[1:] + else: + self.value = value + for g in globals: + if name.startswith(g + "."): + self.alias = name + self.global_alias = True + self.name = name.removeprefix(g + ".") + self.full_name = self.name + break def __eq__(self, other): return self.name == other.name @@ -89,7 +102,7 @@ def snek_name(self): return self.name def cpp_name(self): - return "SNEK_BUILTIN_%s" % (self.name.replace(".", "_")) + return "SNEK_BUILTIN_%s" % self.full_name def func_name(self): if self.is_value(): @@ -97,8 +110,8 @@ def func_name(self): return "(snek_poly_t)(float)%s" % self.value return self.value name = self.name - if self.init is not None: - name = self.init + if self.alias is not None: + name = self.alias return "snek_builtin_%s" % (name.replace(".", "_")) def func_field(self): @@ -114,14 +127,30 @@ def set_id(self): self.id = builtin_id builtin_id += 1 + def __str__(self): + return ( + "builtin(name='%s', value='%r', init='%r', alias='%s', full_name='%s')" + % (self.name, self.value, self.init, self.alias, self.full_name) + ) + headers = [] builtins = [] +globals = [] +aliases = False def add_builtin(name, id, value, condition): - global builtins - builtins += [SnekBuiltin(name, id, value, condition)] + global builtins, globals, aliases + builtin = SnekBuiltin(name, id, value, globals, condition) + for b in builtins: + if b.name == builtin.name: + print("%s: skipping duplicate" % name) + return + builtins += [builtin] + if aliases and builtin.global_alias: + builtin = SnekBuiltin(name, id, value, [], condition) + builtins += [builtin] def load_builtins(filename): @@ -311,6 +340,8 @@ def dump_cpp(fp): def builtin_main(): + global globals, aliases + parser = argparse.ArgumentParser(description="Construct Snek builtin data.") parser.add_argument( "builtins", metavar="F", nargs="+", help="input files describing builtins" @@ -319,9 +350,24 @@ def builtin_main(): parser.add_argument( "-m", "--mu", action="store_true", help="output just non-keyword constants" ) + parser.add_argument( + "-a", "--alias", action="store_true", help="--globals are also namespaced" + ) + parser.add_argument( + "-g", + "--global", + action="append", + dest="globals", + help="remove this leading namespace", + ) args = parser.parse_args() + if args.globals: + globals = args.globals + + aliases = args.alias + for b in args.builtins: load_builtins(b) diff --git a/snek.defs b/snek.defs index 67a45cb8..7d46d79b 100644 --- a/snek.defs +++ b/snek.defs @@ -103,6 +103,14 @@ SNEK_BASE_CFLAGS = \ LOLA_FLAGS ?= +SNEK_GLOBAL_ALIAS ?= y +SNEK_GLOBAL_NAMES ?= math random time + +SNEK_BUILTIN_FLAGS += $^ $(foreach GL,$(SNEK_GLOBAL_NAMES),--global $(GL)) + +ifeq ($(SNEK_GLOBAL_ALIAS),y) + SNEK_BUILTIN_FLAGS += --alias +endif ifdef SNEK_NO_SLICE SNEK_BASE_CFLAGS += -DSNEK_NO_SLICE @@ -144,7 +152,7 @@ snek-gram.h: $(SNEK_ROOT)/snek-gram.ll lola $(SNEK_LOLA_FLAGS) -o $@ $^ snek-builtin.h: $(SNEK_ROOT)/snek-builtin.py $(SNEK_BUILTINS) - python3 $^ -o $@ + python3 $(SNEK_BUILTIN_FLAGS) -o $@ clean:: rm -f snek-gram.h snek-builtin.h $(SNEK_OBJ) diff --git a/test/pass-math.py b/test/pass-math.py index f998c9a5..3316c565 100644 --- a/test/pass-math.py +++ b/test/pass-math.py @@ -15,7 +15,7 @@ # Test math builtins # -import math +from math import * def fail(which): @@ -26,77 +26,77 @@ def fail(which): # # Number-theoretic and representation functions # -if not math.ceil(0.5) == 1: - fail("math.ceil(0.5) == 1") -if not math.ceil(-0.5) == 0: - fail("math.ceil(-0.5) == 0") -if not math.copysign(1.1, -2) == -1.1: - fail("math.copysign(1.1, -2) == -1.1") -if not math.copysign(-1.1, -2) == -1.1: - fail("math.copysign(-1.1, -2) == -1.1") -if not math.copysign(1.1, 2) == 1.1: - fail("math.copysign(1.1, 2) == 1.1") -if not math.copysign(-1.1, 2) == 1.1: - fail("math.copysign(-1.1, 2) == 1.1") -if not math.fabs(-1.1) == 1.1: - fail("math.fabs(-1.1) == 1.1") -if not math.fabs(1.1) == 1.1: - fail("math.fabs(1.1) == 1.1") -if not math.factorial(9) == 362880: - fail("math.factorial(9) == 362880") -if not math.floor(0.5) == 0: - fail("math.floor(0.5) == 0") -if not math.floor(-0.5) == -1: - fail("math.floor(-0.5) == -1") -if not math.frexp(12.5) == (0.78125, 4): - fail("math.frexp(12.5) == (0.78125, 4)") -if not math.isclose(math.fsum([0.001] * 1000), 1): - fail("math.isclose(math.fsum([0.01] * 100), 1)") -if not math.gcd(21, 14) == 7: - fail("math.gcd(21,14) == 7") +if not ceil(0.5) == 1: + fail("ceil(0.5) == 1") +if not ceil(-0.5) == 0: + fail("ceil(-0.5) == 0") +if not copysign(1.1, -2) == -1.1: + fail("copysign(1.1, -2) == -1.1") +if not copysign(-1.1, -2) == -1.1: + fail("copysign(-1.1, -2) == -1.1") +if not copysign(1.1, 2) == 1.1: + fail("copysign(1.1, 2) == 1.1") +if not copysign(-1.1, 2) == 1.1: + fail("copysign(-1.1, 2) == 1.1") +if not fabs(-1.1) == 1.1: + fail("fabs(-1.1) == 1.1") +if not fabs(1.1) == 1.1: + fail("fabs(1.1) == 1.1") +if not factorial(9) == 362880: + fail("factorial(9) == 362880") +if not floor(0.5) == 0: + fail("floor(0.5) == 0") +if not floor(-0.5) == -1: + fail("floor(-0.5) == -1") +if not frexp(12.5) == (0.78125, 4): + fail("frexp(12.5) == (0.78125, 4)") +if not isclose(fsum([0.001] * 1000), 1): + fail("isclose(fsum([0.01] * 100), 1)") +if not gcd(21, 14) == 7: + fail("gcd(21,14) == 7") big = 10.1 for i in range(40): big *= big -if not math.isclose(1, 1): - fail("math.isclose(1,1)") -if not not math.isclose(1.1, 1): - fail("not math.isclose(1.1,1)") -if not math.isclose(1.1, 1, rel_tol=0.2): - fail("math.isclose(1.1,1,rel_tol=.2)") -if not math.isfinite(math.factorial(33)): - fail("math.isfinite(math.factorial(33))") -if not not math.isfinite(big): - fail("not math.isfinite(big)") -if not not math.isfinite(math.inf): - fail("not math.isfinite(math.inf)") -if not math.isinf(math.inf): - fail("math.isinf(math.inf)") -if not math.isinf(big): - fail("math.isinf(math.inf)") -if not not math.isinf(math.factorial(33)): - fail("not math.isinf(math.factorial(33))") -if not math.isnan(math.nan): - fail("math.isnan(math.nan)") -if not math.isnan(math.inf - math.inf): - fail("math.isnan(math.inf - math.inf)") -if not not math.isnan(big): - fail("not math.isnan(math.inf)") -if not not math.isnan(1.0): - fail("not math.isnan(1.0)") -if not math.ldexp(1, 2) == 4: - fail("math.ldexp(1,2) == 4") -if not math.ldexp(1, -2) == 1 / 4: - fail("math.ldexp(1,-2) == 1/4") -if not math.modf(1.25) == (0.25, 1.0): - fail("math.modf(1.25) == (0.25, 1.0)") -if not math.remainder(5, 2) == 1: - fail("math.remainder(5,2) == 1") -if not math.remainder(2.25, 0.5) == 0.25: - fail("math.remainder(2.25,.5) == .25") -if not math.trunc(3.1) == 3: - fail("math.trunc(3.1) == 3") -if not math.trunc(-3.1) == -3: - fail("math.trunc(-3.1) == -3") +if not isclose(1, 1): + fail("isclose(1,1)") +if not not isclose(1.1, 1): + fail("not isclose(1.1,1)") +if not isclose(1.1, 1, rel_tol=0.2): + fail("isclose(1.1,1,rel_tol=.2)") +if not isfinite(factorial(33)): + fail("isfinite(factorial(33))") +if not not isfinite(big): + fail("not isfinite(big)") +if not not isfinite(inf): + fail("not isfinite(inf)") +if not isinf(inf): + fail("isinf(inf)") +if not isinf(big): + fail("isinf(inf)") +if not not isinf(factorial(33)): + fail("not isinf(factorial(33))") +if not isnan(nan): + fail("isnan(nan)") +if not isnan(inf - inf): + fail("isnan(inf - inf)") +if not not isnan(big): + fail("not isnan(inf)") +if not not isnan(1.0): + fail("not isnan(1.0)") +if not ldexp(1, 2) == 4: + fail("ldexp(1,2) == 4") +if not ldexp(1, -2) == 1 / 4: + fail("ldexp(1,-2) == 1/4") +if not modf(1.25) == (0.25, 1.0): + fail("modf(1.25) == (0.25, 1.0)") +if not remainder(5, 2) == 1: + fail("remainder(5,2) == 1") +if not remainder(2.25, 0.5) == 0.25: + fail("remainder(2.25,.5) == .25") +if not trunc(3.1) == 3: + fail("trunc(3.1) == 3") +if not trunc(-3.1) == -3: + fail("trunc(-3.1) == -3") if not round(3.4) == 3: fail("round(3.4) == 3") if not round(3.6) == 4: @@ -108,101 +108,101 @@ def fail(which): # # Power and logarithmic functions # -if not math.exp(0) == 1: - fail("math.exp(0) == 1") -if not math.isclose(math.exp(1), math.e): - fail("isclose(math.exp(1), math.e)") -if not math.isclose(math.exp(1) - 1, math.expm1(1)): - fail("isclose(math.exp(1) - 1, math.expm1(1))") -if not math.isclose(math.log(1), 0): - fail("math.isclose(math.log(1), 0)") -if not math.isclose(math.log(math.e), 1): - fail("math.isclose(math.log(math.e), 1)") -if not math.isclose(math.log1p(1), math.log(2)): - fail("math.isclose(math.log1p(1),math.log(2))") -if not math.isclose(math.log2(5.5), math.log(5.5) / math.log(2)): - fail("math.isclose(math.log2(5.5),math.log(5.5)/math.log(2))") -if not math.isclose(math.log10(5.5), math.log(5.5) / math.log(10)): - fail("math.isclose(math.log10(5.5),math.log(5.5)/math.log(10))") -if not math.isclose(math.pow(2.2, 3.3), math.exp(math.log(2.2) * 3.3)): - fail("math.isclose(pow(2.2,3.3),math.exp(math.log(2.2) * 3.3))") -if not math.sqrt(4) == 2: - fail("math.sqrt(4) == 2") -if not math.isclose(math.sqrt(2) * math.sqrt(2), 2): - fail("isclose(math.sqrt(2) * math.sqrt(2), 2)") +if not exp(0) == 1: + fail("exp(0) == 1") +if not isclose(exp(1), e): + fail("isclose(exp(1), e)") +if not isclose(exp(1) - 1, expm1(1)): + fail("isclose(exp(1) - 1, expm1(1))") +if not isclose(log(1), 0): + fail("isclose(log(1), 0)") +if not isclose(log(e), 1): + fail("isclose(log(e), 1)") +if not isclose(log1p(1), log(2)): + fail("isclose(log1p(1),log(2))") +if not isclose(log2(5.5), log(5.5) / log(2)): + fail("isclose(log2(5.5),log(5.5)/log(2))") +if not isclose(log10(5.5), log(5.5) / log(10)): + fail("isclose(log10(5.5),log(5.5)/log(10))") +if not isclose(pow(2.2, 3.3), exp(log(2.2) * 3.3)): + fail("isclose(pow(2.2,3.3),exp(log(2.2) * 3.3))") +if not sqrt(4) == 2: + fail("sqrt(4) == 2") +if not isclose(sqrt(2) * sqrt(2), 2): + fail("isclose(sqrt(2) * sqrt(2), 2)") # # Trigonometric functions # -if not math.isclose(math.acos(0), math.pi / 2): - fail("math.isclose(math.acos(0), math.pi/2)") -if not math.isclose(math.acos(1), 0): - fail("math.isclose(math.acos(1), 0)") -if not math.isclose(math.asin(0), 0): - fail("math.isclose(math.asin(0), 0)") -if not math.isclose(math.asin(1), math.pi / 2): - fail("math.isclose(math.asin(1), math.pi/2)") -if not math.isclose(math.atan(0), 0): - fail("math.isclose(math.atan(0), 0)") -if not math.isclose(math.atan(1), math.pi / 4): - fail("math.isclose(math.atan(1), math.pi/4)") -if not math.isclose(math.atan2(0, 1), 0): - fail("math.isclose(math.atan2(0,1), 0)") -if not math.isclose(math.atan2(2, 2), math.pi / 4): - fail("math.isclose(math.atan2(2,2), math.pi/4)") +if not isclose(acos(0), pi / 2): + fail("isclose(acos(0), pi/2)") +if not isclose(acos(1), 0): + fail("isclose(acos(1), 0)") +if not isclose(asin(0), 0): + fail("isclose(asin(0), 0)") +if not isclose(asin(1), pi / 2): + fail("isclose(asin(1), pi/2)") +if not isclose(atan(0), 0): + fail("isclose(atan(0), 0)") +if not isclose(atan(1), pi / 4): + fail("isclose(atan(1), pi/4)") +if not isclose(atan2(0, 1), 0): + fail("isclose(atan2(0,1), 0)") +if not isclose(atan2(2, 2), pi / 4): + fail("isclose(atan2(2,2), pi/4)") -if not math.isclose(math.cos(math.pi / 2), 0, abs_tol=1e-6): - fail("math.isclose(math.cos(0), math.pi/2)") -if not math.isclose(math.cos(0), 1): - fail("math.isclose(math.cos(1), 0)") -if not math.isclose(math.hypot(3, 4), 5): - fail("math.isclose(math.hypot(3,4), 5)") -if not math.isclose(math.sin(0), 0): - fail("math.isclose(math.sin(0), 0)") -if not math.isclose(math.sin(math.pi / 2), 1): - fail("math.isclose(math.sin(1), math.pi/2)") -if not math.isclose(math.tan(0), 0): - fail("math.isclose(math.tan(0), 0)") -if not math.isclose(math.tan(math.pi / 4), 1): - fail("math.isclose(math.tan(1), math.pi/4)") +if not isclose(cos(pi / 2), 0, abs_tol=1e-6): + fail("isclose(cos(0), pi/2)") +if not isclose(cos(0), 1): + fail("isclose(cos(1), 0)") +if not isclose(hypot(3, 4), 5): + fail("isclose(hypot(3,4), 5)") +if not isclose(sin(0), 0): + fail("isclose(sin(0), 0)") +if not isclose(sin(pi / 2), 1): + fail("isclose(sin(1), pi/2)") +if not isclose(tan(0), 0): + fail("isclose(tan(0), 0)") +if not isclose(tan(pi / 4), 1): + fail("isclose(tan(1), pi/4)") # # Angular conversion # -if not math.isclose(math.degrees(0), 0): - fail("math.isclose(math.degrees(0),0)") -if not math.isclose(math.degrees(math.pi), 180): - fail("math.isclose(math.degrees(math.pi),180)") -if not math.isclose(math.radians(0), 0): - fail("math.isclose(math.radians(0),0)") -if not math.isclose(math.radians(180), math.pi): - fail("math.isclose(math.radians(180), math.pi)") +if not isclose(degrees(0), 0): + fail("isclose(degrees(0),0)") +if not isclose(degrees(pi), 180): + fail("isclose(degrees(pi),180)") +if not isclose(radians(0), 0): + fail("isclose(radians(0),0)") +if not isclose(radians(180), pi): + fail("isclose(radians(180), pi)") # # Hyperbolic functions # -if not math.isclose(math.sinh(1), (math.e - 1 / math.e) / 2): - fail("math.isclose(math.sinh(1), (math.e - 1/math.e) / 2)") -if not math.isclose(math.cosh(1), (math.e + 1 / math.e) / 2): - fail("math.isclose(math.cosh(1), (math.e + 1/math.e) / 2)") -if not math.isclose(math.tanh(1), math.sinh(1) / math.cosh(1)): - fail("math.isclose(math.tanh(1), math.sinh(1)/math.cosh(1))") -if not math.isclose(math.asinh(math.sinh(1)), 1): - fail("math.isclose(math.asinh(math.sinh(1)), 1)") -if not math.isclose(math.acosh(math.cosh(1)), 1): - fail("math.isclose(math.acosh(math.cosh(1)), 1)") -if not math.isclose(math.atanh(math.tanh(1)), 1): - fail("math.isclose(math.atanh(math.tanh(1)), 1)") +if not isclose(sinh(1), (e - 1 / e) / 2): + fail("isclose(sinh(1), (e - 1/e) / 2)") +if not isclose(cosh(1), (e + 1 / e) / 2): + fail("isclose(cosh(1), (e + 1/e) / 2)") +if not isclose(tanh(1), sinh(1) / cosh(1)): + fail("isclose(tanh(1), sinh(1)/cosh(1))") +if not isclose(asinh(sinh(1)), 1): + fail("isclose(asinh(sinh(1)), 1)") +if not isclose(acosh(cosh(1)), 1): + fail("isclose(acosh(cosh(1)), 1)") +if not isclose(atanh(tanh(1)), 1): + fail("isclose(atanh(tanh(1)), 1)") # # Special functions # -if not math.isclose(math.erf(1), 0.8427007929497149): - fail("math.isclose(math.erf(1), 0.8427007929497149)") -if not math.isclose(math.erfc(1), 1 - math.erf(1)): - fail("math.isclose(math.erfc(1), 1-math.erf(1))") -if not math.isclose(math.gamma(10), math.factorial(9)): - fail("math.isclose(math.gamma(10), math.factorial(9))") -if not math.isclose(math.lgamma(10), math.log(math.factorial(9))): - fail("math.isclose(math.lgamma(10), math.log(math.factorial(9)))") +if not isclose(erf(1), 0.8427007929497149): + fail("isclose(erf(1), 0.8427007929497149)") +if not isclose(erfc(1), 1 - erf(1)): + fail("isclose(erfc(1), 1-erf(1))") +if not isclose(gamma(10), factorial(9)): + fail("isclose(gamma(10), factorial(9))") +if not isclose(lgamma(10), log(factorial(9))): + fail("isclose(lgamma(10), log(factorial(9)))") # # Constants # -if not math.isclose(math.pi * 2, math.tau): - fail("math.isclose(math.pi * 2, math.tau)") +if not isclose(pi * 2, tau): + fail("isclose(pi * 2, tau)") diff --git a/test/pass-op.py b/test/pass-op.py index 8412aca6..14d0a79a 100644 --- a/test/pass-op.py +++ b/test/pass-op.py @@ -15,7 +15,7 @@ # Test arithmetic operations # -import math +from math import * if 2 + 3 != 5: exit(1) @@ -47,9 +47,9 @@ exit(1) if -6.6 // 2.2 != -3.0: exit(1) -if not math.isclose(7.8 % 2.2, 1.2): +if not isclose(7.8 % 2.2, 1.2): exit(1) -if not math.isclose(-7.8 % 2.2, 1.0): +if not isclose(-7.8 % 2.2, 1.0): exit(1) inf = float("inf") diff --git a/test/pass-random.py b/test/pass-random.py index 3a7a414b..ac036bf2 100644 --- a/test/pass-random.py +++ b/test/pass-random.py @@ -13,7 +13,7 @@ # General Public License for more details. # -import random +from random import * def check(got, r): @@ -24,5 +24,7 @@ def check(got, r): for r in (2, 163844, 100000, 8388607): for t in range(100): - v = random.randrange(r) + v = randrange(r) check(v, r) + v = random() + check(v, 1.0) diff --git a/test/pass-trailing-comma.py b/test/pass-trailing-comma.py index 6b1627d9..81ac8f71 100644 --- a/test/pass-trailing-comma.py +++ b/test/pass-trailing-comma.py @@ -12,7 +12,7 @@ # General Public License for more details. # -import math +from math import * # Make sure lists, tuples and parameter lists can have # a trailing comma @@ -37,10 +37,10 @@ 2: "world", } == {1: "hello", 2: "world"} -assert math.gcd(64, 12) == math.gcd( +assert gcd(64, 12) == gcd( 64, 12, ) -assert math.sin( +assert sin( 1, -) == math.sin(1) +) == sin(1)