rev |
line source |
ksenia_yashina@8
|
1 from Tkinter import * |
ksenia_yashina@20
|
2 from math import * |
ksenia_yashina@20
|
3 import bacteria |
ksenia_yashina@20
|
4 import petri |
ksenia_yashina@20
|
5 import random |
ksenia_yashina@20
|
6 import vector |
ksenia_yashina@22
|
7 import webbrowser |
ksenia_yashina@11
|
8 |
ksenia_yashina@13
|
9 class IF(object): |
ksenia_yashina@22
|
10 def __init__(self,delay=2,diam=300,num=0,env=1,reprod_a=False,reprod_s=False,life=0,stat=True): |
ksenia_yashina@11
|
11 self.delay=delay |
ksenia_yashina@11
|
12 self.diam=diam |
ksenia_yashina@11
|
13 self.num=num |
ksenia_yashina@11
|
14 self.env=env |
ksenia_yashina@11
|
15 self.reprod_s=reprod_s |
ksenia_yashina@11
|
16 self.reprod_a=reprod_a |
ksenia_yashina@11
|
17 self.life=life |
ksenia_yashina@22
|
18 self.stat=stat |
ksenia_yashina@11
|
19 |
ksenia_yashina@11
|
20 def __repr__(self): |
ksenia_yashina@22
|
21 return "<%s,%s,%s,%s,%s,%s,%s,%s>"%(self.delay,self.diam,self.num,\ |
ksenia_yashina@11
|
22 self.env,self.reprod_a,\ |
ksenia_yashina@22
|
23 self.reprod_s,self.life,self.stat) |
ksenia_yashina@20
|
24 def mutate(self): |
ksenia_yashina@20
|
25 for bact in p.bacteria: |
ksenia_yashina@20
|
26 if not(bact.mutated): |
ksenia_yashina@20
|
27 bact.mutated=True |
ksenia_yashina@22
|
28 p.total_mut+=1 |
ksenia_yashina@20
|
29 return |
ksenia_yashina@11
|
30 |
ksenia_yashina@11
|
31 def sbmt(self): |
ksenia_yashina@22
|
32 |
ksenia_yashina@20
|
33 b=[] |
ksenia_yashina@11
|
34 submit.config(text="Stop",command=self.stop) |
ksenia_yashina@11
|
35 scl1.config(state=DISABLED) |
ksenia_yashina@11
|
36 scl2.config(state=DISABLED) |
ksenia_yashina@11
|
37 scl3.config(state=DISABLED) |
ksenia_yashina@11
|
38 cb1.config(state=DISABLED) |
ksenia_yashina@11
|
39 cb2.config(state=DISABLED) |
ksenia_yashina@22
|
40 show_stat.config(state=DISABLED) |
ksenia_yashina@11
|
41 self.num=scl1.get() |
ksenia_yashina@11
|
42 self.diam=scl2.get() |
ksenia_yashina@11
|
43 self.life=scl3.get() |
ksenia_yashina@11
|
44 c.config(height=self.diam+20,width=self.diam+20,bg="gray75") |
ksenia_yashina@11
|
45 filler=c.create_rectangle(0,0,self.diam+22,self.diam+22,fill="lightgrey") |
ksenia_yashina@11
|
46 c.grid(row=0,column=2,rowspan=6,padx=50,pady=10) |
ksenia_yashina@11
|
47 dish=c.create_oval(10,10,self.diam+10,self.diam+10,fill="white") |
ksenia_yashina@20
|
48 for i in range(self.num): |
ksenia_yashina@20
|
49 x_i=random.randint(-self.diam/2+15,self.diam/2-15) |
ksenia_yashina@20
|
50 y_i=random.randint(15+(int)(-sqrt((self.diam/2)**2-x_i**2)),-15+(int)(sqrt((self.diam/2)**2-x_i**2))) |
ksenia_yashina@20
|
51 b.append(bacteria.Bacteria(vector.Vector(x_i,y_i), |
ksenia_yashina@20
|
52 vector.Vector(0,1), |
ksenia_yashina@20
|
53 self.life,False)) |
ksenia_yashina@20
|
54 for bact in b: |
ksenia_yashina@20
|
55 bact.velocity = bact.rnd_velocity(pi/4*random.randrange(0,8)) |
ksenia_yashina@20
|
56 p.num=self.num |
ksenia_yashina@22
|
57 p.total=self.num |
ksenia_yashina@22
|
58 p.total_max=self.num |
ksenia_yashina@22
|
59 p.total_min=self.num |
ksenia_yashina@22
|
60 p.total_mut=0 |
ksenia_yashina@22
|
61 p.s_num=0 |
ksenia_yashina@22
|
62 p.a_num=0 |
ksenia_yashina@20
|
63 p.bacteria=b |
ksenia_yashina@20
|
64 p.radius=self.diam/2 |
ksenia_yashina@20
|
65 p.delta=5 |
ksenia_yashina@20
|
66 p.bact_r=5 |
ksenia_yashina@20
|
67 p.full_lifetime=self.life |
ksenia_yashina@20
|
68 self.depict() |
ksenia_yashina@11
|
69 |
ksenia_yashina@22
|
70 def pop_up(self): |
ksenia_yashina@22
|
71 stat_fr=Toplevel() |
ksenia_yashina@22
|
72 stat_fr.title("Statistics") |
ksenia_yashina@22
|
73 init_stat=LabelFrame(stat_fr,text="Initial parameters") |
ksenia_yashina@22
|
74 init_txt="Number of cells: %s\nDiameter of Petri dish: %s\nCell's lifetime: %s\n"%(self.num,self.diam, |
ksenia_yashina@22
|
75 self.life) |
ksenia_yashina@22
|
76 init_txt+="Asexual reproduction allowed: %s\nSexual reproduction allowed: %s"%(self.reprod_a,self.reprod_s) |
ksenia_yashina@22
|
77 init_stat.grid(padx=15,pady=10) |
ksenia_yashina@22
|
78 init_lbl = Label(init_stat,text=init_txt) |
ksenia_yashina@22
|
79 init_lbl.grid(padx=10) |
ksenia_yashina@22
|
80 stat_frame=LabelFrame(stat_fr,text="Statistics") |
ksenia_yashina@22
|
81 stat_frame.grid(padx=15,pady=10) |
ksenia_yashina@22
|
82 stat_txt="Total number of cells: %s\nMaximum number of cells in dish: %s\n"%(p.total,p.total_max) |
ksenia_yashina@22
|
83 stat_txt+="Minimum number of cells in dish: %s\nTotal number of mutated cells: %s\n"%(p.total_min,p.total_mut) |
ksenia_yashina@22
|
84 stat_txt+="Number of asexual reproduction events: %s\nNumber of sexual reproduction events: %s"%(p.a_num,p.s_num) |
ksenia_yashina@22
|
85 stat_lbl = Label(stat_frame,text=stat_txt) |
ksenia_yashina@22
|
86 stat_lbl.grid(padx=10) |
ksenia_yashina@22
|
87 |
ksenia_yashina@11
|
88 def stop(self): |
ksenia_yashina@20
|
89 c.after_cancel(self.rep) |
ksenia_yashina@20
|
90 c.delete("all") |
ksenia_yashina@22
|
91 dish=c.create_oval(10,10,self.diam+10,self.diam+10,fill="white") |
ksenia_yashina@11
|
92 submit.config(text="Submit",command=self.sbmt) |
ksenia_yashina@11
|
93 scl1.config(state=NORMAL) |
ksenia_yashina@11
|
94 scl2.config(state=NORMAL) |
ksenia_yashina@11
|
95 scl3.config(state=NORMAL) |
ksenia_yashina@11
|
96 cb1.config(state=NORMAL) |
ksenia_yashina@11
|
97 cb2.config(state=NORMAL) |
ksenia_yashina@22
|
98 show_stat.config(state=NORMAL) |
ksenia_yashina@11
|
99 |
ksenia_yashina@11
|
100 def new_reprod_a(self): |
ksenia_yashina@11
|
101 self.reprod_a=not(self.reprod_a) |
ksenia_yashina@11
|
102 return |
ksenia_yashina@11
|
103 |
ksenia_yashina@11
|
104 def new_reprod_s(self): |
ksenia_yashina@11
|
105 self.reprod_s=not(self.reprod_s) |
ksenia_yashina@11
|
106 return |
ksenia_yashina@13
|
107 |
ksenia_yashina@13
|
108 def help(self): |
ksenia_yashina@22
|
109 url = 'About.html' |
ksenia_yashina@22
|
110 webbrowser.open(url, new=1, autoraise=True) |
ksenia_yashina@13
|
111 |
ksenia_yashina@13
|
112 def depict(self): |
ksenia_yashina@20
|
113 c.delete("all") |
ksenia_yashina@20
|
114 dish=c.create_oval(10,10,self.diam+10,self.diam+10,fill="white") |
ksenia_yashina@20
|
115 env=scl.get() |
ksenia_yashina@22
|
116 if p.step(0.5,int(env),self.reprod_a,self.reprod_s): |
ksenia_yashina@22
|
117 for bact in p.bacteria: |
ksenia_yashina@22
|
118 if bact.mutated: |
ksenia_yashina@22
|
119 color="black" |
ksenia_yashina@22
|
120 else: |
ksenia_yashina@22
|
121 color="white" |
ksenia_yashina@22
|
122 c.create_oval(10+self.diam/2+bact.position.x-p.bact_r,10+self.diam/2+bact.position.y-p.bact_r,\ |
ksenia_yashina@22
|
123 10+self.diam/2+bact.position.x+p.bact_r*2,\ |
ksenia_yashina@22
|
124 10+self.diam/2+bact.position.y+p.bact_r*2,fill=color) |
ksenia_yashina@22
|
125 self.rep=c.after(self.delay,self.depict) |
ksenia_yashina@22
|
126 else: |
ksenia_yashina@22
|
127 self.stop() |
ksenia_yashina@11
|
128 |
ksenia_yashina@20
|
129 def update_scale(widget, times): |
ksenia_yashina@20
|
130 value = widget.get() |
ksenia_yashina@20
|
131 length = widget['to'] - widget['from'] |
ksenia_yashina@20
|
132 value += length * times / 10 |
ksenia_yashina@20
|
133 widget.set(value) |
me@18
|
134 |
ksenia_yashina@8
|
135 root = Tk() |
ksenia_yashina@8
|
136 root.title("Interface") |
ksenia_yashina@11
|
137 intf=IF() |
ksenia_yashina@11
|
138 c=Canvas() |
ksenia_yashina@20
|
139 p=petri.Petri() |
ksenia_yashina@20
|
140 b=[] |
ksenia_yashina@8
|
141 |
me@18
|
142 root.bind_class("Scale", "<4>", lambda ev: update_scale(ev.widget, +1)) |
me@18
|
143 root.bind_class("Scale", "<5>", lambda ev: update_scale(ev.widget, -1)) |
me@18
|
144 |
ksenia_yashina@13
|
145 menubar = Menu(root) |
ksenia_yashina@13
|
146 |
ksenia_yashina@13
|
147 # create a pulldown menu, and add it to the menu bar |
ksenia_yashina@13
|
148 controlsmenu = Menu(menubar, tearoff=0) |
ksenia_yashina@13
|
149 controlsmenu.add_command(label="Start", command=intf.sbmt) |
ksenia_yashina@13
|
150 controlsmenu.add_command(label="Stop", command=intf.stop) |
ksenia_yashina@13
|
151 controlsmenu.add_command(label="Add mutation", command=intf.mutate) |
ksenia_yashina@13
|
152 controlsmenu.add_separator() |
ksenia_yashina@13
|
153 controlsmenu.add_command(label="Exit", command=root.destroy) |
ksenia_yashina@13
|
154 menubar.add_cascade(label="Controls", menu=controlsmenu) |
ksenia_yashina@13
|
155 |
ksenia_yashina@13
|
156 helpmenu = Menu(menubar, tearoff=0) |
ksenia_yashina@13
|
157 helpmenu.add_command(label="About", command=intf.help) |
ksenia_yashina@13
|
158 menubar.add_cascade(label="Help", menu=helpmenu) |
ksenia_yashina@13
|
159 |
ksenia_yashina@13
|
160 # display the menu |
ksenia_yashina@13
|
161 root.config(menu=menubar) |
ksenia_yashina@13
|
162 |
ksenia_yashina@13
|
163 |
ksenia_yashina@13
|
164 |
ksenia_yashina@8
|
165 init_frame=LabelFrame(root,text="Initial parameters") |
ksenia_yashina@8
|
166 init_frame.grid(padx=15,pady=10) |
ksenia_yashina@10
|
167 scl1 = Scale(init_frame,orient=HORIZONTAL,length=100,from_=1,\ |
ksenia_yashina@20
|
168 to=10,sliderlength=7,width=10) |
ksenia_yashina@10
|
169 scl1.grid(row=0, column=0,padx=10,pady=5) |
ksenia_yashina@10
|
170 lbl1 = Label(init_frame,text="number of cells",bg="white") |
ksenia_yashina@10
|
171 lbl1.grid(row=0,column=1,padx=10) |
ksenia_yashina@11
|
172 scl2 = Scale(init_frame,orient=HORIZONTAL,length=100,from_=100,\ |
ksenia_yashina@10
|
173 to=500,sliderlength=7,width=10) |
ksenia_yashina@10
|
174 scl2.grid(row=1, column=0,padx=10,pady=5) |
ksenia_yashina@10
|
175 lbl2 = Label(init_frame,text="diameter of Petri dish",bg="white") |
ksenia_yashina@10
|
176 lbl2.grid(row=1,column=1,padx=10) |
ksenia_yashina@10
|
177 scl3 = Scale(init_frame,orient=HORIZONTAL,length=100,from_=1,\ |
ksenia_yashina@20
|
178 to=1000,sliderlength=7,width=10) |
ksenia_yashina@10
|
179 scl3.grid(row=2, column=0,padx=10,pady=5) |
ksenia_yashina@10
|
180 lbl3 = Label(init_frame,text="cells' lifetime",bg="white") |
ksenia_yashina@10
|
181 lbl3.grid(row=2,column=1,padx=10) |
ksenia_yashina@8
|
182 lbl_frame=LabelFrame(init_frame,text="Reproduction") |
ksenia_yashina@8
|
183 lbl_frame.grid(row=4,column=0,columnspan=2,padx=15,pady=10) |
ksenia_yashina@8
|
184 list=["Asexual","Sexual"] |
ksenia_yashina@11
|
185 cb1 = Checkbutton(lbl_frame,text="Asexual",command=intf.new_reprod_a) |
ksenia_yashina@10
|
186 cb1.pack() |
ksenia_yashina@11
|
187 cb2 = Checkbutton(lbl_frame,text="Sexual",command=intf.new_reprod_s) |
ksenia_yashina@10
|
188 cb2.pack() |
ksenia_yashina@10
|
189 |
ksenia_yashina@11
|
190 submit=Button(root,text="Submit",width=25,command=intf.sbmt) |
ksenia_yashina@8
|
191 submit.grid(row=1,column=0,columnspan=2,pady=10) |
ksenia_yashina@8
|
192 |
ksenia_yashina@11
|
193 chng_frame=LabelFrame(root,text="Changeable parameters") |
ksenia_yashina@8
|
194 chng_frame.grid(padx=15,pady=10) |
ksenia_yashina@8
|
195 scl = Scale(chng_frame,orient=HORIZONTAL,length=100,from_=1,\ |
ksenia_yashina@8
|
196 to=100,sliderlength=7,width=10) |
ksenia_yashina@8
|
197 scl.grid(row=0, column=0,padx=10,pady=5) |
ksenia_yashina@8
|
198 lbl = Label(chng_frame,text="environment",bg="white") |
ksenia_yashina@8
|
199 lbl.grid(row=0,column=1,padx=10) |
ksenia_yashina@13
|
200 btn = Button(chng_frame,text="Add mutation",width=25,command=intf.mutate) |
ksenia_yashina@8
|
201 btn.grid(row=1,column=0,columnspan=2,pady=10) |
ksenia_yashina@8
|
202 |
ksenia_yashina@22
|
203 show_stat = Button(root,text="Show statistics",width=25,command=intf.pop_up) |
ksenia_yashina@22
|
204 show_stat.grid(pady=10,padx=10) |
ksenia_yashina@22
|
205 |
ksenia_yashina@11
|
206 #root.after(intf.delay,intf.depict()) |
ksenia_yashina@11
|
207 |
ksenia_yashina@8
|
208 mainloop() |