pastebin
| #1 paste tool since 2002
create new paste
tools
api
archive
real-time
faq
pastebin
Follow @pastebin
create new paste
trending pastes
sign up
login
my settings
my profile
My Pastes
Public Pastes
Untitled
0 sec ago
Untitled
4 sec ago
Untitled
7 sec ago
Untitled
14 sec ago
Untitled
16 sec ago
Untitled
21 sec ago
Open Source Cocoa/Cocoa...
22 sec ago
Untitled
23 sec ago
Layout Width
Share Pastebin
Dick Moores
By: a guest | Aug 11th, 2008 | Syntax:
Python
| Size: 31.22 KB | Hits: 24 | Expires: Never
Download
|
Raw
|
Embed
|
Report abuse
This paste has a previous version,
view the difference
.
#!/usr/bin/env python
#coding=utf-8
# random_rectanglesV20_web.py
"""
ATTENTION: The turtle module imported here is the turtle.py that is part of Python2.6 beta2.
See http://article.gmane.org/gmane.comp.python.tutor/49765 for more information.
"""
from
turtle26
import
*
from
random
import
randint, choice, randrange
from
math
import
ceil
import
time
COLOR_NAMES_NO_GREYS =
[
'yellow'
,
'darkseagreen'
,
'aquamarine4'
,
'aquamarine1'
,
'aquamarine3'
,
'aquamarine2'
,
'brown'
,
'indianred4'
,
'skyblue'
,
'rosybrown4'
,
'cornsilk'
,
'lightpink'
,
'indianred2'
,
'chocolate1'
,
'lemonchiffon3'
,
'lemonchiffon2'
,
'lemonchiffon1'
,
'bisque'
,
'violetred1'
,
'chocolate2'
,
'lemonchiffon4'
,
'chocolate3'
,
'chocolate4'
,
'lightgoldenrodyellow'
,
'lavender'
,
'chartreuse3'
,
'chartreuse2'
,
'chartreuse1'
,
'darkslateblue'
,
'chartreuse4'
,
'lightskyblue'
,
'blue'
,
'rosybrown2'
,
'maroon4'
,
'maroon3'
,
'maroon2'
,
'maroon1'
,
'gold3'
,
'gold2'
,
'gold1'
,
'gold4'
,
'wheat4'
,
'rosybrown1'
,
'skyblue4'
,
'skyblue1'
,
'skyblue3'
,
'skyblue2'
,
'indianred1'
,
'floralwhite'
,
'turquoise1'
,
'firebrick3'
,
'firebrick2'
,
'firebrick1'
,
'steelblue2'
,
'steelblue4'
,
'firebrick4'
,
'lightskyblue1'
,
'greenyellow'
,
'lightseagreen'
,
'sienna'
,
'tomato'
,
'indianred3'
,
'royalblue'
,
'gainsboro'
,
'peru'
,
'red3'
,
'red2'
,
'red1'
,
'springgreen3'
,
'violetred4'
,
'lightyellow'
,
'lemonchiffon'
,
'chocolate'
,
'antiquewhite'
,
'moccasin'
,
'deeppink'
,
'springgreen1'
,
'springgreen2'
,
'dodgerblue'
,
'springgreen4'
,
'seashell2'
,
'seashell3'
,
'magenta'
,
'seashell1'
,
'tan'
,
'seashell4'
,
'pink'
,
'palevioletred'
,
'powderblue'
,
'mediumblue'
,
'honeydew1'
,
'mediumpurple1'
,
'mediumpurple2'
,
'mediumpurple3'
,
'mediumpurple4'
,
'honeydew2'
,
'khaki4'
,
'honeydew3'
,
'paleturquoise3'
,
'khaki1'
,
'cadetblue'
,
'khaki3'
,
'salmon1'
,
'honeydew4'
,
'salmon3'
,
'salmon2'
,
'salmon4'
,
'linen'
,
'green'
,
'blueviolet'
,
'brown2'
,
'brown3'
,
'brown1'
,
'brown4'
,
'orange4'
,
'orange1'
,
'orange3'
,
'orange2'
,
'cyan'
,
'yellow4'
,
'yellow3'
,
'yellow2'
,
'yellow1'
,
'orange'
,
'lightsteelblue'
,
'goldenrod'
,
'cyan4'
,
'darkviolet'
,
'darkmagenta'
,
'navy'
,
'ghostwhite'
,
'plum'
,
'khaki2'
,
'darkkhaki'
,
'violetred'
,
'red'
,
'peachpuff'
,
'lightslateblue'
,
'lightskyblue4'
,
'aliceblue'
,
'lightskyblue2'
,
'lightskyblue3'
,
'blue1'
,
'blue3'
,
'blue2'
,
'blue4'
,
'purple3'
,
'lightcyan'
,
'darksalmon'
,
'mediumspringgreen'
,
'tomato4'
,
'tomato1'
,
'tomato3'
,
'tomato2'
,
'mistyrose'
,
'blanchedalmond'
,
'orangered'
,
'navajowhite'
,
'pink3'
,
'pink2'
,
'burlywood'
,
'pink4'
,
'mistyrose1'
,
'white'
,
'darkolivegreen4'
,
'lightyellow3'
,
'paleturquoise4'
,
'darkolivegreen1'
,
'seagreen4'
,
'seagreen3'
,
'seagreen2'
,
'seagreen1'
,
'paleturquoise2'
,
'limegreen'
,
'mistyrose3'
,
'palegreen1'
,
'palegreen3'
,
'palegreen2'
,
'palegreen4'
,
'mistyrose2'
,
'burlywood1'
,
'turquoise2'
,
'burlywood3'
,
'burlywood2'
,
'burlywood4'
,
'rosybrown'
,
'turquoise4'
,
'whitesmoke'
,
'lightblue'
,
'snow'
,
'orangered3'
,
'orangered2'
,
'orangered1'
,
'orangered4'
,
'mistyrose4'
,
'thistle2'
,
'thistle1'
,
'salmon'
,
'thistle4'
,
'oldlace'
,
'darkseagreen4'
,
'darkseagreen3'
,
'darkseagreen2'
,
'darkseagreen1'
,
'darkblue'
,
'lightpink1'
,
'gold'
,
'lightsalmon4'
,
'lightsalmon2'
,
'lightsalmon3'
,
'lightsalmon1'
,
'green4'
,
'green1'
,
'green3'
,
'green2'
,
'steelblue1'
,
'papayawhip'
,
'black'
,
'orchid4'
,
'orchid1'
,
'orchid2'
,
'orchid3'
,
'purple2'
,
'antiquewhite3'
,
'antiquewhite2'
,
'antiquewhite1'
,
'antiquewhite4'
,
'bisque4'
,
'bisque1'
,
'bisque2'
,
'bisque3'
,
'darkturquoise'
,
'turquoise3'
,
'plum4'
,
'plum3'
,
'plum2'
,
'plum1'
,
'lightblue3'
,
'thistle'
,
'violet'
,
'darkorchid4'
,
'darkorchid1'
,
'darkorchid2'
,
'darkorchid3'
,
'rosybrown3'
,
'honeydew'
,
'cornflowerblue'
,
'palevioletred4'
,
'palevioletred1'
,
'palevioletred2'
,
'palevioletred3'
,
'mediumpurple'
,
'lightblue2'
,
'darkcyan'
,
'lightblue1'
,
'lightblue4'
,
'darkred'
,
'lavenderblush1'
,
'lavenderblush3'
,
'lavenderblush2'
,
'lavenderblush4'
,
'mediumturquoise'
,
'lightyellow1'
,
'lightyellow4'
,
'lightgoldenrod'
,
'navajowhite4'
,
'hotpink'
,
'olivedrab'
,
'navajowhite1'
,
'navajowhite2'
,
'magenta2'
,
'magenta1'
,
'palegreen'
,
'seashell'
,
'aquamarine'
,
'tan4'
,
'tan3'
,
'tan2'
,
'tan1'
,
'paleturquoise1'
,
'lawngreen'
,
'slateblue'
,
'darkorange4'
,
'mintcream'
,
'darkorange1'
,
'darkorange3'
,
'darkorange2'
,
'saddlebrown'
,
'goldenrod4'
,
'goldenrod1'
,
'goldenrod2'
,
'goldenrod3'
,
'darkgoldenrod'
,
'lightcyan1'
,
'sandybrown'
,
'lightcyan3'
,
'ivory3'
,
'ivory2'
,
'ivory1'
,
'lightcyan2'
,
'mediumseagreen'
,
'ivory4'
,
'darkorange'
,
'violetred2'
,
'steelblue3'
,
'lightcyan4'
,
'sienna1'
,
'palegoldenrod'
,
'sienna3'
,
'violetred3'
,
'sienna2'
,
'pink1'
,
'lightyellow2'
,
'darkolivegreen3'
,
'darkolivegreen2'
,
'lavenderblush'
,
'azure1'
,
'azure3'
,
'azure2'
,
'azure4'
,
'firebrick'
,
'indianred'
,
'sienna4'
,
'darkolivegreen'
,
'mediumorchid4'
,
'lightsteelblue1'
,
'lightsteelblue2'
,
'lightsteelblue3'
,
'lightsteelblue4'
,
'darkgoldenrod4'
,
'mediumorchid1'
,
'magenta4'
,
'magenta3'
,
'darkgoldenrod1'
,
'darkgoldenrod2'
,
'darkgoldenrod3'
,
'chartreuse'
,
'mediumslateblue'
,
'mediumorchid3'
,
'springgreen'
,
'mediumorchid2'
,
'lightsalmon'
,
'cyan2'
,
'turquoise'
,
'cyan3'
,
'olivedrab4'
,
'royalblue4'
,
'cyan1'
,
'purple4'
,
'navajowhite3'
,
'darkgreen'
,
'peachpuff4'
,
'purple1'
,
'slateblue3'
,
'peachpuff1'
,
'peachpuff2'
,
'olivedrab1'
,
'olivedrab2'
,
'olivedrab3'
,
'slateblue4'
,
'slateblue2'
,
'lightgoldenrod4'
,
'yellowgreen'
,
'lightgoldenrod1'
,
'slateblue1'
,
'lightgoldenrod3'
,
'lightgoldenrod2'
,
'peachpuff3'
,
'orchid'
,
'purple'
,
'darkorchid'
,
'royalblue1'
,
'thistle3'
,
'wheat1'
,
'wheat3'
,
'wheat2'
,
'coral3'
,
'coral2'
,
'coral1'
,
'deepskyblue4'
,
'deepskyblue3'
,
'deepskyblue2'
,
'deepskyblue1'
,
'coral4'
,
'khaki'
,
'wheat'
,
'deepskyblue'
,
'coral'
,
'beige'
,
'azure'
,
'dodgerblue1'
,
'dodgerblue2'
,
'dodgerblue3'
,
'dodgerblue4'
,
'mediumvioletred'
,
'snow4'
,
'snow2'
,
'snow3'
,
'snow1'
,
'lightcoral'
,
'ivory'
,
'lightpink2'
,
'lightpink3'
,
'forestgreen'
,
'lightpink4'
,
'midnightblue'
,
'mediumorchid'
,
'cornsilk4'
,
'cornsilk2'
,
'cornsilk3'
,
'cornsilk1'
,
'royalblue3'
,
'royalblue2'
,
'maroon'
,
'seagreen'
,
'red4'
,
'cadetblue4'
,
'cadetblue3'
,
'cadetblue2'
,
'cadetblue1'
,
'paleturquoise'
,
'deeppink3'
,
'deeppink2'
,
'deeppink1'
,
'deeppink4'
,
'hotpink3'
,
'hotpink2'
,
'hotpink1'
,
'lightgreen'
,
'hotpink4'
,
'navyblue'
,
'mediumaquamarine'
,
'steelblue'
]
BACKGROUND_COLORS =
[
'aquamarine4'
,
'blue'
,
'blueviolet'
,
'cadetblue1'
,
'cadetblue3'
,
'chartreuse2'
,
'chartreuse4'
,
'coral'
,
'cyan'
,
'cyan3'
,
'darkgoldenrod1'
,
'darkgreen'
,
'darkolivegreen1'
,
'darkorange2'
,
'darksalmon'
,
'darkseagreen'
,
'darkseagreen2'
,
'darkviolet'
,
'deeppink'
,
'firebrick'
,
'forestgreen'
,
'gold'
,
'green'
,
'hotpink'
,
'lightcoral'
,
'lightcyan'
,
'lightgoldenrod1'
,
'lightgoldenrodyellow'
,
'lightsalmon2'
,
'lightskyblue'
,
'lightslateblue'
,
'lightsteelblue1'
,
'lightsteelblue3'
,
'magenta'
,
'magenta1'
,
'magenta2'
,
'magenta3'
,
'mediumorchid1'
,
'mediumvioletred'
,
'navy'
,
'orangered'
,
'orangered4'
,
'orchid1'
,
'palegreen'
,
'paleturquoise1'
,
'palevioletred1'
,
'papayawhip'
,
'pink'
,
'plum1'
,
'purple'
,
'purple4'
,
'red4'
,
'skyblue'
,
'skyblue2'
,
'skyblue3'
,
'springgreen'
,
'springgreen4'
,
'turquoise1'
,
'turquoise3'
,
'violetred'
,
'yellow'
]
DUPE_COLORS_NO_GREYS =
[
[
'tomato'
,
'tomato1'
]
,
[
'blue4'
,
'darkblue'
]
,
[
'cyan4'
,
'darkcyan'
]
,
[
'aquamarine3'
,
'mediumaquamarine'
]
,
[
'yellow'
,
'yellow1'
]
,
[
'darkmagenta'
,
'magenta4'
]
,
[
'red1'
,
'red'
]
,
[
'honeydew1'
,
'honeydew'
]
,
[
'lightyellow'
,
'lightyellow1'
]
,
[
'darkred'
,
'red4'
]
,
[
'chocolate4'
,
'saddlebrown'
]
,
[
'springgreen1'
,
'springgreen'
]
,
[
'lavenderblush1'
,
'lavenderblush'
]
,
[
'blue'
,
'blue1'
]
,
[
'ivory1'
,
'ivory'
]
,
[
'deeppink'
,
'deeppink1'
]
,
[
'lemonchiffon1'
,
'lemonchiffon'
]
,
[
'lightsalmon1'
,
'lightsalmon'
]
,
[
'dodgerblue'
,
'dodgerblue1'
]
,
[
'seashell1'
,
'seashell'
]
,
[
'peachpuff'
,
'peachpuff1'
]
,
[
'palegreen2'
,
'lightgreen'
]
,
[
'navy'
,
'navyblue'
]
,
[
'deepskyblue1'
,
'deepskyblue'
]
,
[
'orangered'
,
'orangered1'
]
,
[
'olivedrab3'
,
'yellowgreen'
]
,
[
'magenta'
,
'magenta1'
]
,
[
'mistyrose'
,
'mistyrose1'
]
,
[
'mediumblue'
,
'blue3'
]
,
[
'seagreen4'
,
'seagreen'
]
,
[
'azure1'
,
'azure'
]
,
[
'cornsilk'
,
'cornsilk1'
]
,
[
'navajowhite'
,
'navajowhite1'
]
,
[
'cyan'
,
'cyan1'
]
,
[
'peru'
,
'tan3'
]
,
[
'snow'
,
'snow1'
]
,
[
'lightcyan'
,
'lightcyan1'
]
,
[
'green'
,
'green1'
]
,
[
'orange1'
,
'orange'
]
,
[
'aquamarine1'
,
'aquamarine'
]
,
[
'gold1'
,
'gold'
]
,
[
'bisque'
,
'bisque1'
]
,
[
'chartreuse1'
,
'chartreuse'
]
]
def
floatToNearestInt
(
x
)
:
"""
convert float x to the nearest integer n
e.g., 3.4 --> 3; 45.5 --> 46; -2.1 --> -2; -0.8 --> -1
"""
return
int
(
round
(
x
)
)
def
intCommas
(
n
)
:
"""
inserts commas into integers. E.g. -12345678 -> -12,345,789
"""
s =
str
(
n
)
sign =
''
if
s
[
0
]
==
'-'
:
sign =
'-'
s = s
[
1:
]
slen =
len
(
s
)
a =
''
for
index
in
range
(
slen
)
:
if
index
>
0
and
index
%
3
== slen
%
3
:
a = a +
','
a = a + s
[
index
]
return
sign + a
def
int_to_ordinal
(
n
)
:
"""
Takes an int and returns the string ordinal integer, with commas as appropriate
plus the appropriate suffix; e.g. 1237 -> 1,237th
"""
n =
str
(
n
)
if
n
[
-1
]
in
"0456789"
:
suff =
"th"
elif
n
[
-2:
]
in
[
'11'
,
'12'
,
'13'
]
:
suff =
"th"
elif
n
[
-
1
]
==
"1"
:
suff =
"st"
elif
n
[
-
1
]
==
"2"
:
suff =
"nd"
else
:
suff =
"rd"
return
intCommas
(
n
)
+ suff
def
hmsToText
(
seconds
)
:
"""
Convert seconds to hours, minutes, seconds and return result
"""
seconds = floatToNearestInt
(
seconds
)
hours, minutes = 0, 0
if
seconds
>
= 60
and
seconds
<
3600:
minutes, seconds =
divmod
(
seconds, 60
)
elif
seconds
>
= 3600:
hours, seconds =
divmod
(
seconds, 3600
)
minutes, seconds =
divmod
(
seconds,
60
)
hp, mp, sp =
"s"
,
"s"
,
"s"
## add "s" to make "hour", "minute", "second" plural
if
hours ==
1
:
hp =
""
## no "s" on "hour"
if
minutes ==
1
:
mp =
""
if
seconds
>
= 1
and
seconds
<
2
:
sp =
""
if
hours == 0
and
minutes ==
0
:
result =
"%d second%s"
%
(
seconds, sp
)
elif
hours == 0:
if
seconds ==
0
:
result =
"%d minute%s exactly"
%
(
minutes, mp
)
else
:
result =
"%d minute%s, %d second%s"
%
(
minutes, mp, seconds, sp
)
elif
minutes == 0:
if
seconds ==
0
:
result =
"%d hour%s exactly"
%
(
hours, hp
)
else
:
result =
"%d hour%s, %d second%s"
%
(
hours, hp, seconds, sp
)
else
:
result =
"%d hour%s, %d minute%s, %d second%s"
%
(
hours, hp, minutes, mp, seconds, sp
)
return
result
def
defaults
(
)
:
global
default_min
global
default_max
global
default_begin_range
global
default_end_range
global
default_pause
global
default_speed
global
default_delay
default_min, default_max = 5, 20
default_begin_range, default_end_range = default_min, default_max
default_pause = 1
default_speed = 4
default_delay = 15
def
print_defaults_before_acceptance
(
)
:
print
"The defaults are:"
print
"default min, default max: %d, %d"
%
(
default_min, default_max
)
print
"default pause:"
, default_pause
print
"default speed:"
, default_speed
print
"default delay:"
, default_delay
print
"default number of cycles:"
, default_max_num_cycles
def
initialize_variables
(
)
:
global
used_colors
global
multiple_of_num_avail_colors
global
num_cycles
global
total_rects
global
black_or_colored_list
global
unused_background_colors
mode
(
"standard"
)
setup
(
width=.735, height=
1.0
, startx=-
1
, starty=
0
)
unused_background_colors = BACKGROUND_COLORS
[
:
]
num_cycles =
0
used_colors =
[
]
total_rects =
0
multiple_of_num_avail_colors =
0
black_or_colored_list =
[
10
,
10
,
10
,
0
]
## so that first sum of list cannot be 0 or 4
title_string =
"Random Rectangles with %d Colors"
%
num_avail_colors
title
(
title_string
)
def
getMinAndMaxIntegersFromUser
(
default_min, default_max
)
:
print
"Enter 2 integers > 1 for min and max, with max >= min"
print
"Put a comma between the numbers. E.g., '8, 20'"
print
"Press Enter to set default of %d, %d"
%
(
default_min, default_max
)
while
True
:
ans =
raw_input
(
"min, max: "
)
if
ans ==
''
:
print
"The default min, max have been set to %d, %d"
%
(
default_min, default_max
)
return
(
default_min, default_max
)
try
:
min
,
max
= ans.
split
(
','
)
except
ValueError
:
print
"
\n
Please start over and enter correct min and max."
print
"Enter 2 integers > 1 for min and max, with max >= min"
print
"Press Enter to set default of 5, 20
\n
"
continue
try
:
min
=
int
(
min
)
except
ValueError
:
print
"
\n
Please start over and enter correct min and max."
print
"Enter 2 INTEGERS > 1 for min and max, with max >= min"
print
"Press Enter to set default of 5, 20
\n
"
continue
try
:
max
=
int
(
max
)
except
ValueError
:
print
"
\n
Please start over and enter correct min and max."
print
"Enter 2 INTEGERS > 1 for min and max, with max >= min"
print
"Press Enter to set default of 5, 20"
continue
if
min
>
max
or
min
<
2:
print
"
\n
Please start over and enter correct min and max."
print
"min must be <= max and min must be > 1"
print
"Enter 2 integers > 1 for min and max, with max >= min"
print
"Press Enter to set default of 5, 20"
continue
else
:
break
return
(
min
,
max
)
def
get_pause_from_user
(
default_pause
)
:
print
"""
You can set the pause between the filling of a rectangle and the start of the
next. Enter any non-negative number for the number of seconds to pause.
E.g., 0, 2, or 2.4
To set the default pause of %s, just press Enter
"""
%
singular_to_plural
(
default_pause,
'second'
)
while
True
:
ans =
raw_input
(
"Enter pause in seconds: "
)
if
ans ==
''
:
print
"a pause of %s has been set"
%
singular_to_plural
(
default_pause,
'second'
)
return
default_pause
try
:
pause =
float
(
ans
)
except
ValueError
:
print
"
\n
Please start over and enter a number of seconds >= 0."
print
"Just press Enter to set default pause of %s"
%
singular_to_plural
(
default_pause,
'second'
)
continue
if
pause
<
0:
print
"
\n
Please start over and enter a NONNEGATIVE number."
print
"Press Enter to set default of 5, 20"
continue
print
"a pause of %.3g second%s has been set"
%
(
float
(
ans
)
, s_or_none
(
float
(
ans
)
)
)
return
float
(
ans
)
def
get_speed_and_delay_from_user
(
default_speed, default_delay
)
:
print
"""
Enter the speed and delay you want in the drawing of rectangles as
two integers separated by a comma; e.g., 2, 20.
"""
print
"Enter 2 integers >= 0 for speed and delay"
print
"Put a comma between the numbers. E.g., '2, 20'"
print
"Just press Enter to set defaults of %d, %d"
%
(
default_speed, default_delay
)
while
True
:
ans =
raw_input
(
"speed, delay: "
)
if
ans ==
''
:
print
"The defaults of speed %d, delay %d have been set"
%
(
default_speed, default_delay
)
return
(
default_speed, default_delay
)
try
:
spd, dly = ans.
split
(
','
)
except
ValueError
:
print
"
\n
Please start over and enter correct speed and delay."
print
"Enter 2 integers >= 0 for speed and delay"
print
"Just press Enter to set defaults of %d, %d"
%
(
default_speed, default_delay
)
continue
try
:
spd =
int
(
spd
)
except
ValueError
:
print
"
\n
Please start over and enter correct min and max."
print
"Enter 2 INTEGERS > 1 for min and max, with max >= min"
print
"Just press Enter to set defaults of %d, %d"
%
(
default_speed, default_delay
)
continue
try
:
dly =
int
(
dly
)
except
ValueError
:
print
"
\n
Please start over and enter correct min and max."
print
"Enter 2 INTEGERS > 1 for min and max, with max >= min"
print
"Just press Enter to set defaults of %d, %d"
%
(
default_speed, default_delay
)
continue
if
spd
<
0
or
dly
<
0:
print
"
\n
Please start over and enter correct min and max."
print
"Both speed and delay must be NONNEGATIVE, i.e., >= 0"
print
"Enter 2 integers >= 0 for speed and delay"
print
"Just press Enter to set defaults of %d, %d"
%
(
default_speed, default_delay
)
continue
else
:
break
print
"speed has been set to %d; delay to %d"
%
(
spd, dly
)
return
(
spd, dly
)
def
calculate_num_avail_colors
(
)
:
num_avail_colors =
len
(
COLOR_NAMES_NO_GREYS
)
-
len
(
DUPE_COLORS_NO_GREYS
)
## dupe colors are all in pairs
return
num_avail_colors
def
calculate_num_cycles_to_show_all_colors
(
begin_range, end_range
)
:
avg =
(
begin_range + end_range
)
*
1.0/2
num_cycles_to_show_all_colors =
int
(
ceil
(
num_avail_colors/avg
)
)
print
"num_cycles_to_show_all_colors:"
, num_cycles_to_show_all_colors
return
num_cycles_to_show_all_colors
def
get_max_num_cycles_from_user
(
)
:
num_cycles_to_show_all_colors = calculate_num_cycles_to_show_all_colors
(
begin_range, end_range
)
longstr =
"""
\n
Enter the number of cycles; %d cycles will show approximately %d rectangles using all %d colors"""
print
longstr
%
(
num_cycles_to_show_all_colors, num_avail_colors, num_avail_colors
)
print
"Press Enter to set the default of %d"
%
num_cycles_to_show_all_colors
while
True
:
ans =
raw_input
(
"Number of cycles: "
)
if
ans ==
''
:
ans = num_cycles_to_show_all_colors
print
"The number of cycle%s has been set to %d."
%
(
s_or_none
(
num_cycles_to_show_all_colors
)
, num_cycles_to_show_all_colors
)
try
:
ans =
int
(
ans
)
except
ValueError
:
print
"
\n
Please start over and enter a number of cycles >= 1."
print
"Just press Enter to set default number of cycles of %s"
%
num_cycles_to_show_all_colors
continue
if
ans
<
1:
print
"
\n
Please start over and enter a positive integer."
print
"Press Enter to set default of %d"
%
num_cycles_to_show_all_colors
continue
else
:
ans =
int
(
ans
)
return
ans
def
adjust_for_monitor_resolution
(
)
:
wd = window_width
(
)
width_adjustment = wd
*
1.0/999
ht = window_height
(
)
height_adjustment = ht
*
1.0/702
return
width_adjustment, height_adjustment
def
get_next_rect_params
(
)
:
color_name = get_next_rect_color
(
)
x = randrange
(
15, 451, 2
)
y = randrange
(
15, 251, 2
)
width_adjustment, height_adjustment = adjust_for_monitor_resolution
(
)
x = x
*
width_adjustment
y = y
*
height_adjustment
pen_size = get_pen_size
(
x, y
)
flag = randint
(
1, 8
)
return
pen_size, color_name, x, y, flag
def
get_pen_size
(
x, y
)
:
"""
Return a pen size proportional to the area of the rectangle
"""
pen_size =
(
x
*
y
)
//11320 + 1
return
pen_size
def
get_next_rect_color
(
)
:
global
used_colors
global
multiple_of_num_avail_colors
while
True
:
color_name = choice
(
COLOR_NAMES_NO_GREYS
)
## when have exhausted colors
if
len
(
used_colors
)
>
= num_avail_colors:
used_colors =
[
]
multiple_of_num_avail_colors += num_avail_colors
color_names = dupe_color_names
(
color_name
)
if
isinstance
(
color_names,
tuple
)
:
name0 = color_names
[
0
]
name1 = color_names
[
1
]
if
name0
not
in
used_colors
and
name1
not
in
used_colors:
used_colors.
append
(
name0
)
used_colors.
append
(
name1
)
return
name0
for
col_name
in
color_names:
if
col_name
not
in
used_colors:
used_colors.
append
(
col_name
)
return
col_name
else
:
col_name = color_names
## only one name in this case
if
col_name
not
in
used_colors:
used_colors.
append
(
col_name
)
return
col_name
def
dupe_color_names
(
color_name
)
:
"""
Check if color_name is a dupe.
Return a tuple of it and its fellow dupes.
If not a dupe, return color_name.
(a dupe color_name is a color name that has the same color value as at
least one other color name in COLOR_NAMES_NO_GREYS)
"""
for
x
in
DUPE_COLORS_NO_GREYS:
if
color_name
in
x:
return
x
[
0
]
, x
[
1
]
return
color_name
def
print_color_names
(
color_names
)
:
if
isinstance
(
color_names,
tuple
)
:
for
col_name
in
color_names:
print
col_name,
print
else
:
print
color_names
# a single color
def
draw_rect
(
)
:
speed
(
spd
)
pensize
(
pen_size
)
color
(
color_name
)
color_names = dupe_color_names
(
color_name
)
print_color_names
(
color_names
)
begin_fill
(
)
## NE, CW (northeast, clockwise)
if
flag ==
1
:
up
(
)
goto
(
x, y
)
down
(
)
## up to here tracer(False) is in effect from the last time draw_rect()
## was called (see bottom line)
tracer
(
True
, dly
)
goto
(
x, -y
)
goto
(
-x, -y
)
goto
(
-x, y
)
goto
(
x, y
)
## NE, CCW (northeast, counterclockwise)
elif
flag == 2:
up
(
)
goto
(
x, y
)
down
(
)
tracer
(
True
, dly
)
goto
(
-x, y
)
goto
(
-x, -y
)
goto
(
x, -y
)
goto
(
x, y
)
## SE, CW
elif
flag == 3:
up
(
)
goto
(
x, -y
)
down
(
)
tracer
(
True
, dly
)
goto
(
-x, -y
)
goto
(
-x, y
)
goto
(
x, y
)
goto
(
x, -y
)
## SE, CCW
elif
flag == 4:
up
(
)
goto
(
x, -y
)
down
(
)
tracer
(
True
, dly
)
goto
(
x, y
)
goto
(
-x, y
)
goto
(
-x, -y
)
goto
(
x, -y
)
## SW, CW
elif
flag == 5:
up
(
)
goto
(
-x, -y
)
down
(
)
tracer
(
True
, dly
)
goto
(
-x, y
)
goto
(
x, y
)
goto
(
x, -y
)
goto
(
-x, -y
)
## SW, CCW
elif
flag == 6:
up
(
)
goto
(
-x, -y
)
down
(
)
tracer
(
True
, dly
)
goto
(
x, -y
)
goto
(
x, y
)
goto
(
-x, y
)
goto
(
-x, -y
)
## NW, CW
elif
flag == 7:
up
(
)
goto
(
-x, y
)
down
(
)
tracer
(
True
, dly
)
goto
(
x, y
)
goto
(
x, -y
)
goto
(
-x, -y
)
goto
(
-x, y
)
## NW, CCW
elif
flag == 8:
up
(
)
goto
(
-x, y
)
down
(
)
tracer
(
True
, dly
)
goto
(
-x, -y
)
goto
(
x, -y
)
goto
(
x, y
)
goto
(
-x, y
)
end_fill
(
)
tracer
(
False
)
def
get_black_or_colored
(
)
:
"""
For the next background color, return 0 if it will
be "black"; 1 if it will be colored, i.e., a color
to be chosen from the list of unused background colors.
This function serves the purpose of preventing "black"
from being used more than once in a row, and a non-black
color from being used more than four times in a row.
"""
global
black_or_colored_list
if
sum
(
black_or_colored_list
[
-1:
]
)
== 0:
black_or_colored = 1
elif
sum
(
black_or_colored_list
[
-4:
]
)
== 4:
black_or_colored = 0
else
:
black_or_colored = choice
(
(
0, 1
)
)
black_or_colored_list.
append
(
black_or_colored
)
return
black_or_colored
def
get_next_background_color
(
)
:
"""
Return random hue from an updating list of unused background colors.
"""
global
BACKGROUND_COLORS
global
unused_background_colors
while
True
:
if
len
(
unused_background_colors
)
>
0:
hue = choice
(
unused_background_colors
)
unused_background_colors.
remove
(
hue
)
return
hue
else
:
unused_background_colors = BACKGROUND_COLORS
[
:
]
def
get_background
(
)
:
black_or_colored = get_black_or_colored
(
)
# 0 for black; 1 for colored
clearscreen
(
)
if
black_or_colored ==
0
:
hue =
'black'
else
:
hue = get_next_background_color
(
)
if
num_cycles
<
max_num_cycles:
print
print
'%s is the new background color'
%
hue
return
hue
def
print_so_far_report
(
)
:
"""
Print at end of each cycle except for the last, when
print_program_end_report() will by called.
"""
if
0
<
num_used_colors_to_report
<
num_avail_colors:
astr =
"%d rects drawn, %d colors used so far, of %d colors"
print
astr
%
(
total_rects, total_rects, num_avail_colors
)
elif
total_rects
>
= num_avail_colors:
longstr =
"%d rects drawn so far; all %d colors have been used"
print
longstr
%
(
total_rects, num_avail_colors
)
def
s_or_none
(
n
)
:
"""
Returns 's' to pluralize regular nouns.
n can be an int, long, float, or str
"""
e = .0000000000001
if
isinstance
(
n,
(
int
,
long
)
)
:
if
n == 1:
return
''
elif
isinstance
(
n,
float
)
:
if
n - e
<
1
<
n + e:
print
n
return
''
elif
isinstance
(
n,
str
)
:
if
'.'
not
in
n:
if
n ==
'1'
:
return
''
else
:
n =
float
(
n
)
if
n - e
<
1
<
n + e:
return
''
return
's'
def
singular_to_plural
(
n, noun
)
:
"""
Depending on n, return plural of regular noun in phrase such as
"3 goats", "1 goat", "1.0 goat", "1.3 goats", "0 goats"
n may be an int, long, float, or str
"""
e = .0000000000001
if
isinstance
(
n,
(
int
,
long
)
)
:
if
n == 1:
return
str
(
n
)
+
' '
+ noun
elif
isinstance
(
n,
float
)
:
if
n - e
<
1
<
n + e:
return
str
(
n
)
+
' '
+ noun
elif
isinstance
(
n,
str
)
:
if
'.'
not
in
n:
if
n ==
'1'
:
return
n +
' '
+ noun
else
:
n =
float
(
n
)
if
n - e
<
1
<
n + e:
return
str
(
n
)
+
' '
+ noun
return
str
(
n
)
+
' '
+ noun +
's'
def
print_program_end_report
(
)
:
if
0
<
total_rects
<
num_avail_colors:
astr =
"%d colors of %d were used for %d rectangles"
print
astr
%
(
total_rects, num_avail_colors,
total_rects
)
elif
num_avail_colors
<
= total_rects:
print
"all %d colors were used for %d rectangles"
%
(
num_avail_colors,
total_rects
)
def
beepN
(
times,interval
)
:
"""Calls beep() n times at interval of x seconds."""
import
time
for
k
in
range
(
times-1
)
:
beep
(
)
time
.
sleep
(
interval
)
beep
(
)
def
beep
(
)
:
"""
A very short Beep. Useful at end of program to remind user of the .exe
to check final report in the 10 seconds before the console window closes
"""
import
winsound
pitch = 500
length = 30
winsound
.
Beep
(
pitch,length
)
print
\
"""
This program creates sets (cycles) of concentric randomly sized and
randomly colored rectangles against background colors randomly chosen from a
special list of %d colors. After the initial background of white, a black
background will be chosen at least once in five times, but never twice in a row.
No rectangle color will repeat until all %d colors have been chosen.
"""
%
(
len
(
BACKGROUND_COLORS
)
,
len
(
COLOR_NAMES_NO_GREYS
)
)
## defaults() has all the defaults except max_num_cycles, which depends on
## num_cycles_to_show_all_colors, which in turn depends on num_avail_colors,
## which depends on end_range, begin_range, which depend on the defaults
## default_min, default_max .
defaults
(
)
num_avail_colors = calculate_num_avail_colors
(
)
default_max_num_cycles = calculate_num_cycles_to_show_all_colors
(
default_begin_range, default_end_range
)
print_defaults_before_acceptance
(
)
print
"""
You can accept all defaults by pressing Enter at the prompt
Enter 'n' to decline to accept all defaults
"""
ans =
raw_input
(
"Your choice: "
)
if
ans ==
''
:
print
"All defaults have been set."
accept_all_defaults =
True
begin_range, end_range = default_min, default_max
pause = default_pause
max_num_cycles = default_max_num_cycles
spd, dly = default_speed, default_delay
speed
(
spd
)
else
:
accept_all_defaults =
False
if
not
accept_all_defaults:
print
\
"""You can configure the number of rectangles per cycle by setting the minimum
and maximum numbers. This will be the range from which the actual number will
be chosen by a random process for each cycle. E.g., enter 10, 15 for a range of
10 to 15."""
print
"For the default of %d, %d just press Enter."
%
(
default_min, default_max
)
begin_range, end_range = getMinAndMaxIntegersFromUser
(
default_min, default_max
)
print
pause = get_pause_from_user
(
default_pause
)
if
not
accept_all_defaults:
max_num_cycles = get_max_num_cycles_from_user
(
)
print
"""
The program will stop after %s.
To stop it sooner, click in the console window to
make it the active window; then press Ctrl+Q.
"""
%
singular_to_plural
(
max_num_cycles,
'cycle'
)
if
not
accept_all_defaults:
spd, dly = get_speed_and_delay_from_user
(
default_speed, default_delay
)
## spd is used in line below; dly is used in tracer() in function draw_rect()
speed
(
spd
)
initialize_variables
(
)
print
"
\n
The program has started
\n
"
timeStart =
time
.
time
(
)
for
x
in
range
(
1, max_num_cycles+1
)
:
if
x ==
1
:
bgcolor
(
"white"
)
print
"white is the background color"
## do setup() again (only once again), in order to set the window
## height so that the bottom will be just at the top of task bar.
setup
(
width=.735, height=
(
window_height
(
)
- 40
)
, startx=-1, starty=0
)
final_rect_num = randint
(
begin_range, end_range
)
count = 0
num_used_colors =
len
(
used_colors
)
num_used_colors_to_report = num_used_colors + multiple_of_num_avail_colors
print_so_far_report
(
)
print
"%d rects in new %s cycle are coming up"
%
(
final_rect_num,
int_to_ordinal
(
num_cycles+1
)
)
for
x
in
range
(
0, final_rect_num
)
:
pen_size, color_name, x, y, flag = get_next_rect_params
(
)
hideturtle
(
)
draw_rect
(
)
total_rects += 1
count += 1
if
count == final_rect_num:
num_cycles += 1
print
"That ends the %s cycle of %d cycles"
%
(
int_to_ordinal
(
num_cycles
)
, max_num_cycles
)
time
.
sleep
(
1.5
)
if
num_cycles
<
max_num_cycles:
hue = get_background
(
)
bgcolor
(
hue
)
else
:
beepN
(
3, 0.2
)
print
"The program will close in 10 seconds"
else
:
time
.
sleep
(
pause
)
## report at end of program
print
print_program_end_report
(
)
timeEnd =
time
.
time
(
)
print
"Time was %s"
%
(
hmsToText
(
timeEnd - timeStart
)
)
time
.
sleep
(
8.5
)
create new paste
|
create new version of this paste
RAW Paste Data
#!/usr/bin/env python #coding=utf-8 # random_rectanglesV20_web.py """ ATTENTION: The turtle module imported here is the turtle.py that is part of Python2.6 beta2. See http://article.gmane.org/gmane.comp.python.tutor/49765 for more information. """ from turtle26 import * from random import randint, choice, randrange from math import ceil import time COLOR_NAMES_NO_GREYS = ['yellow', 'darkseagreen', 'aquamarine4', 'aquamarine1', 'aquamarine3', 'aquamarine2', 'brown', 'indianred4', 'skyblue', 'rosybrown4', 'cornsilk', 'lightpink', 'indianred2', 'chocolate1', 'lemonchiffon3', 'lemonchiffon2', 'lemonchiffon1', 'bisque', 'violetred1', 'chocolate2', 'lemonchiffon4', 'chocolate3', 'chocolate4', 'lightgoldenrodyellow', 'lavender', 'chartreuse3', 'chartreuse2', 'chartreuse1', 'darkslateblue', 'chartreuse4', 'lightskyblue', 'blue', 'rosybrown2', 'maroon4', 'maroon3', 'maroon2', 'maroon1', 'gold3', 'gold2', 'gold1', 'gold4', 'wheat4', 'rosybrown1', 'skyblue4', 'skyblue1', 'skyblue3', 'skyblue2', 'indianred1', 'floralwhite', 'turquoise1', 'firebrick3', 'firebrick2', 'firebrick1', 'steelblue2', 'steelblue4', 'firebrick4', 'lightskyblue1', 'greenyellow', 'lightseagreen', 'sienna', 'tomato', 'indianred3', 'royalblue', 'gainsboro', 'peru', 'red3', 'red2', 'red1', 'springgreen3', 'violetred4', 'lightyellow', 'lemonchiffon', 'chocolate', 'antiquewhite', 'moccasin', 'deeppink', 'springgreen1', 'springgreen2', 'dodgerblue', 'springgreen4', 'seashell2', 'seashell3', 'magenta', 'seashell1', 'tan', 'seashell4', 'pink', 'palevioletred', 'powderblue', 'mediumblue', 'honeydew1', 'mediumpurple1', 'mediumpurple2', 'mediumpurple3', 'mediumpurple4', 'honeydew2', 'khaki4', 'honeydew3', 'paleturquoise3', 'khaki1', 'cadetblue', 'khaki3', 'salmon1', 'honeydew4', 'salmon3', 'salmon2', 'salmon4', 'linen', 'green', 'blueviolet', 'brown2', 'brown3', 'brown1', 'brown4', 'orange4', 'orange1', 'orange3', 'orange2', 'cyan', 'yellow4', 'yellow3', 'yellow2', 'yellow1', 'orange', 'lightsteelblue', 'goldenrod', 'cyan4', 'darkviolet', 'darkmagenta', 'navy', 'ghostwhite', 'plum', 'khaki2', 'darkkhaki', 'violetred', 'red', 'peachpuff', 'lightslateblue', 'lightskyblue4', 'aliceblue', 'lightskyblue2', 'lightskyblue3', 'blue1', 'blue3', 'blue2', 'blue4', 'purple3', 'lightcyan', 'darksalmon', 'mediumspringgreen', 'tomato4', 'tomato1', 'tomato3', 'tomato2', 'mistyrose', 'blanchedalmond', 'orangered', 'navajowhite', 'pink3', 'pink2', 'burlywood', 'pink4', 'mistyrose1', 'white', 'darkolivegreen4', 'lightyellow3', 'paleturquoise4', 'darkolivegreen1', 'seagreen4', 'seagreen3', 'seagreen2', 'seagreen1', 'paleturquoise2', 'limegreen', 'mistyrose3', 'palegreen1', 'palegreen3', 'palegreen2', 'palegreen4', 'mistyrose2', 'burlywood1', 'turquoise2', 'burlywood3', 'burlywood2', 'burlywood4', 'rosybrown', 'turquoise4', 'whitesmoke', 'lightblue', 'snow', 'orangered3', 'orangered2', 'orangered1', 'orangered4', 'mistyrose4', 'thistle2', 'thistle1', 'salmon', 'thistle4', 'oldlace', 'darkseagreen4', 'darkseagreen3', 'darkseagreen2', 'darkseagreen1', 'darkblue', 'lightpink1', 'gold', 'lightsalmon4', 'lightsalmon2', 'lightsalmon3', 'lightsalmon1', 'green4', 'green1', 'green3', 'green2', 'steelblue1', 'papayawhip', 'black', 'orchid4', 'orchid1', 'orchid2', 'orchid3', 'purple2', 'antiquewhite3', 'antiquewhite2', 'antiquewhite1', 'antiquewhite4', 'bisque4', 'bisque1', 'bisque2', 'bisque3', 'darkturquoise', 'turquoise3', 'plum4', 'plum3', 'plum2', 'plum1', 'lightblue3', 'thistle', 'violet', 'darkorchid4', 'darkorchid1', 'darkorchid2', 'darkorchid3', 'rosybrown3', 'honeydew', 'cornflowerblue', 'palevioletred4', 'palevioletred1', 'palevioletred2', 'palevioletred3', 'mediumpurple', 'lightblue2', 'darkcyan', 'lightblue1', 'lightblue4', 'darkred', 'lavenderblush1', 'lavenderblush3', 'lavenderblush2', 'lavenderblush4', 'mediumturquoise', 'lightyellow1', 'lightyellow4', 'lightgoldenrod', 'navajowhite4', 'hotpink', 'olivedrab', 'navajowhite1', 'navajowhite2', 'magenta2', 'magenta1', 'palegreen', 'seashell', 'aquamarine', 'tan4', 'tan3', 'tan2', 'tan1', 'paleturquoise1', 'lawngreen', 'slateblue', 'darkorange4', 'mintcream', 'darkorange1', 'darkorange3', 'darkorange2', 'saddlebrown', 'goldenrod4', 'goldenrod1', 'goldenrod2', 'goldenrod3', 'darkgoldenrod', 'lightcyan1', 'sandybrown', 'lightcyan3', 'ivory3', 'ivory2', 'ivory1', 'lightcyan2', 'mediumseagreen', 'ivory4', 'darkorange', 'violetred2', 'steelblue3', 'lightcyan4', 'sienna1', 'palegoldenrod', 'sienna3', 'violetred3', 'sienna2', 'pink1', 'lightyellow2', 'darkolivegreen3', 'darkolivegreen2', 'lavenderblush', 'azure1', 'azure3', 'azure2', 'azure4', 'firebrick', 'indianred', 'sienna4', 'darkolivegreen', 'mediumorchid4', 'lightsteelblue1', 'lightsteelblue2', 'lightsteelblue3', 'lightsteelblue4', 'darkgoldenrod4', 'mediumorchid1', 'magenta4', 'magenta3', 'darkgoldenrod1', 'darkgoldenrod2', 'darkgoldenrod3', 'chartreuse', 'mediumslateblue', 'mediumorchid3', 'springgreen', 'mediumorchid2', 'lightsalmon', 'cyan2', 'turquoise', 'cyan3', 'olivedrab4', 'royalblue4', 'cyan1', 'purple4', 'navajowhite3', 'darkgreen', 'peachpuff4', 'purple1', 'slateblue3', 'peachpuff1', 'peachpuff2', 'olivedrab1', 'olivedrab2', 'olivedrab3', 'slateblue4', 'slateblue2', 'lightgoldenrod4', 'yellowgreen', 'lightgoldenrod1', 'slateblue1', 'lightgoldenrod3', 'lightgoldenrod2', 'peachpuff3', 'orchid', 'purple', 'darkorchid', 'royalblue1', 'thistle3', 'wheat1', 'wheat3', 'wheat2', 'coral3', 'coral2', 'coral1', 'deepskyblue4', 'deepskyblue3', 'deepskyblue2', 'deepskyblue1', 'coral4', 'khaki', 'wheat', 'deepskyblue', 'coral', 'beige', 'azure', 'dodgerblue1', 'dodgerblue2', 'dodgerblue3', 'dodgerblue4', 'mediumvioletred', 'snow4', 'snow2', 'snow3', 'snow1', 'lightcoral', 'ivory', 'lightpink2', 'lightpink3', 'forestgreen', 'lightpink4', 'midnightblue', 'mediumorchid', 'cornsilk4', 'cornsilk2', 'cornsilk3', 'cornsilk1', 'royalblue3', 'royalblue2', 'maroon', 'seagreen', 'red4', 'cadetblue4', 'cadetblue3', 'cadetblue2', 'cadetblue1', 'paleturquoise', 'deeppink3', 'deeppink2', 'deeppink1', 'deeppink4', 'hotpink3', 'hotpink2', 'hotpink1', 'lightgreen', 'hotpink4', 'navyblue', 'mediumaquamarine', 'steelblue'] BACKGROUND_COLORS = ['aquamarine4', 'blue', 'blueviolet', 'cadetblue1', 'cadetblue3', 'chartreuse2', 'chartreuse4', 'coral', 'cyan', 'cyan3', 'darkgoldenrod1', 'darkgreen', 'darkolivegreen1', 'darkorange2', 'darksalmon', 'darkseagreen', 'darkseagreen2', 'darkviolet', 'deeppink', 'firebrick', 'forestgreen', 'gold', 'green', 'hotpink', 'lightcoral', 'lightcyan', 'lightgoldenrod1', 'lightgoldenrodyellow', 'lightsalmon2', 'lightskyblue', 'lightslateblue', 'lightsteelblue1', 'lightsteelblue3', 'magenta', 'magenta1', 'magenta2', 'magenta3', 'mediumorchid1', 'mediumvioletred', 'navy', 'orangered', 'orangered4', 'orchid1', 'palegreen', 'paleturquoise1', 'palevioletred1', 'papayawhip', 'pink', 'plum1', 'purple','purple4', 'red4', 'skyblue', 'skyblue2', 'skyblue3', 'springgreen', 'springgreen4', 'turquoise1', 'turquoise3', 'violetred', 'yellow'] DUPE_COLORS_NO_GREYS = [['tomato', 'tomato1'], ['blue4', 'darkblue'], ['cyan4', 'darkcyan'], ['aquamarine3', 'mediumaquamarine'], ['yellow', 'yellow1'], ['darkmagenta', 'magenta4'], ['red1', 'red'], ['honeydew1', 'honeydew'], ['lightyellow', 'lightyellow1'], ['darkred', 'red4'], ['chocolate4', 'saddlebrown'], ['springgreen1', 'springgreen'], ['lavenderblush1', 'lavenderblush'], ['blue', 'blue1'], ['ivory1', 'ivory'], ['deeppink', 'deeppink1'], ['lemonchiffon1', 'lemonchiffon'], ['lightsalmon1', 'lightsalmon'], ['dodgerblue', 'dodgerblue1'], ['seashell1', 'seashell'], ['peachpuff', 'peachpuff1'], ['palegreen2', 'lightgreen'], ['navy', 'navyblue'], ['deepskyblue1', 'deepskyblue'], ['orangered', 'orangered1'], ['olivedrab3', 'yellowgreen'], ['magenta', 'magenta1'], ['mistyrose', 'mistyrose1'], ['mediumblue', 'blue3'], ['seagreen4', 'seagreen'], ['azure1', 'azure'], ['cornsilk', 'cornsilk1'], ['navajowhite', 'navajowhite1'], ['cyan', 'cyan1'], ['peru', 'tan3'], ['snow', 'snow1'], ['lightcyan', 'lightcyan1'], ['green', 'green1'], ['orange1', 'orange'], ['aquamarine1', 'aquamarine'], ['gold1', 'gold'], ['bisque', 'bisque1'], ['chartreuse1', 'chartreuse']] def floatToNearestInt(x): """ convert float x to the nearest integer n e.g., 3.4 --> 3; 45.5 --> 46; -2.1 --> -2; -0.8 --> -1 """ return int(round(x)) def intCommas(n): """ inserts commas into integers. E.g. -12345678 -> -12,345,789 """ s = str(n) sign = '' if s[0] == '-': sign = '-' s = s[1:] slen = len(s) a = '' for index in range(slen): if index > 0 and index % 3 == slen % 3: a = a + ',' a = a + s[index] return sign + a def int_to_ordinal(n): """ Takes an int and returns the string ordinal integer, with commas as appropriate plus the appropriate suffix; e.g. 1237 -> 1,237th """ n = str(n) if n[-1] in "0456789": suff = "th" elif n[-2:] in ['11', '12', '13']: suff = "th" elif n[-1] == "1": suff = "st" elif n [-1] == "2": suff = "nd" else: suff = "rd" return intCommas(n) + suff def hmsToText(seconds): """ Convert seconds to hours, minutes, seconds and return result """ seconds = floatToNearestInt(seconds) hours, minutes = 0, 0 if seconds >= 60 and seconds < 3600: minutes, seconds = divmod(seconds, 60) elif seconds >= 3600: hours, seconds = divmod(seconds, 3600) minutes, seconds = divmod(seconds, 60) hp, mp, sp = "s", "s", "s" ## add "s" to make "hour", "minute", "second" plural if hours == 1: hp = "" ## no "s" on "hour" if minutes == 1: mp = "" if seconds >= 1 and seconds < 2: sp = "" if hours == 0 and minutes == 0: result = "%d second%s" % (seconds, sp) elif hours == 0: if seconds == 0: result = "%d minute%s exactly" % (minutes, mp) else: result = "%d minute%s, %d second%s" % (minutes, mp, seconds, sp) elif minutes == 0: if seconds == 0: result = "%d hour%s exactly" % (hours, hp) else: result = "%d hour%s, %d second%s" % (hours, hp, seconds, sp) else: result = "%d hour%s, %d minute%s, %d second%s" % (hours, hp, minutes, mp, seconds, sp) return result def defaults(): global default_min global default_max global default_begin_range global default_end_range global default_pause global default_speed global default_delay default_min, default_max = 5, 20 default_begin_range, default_end_range = default_min, default_max default_pause = 1 default_speed = 4 default_delay = 15 def print_defaults_before_acceptance(): print "The defaults are:" print "default min, default max: %d, %d" % (default_min, default_max) print "default pause:", default_pause print "default speed:", default_speed print "default delay:", default_delay print "default number of cycles:", default_max_num_cycles def initialize_variables(): global used_colors global multiple_of_num_avail_colors global num_cycles global total_rects global black_or_colored_list global unused_background_colors mode("standard") setup(width=.735, height= 1.0, startx=-1, starty=0) unused_background_colors = BACKGROUND_COLORS[:] num_cycles = 0 used_colors = [] total_rects = 0 multiple_of_num_avail_colors = 0 black_or_colored_list = [10, 10, 10, 0] ## so that first sum of list cannot be 0 or 4 title_string = "Random Rectangles with %d Colors" % num_avail_colors title(title_string) def getMinAndMaxIntegersFromUser(default_min, default_max): print "Enter 2 integers > 1 for min and max, with max >= min" print "Put a comma between the numbers. E.g., '8, 20'" print "Press Enter to set default of %d, %d" % (default_min, default_max) while True: ans = raw_input("min, max: ") if ans == '': print "The default min, max have been set to %d, %d" % (default_min, default_max) return (default_min, default_max) try: min, max = ans.split(',') except ValueError: print "\nPlease start over and enter correct min and max." print "Enter 2 integers > 1 for min and max, with max >= min" print "Press Enter to set default of 5, 20\n" continue try: min = int(min) except ValueError: print "\nPlease start over and enter correct min and max." print "Enter 2 INTEGERS > 1 for min and max, with max >= min" print "Press Enter to set default of 5, 20\n" continue try: max = int(max) except ValueError: print "\nPlease start over and enter correct min and max." print "Enter 2 INTEGERS > 1 for min and max, with max >= min" print "Press Enter to set default of 5, 20" continue if min > max or min < 2: print "\nPlease start over and enter correct min and max." print "min must be <= max and min must be > 1" print "Enter 2 integers > 1 for min and max, with max >= min" print "Press Enter to set default of 5, 20" continue else: break return (min, max) def get_pause_from_user(default_pause): print """ You can set the pause between the filling of a rectangle and the start of the next. Enter any non-negative number for the number of seconds to pause. E.g., 0, 2, or 2.4 To set the default pause of %s, just press Enter """ % singular_to_plural(default_pause, 'second') while True: ans = raw_input("Enter pause in seconds: ") if ans == '': print "a pause of %s has been set" % singular_to_plural(default_pause, 'second') return default_pause try: pause = float(ans) except ValueError: print "\nPlease start over and enter a number of seconds >= 0." print "Just press Enter to set default pause of %s" % singular_to_plural(default_pause, 'second') continue if pause < 0: print "\nPlease start over and enter a NONNEGATIVE number." print "Press Enter to set default of 5, 20" continue print "a pause of %.3g second%s has been set" % (float(ans), s_or_none(float(ans))) return float(ans) def get_speed_and_delay_from_user(default_speed, default_delay): print """ Enter the speed and delay you want in the drawing of rectangles as two integers separated by a comma; e.g., 2, 20. """ print "Enter 2 integers >= 0 for speed and delay" print "Put a comma between the numbers. E.g., '2, 20'" print "Just press Enter to set defaults of %d, %d" % (default_speed, default_delay) while True: ans = raw_input("speed, delay: ") if ans == '': print "The defaults of speed %d, delay %d have been set" % (default_speed, default_delay) return (default_speed, default_delay) try: spd, dly = ans.split(',') except ValueError: print "\nPlease start over and enter correct speed and delay." print "Enter 2 integers >= 0 for speed and delay" print "Just press Enter to set defaults of %d, %d" % (default_speed, default_delay) continue try: spd = int(spd) except ValueError: print "\nPlease start over and enter correct min and max." print "Enter 2 INTEGERS > 1 for min and max, with max >= min" print "Just press Enter to set defaults of %d, %d" % (default_speed, default_delay) continue try: dly = int(dly) except ValueError: print "\nPlease start over and enter correct min and max." print "Enter 2 INTEGERS > 1 for min and max, with max >= min" print "Just press Enter to set defaults of %d, %d" % (default_speed, default_delay) continue if spd < 0 or dly < 0: print "\nPlease start over and enter correct min and max." print "Both speed and delay must be NONNEGATIVE, i.e., >= 0" print "Enter 2 integers >= 0 for speed and delay" print "Just press Enter to set defaults of %d, %d" % (default_speed, default_delay) continue else: break print "speed has been set to %d; delay to %d" % (spd, dly) return (spd, dly) def calculate_num_avail_colors(): num_avail_colors = len(COLOR_NAMES_NO_GREYS) - len(DUPE_COLORS_NO_GREYS) ## dupe colors are all in pairs return num_avail_colors def calculate_num_cycles_to_show_all_colors(begin_range, end_range): avg = (begin_range + end_range)*1.0/2 num_cycles_to_show_all_colors = int(ceil(num_avail_colors/avg)) print "num_cycles_to_show_all_colors:", num_cycles_to_show_all_colors return num_cycles_to_show_all_colors def get_max_num_cycles_from_user(): num_cycles_to_show_all_colors = calculate_num_cycles_to_show_all_colors(begin_range, end_range) longstr = """\nEnter the number of cycles; %d cycles will show approximately %d rectangles using all %d colors""" print longstr % (num_cycles_to_show_all_colors, num_avail_colors, num_avail_colors) print "Press Enter to set the default of %d" % num_cycles_to_show_all_colors while True: ans = raw_input("Number of cycles: ") if ans == '': ans = num_cycles_to_show_all_colors print "The number of cycle%s has been set to %d." % (s_or_none(num_cycles_to_show_all_colors), num_cycles_to_show_all_colors) try: ans = int(ans) except ValueError: print "\nPlease start over and enter a number of cycles >= 1." print "Just press Enter to set default number of cycles of %s" % num_cycles_to_show_all_colors continue if ans < 1: print "\nPlease start over and enter a positive integer." print "Press Enter to set default of %d" % num_cycles_to_show_all_colors continue else: ans = int(ans) return ans def adjust_for_monitor_resolution(): wd = window_width() width_adjustment = wd*1.0/999 ht = window_height() height_adjustment = ht*1.0/702 return width_adjustment, height_adjustment def get_next_rect_params(): color_name = get_next_rect_color() x = randrange(15, 451, 2) y = randrange(15, 251, 2) width_adjustment, height_adjustment = adjust_for_monitor_resolution() x = x * width_adjustment y = y * height_adjustment pen_size = get_pen_size(x, y) flag = randint(1, 8) return pen_size, color_name, x, y, flag def get_pen_size(x, y): """ Return a pen size proportional to the area of the rectangle """ pen_size = (x * y)//11320 + 1 return pen_size def get_next_rect_color(): global used_colors global multiple_of_num_avail_colors while True: color_name = choice(COLOR_NAMES_NO_GREYS) ## when have exhausted colors if len(used_colors) >= num_avail_colors: used_colors = [] multiple_of_num_avail_colors += num_avail_colors color_names = dupe_color_names(color_name) if isinstance(color_names, tuple): name0 = color_names[0] name1 = color_names[1] if name0 not in used_colors and name1 not in used_colors: used_colors.append(name0) used_colors.append(name1) return name0 for col_name in color_names: if col_name not in used_colors: used_colors.append(col_name) return col_name else: col_name = color_names ## only one name in this case if col_name not in used_colors: used_colors.append(col_name) return col_name def dupe_color_names(color_name): """ Check if color_name is a dupe. Return a tuple of it and its fellow dupes. If not a dupe, return color_name. (a dupe color_name is a color name that has the same color value as at least one other color name in COLOR_NAMES_NO_GREYS) """ for x in DUPE_COLORS_NO_GREYS: if color_name in x: return x[0], x[1] return color_name def print_color_names(color_names): if isinstance(color_names, tuple): for col_name in color_names: print col_name, print else: print color_names # a single color def draw_rect(): speed(spd) pensize(pen_size) color(color_name) color_names = dupe_color_names(color_name) print_color_names(color_names) begin_fill() ## NE, CW (northeast, clockwise) if flag == 1: up() goto(x, y) down() ## up to here tracer(False) is in effect from the last time draw_rect() ## was called (see bottom line) tracer(True, dly) goto(x, -y) goto(-x, -y) goto(-x, y) goto(x, y) ## NE, CCW (northeast, counterclockwise) elif flag == 2: up() goto(x, y) down() tracer(True, dly) goto(-x, y) goto(-x, -y) goto(x, -y) goto(x, y) ## SE, CW elif flag == 3: up() goto(x, -y) down() tracer(True, dly) goto(-x, -y) goto(-x, y) goto(x, y) goto(x, -y) ## SE, CCW elif flag == 4: up() goto(x, -y) down() tracer(True, dly) goto(x, y) goto(-x, y) goto(-x, -y) goto(x, -y) ## SW, CW elif flag == 5: up() goto(-x, -y) down() tracer(True, dly) goto(-x, y) goto(x, y) goto(x, -y) goto(-x, -y) ## SW, CCW elif flag == 6: up() goto(-x, -y) down() tracer(True, dly) goto(x, -y) goto(x, y) goto(-x, y) goto(-x, -y) ## NW, CW elif flag == 7: up() goto(-x, y) down() tracer(True, dly) goto(x, y) goto(x, -y) goto(-x, -y) goto(-x, y) ## NW, CCW elif flag == 8: up() goto(-x, y) down() tracer(True, dly) goto(-x, -y) goto(x, -y) goto(x, y) goto(-x, y) end_fill() tracer(False) def get_black_or_colored(): """ For the next background color, return 0 if it will be "black"; 1 if it will be colored, i.e., a color to be chosen from the list of unused background colors. This function serves the purpose of preventing "black" from being used more than once in a row, and a non-black color from being used more than four times in a row. """ global black_or_colored_list if sum(black_or_colored_list[-1:]) == 0: black_or_colored = 1 elif sum(black_or_colored_list[-4:]) == 4: black_or_colored = 0 else: black_or_colored = choice((0, 1)) black_or_colored_list.append(black_or_colored) return black_or_colored def get_next_background_color(): """ Return random hue from an updating list of unused background colors. """ global BACKGROUND_COLORS global unused_background_colors while True: if len(unused_background_colors) > 0: hue = choice(unused_background_colors) unused_background_colors.remove(hue) return hue else: unused_background_colors = BACKGROUND_COLORS[:] def get_background(): black_or_colored = get_black_or_colored() # 0 for black; 1 for colored clearscreen() if black_or_colored == 0: hue = 'black' else: hue = get_next_background_color() if num_cycles < max_num_cycles: print print '%s is the new background color' % hue return hue def print_so_far_report(): """ Print at end of each cycle except for the last, when print_program_end_report() will by called. """ if 0 < num_used_colors_to_report < num_avail_colors: astr = "%d rects drawn, %d colors used so far, of %d colors" print astr % (total_rects, total_rects, num_avail_colors) elif total_rects >= num_avail_colors: longstr = "%d rects drawn so far; all %d colors have been used" print longstr % (total_rects, num_avail_colors) def s_or_none(n): """ Returns 's' to pluralize regular nouns. n can be an int, long, float, or str """ e = .0000000000001 if isinstance(n, (int, long)): if n == 1: return '' elif isinstance(n, float): if n - e < 1 < n + e: print n return '' elif isinstance(n, str): if '.' not in n: if n == '1': return '' else: n = float(n) if n - e < 1 < n + e: return '' return 's' def singular_to_plural(n, noun): """ Depending on n, return plural of regular noun in phrase such as "3 goats", "1 goat", "1.0 goat", "1.3 goats", "0 goats" n may be an int, long, float, or str """ e = .0000000000001 if isinstance(n, (int, long)): if n == 1: return str(n) + ' ' + noun elif isinstance(n, float): if n - e < 1 < n + e: return str(n) + ' ' + noun elif isinstance(n, str): if '.' not in n: if n == '1': return n + ' ' + noun else: n = float(n) if n - e < 1 < n + e: return str(n) + ' ' + noun return str(n) + ' ' + noun + 's' def print_program_end_report(): if 0 < total_rects < num_avail_colors: astr = "%d colors of %d were used for %d rectangles" print astr % (total_rects, num_avail_colors, total_rects) elif num_avail_colors <= total_rects: print "all %d colors were used for %d rectangles" % (num_avail_colors, total_rects) def beepN(times,interval): """Calls beep() n times at interval of x seconds.""" import time for k in range(times-1): beep() time.sleep(interval) beep() def beep(): """ A very short Beep. Useful at end of program to remind user of the .exe to check final report in the 10 seconds before the console window closes """ import winsound pitch = 500 length = 30 winsound.Beep(pitch,length) print \ """ This program creates sets (cycles) of concentric randomly sized and randomly colored rectangles against background colors randomly chosen from a special list of %d colors. After the initial background of white, a black background will be chosen at least once in five times, but never twice in a row. No rectangle color will repeat until all %d colors have been chosen. """ % (len(BACKGROUND_COLORS), len(COLOR_NAMES_NO_GREYS)) ## defaults() has all the defaults except max_num_cycles, which depends on ## num_cycles_to_show_all_colors, which in turn depends on num_avail_colors, ## which depends on end_range, begin_range, which depend on the defaults ## default_min, default_max . defaults() num_avail_colors = calculate_num_avail_colors() default_max_num_cycles = calculate_num_cycles_to_show_all_colors(default_begin_range, default_end_range) print_defaults_before_acceptance() print """ You can accept all defaults by pressing Enter at the prompt Enter 'n' to decline to accept all defaults """ ans = raw_input("Your choice: ") if ans == '': print "All defaults have been set." accept_all_defaults = True begin_range, end_range = default_min, default_max pause = default_pause max_num_cycles = default_max_num_cycles spd, dly = default_speed, default_delay speed(spd) else: accept_all_defaults = False if not accept_all_defaults: print \ """You can configure the number of rectangles per cycle by setting the minimum and maximum numbers. This will be the range from which the actual number will be chosen by a random process for each cycle. E.g., enter 10, 15 for a range of 10 to 15.""" print "For the default of %d, %d just press Enter." % (default_min, default_max) begin_range, end_range = getMinAndMaxIntegersFromUser(default_min, default_max) print pause = get_pause_from_user(default_pause) if not accept_all_defaults: max_num_cycles = get_max_num_cycles_from_user() print """ The program will stop after %s. To stop it sooner, click in the console window to make it the active window; then press Ctrl+Q. """ % singular_to_plural(max_num_cycles, 'cycle') if not accept_all_defaults: spd, dly = get_speed_and_delay_from_user(default_speed, default_delay) ## spd is used in line below; dly is used in tracer() in function draw_rect() speed(spd) initialize_variables() print "\nThe program has started\n" timeStart = time.time() for x in range(1, max_num_cycles+1): if x == 1: bgcolor("white") print "white is the background color" ## do setup() again (only once again), in order to set the window ## height so that the bottom will be just at the top of task bar. setup(width=.735, height=(window_height()- 40), startx=-1, starty=0) final_rect_num = randint(begin_range, end_range) count = 0 num_used_colors = len(used_colors) num_used_colors_to_report = num_used_colors + multiple_of_num_avail_colors print_so_far_report() print "%d rects in new %s cycle are coming up" % (final_rect_num, int_to_ordinal(num_cycles+1)) for x in range(0, final_rect_num): pen_size, color_name, x, y, flag = get_next_rect_params() hideturtle() draw_rect() total_rects += 1 count += 1 if count == final_rect_num: num_cycles += 1 print "That ends the %s cycle of %d cycles" % (int_to_ordinal(num_cycles), max_num_cycles) time.sleep(1.5) if num_cycles < max_num_cycles: hue = get_background() bgcolor(hue) else: beepN(3, 0.2) print "The program will close in 10 seconds" else: time.sleep(pause) ## report at end of program print print_program_end_report() timeEnd = time.time() print "Time was %s" % (hmsToText(timeEnd - timeStart)) time.sleep(8.5)