Прикреплённый файл «task.py»

Загрузка

   1 #!/usr/bin/env python3
   2 import random
   3 from tkinter import Canvas, Text, N, E, W, S, END, StringVar, IntVar, PhotoImage
   4 from tkinter.ttk import Frame, LabelFrame, Button, Label, Entry, Checkbutton
   5 import sys
   6 import os
   7 import re
   8 # argv: 23996 100000 1
   9 
  10 DWIDTH, DHEIGHT = 512, 256
  11 
  12 def rand(a, b):
  13     return round(random.random()*a+b, 2)
  14 
  15 lDigits = str.maketrans('0123456789', '⁰¹²³⁴⁵⁶⁷⁸⁹')
  16 
  17 
  18 def pownumber(c):
  19     return str(c).translate(lDigits)
  20 
  21 
  22 def scale(x, a, b, A, B):
  23     return (x-a)/(b-a)*(B-A)+A
  24 
  25 
  26 def mscale(x, a, b, A, B, d=1):
  27     X = scale(x, a, b, A, B)
  28     A, B = min(A, B), max(A, B)
  29     return A-d if X<A else (B+d if X>B else X)
  30 
  31 class LabelNum(Frame):
  32     def __init__(self, master=None, Name="Value", Value=0, **kwargs):
  33         Frame.__init__(self, master, **kwargs)
  34         self.Value = StringVar()
  35         self.set(Value, Value)
  36         self.Value.trace_add('write', self.check)
  37         Label(self, text=' '+Name+':').grid(sticky=W+E)
  38         self.Entry = Entry(self, textvariable=self.Value,
  39                            validatecommand=self.check, validate='focusout',
  40                            invalidcommand=self.correct,
  41                            ).grid(row=0, column=1, sticky=W+E)
  42         self.columnconfigure(0, weight=0)
  43         self.columnconfigure(1, weight=1)
  44 
  45     def set(self, val, default=None):
  46         if default is not None:
  47             self.Value.Default = default
  48         self.Value.Value = val
  49         self.Value.Type = type(val)
  50         self.Value.set(str(val))
  51 
  52     def get(self):
  53         return self.Value.Value
  54 
  55     def correct(self, *args):
  56         self.set(self.Value.Value)
  57 
  58     def check(self, *args):
  59         try:
  60             self.Value.Value = self.Value.Type(self.Value.get())
  61         except ValueError:
  62             return False
  63         return True
  64 
  65 
  66 class Controls(Frame):
  67 
  68     def __init__(self, master=None, **kwargs):
  69         Frame.__init__(self, master, **kwargs)
  70         master.Seed = LabelNum(self, "Seed")
  71         master.Seed.grid(row=0, column=0, sticky=W+E)
  72         master.Gen = Button(self, text="Generate", command=master.genrand)
  73         master.Gen.grid(row=0, column=1, sticky=W+E)
  74         master.New = Button(self, text="New", command=master.regen)
  75         master.New.grid(row=0, column=2, sticky=W+E)
  76         master.Draw = Button(self, text="Draw", command=master.redraw)
  77         master.Draw.grid(row=0, column=3, sticky=W+E)
  78         master.Filled = IntVar(master, 1)
  79         master.Fill = Checkbutton(self, text="Fill", variable=master.Filled, command=master.redraw)
  80         master.Fill.grid(row=0, column=4, sticky=W+E)
  81         master.Quit = Button(self, text="Quit", command=master.quit)
  82         master.Quit.grid(row=0, column=5, sticky=W+E)
  83         if len(sys.argv)>3:
  84             master.Dump = Button(self, text="Dump", command=master.dump)
  85             master.Dump.grid(row=0, column=6, sticky=W+E)
  86 
  87         for i in range(self.size()[0]):
  88             self.columnconfigure(i, weight=0)
  89 
  90 
  91 class Values(Frame):
  92 
  93     def __init__(self, master=None, **kwargs):
  94         Frame.__init__(self, master, **kwargs)
  95         master.A = LabelNum(self, 'A')
  96         master.A.grid(row=0, column=0, sticky=W+E)
  97         master.B = LabelNum(self, 'B')
  98         master.B.grid(row=0, column=1, sticky=W+E)
  99         master.M = LabelNum(self, 'M')
 100         master.M.grid(row=0, column=2, sticky=W+E)
 101         master.N = LabelNum(self, 'N')
 102         master.N.grid(row=0, column=3, sticky=W+E)
 103         master.X0 = LabelNum(self, 'X0')
 104         master.X0.grid(row=1, column=0, sticky=W+E)
 105         master.X1 = LabelNum(self, 'X1')
 106         master.X1.grid(row=1, column=1, sticky=W+E)
 107         master.Y0 = LabelNum(self, 'Y0')
 108         master.Y0.grid(row=1, column=2, sticky=W+E)
 109         master.Y1 = LabelNum(self, 'Y1')
 110         master.Y1.grid(row=1, column=3, sticky=W+E)
 111 
 112         for i in range(self.size()[0]):
 113             self.columnconfigure(i, weight=1)
 114 
 115 
 116 class Graph(LabelFrame):
 117 
 118     def __init__(self, master=None, Title="Graph", **kwargs):
 119         LabelFrame.__init__(self, master, text=Title)
 120         self.Graph = Canvas(self, **kwargs)
 121         self.Graph.grid(sticky=N+E+W+S)
 122         self.columnconfigure(0, weight=1)
 123         self.rowconfigure(0, weight=1)
 124         self.Coords = Label(self, text='0:0')
 125         self.Coords.grid(sticky=N+E)
 126 
 127     def fill(self, dots, region, fill=True, **kwargs):
 128         self.Graph.delete('A')
 129         X0, X1, Y0, Y1 = region
 130         ddots = list(dots)
 131         coords = [(mscale(x, X0, X1, 0, self.Graph.winfo_width()),
 132                    mscale(y, Y0, Y1, self.Graph.winfo_height(), 0))
 133                   for x, y in ddots]
 134         mx, Mx = min(coords)[0], max(coords)[0]
 135         my = min(0, min((y, x) for x, y in coords)[0])
 136         coords = [(mx, my)]+coords+[(Mx, my)]
 137         if fill:
 138             self.Graph.create_polygon(*coords, fill='khaki', **kwargs)
 139         else:
 140             self.Graph.create_line(*coords, fill='khaki', **kwargs)
 141         x = scale(0, X0, X1, 0, self.Graph.winfo_width())
 142         y = scale(0, Y0, Y1, self.Graph.winfo_height(), 0)
 143         self.Graph.create_oval(x-3, y-3, x+3, y+3, fill='tomato')
 144         self.Graph.addtag_all('A')
 145 
 146 
 147 class App(Frame):
 148 
 149     res = """Task № {Seed}
 150 
 151 Write a MARS program that paints Bitmap Display in two colors,
 152 depending on whether f(x) = {A}x{m}{B:+}x{n} > y or not for each x:y.
 153 Bottom left pixel of the display must represent {X0}:{Y0},
 154 and upper right one must represent {X1}:{Y1}.
 155 
 156 This is how an assembly program can start:
 157         # Task № {Seed}
 158         .eqv    AA  {A}
 159         .eqv    BB  {B}
 160         .eqv    MM  {M}
 161         .eqv    NN  {N}
 162         .eqv    X0  {X0}
 163         .eqv    Y0  {Y0}
 164         .eqv    X1  {X1}
 165         .eqv    Y1  {Y1}
 166 
 167 Output task №.
 168 Dump Bitmap Display memory to standard output line by line,
 169 using 0 when f(x)<=y and 1 when f(x)>y.
 170 Output should look like this:
 171     {Seed}
 172     00000001111111111111…
 173     00000000111111111111…
 174     00000000000111111111…
 175 
 176 
 177 Do not forget to turn you output upside down!
 178     """
 179 
 180     def __init__(self, master=None, Title="App", **kwargs):
 181         Frame.__init__(self, master, **kwargs)
 182         self.master.rowconfigure(0, weight=1)
 183         self.master.columnconfigure(0, weight=1)
 184         self.master.title(Title)
 185         self.grid(sticky=N+E+S+W)
 186         self.rowconfigure(0, weight=1)
 187         self.columnconfigure(0, weight=1)
 188 
 189         self.Graph = Graph(self, bg='darkgreen')
 190         self.Graph.Graph.bind(('<Configure>'), self.redraw)
 191         self.Graph.grid(row=0, column=0, sticky=N+E+W+S)
 192         self.Graph.Graph.bind('<Motion>', self.showcoords)
 193         self.Task = Text(self, height=self.res.count('\n')+1)
 194         self.Task.insert(1.0, self.res)
 195         self.Task.grid(row=1, column=0, sticky=W+E)
 196         self.Values = Values(self)
 197         self.Values.grid(row=2, column=0, sticky=W+E)
 198         self.Controls = Controls(self)
 199         self.Controls.grid(row=3, column=0, sticky=W+E)
 200 
 201         self.regen(*sys.argv[1:3])
 202 
 203     def showcoords(self, event):
 204         A, B, M, N, X0, X1, Y0, Y1 = self.get()
 205         X = scale(event.x, 0, self.Graph.Graph.winfo_width(), X0, X1)
 206         Y = scale(event.y, self.Graph.Graph.winfo_height(), 0, Y0, Y1)
 207         F = self.fun(X)
 208 
 209         self.Graph.Coords["text"] = f"{X:.3f}:{Y:.3f}:{F:.3f}{'#' if F>Y else ' '}"
 210 
 211     def fun(self, x):
 212         return self.A.get()*x**self.M.get()+self.B.get()*x**self.N.get()
 213 
 214     def graph(self, num=200):
 215         A, B, M, N, X0, X1, Y0, Y1 = self.get()
 216         X = [scale(i, 0, num-1, X0, X1) for i in range(num)]
 217         return zip(X, (self.fun(x) for x in X))
 218 
 219     def regen(self, *par):
 220         self.setrand(*par)
 221         self.genrand()
 222         self.redraw()
 223 
 224     def redraw(self, *args):
 225         m, n = pownumber(self.M.get()), pownumber(self.N.get())
 226         self.Graph['text'] = f'f(x) = {self.A.get()}x{m}{self.B.get():+}x{n} > y'
 227         self.Graph.fill(self.graph(), (self.X0.get(), self.X1.get(), self.Y0.get(), self.Y1.get()), fill=self.Filled.get())
 228 
 229     def dump(self):
 230         A, B, M, N, X0, X1, Y0, Y1 = self.get()
 231         Y = list(map(self.fun, (scale(i, 0, DWIDTH-1, X0, X1) for i in range(DWIDTH))))
 232         pr = "01"
 233         of = "/tmp/f.xpm"
 234         XPM = f"""/* XPM */
 235 static char * xarchie_xpm[] = {{
 236 "{DWIDTH} {DHEIGHT} 2 1",
 237 "0  c MidnightBlue",
 238 "1  c PeachPuff",
 239 """
 240         for iy in range(DHEIGHT):
 241             y = scale(iy, DHEIGHT-1, 0, Y0, Y1)
 242             XPM += '"'
 243             for ey in Y:
 244                 XPM += f"{pr[y>ey]}"
 245             if iy<DHEIGHT-1:
 246                 XPM += '",\n'
 247             else:
 248                 XPM += '"};\n'
 249         with open(of, "w") as f:
 250             f.write(XPM)
 251         os.system("feh /tmp/f.xpm &")
 252         d = re.sub("[^01]", "", XPM)
 253         print(d)
 254 
 255     def genrand(self):
 256         Seed = self.Seed.get()
 257         random.seed(int(Seed))
 258         S = random.choice((1, -1))
 259         A = -rand(3, 0.1)*S
 260         B = rand(10, 0.1)*-S
 261         M = random.choice((3, 4, 5))
 262         N = random.choice((1, 2))
 263         X0 = random.randrange(-9, -2)
 264         X1 = random.randrange(2, 9)
 265         Y0 = random.randrange(-16, -7)
 266         Y1 = random.randrange(8, 17)
 267         self.set(A, B, M, N, X0, X1, Y0, Y1)
 268         m, n = pownumber(self.M.get()), pownumber(self.N.get())
 269         self.Task.delete(1.0, END)
 270         self.Task.insert(1.0, self.res.format(**locals()))
 271 
 272         print(self.res.format(**locals()))
 273 
 274     def get(self):
 275         return \
 276             self.A.get(), \
 277             self.B.get(), \
 278             self.M.get(), \
 279             self.N.get(), \
 280             self.X0.get(), \
 281             self.X1.get(), \
 282             self.Y0.get(), \
 283             self.Y1.get()
 284 
 285     def set(self, A, B, M, N, X0, X1, Y0, Y1):
 286         self.A.set(A)
 287         self.B.set(B)
 288         self.M.set(M)
 289         self.N.set(N)
 290         self.X0.set(X0)
 291         self.X1.set(X1)
 292         self.Y0.set(Y0)
 293         self.Y1.set(Y1)
 294 
 295     def setrand(self, seed=None, mod=100000):
 296         global out
 297         if seed is None:
 298             random.seed()
 299             seed = random.randrange(int(mod))
 300         else:
 301             seed = int(seed) % int(mod)
 302         self.Seed.Value.set(str(seed))
 303 
 304 def main():
 305     A = App()
 306     A.mainloop()
 307 
 308 if __name__ == "__main__":
 309     main()

Прикреплённые файлы

Для ссылки на прикреплённый файл в тексте страницы напишите attachment:имяфайла, как показано ниже в списке файлов. Не используйте URL из ссылки «[получить]», так как он чисто внутренний и может измениться.
 Все файлы | Выбранные файлы: удалить переместить на страницу скопировать на страницу

Вам нельзя прикреплять файлы к этой странице.