How to use "if" and "onkeypress" in python turtle? - key-value

'''
from sys import exit
from turtle import *
from math import sqrt, cos, radians
def tria():
seth(180)
fd(radius*sqrt(3))
lt(120)
fd(radius *sqrt(3))
lt(120)
fd(radius * sqrt(3))
seth(120)
circle(radius)
seth(0)
def rect():
seth(0)
fd(radius * sqrt(2))
rt(90)
fd(radius * sqrt(2))
rt(90)
fd(radius * sqrt(2))
rt(90)
fd(radius * sqrt(2))
seth(0)
def penta():
seth(-36)
fd(cos(radians(54))*radius*2)
rt(72)
fd(cos(radians(54))*radius*2)
rt(72)
fd(cos(radians(54))*radius*2)
rt(72)
fd(cos(radians(54))*radius*2)
rt(72)
fd(cos(radians(54))*radius*2)
seth(180)
def hexa():
seth(-30)
fd(radius)
rt(60)
fd(radius)
rt(60)
fd(radius)
rt(60)
fd(radius)
rt(60)
fd(radius)
rt(60)
fd(radius)
seth(180)
radius = float(input("Write the radius "))
screen = getscreen()
shape('turtle')
speed(5)
screen.onkeypress(tria,"3")
screen.onkeypress(reset,"r")
screen.onkeypress(exit,"q")
screen.onkeypress(exit,"q")
if (screen.onkeypress(None,'4')):
rect()
if (screen.onkeypress(None,'o')):
seth(120)
circle(radius)
seth(0)
screen.listen()
screen.mainloop()
'''
Error : jinhojeon#jinui-MacBookAir jinhojeon % python polygons2.py
Write the radius 100
2021-06-30 18:10:06.982 python[10480:325389] TSM AdjustCapsLockLEDForKeyTransitionHandling - _ISSetPhysicalKeyboardCapsLockLED Inhibit
Exception in Tkinter callback
Q : Want to separate two actions, drawing polygons, drawing the outer circle by using onkeypress. Like, pressing '4', drawing rectangular, and then pressing 'o', drawing its outer circle. If it's not working in onkeypress, I hope you would indicate that to me.
Problem : Don't know how to call press-key's str or ascii in python, in Mac os. I don't know either that it is working even if I could "if ~~ == 'o': onkeypress(outer_rect,'o').
As I know, the function onkeypress is meant to do "fun" when the appropriate key is read. I googled it before, but, "msvcrt" doesn't work in Mac. Anybody knows how to get press-key as str or ascii in python with mac or how to separate them well. I'd really appreciate it if you could share with me your knowledge.
If my words are vague, I am really thankful for you to point out which are vague.
My solution is below. I noticed that outer circle of rectangular and the others are different.
How to change the code like if press '4' -> press 'o'(outercircle) -> if not -> get back to the loop -> ? : expect that press same button 'o', but different output
from sys import exit
from turtle import *
from math import sqrt, cos, radians
def tria():
speed(6)
seth(180)
fd(radius*sqrt(3))
lt(120)
fd(radius *sqrt(3))
lt(120)
fd(radius * sqrt(3))
seth(120)
def rect():
speed(6)
seth(0)
fd(radius * sqrt(2))
rt(90)
fd(radius * sqrt(2))
rt(90)
fd(radius * sqrt(2))
rt(90)
fd(radius * sqrt(2))
seth(0)
def penta():
speed(6)
seth(-36)
fd(cos(radians(54))*radius*2)
rt(72)
fd(cos(radians(54))*radius*2)
rt(72)
fd(cos(radians(54))*radius*2)
rt(72)
fd(cos(radians(54))*radius*2)
rt(72)
fd(cos(radians(54))*radius*2)
seth(180)
def hexa():
speed(6)
seth(-30)
fd(radius)
rt(60)
fd(radius)
rt(60)
fd(radius)
rt(60)
fd(radius)
rt(60)
fd(radius)
rt(60)
fd(radius)
seth(180)
def one():
speed(6)
seth(225)
circle(radius)
seth(0)
def outercircle():
speed(6)
circle(radius)
seth(0)
radius = float(input("Write the radius "))
screen = getscreen()
shape('turtle')
speed(6)
screen.listen()
screen.onkeypress(reset,"r")
screen.onkeypress(exit,"q")
screen.onkeypress(tria,"3")
screen.onkeypress(rect,'4')
screen.onkeypress(penta,'5')
screen.onkeypress(hexa,'6')
screen.onkeypress(one,'o')
screen.onkeypress(outercircle,'C')
screen.mainloop()

That was hard to follow. Hope you got the keyboard thing straightened out.
Thought it was an unbound turtle, then I realized you used from turtle import * which, I guess allows you to type in commands without declaring a turtle instance. Then I thought you were saying that it needed screen.listen() but that was typed in above where I expected it. Thought that'd be under your keybindings. Guess it runs fine either way.
So your real question is about how to keep track of the current drawstyle, then make a circle specific for that. Just set a global, and use an if-then.
Edit: Yea, you'd need to do something like the answer here, Python Turtle screen.onkey() to print out keysymbols, and figure out which is required. Then type that into your script. Combos would look like this, Tkinter keybinding for Control-Shift-Tab
#! /usr/bin/env python3
from sys import exit
from turtle import *
from math import sqrt, cos, radians
current = None
def tria():
global current ; current = 'tria'
speed(6)
seth(180)
fd(radius*sqrt(3))
lt(120)
fd(radius *sqrt(3))
lt(120)
fd(radius * sqrt(3))
seth(120)
def rect():
global current ; current = 'rect'
speed(6)
seth(0)
fd(radius * sqrt(2))
rt(90)
fd(radius * sqrt(2))
rt(90)
fd(radius * sqrt(2))
rt(90)
fd(radius * sqrt(2))
seth(0)
def penta():
global current ; current = 'penta'
speed(6)
seth(-36)
fd(cos(radians(54))*radius*2)
rt(72)
fd(cos(radians(54))*radius*2)
rt(72)
fd(cos(radians(54))*radius*2)
rt(72)
fd(cos(radians(54))*radius*2)
rt(72)
fd(cos(radians(54))*radius*2)
seth(180)
def hexa():
global current ; current = 'hexa'
speed(6)
seth(-30)
fd(radius)
rt(60)
fd(radius)
rt(60)
fd(radius)
rt(60)
fd(radius)
rt(60)
fd(radius)
rt(60)
fd(radius)
seth(180)
def one():
global current ; current = 'one'
speed(6)
seth(225)
circle(radius)
seth(0)
def outercircle():
if current == 'tria':
seth(120)
speed(6)
circle(radius)
seth(0)
if current == 'rect':
seth(224)
speed(6)
circle(radius *1.01)
seth(0)
else:
speed(6)
circle(radius)
seth(0)
def test( event ): ## print keysymbols, so you can see which to use
print('test event:', event)
print('test keysym:', event.keysym)
print('test state:', event.state)
print('test Ctrl :', bool(event.state & 4))
print('test Shift:', bool(event.state & 1))
print('test Alt :', bool(event.state & 8))
print('---')
radius = float(input("Write the radius "))
screen = getscreen()
canvas = screen.getcanvas() ## get the raw tkinter canvas
shape('turtle')
speed(6)
screen.listen()
screen.onkeypress(reset,"r")
screen.onkeypress(exit,"q")
screen.onkeypress(tria,"3")
screen.onkeypress(rect,'4')
screen.onkeypress(penta,'5')
screen.onkeypress(hexa,'6')
screen.onkeypress(one,'o')
screen.onkeypress(outercircle,'c')
canvas.bind( '<KeyPress>', test ) ## bind any unbound keys to the test() function
screen.mainloop()

Related

Types of parameters in functions that accept functions

I am trying to learn Scala using SICP, but I am having a hard time with type definitions of functions and got stuck at SICP. Here a generalized expression is build to find the square root of a number (through fixed-point search or Newton's method) where instead of:
def sqrt_damp(x: Double) =
fixed_point(average_damp(y => x / y))(1)
def sqrt_newton(x: Double) =
fixed_point(newton_method(y => square(y) - x))(1)
Based on the functions:
def square(x: Double) = x * x
def average(x: Double, y: Double) = (x + y) / 2
def abs(x: Double) = if (x < 0) -x else x
val tolerance = 0.00001
def fixed_point(f: Double => Double)(first_guess: Double) = {
def close_enough(v1: Double, v2: Double): Boolean = abs(v1 - v2) < tolerance
def attempt(guess: Double): Double = {
val next = f(guess)
if (close_enough(guess, next)) next else attempt(next)
}
attempt(first_guess)
}
def average_damp(f: Double => Double): Double => Double =
x => average(x, f(x))
val dx = 0.00001
def deriv(g: Double => Double): Double => Double =
x => (g(x + dx) - g(x)) / dx
def newton_transform(g: Double => Double): Double => Double =
x => x - g(x) / deriv(g)(x)
def newton_method(g: Double => Double)(guess: Double): Double =
fixed_point(newton_transform(g))(guess)
The square functions can be generalized in the form:
(define (fixed-point-of-transform g transform guess)
(fixed-point (transform g) guess))
Which I attempted to express as follows in Scala:
def fixed_point_of_transform(g: Double => Double, transform: Double => Double)(guess: Double): Double =
fixed_point(transform(g))(guess)
Yet the above does not compile and generates the error
type mismatch; found : Double => Double required: Double
Edit, the following works:
def fixed_point_of_transform(g: Double => Double, transform: (Double => Double) => (Double => Double))(guess: Double): Double =
fixed_point(transform(g))(guess)
So now the previous functions can be defined as:
def sqrt_damp(x: Double) =
fixed_point_of_transform(y => x / y, average_damp)(1)
def sqrt_newton(x: Double) =
fixed_point_of_transform(y => square(y) - x, newton_method)(1)
transform takes a Double and returns a Double. You cannot apply it to g, because g is a a function Double => Double. You can apply it to g(x), where x: Double. I think this is what you want: fixed_point((x: Double) => transform(g(x)))(guess)

when testing for convergence using successive approximation technique, why does this code divide by the guess twice?

While working through the coursera class on scala I ran into the code below (from another question asked here by Sudipta Deb.)
package src.com.sudipta.week2.coursera
import scala.math.abs
import scala.annotation.tailrec
object FixedPoint {
println("Welcome to the Scala worksheet") //> Welcome to the Scala worksheet
val tolerance = 0.0001 //> tolerance : Double = 1.0E-4
def isCloseEnough(x: Double, y: Double): Boolean = {
abs((x - y) / x) / x < tolerance
} //> isCloseEnough: (x: Double, y: Double)Boolean
def fixedPoint(f: Double => Double)(firstGuess: Double): Double = {
#tailrec
def iterate(guess: Double): Double = {
val next = f(guess)
if (isCloseEnough(guess, next)) next
else iterate(next)
}
iterate(firstGuess)
} //> fixedPoint: (f: Double => Double)(firstGuess: Double)Double
def myFixedPoint = fixedPoint(x => 1 + x / 2)(1)//> myFixedPoint: => Double
myFixedPoint //> res0: Double = 1.999755859375
def squareRoot(x: Double) = fixedPoint(y => (y + x / y) / 2)(1)
//> squareRoot: (x: Double)Double
squareRoot(2) //> res1: Double = 1.4142135623746899
def calculateAverate(f: Double => Double)(x: Double) = (x + f(x)) / 2
//> calculateAverate: (f: Double => Double)(x: Double)Double
def myNewSquareRoot(x: Double): Double = fixedPoint(calculateAverate(y => x / y))(1)
//> myNewSquareRoot: (x: Double)Double
myNewSquareRoot(2) //> res2: Double = 1.4142135623746899
}
My puzzlement concerns the isCloseEnough function.
I understand that for guesses which are large numbers, the difference between a guess and
the large value that the function returns could potentially be very big all the time, so we may never converge.
Conversely, if the guess is small, and if what f(x) produces is small then we will likely converge too quickly.
So dividing through by the guess like this:
def isCloseEnough(x: Double, y: Double): Boolean = {
abs((x - y) / x) / x < tolerance
}
makes perfect sense. (here is 'x' is the guess, and y is f_of_x.)
My question is why do why does the solution given divide by the guess TWICE ?
Wouldn't that undo all the benefits of dividing through by the guess the first time ?
As an example... let's say that my current guess and the value actually returned by the
function given my current x is as shown below:
import math.abs
var guess=.0000008f
var f_of_x=.00000079999f
And lets' say my tolerance is
var tolerance=.0001
These numbers look pretty close, and indeed, if i divide through by x ONCE, i see that the result
is less than my tolerance.
( abs(guess - f_of_x) / guess)
res3: Float = 1.2505552E-5
However, if i divide through by x TWICE the result is much greater than my tolerance, which would suggest
we need to keep iterating.. which seems wrong since guess and observed f(x) are so close.
scala> ( abs(guess - f_of_x) / guess) / guess
res11: Float = 15.632331
Thanks in advance for any help you can provide.
You are completely right, it does not make sense. Further, the second division is outside of the absolute value rendering the inequality true for any negative x.
Perhaps someone got confused with testing for quadratic convergence.

Efficient Scala idiomatic way to pick top 85 percent of sorted values?

Given a non-increasing list of numbers, I want to pick top 85% of values in the list. Here is how I am currently doing it.
scala> val a = Array(8.60, 6.85, 4.91, 3.45, 2.74, 2.06, 1.53, 0.35, 0.28, 0.12)
a: Array[Double] = Array(8.6, 6.85, 4.91, 3.45, 2.74, 2.06, 1.53, 0.35, 0.28, 0.12)
scala> val threshold = a.sum * 0.85
threshold: Double = 26.2565
scala> val successiveSums = a.tail.foldLeft(Array[Double](a.head)){ case (x,y) => x ++ Array(y + x.last) }
successiveSums: Array[Double] = Array(8.6, 15.45, 20.36, 23.81, 26.549999999999997, 28.609999999999996, 30.139999999999997, 30.49, 30.77, 30.89)
scala> successiveSums.takeWhile( x => x <= threshold )
res40: Array[Double] = Array(8.6, 15.45, 20.36, 23.81)
scala> val size = successiveSums.takeWhile( x => x <= threshold ).size
size: Int = 4
scala> a.take(size)
res41: Array[Double] = Array(8.6, 6.85, 4.91, 3.45)
I want improve its
performance
code-size
Any suggestions ?
On code size, consider this oneliner,
a.take( a.scanLeft(0.0)(_+_).takeWhile( _ <= a.sum * 0.85 ).size - 1 )
Here scanLeft accumulates additions.
On performance, tagging intermediate values may help not to recompute same operations, namely
val threshold = a.sum * 0.85
val size = a.scanLeft(0.0)(_+_).takeWhile( _ <= threshold ).size - 1
a.take( size )
There is some space for improvement in elm's answer:
1) You don't need to compute sum 2 times.
2) You can avoid creation of additional collection with takeWhile method and use indexWhere instead.
val sums = a.scanLeft(0.0)(_ + _)
a.take(sums.indexWhere(_ > sums.last * 0.85) - 1)
There's no library method that will do exactly what you want. Generally if you want something that performs well, you'd use a tail-recursive method both to find the sum and to find the point where the 85th percentile of the total sum is crossed. Something like
def threshold(
xs: Array[Double], thresh: Double,
i: Int = 0, sum: Double = 0
) {
val next = sum + x(i)
if (next > thresh) xs.take(i)
else threshold(xs, thresh, i+1, next)
}
Well in this case I would make a little use of mutable state. See the code below:
val a = Array(8.60, 6.85, 4.91, 3.45, 2.74, 2.06, 1.53, 0.35, 0.28, 0.12)
def f(a: Array[Double]) = {
val toGet = a.sum * 0.85
var sum = 0.0
a.takeWhile(x => {sum += x; sum <= toGet })
}
println(f(a).deep) //Array(8.6, 6.85, 4.91, 3.45)
In my opinion it's acceptable because function f does not have any side effects

Function parameters evaluation in Scala (functional programming)

please find below a piece of code from Coursera online course (lecture 2.3) on functional programming in Scala.
package week2
import math.abs
object lecture2_3_next {
def fixedPoint(f: Double => Double)(firstGuess: Double): Double = {
val tolerance = 0.0001
def isCloseEnough(x: Double, y: Double): Boolean = abs((x - y) / x) / x < tolerance
def iterate(guess: Double): Double = {
val next = f(guess)
if (isCloseEnough(guess, next)) next
else iterate(next)
}
iterate(firstGuess)
}
def averageDamp(f: Double => Double)(x: Double): Double = (x + f(x)) / 2
def sqrt(x: Double): Double = fixedPoint(averageDamp(y => x / y))(1)
sqrt(2)
}
A few points blocked me while I'm trying to understand this piece of code.
I'd like your help to understanding this code.
The 2 points that annoying me are :
- when you call averageDamp, there are 2 parameters 'x' and 'y' in the function passed (eg. averageDamp(y => x / y)) but you never specify the 'y' parameter in the definition of the averageDamp function (eg. def averageDamp(f: Double => Double)(x: Double): Double = (x + f(x)) / 2). Where and how do the scala compiler evaluate the 'y' parameter.
- second point may be related to the first, I don't know in fact. When I call the averageDamp function, I pass only the function 'f' parameter (eg. y => x / y) but I don't pass the second parameter of the function which is 'x' (eg. (x: Double) second parameter). How the scala compiler is evaluating the 'x' parameter in this case to render the result of the averageDamp call.
I think I missed something about the evaluation or substitution model of scala and functional programming.
Thank's for your help and happy new year !
Hervé
1) You don't pass an x and an y parameter as f, you pass a function. The function is defined as y => x / y, where y is just a placeholder for the argument of this function, while x is a fixed value in this context, as it is given as argument for the sqrt method (in the example x is 2). Instead of the fancy lambda-syntax, you could write as well
def sqrt(x: Double): Double = fixedPoint(averageDamp(
new Function1[Double,Double] {
def apply(y:Double):Double = x / y
}
))(1)
Nothing magic about this, just an abbreviation.
2) When you have a second parameter list, and don't use it when calling the method, you do something called "currying", and you get back a partial function. Consider
def add(x:Int)(y:Int) = x + y
If you call it as add(2)(3), everything is "normal", and you get back 5. But if you call add(2), the second argument is still "missing", and you get back a function expecting this missing second argument, so you have something like y => 2 + y
The x is not a parameter of the (anonymous) function, it is a parameter of the function sqrt. For the anonymous function it is a bound closure.
To make it more obvious, let's rewrite it and use a named instead of an anonymous function:
def sqrt(x: Double): Double = fixedPoint(averageDamp(y => x / y))(1)
will can be rewritten as this:
def sqrt(x: Double): Double = {
def funcForSqrt(y: Double) : Double = x / y // Note that x is not a parameter of funcForSqrt
// Use the function fundForSqrt as a parameter of averageDamp
fixedPoint(averageDamp(funcForSqrt))(1)
}

What is a good way of reusing function result in Scala

Let me clarify my question by example. This is a standard exponentiation algorithm written with tail recursion in Scala:
def power(x: Double, y: Int): Double = {
def sqr(z: Double): Double = z * z
def loop(xx: Double, yy: Int): Double =
if (yy == 0) xx
else if (yy % 2 == 0) sqr(loop(xx, yy / 2))
else loop(xx * x, yy - 1)
loop(1.0, y)
}
Here sqr method is used to produce the square of loop's result. It doesn't look like a good idea - to define a special function for such a simple operation. But, we can't write just loop(..) * loop(..) instead, since it doubles the calculations.
We also can write it with val and without sqr function:
def power(x: Double, y: Int): Double = {
def loop(xx: Double, yy: Int): Double =
if (yy == 0) xx
else if (yy % 2 == 0) { val s = loop(xx, yy / 2); s * s }
else loop(xx * x, yy - 1)
loop(1.0, y)
}
I can't say that it looks better then variant with sqr, since it uses state variable. The first case is more functional the second way is more Scala-friendly.
Anyway, my question is how to deal with cases when you need to postprocess function's result? Maybe Scala has some other ways to achieve that?
You are using the law that
x^(2n) = x^n * x^n
But this is the same as
x^n * x^n = (x*x)^n
Hence, to avoid squaring after recursion, the value in the case where y is even should be like displayed below in the code listing.
This way, tail-calling will be possible. Here is the full code (not knowing Scala, I hope I get the syntax right by analogy):
def power(x: Double, y: Int): Double = {
def loop(xx: Double, acc: Double, yy: Int): Double =
if (yy == 0) acc
else if (yy % 2 == 0) loop(xx*xx, acc, yy / 2)
else loop(xx, acc * xx, yy - 1)
loop(x, 1.0, y)
}
Here it is in a Haskell like language:
power2 x n = loop x 1 n
where
loop x a 0 = a
loop x a n = if odd n then loop x (a*x) (n-1)
else loop (x*x) a (n `quot` 2)
You could use a "forward pipe". I've got this idea from here: Cache an intermediate variable in an one-liner.
So
val s = loop(xx, yy / 2); s * s
could be rewritten to
loop(xx, yy / 2) |> (s => s * s)
using an implicit conversion like this
implicit class PipedObject[A](value: A) {
def |>[B](f: A => B): B = f(value)
}
As Petr has pointed out: Using an implicit value class
object PipedObjectContainer {
implicit class PipedObject[A](val value: A) extends AnyVal {
def |>[B](f: A => B): B = f(value)
}
}
to be used like this
import PipedObjectContainer._
loop(xx, yy / 2) |> (s => s * s)
is better, since it does not need a temporary instance (requires Scala >= 2.10).
In my comment I pointed out that your implementations can't be tail call optimised, because in the case where yy % 2 == 0, there is a recursive call that is not in tail position. So, for a large input, this can overflow the stack.
A general solution to this is to trampoline your function, replacing recursive calls with data which can be mapped over with "post-processing" such as sqr. The result is then computed by an interpreter, which steps through the return values, storing them on the heap rather than the stack.
The Scalaz library provides an implementation of the data types and interpreter.
import scalaz.Free.Trampoline, scalaz.Trampoline._
def sqr(z: Double): Double = z * z
def power(x: Double, y: Int): Double = {
def loop(xx: Double, yy: Int): Trampoline[Double] =
if (yy == 0)
done(xx)
else if (yy % 2 == 0)
suspend(loop(xx, yy / 2)) map sqr
else
suspend(loop(xx * x, yy - 1))
loop(1.0, y).run
}
There is a considerable performance hit for doing this, though. In this particular case, I would use Igno's solution to avoid the need to call sqr at all. But, the technique described above can be useful when you can't make such optimisations to your algorithm.
In this particular case
No need for utility functions
No need for obtuse piping / implicits
Only need a single standalone recursive call at end - to always give tail recursion
def power(x: Double, y: Int): Double =
if (y == 0) x
else {
val evenPower = y % 2 == 0
power(if (evenPower) x * x else x, if (evenPower) y / 2 else y - 1)
}