diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..c735cbc --- /dev/null +++ b/.editorconfig @@ -0,0 +1,7 @@ +# top-most EditorConfig file +root = true + +# all files +[*] +indent_style = space +indent_size = 4 \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..26d3f99 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +# vscode files +.vscode/ + +# python bytecode +**/__pycache__/ + +# test email infos +Email/pop3.txt +Email/smtp.txt + +# sqlite3 database files +SQL/*.db \ No newline at end of file diff --git a/AsynchronousIO/AiohttpServer.py b/AsynchronousIO/AiohttpServer.py new file mode 100644 index 0000000..7a77c78 --- /dev/null +++ b/AsynchronousIO/AiohttpServer.py @@ -0,0 +1,28 @@ +''' +async web application. +''' + +import asyncio + +from aiohttp import web + +async def index(request): + await asyncio.sleep(0.5) + return web.Response(body=b'

Index

', content_type='text/html') + +async def hello(request): + await asyncio.sleep(0.5) + text = '

hello, %s!

' % request.match_info['name'] + return web.Response(body=text.encode('utf-8'), content_type='text/html') + +async def init(loop): + app = web.Application(loop=loop) + app.router.add_route('GET', '/', index) + app.router.add_route('GET', '/hello/{name}', hello) + srv = await loop.create_server(app.make_handler(), '127.0.0.1', 8000) + print('Server started at http://127.0.0.1:8000...') + return srv + +loop = asyncio.get_event_loop() +loop.run_until_complete(init(loop)) +loop.run_forever() \ No newline at end of file diff --git a/AsynchronousIO/AsyncIoHello.py b/AsynchronousIO/AsyncIoHello.py new file mode 100644 index 0000000..f634e41 --- /dev/null +++ b/AsynchronousIO/AsyncIoHello.py @@ -0,0 +1,14 @@ +import asyncio +import threading + +@asyncio.coroutine +def hello(n): + print(f'hello,world! from {threading.currentThread()}, n = {n}') + r = yield from asyncio.sleep(1) + print(f'hello,again! from {threading.currentThread()}, n = {n}') + +loop = asyncio.get_event_loop() +# execute coroutine +tasks = [hello(1), hello(2)] +loop.run_until_complete(asyncio.wait(tasks)) +loop.close() \ No newline at end of file diff --git a/AsynchronousIO/AsyncIoWget2.py b/AsynchronousIO/AsyncIoWget2.py new file mode 100644 index 0000000..e7a0429 --- /dev/null +++ b/AsynchronousIO/AsyncIoWget2.py @@ -0,0 +1,21 @@ +import asyncio + +async def wget(host): + print('wget %s...' % host) + connect = asyncio.open_connection(host, 80) # connect is a coroutine + reader, writer = await connect + header = 'GET / HTTP/1.0\r\nHost: %s\r\n\r\n' % host + writer.write(header.encode('utf-8')) + await writer.drain() + while True: + line = await reader.readline() + if line == b'\r\n': + break + print('%s header > %s' % (host, line.decode('utf-8').rstrip())) + # Ignore the body, close the socket + writer.close() + +loop = asyncio.get_event_loop() +tasks = [wget(host) for host in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']] +loop.run_until_complete(asyncio.wait(tasks)) +loop.close() \ No newline at end of file diff --git a/AsynchronousIO/AsyncioWget.py b/AsynchronousIO/AsyncioWget.py new file mode 100644 index 0000000..39ba0d2 --- /dev/null +++ b/AsynchronousIO/AsyncioWget.py @@ -0,0 +1,22 @@ +import asyncio + +@asyncio.coroutine +def wget(host): + print('wget %s...' % host) + connect = asyncio.open_connection(host, 80) # connect is a coroutine + reader, writer = yield from connect + header = 'GET / HTTP/1.0\r\nHost: %s\r\n\r\n' % host + writer.write(header.encode('utf-8')) + yield from writer.drain() + while True: + line = yield from reader.readline() + if line == b'\r\n': + break + print('%s header > %s' % (host, line.decode('utf-8').rstrip())) + # Ignore the body, close the socket + writer.close() + +loop = asyncio.get_event_loop() +tasks = [wget(host) for host in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']] +loop.run_until_complete(asyncio.wait(tasks)) +loop.close() \ No newline at end of file diff --git a/AsynchronousIO/CoroutineTest.py b/AsynchronousIO/CoroutineTest.py new file mode 100644 index 0000000..2c3e73d --- /dev/null +++ b/AsynchronousIO/CoroutineTest.py @@ -0,0 +1,22 @@ +def consumer(): + print("hello") + r = '' + while True: + n = yield r # get message through return value of yield + if not n: + return + print('[CONSUMER] Consuming %s...' % n) + r = '200 OK' + +def produce(c): + c.send(None) # start generator, will first call generator, print hello, then run to first yield + n = 0 + while n < 5: + n = n + 1 + print('[PRODUCER] Producing %s...' % n) + r = c.send(n) + print('[PRODUCER] Consumer return: %s' % r) + c.close() # close generator + +c = consumer() +produce(c) \ No newline at end of file diff --git a/Basics/BuiltInFuncs.py b/Basics/BuiltInFuncs.py new file mode 100644 index 0000000..e56bf75 --- /dev/null +++ b/Basics/BuiltInFuncs.py @@ -0,0 +1,427 @@ +# -*- coding: utf-8 -*- + +# test suite +count = 0 +category = "" +def myprint(*args, **kwargs): + global count + count += 1 + print(f"{count} {category} : ", *args, **kwargs) + +def test(s): + global category + category = s + +# abs +test("abs") +myprint(abs(-10)) + +# all any bool +test("all any bool") +myprint(all([]), all(()), all([0, 1]), all([True, False])) +myprint(any([]), any([[]]), any([0, 1]), any([True, False])) +myprint(bool([]), bool([[]]), bool([0, 1]), bool([True, False])) + +class Student: + def __repr__(self) -> str: + return b'asf\xe4\xb8\xad\xe6\x96\x87'.decode("utf-8") + def __bool__(self): + return False + +# ascii +test("ascii repr") +myprint(ascii(Student()), repr(Student())) + +# bin : to 0b10101... binary format string +test("bin") +myprint(bin(-10), bin(0xFFFF), type(bin(1)), f"{100:#b}") + +# class bool : __bool__() return False or __len__() return 0 -> False, else -> True +test("bool") +myprint(bool(Student())) + +# class bytearray([source[, encoding[, errors]]]), mutable version of bytes +test("bytearray") +myprint(bytearray(b"asdf\xff"), type(bytearray())) + +# class bytes([source[, encoding[, errors]]]), immutable version of bytearray +test("bytes") +myprint(bytes(b"asdf\xff"), type(bytes())) + +# callable(object), can call(the class of the object have __call__()) -> True, else -> False, a class is a callable and calling will return a new instance +test("callable") +myprint(callable(int), callable(callable), callable(lambda x : x * x)) + +# chr(i) return a single character string of code point i +# ord(c) inversion of chr, return code point of a single character string +test("chr ord") +myprint(chr(8364), ord(chr(8346))) + +# @classmethod, decorate a method to a class method, will pass the class itself at first argument implicitly +class Person: + @classmethod + def f(cls, *args, **kwargs): + myprint("call function f in calss ", cls.__name__) + def f2(): + pass +test("@classmethod") +Person.f() +myprint(Person.f, Person.f2) + +# class complex +test("complex") +myprint(complex(1, 2), complex("1+2j"), complex()) +myprint(complex(1, 2.5) + complex(1, 3) - complex(1.5, 4)) +myprint(type(complex())) + +class MyComplex: + def __init__(self, a, b): + self._a = a + self._b = b + # if do not have __complex__, will call __float__ __index__ in order + # def __complex__(self): + # return complex(self._a, self._b) + def __float__(self): + return (self._a ** 2 + self._b ** 2) ** 0.5 +myprint(complex(MyComplex(1, 3))) + +# delattr(object, name) : delete attribute +# setattr(object, name, value) +# getattr(object, name[, default]) +# hasattr(object, name) +test("delattr setattr getattr hasattr") +delattr(MyComplex, "__float__") +try: + myprint(complex(MyComplex(1, 3))) +except Exception as e: + myprint(e) + +def special_complex(self): + return complex(self._a, self._b) +setattr(MyComplex, "__complex__", special_complex) +myprint(complex(MyComplex(1, 3))) +myprint(getattr(MyComplex, "__complex__", None) == special_complex) +myprint(hasattr(MyComplex, "justamethod")) + +# calss dict +test("dict") +myprint(dict((x, str(x)) for x in range(10))) + +# dir([object]) : return name list of current domain or specific object +test("dir") +myprint(dir()) +myprint(dir(MyComplex)) +myprint(dir(test)) + +# divmod(a, b) : get (result of division, remainder), (a // b, a % b) for int, and (match.floor(a/b), a % b) for float usually +test("divmod") +myprint(divmod(10.5, 3.1)) + +# enumerate(iterable, start=0) +test("enumerate") +myprint([t for t in enumerate(["hello", "world"], 10)]) + +# eval(expression[, globals[, locals]]), eval as a python expression +test("eval") +a = 1 +myprint(eval("1+2+a")) + +# exec(object[, globals[, locals]]) +test("exec") +exec("b = 1") +myprint(b) + +# filter(function, iterable) +test("filter") +myprint([x for x in filter(lambda x : x % 2 == 0, [1, 2, 3, 4])]) +# supplement : itertools.filterfalse() +from array import array +from io import TextIOWrapper +from itertools import filterfalse +myprint([x for x in filterfalse(lambda x : x % 2 == 0, [1, 2, 3, 4])]) + +# class float([x]), return float number from number or string +# for normal object: call __float__, if not exist, call __index__ instead, else fail +test("float") +myprint(float(" -1234.5 ")) +myprint(float("1.4e300")) +myprint(float("-InfInItY")) # case non-sensitive +myprint(float("+InF")) +class MyFloat: + def __init__(self, val) -> None: + self._val = val + def __float__(self): + return self._val * 10 +class MyInt: + def __init__(self, val): + self._val = int(val) + def __index__(self): + return self._val * 10 + +myprint(float(MyFloat(10.0))) +myprint(float(MyInt(100))) + +# format() +test("format") +myprint(format(101, "#X")) + +# class frozenset([iterable]), as inner elemnt of set, if there is a nested set +# class set([iterable]) +test("set frozenset") +myprint({frozenset([1, 2]), frozenset([2, 3])}) +myprint(frozenset([1, 2, 3, 3, 4])) +myprint(set([1, 2, 3, 4])) + +# globals() : dict of global symbol table +test("globals") +myprint(globals()) + +# hash(object) : get hash value, call object.__hash__() +test("hash") +myprint(hash(object)) +myprint(hash(1)) +myprint(hash(1.10)) + +# hex(x) : integer to hex lower-case string with 0x prefix +test("hex") +myprint(hex(255)) +myprint(hex(46543468463545343)) + +# id(object) : id of a oejct, unique and constant in it's lifetime +test('id') +myprint(id(object)) +myprint(id(1)) +myprint(id(1 + 2)) + +# input([prompt]) : write prompt to stdout and read one line from input +test("input") +# a = input("input a integer: ") +# myprint(a) + +# class int([x]) +# class int(x, base=10) +# __int__, __index__, __trunc__ +test('int') +myprint(int("10", base = 8)) +myprint(int(10.07)) +myprint(int()) + +# RTTI +# isinstance(object, classinfo) +# issubclass(class, classinfo) +class Person: + pass +class Student(Person): + pass +test("isinstance issubclass") +myprint(isinstance(Student(), (Student, object))) +myprint(isinstance(1, object)) +myprint(issubclass(Student, Person)) +myprint(issubclass(int, object)) + +# iter(object[, sentinel]) : __iter__(), __getitem__() +test("iter") +myprint(iter([])) +myprint(iter({})) +myprint(iter({1, 2})) + +# len(s) : __len__ +test("len") +myprint(len([])) +myprint(len({1, 2})) + +# locals() : local symbol table, do not modify +test("locals") +myprint(locals()) +myprint(globals() == locals()) # True +class Person: + name = "Kim" + age = 10 + def __init__(self, *args, **kwargs): + pass + myprint(locals()) + +# map(function, iterable, ...) +from itertools import starmap +test("map") +myprint([elem for elem in map(lambda x, y: x * y, [x for x in range(10)], [y for y in range(0, -10, -1)])]) +myprint([elem for elem in starmap(lambda x, y: x * y, [(x, -x) for x in range(10)])]) # element for func are tuples + +# max(iterable, *[, key, default]) +# max(arg1, arg2, *args[, key]) +# min(iterable, *[, key, default])¶ +# min(arg1, arg2, *args[, key]) +test('max min') +myprint(max([1, 2, 3], key = lambda x : -x)) +myprint(max(1, 2, 3)) + +# class memoryview(object) : memory view of an object +test("memoryview") +myprint(memoryview(b"\xffasdfl")[1]) + +# next(iterator[, default]) : call __next__ of iterator, return defualt at end, if no defualt, raise StopIteration +test("next") +try: + it = iter([1, 2, 3, 4]) + while True: + myprint(next(it)) +except StopIteration as e: + myprint(e.value) + +# class object +test('object') +myprint(object()) + +# oct(x) : to octal number with a 0o prefix +test("oct") +myprint(oct(0xff), oct(10), oct(8), oct(0o77)) + +# open(file, mode='r', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) : open file +test("open") +with open("BuiltInFuncs.py", mode = "r") as f: + from functools import reduce + myprint(reduce(lambda x, y: x + 1, f, 0)) # get line of current file + +# pow(base, exp[, mod]) +test("pow") +myprint(pow(10, 3, 512)) +myprint(pow(10, 100)) # equals to 10 ** 100 + +# class property(fget=None, fset=None, fdel=None, doc=None) +test("property") +class C: + def __init__(self): + self._x = None + def getx(self): + return self._x + def setx(self, value): + self._x = value + def delx(self): + del self._x + x = property(getx, setx, delx, "I'm the 'x' property.") # defoine a delegate property +c = C() +c.x = 10 +myprint(c.x) +del c.x +# myprint(c.x) # will failed + +# or use as decorator, equals to definition of C +class D: + def __init__(self): + self._x = None + @property + def x(self): + """I'm the 'x' property.""" # doc + return self._x + @x.setter + def x(self, value): + self._x = value + @x.deleter + def x(self): + del self._x +d = D() +d.x = 10 +myprint(d.x) +del d.x +# myprint(d.x) + +# reversed(seq) : __reversed__ or (__len__ and __getitem__) +test("reversed") +myprint([x for x in reversed(range(10))]) + +# round(number[, ndigits]) +test("round") +myprint(round(2.346, 2)) + +# class slice(stop) +# class slice(start, stop[, step]) +test("slice") +myprint(slice(10)) +myprint(slice(0, 10, 2)) +myprint([x for x in range(10)][slice(0, 10, 2)]) + +# sorted(iterable, *, key=None, reverse=False) +test("sorted") +import random +L = [x for x in range(100)] +random.shuffle(L) +myprint(L) +myprint(sorted(L, key = lambda x : -x, reverse = True)) + +# @staticmethod, change a method to static method, will not pass class or object implicitly +# just like static method in java/method +test("@staticmethod") +class A: + @staticmethod + def f(x): + return x * x + def f2(x): # just like f + return -x +myprint(A.f) # +myprint(A.f(20)) +myprint(A.f2) # +myprint(A.f2(-10)) + +# class str(object='') +# class str(object=b'', encoding='utf-8', errors='strict') +test("str") +myprint(str("hello")) +myprint(str(b"\x7fasdf")) + +# sum(iterable, /, start=0) +test("sum") +myprint(sum([x for x in range(11)], 0)) +myprint(sum([[x for x in range(10)], [x for x in range(30, 40)], [10, 100, 1000, 10000]], [])) # to one dim array + +# class super([type[, object-or-type]]) +# return a proxy object, delegate a method call to father or brother class +test("super") +class A: + def foo(self): + myprint("foo in A") +class B(A): + def foo(self): + myprint("foo in B") +class C(A): + def foo(self): + myprint("foo in C") +class D(B, C): + def foo1(self): + super().foo() # B, super(D, self).foo() + def foo2(self): + super(B, self).foo() # C + def foo3(self): + super(C, self).foo() # A + def foo4(self): + super(C, D).foo(self) # A + def foo5(self): + super(B, D).foo(self) # C + +myprint(D.__mro__) # D -> B -> C -> A +D().foo() # B +D().foo1() # B +D().foo2() # C +D().foo3() # A +D().foo4() # A +D().foo5() # C + +# class tuple([iterable]) +test("tuple") +myprint(tuple([1, 2, 3])) + +# class type(object), get type of object +# class type(name, bases, dict, **kwds), return a new type +test("type") +myprint(type(1)) +Coord = type("Coord", (object, ), dict(x = 1, y = 2, res = lambda x, y : x + y)) +myprint(Coord) +myprint(Coord.x, Coord.y, Coord.res(1, 2)) + +# zip(*iterables, strict=False) +test("zip") +myprint(list(zip([x for x in range(10)], [chr(a) for a in range(ord('a'), ord('z'), 2)], [10 ** x for x in range(10)]))) +x, y = zip(*zip([1, 2, 3], [4, 5, 6])) # disassemable a tuple list to seperate tuple +myprint(x, y) + +# __import__(name, globals=None, locals=None, fromlist=(), level=0) +# import statement will call \ No newline at end of file diff --git a/Basics/ControlFlows.py b/Basics/ControlFlows.py new file mode 100644 index 0000000..7794978 --- /dev/null +++ b/Basics/ControlFlows.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- + +# if elif else +a = False +b = True +if a: + print("a is True") +elif b: + print("b is True") +else: + print("a and b are False") + + +# while +n = 1 +sum = 0 +while (n < 10): + sum += n + n += 1 +print(sum) + +# for +sum = 0 +for x in (1, 2, 3): + sum += x +print(sum) + + +sum = 0 +for x in range(0, 100, 10): + sum += x + c = 1 +print(sum) +print(x) +print(c) # scope ? + +s = "" +for x in range(ord('a'), ord('z') + 1): + s += chr(x) +print(s) diff --git a/Basics/Function.py b/Basics/Function.py new file mode 100644 index 0000000..8005354 --- /dev/null +++ b/Basics/Function.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- + +def myabs(a): + if a < 0: + return -a + else: + return a + +print(myabs(-10)) + +def swap(x, y): + return x, y # return as a tuple + +x = 1 +y = 2 +x, y = swap(x, y) +print(x, y) +(x, y) = (y, x) +print(x, y) + +import math +print(math.sin(math.pi / 4)) + +# default arguments +def power(x, n = 2): + res = 1 + while n > 0: + res *= x + n -= 1 + return res +print(power(10)) +print(power(10, 3)) + +# variable arguments +def printargs(*args): + print(args) + +printargs() +printargs((1, 2), 10) +printargs(1, 2, 3) +printargs(*[1, 2, 3], 10, 100) +printargs([1, 2, 3]) + +# keyword arguments +def person(name, age, *, city, job): + print(f"name: {name}, age: {age}, city: {city}, jog: {job}") + +person("kim", 18, job = "waiter", city = "beijing") + +def person2(name, age, *args, city, job): + print(f"name: {name}, age: {age}, city: {city}, jog: {job}") + +person2("kim", 18, job = "waiter", city = "beijing") + +# named keyword arguments +def person3(name, age, **args): + print(f"name: {name}, age: {age}, args: {args}") + +person3("kim", 18, job = "waiter", city = "beijing") +person3("kim", 18, **{'job': 'waiter', 'city': 'beijing'}) + +# combine multiple arguments +def foo(a, b, c = 0, *args, d = 10, **kw): + print(a, b, c, args, d, kw) + +foo(1, 2) +foo(1, 2, 3) +foo(1, 2, 3, 100) +foo(1, 2, 3, 100) +foo(1, d = 10, b = 2, c = 3, args = {1, 2}, kw = {"hello": 10}) + +# recursive +def fib(n): + return fibonacci(n, 0, 1) + +def fibonacci(n, a, b): + if (n == 0): + return a + else: + return fibonacci(n-1, b, a+b) + +import sys +sys.setrecursionlimit(2000) +print(fib(1990)) \ No newline at end of file diff --git a/Basics/String.py b/Basics/String.py new file mode 100644 index 0000000..537dc56 --- /dev/null +++ b/Basics/String.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- + +# string encoding +print('\u4e2d\u6587') # unicode escape +print(chr(74562)) +print(ord("𒍂")) +print("asf中文".encode("utf-8")) +print(b'asf\xe4\xb8\xad\xe6\x96\x87'.decode("utf-8")) # bytes + +# string format +name = "michael" +age = 18 +print("name = %s, age = %2d, %% {{ }}" % (name, age)) + +# format() +print("name = {0}, age = {1:2.3f} {{ }}".format(name, age)) +print(f"name = {name}, age = {age:2.3f} {{ }}") diff --git a/Basics/VarAndTypes.py b/Basics/VarAndTypes.py new file mode 100644 index 0000000..258edd4 --- /dev/null +++ b/Basics/VarAndTypes.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- + +# int +print(100_100) +print(0xFFFF_FFFF) +print(0xffff_ffff_ffff_ffff) +print(0xffff_ffff_ffff_ffff_ffff) +print(1234123423421324132341233541251134323145231) + +# float +print(1.324e10) +print(1.234213e300) +print(1.1321e303) +print(1.132423e309) # inf IEEE 754 64 bit +print(1.324e135434134356143_131435143541313135135135145) # inf + +# string +print("hello") +print(r"\\\r\t\nhello") # raw string +print("\r\nhello\ttest") +print("""\ + hello + world + asdfas + asdf + shit +""") + +# bool +print(True) +print(False) +print(True and False) +print(True or False) + +# none +print(None) + +# variable +name = "nephren" +# dynamic type, reference type +a = "ABC" +b = a +b = "abc" +print(a, b) + +# 中文标识符 +你好 = "你好" +print(你好) \ No newline at end of file diff --git a/BuiltInModules/Base64.py b/BuiltInModules/Base64.py new file mode 100644 index 0000000..dda3730 --- /dev/null +++ b/BuiltInModules/Base64.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- + +import base64 + +print(base64.b64encode(b'helloworld')) +print(base64.b64decode(b'aGVsbG93b3JsZA==')) + +# safe url encoding and decoding +print(base64.b64encode(b'\xff\xff\xff', altchars=b"-_")) +print(base64.b64decode(b'____', altchars=b"-_")) + +# euqals to +print(base64.urlsafe_b64encode(b'\xff\xff\xff')) +print(base64.urlsafe_b64decode(b'____')) \ No newline at end of file diff --git a/BuiltInModules/Collections.py b/BuiltInModules/Collections.py new file mode 100644 index 0000000..59cf60b --- /dev/null +++ b/BuiltInModules/Collections.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- + +from collections import defaultdict, namedtuple, deque +from typing import ChainMap, Counter, OrderedDict + +# namedtuple +Point = namedtuple('Point', ['x', 'y']) +p = Point(10, 20) +print(p, p.x, p.y, p[0], p[1]) + +# deque +q = deque([1, 2, 3, 'x']) +print(q.pop()) +q.append(10) # return None +print(q.popleft()) +q.appendleft(10) +print(q) + +# defaultdict +d = defaultdict(lambda: 'N/A') +print(d[10], d['nonexistkey']) +d[10] = 100 +print(d) + +# OrderedDict +d = OrderedDict() +d['x'] = 1 +d['y'] = 2 +print(d.keys()) +print(d) + +# ChainMap +c = ChainMap(d, {'x' : 200}) +print(c['x']) + +# Counter +c = Counter() +for ch in "hello": + c[ch] = c[ch] + 1 +print(c) \ No newline at end of file diff --git a/BuiltInModules/ContextLib.py b/BuiltInModules/ContextLib.py new file mode 100644 index 0000000..47afcb9 --- /dev/null +++ b/BuiltInModules/ContextLib.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- + +# with statement +class Query(object): + def __init__(self, name) -> None: + self.name = name + def __enter__(self): + print('Begin') + return self + def __exit__(self, exc_type, exc_value, traceback): + if exc_type: + print('Error') + else: + print('End') + def query(self): + print(f"Query info about {self.name}") + +with Query('Bob') as q: + q.query() + + +from contextlib import contextmanager + +class Query2(object): + def __init__(self, name): + self.name = name + def query(self): + print(f"Query info about {self.name}") + +@contextmanager +def create_query(name): + print("Begin") + q = Query2(name) + yield q + print('End') + +with create_query('Bob') as q: + q.query() + +# application auto generate xml tag +@contextmanager +def tag(name): + print(f"<{name}>") + yield + print(f"") + +with tag("h1"): + print("hello") \ No newline at end of file diff --git a/BuiltInModules/DateTime.py b/BuiltInModules/DateTime.py new file mode 100644 index 0000000..6b97875 --- /dev/null +++ b/BuiltInModules/DateTime.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- + +from datetime import date, datetime, timedelta, timezone +import re + +now = datetime.now() +print(now) +print(type(now)) # +print(datetime.fromtimestamp(datetime.now().timestamp())) + +# epoch time: 1970.01.01 UTC+0 zone 00::00 +# timstamp: epoch time to now, unit is seconds, a float point, precision to us +print(datetime.now().timestamp()) + +# construct specific datetime +dt = datetime(2021, 10, 14, 0, 0, 1) +print(dt) +print(datetime.fromtimestamp(dt.timestamp())) # time in current zone +print(datetime.utcfromtimestamp(dt.timestamp())) # UTC+0:00 time + +# user input string to datetime +print(datetime.strptime("2021-1-1 10:00:01", "%Y-%m-%d %H:%M:%S")) # do not have a zone + +# datetime to string +print(datetime.now().strftime('%a, %b %d %H:%M')) + +# calculate time interval +print(datetime.now() - datetime(2021, 10, 14, 0, 0, 1)) +print(datetime.now() - timedelta(1, 1, 1)) +print(timedelta(10, 10, 10) - timedelta(1, 1, 1)) + +# timezone +# UTC+08:00 zone: +print(timezone(timedelta(hours=8))) +print(datetime.now().replace(tzinfo=timezone(timedelta(hours=7))).timestamp()) # enforce to change timezone, do not change date and time + +# change timezone +print(datetime.utcnow()) +print(datetime.now().astimezone()) +print(datetime.now().astimezone(timezone(timedelta(hours=8))).timestamp()) + +# timestamp from datetime and timezone string +def to_timestamp(dt_str, tz_str): + dt = datetime.strptime(dt_str, "%Y-%m-%d %H:%M:%S") + m = re.match(r"(UTC)([-+]\d{1,2}):(\d{2})", tz_str) + dt = dt.replace(tzinfo=timezone(timedelta(hours=int(m.group(2))))) + return dt.timestamp() + +t1 = to_timestamp('2015-6-1 08:10:30', 'UTC+7:00') +assert t1 == 1433121030.0, t1 +t2 = to_timestamp('2015-5-31 16:10:30', 'UTC-09:00') +assert t2 == 1433121030.0, t2 \ No newline at end of file diff --git a/BuiltInModules/HTMLParserTest.py b/BuiltInModules/HTMLParserTest.py new file mode 100644 index 0000000..56e3205 --- /dev/null +++ b/BuiltInModules/HTMLParserTest.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- + +# HTMLParser +from html.parser import HTMLParser +from html.entities import name2codepoint + +class MyHTMLParser(HTMLParser): + + def handle_starttag(self, tag, attrs): + print('<%s>' % tag) + + def handle_endtag(self, tag): + print('' % tag) + + def handle_startendtag(self, tag, attrs): + print('<%s/>' % tag) + + def handle_data(self, data): + print(data) + + def handle_comment(self, data): + print('') + + def handle_entityref(self, name): + print('&%s;' % name) + + def handle_charref(self, name): + print('&#%s;' % name) + +parser = MyHTMLParser() +parser.feed(''' + + + +

Some html HTML tutorial...
END

+''') \ No newline at end of file diff --git a/BuiltInModules/HashLib.py b/BuiltInModules/HashLib.py new file mode 100644 index 0000000..1a683b5 --- /dev/null +++ b/BuiltInModules/HashLib.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- + +import hashlib + +# hashlib + +# md5 +# result: 128bit byte, usually denoted with a hex charcter string which length is 32 +md5 = hashlib.md5() +print(md5) +md5.update('how to use md5 in python hashlib?'.encode('utf-8')) +print(md5.hexdigest()) + +# call update multiple times, equals to call it one time +md5 = hashlib.md5() +md5.update('how to use md5 in '.encode('utf-8')) +md5.update('python hashlib?'.encode('utf-8')) +print(md5.hexdigest()) + +md5 = hashlib.md5() +md5.update('how to use md5 in python hashlib'.encode('utf-8')) # modify one character, will cause a totally different result +print(md5.hexdigest()) + + +# sha1 +# same as md5 +# result: 160 bit, hex character which length is 40 +sha1 = hashlib.sha1() +sha1.update('how to use sha1 in '.encode('utf-8')) +sha1.update('python hashlib?'.encode('utf-8')) +print(sha1.hexdigest()) + + +# sha256 and sha512 +sha256 = hashlib.sha256() +sha256.update('how to use md5 in python hashlib?'.encode('utf-8')) +print(sha256.hexdigest()) + +sha512 = hashlib.sha512() +sha512.update('how to use md5 in python hashlib?'.encode('utf-8')) +print(sha512.hexdigest()) \ No newline at end of file diff --git a/BuiltInModules/Hmac.py b/BuiltInModules/Hmac.py new file mode 100644 index 0000000..bf804b1 --- /dev/null +++ b/BuiltInModules/Hmac.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- + +# hashing for message authentication +import hmac +import hashlib +message = b"hello,world!" +key = b"sercet" +h = hmac.new(key, message, digestmod="MD5") +print(h.hexdigest()) + +h = hmac.new(key, message, digestmod="SHA1") +print(h.hexdigest()) + +h = hmac.new(key, message, digestmod="SHA256") +print(h.hexdigest()) + +h = hmac.new(key, message, digestmod="SHA512") +print(h.hexdigest()) \ No newline at end of file diff --git a/BuiltInModules/Itertools.py b/BuiltInModules/Itertools.py new file mode 100644 index 0000000..5c156e4 --- /dev/null +++ b/BuiltInModules/Itertools.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- + +import itertools + +# infinite iterators: count, cycle, repeat +naturals = itertools.count(10, 10) +for i, n in enumerate(naturals): + if (i >= 10): + break + print(n) + +cs = itertools.cycle([1, 2, 3]) +for i,n in enumerate(cs): + if (i >= 10): + break + print(n) + +riter = itertools.repeat('A', 10) +for elem in riter: + print(elem) + +# chain +for elem in itertools.chain([1, 2, 3], ('x', 'y', 'z'), (x for x in range(10) if x % 2 == 0)): + print(elem) + +# groupby +for key, group in itertools.groupby('AAaaBBbbCccC', lambda c : c.upper()): + print(key, list(group)) + +# calculate PI +def pi(N): + oddnums = itertools.count(1, 2) # 1, 3, 5, 7, ... + ns = itertools.takewhile(lambda x : x <= 2*N-1, oddnums) # 1, 3, ..., 2*N-1 + nss = map(lambda x : (-1)**(x//2)*4/x, ns) + return sum(nss) # PI = (1 - 1/3 + 1/5 + ...) * 4 + +print(pi(10)) +print(pi(100)) +print(pi(1000)) +print(pi(10000)) \ No newline at end of file diff --git a/BuiltInModules/Struct.py b/BuiltInModules/Struct.py new file mode 100644 index 0000000..24872c2 --- /dev/null +++ b/BuiltInModules/Struct.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- + +import struct + +# > big endian +# < little endian +# I 32-bit unsinged integer +# https://docs.python.org/zh-cn/3/library/struct.html#format-characters +print(struct.pack('>I', 10234)) +print(struct.unpack('>I', b"\x00\x00'\xfa")) \ No newline at end of file diff --git a/BuiltInModules/UrlLib.py b/BuiltInModules/UrlLib.py new file mode 100644 index 0000000..2b272d7 --- /dev/null +++ b/BuiltInModules/UrlLib.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- + +from urllib import request + +with request.urlopen('https://baidu.com') as f: + data = f.read() + print('Status:', f.status, f.reason) + for k, v in f.getheaders(): + print('%s: %s' % (k, v)) + print('Data:', data.decode('utf-8')) + +req = request.Request('http://www.douban.com/') +req.add_header('User-Agent', 'Mozilla/6.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/8.0 Mobile/10A5376e Safari/8536.25') +with request.urlopen(req) as f: + print('Status:', f.status, f.reason) + for k, v in f.getheaders(): + print('%s: %s' % (k, v)) + print('Data:', f.read().decode('utf-8')) \ No newline at end of file diff --git a/BuiltInModules/XML.py b/BuiltInModules/XML.py new file mode 100644 index 0000000..e8c1f39 --- /dev/null +++ b/BuiltInModules/XML.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- + +from xml.parsers.expat import ParserCreate + +class DefaultSaxHandler(object): + def start_element(self, name, attrs): + print('sax:start_element: %s, attrs: %s' % (name, str(attrs))) + + def end_element(self, name): + print('sax:end_element: %s' % name) + + def char_data(self, text): + print('sax:char_data: %s' % text) + +xml = r''' +
    +
  1. Python
  2. +
  3. Ruby
  4. +
+''' + +handler = DefaultSaxHandler() +parser = ParserCreate() +parser.StartElementHandler = handler.start_element +parser.EndElementHandler = handler.end_element +parser.CharacterDataHandler = handler.char_data +parser.Parse(xml) \ No newline at end of file diff --git a/Collections/Collections.py b/Collections/Collections.py new file mode 100644 index 0000000..355590e --- /dev/null +++ b/Collections/Collections.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- + +# list +print("list============================") +l = list([1, 3, 4]) +print([1, 3, 4][2]) +print(l) + +print(len([1, 3, 4])) + +# tuple +print("tuple============================") +print((1, 2, "hello")) +t = () +print(t) # empty tuple +print(()) +print((1)) # just 1 +print((1, )) # tuple with one element + +a = 1 +b = 2 +t = (a, b, "hello") +b = 3 +print(t) # keep (1, 2, "hello") + +# range +print("range============================") +print(range(10)) # 0 to 9 by step 1 +print(list(range(10))) # 0 to 9 by step 1 +print(range(1, 5)) +print(list(range(1, 5))) +print(range(1, 100, 10)) +print(list(range(1, 100, 10))) + + +# dict +print("dict============================") +d = {"hello": 1, "world": 2} +print(d) +print(d["hello"]) +print(d.get("yes", -1)) +print(d.get("yes")) +d["yes"] = 100 +d.pop("hello") +print(d) + + +# set +print("set============================") +s = {1, 3, 100, "hello", "yes"} +print(s) +s = set([1, 3, 100, "hello"]) +print(s) +s.add(1024) +s.remove("hello") +print(s) +print("hello" in s) + +s.add((1, 2, 3)) +print(s) \ No newline at end of file diff --git a/Collections/Generator.py b/Collections/Generator.py new file mode 100644 index 0000000..b7e756d --- /dev/null +++ b/Collections/Generator.py @@ -0,0 +1,71 @@ +# -*- coding -*- + +from re import I +from typing import Iterable, Iterator + +# list comprehension +print(list(range(100))) +print([n for n in range(100) if n % 10 + n // 10 == 9]) +print([x*x for x in range(10) if x % 2 == 0]) + +print([m + n for m in "ABC" for n in "XYZ"]) + +L1 = ['Hello', 'World', 18, 'Apple', None] +L2 = [s.lower() for s in L1 if isinstance(s, str)] +print(L2) + +# generator +g = (x * x for x in range(10) if x % 2 == 0) + +def fib(max): + n, a, b = 0, 0, 1 + while (n < max): + yield a + a, b = b, a + b + n += 1 + return "done" + +print([x for x in fib(10)]) + +g = fib(10) +while True: + try: + print(next(g)) + except StopIteration as e: + print("Generator return value: ", e.value) + break + +# pascal triangles +def triangles(max): + n, L = 0, [1] + while n < max: + yield L.copy() + L.append(0) + L = [L[i] + L[i-1] for i in range(len(L))] + n += 1 + return "done" + +g = triangles(10) +res = [elem for elem in g] +print(res) +print(isinstance(g, Iterator)) # True +print(isinstance(g, Iterable)) # True + +print(isinstance([1, 2], Iterable)) # True +print(isinstance([1, 2], Iterator)) # False +print(isinstance(iter([1, 2]), Iterator)) # True, collections to Iterator + +# the natrue of for +for x in [1, 2, 3, 4, 5]: + print(x) + +# equals to +it = iter([1, 2, 3, 4, 5]) +while True: + try: + x = next(it) + print(x) + except StopIteration: + break + +print(triangles) \ No newline at end of file diff --git a/Collections/Iteration.py b/Collections/Iteration.py new file mode 100644 index 0000000..e07e7ae --- /dev/null +++ b/Collections/Iteration.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- + +# use for to iterate collections, aka range for + +from collections.abc import Iterable + + +for x in [12, 124, 1234]: + print(x) + +for x in (1, 2, 3): + print(x) + +for x in {1, 2, 3, 1, 4}: + print(x) + +d = {"hello": 10, 2 : 100, "world": "yes"} +for k in d: + print(k) +for k, v in d.items(): + print(k, v) +for kv in d.items(): + print(kv) +for v in d.values(): + print(v) + +print(isinstance([1, 2, 3], Iterable)) +print(isinstance((1, 2, 3), Iterable)) +print(isinstance({1, 2, 3}, Iterable)) +print(isinstance({1:2}, Iterable)) +print(isinstance(range(100), Iterable)) +print(isinstance('abc', Iterable)) + +a = [1, 2, "hello"] +for i, val in enumerate(a): + print(i, val) + +for i, pair in enumerate(d.items()): + print(i, pair) + +for x in range(100): + print(x) \ No newline at end of file diff --git a/Collections/Slicing.py b/Collections/Slicing.py new file mode 100644 index 0000000..fae2687 --- /dev/null +++ b/Collections/Slicing.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- + +# slicing of collections: tuple and list +l = list(range(101)) +print(l[:]) +print(l[:10]) +print(l[10:20]) +print(l[::5]) +print(l[-20:]) # last 20 elements +print(l[-1:]) # last element +print(l[70:40:-1]) + +# slicing of string +s = "abcdefghijklmnopqrstuvwxyz" +print(s[10:20:2]) +print(s[2:]) +print(s) + +print(range(0, 10)[:50:2]) +print(list(range(1, 100)[::2])) +print(range(0, 10)) \ No newline at end of file diff --git a/Concurrent/DistributedProcess/TaskMaster.py b/Concurrent/DistributedProcess/TaskMaster.py new file mode 100644 index 0000000..5205eed --- /dev/null +++ b/Concurrent/DistributedProcess/TaskMaster.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# TaskMaster.py + +# distributed multi process, task manager +import random, time, queue +from multiprocessing.managers import BaseManager + +# queue that send tasks +task_queue = queue.Queue() +# queue that receive tasks +result_queue = queue.Queue() + +class QueueManager(BaseManager): + pass + +def get_task_q(): + return task_queue +def get_result_q(): + return result_queue + +if __name__ == '__main__': + # register two queues to network + QueueManager.register('get_task_queue', callable=get_task_q) + QueueManager.register('get_result_queue', callable=get_result_q) + # bind to port 5000, authentication code abc + manager = QueueManager(address=('127.0.0.1', 5000), authkey=b'abc') + + # start the manager + manager.start() + # get Queue object through network + task = manager.get_task_queue() + result = manager.get_result_queue() + + # put some tasks to task queue + for i in range(10): + n = random.randint(0, 10000) + print(f"Put task {n}") + task.put(n) + + # read result from result queue + print("Try get results...") + for i in range(10): + try: + r = result.get(timeout=10) + print(f"Result : {r}") + except queue.Empty: + print("The queue is empty...") + + # shudown manager + manager.shutdown() + print("Master exit.") \ No newline at end of file diff --git a/Concurrent/DistributedProcess/TaskWorker.py b/Concurrent/DistributedProcess/TaskWorker.py new file mode 100644 index 0000000..e3f3115 --- /dev/null +++ b/Concurrent/DistributedProcess/TaskWorker.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# TaskWorker.py + +# distributed multi process, task wroker +import time, sys, queue +from multiprocessing.managers import BaseManager + +class QueueManager(BaseManager): + pass + +if __name__ == '__main__': + QueueManager.register('get_task_queue') + QueueManager.register('get_result_queue') + server_addr = "127.0.0.1" + print(f"Connect to server {server_addr}...") + m = QueueManager(address=(server_addr, 5000), authkey=b'abc') + # connect manager obejct to server + m.connect() + # get Queue from network + task = m.get_task_queue() + result = m.get_result_queue() + # get task from task queue, calculate and put result to result queue + for i in range(10): + try: + n = task.get(timeout=1) + print(f"Run task {n} * {n}...") + r = f"{n} * {n} = {n * n}" + time.sleep(1) + result.put(r) + except queue.Empty: + print("task queue is empty.") + + # end wrok process + print("Worker exit.") diff --git a/Concurrent/MultiProcessing.py b/Concurrent/MultiProcessing.py new file mode 100644 index 0000000..85e22b0 --- /dev/null +++ b/Concurrent/MultiProcessing.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- + +import os +print(f"porcess {os.getpid()} start ...") + +# only works on *nix(Linux/Unix/MacOS) +pid = os.fork() +if pid == 0: + print(f"This is child process {os.getpid()}, and parent is {os.getppid()}.") +else: + print(f"This is parent process {os.getpid()}, and just created a child process {pid}") diff --git a/Concurrent/ProcessCommunication.py b/Concurrent/ProcessCommunication.py new file mode 100644 index 0000000..df93c69 --- /dev/null +++ b/Concurrent/ProcessCommunication.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- + +from multiprocessing import Process, Queue +import os, time, random + +# write to queue +def write(q): + print(f"Process to write : {os.getpid()}") + for value in ['A', 'B', 'C']: + print(f"Put {value} in queue...") + q.put(value) + time.sleep(random.random()) + +# read from queue +def read(q : Queue): + print(f"Process to read : {os.getpid()}") + while True: + value = q.get(True) # block = True + print(f"Get value {value} from queue.") + +if __name__ == "__main__": + # create queue and pass to subprocess + q = Queue() + pw = Process(target=write, args=(q,)) + pr = Process(target=read, args=(q,)) + # start subprocess to write + pw.start() + # start subprocess to read + pr.start() + # wait pw end + pw.join() + # pr is infinite loop, can not end by itself, must be terminated. + pr.terminate() diff --git a/Concurrent/ProcessCrossPlatfrom.py b/Concurrent/ProcessCrossPlatfrom.py new file mode 100644 index 0000000..d54ebf7 --- /dev/null +++ b/Concurrent/ProcessCrossPlatfrom.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- + +from multiprocessing import Process +import os + +# subprocess will execute +def run_proc(name): + print(f"Run child process {name} ({os.getpid()})...") + +if __name__ == "__main__": + print(f"Parent process {os.getpid()}.") + p = Process(target = run_proc, args = ('test', )) + print("Child process will start.") + p.start() + p.join() + print("Child process end.") \ No newline at end of file diff --git a/Concurrent/ProcessPool.py b/Concurrent/ProcessPool.py new file mode 100644 index 0000000..ba7414e --- /dev/null +++ b/Concurrent/ProcessPool.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- + +from multiprocessing import Pool, Process +import os, time, random + +def long_time_task(name): + print(f"Run task {name} ({os.getpid()})...") + start = time.time() + time.sleep(random.random() * 3) + end = time.time() + print(f"Task {name} runs {end-start:0.2f} seconds.") + +if __name__ == "__main__": + print(f"Parent process {os.getpid()}.") + p = Pool(4) + for i in range(5): + p.apply_async(long_time_task, args = (i, )) + print("Waiting for all subprocess done...") + p.close() + p.join() + print("All subprocess done.") \ No newline at end of file diff --git a/Concurrent/SubProcess.py b/Concurrent/SubProcess.py new file mode 100644 index 0000000..52bde26 --- /dev/null +++ b/Concurrent/SubProcess.py @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- + +import subprocess + +p = subprocess.Popen(['python', '-c', 'print("hello,world!")'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) +out, err = p.communicate() +print(out.decode("utf-8"), err.decode("utf-8")) +print("exit code: ", p.returncode) \ No newline at end of file diff --git a/Concurrent/ThreadLocal.py b/Concurrent/ThreadLocal.py new file mode 100644 index 0000000..6988715 --- /dev/null +++ b/Concurrent/ThreadLocal.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- + +import threading + +class Student(): + def __init__(self, name) -> None: + self.name = name + def __str__(self) -> str: + return f"Student {self.name}" + +# create global ThreadLocal object +local_shool = threading.local() + +def process_student(): + std = local_shool.student + print(f"hello, {std} in thread {threading.current_thread().name}") + +def process_thread(name): + local_shool.student = Student(name) # bind thread local object to atrribute of global threading.local object + process_student() + +if __name__ == "__main__": + t1 = threading.Thread(target=process_thread, args=("Alice",), name="Thread-A") + t2 = threading.Thread(target=process_thread, args=("Bob",), name="Thread-B") + t1.start() + t2.start() + t1.join() + t2.join() \ No newline at end of file diff --git a/Concurrent/Threading.py b/Concurrent/Threading.py new file mode 100644 index 0000000..99ca74a --- /dev/null +++ b/Concurrent/Threading.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- + +import time, threading + +def loop(): + print(f"thread {threading.current_thread().name} is running...") + for i in range(5): + print(f"thread {threading.current_thread().name} >>> {i}") + time.sleep(1) + print(f"thread {threading.current_thread().name} end.") + +if __name__ == "__main__": + print(f"thread {threading.current_thread().name} is running...") + t = threading.Thread(target=loop, name="LoopThread") + t.start() + t.join() + print(f"thread {threading.current_thread().name} end.") \ No newline at end of file diff --git a/Email/POP3.py b/Email/POP3.py new file mode 100644 index 0000000..f35204e --- /dev/null +++ b/Email/POP3.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- + +import poplib +from email.parser import Parser +from email.header import decode_header +from email.utils import parseaddr + +# utils to parse mail content +def decode_str(s): + value, charset = decode_header(s)[0] + if charset: + value = value.decode(charset) + return value + +def guess_charset(msg): + charset = msg.get_charset() + if charset is None: + content_type = msg.get('Content-Type', '').lower() + pos = content_type.find('charset=') + if pos >= 0: + charset = content_type[pos + 8:].strip() + return charset + +# print mail info recursively +def print_info(msg, indent=0): + if indent == 0: + for header in ['From', 'To', 'Subject']: + value = msg.get(header, '') + if value: + if header=='Subject': + value = decode_str(value) + else: + hdr, addr = parseaddr(value) + name = decode_str(hdr) + value = u'%s <%s>' % (name, addr) + print('%s%s: %s' % (' ' * indent, header, value)) + if (msg.is_multipart()): + parts = msg.get_payload() + for n, part in enumerate(parts): + print('%spart %s' % (' ' * indent, n)) + print('%s--------------------' % (' ' * indent)) + print_info(part, indent + 1) + else: + content_type = msg.get_content_type() + if content_type=='text/plain' or content_type=='text/html': + content = msg.get_payload(decode=True) + charset = guess_charset(msg) + if charset: + content = content.decode(charset) + print('%sText: %s' % (' ' * indent, content + '...')) + else: + print('%sAttachment: %s' % (' ' * indent, content_type)) + + +if __name__ == '__main__': + # input email + email = input('Email: ') + password = input('Password: ') + pop3_server = input('POP3 server: ') + + # connect to POP3 server + server = poplib.POP3(pop3_server) + server.set_debuglevel(1) + print(server.getwelcome().decode('utf-8')) + + # authentication + server.user(email) + server.pass_(password) + + # email number and space + print('Message: %s, Size: %s', server.stat()) + + # get numbers of all mails + resp, mails, octets = server.list() + print(mails) + + # get newest mail + index = len(mails) + resp, lines, octets = server.retr(index) + + # get raw content of mail + msg_content = b'\r\n'.join(lines).decode('utf-8') + # parse mail content + msg = Parser().parsestr(msg_content) + + server.quit() + + # print mail + print_info(msg) diff --git a/Email/SMTP.py b/Email/SMTP.py new file mode 100644 index 0000000..fcbb7e2 --- /dev/null +++ b/Email/SMTP.py @@ -0,0 +1,32 @@ +# -*- coding:utf-8 -*- + +from email.mime.text import MIMEText +from email.header import Header +from email.utils import parseaddr, formataddr + +def _format_addr(s): + name, addr = parseaddr(s) + return formataddr((Header(name, 'utf-8').encode(), addr)) + +# input email and passwd +from_addr = input('From: ') +password = input('password: ') +to_addr = input('To: ') + +# input SMTP server address +smtp_server = input('SMTP server: ') + +# plain text email +msg = MIMEText("hello, send by Python...", 'Plain', 'utf-8') +msg['From'] = _format_addr('暗之恶魔 <%s>' % from_addr) # 发件人 +msg['To'] = _format_addr('光之使者 <%s>' % to_addr) # 收件人 +msg['Subject'] = Header("接受地狱的审判吧!", 'utf-8').encode() # 主题 + +# send to MTA +import smtplib +server = smtplib.SMTP(smtp_server, 25) +server.starttls() +server.set_debuglevel(1) # print interactive info with the server +server.login(from_addr, password) +server.sendmail(from_addr, [to_addr], msg.as_string()) +server.quit() \ No newline at end of file diff --git a/ErrorsAndDebug/Debug.py b/ErrorsAndDebug/Debug.py new file mode 100644 index 0000000..72c4910 --- /dev/null +++ b/ErrorsAndDebug/Debug.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- + + +import logging +import pdb +logging.basicConfig(level = logging.INFO, filename="Debug.log", encoding="utf-8", filemode="w") + +# assert +def test1(): + n = 11 + assert n == 10, "n is not 10" + print(n) + +# logging +def Fib(n, a, b): + logging.info(f"call Fib({n}, {a}, {b})") + # pdb.set_trace() + if (n == 0): + return a + else: + return Fib(n-1, b, a + b) + +def test2(): + n = Fib(10, 0, 1) + print(n) + + +if __name__ == "__main__": + # test1() + test2() \ No newline at end of file diff --git a/ErrorsAndDebug/TryExcept.py b/ErrorsAndDebug/TryExcept.py new file mode 100644 index 0000000..85e0317 --- /dev/null +++ b/ErrorsAndDebug/TryExcept.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +import logging +def f(): + try: + a = 10 / 0 + except ValueError as e: + print("except :", e) + raise + except ZeroDivisionError as e: + print('except: ', e) + raise + finally: + print("finally...") + +def main(): + try: + f() + except Exception as e: + logging.exception(e) # log error and continue to execute + +if __name__ == "__main__": + main() + + print("END") diff --git a/ErrorsAndDebug/UnitTest.py b/ErrorsAndDebug/UnitTest.py new file mode 100644 index 0000000..8c261ab --- /dev/null +++ b/ErrorsAndDebug/UnitTest.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- + +class Dict(dict): + """ + >>> d1 = Dict() + >>> d1['x'] = 100 + >>> d1.x + 100 + >>> d1.y = 200 + >>> d1['y'] + 200 + >>> d2 = Dict(a=1, b=2, c='3') + >>> d2.c + '3' + >>> d2['empty'] + Traceback (most recent call last): + ... + KeyError: 'empty' + >>> d2.empty + Traceback (most recent call last): + ... + AttributeError: 'Dict' object has no attribute 'empty' + """ + def __init__(self, **kw): + super().__init__(**kw) + def __getattr__(self, key): + try: + return self[key] + except: + raise AttributeError(f"'Dict' object has no attribute '{key}'") + def __setattr__(self, key, value): + self[key] = value + +import unittest +class DictTest(unittest.TestCase): + def test_init(self): + d = Dict(a = 1, b = "test") + self.assertEqual(d.a, 1) + self.assertEqual(d.b, 'test') + self.assertTrue(isinstance(d, dict)) + + def test_key(self): + d = Dict() + d['key'] = 'value' + self.assertEqual(d.key, 'value') + + def test_attr(self): + d = Dict() + with self.assertRaises(KeyError): + value = d['empty'] + + def test_attrerror(self): + d = Dict() + with self.assertRaises(AttributeError): + value = d.empty + + # call before every test + def setUp(self) -> None: + print("setUp()...") + + # call after every test + def tearDown(self) -> None: + print("tearDown()...") + + +if __name__ == '__main__': + # unittest + unittest.main() + # doctest + import doctest + doctest.testmod() \ No newline at end of file diff --git a/Functional/Closure.py b/Functional/Closure.py new file mode 100644 index 0000000..7c51d1d --- /dev/null +++ b/Functional/Closure.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- + +# do not use a loop variable if return a closure +def count(): + fs = [] + for i in range(1, 4): + def f(): + return i*i + fs.append(f) + return fs + +f1, f2, f3 = count() +print(f1(), f2(),f3()) # 9 9 9 + +# bind before i chagne +def count2(): + def f(j): + def g(): + return j*j + return g + fs = [] + for i in range(1, 4): + fs.append(f(i)) + return fs + +f1, f2, f3 = count2() +print(f1(), f2(), f3()) + +# every call will return a incresing value +def createCounter(): + n = 0 + def counter(): + nonlocal n # need define as nonlocal, if call outter local variable + n = n + 1 + return n + return counter + +c = createCounter() +print([c() for _ in range(10)]) +d = createCounter() +print([d() for _ in range(10)]) \ No newline at end of file diff --git a/Functional/Decorator.py b/Functional/Decorator.py new file mode 100644 index 0000000..79097be --- /dev/null +++ b/Functional/Decorator.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- + +import functools, time + +# __name__ of a function +def f(x): + return x * x + +print(f.__name__) # f +print((lambda x : x * x).__name__) # + +# decorator +def log(func): + def warpper(*args, **kv): + print(f"call {func.__name__}") + return func(*args, **kv) + return warpper + +@log # equals to log = log(now2) +def now(): + print('2021-10-2') + +def now2(): + print('2021-10-2') + +now() +log(now2)() # equals to now() +print(now.__name__) # wrapper + +# decorator with arguments +def log2(text): + def decorator(func): + @functools.wraps(func) + def warpper(*args, **kv): + print(f"{text} : {func.__name__}") + return func(*args, **kv) + return warpper + return decorator + +@log2("execute") # equals to now3 = log("execute")(now3) +def now3(): + print('2021-10-2') + +now3() +print(now3.__name__) # now3, if without @functools.wraps(func), will be wrapper + + +# example: for any functions, print time of the execution in miniseconds +def metric(func): + t = time.time() + @functools.wraps(func) + def warpper(*args, **kv): + k = func(*args, **kv) + print(f"{func.__name__} executed in {(time.time() - t) * 1000} ms") + return k + return warpper + +@metric +def fast(x, y): + time.sleep(0.0012) + return x + y + +@metric +def slow(x, y, z): + time.sleep(0.1234) + return x + y + z + +print(fast(10, 20)) +print(slow(20, 30, 134)) diff --git a/Functional/HighOrderFunction.py b/Functional/HighOrderFunction.py new file mode 100644 index 0000000..b22dc35 --- /dev/null +++ b/Functional/HighOrderFunction.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- + +from functools import reduce + +# assignment +print(abs) +a = abs +print(a) +print(a(-10)) + +# as parameter +def add(x, y, f): + return f(x) + f(y) + +print(add(10, -5, abs)) + +# as return value +def addz(x, y): + def other(z): + return x + y + z + return other + +print(addz) +print(addz(1, 2)) +print(addz(1, 2) == addz(1, 2)) # False +print(addz(1, 2)(3)) + +# map +def add10(x): + return x + 10 +print(list(map(add10, [1, 2, 3]))) + +def add(x, y): + return x + y +print(list(map(add, range(100)[::-1], [-x for x in range(100, 250)]))) + +# reduce +def sum(x, y): + return x + y +print(reduce(sum, range(101))) + +# example +DIGITS = dict((chr(ord('0') + val), val) for val in range(10)) # '0': 0, '1': 1, ... +def str2int(s): + def fn(x, y): + return x * 10 + y + def char2num(s): + return DIGITS[s] + return reduce(fn, map(char2num, s)) + +print(str2int("1024")) + +def str2float(s): + loc = s.find('.') + def char2num(s): + return DIGITS[s] + part1 = reduce(lambda x, y: x * 10 + y, map(char2num, s[:loc])) + part2 = reduce(lambda x, y: x / 10 + y, map(char2num, s[-1:loc:-1])) + return part1 + part2/10 + +print(str2float("1.234")) + +# filter +print(list(filter(lambda x: x % 5 == 0, range(100, 200)))) + +# example: use Sieve of Eratosthenes to find all prime nunbers +# https://zh.wikipedia.org/wiki/%E5%9F%83%E6%8B%89%E6%89%98%E6%96%AF%E7%89%B9%E5%B0%BC%E7%AD%9B%E6%B3%95 +def _odd_iter(): + n = 1 + while True: + n = n + 2 + yield n + +def _not_division(n): + return lambda x: x % n > 0 + +def primes(): + yield 2 + it = _odd_iter() # generate odd numbers + while True: + n = next(it) + yield n + it = filter(_not_division(n), it) # construct new Iterator + +gp = primes() +print([next(gp) for _ in range(100)]) + +# sorted +s = ['bob', 'about', 'Zoo', 'Credit'] +print(sorted(s, key = str.lower, reverse=True)) diff --git a/Functional/Lambda.py b/Functional/Lambda.py new file mode 100644 index 0000000..d120c06 --- /dev/null +++ b/Functional/Lambda.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- + +# anonymous function aka lambda expression +# with limited support in Python + +print(list(map(lambda x : x * x, range(0, 10)))) + +f = lambda x : x * x +print(f(10)) + +def fn(x): + return x * x + +print(f) # at 0x000002A39C515040> +print(fn) # + +f = lambda x : (lambda y : (lambda z : x + y + z)) +print(f) # at 0x000001B74BF061F0> +print(f(1)) # .. at 0x000001B74BF060D0> +print(f(1)(2)) # .... at 0x000001B74BF06280> +print(f(1)(2)(3)) diff --git a/Functional/PartialFunction.py b/Functional/PartialFunction.py new file mode 100644 index 0000000..7f82408 --- /dev/null +++ b/Functional/PartialFunction.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- + +from functools import partial +from math import log + +# partial function +int2 = partial(int, base = 2) +print(int2("1000")) # 8 + +# equals to +kw = {"base": 2} +print(int("1000", **kw)) + +def f(a, b, *, c, d): + print(f"{a}, {b}, {c}, {d}") + +f1 = partial(f, 10, d = 40) +f1(20, c = 30, d = 50) # named arguemnt from partial function can be overrided + +f2 = partial(f, b = 20) +f2(10, c = 30, d = 40) \ No newline at end of file diff --git a/GUI/HelloInput.py b/GUI/HelloInput.py new file mode 100644 index 0000000..7a2a938 --- /dev/null +++ b/GUI/HelloInput.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +from tkinter import * +import tkinter.messagebox as messagebox + +class Application(Frame): + def __init__(self, master=None): + Frame.__init__(self, master) + self.pack() + self.createWidgets() + + def createWidgets(self): + self.nameInput = Entry(self) + self.nameInput.pack() + self.alertButton = Button(self, text='Hello', command=self.hello) + self.alertButton.pack() + + def hello(self): + name = self.nameInput.get() or 'world' + messagebox.showinfo('Message', 'Hello, %s' % name) + +app = Application() +app.master.title('Hello World') +app.mainloop() \ No newline at end of file diff --git a/GUI/HelloWorld.py b/GUI/HelloWorld.py new file mode 100644 index 0000000..0969d2c --- /dev/null +++ b/GUI/HelloWorld.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- + +from tkinter import * + +class Application(Frame): + def __init__(self, master = None): + Frame.__init__(self, master) + self.pack() + self.createWidgets() + def createWidgets(self): + self.helloLabel = Label(self, text='Hello, world!') + self.helloLabel.pack() + self.quitButton = Button(self, text='Quit', command=self.quit) + self.quitButton.pack() + +app = Application() +app.master.title('hello,world') +app.mainloop() \ No newline at end of file diff --git a/GUI/TurtleTest.py b/GUI/TurtleTest.py new file mode 100644 index 0000000..352425c --- /dev/null +++ b/GUI/TurtleTest.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- + +# example +from turtle import * + +color('red', 'yellow') +begin_fill() +while True: + forward(200) + left(170) + if abs(pos()) < 1: + break +end_fill() +done() \ No newline at end of file diff --git a/IO/FileIO.py b/IO/FileIO.py new file mode 100644 index 0000000..92d85e0 --- /dev/null +++ b/IO/FileIO.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- + +# synchronous IO : simple but inefficient +# asynchronous IO : complicated and efficient + +with open("Test.txt", "r") as f: + for line in f.readlines(): + print(line.strip()) + +try: + f = open("Test.txt", "r") + print(f.read()) +finally: + if f: + f.close() \ No newline at end of file diff --git a/IO/OS.py b/IO/OS.py new file mode 100644 index 0000000..b8e8864 --- /dev/null +++ b/IO/OS.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- + +import os +import shutil + +print(os.name) # posix fox Unix-like, nt for windows + +# prrint(os.uname()) # detailed system info, do not support in windows + +print(os.environ) # all environment variables +print(os.environ.get("path")) # get specific environment variable + + +# file and directory operations +print(os.path.abspath('.')) +print(os.path.join('..', "test", "hello")) # ../test/hello in Unix-like, ..\test\hello in windows +print(os.path.split("./test/hello.txt")) +print(os.path.splitext("./test/hello.txt")) + +# crate and remove dir file +try: + os.mkdir("./test") +except: + pass +shutil.copyfile("./OS.py", "./test/OS.py") + +testdir = "./test" +for f in os.listdir(testdir): + os.remove(os.path.join(testdir, f)) +os.rmdir(testdir) + +# list all files in . +print(os.listdir('.')) diff --git a/IO/Serilization.py b/IO/Serilization.py new file mode 100644 index 0000000..fa45554 --- /dev/null +++ b/IO/Serilization.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- + +# pickling and unpickling +import pickle + +d = {chr(c) : c for c in range(ord('a'), ord('z') + 1)} +with open("dump.hex", "wb") as f: + pickle.dump(d, f) + print(pickle.dumps(d)) + +with open("dump.hex", 'rb') as f: + print(pickle.load(f)) # dict + +# JSON serilization +import json +with open('dump.json', "wt") as f: + json.dump(d, f) + +with open('dump.json', 'rt') as f: + print(json.load(f)) + +# normal object json serilization + +class Person: + def __init__(self, name, age): + self.name = name + self.age = age + def __str__(self) -> str: + return f"Person -> name : {self.name}, age : {self.age}" + +def person2dict(p): + return { + "name": p.name, + "age": p.age + } + +def dict2person(d): + return Person(d['name'], d['age']) + +json_str = json.dumps(Person("Kim", 18), default=person2dict) +print(json_str) +print(json.dumps(Person("Jim", 17), default=lambda x : x.__dict__)) +print(json.loads(json_str, object_hook=dict2person)) + +obj = dict(name="小明", age = 20) +print(json.dumps(obj, ensure_ascii=False)) # {"name": "\u5c0f\u660e", "age": 20}, use \uxxxx represent non-ascii character \ No newline at end of file diff --git a/IO/StringByteIO.py b/IO/StringByteIO.py new file mode 100644 index 0000000..5f345e8 --- /dev/null +++ b/IO/StringByteIO.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from io import StringIO, BytesIO + +f = StringIO("hello,world!\r\nyes\r\nno\r\n") +while True: + s = f.readline() + if s == '': + break + print(s.strip()) + +print(f.getvalue()) + +f = BytesIO() +f.write("中文".encode('utf-8')) +print(f.getvalue()) # b'\xe4\xb8\xad\xe6\x96\x87' +print(f.tell()) # 6 +f.seek(-6, 1) # move current positiont to begin +print(f.read()) \ No newline at end of file diff --git a/IO/Test.txt b/IO/Test.txt new file mode 100644 index 0000000..2c5f49b --- /dev/null +++ b/IO/Test.txt @@ -0,0 +1,2 @@ +Nehpren Ruq Insania +Catholly Nota Seniorious \ No newline at end of file diff --git a/IO/dump.hex b/IO/dump.hex new file mode 100644 index 0000000..4763074 Binary files /dev/null and b/IO/dump.hex differ diff --git a/IO/dump.json b/IO/dump.json new file mode 100644 index 0000000..a4447ba --- /dev/null +++ b/IO/dump.json @@ -0,0 +1 @@ +{"a": 97, "b": 98, "c": 99, "d": 100, "e": 101, "f": 102, "g": 103, "h": 104, "i": 105, "j": 106, "k": 107, "l": 108, "m": 109, "n": 110, "o": 111, "p": 112, "q": 113, "r": 114, "s": 115, "t": 116, "u": 117, "v": 118, "w": 119, "x": 120, "y": 121, "z": 122} \ No newline at end of file diff --git a/Module/Bar.py b/Module/Bar.py new file mode 100644 index 0000000..8589f75 --- /dev/null +++ b/Module/Bar.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- + +print(f"__name__ in Bar.py is {__name__}") + +import Foo + +print(f"__name__ in Bar.py is {__name__}") \ No newline at end of file diff --git a/Module/Foo.py b/Module/Foo.py new file mode 100644 index 0000000..821e498 --- /dev/null +++ b/Module/Foo.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + +print(f"__name__ in Foo.py is {__name__}") + +if __name__ == "__main__": + print("__name__ in foo.py is __main__") \ No newline at end of file diff --git a/Network/TCP/Client.py b/Network/TCP/Client.py new file mode 100644 index 0000000..a4cf193 --- /dev/null +++ b/Network/TCP/Client.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- + +import socket, time + +# create a socket +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +s.connect(('127.0.0.1', 9999)) + +# send requests +print(s.recv(1024).decode('utf-8')) +for data in [b"Alice", b"Bob", b"Mary"]: + s.send(data) + print(s.recv(1024).decode('utf-8')) +s.send(b'exit') +s.close() \ No newline at end of file diff --git a/Network/TCP/Server.py b/Network/TCP/Server.py new file mode 100644 index 0000000..3f49c2a --- /dev/null +++ b/Network/TCP/Server.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- + +import socket, threading, time + +def tcplink(sock, addr): + print('Accept new connection from %s:%s...' % addr) + sock.send(b"Welcome!") + while True: + data = sock.recv(1024) + time.sleep(1) + if not data or data.decode('utf-8') == 'exit': + break + sock.send((f"hello {data.decode('utf-8')}").encode('utf-8')) + sock.close() + print("Connection from %s:%s closed." % addr) + +if __name__ == "__main__": + # create a socket: Ipv4, TCP + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + # bind a port + s.bind(('127.0.0.1', 9999)) + + # listen a port, argument is max connection count + s.listen(5) + print("waiting for connection...") + # accept connection from client + while True: + # accept a new conection + sock, addr = s.accept() + # create a new thread to handle TCP connection + t = threading.Thread(target=tcplink, args=(sock, addr)) + t.start() diff --git a/Network/TCP/TCPConnection.py b/Network/TCP/TCPConnection.py new file mode 100644 index 0000000..738d228 --- /dev/null +++ b/Network/TCP/TCPConnection.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- + + +import socket + +# create a socket: AF_INET -> ipv4, SOCK_STREAM -> TCP +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +s.connect(('www.baidu.com', 80)) + +# send a request +s.send(b'GET / HTTP/1.1\r\nHost: www.baidu.com\r\nConnection: close\r\n\r\n') + +# receive data +buffer = [] +while True: + # 1 KB every time + d = s.recv(1024) + if d: + buffer.append(d) + else: + break +data = b''.join(buffer) +s.close() + +header, html = data.split(b'\r\n\r\n') +print(header.decode('utf-8')) +with open('baidu.html', 'wb') as f: + f.write(html) \ No newline at end of file diff --git a/Network/TCP/baidu.html b/Network/TCP/baidu.html new file mode 100644 index 0000000..825a874 --- /dev/null +++ b/Network/TCP/baidu.html @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + 百度一下,你就知道 + + + + + + + + +
+ + + + + + + + + + + + diff --git a/Network/UDP/Client.py b/Network/UDP/Client.py new file mode 100644 index 0000000..15270fa --- /dev/null +++ b/Network/UDP/Client.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- + +import socket + +# IPv4, UDP +s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +for data in [b"Alice", b"Bob", b"Mary"]: + s.sendto(data, ('127.0.0.1', 9999)) + print(s.recv(1024).decode('utf-8')) +s.close() \ No newline at end of file diff --git a/Network/UDP/Server.py b/Network/UDP/Server.py new file mode 100644 index 0000000..f835546 --- /dev/null +++ b/Network/UDP/Server.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- + +import socket + +# create a socket: IPv4, UDP +s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +# bind to port +s.bind(('127.0.0.1', 9999)) +print("Bind UDP on 9999...") + +# do not need listen, just receive +while True: + data, addr = s.recvfrom(1024) + print("Received from %s:%s" % addr) + s.sendto(b'hello, %s' % data, addr) \ No newline at end of file diff --git a/OOP/AdvancedOO.py b/OOP/AdvancedOO.py new file mode 100644 index 0000000..b6150f9 --- /dev/null +++ b/OOP/AdvancedOO.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- + +from types import MethodType +from typing import SupportsAbs +from functools import partial + +# bind attribute to obejct dynamically +class Person: + def __init__(self, *args, **kwargs) -> None: + self.age = kwargs.pop("age") + +def setAge(self, age): + self.age = age +def getAge(self): + return self.age +def hello(): + print("hello") + +# bind to a single object +p = Person(age = 20) +p.setAge = MethodType(setAge, p) +p.getAge = MethodType(getAge, p) +p.setAge(10) +print(p.age) # 10 +print(p.getAge()) # 10 + +# bind to class +Person.setAge = MethodType(setAge, Person) +Person.getAge = MethodType(getAge, Person) +Person.setAge(18) +print(Person.getAge()) # 18 +print(Person.age) # 18 + +# bind instance method to class +Person.setAge = setAge +p = Person(age = 10) +p.setAge(100) +print(p.age) # 100 +print(p.getAge()) # 18 +Person.getAge = getAge +print(p.getAge()) # 100 + + +# __slots__ +class Student(object): + __slots__ = ("name", "age", "getName") + def getAge(self): + return self.age + +s = Student() +s.age = 10 +s.name = "Adam" + +def getName(self): + return self.name + +s2 = Student() +s2.age = 20 +s2.name = "lisa" +s2.getName = MethodType(getName, s) +print(s2.getName()) # Adam + +# bound method & function +s = Student() +s.age = 10 +f = s.getAge +print(f) # > +print(Student.getAge) # +print(f()) # 10 +print(Student.getAge(s)) # 10 + +# define a function just like MethodType +def MyMethodType(f, obj): + return partial(f, self = obj) + +print(MyMethodType(getAge, s)) +Student.getName = MyMethodType(getName, Student) +Student.getName() +Student.name = "hello" +print(Student.name) diff --git a/OOP/Class.py b/OOP/Class.py new file mode 100644 index 0000000..ade42a6 --- /dev/null +++ b/OOP/Class.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- + +class Person(object): + def __init__(self, name, age) -> None: + super().__init__() + self.name = name + self.age = age + self.__gender = "female" + def put(self): + print(f"name: {self.name}, age: {self.age}") + def hi(self): + print("hello, self") + self.put() + Person.hello() + def hello(): + print("hello") + +p = Person("lisa", 10) +p.__init__("Adam", 20) +p.put() +p.hi() +Person.hello() + +# add property dynamically +p.gender = "male" +print(p.gender) +print(p._Person__gender) # decorated name \ No newline at end of file diff --git a/OOP/Enum.py b/OOP/Enum.py new file mode 100644 index 0000000..79c45a2 --- /dev/null +++ b/OOP/Enum.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- + +from enum import Enum, unique +WeekDay = Enum('WeekDay', ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')) + +print(WeekDay) +print(WeekDay.Monday) +print(WeekDay['Tuesday']) + +# more precise control about enum +@unique +class WeekD(Enum): + Sun = 0 + Mon = 1 + Tue = 2 + Wed = 3 + Thu = 4 + Fri = 5 + Sat = 6 +print(WeekD) # +print(WeekD.Sun) +print(WeekD["Tue"]) +print(WeekD(1)) +print(WeekD.Fri.value) + +for name, member in WeekD.__members__.items(): + print(name, "->", member) \ No newline at end of file diff --git a/OOP/Inheritance.py b/OOP/Inheritance.py new file mode 100644 index 0000000..70f874d --- /dev/null +++ b/OOP/Inheritance.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- + +class Person: + def __init__(self, name, age) -> None: + super().__init__() + self.__name = name + self.age = age + def sayHello(self): + print("hello in Person") + def getName(self): + return self.__name + def getAge(self): + return self.age + def hi(): + print("hi in Person") + +class Student(Person): + def __init__(self, name, age, score) -> None: + super().__init__(name, age) + self.__name = "default" # new variable, not the __name from Person + self.age = 20 + self.__score = score + def sayHello(self): # override + super().sayHello() + print("hello in Student") + def getName2(self): + return self.__name + def getAge2(self): + return self.age + def hi(): + print("hi in Student") + +p = Person("lisa", 18) +p.sayHello() + +s = Student("lisa", 18, 100) +s.sayHello() +print(s._Person__name) # lisa +print(s._Student__name) # default +print(s.getAge()) # 20 +print(s.getAge2()) # 20 +print(isinstance(s, Person)) # True +print(isinstance(s, object)) # True + +Student.hi() +Person.hi() + +print(isinstance(1, object)) # True +print(isinstance(None, object)) # True +print(isinstance("hello", object)) # True +print(isinstance(True, object)) # True \ No newline at end of file diff --git a/OOP/MeteClass.py b/OOP/MeteClass.py new file mode 100644 index 0000000..1d057dc --- /dev/null +++ b/OOP/MeteClass.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- + + +# create class dynamically using type() +def fn(self, name = "world"): + print(f"hello, {name}!") + +Hello = type("Hello", (object, ), dict(hello = fn)) + +h = Hello() +h.hello() +print(type(h)) # +print(Hello) + + +# create class dynamically using metaclass + +# first define metaclass, derived from type +class ListMetaClass(type): + def __new__(cls, name, bases, attrs): + attrs['add'] = lambda self, value: self.append(value) + return type.__new__(cls, name, bases, attrs) + +# create class using metaclass +class MyList(list, metaclass = ListMetaClass): + pass + +print(MyList) # +print(type(MyList)) # +print(type(ListMetaClass)) # + +l = MyList() +l.add(10) +l.add(100) +print(l) # [10, 100] \ No newline at end of file diff --git a/OOP/MixIn.py b/OOP/MixIn.py new file mode 100644 index 0000000..250f88c --- /dev/null +++ b/OOP/MixIn.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- + +class A(object): + def foo(self): + print('A foo') + def bar(self): + print('A bar') + +class B(object): + def foo(self): + print('B foo') + def bar(self): + print('B bar') + +class C1(A, B): + pass + +class C2(A, B): + def bar(self): + super().bar() + print('C2-bar') + +class D(C1, C2): + pass + +if __name__ == '__main__': + print(D.__mro__) # (, , , , , ) + d = D() + d.foo() # A foo + d.bar() # C2-bar \ No newline at end of file diff --git a/OOP/ORM.py b/OOP/ORM.py new file mode 100644 index 0000000..8a126a6 --- /dev/null +++ b/OOP/ORM.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- + +# a simple ORM(Object Relational Mapping) framwork +# maping one line in database to an object, a table to a class +# define a class according to the data dynamically. + +# ORM frame Model +class Field(object): + def __init__(self, name, column_type): + self.name = name + self.column_type = column_type + def __str__(self): + return f"<{self.__class__.__name__}:{self.name}>" + +class StringField(Field): + def __init__(self, name): + super(StringField, self).__init__(name, 'varchar(100)') + +class IntegerField(Field): + def __init__(self, name): + super(IntegerField, self).__init__(name, 'bigint') + +class ModelMetaClass(type): + def __new__(cls, name, bases, attrs): + if name == 'Model': + return type.__new__(cls, name, bases, attrs) + print(f'Found Model: {name}') + mappings = dict() + for k, v in attrs.items(): + if isinstance(v, Field): + print(f'Found mapping: {k} => {v}') + mappings[k] = v + for k in mappings.keys(): # delete class attributes from table class. + attrs.pop(k) + attrs['__mappings__'] = mappings # save the mapping between atrribute and column + attrs['__table__'] = name # name of table, assume that is same as class name + return type.__new__(cls, name, bases, attrs) + +# derived from dict, add an attribute will add to dict +class Model(dict, metaclass = ModelMetaClass): + def __init__(self, **kw): + super(Model, self).__init__(**kw) + + def __getattr__(self, key): + try: + return self[key] + except KeyError: + raise AttributeError(f"'Model' objct has no attribute {key}") + + def __setattr__(self, key, value) -> None: + self[key] = value + + def save(self): + fields = [] + params = [] + args = [] + for k, v in self.__mappings__.items(): + fields.append(v.name) + params.append('?') + args.append(getattr(self, k, None)) + sql = f"insert into {self.__table__} ({','.join(fields)}) values {','.join(params)}" + print(f"SQL: {sql}") + print(f'ARGS: {args}') + + # other operations like: delete, find, update, ... + + +# using like this +# map to table User +class User(Model): + id = IntegerField('id') + name = StringField("username") + email = StringField("email") + password = StringField("password") + +# create instance, map to one line in table User +u = User(id = 12345, name = "Adam", email = "Adam@orm.org", password = "my-passwd") +# save to databse +u.save() diff --git a/OOP/ObjectTypeInfo.py b/OOP/ObjectTypeInfo.py new file mode 100644 index 0000000..531e1d5 --- /dev/null +++ b/OOP/ObjectTypeInfo.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- + +import types +from typing import get_args + +print(type(1)) # +print(type(1) == type(13)) + +print(type(type(1))) # +print(type(abs)) # +print(type(int)) # + +print(int) + +def f(): + pass + +# all True +print(type(1) == int) +print(type(type) == type) +print(type(object) == type) +print(type(int) == type) +print(type(f) == types.FunctionType) +print(type(abs) == types.BuiltinFunctionType) +print(type(x for x in range(100)) == types.GeneratorType) +print(type([].append) == types.BuiltinMethodType) +print(type(lambda x : x) == types.LambdaType) + +# isinstance +print(isinstance([], (list, tuple))) + +print("===============================") +# dir, getattr(), setattr(), hasattr() +class Person(): + className = "Person" + def __init__(self, name) -> None: + self.name = name + def sayHi(self): + print(f"hi, {self.name}") + def sayHello(): + print("hello") + +p = Person("Adam") +print(dir(p)) +print(hasattr(p, "name")) +setattr(p, "age", 10) +print(p.age) +print(getattr(p, "age")) +print(getattr(p, "nonexist", "default value")) + +f = getattr(Person, "sayHello") +f() +print(f) # +f = getattr(p, "sayHi") +f() +print(f) # > + +print(p.className) +print(Person.className) \ No newline at end of file diff --git a/OOP/Property.py b/OOP/Property.py new file mode 100644 index 0000000..5cfcbe2 --- /dev/null +++ b/OOP/Property.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +class Person: + __slots__ = ("_age") + @property + def age(self): + return self._age + @age.setter + def age(self, value): + if not isinstance(value, int): + raise ValueError("age must be a integer!") + if value < 0: + raise ValueError("age must non-negative!") + self._age = value + +p = Person() +p.age = 10 +print(p.age) +p.age = "18" # ValueError: age must be a integer! \ No newline at end of file diff --git a/OOP/SpecialMethods.py b/OOP/SpecialMethods.py new file mode 100644 index 0000000..fb5d22a --- /dev/null +++ b/OOP/SpecialMethods.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- + +from typing import Iterable, Iterator + +# more about special methods and attributes: https://docs.python.org/zh-cn/3/reference/datamodel.html#special-method-names + +# __str__ +class Person: + def __init__(self, name, age) -> None: + self.name = name + self.age = age + def __str__(self) -> str: + return f"Person: name: {self.name}, age: {self.age}" + __repr__ = __str__ + def __call__(self): + print(f"Call from Person object") + +if __name__ == "__main__": + print(Person("Adam", 20)) + Person("Adam", 18)() \ No newline at end of file diff --git a/README.md b/README.md index da477ba..57c915b 100644 --- a/README.md +++ b/README.md @@ -1,114 +1,3 @@ -# 个人备忘录 - -# Github上的仓库 - -选入标准:觉得有趣,拿来玩,看一看学习,很牛,学习方向,时下流行。 - - -## Cpp - -- [vczh/vczh_toys][cpp-1]——轮子哥的黑魔法玩具与实验,学习学习。 -- [vczh/tinymoe][cpp-2]——轮子哥的动态类型编程语言,学习编译原理。 -- [vczh-libraries/GacUI][cpp-3]——轮子哥的C++界面库,支持GPU加速。 -- [wuye9036/cppTemplateTutorial][cpp-4]——C++模板编程入门进阶教程,可惜作者没有写完,有机会的话可以PR。 -- [duilib/duilib][cpp-5]——一个C++轻量级UI库。 - -[cpp-1]: https://github.com/vczh/vczh_toys -[cpp-2]: https://github.com/vczh/tinymoe -[cpp-3]: https://github.com/vczh-libraries/GacUI -[cpp-4]: https://github.com/wuye9036/cppTemplateTutorial -[cpp-5]: https://github.com/duilib/duilib - - -## 图形学 - -- [ssloy/tinyrenderer][graphics-1]——OpenGL的渲染器课程,使用OpenGL。 -- [TensShinet/toy_renderer][graphics-2]——一个大佬学习上面课程的记录。 -- [yangzhenzhuozz/Renderer][graphics-3]——基于EasyX实现一个3D渲染器,有文档提供入门教程。 -- [matrixcascade/PainterEngine][graphics-4]——一个高度可移植完整开源的游戏引擎,使用C/C++。 -- [miloyip/light2d][graphics-5]——2D图形学光照入门。 - - -[graphics-1]: https://github.com/ssloy/tinyrenderer -[graphics-2]: https://github.com/TensShinet/toy_renderer -[graphics-3]: https://github.com/yangzhenzhuozz/Renderer -[graphics-4]: https://github.com/matrixcascade/PainterEngine -[graphics-5]: https://github.com/miloyip/light2d - - -## Windows/Microsoft - -- [PowerShell/PowerShell][windows-1]——Windows PowerShell。 -- [microsoft/TypeScript][windows-2]——微软亲生TS语言。 -- [microsoft/Windows-classic-samples][windows-3]——WindowsAPI编程实例。 -- [microsoft/calculator][windows-4]——win10上的计算器。 - -[windows-1]: https://github.com/PowerShell/PowerShell -[windows-2]: https://github.com/microsoft/TypeScript -[windows-3]: https://github.com/microsoft/Windows-classic-samples -[windows-4]: https://github.com/microsoft/calculator - - -## VSCode插件 - -- [hediet/vscode-drawio][vscode-1]——在VSCode里面画图。 -- [shd101wyy/markdown-preview-enhanced][vscode-2]——MarkDown插件。 - -[vscode-1]: https://github.com/hediet/vscode-drawio -[vscode-2]: https://github.com/shd101wyy/markdown-preview-enhanced - - -## 面试、知识体系、技能树、教程 - -- [qianguyihao/Web][skilltree-1]——前端入门进阶学习笔记。 -- [LearnOpenGL-CN/LearnOpenGL-CN][skilltree-2]——LeanOpenGL教程中文翻译。 -- [linw7/Skill-Tree][skilltree-3]——后端开发面试知识体系。 -- [zhengjianglong915/note-of-interview][skilltree-4]——互联网面试笔记。 -- [CyC2018/CS-Notes][skilltree-5]——技术面试必备基础知识,计算机体系。 - -[skilltree-1]: https://github.com/qianguyihao/Web -[skilltree-2]: https://github.com/LearnOpenGL-CN/LearnOpenGL-CN -[skilltree-3]: https://github.com/linw7/Skill-Tree -[skilltree-4]: https://github.com/zhengjianglong915/note-of-interview -[skilltree-5]: https://github.com/CyC2018/CS-Notes - - -## 前端 - -- [markdown-it/markdown-it][frontend-1]——一个MarkDown解析器。 - -[frontend-1]: https://github.com/markdown-it/markdown-it - -## AI - -- [lllyasviel/style2paints][ai-1]——二次元线稿自动上色的引擎。 - - -[ai-1]: https://github.com/lllyasviel/style2paints - - -## 工具 - -- [OpenCppCoverage/OpenCppCoverage][tools-1]——C++覆盖率测试工具。 -- [skywind3000/awesome-cheatsheets][tools-2]——编程语言、开发工具速查表。 - -[tools-1]: https://github.com/OpenCppCoverage/OpenCppCoverage -[tools-2]: https://github.com/skywind3000/awesome-cheatsheets - - -## 编译原理 - -- [miloyip/json-tutorial][compiler-1]——从零开始的JSON库教程。 -- [fool2fish/dragon-book-exercise-answers][compiler-2]——龙书第二版课后习题答案。 - -[compiler-1]: https://github.com/miloyip/json-tutorial -[compiler-2]: https://github.com/fool2fish/dragon-book-exercise-answers - - -## 娱乐项目 - -- [komeiji-satori/Dress][fun-1]——女装。 -- [995icu/996ICU][fun-2]——996.ICU。 - -[fun-1]: https://github.com/komeiji-satori/Dress -[fun-2]: https://github.com/995icu/996ICU \ No newline at end of file +## Python入门笔记 + +测试用的代码,笔记在[主分支的Python.md](../../blob/master/Python.md)。 \ No newline at end of file diff --git a/Regex/Re.py b/Regex/Re.py new file mode 100644 index 0000000..5a286c2 --- /dev/null +++ b/Regex/Re.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- + +import re + +print(re.match(r"^\d{3}-\d{3,8}", "012-23423")) +print(re.split(r'\s+', 'a b c')) # ['a', 'b', 'c'] +print(re.split(r'\$\^\.\{\}', 'a$^.{}b$^.c$')) +print(re.match(r'^(\d+?)(0*)$', '102300').groups()) # non-greedy matching of \d+? + +print(type(re.compile(r"\d+$"))) + +# test if a string is a email address +def is_valid_email(addr): + regex = r"\w+(\.\w+)*@\w+.\w+" + return re.match(regex, addr) != None + +assert is_valid_email('someone@gmail.com') +assert is_valid_email('bill.gates@microsoft.com') +assert not is_valid_email('bob#example.com') +assert not is_valid_email('mr-bob@example.com') + +def name_of_email(addr): + m1 = re.match(r"<([\w\s]+)>\s([a-zA-Z]+)@\w+.\w+", addr) + m2 = re.match(r"([a-zA-Z]+)@\w+.\w+", addr) + if m1 == None and m2 == None: + return None + elif m1 != None: + return m1.group(1) + else: + return m2.group(1) + +assert name_of_email(' tom@voyager.org') == 'Tom Paris' +assert name_of_email('tom@voyager.org') == 'tom' \ No newline at end of file diff --git a/SQL/MySQLTest.py b/SQL/MySQLTest.py new file mode 100644 index 0000000..0557f95 --- /dev/null +++ b/SQL/MySQLTest.py @@ -0,0 +1,24 @@ +import mysql.connector + +with mysql.connector.connect(host = 'localhost', user = 'root', password = 'aojue', database = 'test') as conn: + cursor = conn.cursor() + cursor.execute('select * from students') + values = cursor.fetchall() + for x in values: + print(x) + cursor.execute("show tables") + for x in cursor: + print(x) + cursor.close() + +import pymysql +with pymysql.connect(host = 'localhost', user='root', password='aojue', database='test') as conn: + cursor = conn.cursor() + cursor.execute('select * from students') + values = cursor.fetchall() + for x in values: + print(x) + cursor.execute("show tables") + for x in cursor: + print(x) + cursor.close() \ No newline at end of file diff --git a/SQL/SQLAlchemyTest.py b/SQL/SQLAlchemyTest.py new file mode 100644 index 0000000..e3ae025 --- /dev/null +++ b/SQL/SQLAlchemyTest.py @@ -0,0 +1,50 @@ +from sqlalchemy import Column, String, create_engine +from sqlalchemy.orm import sessionmaker +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.sql.ddl import DDLBase +import sqlalchemy + +# create a base class +Base = declarative_base() + +# define ORM class +class User(Base): + # table name + __tablename__ = 'user' + # table structrue + id = Column(String(20), primary_key=True) + name = Column(String(20)) + +# initialize database connection +# databse+connector://user:password@host:port/database +engine = create_engine('mysql+mysqlconnector://root:aojue@localhost:3306/test') +# create DBSession class +DBSession = sessionmaker(bind=engine) + +### create table: CREATE TABLE ... +Base.metadata.create_all(engine) + +### add new record: INSERT INTO ... +# create DbSession object +session = DBSession() + +# delete all records in User table +users = session.query(User).filter() +print(users.all()) +for user in users.all(): + session.delete(user) + +# create new User object +new_user = User(id = '5', name = 'Bob') +# add to session +session.add(new_user) +# commit to database +session.commit() +session.close() + +### query: SELECT ... FROM ... +session = DBSession() +user = session.query(User).filter(User.id == 5).one() +print('type: ', type(user)) +print('name: ', user.name) +session.close() \ No newline at end of file diff --git a/SQL/SQLiteTest.py b/SQL/SQLiteTest.py new file mode 100644 index 0000000..f008fcc --- /dev/null +++ b/SQL/SQLiteTest.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- + +import sqlite3 + +import sqlite3 + +# connect to sqlite3 database, the database is file test.db, if not exist, will create a new file +with sqlite3.connect('test.db') as conn: + # creat a cursor + cursor = conn.cursor() + # execute SQL + cursor.execute('drop table if exists user') + cursor.execute('create table user (id varchar(20) primary key, name varchar(20), score int)') + cursor.execute(r'insert into user (id, name, score) values ("1", "Michael", 90)') + cursor.execute(r'insert into user (id, name, score) values ("2", "Kim", 80)') + cursor.execute(r'insert into user (id, name, score) values ("3", "Bob", 65)') + + print(cursor.rowcount) + + # querys + cursor.execute('select * from user where id=? or id=?', ('1','2')) + + values = cursor.fetchall() + print(values) + + # close + cursor.close() # not necessary, __del__ will close automatically + conn.commit() + + def get_score_in(con, min, max): + cursor = conn.cursor() + cursor.execute(r'select name from user where score >= ? and score <= ?', (min, max)) + values = cursor.fetchall() + cursor.close() + return [v[0] for v in values] + + assert get_score_in(conn, 85, 100) == ['Michael'] + assert get_score_in(conn, 70, 100) == ['Michael', 'Kim'] + assert get_score_in(conn, 60, 100) == ['Michael', 'Kim', 'Bob'] \ No newline at end of file diff --git a/ThirdPartyLibs/ChardetTest.py b/ThirdPartyLibs/ChardetTest.py new file mode 100644 index 0000000..5e5097a --- /dev/null +++ b/ThirdPartyLibs/ChardetTest.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- + +import chardet +print(chardet.detect(b'Hello, world!')) + +data = '你好,世界!'.encode('gbk') +print(chardet.detect(data)) # {'encoding': None, 'confidence': 0.0, 'language': None}, why? + +data = '你好,世界!'.encode('utf-8') +print(chardet.detect(data)) + +data = '最新の主要ニュース'.encode('euc-jp') +print(chardet.detect(data)) \ No newline at end of file diff --git a/ThirdPartyLibs/PillowTest.py b/ThirdPartyLibs/PillowTest.py new file mode 100644 index 0000000..e276d7c --- /dev/null +++ b/ThirdPartyLibs/PillowTest.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from PIL import Image, ImageFilter + +# open an image +im = Image.open('nephren.png') +# get image size +w, h = im.size +print('Original image size: %sx%s' % (w, h)) +# resize to 50% +im.thumbnail((w//2, h//2)) +print('Resize image to: %sx%s' % (w//2, h//2)) +# save scaled image +im.save('thumbnail.png', 'png') + +# blur an iamge +im = Image.open('nephren.png') +im2 = im.filter(ImageFilter.BLUR) +im2.save('blur.png', 'png') \ No newline at end of file diff --git a/ThirdPartyLibs/PsUtilTest.py b/ThirdPartyLibs/PsUtilTest.py new file mode 100644 index 0000000..5e45fb3 --- /dev/null +++ b/ThirdPartyLibs/PsUtilTest.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- + +import psutil + +# CPU info +print(psutil.cpu_count()) # logical cpu count +print(psutil.cpu_count(logical=False)) # physical cpy count +print(psutil.cpu_times()) + +# print the usage of every cpu core, 5 times in one second +for x in range(5): + print(psutil.cpu_percent(interval=0.2, percpu=True)) + +# memory and swap memory info +print(psutil.virtual_memory()) +print(psutil.swap_memory()) + +# internet +print(psutil.net_io_counters()) +print(psutil.net_if_addrs()) # port info +print(psutil.net_if_stats()) # port status +print(psutil.net_connections()) + +# process +print(psutil.pids()) +p = psutil.Process(psutil.pids()[-1]) +print(p.exe()) # executable of process +print(p.cwd()) # working directory of process +print(p.cmdline()) # cmd line of process +print(p.ppid()) # parent process id +print(p.parent()) # parent process +print(p.children()) # children processes +print(p.status()) # status +print(p.username()) +print(p.create_time()) +# print(p.terminal()) # Unix only +print(p.cpu_times()) +print(p.memory_info()) +print(p.connections()) # internet connections +print(p.num_threads()) +print(p.threads()) +print(p.environ()) # environment variables of process + +# like ps command +print(psutil.test()) \ No newline at end of file diff --git a/ThirdPartyLibs/RequestsTest.py b/ThirdPartyLibs/RequestsTest.py new file mode 100644 index 0000000..f29afc1 --- /dev/null +++ b/ThirdPartyLibs/RequestsTest.py @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- + +import requests +r = requests.get('https://baidu.com') +print(r.status_code) +print(r.text) +print(r.encoding) +print(r.content.decode('utf-8')) diff --git a/ThirdPartyLibs/nephren.png b/ThirdPartyLibs/nephren.png new file mode 100644 index 0000000..336f085 Binary files /dev/null and b/ThirdPartyLibs/nephren.png differ diff --git a/VeryStarted/hello.py b/VeryStarted/hello.py new file mode 100644 index 0000000..6909ee2 --- /dev/null +++ b/VeryStarted/hello.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +print("hello,world!") + +print("the quick brown fox jumps over the lazy dog's back.") \ No newline at end of file diff --git a/Web/FlaskTemplateTest.py b/Web/FlaskTemplateTest.py new file mode 100644 index 0000000..9e4b33f --- /dev/null +++ b/Web/FlaskTemplateTest.py @@ -0,0 +1,22 @@ +from flask import Flask, request, render_template + +app = Flask(__name__) + +@app.route('/', methods=['GET', 'POST']) +def home(): + return render_template('home.html') + +@app.route('/signin', methods=['GET']) +def signin_form(): + return render_template('form.html') + +@app.route('/signin', methods=['POST']) +def signin(): + username = request.form['username'] + password = request.form['password'] + if username == 'admin' and password == 'password': + return render_template('signin-ok.html', username=username) + return render_template('form.html', message='Bad username or password', username=username) + +if __name__ == '__main__': + app.run() \ No newline at end of file diff --git a/Web/FlaskTest.py b/Web/FlaskTest.py new file mode 100644 index 0000000..87b67be --- /dev/null +++ b/Web/FlaskTest.py @@ -0,0 +1,26 @@ +from flask import Flask +from flask import request + +app = Flask(__name__) + +@app.route('/', methods=['GET', 'POST']) +def home(): + return '

Home

' + +@app.route('/signin', methods=['GET']) +def signin_form(): + return '''
+

+

+

+
''' + +@app.route('/signin', methods=['POST']) +def signin(): + # 需要从request对象读取表单内容: + if request.form['username']=='admin' and request.form['password']=='password': + return '

Hello, admin!

' + return '

Bad username or password.

' + +if __name__ == '__main__': + app.run() \ No newline at end of file diff --git a/Web/WSGITest.py b/Web/WSGITest.py new file mode 100644 index 0000000..ef969a4 --- /dev/null +++ b/Web/WSGITest.py @@ -0,0 +1,10 @@ +from wsgiref.simple_server import make_server + +def application(environ, start_response): + start_response('200 OK', [('Content-Type', 'text/html')]) # header, response code and header content + return [b'

Hello, web!

'] # body + +# create a http server +httpd = make_server('', 8000, application) +print("Serving HTTP on port 8000...") +httpd.serve_forever() \ No newline at end of file diff --git a/Web/templates/form.html b/Web/templates/form.html new file mode 100644 index 0000000..29c260b --- /dev/null +++ b/Web/templates/form.html @@ -0,0 +1,16 @@ + + + Please Sign In + + + {% if message %} +

{{ message }}

+ {% endif %} +
+ Please sign in: +

+

+

+
+ + \ No newline at end of file diff --git a/Web/templates/home.html b/Web/templates/home.html new file mode 100644 index 0000000..d310726 --- /dev/null +++ b/Web/templates/home.html @@ -0,0 +1,8 @@ + + + Home + + +

Home

+ + \ No newline at end of file diff --git a/Web/templates/signin-ok.html b/Web/templates/signin-ok.html new file mode 100644 index 0000000..5469d13 --- /dev/null +++ b/Web/templates/signin-ok.html @@ -0,0 +1,8 @@ + + + Welcome, {{ username }} + + +

Welcome, {{ username }}!

+ + \ No newline at end of file