I am not quite sure what exactly you are asking but the get a random integer value inside a range you could use randint(min_value, max_value)
. This works for integers. To get a random value between 100 and 900 you would use randint(100, 900)
.
If you have a smaller range and want fractions as well you could use min_value + random() * (max_value  min_value)
eg 100 + (900100) * random()
I hope that helps, good luck!
Posts made by jo

RE: Random values inside the axes of a variable font

binary counting with a 7 segment LCD
here is some code to draw a 7 segment LCD and use the segments to count up to 127 (2**71).
class digit(object): """a digit of the lcd display""" def __init__(self, pos, size, seg_l, seg_h): self.pos = pos self.size = size self.seg_l = seg_l self.seg_h = seg_h def draw_segment(self, indx, l, h): seg_poss = [ ( 0, self.size), ( self.size/2, self.size/2), ( self.size/2, self.size/2), ( 0, self.size), (self.size/2, self.size/2), (self.size/2, self.size/2), ( 0, 0), ] x = self.pos[0] + seg_poss[indx][0] y = self.pos[1] + seg_poss[indx][1] if indx in [1, 2, 4, 5]: polygon( (x, y + l/2), (x  h/2, y + l/2  h/2), (x  h/2, y  l/2 + h/2), (x, y  l/2), (x + h/2, y  l/2 + h/2), (x + h/2, y + l/2  h/2),) else: polygon( (x + l/2, y), (x + l/2  h/2, y + h/2), (x  l/2 + h/2, y + h/2), (x  l/2, y), (x  l/2 + h/2, y  h/2), (x + l/2  h/2, y  h/2),) def draw(self, num): for s in range(7): if (num & (1<<s)): self.draw_segment(s, self.seg_l, self.seg_h) #  int_to_bin = { 0 : 63, 1 : 6, 2 : 91, 3 : 79, 4 : 102, 5 : 109, 6 : 125, 7 : 7, 8 : 127, 9 : 111, } #  PW, PH = 500, 500 d = digit((0, 0), PW/3, 150, 30) d_int = digit((PW*.5, PH*.4), 16, 14, 4) for n in range(128): assert (0 <= n < 128), "Values should be higher than 1 and smaller than 128!" newPage(PW, PH) fill(.2) rect(0, 0, PW, PH) translate(PW/2, PH/2) skew(2) fill(0, 1, 0) d.seg_h = n+4 d.draw(n) with savedState(): for i in reversed(str(n)): translate(30) d_int.draw(int_to_bin[int(i)])
should make animations like this:

RE: 2D 5Neighbor Cellular Automata
i would leave the center or starting point at
(0, 0)
and shift the origin withtranslate(canvas/2, canvas/2)
. If cell at(n, n)
is positive add(n, n), (n, n), (n, n), (n, n)
to the list or dict of active cells. hmmhmh not sure if that makes sense.for x in range(cell_amount): for y in range(cell_amount): if (x, y): #check if cell is active here grid[( x, y)] == 1 grid[(x, y)] == 1 grid[( x, y)] == 1 grid[(x, y)] == 1
hope that makes sense. good luck!

RE: 2D 5Neighbor Cellular Automata
hi juan, pretty nice!
I hope somebody will post a more general and cleaner solution to this but one way would be remove all theif
s and calculate the ruleSet position:val = 9  2 * nbs(grid,r,c)  grid[r][c] newGrid[r].append(int(ruleSet[val]))
This line:
return sum(map(bool, neighbors_list))
could be simplified to just:
return sum(neighbors_list)
Two remarks:
If you are drawing the result in two colors you could just draw the background colour with onerect
covering the whole canvas and then draw black cells if the grid position is positive.
Lists are not pythons fastest collection. It would need some rewriting but using a dictionary for the grid could speed this up.Good luck!
UPDATE / ADDITION
actually the whole check if a cell is active or not could be reduced to one quarter since there is a twofold symmetry. so just checking it once and then setting all four quarters. 
RE: Tutorial request: how to animate a variable font
not sure how best to improve this
more frames and higher resolution might be a start
and maybe adding a background. 
RE: Tutorial request: how to animate a variable font
@hzinn hi,
maybe some calculation is going wrong. maybe the variable font has some issues? but it is really hard to say what is happening without some code or image.
does it work if you use the Skia font? 
RE: Unknown Pleasures Tutorial
@eduairet nice!
I am happy you found the comments helpful! So I will mention one more about the page count. The 66 pages confused me at first since I did not see them assigned anywhere. Until I realized that you are generating the Triangular Number since you are looping twice. Not sure if you are doing this on purpose but maybe the last loopfor i in range(12): lineGrid(i)
could just be.
lineGrid(12)
or
lineGrid(66)
if you really wanted exactly that amount of frames.

RE: Unknown Pleasures Tutorial
hi @eduairet
nice one! I don’t think I have ever tried that one myself. I had a look at your code and have some suggestions that might shorten it but hopefully keep it readable.Here are some comments on the
lsPts
function:The
if
statements could be written without theand
:if min_limit < value <= max_limit:
Not sure why you are doing
10**1
since it is the same as10
All the
if
s could probably be anif
and someelif
s and a finalelse
so not every value gets checked four times.DRY! The line
x = i
is used four times but since you only changey
you could write this line outside of yourif
s just once. Also thepoints.append()
could happen just at the end of theif
s.The
lsPts()
function takes the parameternum
but it never gets used. Maybe this could be the gap between the points?Maybe some of these comments are helpful — Have fun!

RE: Variable portrait
hi @eduairet
you can submit a string of characters to the random choice function:chars = 'aeiou' print (random.choice(chars))
any call of a ‘drawing function’ will make a new Page. Remove the
translate(0, 2)
to not have the blank page.Finally getting the image pixel color takes some time. Try to move stuff outside of the loops if they do not change. Eg try a loop outside the
ranLetters()
function to get and store the pixel colors, so you do not have to do that for every page.pix_cols = {} for x in range(0, w, s): for y in range(0, h, s): pix_cols[(x, y)] = imagePixelColor(path, (x, y))
then inside the loop just ask for the stored value:
color = pix_cols[(x, y)]
also these three lines do not change so they could be outside of the loop:
font("League Spartan Variable") fontSize(s) lineHeight(s * 0.75)
good luck!

bezierPath.polygon()?
I just tried to use
bezierPath.polygon()
sincebezierPath.rect()
andbezierPath.oval()
work.
this does not work (and can be solved in other ways), but maybe it would be nice and somewhat logic since rect and oval do work? 
RE: How can I split a path into multiple segments?
@jansindl3r keep in mind that in a Bezier curve time and distance do not correlate. if you construct a point at time .1 it will not be at one tenth of the curve length.
afaik the most common technique to get similar distances is to calculate lots of points on the curve(s), calculate some distances and select the closest points.
this link has some very helpful information.
good luck.

RE: Output text
@gferreira
probably not pythonic
but i was surprised this works
(if you keep things black and white)coin = randint(0, 1) color1 = coin, color2 = not coin,

Lissajous table
Here is some code to draw a Lissajous table.
Change thefunc_x
and/orfunc_y
(sin or cos) and/or add some value to thedelta
to get other curves.
Well, actually the curves are just polygons.#  # lissajous table #  # settings cols = 12 rows = 8 cell_s = 80 r_factor = .8 # fraction of the cell size to have a gap between them func_x = cos # should be `sin` or `cos` func_y = sin # should be `sin` or `cos` delta = 0 #pi/3 # some angle in radians density = 360 # amount of points per cell – higher values make nicer curve approximations #  # calculated settings radius = (cell_s * r_factor) / 2 step = (2 * pi) / density pw = cell_s * (cols + 1) ph = cell_s * (rows + 1) x_coords = { (col, d) : func_x(step * (col + 1) * d + pi/2 + delta) * radius for col in range(cols) for d in range(density) } y_coords = { (row, d) : func_y(step * (row + 1) * d + pi/2) * radius for row in range(rows) for d in range(density) } #  # function(s) def draw_cell(pos, col, row): cx, cy = pos points = [(cx + x_coords[(col, f)], cy + y_coords[(row, f)]) for f in range(density)] polygon(*points) #  # drawings newPage(pw, ph) rect(0, 0, pw, ph) fontSize(12) translate(0, ph) fill(1) text('δ\n{0:.2f}°'.format(degrees(delta)), (cell_s * (1  r_factor)/2, 20)) for col in range(1, cols+1): cx = col * cell_s + cell_s * (1  r_factor)/2 text('{0}\n{1}'.format(func_x.__name__, col), (cx, 20)) for row in range(1, rows + 1): cy = row * cell_s + cell_s * (1  r_factor) text('{0}\n{1}'.format(func_y.__name__, row), (cell_s * (1  r_factor)/2, cy)) fill(None) stroke(.5) strokeWidth(1) for col in range(cols): for row in range(rows): draw_cell((cell_s * col + cell_s * 1.5,  cell_s * row cell_s * 1.5), col, row)

RE: How to mirror/flip a object?
@habakuk nice to read that you can use some of the code!
about the lissajous: I am not sure what exactly you want to achieve. the german wiki entry has vizualisations for a few values. you might want to change the value for
a
andb
and alsodelta
, eg:a = 1 b = 3 delta = pi/4
I do not have your variable font so I cannot test this but I was wondering why you added the plus and minus 20 here:
curr_axis1 = ip(axis1_min + 20, axis1_max  20, x) curr_axis2 = ip(axis2_min + 20, axis2_max  20, y)
lastly if you want to draw the shadow in the back, just put the lines of code before you call the pink drawing. you might then use the
savedState()
so draw it without the mirroring.good luck, jo!

RE: How to mirror/flip a object?
the mirrored drawing is probably happening outside your canvas. keep in mind that every transformation (scale, skew, rotation, etc) is always starting from the origin. so a mirroring from the default origin (left, bottom corner) will be to the left or below your canvas. see the example below with a shifted origin.
pw = 1000 ph = 400 txt = "SHADE" newPage(pw, ph) translate(0, 160) # shift the origin up a bit fontSize(300) text(txt, (pw/2, 0), align = 'center') scale(x=1, y=.5) # the mirroring text(txt, (pw/2, 0), align = 'center')

RE: More variable fonts nonsense
@Christine hello!
I just downloaded the zip from github and did test a few of the scripts in drawbot without any issue. did you change the folder structure and / or do you get an error message? what OS are you using? 
RE: Random Lines with no intersection
ok if i got you right you want the function to
return
a value — in your case the height of the legs. this value could then be used in awhile
loop. while loops are quite helpful but might run forever if done incorrect. I adapted the code a bit so the legs function returns the length of the legs which is then added to the y value in the while loop. There is a check inside the while loop so it will run for a maximum of 3000 times.#  # settings pw = ph = 500 amount_x = 10 cell_w = pw / amount_x max_h = 50 gap = max_h * .2 #  # fucntion(s) def legs(pos, max_w, max_h): x, y = pos length = random() * max_h step_s = random() * max_w polygon((x  step_s, y) , (x, y + length), (x + step_s, y), close = False) return length #  # drawings newPage(pw, ph) fill(None) stroke(0) strokeWidth(2) for x in range(amount_x): count = 0 y = random() * max_h while y < ph: y += legs((x * cell_w + cell_w/2, y), cell_w/2, max_h) y += gap count += 1 if count > 3000: break
and the while loop without the check:
for x in range(amount_x): y = random() * max_h while y < ph: y += legs((x * cell_w + cell_w/2, y), cell_w/2, max_h) y += gap

Vera Molnar recoded
Vera Molnar is a great computer generated arts pioneer and is still working. I could not resist to emulate and try to recode some of her artworks. Using drawbot to do so is great fun and pretty easy — one can only wonder about the struggles she had to overcome. With all due respect here is a link to github with my humble attempts.

Solar eclipse
if you are not in chile or argentina for the solar eclipse this code can gif you solace:
#  # settings pw = 800 ph = 500 dia = pw * .45 frames = 20 #  # function(s) def a_page(): newPage(pw, ph) rect(0, 0, pw, ph) radialGradient((pw/2, ph/2), (pw/2, ph/2), [(1, 0.8, 0), (0.9, 0.6, 0) ]) oval(pw/2dia/2, ph/2dia/2, dia, dia) def ip(a, b, f): return a + (ba)*f #  # drawings for frame in range(frames): a_page() f = frame / frames x = ip(pw/4, pw/4*3, f) y = ip(0, ph, f) fill(0) if abs(x  pw/2) < .2: shadow((0, 0), dia/3, (1, 1, 1)) oval(x  dia/2, y  dia/2, dia, dia) # saveImage('solar_eclipse.gif')

RE: Random Lines with no intersection
@mrrouge
I am not quite sure if this is what you are asking for but you either need totranslate(x,y)
the maximum leg length or width or just draw the legs at the position you want them to. In yourlegs()
function you do have the parametersx
andy
but they are not used inside the function.Also I do recommend to use a variable if you repeatedly use the same value. So instead of
randint(20, 100)
you could usemin_val = 20 max_val = 100 randint(min_val, max_val)
I put together a simple “legs” drawing that might help.
Good luck#  # settings pw = ph = 500 amount_x = 10 amount_y = 4 cell_w = pw / amount_x cell_h = ph / amount_y #  # fucntion(s) def legs(pos, max_w, max_h): x, y = pos length = random() * max_h step_s = random() * max_w polygon((x  step_s, y  length) , pos, (x + step_s, y  length), close = False) #  # drawings newPage(pw, ph) fill(None) stroke(0) strokeWidth(2) for x in range(amount_x): for y in range(amount_y): legs((x * cell_w + cell_w/2, y * cell_h + cell_h/2), cell_w/2, cell_h/2)