7856
Comment: Added "Queens on board"
|
12839
Python 3 for Unreadable code
|
Deletions are marked like this. | Additions are marked like this. |
Line 7: | Line 7: |
== Hearing a trigonometric identity == by Marshall Hampton. When the two frequencies are well separated, we hear the right hand side of the identity. When they start getting close, we hear the higher-pitched factor in the left-hand side modulated by the lower-pitched envelope. {{{#!sagecell import wave class SoundFile: def __init__(self, signal,lab=''): self.file = wave.open('./test' + lab + '.wav', 'wb') self.signal = signal self.sr = 44100 def write(self): self.file.setparams((1, 2, self.sr, 44100*4, 'NONE', 'noncompressed')) self.file.writeframes(self.signal) self.file.close() mypi = float(pi) from math import sin @interact def sinsound(freq_ratio = slider(1/144,1,1/144,1/12)): hz1 = 440.0 hz2 = float(440.0*2^freq_ratio) html('$\cos(\omega t) - \cos(\omega_0 t) = 2 \sin(\\frac{\omega + \omega_0}{2}t) \sin(\\frac{\omega - \omega_0}{2}t)$') s2 = [sin(hz1*x*mypi*2)+sin(hz2*x*mypi*2) for x in srange(0,4,1/44100.0)] s2m = max(s2) s2f = [16384*x/s2m for x in s2] s2str = ''.join(wave.struct.pack('h',x) for x in s2f) lab="%1.2f"%float(freq_ratio) f = SoundFile(s2str,lab=lab) f.write() pnum = 1500+int(500/freq_ratio) show(list_plot(s2[0:pnum],plotjoined=True)) html('<embed src="cell://test'+ lab +'.wav" width="200" height="100"></embed>') html('Frequencies: '+ '$\omega_0 = ' + str(hz1) + ' $, $\omega = '+latex(hz2) + '$') }}} {{attachment:sinsound.png}} == Karplus-Strong algorithm for plucked and percussive sound generation == by Marshall Hampton {{{#!sagecell import wave class SoundFile: def __init__(self, signal,lab=''): self.file = wave.open('./test' + lab + '.wav', 'wb') self.signal = signal self.sr = 44100 def write(self): self.file.setparams((1, 2, self.sr, 44100*4, 'NONE', 'noncompressed')) self.file.writeframes(self.signal) self.file.close() mypi = float(pi) from math import sin def ks(delay,length,blend = 0,filler=None,stretch=0): if filler == None: filler = [randint(-16383,16383) for q in range(delay+1)] outsig = filler[:] index = len(filler) while len(outsig) < length: s = random() if s > stretch: b = random() if b < 1-blend: newvalue = (outsig[index-delay]+outsig[index-delay-1])*.5 else: newvalue = -(outsig[index-delay]+outsig[index-delay-1])*.5 else: newvalue = outsig[index-delay] outsig.append(newvalue) index += 1 return [int(round(x)) for x in outsig] @interact def sinsound(delay = slider([int(2^i) for i in range(2,10)], default=100, label="initial delay"), blend=slider(srange(0,1,.01,include_endpoint=True),default=0,label="blend factor"), stretch=slider(srange(0,1,.01,include_endpoint=True),default=0,label="stretch factor")): s2f = ks(delay,int(44100*(1/2)),blend=blend,stretch=stretch) for i in range(12): s2f = s2f + ks(int(2^((12+i)/12.0)*delay),int(44100*(1/2)),blend=blend, stretch=stretch) html("Karplus-Strong algorithm with blending and delay stretching") html("<br>K. Karplus and A. Strong, <em>Digital synthesis of plucked string and drum timbres</em>, \nComputer Music Journal 7 (2) (1983), 43–55.<br>") html("Initial waveform:") show(list_plot(s2f[0:2000],plotjoined=True), figsize = [7,3.5]) html("Waveform after stabilization:") show(list_plot(s2f[20000:22000],plotjoined=True), figsize = [7,3.5]) s2str = ''.join(wave.struct.pack('h',x) for x in s2f) lab="" f = SoundFile(s2str,lab=lab) f.write() html('<embed src="cell://test'+ lab +'.wav" width="200" height="100"></embed>') }}} {{attachment:KarplusStrong.png}} |
|
Line 9: | Line 107: |
{{{ | {{{#!sagecell |
Line 20: | Line 118: |
XY = X.intersection(Y) XZ = X.intersection(Z) YZ = Y.intersection(Z) XYZ = XY.intersection(Z) |
XY = X & Y XZ = X & Z YZ = Y & Z XYZ = XY & Z |
Line 25: | Line 123: |
html("$X \cap Y$ = %s"%f(XY)) html("$X \cap Z$ = %s"%f(XZ)) html("$Y \cap Z$ = %s"%f(YZ)) html("$X \cap Y \cap Z$ = %s"%f(XYZ)) |
html("$X \\cap Y$ = {}".format(f(XY))) html("$X \\cap Z$ = {}".format(f(XZ))) html("$Y \\cap Z$ = {}".format(f(YZ))) html("$X \\cap Y \\cap Z$ = {}".format(f(XYZ))) |
Line 50: | Line 148: |
Z = set(S[i]).intersection(S[(i+1)%3]).difference(set(XYZ)) | Z = (set(S[i]) & S[(i+1)%3]) - set(XYZ) |
Line 65: | Line 163: |
{{{ | {{{#!sagecell |
Line 68: | Line 166: |
print (lambda f:f(0,f))( | print9(lambda f:f(0,f))( |
Line 73: | Line 171: |
) | )) |
Line 79: | Line 177: |
{{{ | {{{#!sagecell |
Line 86: | Line 184: |
print "<html>" # trick to avoid word wrap | |
Line 88: | Line 185: |
cProfile.run(cmd) | cProfile.runctx(cmd,globals(), locals()) |
Line 90: | Line 187: |
profile.run(cmd) print "</html>" |
profile.runctx(cmd,globals(), locals()) |
Line 99: | Line 195: |
{{{ | {{{#!sagecell |
Line 102: | Line 198: |
print globals()[system].eval(code) | print(globals()[system].eval(code)) |
Line 107: | Line 203: |
== A Random Walk == by William Stein {{{ html('<h1>A Random Walk</h1>') vv = []; nn = 0 @interact def foo(pts = checkbox(True, "Show points"), refresh = checkbox(False, "New random walk every time"), steps = (50,(10..500))): # We cache the walk in the global variable vv, so that # checking or unchecking the points checkbox doesn't change # the random walk. html("<h2>%s steps</h2>"%steps) global vv if refresh or len(vv) == 0: s = 0; v = [(0,0)] for i in range(steps): s += random() - 0.5 v.append((i, s)) vv = v elif len(vv) != steps: # Add or subtract some points s = vv[-1][1]; j = len(vv) for i in range(steps - len(vv)): s += random() - 0.5 vv.append((i+j,s)) v = vv[:steps] else: v = vv L = line(v, rgbcolor='#4a8de2') if pts: L += points(v, pointsize=10, rgbcolor='red') show(L, xmin=0, figsize=[8,3]) }}} {{attachment:randomwalk.png}} == 3D Random Walk == {{{ @interact def rwalk3d(n=(50,1000), frame=True): pnt = [0,0,0] v = [copy(pnt)] for i in range(n): pnt[0] += random()-0.5 pnt[1] += random()-0.5 pnt[2] += random()-0.5 v.append(copy(pnt)) show(line3d(v,color='black'),aspect_ratio=[1,1,1],frame=frame) }}} {{attachment:randomwalk3d.png}} |
|
Line 161: | Line 206: |
{{{ def minkdemo(list1,list2): |
{{{#!sagecell def minkdemo(list1, list2): |
Line 164: | Line 209: |
Returns the Minkowski sum of two lists. | Return the Minkowski sum of two lists. |
Line 169: | Line 214: |
temp = [stuff1[i] + stuff2[i] for i in range(len(stuff1))] output.append(temp) |
output.append([a + b for a, b in zip(stuff1, stuff2)]) |
Line 172: | Line 216: |
@interact def minksumvis(x1tri = slider(-1,1,1/10,0, label = 'Triangle point x coord.'), yb = slider(1,4,1/10,2, label = 'Blue point y coord.')): t_list = [[1,0],[x1tri,1],[0,0]] |
@interact def minksumvis(x1tri=slider(-1,1,1/10,0, label='Triangle point x coord.'), yb=slider(1,4,1/10,2, label='Blue point y coord.')): t_list = [[1,0], [x1tri,1], [0,0]] |
Line 185: | Line 230: |
for an_edge in p12poly.vertex_adjacencies(): edge_lines = edge_lines + line([verts[an_edge[0]], verts[an_edge[1][0]]]) edge_lines = edge_lines + line([verts[an_edge[0]], verts[an_edge[1][1]]]) |
for v0, v1 in p12poly.graph().edges(False): edge_lines += line([v0, v1]) |
Line 193: | Line 237: |
triangle_sum = triangle_sum + polygon(temp_list, alpha = .5, rgbcolor = (1,0,0)) | triangle_sum += polygon(temp_list, alpha = .5, rgbcolor = (1,0,0)) |
Line 199: | Line 243: |
kite_sum = kite_sum + polygon(temp_list, alpha = .3,rgbcolor = (0,0,1)) | kite_sum += polygon(temp_list, alpha = .3,rgbcolor = (0,0,1)) |
Line 201: | Line 245: |
labels = labels + text('=', (-.2,.5), rgbcolor = (0,0,0)) | labels += text('=', (-.2,.5), rgbcolor = (0,0,0)) |
Line 205: | Line 249: |
== Queens on board == An interaction to play with the problem of placing eight queens on a board so that they do not threaten each other. This interaction exemplifies the use of persistent data, and the auto_update=False option coded by mhansen and included in sage 3.3. by Pablo Angulo {{{ queens=[] opciones=['Clean board', 'Add queen', 'Remove queen' ] @interact def _(queen=input_box(default=(0,0)), opcion=selector(opciones, buttons=True), auto_update=False ): global queens if opcion=='Clean board': queens=[] elif opcion=='Add queen': if queen not in queens: queens.append(queen) |
== Cellular Automata == by Pablo Angulo, Eviatar Bach {{{#!sagecell from numpy import zeros from random import randint def cellular(rule, N, initial='Single-cell'): '''Yields a matrix showing the evolution of a Wolfram's cellular automaton rule: determines how a cell's value is updated, depending on its neighbors N: number of iterations initial: starting condition; can be either single-cell or a random binary row ''' M=zeros( (N,2*N+2), dtype=int) if initial=='Single-cell': M[0,N]=1 |
Line 221: | Line 268: |
queens.remove(queen) board=matrix(ZZ,8,8) for x in range(8): for y in range(8): board[x,y]=(x+y)%2*7 for x,y in queens: for i in range(8): if i!=y: board[x,i]=1+(x+i)%2*5 if i!=x: board[i,y]=1+(i+y)%2*5 for i in range(-min(x,y),min(8-x,8-y)): if i!=0: board[x+i,y+i]=1+(x+y)%2*5 for i in range(max(-x,y-7),min(8-x,y+1)): if i!=0: board[x+i,y-i]=1+(x+y)%2*5 for x,y in queens: if ( board[x,y]==1 or board[x,y]==6 ): print 'Queen at (%d,%d) is threatened by another queen'%(x,y) board[x,y]=4 else: board[x,y]=3 show(matrix_plot(board, cmap='Oranges' )) |
M[0]=[randint(0,1) for a in range(0,2*N+2)] |
Line 243: | Line 270: |
}}} {{attachment:queens.png}} |
for j in range(1,N): for k in range(0,2*N): l = 4*M[j-1,k-1] + 2*M[j-1,k] + M[j-1,k+1] M[j,k]=rule[ l ] return M[:,:-1] def num2rule(number): if not 0 <= number <= 255: raise Exception('Invalid rule number') binary_digits = number.digits(base=2) return binary_digits + [0]*(8-len(binary_digits)) @interact def _( initial=selector(['Single-cell', 'Random'], label='Starting condition'), N=input_box(label='Number of iterations',default=100), rule_number=input_box(label='Rule number',default=110), size = slider(1, 11, label= 'Size', step_size=1, default=6 ), auto_update=False): rule = num2rule(rule_number) M = cellular(rule, N, initial) plot_M = matrix_plot(M, cmap='binary') plot_M.show( figsize=[size,size]) }}} {{attachment:cellular2.png}} == Another Interactive Venn Diagram == by Jane Long (adapted from http://wiki.sagemath.org/interact/misc) This interact models a problem in which a certain number of people are surveyed to see if they participate in three different activities (running, biking, and swimming). Users can indicate the numbers of people in each category, from 0 to 100. Returns a graphic of a labeled Venn diagram with the number of people in each region. Returns an explanatory error message if user input is inconsistent. {{{#!sagecell @interact def _(T=slider([0..100],default=100,label='People surveyed'),X=slider([0..100],default=28,label='Run'), Y=slider([0..100],default=33,label='Bike'), Z=slider([0..100],default=59,label='Swim'),XY=slider([0..100],default=16,label='Run and Bike'),XZ=slider([0..100],default=13,label='Run and Swim'),YZ=slider([0..100],default=12,label='Bike and Swim'),XYZ=slider([0..100],default=7,label='Run, Bike, and Swim')): centers = [(cos(n*2*pi/3), sin(n*2*pi/3)) for n in [0,1,2]] scale = 1.7 clr = ['yellow', 'blue', 'green'] G = Graphics() for i in range(3): G += circle(centers[i], scale, rgbcolor=clr[i], fill=True, alpha=0.3) for i in range(3): G += circle(centers[i], scale, rgbcolor='black') # Label sets G += text('Run',(3,0),rgbcolor='black') G += text('Bike',(-1,3),rgbcolor='black') G += text('Swim',(-1,-3),rgbcolor='black') # Plot pairs of intersections ZX=XZ-XYZ G += text(ZX, (1.3*cos(2*2*pi/3 + pi/3), 1.3*sin(2*2*pi/3 + pi/3)), rgbcolor='black') YX=XY-XYZ G += text(YX, (1.3*cos(0*2*pi/3 + pi/3), 1.3*sin(0*2*pi/3 + pi/3)), rgbcolor='black') ZY=YZ-XYZ G += text(ZY, (1.3*cos(1*2*pi/3 + pi/3), 1.3*sin(1*2*pi/3 + pi/3)), rgbcolor='black') # Plot what is in one but neither other XX=X-ZX-YX-XYZ G += text(XX, (1.5*centers[0][0],1.7*centers[0][1]), rgbcolor='black') YY=Y-ZY-YX-XYZ G += text(YY, (1.5*centers[1][0],1.7*centers[1][1]), rgbcolor='black') ZZ=Z-ZY-ZX-XYZ G += text(ZZ, (1.5*centers[2][0],1.7*centers[2][1]), rgbcolor='black') # Plot intersection of all three G += text(XYZ, (0,0), rgbcolor='black') # Indicate number not in X, in Y, or in Z C = T-XX-YY-ZZ-ZX-ZY-YX-XYZ G += text(C,(3,-3),rgbcolor='black') # Check reasonableness before displaying result if XYZ>XY or XYZ>XZ or XYZ>YZ or XY>X or XY>Y or XZ>X or XZ>Z or YZ>Y or YZ>Z or C<0 or XYZ<0 or XZ<0 or YZ<0 or XY<0 or X<0 or Y<0 or Z<0: print('This situation is impossible! (Why?)') else: G.show(aspect_ratio=1, axes=False) }}} {{attachment:vennjhl.png}} |
Sage Interactions - Miscellaneous
goto interact main page
Contents
Hearing a trigonometric identity
by Marshall Hampton. When the two frequencies are well separated, we hear the right hand side of the identity. When they start getting close, we hear the higher-pitched factor in the left-hand side modulated by the lower-pitched envelope.
Karplus-Strong algorithm for plucked and percussive sound generation
by Marshall Hampton
An Interactive Venn Diagram
Unreadable code
by Igor Tolkov
Profile a snippet of code
Evaluate a bit of code in a given system
by William Stein (there is no way yet to make the text box big):
Minkowski Sum
by Marshall Hampton
Cellular Automata
by Pablo Angulo, Eviatar Bach
Another Interactive Venn Diagram
by Jane Long (adapted from http://wiki.sagemath.org/interact/misc)
This interact models a problem in which a certain number of people are surveyed to see if they participate in three different activities (running, biking, and swimming). Users can indicate the numbers of people in each category, from 0 to 100. Returns a graphic of a labeled Venn diagram with the number of people in each region. Returns an explanatory error message if user input is inconsistent.