From 60e47f902d1a53cb0376bc30166e730c32441cba Mon Sep 17 00:00:00 2001 From: Henocks Date: Wed, 2 Nov 2016 09:40:43 +0900 Subject: [PATCH 01/29] Update rpmdb.py --- py2016/rpmdb.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/py2016/rpmdb.py b/py2016/rpmdb.py index e561c36..56ba747 100644 --- a/py2016/rpmdb.py +++ b/py2016/rpmdb.py @@ -77,6 +77,7 @@ def check_db(module, timeout=10): elapsed_time = 0 cmd = '%s -qa &> %s' % (RPMBIN, logfile) child = subprocess.Popen(cmd, shell=True) + while elapsed_time <= timeout: child_ret = child.poll() if child_ret is None: # child still running @@ -112,8 +113,8 @@ def main(): # defining module module = AnsibleModule( argument_spec=dict( - action=dict(required=False, default='check', choices=['check', 'rebuild']), - timeout=dict(required=False, default=10, type='int') + action = dict(required=False, default='check', choices=['check', 'rebuild']), + timeout = dict(required=False, default=10, type='int') ) ) @@ -126,13 +127,14 @@ def main(): if action == 'check': rc = check_db(module, timeout) if rc == 1: - module.fail_json(msg='Error when running cmd: %s' % check_cmd) + module.fail_json(msg='Error when running cmd: %s' % (check_cmd)) elif rc == 2: module.fail_json(msg='return code error. cmd: %s' % (check_cmd)) elif rc == 3: - module.fail_json(msg='Timeout %d s. cmd: %s' % (timeout, check_cmd)) + module.fail_json(msg='Timeout %d s. cmd: %s' % (timeout, check_cmd)) elif rc == 0: msg = 'OK. cmd: %s' % check_cmd + elif action == 'rebuild': rc = check_db(module, timeout) if rc != 0: @@ -144,9 +146,9 @@ def main(): module.fail_json(msg=msg) module.exit_json( - changed=changed, - action=action, - msg=msg + changed = changed, + action = action, + msg = msg ) # this is magic, see lib/ansible/executor/module_common.py From d169bfe4e77bcb1b7f5379af37659137a637a7b5 Mon Sep 17 00:00:00 2001 From: Jay Date: Wed, 28 Nov 2018 12:53:30 +0800 Subject: [PATCH 02/29] set/check localtime with internet --- py2018/set_check_localtime.py | 68 +++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 py2018/set_check_localtime.py diff --git a/py2018/set_check_localtime.py b/py2018/set_check_localtime.py new file mode 100644 index 0000000..1e0c776 --- /dev/null +++ b/py2018/set_check_localtime.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 + +import sys +import time +import subprocess +import argparse +import urllib2 + + +def set_beijing_time_from_web(url): + ''' set os and hardware clock as beijing time from internet ''' + # use urllib2 in python2; not use requests which need installation + response = urllib2.urlopen(url) + #print response.read() + # 获取http头date部分 + ts = response.headers['date'] + # 将日期时间字符转化为time + gmt_time = time.strptime(ts[5:25], "%d %b %Y %H:%M:%S") + # 将GMT时间转换成北京时间 + local_time = time.localtime(time.mktime(gmt_time) + 8*3600) + str1 = "%u-%02u-%02u" % (local_time.tm_year, + local_time.tm_mon, local_time.tm_mday) + str2 = "%02u:%02u:%02u" % ( + local_time.tm_hour, local_time.tm_min, local_time.tm_sec) + cmd = 'date -s "%s %s"' % (str1, str2) + #print cmd + subprocess.check_call(cmd, shell=True) + hw_cmd = 'hwclock -w' + #print hw_cmd + subprocess.check_call(hw_cmd, shell=True) + print 'OK. set time: %s' % ' '.join([str1, str2]) + + +def check_localtime_with_internet(url): + ''' check local time with internet ''' + threshold = 2 + # use urllib2 in python2; not use requests which need installation + response = urllib2.urlopen(url) + #print response.read() + # 获取http头date部分 + ts = response.headers['date'] + # 将日期时间字符转化为time + gmt_time = time.strptime(ts[5:25], "%d %b %Y %H:%M:%S") + # 将GMT时间转换成北京时间 + internet_ts = time.mktime(gmt_time) + local_ts = time.mktime(time.gmtime()) + if abs(local_ts - internet_ts) <= threshold: + print 'OK. check localtime.' + else: + print 'ERROR! local_ts: %s internet_ts:%s' % (local_ts, internet_ts) + sys.exit(1) + + +if __name__ == '__main__': + url = 'http://www.baidu.com' + parser = argparse.ArgumentParser() + parser.description = 'set/check localtime (i.e. CST) with internet' + parser.add_argument('-c', '--check', action='store_true', + help='only check local time') + parser.add_argument('-s', '--set', action='store_true', + help='only set local time') + parser.add_argument('-u', '--url', default=url, + help='the url to sync time') + args = parser.parse_args() + if args.set: + set_beijing_time_from_web(args.url) + else: + check_localtime_with_internet(args.url) From 27324bc10c21e3c2d5115e5403a8d0b8d318dc2a Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 18 Jul 2020 20:25:52 +0800 Subject: [PATCH 03/29] update non-recursion method to fibonacci --- py2014/fibonacci.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/py2014/fibonacci.py b/py2014/fibonacci.py index c47c965..98d40b2 100644 --- a/py2014/fibonacci.py +++ b/py2014/fibonacci.py @@ -2,6 +2,7 @@ def fib1(n): + ''' normal recursion ''' if n == 0: return 0 elif n == 1: @@ -14,6 +15,7 @@ def fib1(n): def fib2(n): + ''' recursion with cached results ''' if n in known: return known[n] @@ -22,6 +24,30 @@ def fib2(n): return res +def fib3(n): + ''' non-recursion ''' + last1 = 0 + last2 = 1 + if n == 0: + return 0 + elif n == 1: + return 1 + elif n >= 2: + for _ in range(2, n+1): + res = last1 + last2 + last1 = last2 + last2 = res + return last2 + + +def fib4(n): + ''' use a list to store all the results ''' + l = [0, 1] + for i in range(2, n+1): + l.append(l[i-2] + l[i-1]) + return l[n] + + if __name__ == '__main__': n = 40 print(datetime.datetime.now()) @@ -29,3 +55,7 @@ def fib2(n): print(datetime.datetime.now()) print('fib2(%d)=%d' % (n, fib2(n))) print(datetime.datetime.now()) + print('fib3(%d)=%d' % (n, fib3(n))) + print(datetime.datetime.now()) + print('fib4(%d)=%d' % (n, fib4(n))) + print(datetime.datetime.now()) From 70e807eacb83497ace4aebc6fbaad66fda8ab59b Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 18 Jul 2020 21:34:56 +0800 Subject: [PATCH 04/29] add try_collections.py --- py2016/try_collections.py | 46 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 py2016/try_collections.py diff --git a/py2016/try_collections.py b/py2016/try_collections.py new file mode 100644 index 0000000..7c9a940 --- /dev/null +++ b/py2016/try_collections.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- + +from collections import defaultdict + +colors = ['red', 'green', 'white', 'red', 'blue', 'red'] + +d = {} +for c in colors: + if c not in d: + d[c] = 0 + d[c] += 1 +print(d) + +d1 = {} +for c in colors: + d1[c] = d1.get(c, 0) + 1 +print(d1) + +d2 = defaultdict(int) +for c in colors: + d2[c] += 1 +print(d2) + + +from collections import OrderedDict +od = OrderedDict() +od['z'] = 1 +od['y'] = 2 +od['x'] = 3 +print(od.keys()) # 按照插入的Key的顺序返回 + + +from collections import deque + +# 双端队列 +q = deque(['a', 'b', 'c']) +q.append('x') +q.appendleft('y') +print(q) + + +from collections import Counter +c = Counter() +for ch in 'helloworld': + c[ch] = c[ch] + 1 +print(c) \ No newline at end of file From e143dd219e3c9d3498727ecda53a2849915fd9e2 Mon Sep 17 00:00:00 2001 From: Jay Date: Sun, 19 Jul 2020 00:00:42 +0800 Subject: [PATCH 05/29] update .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 9ba0fba..b6c2344 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ build *.pyc *.swp *.log +.DS_Store +.vscode From 08209f21696fff1069cdd720b8bb951240a8690c Mon Sep 17 00:00:00 2001 From: Jay Date: Sun, 19 Jul 2020 00:01:03 +0800 Subject: [PATCH 06/29] decorator example --- py2020/test_decorator.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 py2020/test_decorator.py diff --git a/py2020/test_decorator.py b/py2020/test_decorator.py new file mode 100644 index 0000000..4c893d5 --- /dev/null +++ b/py2020/test_decorator.py @@ -0,0 +1,31 @@ +from functools import wraps + + +''' useful doc: https://www.runoob.com/w3cnote/python-func-decorators.html ''' + +def logit(logfile='logit.log'): + def logging_decorator(func): + @wraps(func) + def wrapped_function(*args, **kwargs): + log_string = func.__name__ + " was called" + print(log_string) + with open(logfile, 'a') as opened_file: + opened_file.write(log_string + '\n') + return func(*args, **kwargs) + return wrapped_function + return logging_decorator + + +@logit() +def myfunc1(): + pass + + +@logit(logfile='func2.log') +def myfunc2(): + pass + + +if __name__ == '__main__': + myfunc1() + myfunc2() \ No newline at end of file From 0a80d39132fceffcc844931f9af5dad7f08187b8 Mon Sep 17 00:00:00 2001 From: Jay Date: Mon, 20 Jul 2020 00:30:28 +0800 Subject: [PATCH 07/29] use asyncio to crawl urls --- py2020/crawler_douban_movie.py | 48 ++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 py2020/crawler_douban_movie.py diff --git a/py2020/crawler_douban_movie.py b/py2020/crawler_douban_movie.py new file mode 100644 index 0000000..e5133ba --- /dev/null +++ b/py2020/crawler_douban_movie.py @@ -0,0 +1,48 @@ +import time +import asyncio +import aiohttp +from bs4 import BeautifulSoup + + +async def fetch_content(url): + default_header = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:77.0) Gecko/20100101 Firefox/77.0"} + async with aiohttp.ClientSession( + headers=default_header, connector=aiohttp.TCPConnector(ssl=False) + ) as session: + async with session.get(url) as response: + return await response.text() + + +async def main(): + url = "https://movie.douban.com/cinema/later/hangzhou/" + init_page = await fetch_content(url) + init_soup = BeautifulSoup(init_page, 'lxml') + + movie_names, urls_to_fetch, movie_dates = [], [], [] + + all_movies = init_soup.find('div', id="showing-soon") + for each_movie in all_movies.find_all('div', class_="item"): + all_a_tag = each_movie.find_all('a') + all_li_tag = each_movie.find_all('li') + + movie_names.append(all_a_tag[1].text) + urls_to_fetch.append(all_a_tag[1]['href']) + movie_dates.append(all_li_tag[0].text) + + tasks = [fetch_content(url) for url in urls_to_fetch] + pages = await asyncio.gather(*tasks) + + for movie_name, movie_date, page in zip(movie_names, movie_dates, pages): + soup_item = BeautifulSoup(page, 'lxml') + img_tag = soup_item.find('img') + + print('{} {} {}'.format(movie_name, movie_date, img_tag['src'])) + + +if '__name__' == '__main__': + start = time.time() + print('start: {}'.format(start)) + asyncio.run(main()) + end = time.time() + print('end: {}'.format(end)) + print('it took {} seconds.'.format(end - start)) From e4c91b0f8ea66ec59a2dc988518ba910dd4acc85 Mon Sep 17 00:00:00 2001 From: Vinayak-cody <72245620+Vinayak-cody@users.noreply.github.com> Date: Fri, 2 Oct 2020 12:17:10 +0530 Subject: [PATCH 08/29] Error in the code --- py2015/try_requests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/py2015/try_requests.py b/py2015/try_requests.py index b5d37ed..36fc8c5 100644 --- a/py2015/try_requests.py +++ b/py2015/try_requests.py @@ -17,4 +17,5 @@ headers = {'User-Agent': 'Mozilla/5.0 (Macintosh) Gecko/20100101 Firefox/38.0'} request = requests.get(url, headers=headers) if request.ok: - print request.text + print(request.text) + From 61dcd6082d2ee0f0befa09a9247494b3629f9867 Mon Sep 17 00:00:00 2001 From: Archana Mondal <71519727+archu2020@users.noreply.github.com> Date: Fri, 2 Oct 2020 20:42:34 +0530 Subject: [PATCH 09/29] Update mem_profile.py --- py2014/mem_profile.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/py2014/mem_profile.py b/py2014/mem_profile.py index 9860361..5c787f5 100644 --- a/py2014/mem_profile.py +++ b/py2014/mem_profile.py @@ -33,6 +33,6 @@ def f(a, n=100): if __name__ == '__main__': a = my_func() - print cur_python_mem() - print "" - print memory_usage((f, (1,), {'n': int(1e6)}), interval=0.5) + print ("cur_python_mem()") + print ("") + print (f"memory_usage((f, (1,), {'n': int(1e6)}), interval=0.5)") From 4025e9f8d55f428c9dc72465a58c2670ec33de2b Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 28 Nov 2020 00:37:01 +0800 Subject: [PATCH 10/29] add utils/run_cmd.py for dealing with shell cmd --- utils/run_cmd.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 utils/run_cmd.py diff --git a/utils/run_cmd.py b/utils/run_cmd.py new file mode 100644 index 0000000..d758e98 --- /dev/null +++ b/utils/run_cmd.py @@ -0,0 +1,22 @@ +from subprocess import Popen, PIPE, STDOUT + +def shell_output(cmd): + ''' execute a shell command and get its output (stdout/stderr) ''' + p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT) + return p.communicate()[0] + + +def shell_rc_and_output(cmd): + ''' execute a shell command and get its return code and output (stdout/stderr) ''' + p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT) + out = p.communicate()[0] + rc = p.returncode + return rc, out + + +if __name__ == "__main__": + cmd = 'ls -l' + print(shell_output(cmd)) + rc, out = shell_rc_and_output(cmd) + print(rc) + print('rc: {}, out: {}'.format(rc, out)) From 3987799136aa83f387ed20b10f88f2ffa51583ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=AC=91=E9=81=8D=E4=B8=96=E7=95=8C?= Date: Sat, 5 Dec 2020 22:54:56 +0800 Subject: [PATCH 11/29] Revert "Update mem_profile.py" --- py2014/mem_profile.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/py2014/mem_profile.py b/py2014/mem_profile.py index 5c787f5..9860361 100644 --- a/py2014/mem_profile.py +++ b/py2014/mem_profile.py @@ -33,6 +33,6 @@ def f(a, n=100): if __name__ == '__main__': a = my_func() - print ("cur_python_mem()") - print ("") - print (f"memory_usage((f, (1,), {'n': int(1e6)}), interval=0.5)") + print cur_python_mem() + print "" + print memory_usage((f, (1,), {'n': int(1e6)}), interval=0.5) From a4c207bea01fdcc018040fe82848172421f4152a Mon Sep 17 00:00:00 2001 From: Jay Date: Mon, 5 Apr 2021 00:03:56 +0800 Subject: [PATCH 12/29] leetcode: add intersection.py --- leetcode/easy/intersection.py | 50 +++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 leetcode/easy/intersection.py diff --git a/leetcode/easy/intersection.py b/leetcode/easy/intersection.py new file mode 100644 index 0000000..2a16a13 --- /dev/null +++ b/leetcode/easy/intersection.py @@ -0,0 +1,50 @@ +# -*- coding:UTF-8 -*- +''' +给定两个数组,编写一个函数来计算它们的交集。 + +示例 1: +输入:nums1 = [1,2,2,1], nums2 = [2,2] +输出:[2] + +示例 2: +输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4] +输出:[9,4] + + +说明: + * 输出结果中的每个元素一定是唯一的。 + * 我们可以不考虑输出结果的顺序。 + +来源:力扣(LeetCode) +链接:https://leetcode-cn.com/problems/intersection-of-two-arrays +''' + +class Solution(object): + def intersection(self, nums1, nums2): + """ + :type nums1: List[int] + :type nums2: List[int] + :rtype: List[int] + """ + """ + 元组set 是基于Hash来实现的,故: + 1. set 中的元素必须唯一(不可重复) + 2. set 中的元素必须是Hashable的 + 3. 向集合中添加元素、删除元素、检查元素是否存在,都是非常快速的。平均时间复杂度为O(1),最坏的事件复杂度是O(n) + """ + ret = [] + s1 = set(nums1) + s2 = set(nums2) + # 考虑到检查集合重元素O(1)的复杂度,所以只遍历较小的集合是时间复杂度更低的 + if len(s1) > len(s2): + ret = [i for i in s2 if i in s1] + else: + ret = [i for i in s1 if i in s2] + return ret + + +if __name__ == '__main__': + nums1 = [4,9,5] + nums2 = [9,4,9,8,4] + s = Solution() + print(s.intersection(nums1, nums2)) From 6e996202b7c258ed8424bb523753f3bae60582fc Mon Sep 17 00:00:00 2001 From: Jay Date: Thu, 13 May 2021 23:28:09 +0800 Subject: [PATCH 13/29] leetcode: word_pattern.py --- leetcode/easy/word_pattern.py | 89 +++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 leetcode/easy/word_pattern.py diff --git a/leetcode/easy/word_pattern.py b/leetcode/easy/word_pattern.py new file mode 100644 index 0000000..9eee48e --- /dev/null +++ b/leetcode/easy/word_pattern.py @@ -0,0 +1,89 @@ +# *_* coding=utf-8 *_* + +''' +给定一种规律 pattern 和一个字符串 str ,判断 str 是否遵循相同的规律。 +这里的 遵循 指完全匹配,例如, pattern 里的每个字母和字符串 str 中的每个非空单词之间存在着双向连接的对应规律。 + +说明: 你可以假设 pattern 只包含小写字母, str 包含了由单个空格分隔的小写字母。 + +示例1: +输入: pattern = "abba", str = "dog cat cat dog" +输出: true + +示例 2: +输入:pattern = "abba", str = "dog cat cat fish" +输出: false + +链接:https://leetcode-cn.com/problems/word-pattern + +以第2中为例:时间复杂度O(n+m),空间复杂度O(n+m) +''' + +class Solution(object): + def wordPattern(self, pattern, s): + """ + :type pattern: str + :type s: str + :rtype: bool + """ + s_list = s.strip().split() + my_map = dict() + if len(pattern) != len(s_list): + return False + for i, j in zip(pattern, s_list): + if i in my_map: + if my_map[i] != j: + return False + else: + if j in my_map.values(): + return False + else: + my_map[i] = j + return True + + def wordPattern_1(self, pattern, s): + """ + :type pattern: str + :type s: str + :rtype: bool + """ + s_list = s.strip().split() + ch_map = dict() + word_map = dict() + if len(pattern) != len(s_list): + return False + for i, j in zip(pattern, s_list): + if (i in ch_map and ch_map[i] != j) or (j in word_map and word_map[j] != i): + return False + else: + ch_map[i] = j + word_map[j] = i + return True + + def wordPattern_2(self, pattern, s): + """ + :type pattern: str + :type s: str + :rtype: bool + """ + res=s.split() + return list(map(pattern.index, pattern))==list(map(res.index,res)) + + +if __name__ == '__main__': + s = Solution() + p1 = 'abba' + s1 = 'dog cat cat dog' + print(s.wordPattern(p1, s1)) + print(s.wordPattern_1(p1, s1)) + print(s.wordPattern_2(p1, s1)) + p2 = 'abba' + s2 = 'dog cat cat fish' + print(s.wordPattern(p2, s2)) + print(s.wordPattern_1(p2, s2)) + print(s.wordPattern_2(p2, s2)) + p3 = 'abba' + s3 = 'dog dog dog dog' + print(s.wordPattern(p3, s3)) + print(s.wordPattern_1(p3, s3)) + print(s.wordPattern_2(p3, s3)) From 1748fa45f9aa55f12fc2a9ba8d8a692b0b38d9d2 Mon Sep 17 00:00:00 2001 From: Jay Date: Thu, 13 May 2021 23:32:33 +0800 Subject: [PATCH 14/29] leetcode: add two_num_sum.py --- leetcode/easy/two_num_sum.py | 51 ++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 leetcode/easy/two_num_sum.py diff --git a/leetcode/easy/two_num_sum.py b/leetcode/easy/two_num_sum.py new file mode 100644 index 0000000..5978a4a --- /dev/null +++ b/leetcode/easy/two_num_sum.py @@ -0,0 +1,51 @@ +# *_* coding=utf-8 *_* + +''' +给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。 +你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 +你可以按任意顺序返回答案。 + +链接:https://leetcode-cn.com/problems/two-sum + +1. 暴力破解:时间复杂度 O(N^2) 空间复杂度 O(1) +2. 哈希表:时间复杂度 O(N) 空间复杂度 O(N) + +''' + +class Solution(object): + def twoSum(self, nums, target): + """ + :type nums: List[int] + :type target: int + :rtype: List[int] + """ + n = len(nums) + for i in range(n): + for j in range(i + 1, n): + if nums[i] + nums[j] == target: + return [i, j] + return ['not-found', 'not-found'] + + def twoSum_1(self, nums, target): + hashtable = dict() + for i, num in enumerate(nums): + if target - num in hashtable: + return [hashtable[target - num], i] + hashtable[nums[i]] = i + return ['not-found', 'not-found'] + + +if __name__ == '__main__': + num_list = [1, 7, 9, 4, 53, 42] + sum = 62 + s = Solution() + print(s.twoSum(num_list, sum)) + print(s.twoSum_1(num_list, sum)) + num_list = [3, 2, 4] + sum = 6 + print(s.twoSum(num_list, sum)) + print(s.twoSum_1(num_list, sum)) + num_list = [3, 3] + sum = 6 + print(s.twoSum(num_list, sum)) + print(s.twoSum_1(num_list, sum)) From 5285c97fc230f90cc332dfb90d614e32f0a955dd Mon Sep 17 00:00:00 2001 From: Jay Date: Thu, 13 May 2021 23:37:35 +0800 Subject: [PATCH 15/29] leetcode: reverse_list.py --- leetcode/easy/reverse_list.py | 84 +++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 leetcode/easy/reverse_list.py diff --git a/leetcode/easy/reverse_list.py b/leetcode/easy/reverse_list.py new file mode 100644 index 0000000..2aed9b8 --- /dev/null +++ b/leetcode/easy/reverse_list.py @@ -0,0 +1,84 @@ +# *_* coding=utf-8 *_* + +''' +反转链表: +https://leetcode-cn.com/problems/reverse-linked-list/ + +实现了一个链表;并且用 迭代/递归 两种方法进行反转。 + +1. 迭代:时间复杂度 O(N) 空间复杂度 O(1) +2. 递归:时间复杂度 O(N) 空间复杂度 O(N) + +''' + + +# Definition for singly-linked list. +class ListNode(object): + def __init__(self, val=0, next=None): + self.val = val + self.next = next + + +class LinkedList(object): + # 通过一个list 初始化一个链表 + def __init__(self, l=[1, 2, 3, 4, 5, 6]): + self.head = ListNode(l[0]) + cur = self.head + for i in l[1:]: + cur.next = ListNode(i) + cur = cur.next + + def print_linked_list(self): + # 为了保持链表 head 不被破坏 + temp_head = self.head + while temp_head: + print(temp_head.val) + temp_head = temp_head.next + + +class Solution(object): + # 遍历方式反转链表 + def reverse_list(self, head): + """ + :type head: ListNode + :rtype: ListNode + """ + cur, pre = head, None + while cur: + # pre, pre.next, cur = cur, pre, cur.next + temp = cur.next + cur.next = pre + pre = cur + cur = temp + return pre + + # 递归方式反转链表 + def reverse_list_recursion(self, head): + """ + :type head: ListNode + :rtype: ListNode + """ + if (not head) or (not head.next): + return head + node = self.reverse_list_recursion(head.next) + head.next.next = head + head.next = None + return node + + +if __name__ == '__main__': + ll = LinkedList(l=[1, 2, 3, 4, 5]) + print('------------------------------') + print('before reverse') + ll.print_linked_list() + h = ll.head + s = Solution() + ll.head = s.reverse_list(h) + print('------------------------------') + print('after reverse: reverse_list()') + ll.print_linked_list() + print('------------------------------') + ll.head = s.reverse_list_recursion(ll.head) + print('after reverse: reverse_list_recursion()') + ll.print_linked_list() + From 96995c636c3f9768fc841865f86d397b7dcb3a5f Mon Sep 17 00:00:00 2001 From: Jay Date: Thu, 13 May 2021 23:41:00 +0800 Subject: [PATCH 16/29] leetcode: remove_duplicates.py --- leetcode/easy/remove_duplicates.py | 87 ++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 leetcode/easy/remove_duplicates.py diff --git a/leetcode/easy/remove_duplicates.py b/leetcode/easy/remove_duplicates.py new file mode 100644 index 0000000..47143bb --- /dev/null +++ b/leetcode/easy/remove_duplicates.py @@ -0,0 +1,87 @@ +# -*- coding:UTF-8 -*- +''' +给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。 +在 S 上反复执行重复项删除操作,直到无法继续删除。 +在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。 + +示例: + +输入:"abbaca" +输出:"ca" +解释: +例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。 + +提示: + * 1 <= S.length <= 20000 + * S 仅由小写英文字母组成。 + +来源:力扣(LeetCode) +链接:https://leetcode-cn.com/problems/remove-all-adjacent-duplicates-in-string +''' + +class Solution(object): + def removeDuplicates(self, S): + """ + :type S: str + :rtype: str + 这是通过递归的方法来做,时间复杂度很高 O(n^2) + """ + length = len(S) + for i in range(length-1): + if S[i] == S[i+1]: + S1 = S.replace('%s%s' % (S[i], S[i+1]), '') + # print(S1) + return self.removeDuplicates(S1) + return S + + + def removeDuplicates_1(self, S): + """ + :type S: str + :rtype: str + 使用 栈,代码非常简洁,时间复杂度 O(n) ,空间复杂度O(n) + 消除一对相邻重复项可能会导致新的相邻重复项出现,如从字符串 abba中删除 bb 会导致出现新的相邻重复项 aa 出现。 + 因此我们需要保存当前还未被删除的字符。一种显而易见的数据结构呼之欲出:栈。 + 我们只需要遍历该字符串,如果当前字符和栈顶字符相同,我们就贪心地将其消去,否则就将其入栈即可。 + """ + stack = [''] + for i in S: + if i == stack[-1]: + stack.pop(-1) + else: + stack.append(i) + return ''.join(stack) + + + def removeDuplicates_2(self, S): + """ + :type S: str + :rtype: str + 使用 双指针 , 时间复杂度 O(n),空间复杂度 O(n) + 挨着两个相同的同时消失,可以使用两个指针。 + * 一个right一直往右移动,然后把指向的值递给left指向的值即可。 + * 一个left每次都会比较挨着的两个是否相同,如果相同,他两同时消失 + """ + left = 0 + right = 0 + length = len(S) + l1 = list(S) + while (right < length): + l1[left] = l1[right] + if (left > 0) and l1[left - 1] == l1[left]: + left -= 2 + left += 1 + right += 1 + return ''.join(l1[:left]) + + +if __name__ == '__main__': + s = Solution() + str1 = "aababaab" + print(s.removeDuplicates(str1)) + print(s.removeDuplicates_1(str1)) + print(s.removeDuplicates_2(str1)) + str1 = "abbaca" + print(s.removeDuplicates(str1)) + print(s.removeDuplicates_1(str1)) + print(s.removeDuplicates_2(str1)) From 2f339891f1b21e0232d18a7e667ee3b93d12da1b Mon Sep 17 00:00:00 2001 From: Jay Date: Thu, 13 May 2021 23:47:04 +0800 Subject: [PATCH 17/29] intersection.py: update comments --- leetcode/easy/intersection.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/leetcode/easy/intersection.py b/leetcode/easy/intersection.py index 2a16a13..fd74953 100644 --- a/leetcode/easy/intersection.py +++ b/leetcode/easy/intersection.py @@ -30,12 +30,14 @@ def intersection(self, nums1, nums2): 元组set 是基于Hash来实现的,故: 1. set 中的元素必须唯一(不可重复) 2. set 中的元素必须是Hashable的 - 3. 向集合中添加元素、删除元素、检查元素是否存在,都是非常快速的。平均时间复杂度为O(1),最坏的事件复杂度是O(n) + 3. 向集合中添加元素、删除元素、检查元素是否存在,都是非常快速的。平均时间复杂度为O(1),最坏的时间复杂度是O(n) + + 本算法 时间复杂度 O(n+m) 空间复杂度 O(n+m) """ ret = [] s1 = set(nums1) s2 = set(nums2) - # 考虑到检查集合重元素O(1)的复杂度,所以只遍历较小的集合是时间复杂度更低的 + # 考虑到检查集合中元素O(1)的复杂度,所以只遍历较小的集合是时间复杂度更低的 if len(s1) > len(s2): ret = [i for i in s2 if i in s1] else: From 563759dd0430b7cbc3964d1eff8f316ddf397bc6 Mon Sep 17 00:00:00 2001 From: Jay Date: Thu, 13 May 2021 23:47:39 +0800 Subject: [PATCH 18/29] add try_turtle.py --- py2016/try_turtle.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 py2016/try_turtle.py diff --git a/py2016/try_turtle.py b/py2016/try_turtle.py new file mode 100644 index 0000000..3f3a095 --- /dev/null +++ b/py2016/try_turtle.py @@ -0,0 +1,24 @@ +# *-* coding=utf-8 *-* +import turtle +import time +#定义绘制时画笔的颜色 +turtle.color("purple") +#定义绘制时画笔的线条的宽度 +turtle.pensize(5) +#定义绘图的速度 +turtle.speed(10) +#以0,0为起点进行绘制 +turtle.goto(0,0) +#绘出正方形的四条边 +for i in range(4): + turtle.forward(100) + turtle.right(90) +#画笔移动到点(-150,-120)时不绘图 +turtle.up() +turtle.goto(-150,-120) +#再次定义画笔颜色 +turtle.color("red") +#在(-150,-120)点上打印"Done" +turtle.write("Done") +turtle.done() +#time.sleep(10) From f95a0851b298aea1c3a04fd823e3c6fd64ce7e94 Mon Sep 17 00:00:00 2001 From: Jay Date: Thu, 13 May 2021 23:48:27 +0800 Subject: [PATCH 19/29] add draw_a_tree_with_turtle.py --- py2016/draw_a_tree_with_turtle.py | 34 +++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 py2016/draw_a_tree_with_turtle.py diff --git a/py2016/draw_a_tree_with_turtle.py b/py2016/draw_a_tree_with_turtle.py new file mode 100644 index 0000000..4c43e0b --- /dev/null +++ b/py2016/draw_a_tree_with_turtle.py @@ -0,0 +1,34 @@ +from turtle import Turtle +import time + + +def tree(tlist, l, a, f): + if l > 5: + lst = [] + for t in tlist: + t.forward(l) + p = t.clone() + t.left(a) + p.right(a) + lst.append(t) + lst.append(p) + time.sleep(1) + tree(lst, l*f, a, f) + + +def main(): + t = Turtle() + t.color('green') + t.pensize(5) + #t.hideturtle() + #t.speed(1) + t.getscreen().tracer(30, 0) + t.left(90) + t.penup() + t.goto(0, -200) + t.pendown() + tree([t], 150, 60, 0.6) + + +if __name__ == '__main__': + main() From 4fd141161273d3b423544da21c6d1ba720a0b184 Mon Sep 17 00:00:00 2001 From: Jay Date: Thu, 13 May 2021 23:50:05 +0800 Subject: [PATCH 20/29] add test_gc.py --- py2021/test_gc.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 py2021/test_gc.py diff --git a/py2021/test_gc.py b/py2021/test_gc.py new file mode 100644 index 0000000..b8c6c38 --- /dev/null +++ b/py2021/test_gc.py @@ -0,0 +1,42 @@ +import os +import gc +import time +import psutil + + +def print_memory_info(): + pid = os.getpid() + p = psutil.Process(pid) + + info = p.memory_full_info() + MB = 1024 * 1024 + memory = info.uss / MB + print('used %d MB' % memory) + +def test_func(): + print("test start") + print_memory_info() + length = 1000 * 1000 + list = [i for i in range(length)] + print_memory_info() + +def test1_func(): + print("test1 start") + print_memory_info() + length = 1000 * 1000 + list_a = [i for i in range(length)] + list_b = [i for i in range(length)] + list_a.append(list_b) + list_b.append(list_a) + print_memory_info() + return list + + +test_func() +print_memory_info() +test1_func() +print_memory_info() +time.sleep(10) +print_memory_info() +gc.collect() +print_memory_info() From 1fbbbc20b485260acd85ed558677ad61507f7b98 Mon Sep 17 00:00:00 2001 From: Jay Date: Wed, 27 Apr 2022 00:35:13 +0800 Subject: [PATCH 21/29] leetcode: add length_of_longest_substring.py --- .../medium/length_of_longest_substring.py | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 leetcode/medium/length_of_longest_substring.py diff --git a/leetcode/medium/length_of_longest_substring.py b/leetcode/medium/length_of_longest_substring.py new file mode 100644 index 0000000..17b7e73 --- /dev/null +++ b/leetcode/medium/length_of_longest_substring.py @@ -0,0 +1,62 @@ +# -*- coding:UTF-8 -*- +''' +给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。 + +示例 1: +输入: s = "abcabcbb" +输出: 3 +解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 + +示例 2: +输入: s = "bbbbb" +输出: 1 +解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。 + +s 由英文字母、数字、符号和空格组成 + + +思路: +我们使用两个指针表示字符串中的某个子串(或窗口)的左右边界,其中左指针代表着上文中「枚举子串的起始位置」,而右指针即为上文中的 rk ; +在每一步的操作中,我们会将左指针向右移动一格,表示 我们开始枚举下一个字符作为起始位置,然后我们可以不断地向右移动右指针,但需要保证这两个指针对应的子串中没有重复的字符。在移动结束后,这个子串就对应着 以左指针开始的,不包含重复字符的最长子串。我们记录下这个子串的长度; +在枚举结束后,我们找到的最长的子串的长度即为答案。 + +判断 是否有重复的字符,常用的数据结构为哈希集合 python中用set() +在左指针向右移动的时候,我们从哈希集合中移除一个字符,在右指针向右移动的时候,我们往哈希集合中添加一个字符。 + + +作者:LeetCode-Solution +链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/wu-zhong-fu-zi-fu-de-zui-chang-zi-chuan-by-leetc-2/ +来源:力扣(LeetCode) +著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 + +来源:力扣(LeetCode) +链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/wu-zhong-fu-zi-fu-de-zui-chang-zi-chuan-by-leetc-2/ +''' + + +class Solution: + def lengthOfLongestSubstring(self, s): + # 哈希集合,记录每个字符是否出现过 + occ = set() + n = len(s) + # 右指针,初始值为 -1,相当于我们在字符串的左边界的左侧,还没有开始移动 + rk, ans = -1, 0 + for i in range(n): + if i != 0: + # 左指针向右移动一格,移除一个字符 + occ.remove(s[i - 1]) + while rk + 1 < n and s[rk + 1] not in occ: + # 不断地移动右指针 + occ.add(s[rk + 1]) + rk += 1 + # 第 i 到 rk 个字符是一个极长的无重复字符子串 + ans = max(ans, rk - i + 1) + return ans + + +if __name__ == '__main__': + s1 = 'abcabcbb' + s2 = 'bbbbbb' + s = Solution() + print(s.lengthOfLongestSubstring(s1)) + print(s.lengthOfLongestSubstring(s2)) From 8b255c1cc7822c48e782d4e06445f52e31366148 Mon Sep 17 00:00:00 2001 From: Jay Date: Wed, 27 Apr 2022 08:46:44 +0800 Subject: [PATCH 22/29] leetcode: add buy_sell_stock_once_max_profit.py --- .../medium/buy_sell_stock_once_max_profit.py | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 leetcode/medium/buy_sell_stock_once_max_profit.py diff --git a/leetcode/medium/buy_sell_stock_once_max_profit.py b/leetcode/medium/buy_sell_stock_once_max_profit.py new file mode 100644 index 0000000..31ff737 --- /dev/null +++ b/leetcode/medium/buy_sell_stock_once_max_profit.py @@ -0,0 +1,34 @@ +# -*- coding:UTF-8 -*- +''' +给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 +你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 +返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。 + +思路: +如果我是在历史最低点买的股票就好了!太好了,在题目中,我们只要用一个变量记录一个历史最低价格 minprice, +我们就可以假设自己的股票是在那天买的。那么我们在第 i 天卖出股票能得到的利润就是 prices[i] - minprice。 +因此,我们只需要遍历价格数组一遍,记录历史最低点,然后在每一天考虑这么一个问题: +如果我是在历史最低点买进的,那么我今天卖出能赚多少钱?当考虑完所有天数之时,我们就得到了最好的答案。 + + +来源:力扣(LeetCode) +链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock +''' + + +class Solution: + def maxProfit(self, prices): + min_price = float('inf') + max_profit = 0 + for price in prices: + min_price = min(min_price, price) + max_profit = max(max_profit, price - min_price) + return max_profit + + +if __name__ == '__main__': + l1 = [7,1,5,3,6,4] + l2 = [7,6,4,3,1] + s = Solution() + print(s.maxProfit(l1)) + print(s.maxProfit(l2)) From 0456767390f045c1d1db4a11c512ec3a6e087da8 Mon Sep 17 00:00:00 2001 From: Jay Date: Mon, 12 Sep 2022 00:12:55 +0800 Subject: [PATCH 23/29] a decorator to time a func() --- py2021/my_time_it.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 py2021/my_time_it.py diff --git a/py2021/my_time_it.py b/py2021/my_time_it.py new file mode 100644 index 0000000..828fcd3 --- /dev/null +++ b/py2021/my_time_it.py @@ -0,0 +1,35 @@ +# *_* coding=utf-8 *_* + +import time +import functools + + +# 装饰器 用于打印函数执行耗时 性能分析很有用 +# 这是为python2 写的; python3中 不要使用time.clock()了 +# DeprecationWarning: time.clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time.perf_counter or time.process_time instead +def time_it(func): + @functools.wraps(func) + def _wrapper(*args, **kwargs): + # start = time.clock() + start = time.time() + func(*args, **kwargs) + # end = time.clock() + end = time.time() + print("function %s() costs %s second(s)" % (func.__name__, end - start)) + return _wrapper + + +@time_it +def test1(x, y): + time.sleep(1) + return x + y + + +@time_it +def test2(x, y): + time.sleep(3) + return x + y + +if __name__ == '__main__': + test1(3, 5) + test2(3, 5) From 7dce7da65ba67ce61956be50ed92c8a9fc71b0cb Mon Sep 17 00:00:00 2001 From: Jay Date: Mon, 12 Sep 2022 00:45:36 +0800 Subject: [PATCH 24/29] ssh exec cmd using paramiko in python --- py2022/ssh_cmd.py | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 py2022/ssh_cmd.py diff --git a/py2022/ssh_cmd.py b/py2022/ssh_cmd.py new file mode 100644 index 0000000..6867753 --- /dev/null +++ b/py2022/ssh_cmd.py @@ -0,0 +1,54 @@ +#!/usr/bin/python + +import paramiko + +hostname_list = ['192.168.1.2', '192.162.1.3'] +username = 'root' +password = 'yourpassword' +username = 'admin' +password = '' +port = 22 + + +hostname_list = [] + +def get_hosts(h_file): + with open(h_file) as f: + for l in f.readlines(): + hostname_list.append(l.strip()) + + +def exec_cmd(cmd): + ''' exec a cmd on a remote linux system ''' + for h in hostname_list: + try: + client = paramiko.SSHClient() + client.load_system_host_keys() + client.set_missing_host_key_policy(paramiko.MissingHostKeyPolicy) + print('connecting: %s' % h) + client.connect(h, port=port, username=username, password=password, + timeout=5) + chan = client.get_transport().open_session() + print('exec cmd: %s' % cmd) + chan.exec_command(cmd) + print('exit code: %d' % chan.recv_exit_status()) + if chan.recv_exit_status() == 0: + print('%s OK' % h) + else: + print('%s Error!' % h) + print(chan.recv(200).strip()) + # stdin, stdout, stderr = client.exec_command(cmd) + # print(stdout.read().strip()) + # print(stderr.read().strip()) + except Exception as e: + print(e) + finally: + client.close() + + +if __name__ == '__main__': + host_file = 'temp_test_ips' + get_hosts(host_file) + cmd = 'uptime' + cmd = 'echo $(date)>>/tmp/a; sleep 1; uptime; exit 1' + exec_cmd(cmd) From a6bdea1a826b2550eaf61286da662b770ac1738d Mon Sep 17 00:00:00 2001 From: Jay Date: Mon, 12 Sep 2022 01:01:55 +0800 Subject: [PATCH 25/29] ssh send a file useing paramiko --- py2022/ssh_scp.py | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 py2022/ssh_scp.py diff --git a/py2022/ssh_scp.py b/py2022/ssh_scp.py new file mode 100644 index 0000000..73ba104 --- /dev/null +++ b/py2022/ssh_scp.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python +# *_* coding=utf-8 *_* + +import paramiko + +hostname_list = ['192.168.1.2', '192.162.1.3'] +username = 'admin' +password = 'yourpassword' +port = 22 + + +hostname_list = [] + +def get_hosts(h_file): + with open(h_file) as f: + for l in f.readlines(): + hostname_list.append(l.strip()) + + +def send_file(): + ''' send (or fetch) a file to (or from) a remote linux machine ''' + src_1 = 'ssh_cmd.py' + dst_1 = '/tmp/ssh_cmd.py' + put_files = [(src_1, dst_1)] + for h in hostname_list: + try: + client = paramiko.SSHClient() + client.load_system_host_keys() + client.set_missing_host_key_policy(paramiko.MissingHostKeyPolicy) + print('connecting: %s' % h) + client.connect(h, port=port, username=username, password=password, + timeout=5) + sftp = client.open_sftp() + for p in put_files: + print('src file: %s , dst file: %s' % (p[0], p[1])) + sftp.put(p[0], p[1]) + except Exception as e: + print(e) + finally: + sftp.close() + client.close() + + +if __name__ == '__main__': + host_file = 'temp_test_ips' + get_hosts(host_file) + send_file() From 40dc862e366acbc7d524b035351640574f8b3bdd Mon Sep 17 00:00:00 2001 From: Jay Date: Mon, 12 Sep 2022 01:02:44 +0800 Subject: [PATCH 26/29] add encoding and close channel --- py2022/ssh_cmd.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/py2022/ssh_cmd.py b/py2022/ssh_cmd.py index 6867753..9015d17 100644 --- a/py2022/ssh_cmd.py +++ b/py2022/ssh_cmd.py @@ -1,4 +1,5 @@ #!/usr/bin/python +# *_* coding=utf-8 *_* import paramiko @@ -28,6 +29,7 @@ def exec_cmd(cmd): print('connecting: %s' % h) client.connect(h, port=port, username=username, password=password, timeout=5) + # 多次执行命令 可复用同一个Channel chan = client.get_transport().open_session() print('exec cmd: %s' % cmd) chan.exec_command(cmd) @@ -43,6 +45,7 @@ def exec_cmd(cmd): except Exception as e: print(e) finally: + chan.close() client.close() From 2de32e2ec29ae91d49e4341b818cc287a8336b51 Mon Sep 17 00:00:00 2001 From: Jay Date: Tue, 20 Dec 2022 23:57:22 +0800 Subject: [PATCH 27/29] add remove_item_in_for_list.py --- py2022/remove_item_in_for_list.py | 42 +++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 py2022/remove_item_in_for_list.py diff --git a/py2022/remove_item_in_for_list.py b/py2022/remove_item_in_for_list.py new file mode 100644 index 0000000..f859037 --- /dev/null +++ b/py2022/remove_item_in_for_list.py @@ -0,0 +1,42 @@ +list1 = [1, 2, 3, 4, 5, 2, 2] +for i in list1: + if i == 2: + list1.remove(i) +print(list1) + + +# list1 = [1, 2, 3, 4, 5, 2, 2] +# for i in range(len(list1)): +# if list1[i] == 2: +# list1.remove(list1[i]) + # IndexError: list index out of range +# print(list1) + +list1 = [1, 2, 3, 4, 5, 2, 2] +list2 = list(filter(lambda x: x!=2, list1)) +print(list2) + +list1 = [1, 2, 3, 4, 5, 2, 2] +list2 = [i for i in list1 if i!=2] +print(list2) + +list1 = [1, 2, 3, 4, 5, 2, 2] +for i in list1[:]: + if i == 2: + list1.remove(i) +print(list1) + +import copy + +list1 = [1, 2, 3, 4, 5, 2, 2] +# list2 = copy.copy(list1) +list2 = copy.deepcopy(list1) +for i in list1: + if i == 2: + list2.remove(i) +print(list2) + +list1 = [1, 2, 3, 4, 5, 2, 2] +while 2 in list1: + list1.remove(2) +print(list1) From b4df4c0cbd6d404f26a788df906a2472ccf3a1e5 Mon Sep 17 00:00:00 2001 From: Jay Date: Sun, 21 Apr 2024 00:20:21 +0800 Subject: [PATCH 28/29] add a script to calculate the reserved memory in the BIOS-e820 table --- py2024/calculate_reserved_mem.py | 115 +++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 py2024/calculate_reserved_mem.py diff --git a/py2024/calculate_reserved_mem.py b/py2024/calculate_reserved_mem.py new file mode 100644 index 0000000..a682695 --- /dev/null +++ b/py2024/calculate_reserved_mem.py @@ -0,0 +1,115 @@ +#!/usr/bin/python3 + +import re +import sys +from subprocess import Popen, PIPE, STDOUT + + +def shell_rc_and_output(cmd): + ''' execute a shell command and get its return code and output (stdout/stderr) ''' + p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT) + out = p.communicate()[0] + rc = p.returncode + if isinstance(out, bytes): + # out is a string + out = out.decode() + return rc, str(out) + + +def parse_memory_line(line): + """ + 解析单行内存映射信息,并返回内存区域的起始和结束地址。 + """ + pattern = '.+\[mem (.+)-(.+)\].+' + match = re.search(pattern, line) + # print(match) + if match: + start = match.group(1) + end = match.group(2) + # print(match.group(1)) + # print(match.group(2)) + start = int(start, 16) + end = int(end, 16) + return start, end + + +def calculate_reserved_memory(lines): + """ + 计算所有保留内存区域的总大小。 + """ + total_reserved_memory = 0 + for line in lines: + if 'mem' in line and 'reserved' in line: + start, end = parse_memory_line(line) + # 计算内存区域的大小,并考虑包含结束地址 + size = end - start + 1 + total_reserved_memory += size + return total_reserved_memory + + +def calculate_memory(lines): + """ + 计算所有内存区域的总大小。 + """ + total_memory = 0 + for line in lines: + if 'mem' in line: + start, end = parse_memory_line(line) + # 计算内存区域的大小,并考虑包含结束地址 + size = end - start + 1 + total_memory += size + return total_memory + + +def get_e820_mem_map(): + """" + 根据 dmesg -T 命令查看 e820表的信息, 返回一个列表。 + """ + # 返回如下这样格式的列表 (放在这里仅供代码调试用) + # memory_map = [ + # "BIOS-e820: [mem 0x0000000000000000-0x000000000009ffff] usable", + # "BIOS-e820: [mem 0x0000000000100000-0x000000005ad0efff] usable", + # "BIOS-e820: [mem 0x000000005ad0f000-0x0000000060377fff] reserved", + # "BIOS-e820: [mem 0x0000000060378000-0x000000007fffefff] usable", + # "BIOS-e820: [mem 0x000000007ffff000-0x000000007fffffff] reserved", + # "BIOS-e820: [mem 0x0000000080000000-0x00000000bf8eefff] usable", + # "BIOS-e820: [mem 0x00000000bf8ef000-0x00000000bfb6efff] reserved", + # "BIOS-e820: [mem 0x00000000bfb6f000-0x00000000bfb7efff] ACPI data", + # "BIOS-e820: [mem 0x00000000bfb7f000-0x00000000bfbfefff] ACPI NVS", + # "BIOS-e820: [mem 0x00000000bfbff000-0x00000000bff7bfff] usable", + # "BIOS-e820: [mem 0x00000000bff7c000-0x00000000bfffffff] reserved", + # "BIOS-e820: [mem 0x0000000100000000-0x000000081fffffff] usable", + # "BIOS-e820: [mem 0x0000000820000000-0x000000083fffffff] reserved" + # ] + # return memory_map + cmd = "dmesg -T | grep -Eio ' (bios-e820:.*mem .*)'" + rc, out = shell_rc_and_output(cmd) + if rc != 0: + print("Error! failed to run cmd: {}".format(cmd)) + sys.exit(1) + else: + memory_map = out.split('\n') + return memory_map + + +def print_reserved_ratio(total, reserved): + """ + 计算内存被reserved的比例, 并打印百分比 + """ + ratio = reserved / total + percentage = ratio * 100 + print("memory reserved percentage: {:.2f}%".format(percentage)) + + +if __name__ == '__main__': + # 获取BIOS-e820内存映射信息 + mem_map = get_e820_mem_map() + # 计算总内存大小 + total_memory = calculate_memory(mem_map) + total_mem_mb = total_memory / 1024 / 1024 + print("Total memory: {:.0f} MB".format(total_mem_mb)) + # 计算保留的内存大小 + reserved_memory = calculate_reserved_memory(mem_map) + res_mem_mb = reserved_memory / 1024 / 1024 + print("Total reserved memory: {:.0f} MB".format(res_mem_mb)) + print_reserved_ratio(total_mem_mb, res_mem_mb) From 796c88c205dc375cb3bcc5bfc8e330c90dbe37e1 Mon Sep 17 00:00:00 2001 From: Jay Date: Mon, 20 May 2024 00:14:04 +0800 Subject: [PATCH 29/29] update beer.py for python3 add a condition: can borrow 1 empty bottle from the shop --- py2015/beer.py | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/py2015/beer.py b/py2015/beer.py index 76cf475..2e8b04c 100644 --- a/py2015/beer.py +++ b/py2015/beer.py @@ -1,21 +1,42 @@ +#!/usr/bin/python3 ''' calculate how many bottles of beer you can drink. 1. money: n RMB (e.g. n=10) 2. price: 2 RMB / bottle 3. 3 empty bottles --> 1 bottle of beer +可以最多向商店借1个空瓶, 但需要兑换喝完后将1个空瓶还回。 +2024年update: a. 增加了向商店借空瓶的说明 b. 使用python3而不是python2 ''' def bottles_cnt_beer(money=10): + ''' + 计算能够喝到多少瓶啤酒。 + 供参考答案如下: + 10 -> 7 + 100 -> 75 + 1234 -> 925 + 12345 -> 9258 + ''' price = 2 m = 3 # m empty bottles --> 1 bottle of beer - count = money / price - empty_cnt = money / price + count = int(money / price) + empty_cnt = int(money / price) while empty_cnt >= m: - count += empty_cnt / m - empty_cnt = (empty_cnt / m) + (empty_cnt % m) + count += int(empty_cnt / m) + empty_cnt = int(empty_cnt / m) + int(empty_cnt % m) + # borrow 1 empt bottle from the shop; drink; return 1 empty bottle to the shop. + if empty_cnt == (m - 1): + count += 1 return count + if __name__ == '__main__': - n = int(raw_input('Enter a number: ')) - print "you can drink %d bottles of beer." % bottles_cnt_beer(n) + n = 10 + print("money n={}, you can drink {} bottles of beer.".format(n, bottles_cnt_beer(n))) + n = 100 + print("money n={}, you can drink {} bottles of beer.".format(n, bottles_cnt_beer(n))) + n = 1234 + print("money n={}, you can drink {} bottles of beer.".format(n, bottles_cnt_beer(n))) + n = int(input('Enter a number: ')) + print("money n={}, you can drink {} bottles of beer.".format(n, bottles_cnt_beer(n)))