├── LICENSE
├── README.md
├── copcode.py
├── csandbox.py
├── frame.py
├── function.py
├── g.py
├── opcode
├── stack.py
├── test.py
└── test_files
├── test0.py
├── test1.py
├── test2.py
├── test3.py
├── test4.py
├── test5.py
├── test6.py
├── test7.py
├── test8.py
└── test9.py
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CSandBox
2 | 这是一个基于 Python 的 Python 沙盒程序.
3 | 只支持单文件进行运行.
4 |
5 | 以支持的功能:
6 | + 基础数据结构
7 | + 字符串
8 | + int
9 | + float
10 | + bool
11 | + 列表
12 | + 字典
13 | + 元组
14 | + 切片
15 |
16 | + 函数
17 | + 位置参数
18 | + 闭包
19 | + 递归
20 |
21 | + 控制语句
22 | + if
23 | + for
24 | + while
25 | + 运算
26 | + 基础四则运算
27 | + 位运算
28 | + 逻辑运算
29 | + 几乎全部的 Python 支持的运算
30 |
31 | 以上足以满足基础的算法编写需求
32 |
33 | 不支持的功能:
34 | + 函数
35 | + 装饰器
36 | + 键传参
37 |
38 | + 类
39 | + 生成器(包括生成器表达式)
40 | + 协程
41 | + 导入包
42 | + 多文件
43 | + 等高级特性
44 |
45 | 如果想要了解更多请去看测试用例.
--------------------------------------------------------------------------------
/copcode.py:
--------------------------------------------------------------------------------
1 | from operator import le, lt, ge, gt, eq, ne, is_, is_not, contains, not_
2 | from function import Function
3 | from frame import new_frame
4 |
5 | frames = []
6 |
7 |
8 | class OpCode:
9 | cmp_op = (lt, le, eq, ne, gt, ge, lambda a, b: contains(b, a),
10 | lambda a, b: not_(contains(b, a)), is_, is_not) # 支持的比较运算符
11 |
12 | def __init__(self, frame):
13 | self.frame = frame
14 | self.stack = frame.stack
15 | self.co_code = frame.co_code
16 | self.co_consts = frame.co_consts
17 | self.co_cellvars = frame.co_cellvars
18 | self.co_freevars = frame.co_freevars
19 | self.co_consts = frame.co_consts
20 | self.co_name = frame.co_name
21 | self.co_names = frame.co_names
22 | self.co_nlocals = frame.co_nlocals
23 | self.co_argcount = frame.co_argcount
24 | self.global_ = frame.global_
25 | self.local = frame.local
26 | self.builtin = frame.builtin
27 | self.dict = frame.dict
28 | self.co_varnames = frame.co_varnames
29 | self.blocks = frame.blocks
30 | self.if_return = False
31 | self.opcode_dict = {'1': 'POP_TOP',
32 | '2': 'ROT_TWO',
33 | '3': 'ROT_THREE',
34 | '4': 'DUP_TOP',
35 | '5': 'DUP_TOP_TWO',
36 | '9': 'NOP',
37 | '10': 'UNARY_POSITIVE',
38 | '11': 'UNARY_NEGATIVE',
39 | '12': 'UNARY_NOT',
40 | '15': 'UNARY_INVERT',
41 | '16': 'BINARY_MATRIX_MULTIPLY',
42 | '17': 'INPLACE_MATRIX_MULTIPLY',
43 | '19': 'BINARY_POWER',
44 | '20': 'BINARY_MULTIPLY',
45 | '22': 'BINARY_MODULO',
46 | '23': 'BINARY_ADD',
47 | '24': 'BINARY_SUBTRACT',
48 | '25': 'BINARY_SUBSCR',
49 | '26': 'BINARY_FLOOR_DIVIDE',
50 | '27': 'BINARY_TRUE_DIVIDE',
51 | '28': 'INPLACE_FLOOR_DIVIDE',
52 | '29': 'INPLACE_TRUE_DIVIDE',
53 | '50': 'GET_AITER',
54 | '51': 'GET_ANEXT',
55 | '52': 'BEFORE_ASYNC_WITH',
56 | '55': 'INPLACE_ADD',
57 | '56': 'INPLACE_SUBTRACT',
58 | '57': 'INPLACE_MULTIPLY',
59 | '59': 'INPLACE_MODULO',
60 | '60': 'STORE_SUBSCR',
61 | '61': 'DELETE_SUBSCR',
62 | '62': 'BINARY_LSHIFT',
63 | '63': 'BINARY_RSHIFT',
64 | '64': 'BINARY_AND',
65 | '65': 'BINARY_XOR',
66 | '66': 'BINARY_OR',
67 | '67': 'INPLACE_POWER',
68 | '68': 'GET_ITER',
69 | '69': 'GET_YIELD_FROM_ITER',
70 | '70': 'PRINT_EXPR',
71 | '71': 'LOAD_BUILD_CLASS',
72 | '72': 'YIELD_FROM',
73 | '73': 'GET_AWAITABLE',
74 | '75': 'INPLACE_LSHIFT',
75 | '76': 'INPLACE_RSHIFT',
76 | '77': 'INPLACE_AND',
77 | '78': 'INPLACE_XOR',
78 | '79': 'INPLACE_OR',
79 | '80': 'BREAK_LOOP',
80 | '81': 'WITH_CLEANUP_START',
81 | '82': 'WITH_CLEANUP_FINISH',
82 | '83': 'RETURN_VALUE',
83 | '84': 'IMPORT_STAR',
84 | '85': 'SETUP_ANNOTATIONS',
85 | '86': 'YIELD_VALUE',
86 | '87': 'POP_BLOCK',
87 | '88': 'END_FINALLY',
88 | '89': 'POP_EXCEPT',
89 | '90': 'STORE_NAME',
90 | '91': 'DELETE_NAME',
91 | '92': 'UNPACK_SEQUENCE',
92 | '93': 'FOR_ITER',
93 | '94': 'UNPACK_EX',
94 | '95': 'STORE_ATTR',
95 | '96': 'DELETE_ATTR',
96 | '97': 'STORE_GLOBAL',
97 | '98': 'DELETE_GLOBAL',
98 | '100': 'LOAD_CONST',
99 | '101': 'LOAD_NAME',
100 | '102': 'BUILD_TUPLE',
101 | '103': 'BUILD_LIST',
102 | '104': 'BUILD_SET',
103 | '105': 'BUILD_MAP',
104 | '106': 'LOAD_ATTR',
105 | '107': 'COMPARE_OP',
106 | '108': 'IMPORT_NAME',
107 | '109': 'IMPORT_FROM',
108 | '110': 'JUMP_FORWARD',
109 | '111': 'JUMP_IF_FALSE_OR_POP',
110 | '112': 'JUMP_IF_TRUE_OR_POP',
111 | '113': 'JUMP_ABSOLUTE',
112 | '114': 'POP_JUMP_IF_FALSE',
113 | '115': 'POP_JUMP_IF_TRUE',
114 | '116': 'LOAD_GLOBAL',
115 | '119': 'CONTINUE_LOOP',
116 | '120': 'SETUP_LOOP',
117 | '121': 'SETUP_EXCEPT',
118 | '122': 'SETUP_FINALLY',
119 | '124': 'LOAD_FAST',
120 | '125': 'STORE_FAST',
121 | '126': 'DELETE_FAST',
122 | '127': 'STORE_ANNOTATION',
123 | '130': 'RAISE_VARARGS',
124 | '131': 'CALL_FUNCTION',
125 | '132': 'MAKE_FUNCTION',
126 | '133': 'BUILD_SLICE',
127 | '135': 'LOAD_CLOSURE',
128 | '136': 'LOAD_DEREF',
129 | '137': 'STORE_DEREF',
130 | '138': 'DELETE_DEREF',
131 | '141': 'CALL_FUNCTION_KW',
132 | '142': 'CALL_FUNCTION_EX',
133 | '143': 'SETUP_WITH',
134 | '144': 'EXTENDED_ARG',
135 | '145': 'LIST_APPEND',
136 | '146': 'SET_ADD',
137 | '147': 'MAP_ADD',
138 | '148': 'LOAD_CLASSDEREF',
139 | '149': 'BUILD_LIST_UNPACK',
140 | '150': 'BUILD_MAP_UNPACK',
141 | '151': 'BUILD_MAP_UNPACK_WITH_CALL',
142 | '152': 'BUILD_TUPLE_UNPACK',
143 | '153': 'BUILD_SET_UNPACK',
144 | '154': 'SETUP_ASYNC_WITH',
145 | '155': 'FORMAT_VALUE',
146 | '156': 'BUILD_CONST_KEY_MAP',
147 | '157': 'BUILD_STRING',
148 | '158': 'BUILD_TUPLE_UNPACK_WITH_CALL',
149 | '257': 'EXCEPT_HANDLER'}
150 |
151 | def opcode_1(self, oparg):
152 | """弹出栈顶元素."""
153 | # define POP_TOP 1
154 | self.stack.pop()
155 |
156 | def opcode_2(self, oparg):
157 | """交换栈顶和第二个的位置."""
158 | # define ROT_TWO 2
159 | top = self.stack.top()
160 | second = self.stack.second()
161 | self.stack.set_top(second)
162 | self.stack.set_second(top)
163 |
164 | def opcode_3(self, oparg):
165 | """栈顶三个元素之间交换."""
166 | # define ROT_THREE 3
167 | top = self.stack.pop()
168 | second = self.stack.pop()
169 | third = self.stack.pop()
170 | self.stack.push(top)
171 | self.stack.push(third)
172 | self.stack.push(second)
173 |
174 | def opcode_4(self, oparg):
175 | """复制栈顶并压入栈."""
176 | # define DUP_TOP 4
177 | top = self.stack.top()
178 | self.stack.push(top)
179 |
180 | def opcode_5(self, oparg):
181 | """复制栈顶两个元素并压入栈, 顺序不变."""
182 | # define DUP_TOP_TWO 5
183 | top = self.stack.top()
184 | second = self.stack.second()
185 | self.stack.push(second)
186 | self.stack.push(top)
187 |
188 | def opcode_9(self, oparg):
189 | # define NOP 9
190 | code = "NOP"
191 | raise RuntimeError("使用到未实现的字节码:"+code)
192 |
193 | def opcode_10(self, oparg):
194 |
195 | # define UNARY_POSITIVE 10
196 | code = "UNARY_POSITIVE"
197 | raise RuntimeError("使用到未实现的字节码:"+code)
198 |
199 | def opcode_11(self, oparg):
200 | """针对 -a 运算的字节码."""
201 | # define UNARY_NEGATIVE 11
202 | value = self.stack.pop()
203 | res = -value
204 | self.stack.push(res)
205 |
206 | def opcode_12(self, oparg):
207 | # define UNARY_NOT 12
208 | code = "UNARY_NOT"
209 | raise RuntimeError("使用到未实现的字节码:"+code)
210 |
211 | def opcode_15(self, oparg):
212 | # define UNARY_INVERT 15
213 | value = self.stack.pop()
214 | res = ~value
215 | self.stack.push(res)
216 |
217 | def opcode_16(self, oparg):
218 | # define BINARY_MATRIX_MULTIPLY 16
219 | code = "BINARY_MATRIX_MULTIPLY"
220 | raise RuntimeError("使用到未实现的字节码:"+code)
221 |
222 | def opcode_17(self, oparg):
223 | # define INPLACE_MATRIX_MULTIPLY 17
224 | code = "INPLACE_MATRIX_MULTIPLY"
225 | raise RuntimeError("使用到未实现的字节码:"+code)
226 |
227 | def opcode_19(self, oparg):
228 | """乘方运算."""
229 | # define BINARY_POWER 19
230 | right = self.stack.pop()
231 | left = self.stack.pop()
232 | res = left ** right
233 | self.stack.push(res)
234 |
235 | def opcode_20(self, oparg):
236 | """乘法运算."""
237 | # define BINARY_MULTIPLY 20
238 | rigth = self.stack.pop()
239 | left = self.stack.pop()
240 | res = left * rigth
241 | self.stack.push(res)
242 |
243 | def opcode_22(self, oparg):
244 | """取模运算."""
245 | # define BINARY_MODULO 22
246 | divisor = self.stack.pop()
247 | dividend = self.stack.pop()
248 | res = dividend % divisor
249 | self.stack.push(res)
250 |
251 | def opcode_23(self, oparg):
252 | """加法运算."""
253 | # define BINARY_ADD 23
254 | right = self.stack.pop()
255 | left = self.stack.pop()
256 | res = left + right
257 | self.stack.push(res)
258 |
259 | def opcode_24(self, oparg):
260 | """减法运算."""
261 | # define BINARY_SUBTRACT 24
262 | right = self.stack.pop()
263 | left = self.stack.pop()
264 | res = left - right
265 | self.stack.push(res)
266 |
267 | def opcode_25(self, oparg):
268 | """如果 index 是数字的话就是按照索引取值,如果是 slice 就是取子序列."""
269 | # define BINARY_SUBSCR 25
270 | index = self.stack.pop()
271 | list_ = self.stack.pop()
272 | value = list_[index]
273 | self.stack.push(value)
274 |
275 | def opcode_26(self, oparg):
276 | """除法运算."""
277 | # define BINARY_FLOOR_DIVIDE 26
278 | right = self.stack.pop()
279 | left = self.stack.pop()
280 | res = left // right
281 | self.stack.push(res)
282 |
283 | def opcode_27(self, oparg):
284 | """真除法运算."""
285 | # define BINARY_TRUE_DIVIDE 27
286 | right = self.stack.pop()
287 | left = self.stack.pop()
288 | res = left / right
289 | self.stack.push(res)
290 |
291 | def opcode_28(self, oparg):
292 | """就地除法运算."""
293 | # define INPLACE_FLOOR_DIVIDE 28
294 | right = self.stack.pop()
295 | left = self.stack.pop()
296 | left //= right
297 | self.stack.push(left)
298 |
299 | def opcode_29(self, oparg):
300 | """就地真除法运算."""
301 | # define INPLACE_TRUE_DIVIDE 29
302 | right = self.stack.pop()
303 | left = self.stack.pop()
304 | left /= right
305 | self.stack.push(left)
306 |
307 | def opcode_50(self, oparg):
308 | # define GET_AITER 50
309 | code = "GET_AITER"
310 | raise RuntimeError("使用到未实现的字节码:"+code)
311 |
312 | def opcode_51(self, oparg):
313 | # define GET_ANEXT 51
314 | code = "GET_ANEXT"
315 | raise RuntimeError("使用到未实现的字节码:"+code)
316 |
317 | def opcode_52(self, oparg):
318 |
319 | # define BEFORE_ASYNC_WITH 52
320 | code = "BEFORE_ASYNC_WITH"
321 | raise RuntimeError("使用到未实现的字节码:"+code)
322 |
323 | def opcode_55(self, oparg):
324 | """就地加法运算."""
325 | # define INPLACE_ADD 55
326 | right = self.stack.pop()
327 | left = self.stack.pop()
328 | left += right
329 | self.stack.push(left)
330 |
331 | def opcode_56(self, oparg):
332 | """就地减法运算."""
333 | # define INPLACE_SUBTRACT 56
334 | right = self.stack.pop()
335 | left = self.stack.pop()
336 | left -= right
337 | self.stack.push(left)
338 |
339 | def opcode_57(self, oparg):
340 | """就地乘法运算."""
341 | # define INPLACE_MULTIPLY 57
342 | right = self.stack.pop()
343 | left = self.stack.pop()
344 | left *= right
345 | self.stack.push(left)
346 |
347 | def opcode_59(self, oparg):
348 | """就地取模运算."""
349 | # define INPLACE_MODULO 59
350 | right = self.stack.pop()
351 | left = self.stack.pop()
352 | left %= right
353 | self.stack.push(left)
354 |
355 | def opcode_60(self, oparg):
356 | """将一个序列插入另外一个序列 a[1:2] = [1,2,3,4,5,6]."""
357 | # define STORE_SUBSCR 60
358 | s = self.stack.pop()
359 | x = self.stack.pop()
360 | other_list = self.stack.pop()
361 | x[s] = other_list
362 |
363 | def opcode_61(self, oparg):
364 | # define DELETE_SUBSCR 61
365 | code = "DELETE_SUBSCR"
366 | raise RuntimeError("使用到未实现的字节码:"+code)
367 |
368 | def opcode_62(self, oparg):
369 | """左移运算"""
370 | # define BINARY_LSHIFT 62
371 | right = self.stack.pop()
372 | left = self.stack.pop()
373 | res = left << right
374 | self.stack.push(res)
375 |
376 | def opcode_63(self, oparg):
377 | """右移运算"""
378 | # define BINARY_RSHIFT 63
379 | rigth = self.stack.pop()
380 | left = self.stack.pop()
381 | res = left >> rigth
382 | self.stack.push(res)
383 |
384 | def opcode_64(self, oparg):
385 | """与运算"""
386 | # define BINARY_AND 64
387 | rigth = self.stack.pop()
388 | left = self.stack.pop()
389 | res = left & rigth
390 | self.stack.push(res)
391 |
392 | def opcode_65(self, oparg):
393 | """异或运算"""
394 | # define BINARY_XOR 65
395 | rigth = self.stack.pop()
396 | left = self.stack.pop()
397 | res = left ^ rigth
398 | self.stack.push(res)
399 |
400 | def opcode_66(self, oparg):
401 | """或运算"""
402 | # define BINARY_OR 66
403 | rigth = self.stack.pop()
404 | left = self.stack.pop()
405 | res = left | rigth
406 | self.stack.push(res)
407 |
408 | def opcode_67(self, oparg):
409 | """就地乘方运算."""
410 | # define INPLACE_POWER 67
411 | right = self.stack.pop()
412 | left = self.stack.pop()
413 | left **= right
414 | self.stack.push(left)
415 |
416 | def opcode_68(self, oparg):
417 | """获取可迭代对象的迭代器."""
418 | # define GET_ITER 68
419 | a = self.stack.pop()
420 | it = iter(a)
421 | self.stack.push(it)
422 |
423 | def opcode_69(self, oparg):
424 | # define GET_YIELD_FROM_ITER 69
425 | code = "GET_YIELD_FROM_ITER"
426 | raise RuntimeError("使用到未实现的字节码:"+code)
427 |
428 | def opcode_70(self, oparg):
429 | # define PRINT_EXPR 70
430 | code = "PRINT_EXPR"
431 | raise RuntimeError("使用到未实现的字节码:"+code)
432 |
433 | def opcode_71(self, oparg):
434 | # define LOAD_BUILD_CLASS 71
435 | # code = "LOAD_BUILD_CLASS"
436 | # raise RuntimeError("使用到未实现的字节码:"+code)
437 | print(self.stack)
438 | def opcode_72(self, oparg):
439 | # define YIELD_FROM 72
440 | code = "YIELD_FROM"
441 | raise RuntimeError("使用到未实现的字节码:"+code)
442 |
443 | def opcode_73(self, oparg):
444 | # define GET_AWAITABLE 73
445 | code = "GET_AWAITABLE"
446 | raise RuntimeError("使用到未实现的字节码:"+code)
447 |
448 | def opcode_75(self, oparg):
449 | # define INPLACE_LSHIFT 75
450 | code = "INPLACE_LSHIFT"
451 | raise RuntimeError("使用到未实现的字节码:"+code)
452 |
453 | def opcode_76(self, oparg):
454 | # define INPLACE_RSHIFT 76
455 | code = "INPLACE_RSHIFT"
456 | raise RuntimeError("使用到未实现的字节码:"+code)
457 |
458 | def opcode_77(self, oparg):
459 | """按位与运算"""
460 | # define INPLACE_AND 77
461 | right = self.stack.pop()
462 | left = self.stack.pop()
463 | left &= right
464 | self.stack.push(left)
465 |
466 | def opcode_78(self, oparg):
467 | # define INPLACE_XOR 78
468 | code = "INPLACE_XOR"
469 | raise RuntimeError("使用到未实现的字节码:"+code)
470 |
471 | def opcode_79(self, oparg):
472 | """按位或运算"""
473 | # define INPLACE_OR 79
474 | right = self.stack.pop()
475 | left = self.stack.pop()
476 | left |= right
477 | self.stack.push(left)
478 |
479 | def opcode_80(self, oparg):
480 | """循环结束."""
481 | # define BREAK_LOOP 80
482 | self.frame.index = self.forend
483 | self.stack.pop()
484 |
485 | def opcode_81(self, oparg):
486 |
487 | # define WITH_CLEANUP_START 81
488 | code = "WITH_CLEANUP_START"
489 | raise RuntimeError("使用到未实现的字节码:"+code)
490 |
491 | def opcode_82(self, oparg):
492 | # define WITH_CLEANUP_FINISH 82
493 | code = "WITH_CLEANUP_FINISH"
494 | raise RuntimeError("使用到未实现的字节码:"+code)
495 |
496 | def opcode_83(self, oparg):
497 | """返回值."""
498 | # define RETURN_VALUE 83
499 | value = self.stack.pop()
500 | index = frames.index(self.frame)
501 | if (index != 0):
502 | frame = frames[index-1]
503 | frame.stack.push(value)
504 | self.if_return = True
505 | else:
506 | exit(0)
507 |
508 | def opcode_84(self, oparg):
509 | # define IMPORT_STAR 84
510 | code = "IMPORT_STAR"
511 | raise RuntimeError("使用到未实现的字节码:"+code)
512 |
513 | def opcode_85(self, oparg):
514 | # define SETUP_ANNOTATIONS 85
515 | code = "SETUP_ANNOTATIONS"
516 | raise RuntimeError("使用到未实现的字节码:"+code)
517 |
518 | def opcode_86(self, oparg):
519 | # define YIELD_VALUE 86
520 | code = "YIELD_VALUE"
521 | raise RuntimeError("使用到未实现的字节码:"+code)
522 |
523 | def opcode_87(self, oparg):
524 | """这个我只针对了 for 进行的处理."""
525 | # define POP_BLOCK 87
526 | p = self.blocks.pop()
527 | index = len(self.stack)
528 | while index > p:
529 | self.stack.pop()
530 | index -= 1
531 |
532 | def opcode_88(self, oparg):
533 | # define END_FINALLY 88
534 | code = "END_FINALLY"
535 | raise RuntimeError("使用到未实现的字节码:"+code)
536 |
537 | def opcode_89(self, oparg):
538 | # define POP_EXCEPT 89
539 | code = "POP_EXCEPT"
540 | raise RuntimeError("使用到未实现的字节码:"+code)
541 |
542 | def opcode_90(self, oparg):
543 | """给相应对象设置名字."""
544 | # define STORE_NAME 90
545 | value = self.stack.pop()
546 | name = self.co_names[oparg]
547 | self.local[name] = value
548 |
549 | def opcode_91(self, oparg):
550 | # define DELETE_NAME 91
551 | code = "DELETE_NAME"
552 | raise RuntimeError("使用到未实现的字节码:"+code)
553 |
554 | def opcode_92(self, oparg):
555 | """从堆栈中获取一个可迭代的对象然后对它进行拆包然后倒序压入栈"""
556 | # define UNPACK_SEQUENCE 92
557 | sequence = self.stack.pop()
558 | for item in sequence[::-1]:
559 | self.stack.push(item)
560 |
561 | def opcode_93(self, oparg):
562 | # define FOR_ITER 93
563 | it = self.stack.top()
564 | try:
565 | value = next(it)
566 | self.stack.push(value)
567 | except StopIteration:
568 | self.stack.pop()
569 | self.frame.index += oparg
570 |
571 | def opcode_94(self, oparg):
572 | # define UNPACK_EX 94
573 | code = "UNPACK_EX"
574 | raise RuntimeError("使用到未实现的字节码:"+code)
575 |
576 | def opcode_95(self, oparg):
577 | # define STORE_ATTR 95
578 | code = "STORE_ATTR"
579 | raise RuntimeError("使用到未实现的字节码:"+code)
580 |
581 | def opcode_96(self, oparg):
582 | # define DELETE_ATTR 96
583 | code = "DELETE_ATTR"
584 | raise RuntimeError("使用到未实现的字节码:"+code)
585 |
586 | def opcode_97(self, oparg):
587 | # define STORE_GLOBAL 97
588 | name = self.co_names[oparg]
589 | value = self.stack.pop()
590 | self.global_[name] = value
591 |
592 | def opcode_98(self, oparg):
593 | # define DELETE_GLOBAL 98
594 | code = "DELETE_GLOBAL"
595 | raise RuntimeError("使用到未实现的字节码:"+code)
596 |
597 | def opcode_100(self, oparg):
598 | # define LOAD_CONST 100
599 | value = self.co_consts[oparg]
600 | self.stack.push(value)
601 |
602 | def opcode_101(self, oparg):
603 | # define LOAD_NAME 101
604 | name = self.co_names[oparg]
605 | value = None
606 | if name in self.local:
607 | value = self.local[name]
608 | if not value:
609 | if name in self.global_:
610 | value = self.global_[name]
611 | if not value:
612 | if name in self.builtin:
613 | value = self.builtin[name]
614 | self.stack.push(value)
615 |
616 | def opcode_102(self, oparg):
617 | # define BUILD_TUPLE 102
618 | list_ = []
619 | for _ in range(oparg):
620 | a = self.stack.pop()
621 | list_.append(a)
622 | res = tuple(list_[::-1])
623 | self.stack.push(res)
624 |
625 | def opcode_103(self, oparg):
626 | # define BUILD_LIST 103
627 | list_ = []
628 | for i in range(oparg):
629 | value = self.stack.pop()
630 | list_.append(value)
631 | self.stack.push(list_[::-1])
632 |
633 | def opcode_104(self, oparg):
634 | # define BUILD_SET 104
635 | code = "BUILD_SET"
636 | raise RuntimeError("使用到未实现的字节码:"+code)
637 |
638 | def opcode_105(self, oparg):
639 | # define BUILD_MAP 105
640 | res = {}
641 | values = []
642 | keys = []
643 | for _ in range(oparg):
644 | values.append(self.stack.pop())
645 | keys.append(self.stack.pop())
646 | for key, value in zip(keys[::-1], values[::-1]):
647 | res[key] = value
648 | self.stack.push(res)
649 |
650 | def opcode_106(self, oparg):
651 | """屏蔽所以 LOAD_ATTR 中以 __ 开头的并且不是 __init__ 的所有属性"""
652 | # define LOAD_ATTR 106
653 | c = self.stack.pop()
654 | name = self.co_names[oparg]
655 | assert not (name.startswith("__") and name != "__init__")
656 | res = getattr(c, name)
657 | self.stack.push(res)
658 |
659 | def opcode_107(self, oparg):
660 | # define COMPARE_OP 107
661 | right = self.stack.pop()
662 | left = self.stack.pop()
663 | cmp_ = self.cmp_op[oparg]
664 | res = cmp_(left, right)
665 | self.stack.push(res)
666 |
667 | def opcode_108(self, oparg):
668 | # define IMPORT_NAME 108
669 | code = "IMPORT_NAME"
670 | raise RuntimeError("使用到未实现的字节码:"+code)
671 |
672 | def opcode_109(self, oparg):
673 | # define IMPORT_FROM 109
674 | code = "IMPORT_FROM"
675 | raise RuntimeError("使用到未实现的字节码:"+code)
676 |
677 | def opcode_110(self, oparg):
678 | # define JUMP_FORWARD 110
679 | self.frame.index += oparg
680 |
681 | def opcode_111(self, oparg):
682 | # define JUMP_IF_FALSE_OR_POP 111
683 | cond = self.stack.top()
684 | if cond is True:
685 | self.stack.pop()
686 | else:
687 | self.frame.index = oparg
688 |
689 | def opcode_112(self, oparg):
690 | # define JUMP_IF_TRUE_OR_POP 112
691 | cond = self.stack.top()
692 | if cond is True:
693 | self.frame.index = oparg
694 | else:
695 | self.stack.pop()
696 |
697 | def opcode_113(self, oparg):
698 | # define JUMP_ABSOLUTE 113
699 | self.frame.index = oparg
700 |
701 | def opcode_114(self, oparg):
702 | # define POP_JUMP_IF_FALSE 114
703 | a = self.stack.pop()
704 | if a:
705 | pass
706 | else:
707 | self.frame.index = oparg
708 |
709 | def opcode_115(self, oparg):
710 | # define POP_JUMP_IF_TRUE 115
711 | a = self.stack.pop()
712 | if a:
713 | self.frame.index = oparg
714 |
715 | def opcode_116(self, oparg):
716 | # define LOAD_GLOBAL 116
717 | name = self.co_names[oparg]
718 | if name in self.global_:
719 | value = self.global_[name]
720 | else:
721 | value = self.builtin[name]
722 | self.stack.push(value)
723 |
724 | def opcode_119(self, oparg):
725 | # define CONTINUE_LOOP 119
726 | code = "CONTINUE_LOOP"
727 | raise RuntimeError("使用到未实现的字节码:"+code)
728 |
729 | def opcode_120(self, oparg):
730 | # define SETUP_LOOP 120
731 | p = len(self.stack)
732 | self.blocks.push(p) # 将当前运行时栈长度压入 blocks 栈
733 | self.forend = self.frame.index + oparg
734 |
735 | def opcode_121(self, oparg):
736 | # define SETUP_EXCEPT 121
737 | code = "SETUP_EXCEPT"
738 | raise RuntimeError("使用到未实现的字节码:"+code)
739 |
740 | def opcode_122(self, oparg):
741 | # define SETUP_FINALLY 122
742 | code = "SETUP_FINALLY"
743 | raise RuntimeError("使用到未实现的字节码:"+code)
744 |
745 | def opcode_124(self, oparg):
746 | # define LOAD_FAST 124
747 | name = self.co_varnames[oparg]
748 | try:
749 | value = self.dict[self.co_varnames[oparg]]
750 | except KeyError as e:
751 | raise TypeError("missing " + name)
752 | self.stack.push(value)
753 |
754 | def opcode_125(self, oparg):
755 | # define STORE_FAST 125
756 | name = self.co_varnames[oparg]
757 | value = self.stack.pop()
758 | self.dict[name] = value
759 |
760 | def opcode_126(self, oparg):
761 | # define DELETE_FAST 126
762 | code = "DELETE_FAST"
763 | raise RuntimeError("使用到未实现的字节码:"+code)
764 |
765 | def opcode_127(self, oparg):
766 | # define STORE_ANNOTATION 127
767 | code = "STORE_ANNOTATION"
768 | raise RuntimeError("使用到未实现的字节码:"+code)
769 |
770 | def opcode_130(self, oparg):
771 | # define RAISE_VARARGS 130
772 | code = "RAISE_VARARGS"
773 | raise RuntimeError("使用到未实现的字节码:"+code)
774 |
775 | def opcode_131(self, oparg):
776 | # define CALL_FUNCTION 131
777 | args = []
778 |
779 | for _ in range(oparg):
780 | args.append(self.stack.pop())
781 |
782 | func = self.stack.pop()
783 | if callable(func):
784 | res = func(*args[::-1])
785 | self.stack.push(res)
786 | elif(isinstance(func, Function)):
787 | frame = new_frame(func)
788 | if oparg > frame.co_argcount:
789 | raise TypeError(
790 | f"{frame.co_name}() takes {frame.co_argcount} positional \
791 | arguments but {oparg} were given")
792 |
793 | if oparg < frame.co_argcount:
794 | raise TypeError(
795 | f"{frame.co_name}() missing {frame.co_argcount - oparg} \
796 | required positional arguments: "
797 | + ",".join(frame.co_varnames[oparg:]))
798 |
799 | for name, value in zip(func.varnames, args[::-1]):
800 | frame.dict[name] = value
801 |
802 | frames.append(frame)
803 | run(frame)
804 | frames.pop()
805 | else:
806 | raise RuntimeError("有些事情没有考虑到")
807 |
808 | def opcode_132(self, oparg):
809 | # define MAKE_FUNCTION 132
810 | name = self.stack.pop()
811 | mycode = self.stack.pop()
812 | f = Function(name, mycode)
813 | for i in f.freevars:
814 | f.dict[i] = self.dict[i]
815 | self.stack.push(f)
816 |
817 | def opcode_133(self, oparg):
818 | # define BUILD_SLICE 133
819 | args = []
820 | for _ in range(oparg):
821 | args.append(self.stack.pop())
822 | value = slice(*args[::-1])
823 | self.stack.push(value)
824 |
825 | def opcode_135(self, oparg):
826 | # define LOAD_CLOSURE 135
827 | key = self.co_cellvars[oparg]
828 | value = self.dict[key]
829 | self.stack.push(value)
830 |
831 | def opcode_136(self, oparg):
832 | # define LOAD_DEREF 136
833 | cell = self.co_freevars[oparg]
834 | value = self.dict[cell]
835 | self.stack.push(value)
836 |
837 | def opcode_137(self, oparg):
838 | # define STORE_DEREF 137
839 | value = self.stack.pop()
840 | key = self.co_cellvars[oparg]
841 | self.dict[key] = value
842 |
843 | def opcode_138(self, oparg):
844 | # define DELETE_DEREF 138
845 | code = "DELETE_DEREF"
846 | raise RuntimeError("使用到未实现的字节码:"+code)
847 |
848 | def opcode_141(self, oparg):
849 | # define CALL_FUNCTION_KW 141
850 | code = "CALL_FUNCTION_KW"
851 | raise RuntimeError("使用到未实现的字节码:"+code)
852 |
853 | def opcode_142(self, oparg):
854 | # define CALL_FUNCTION_EX 142
855 | code = "CALL_FUNCTION_EX"
856 | raise RuntimeError("使用到未实现的字节码:"+code)
857 |
858 | def opcode_143(self, oparg):
859 | # define SETUP_WITH 143
860 | code = "SETUP_WITH"
861 | raise RuntimeError("使用到未实现的字节码:"+code)
862 |
863 | def opcode_144(self, oparg):
864 | """计算下一条字节码的参数"""
865 | # define EXTENDED_ARG 144
866 | oldoparg = oparg
867 | oparg = self.frame.co_code[self.frame.index+1]
868 | oparg |= oldoparg << 8
869 | self.frame.co_code[self.frame.index+1] = oparg
870 |
871 | def opcode_145(self, oparg):
872 | # define LIST_APPEND 145
873 | v = self.stack.pop()
874 | list_ = self.stack.peek(oparg)
875 | list_.append(v)
876 |
877 | def opcode_146(self, oparg):
878 | # define SET_ADD 146
879 | code = "SET_ADD"
880 | raise RuntimeError("使用到未实现的字节码:"+code)
881 |
882 | def opcode_147(self, oparg):
883 | # define MAP_ADD 147
884 | key = self.stack.pop()
885 | value = self.stack.pop()
886 | map_ = self.stack.peek(oparg)
887 | map_[key] = value
888 |
889 | def opcode_148(self, oparg):
890 | # define LOAD_CLASSDEREF 148
891 | code = "LOAD_CLASSDEREF"
892 | raise RuntimeError("使用到未实现的字节码:"+code)
893 |
894 | def opcode_149(self, oparg):
895 | # define BUILD_LIST_UNPACK 149
896 | code = "BUILD_LIST_UNPACK"
897 | raise RuntimeError("使用到未实现的字节码:"+code)
898 |
899 | def opcode_150(self, oparg):
900 | # define BUILD_MAP_UNPACK 150
901 | code = "BUILD_MAP_UNPACK"
902 | raise RuntimeError("使用到未实现的字节码:"+code)
903 |
904 | def opcode_151(self, oparg):
905 | # define BUILD_MAP_UNPACK_WITH_CALL 151
906 | code = "BUILD_MAP_UNPACK_WITH_CALL"
907 | raise RuntimeError("使用到未实现的字节码:"+code)
908 |
909 | def opcode_152(self, oparg):
910 | # define BUILD_TUPLE_UNPACK 152
911 | code = "BUILD_TUPLE_UNPACK"
912 | raise RuntimeError("使用到未实现的字节码:"+code)
913 |
914 | def opcode_153(self, oparg):
915 | # define BUILD_SET_UNPACK 153
916 | code = "BUILD_SET_UNPACK"
917 | raise RuntimeError("使用到未实现的字节码:"+code)
918 |
919 | def opcode_154(self, oparg):
920 | # define SETUP_ASYNC_WITH 154
921 | code = "SETUP_ASYNC_WITH"
922 | raise RuntimeError("使用到未实现的字节码:"+code)
923 |
924 | def opcode_155(self, oparg):
925 | # define FORMAT_VALUE 155
926 | code = "FORMAT_VALUE"
927 | raise RuntimeError("使用到未实现的字节码:"+code)
928 |
929 | def opcode_156(self, oparg):
930 | # define BUILD_CONST_KEY_MAP 156
931 | keys = self.stack.pop()
932 | values = []
933 | for _ in range(oparg):
934 | t = self.stack.pop()
935 | values.append(t)
936 | values = values[::-1]
937 | res = dict(zip(keys, values))
938 | self.stack.push(res)
939 |
940 | def opcode_157(self, oparg):
941 | # define BUILD_STRING 157
942 | code = "BUILD_STRING"
943 | raise RuntimeError("使用到未实现的字节码:"+code)
944 |
945 | def opcode_158(self, oparg):
946 | # define BUILD_TUPLE_UNPACK_WITH_CALL 158
947 | code = "BUILD_TUPLE_UNPACK_WITH_CALL"
948 | raise RuntimeError("使用到未实现的字节码:"+code)
949 |
950 | def opcode_257(self, oparg):
951 | # define EXCEPT_HANDLER 25
952 | code = "EXCEPT_HANDLER"
953 | raise RuntimeError("使用到未实现的字节码:"+code)
954 |
955 |
956 | def run(f):
957 | run_code = OpCode(f)
958 | co_code = f.co_code
959 | while True:
960 | code = str(co_code[f.index])
961 | oparg = int(co_code[f.index+1])
962 | f.index += 2
963 | # import time
964 | # time.sleep(0.2)
965 | # print("下一个字节码的地址是",f.index)
966 | # print(run_code.opcode_dict[code]," ",oparg)
967 | func = getattr(run_code, "opcode_"+code)
968 | if func:
969 | func(oparg)
970 | if f.index == len(co_code) or run_code.if_return is True:
971 | break
972 |
--------------------------------------------------------------------------------
/csandbox.py:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 | from copcode import (Function, new_frame, frames, run)
4 |
5 |
6 | def init():
7 | assert len(sys.argv) == 2 and sys.argv[1].endswith(".py")
8 | source = open(sys.argv[1]).read()
9 | co = compile(source, sys.argv[1], 'exec')
10 | fun = Function(sys.argv[1], co)
11 | frame = new_frame(fun)
12 | return frame
13 |
14 |
15 | def main():
16 | frame = init()
17 | frames.append(frame)
18 | run(frame)
19 | frames.pop()
20 |
21 |
22 | if __name__ == '__main__':
23 | main()
24 |
--------------------------------------------------------------------------------
/frame.py:
--------------------------------------------------------------------------------
1 | from stack import stack
2 | from g import builtin, global_
3 | import copy
4 |
5 |
6 | class MyFrame:
7 | def __init__(self, co):
8 | """dict 是保存 局部变量的,不要误认为是 f.local 了
9 | 它在新的 frame 中和 f.global 是相同的.
10 | 不要问我为什么这样处理因为 Python 源码的实现也是这样处理的."""
11 | self.co_consts = co.consts
12 | self.co_cellvars = co.cellvars
13 | self.co_freevars = co.freevars
14 | self.co_name = co.name
15 | self.co_names = co.names
16 | self.co_nlocals = co.nlocals
17 | self.co_argcount = co.argcount
18 | self.co_varnames = co.varnames
19 | self.stack = stack(size=co.stacksize)
20 | self.global_ = None
21 | self.local = None
22 | self.bulitin = None
23 | self.dict = copy.deepcopy(co.dict)
24 | self.index = None
25 | self.co_code = self.code_to_int(co.code)
26 | self.blocks = stack(size=20) # python 中块级操作的堆栈.方便运行时堆栈的恢复
27 |
28 | def code_to_int(self, code):
29 | """将 co.co_code 中的 bytes 转为 [int]."""
30 | return [int(x) for x in code]
31 |
32 |
33 | def new_frame(co_code):
34 | f = MyFrame(co_code)
35 | f.global_ = global_
36 | f.local = global_
37 | f.builtin = builtin
38 | f.index = 0
39 | return f
40 |
--------------------------------------------------------------------------------
/function.py:
--------------------------------------------------------------------------------
1 | class Function:
2 | def __init__(self, name, co_code):
3 | self.name = name
4 | self.code = co_code.co_code
5 | self.consts = co_code.co_consts
6 | self.cellvars = co_code.co_cellvars
7 | self.freevars = co_code.co_freevars
8 | self.names = co_code.co_names
9 | self.nlocals = co_code.co_nlocals
10 | self.argcount = co_code.co_argcount
11 | self.varnames = co_code.co_varnames
12 | self.stacksize = co_code.co_stacksize
13 | self.dict = {}
14 |
15 | def __repr__(self):
16 | return f""
17 |
--------------------------------------------------------------------------------
/g.py:
--------------------------------------------------------------------------------
1 | global_ = {}
2 | builtin = {"print": print,
3 | "max": max,
4 | "sum": sum,
5 | "len": len,
6 | "range": range,
7 | 'hash': hash,
8 | "__name__": "__main__",
9 | "abs": abs,
10 | "all": all,
11 | "any": any,
12 | "bin": bin,
13 | "chr": chr,
14 | "divmod": divmod,
15 | "format": format,
16 | "hex": hex,
17 | "input": input,
18 | "iter": iter,
19 | "len": len,
20 | "max": max,
21 | "min": min,
22 | "next": next,
23 | "oct": oct,
24 | "ord": ord,
25 | "pow": pow,
26 | "repr": repr,
27 | "round": round,
28 | "sorted": sorted,
29 | "None": None,
30 | "False": False,
31 | "True": True,
32 | "bool": bool,
33 | "bytes": bytes,
34 | "complex": complex,
35 | "dict": dict,
36 | "enumerate": enumerate,
37 | "filter": filter,
38 | "float": float,
39 | "frozenset": frozenset,
40 | "int": int,
41 | "list": list,
42 | "map": map,
43 | "set": set,
44 | "slice": slice,
45 | "str": str,
46 | "zip": zip,
47 | "copyright": "来自于copie的沙盒"
48 | }
49 |
--------------------------------------------------------------------------------
/opcode:
--------------------------------------------------------------------------------
1 | # Python3.6.5 的字节码
2 | #define POP_TOP 1
3 | #define ROT_TWO 2
4 | #define ROT_THREE 3
5 | #define DUP_TOP 4
6 | #define DUP_TOP_TWO 5
7 | #define NOP 9
8 | #define UNARY_POSITIVE 10
9 | #define UNARY_NEGATIVE 11
10 | #define UNARY_NOT 12
11 | #define UNARY_INVERT 15
12 | #define BINARY_MATRIX_MULTIPLY 16
13 | #define INPLACE_MATRIX_MULTIPLY 17
14 | #define BINARY_POWER 19
15 | #define BINARY_MULTIPLY 20
16 | #define BINARY_MODULO 22
17 | #define BINARY_ADD 23
18 | #define BINARY_SUBTRACT 24
19 | #define BINARY_SUBSCR 25
20 | #define BINARY_FLOOR_DIVIDE 26
21 | #define BINARY_TRUE_DIVIDE 27
22 | #define INPLACE_FLOOR_DIVIDE 28
23 | #define INPLACE_TRUE_DIVIDE 29
24 | #define GET_AITER 50
25 | #define GET_ANEXT 51
26 | #define BEFORE_ASYNC_WITH 52
27 | #define INPLACE_ADD 55
28 | #define INPLACE_SUBTRACT 56
29 | #define INPLACE_MULTIPLY 57
30 | #define INPLACE_MODULO 59
31 | #define STORE_SUBSCR 60
32 | #define DELETE_SUBSCR 61
33 | #define BINARY_LSHIFT 62
34 | #define BINARY_RSHIFT 63
35 | #define BINARY_AND 64
36 | #define BINARY_XOR 65
37 | #define BINARY_OR 66
38 | #define INPLACE_POWER 67
39 | #define GET_ITER 68
40 | #define GET_YIELD_FROM_ITER 69
41 | #define PRINT_EXPR 70
42 | #define LOAD_BUILD_CLASS 71
43 | #define YIELD_FROM 72
44 | #define GET_AWAITABLE 73
45 | #define INPLACE_LSHIFT 75
46 | #define INPLACE_RSHIFT 76
47 | #define INPLACE_AND 77
48 | #define INPLACE_XOR 78
49 | #define INPLACE_OR 79
50 | #define BREAK_LOOP 80
51 | #define WITH_CLEANUP_START 81
52 | #define WITH_CLEANUP_FINISH 82
53 | #define RETURN_VALUE 83
54 | #define IMPORT_STAR 84
55 | #define SETUP_ANNOTATIONS 85
56 | #define YIELD_VALUE 86
57 | #define POP_BLOCK 87
58 | #define END_FINALLY 88
59 | #define POP_EXCEPT 89
60 | #define HAVE_ARGUMENT 90
61 | #define STORE_NAME 90
62 | #define DELETE_NAME 91
63 | #define UNPACK_SEQUENCE 92
64 | #define FOR_ITER 93
65 | #define UNPACK_EX 94
66 | #define STORE_ATTR 95
67 | #define DELETE_ATTR 96
68 | #define STORE_GLOBAL 97
69 | #define DELETE_GLOBAL 98
70 | #define LOAD_CONST 100
71 | #define LOAD_NAME 101
72 | #define BUILD_TUPLE 102
73 | #define BUILD_LIST 103
74 | #define BUILD_SET 104
75 | #define BUILD_MAP 105
76 | #define LOAD_ATTR 106
77 | #define COMPARE_OP 107
78 | #define IMPORT_NAME 108
79 | #define IMPORT_FROM 109
80 | #define JUMP_FORWARD 110
81 | #define JUMP_IF_FALSE_OR_POP 111
82 | #define JUMP_IF_TRUE_OR_POP 112
83 | #define JUMP_ABSOLUTE 113
84 | #define POP_JUMP_IF_FALSE 114
85 | #define POP_JUMP_IF_TRUE 115
86 | #define LOAD_GLOBAL 116
87 | #define CONTINUE_LOOP 119
88 | #define SETUP_LOOP 120
89 | #define SETUP_EXCEPT 121
90 | #define SETUP_FINALLY 122
91 | #define LOAD_FAST 124
92 | #define STORE_FAST 125
93 | #define DELETE_FAST 126
94 | #define STORE_ANNOTATION 127
95 | #define RAISE_VARARGS 130
96 | #define CALL_FUNCTION 131
97 | #define MAKE_FUNCTION 132
98 | #define BUILD_SLICE 133
99 | #define LOAD_CLOSURE 135
100 | #define LOAD_DEREF 136
101 | #define STORE_DEREF 137
102 | #define DELETE_DEREF 138
103 | #define CALL_FUNCTION_KW 141
104 | #define CALL_FUNCTION_EX 142
105 | #define SETUP_WITH 143
106 | #define EXTENDED_ARG 144
107 | #define LIST_APPEND 145
108 | #define SET_ADD 146
109 | #define MAP_ADD 147
110 | #define LOAD_CLASSDEREF 148
111 | #define BUILD_LIST_UNPACK 149
112 | #define BUILD_MAP_UNPACK 150
113 | #define BUILD_MAP_UNPACK_WITH_CALL 151
114 | #define BUILD_TUPLE_UNPACK 152
115 | #define BUILD_SET_UNPACK 153
116 | #define SETUP_ASYNC_WITH 154
117 | #define FORMAT_VALUE 155
118 | #define BUILD_CONST_KEY_MAP 156
119 | #define BUILD_STRING 157
120 | #define BUILD_TUPLE_UNPACK_WITH_CALL 158
121 | #define EXCEPT_HANDLER 257
--------------------------------------------------------------------------------
/stack.py:
--------------------------------------------------------------------------------
1 | class stack:
2 | def __init__(self,*,size):
3 | self.size = size
4 | self.stack = []
5 |
6 | def push(self, value):
7 | assert len(self.stack)+1 <= self.size
8 | # print(self.stack)
9 | self.stack.append(value)
10 |
11 | def top(self):
12 | assert len(self.stack) != 0
13 | return self.stack[-1]
14 |
15 | def second(self):
16 | assert len(self.stack)-1 != 0
17 | return self.stack[-2]
18 |
19 | def pop(self):
20 | # assert len(self.stack) != 0
21 | return self.stack.pop()
22 |
23 | def set_value(self, index, value):
24 | assert len(self.stack)+1 <= self.size
25 | self.stack[index] = value
26 |
27 | def set_top(self, value):
28 | assert len(self.stack) != 0
29 | self.stack[-1] = value
30 |
31 | def set_second(self, value):
32 | assert len(self.stack)-1 != 0
33 | self.stack[-2] = value
34 |
35 | def peek(self,n):
36 | return self.stack[-n]
37 |
38 | def __repr__(self):
39 | return str(self.stack)
40 |
41 | def __len__(self):
42 | return len(self.stack)
--------------------------------------------------------------------------------
/test.py:
--------------------------------------------------------------------------------
1 | import os
2 | import subprocess
3 | path = os.getcwd()+"/test_files/"
4 | test_files = os.listdir(path)
5 | test_files = [path + file_ for file_ in test_files]
6 | print("获取测试所用的文件成功")
7 | for file_name in test_files:
8 | with open(file_name) as file_:
9 | line = file_.readline()
10 | print(line.strip())
11 |
12 | run_code = subprocess.run(
13 | ["python", 'csandbox.py', file_name],
14 | stdout=subprocess.PIPE,
15 | timeout=3
16 | )
17 |
18 | python = subprocess.run(["python", file_name],
19 | stdout=subprocess.PIPE,
20 | timeout=3
21 | )
22 |
23 | if run_code.stdout == python.stdout:
24 | print("成功完成: "+file_name+" 的测试\n")
25 | else:
26 | print(file_name+" 测试失败")
27 | break
28 | else:
29 | print("所有测试文件都测试完毕,没有问题")
30 |
--------------------------------------------------------------------------------
/test_files/test0.py:
--------------------------------------------------------------------------------
1 | """基础数据结构的创建"""
2 | a = "测试1"
3 | b = "测试2"
4 |
5 | # 元组
6 | x = (a, 2, 3, b, 5, 6)
7 | print(x)
8 |
9 | # 字典
10 | x = {1: "测试1", 2: "测试2"}
11 | print(x)
12 | x = {a: "测试1", b: "测试2"}
13 | print(x)
14 |
15 | # 列表
16 | x = [1, 2, 3, a, 5, b, 34]
17 | print(x)
18 |
19 | # 切片
20 | x = [1, 2, 3, a, 5, b, 34]
21 | print(x[1])
22 | print(x[3:5])
23 | print(x[3:6:2])
24 | x[1:2] = [a, b]
25 | print(x)
26 |
--------------------------------------------------------------------------------
/test_files/test1.py:
--------------------------------------------------------------------------------
1 | """简单测试文件"""
2 | a = [1, 2, 3, 4, 5, 6, 7, 8]
3 | x = a[:2]
4 | y = a[1]
5 | print(a)
6 | print(x)
7 | print(y)
8 |
--------------------------------------------------------------------------------
/test_files/test2.py:
--------------------------------------------------------------------------------
1 | """函数测试文件"""
2 | a = 100
3 |
4 |
5 | def x():
6 | a = 111
7 | print(a)
8 |
9 |
10 | def y():
11 | global a
12 | a = 222
13 | print(a)
14 |
15 |
16 | print(a)
17 | x()
18 | print(a)
19 | y()
20 | print(a)
21 |
--------------------------------------------------------------------------------
/test_files/test3.py:
--------------------------------------------------------------------------------
1 | """运算符测试文件"""
2 | a = 100
3 | b = 124
4 |
5 |
6 | def operator():
7 | c = a + b
8 | print(c)
9 | print("加法运算结束\n")
10 |
11 | c = a - b
12 | print(c)
13 | print("减法运算结束\n")
14 |
15 | c = a * b
16 | print(c)
17 | print("乘法运算结束\n")
18 |
19 | c = a / b
20 | print(c)
21 | print("真除除法运算结束\n")
22 |
23 | c = a // b
24 | print(c)
25 | print("除法运算结束")
26 |
27 | c = a ** b
28 | print(c)
29 | print("乘方运算结束")
30 |
31 |
32 | operator()
33 |
34 | a = 21
35 | b = 10
36 | c = 0
37 |
38 | c = a + b
39 | print("1 - c 的值为:", c)
40 |
41 | c = a - b
42 | print("2 - c 的值为:", c)
43 |
44 | c = a * b
45 | print("3 - c 的值为:", c)
46 |
47 | c = a / b
48 | print("4 - c 的值为:", c)
49 |
50 | c = a % b
51 | print("5 - c 的值为:", c)
52 |
53 | # 修改变量 a 、b 、c
54 | a = 2
55 | b = 3
56 | c = a**b
57 | print("6 - c 的值为:", c)
58 |
59 | a = 10
60 | b = 5
61 | c = a//b
62 | print("7 - c 的值为:", c)
63 |
64 |
65 | a = 21
66 | b = 10
67 | c = 0
68 |
69 | c = a + b
70 | print("1 - c 的值为:", c)
71 |
72 | c += a
73 | print("2 - c 的值为:", c)
74 |
75 | c *= a
76 | print("3 - c 的值为:", c)
77 |
78 | c /= a
79 | print("4 - c 的值为:", c)
80 |
81 | c = 2
82 | c %= a
83 | print("5 - c 的值为:", c)
84 |
85 | c **= a
86 | print("6 - c 的值为:", c)
87 |
88 | c //= a
89 | print("7 - c 的值为:", c)
90 |
--------------------------------------------------------------------------------
/test_files/test4.py:
--------------------------------------------------------------------------------
1 | """getattr 测试"""
2 |
3 | a = 100 + 2389j
4 | print(a.real)
5 | print(a.imag)
6 |
--------------------------------------------------------------------------------
/test_files/test5.py:
--------------------------------------------------------------------------------
1 | """用于测试比较运算符"""
2 | # 小于等于 le
3 | a = (100 <= 1000)
4 | print(a)
5 | a = (10000 <= 100)
6 | print(a)
7 | a = (100 <= 100)
8 | print(a)
9 |
10 | # 小于 lt
11 | a = (100 < 1000)
12 | print(a)
13 | a = (10000 < 100)
14 | print(a)
15 | a = (100 < 100)
16 | print(a)
17 |
18 | # 大于等于 ge
19 | a = (100 >= 1000)
20 | print(a)
21 | a = (10000 >= 100)
22 | print(a)
23 | a = (100 >= 100)
24 | print(a)
25 |
26 | # 大于 gt
27 | a = (100 > 1000)
28 | print(a)
29 | a = (10000 > 100)
30 | print(a)
31 | a = (100 > 100)
32 | print(a)
33 |
34 | # 等于 eq
35 | a = (100 == 1000)
36 | print(a)
37 | a = (10000 == 100)
38 | print(a)
39 | a = (100 == 100)
40 | print(a)
41 |
42 | # 不等于 ne
43 | a = (100 != 1000)
44 | print(a)
45 | a = (10000 != 100)
46 | print(a)
47 | a = (100 != 100)
48 | print(a)
49 |
50 | # in contains
51 | a = [1, 2, 3, 4] in [1, 2, 3, 4, 5]
52 | print(a)
53 | a = [1, 2, 3, 4, 5, 6] in [1, 2, 3, 4]
54 |
55 | # not in
56 | a = [1, 2, 3, 4] not in [1, 2, 3, 4, 5]
57 | print(a)
58 | a = [1, 2, 3, 4, 5, 6] not in [1, 2, 3, 4]
59 |
60 | # is
61 | a = None is None
62 | print(a)
63 | a = 1 is None
64 | print(a)
65 |
66 | # is_not
67 | a = None is not None
68 | print(a)
69 | a = 1 is not None
70 | print(a)
71 |
72 | # and
73 | x = True and True
74 | print(x)
75 | x = False and True
76 | print(x)
77 |
78 | # or
79 | x = True or False
80 | print(x)
81 | x = False or False
82 | print(x)
83 |
84 |
85 | a = 10
86 | b = 20
87 |
88 | if (a and b):
89 | print("1 - 变量 a 和 b 都为 true")
90 | else:
91 | print("1 - 变量 a 和 b 有一个不为 true")
92 |
93 | if (a or b):
94 | print("2 - 变量 a 和 b 都为 true,或其中一个变量为 true")
95 | else:
96 | print("2 - 变量 a 和 b 都不为 true")
97 |
98 | # 修改变量 a 的值
99 | a = 0
100 | if (a and b):
101 | print("3 - 变量 a 和 b 都为 true")
102 | else:
103 | print("3 - 变量 a 和 b 有一个不为 true")
104 |
105 | if (a or b):
106 | print("4 - 变量 a 和 b 都为 true,或其中一个变量为 true")
107 | else:
108 | print("4 - 变量 a 和 b 都不为 true")
109 |
110 | if not(a and b):
111 | print("5 - 变量 a 和 b 都为 false,或其中一个变量为 false")
112 | else:
113 | print("5 - 变量 a 和 b 都为 true")
114 |
115 |
116 | a = 10
117 | b = 20
118 | lists = [1, 2, 3, 4, 5]
119 |
120 | if (a in lists):
121 | print("1 - 变量 a 在给定的列表中 list 中")
122 | else:
123 | print("1 - 变量 a 不在给定的列表中 list 中")
124 |
125 | if (b not in lists):
126 | print("2 - 变量 b 不在给定的列表中 list 中")
127 | else:
128 | print("2 - 变量 b 在给定的列表中 list 中")
129 |
130 | # 修改变量 a 的值
131 | a = 2
132 | if (a in lists):
133 | print("3 - 变量 a 在给定的列表中 list 中")
134 | else:
135 | print("3 - 变量 a 不在给定的列表中 list 中")
136 |
--------------------------------------------------------------------------------
/test_files/test6.py:
--------------------------------------------------------------------------------
1 | """if 的测试文件"""
2 |
3 | if 100 > 1000:
4 | print(True)
5 | else:
6 | print(False)
7 |
8 | if 100 < 1000:
9 | print(True)
10 | else:
11 | print(False)
12 |
13 | if 100 > 1000:
14 | print("测试1")
15 | elif 100 > 99:
16 | print("测试2")
17 | else:
18 | print("测试3")
19 |
20 | if 100 == 1000:
21 | print("测试1")
22 | elif 2000 == 100:
23 | print("测试2")
24 | else:
25 | print("测试3")
26 |
27 | if 100 < 1000:
28 | print("测试1")
29 | elif 2000 == 100:
30 | print("测试2")
31 | else:
32 | print("测试3")
33 |
34 | if not None:
35 | print("测试1")
36 | else:
37 | print("测试2")
38 |
39 | if None is not None:
40 | print("测试1")
41 | else:
42 | print("测试2")
43 |
44 | a = 100
45 | if a >= 0:
46 | print(a)
47 | else:
48 | print(-a)
49 |
50 | a = 21
51 | b = 10
52 | c = 0
53 |
54 | if a == b:
55 | print("1 - a 等于 b")
56 | else:
57 | print("1 - a 不等于 b")
58 |
59 | if (a != b):
60 | print("2 - a 不等于 b")
61 | else:
62 | print("2 - a 等于 b")
63 |
64 | if (a < b):
65 | print("3 - a 小于 b")
66 | else:
67 | print("3 - a 大于等于 b")
68 |
69 | if (a > b):
70 | print("4 - a 大于 b")
71 | else:
72 | print("4 - a 小于等于 b")
73 |
74 | # 修改变量 a 和 b 的值
75 | a = 5
76 | b = 20
77 | if (a <= b):
78 | print("5 - a 小于等于 b")
79 | else:
80 | print("5 - a 大于 b")
81 |
82 | if (b >= a):
83 | print("6 - b 大于等于 a")
84 | else:
85 | print("6 - b 小于 a")
86 |
--------------------------------------------------------------------------------
/test_files/test7.py:
--------------------------------------------------------------------------------
1 | """for 的测试文件"""
2 |
3 | for x in [1, 2, 3, 4, 5, 6, 6, 7, 5]:
4 | print(x)
5 |
6 | for x in [1, 2, 3, 4, 5, 6, 6, 7, 5]:
7 | print(x)
8 | else:
9 | print("正常结束")
10 |
11 |
12 | for x in [1, 2, 3, 4, 5, 6, 7]:
13 | if x == 4:
14 | print("continue")
15 | continue
16 | if x == 5:
17 | break
18 | print(x)
19 | else:
20 | print("正常结束")
21 |
22 |
23 | def bubble_sort(nums):
24 | for i in range(len(nums) - 1): # 这个循环负责设置冒泡排序进行的次数
25 | for j in range(len(nums) - i - 1): # j为列表下标
26 | if nums[j] > nums[j + 1]:
27 | nums[j], nums[j + 1] = nums[j + 1], nums[j]
28 | return nums
29 |
30 |
31 | print(bubble_sort([45, 32, 8, 33, 12, 22, 19, 97]))
32 |
--------------------------------------------------------------------------------
/test_files/test8.py:
--------------------------------------------------------------------------------
1 | """位运算测试文件"""
2 |
3 | a = 296
4 | b = 46
5 | b |= a << 8
6 | print(b)
7 |
8 | b &= a >> 8
9 | print(b)
10 |
11 | a = 60 # 60 = 0011 1100
12 | b = 13 # 13 = 0000 1101
13 | print('a=', a, ':', bin(a), 'b=', b, ':', bin(b))
14 | c = 0
15 |
16 | c = a & b # 12 = 0000 1100
17 | print("result of AND is ", c, ':', bin(c))
18 |
19 | c = a | b # 61 = 0011 1101
20 | print("result of OR is ", c, ':', bin(c))
21 |
22 | c = a ^ b # 49 = 0011 0001
23 | print("result of EXOR is ", c, ':', bin(c))
24 |
25 | c = ~a # -61 = 1100 0011
26 | print("result of COMPLEMENT is ", c, ':', bin(c))
27 |
28 | c = a << 2 # 240 = 1111 0000
29 | print("result of LEFT SHIFT is ", c, ':', bin(c))
30 |
31 | c = a >> 2 # 15 = 0000 1111
32 | print("result of RIGHT SHIFT is ", c, ':', bin(c))
33 |
--------------------------------------------------------------------------------
/test_files/test9.py:
--------------------------------------------------------------------------------
1 | """各种排序算法的综合测试"""
2 |
3 |
4 | def pail_sort(my_list):
5 |
6 | max_num = max(my_list)
7 | min_num = min(my_list)
8 |
9 | Y_list = list()
10 |
11 | for i in range(min_num, max_num+1):
12 | zhao_list = [i, 0]
13 | Y_list.append(zhao_list)
14 | for m in my_list:
15 | for Y in Y_list:
16 | if Y[0] == m:
17 | Y[1] += 1
18 |
19 | result = list()
20 |
21 | for n in Y_list:
22 | for t in range(0, n[1]):
23 | result.append(n[0])
24 |
25 | return result
26 |
27 |
28 | def main():
29 |
30 | Y_list = [100, 54, 26, 63, 12, 22, 93, 17, 12, 77, 31, 44, 55, 20]
31 | print("简单桶排序之前的序列:", Y_list)
32 | print("简单桶排序之后的序列:", pail_sort(Y_list))
33 |
34 |
35 | if __name__ == '__main__':
36 | main()
37 |
38 |
39 | def bubble_sort(my_list):
40 |
41 | N = len(my_list)
42 | # 循环的次数
43 | circle_num = N-1
44 |
45 | while circle_num > 0:
46 | # 初始的游标值
47 | index_value = 0
48 |
49 | while index_value < circle_num:
50 | if my_list[index_value] < my_list[index_value+1]:
51 | pass
52 | else:
53 | my_list[index_value], my_list[index_value +1] = my_list[index_value + 1], my_list[index_value]
54 |
55 | # 游标右移一个单位
56 | index_value += 1
57 |
58 | circle_num -= 1
59 |
60 | print("冒泡排序之后的序列:", my_list)
61 | return my_list
62 |
63 |
64 | def main():
65 | Y_list = [100, 54, 26, 63, 12, 22, 93, 17, 12, 77, 31, 44, 55, 20]
66 | print("冒泡排序之前的序列:", Y_list)
67 | bubble_sort(Y_list)
68 |
69 |
70 | if __name__ == '__main__':
71 | main()
72 |
73 |
74 | def selection_sort(my_list):
75 |
76 | # N为列表元素的个数
77 | N = len(my_list)
78 |
79 | circle_num = 0
80 |
81 | # 需要进行N-1次循环
82 | while circle_num < N:
83 |
84 | # 每次循环开始的游标索引值 为 circle_num , 结束的索引值为N-1
85 | for m in range(circle_num, N):
86 | if my_list[circle_num] <= my_list[m]:
87 | pass
88 | else:
89 | my_list[circle_num], my_list[m] = my_list[m], my_list[circle_num]
90 |
91 | circle_num += 1
92 |
93 | print("选择排序之后的序列:", my_list)
94 |
95 |
96 | def main():
97 | Y_list = [100, 54, 26, 63, 12, 22, 93, 17, 12, 77, 31, 44, 55, 20]
98 | print("选择排序之前的序列:", Y_list)
99 | selection_sort(Y_list)
100 | pass
101 |
102 |
103 | if __name__ == '__main__':
104 | main()
105 |
106 |
107 | def insert_sort(my_list):
108 | N = len(my_list)
109 | finish_list = list()
110 | f_len = len(finish_list)
111 | finish_list.append(my_list[0])
112 | # circle_num为待插入的值的索引
113 | for circle_num in range(1, N):
114 | for pre in range(0, circle_num):
115 |
116 | # 如果新加入的值比已排序的值小,就把新值加入到 已排序值的前面
117 | if my_list[circle_num] < finish_list[pre]:
118 | finish_list.insert(pre, my_list[circle_num])
119 | break
120 |
121 | # 如果新加入的值比已排序的序列最大的值都大,那么
122 | elif my_list[circle_num] >= finish_list[-1]:
123 | finish_list.append(my_list[circle_num])
124 |
125 | break
126 | # 如果新加入的值 比已排序的某个值大但比 已排序后面的值小
127 | elif my_list[circle_num] >= finish_list[pre] and my_list[circle_num] < finish_list[pre+1]:
128 | finish_list.insert(pre+1, my_list[circle_num])
129 | break
130 | else:
131 | pass
132 |
133 | return finish_list
134 |
135 |
136 | def main():
137 | Y_list = [100, 54, 26, 63, 12, 22, 93, 17, 12, 77, 31, 44, 55, 20]
138 | print("插入排序之前的序列:", Y_list)
139 | insert_sort(Y_list)
140 | print("插入排序之后的序列:", insert_sort(Y_list))
141 |
142 |
143 | if __name__ == '__main__':
144 | main()
145 |
146 |
147 | def q_sort(my_list, left, right):
148 |
149 | # 设置左右指针
150 | left_point = left
151 | right_point = right
152 | stand_num = left
153 | if left > right:
154 | return
155 |
156 | while left_point != right_point:
157 |
158 | # 先移动右指针,如果遇到 比基准值更小 的值,就停下来
159 |
160 | while (my_list[right_point] >= my_list[stand_num]) and (left_point < right_point):
161 | right_point -= 1
162 |
163 | # 再移动左指针,如果遇到比基准值更大的值,就停下来
164 |
165 | while (my_list[left_point] < my_list[stand_num]) and (left_point < right_point):
166 | left_point += 1
167 |
168 | # 找到了双方可交换的点后, 开始交换
169 |
170 | my_list[left_point], my_list[right_point] = my_list[right_point], my_list[left_point]
171 |
172 | # 将基准点 与 指针相遇的点互换
173 |
174 | if left_point == right_point:
175 | my_list[stand_num], my_list[left_point] = my_list[left_point], my_list[stand_num]
176 |
177 | q_sort(my_list, left, left_point-1)
178 | q_sort(my_list, right_point+1, right)
179 |
180 | return (my_list)
181 |
182 |
183 | def quick_sort(out_of_order):
184 | end = len(out_of_order) - 1
185 | start = 0
186 | q_sort(out_of_order, start, end)
187 | # print("排列完成的数组:",out_of_order)
188 |
189 | return out_of_order
190 |
191 |
192 | def main():
193 | Y_list = [100, 54, 26, 63, 12, 22, 93, 17, 12, 77, 31, 44, 55, 20]
194 | print("快速排序之前的序列:", Y_list)
195 | print("快速排序之后的序列:", quick_sort(Y_list))
196 |
197 |
198 | if __name__ == '__main__':
199 | main()
200 |
201 |
202 | # 负责 将列表拆分
203 | def merge_sort(Y_list):
204 |
205 | if len(Y_list) <= 1:
206 | return Y_list
207 |
208 | # 先将未排序的列表进行分组
209 | num = len(Y_list) // 2
210 |
211 | left_list = merge_sort(Y_list[:num])
212 | right_list = merge_sort(Y_list[num:])
213 |
214 | # 将分组的列表交给merge函数, merge负责将列表合并
215 | return merge(left_list, right_list)
216 |
217 |
218 | # 负责将列表合并
219 | def merge(left, right):
220 |
221 | left_point = 0
222 | right_point = 0
223 |
224 | finish_list = list()
225 |
226 | while right_point < len(right) and left_point < len(left):
227 |
228 | if left[left_point] <= right[right_point]:
229 | finish_list.append(left[left_point])
230 | left_point += 1
231 |
232 | else:
233 | finish_list.append(right[right_point])
234 | right_point += 1
235 |
236 | finish_list += left[left_point:]
237 | finish_list += right[right_point:]
238 |
239 | return finish_list
240 |
241 |
242 | def main():
243 | Y_list = [100, 54, 26, 63, 12, 22, 93, 17, 12, 77, 31, 44, 55, 20]
244 | print("归并排序之前的序列:", Y_list)
245 | print("归并排序之后的序列:", merge_sort(Y_list))
246 |
247 |
248 | if __name__ == '__main__':
249 | main()
250 |
251 |
252 | def shell_sort(Y_list):
253 |
254 | gap = len(Y_list)
255 |
256 | while gap >= 0:
257 |
258 | tem_list = list()
259 |
260 | if gap == 0:
261 | return Y_list
262 |
263 | # 将要抽取的值和索引保存到一个 列表里
264 |
265 | for index, value in enumerate(Y_list):
266 | if index % gap == 0:
267 | zhao_list = [index, value]
268 | tem_list.append(zhao_list)
269 |
270 | tem_value_list = list()
271 |
272 | for i in tem_list:
273 | tem_value_list.append(i[1])
274 | tem_value_list = insert_sort(tem_value_list)
275 |
276 | for i, vv in enumerate(tem_value_list):
277 |
278 | tem_list[i][1] = vv
279 |
280 | # 排序好的值 替换 原位置的值
281 | for iv in tem_list:
282 |
283 | Y_list[iv[0]] = iv[1]
284 |
285 | gap = gap // 2
286 |
287 | return Y_list
288 |
289 |
290 | def insert_sort(my_list):
291 | N = len(my_list)
292 | finish_list = list()
293 | f_len = len(finish_list)
294 | finish_list.append(my_list[0])
295 | # circle_num为待插入的值的索引
296 | for circle_num in range(1, N):
297 | for pre in range(0, circle_num):
298 |
299 | # 如果新加入的值比已排序的值小,就把新值加入到 已排序值的前面
300 | if my_list[circle_num] < finish_list[pre]:
301 | finish_list.insert(pre, my_list[circle_num])
302 | break
303 |
304 | # 如果新加入的值比已排序的序列最大的值都大,那么
305 | elif my_list[circle_num] >= finish_list[-1]:
306 | finish_list.append(my_list[circle_num])
307 |
308 | break
309 | # 如果新加入的值 比已排序的某个值大但比 已排序后面的值小
310 | elif my_list[circle_num] >= finish_list[pre] and my_list[circle_num] < finish_list[pre+1]:
311 | finish_list.insert(pre+1, my_list[circle_num])
312 | break
313 | else:
314 | pass
315 |
316 | return finish_list
317 |
318 |
319 | def main():
320 |
321 | Y_list = [100, 54, 26, 63, 12, 22, 93, 17, 12, 77, 31, 44, 55, 20]
322 | print("希尔排序之前的序列:", Y_list)
323 | print("希尔排序之后的序列:", shell_sort(Y_list))
324 |
325 |
326 | if __name__ == '__main__':
327 | main()
328 |
329 |
330 | # 实现快排
331 | def quicksort(nums):
332 | if len(nums) <= 1:
333 | return nums
334 |
335 | # 左子数组
336 | less = []
337 | # 右子数组
338 | greater = []
339 | # 基准数
340 | base = nums.pop()
341 |
342 | # 对原数组进行划分
343 | for x in nums:
344 | if x < base:
345 | less.append(x)
346 | else:
347 | greater.append(x)
348 |
349 | # 递归调用
350 | return quicksort(less) + [base] + quicksort(greater)
351 |
352 |
353 | def main():
354 | nums = [6, 1, 2, 7, 9, 3, 4, 5, 10, 8]
355 | print(quicksort(nums))
356 |
357 | def x(y): return y
358 |
359 |
360 | if __name__ == '__main__':
361 | main()
362 |
--------------------------------------------------------------------------------