├── .gitignore ├── Day01-15 ├── Day01 │ ├── hello.py │ ├── peppa_pig.py │ ├── res │ │ ├── python-idle.png │ │ ├── python-ipython.png │ │ ├── python-jupyter-1.png │ │ ├── python-jupyter-2.png │ │ ├── python-pycharm.png │ │ └── python-sublime.png │ └── 初識Python.md ├── Day02 │ ├── centigrade.py │ ├── circle.py │ ├── leap.py │ ├── operator.py │ ├── string.py │ ├── variable1.py │ ├── variable2.py │ ├── variable3.py │ ├── variable4.py │ ├── variable5.py │ └── 語言元素.md ├── Day03 │ ├── .py │ ├── convert.py │ ├── grade.py │ ├── piecewise.py │ ├── rolldice.py │ ├── tax.py │ ├── triangle.py │ ├── verify.py │ └── 分支結構.md ├── Day04 │ ├── for1.py │ ├── for2.py │ ├── for3.py │ ├── for4.py │ ├── for5.py │ ├── for6.py │ ├── while1.py │ ├── while2.py │ └── 循環結構.md ├── Day05 │ ├── chicken.py │ ├── craps.py │ ├── fibonacci.py │ ├── guess.py │ ├── lily.py │ ├── palindrome.py │ ├── perfect.py │ ├── prime.py │ ├── table.py │ └── 總結和練習.md ├── Day06 │ ├── function1.py │ ├── function2.py │ ├── function3.py │ ├── function4.py │ ├── function5.py │ ├── function6.py │ └── 函數和模塊的使用.md ├── Day07 │ ├── avgscore.py │ ├── dict1.py │ ├── dict2.py │ ├── fibonacci.py │ ├── findmax.py │ ├── list1.py │ ├── list2.py │ ├── list3.py │ ├── lottery.py │ ├── marquee.py │ ├── res │ │ ├── fibonacci-blocks.png │ │ ├── ipython-timeit.png │ │ └── python-set.png │ ├── scoretable.py │ ├── set1.py │ ├── set2.py │ ├── tic-tac-toe.py │ ├── tuple.py │ ├── yanghui.py │ └── 字符串和常用數據結構.md ├── Day08 │ ├── access.py │ ├── circle.py │ ├── clock.py │ ├── guess.py │ ├── hack.py │ ├── rect.py │ ├── res │ │ ├── object-feature.png │ │ └── oop-zhihu.png │ ├── student.py │ ├── test.py │ └── 面向對象編程基礎.md ├── Day09 │ ├── association.py │ ├── car1.py │ ├── car2.py │ ├── clock.py │ ├── dependency.py │ ├── diamond.py │ ├── employee.py │ ├── multi.py │ ├── pet.py │ ├── rational.py │ ├── res │ │ ├── uml-components.png │ │ ├── uml-example.gliffy │ │ └── uml-example.png │ ├── shape.py │ ├── triangle.py │ └── 面向對象進階.md ├── Day10 │ ├── ball.py │ ├── gui1.py │ ├── gui2.py │ ├── gui3.py │ ├── res │ │ ├── ball-game.png │ │ └── ball.png │ ├── turtle1.py │ └── 圖形用戶界面和遊戲開發.md ├── Day11 │ ├── .py │ ├── csv1.py │ ├── csv2.py │ ├── ex1.py │ ├── ex2.py │ ├── ex3.py │ ├── ex4.py │ ├── example.csv │ ├── file1.py │ ├── file2.py │ ├── file3.py │ ├── file4.py │ ├── json1.py │ ├── json2.py │ ├── mm.jpg │ ├── pi_million_digits.txt │ ├── res │ │ └── file-open-mode.png │ ├── teacher.csv │ ├── 文件和異常.md │ └── 致橡树.txt ├── Day12 │ ├── res │ │ └── tel-start-number.png │ ├── str1.py │ ├── str2.py │ ├── test3.py │ ├── test4.py │ ├── test5.py │ └── 字符串和正則表達式.md ├── Day13 │ ├── asyncio1.py │ ├── asyncio2.py │ ├── asyncio3.py │ ├── coroutine1.py │ ├── coroutine2.py │ ├── generator1.py │ ├── generator2.py │ ├── multiprocess1.py │ ├── multiprocess2.py │ ├── multiprocess3.py │ ├── multiprocess4.py │ ├── multithread1.py │ ├── multithread2.py │ ├── multithread3.py │ ├── multithread4.py │ ├── multithread5.py │ ├── multithread6.py │ ├── res │ │ └── macos-monitor.png │ ├── singlethread1.py │ ├── singlethread2.py │ ├── test2.py │ ├── test3.py │ └── 進程和線程.md ├── Day14 │ ├── chatclient.py │ ├── chatserver.py │ ├── fileclient.py │ ├── fileserver.py │ ├── guido.jpg │ ├── mmdownloader.py │ ├── res │ │ ├── TCP-IP-model.png │ │ ├── after-browser.jpg │ │ ├── arpanet.png │ │ ├── before-browser.jpg │ │ ├── browers.jpg │ │ ├── browser-market-place.jpeg │ │ ├── how-data-is-processed.jpg │ │ ├── osi_rm.gif │ │ ├── osimodel.png │ │ ├── tcpipprotocols.png │ │ └── telnet.png │ ├── socket1.py │ ├── socket2.py │ ├── socket3.py │ ├── socket4.py │ ├── socket5.py │ ├── timeclient.py │ ├── timeserver.py │ └── 網絡編程入門.md └── Day15 │ └── 網絡應用開發.md ├── Day16-20 └── Python語言進階.md ├── Day21-30 ├── Web前端概述.md ├── classical_layout.html ├── example.html ├── form.html ├── form_and_table.html ├── img │ ├── Thumbs.db │ ├── a1.jpg │ ├── a2.jpg │ └── a3.jpg ├── jquery3.html ├── js │ └── jquery.min.js ├── qq_link.html └── res │ ├── browser-joke-1.jpeg │ ├── browser-joke-2.jpg │ ├── browser-joke-3.jpg │ ├── dom-page.png │ └── dom-tree.png ├── Day31-35 ├── res │ ├── Dennis-Ritchie.jpg │ ├── Ken-Thompson.png │ ├── Linus-Torvalds.jpg │ ├── Stallman.jpg │ ├── Tanenbaum.jpg │ ├── history-of-os.png │ ├── history-of-unix.png │ └── linux-network-config.png └── 玩轉Linux.md ├── Day36-40 ├── NoSQL入門.md ├── res │ ├── IMG_0358.PNG │ ├── IMG_0360.png │ ├── IMG_0361.png │ ├── IMG_0362.png │ ├── IMG_0363.png │ ├── IMG_0364.png │ ├── IMG_0365.png │ ├── IMG_0366.png │ └── redis-data-type.png └── 關係型數據庫MySQL.md ├── Day41-55 ├── Django2實戰01.md ├── Django2實戰02.md ├── Django2實戰03.md ├── Django2實戰04.md ├── Django2實戰05.md ├── Django2實戰06.md ├── Django2實戰07.md ├── Django2實戰08.md ├── Django2實戰09.md ├── Django2實戰10.md ├── Django2项目实战.md ├── car │ ├── car │ │ ├── __init__.py │ │ ├── settings.py │ │ ├── urls.py │ │ └── wsgi.py │ ├── manage.py │ ├── search │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_auto_20180524_1420.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── tests.py │ │ └── views.py │ ├── static │ │ └── images │ │ │ ├── icon-no.svg │ │ │ └── icon-yes.svg │ └── templates │ │ ├── add.html │ │ ├── search.html │ │ └── search2.html ├── oa │ ├── hrs │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_auto_20180523_0923.py │ │ │ ├── 0003_auto_20180524_1646.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── tests.py │ │ ├── urls.py │ │ └── views.py │ ├── manage.py │ ├── oa │ │ ├── __init__.py │ │ ├── settings.py │ │ ├── urls.py │ │ └── wsgi.py │ ├── static │ │ ├── css │ │ │ └── bootstrap.min.css │ │ ├── images │ │ │ └── mm.jpg │ │ └── js │ │ │ ├── bootstrap.min.js │ │ │ └── jquery.min.js │ └── templates │ │ ├── dept.html │ │ ├── emp.html │ │ └── index.html ├── res │ ├── admin-login.png │ ├── admin-model-create.png │ ├── admin-model-delete-and-update.png │ ├── admin-model-depts.png │ ├── admin-model-emps-modified.png │ ├── admin-model-emps.png │ ├── admin-model-read.png │ ├── admin-model.png │ ├── admin-welcome.png │ ├── django-index-1.png │ ├── django-index-2.png │ ├── er-graph.png │ ├── http-request.png │ ├── http-response.png │ ├── mvc.png │ ├── runserver.png │ └── web-application.png ├── shop │ ├── cart │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── tests.py │ │ └── views.py │ ├── manage.py │ ├── shop │ │ ├── __init__.py │ │ ├── settings.py │ │ ├── urls.py │ │ └── wsgi.py │ ├── static │ │ └── images │ │ │ ├── Thumbs.db │ │ │ ├── dolbee.jpg │ │ │ ├── lay.jpg │ │ │ ├── noodle.jpg │ │ │ ├── oil.jpg │ │ │ ├── wang.jpg │ │ │ └── wine.jpg │ └── templates │ │ ├── cart.html │ │ └── goods.html └── shop_origin │ ├── cart │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ └── views.py │ ├── manage.py │ ├── shop │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py │ ├── shop_create_sql.sql │ ├── static │ └── images │ │ ├── dolbee.jpg │ │ ├── lay.jpg │ │ ├── noodle.jpg │ │ ├── oil.jpg │ │ ├── wang.jpg │ │ └── wine.jpg │ └── templates │ ├── cart.html │ └── goods.html ├── Day56-65 ├── Flask安装和入门.md ├── Flask项目实战.md ├── 使用Flask进行项目开发.md ├── 数据库操作.md ├── 模板的使用.md └── 表单的处理.md ├── Day66-75 ├── 01.網絡爬蟲和相關工具.md ├── 02.數據采集和解析.md ├── 03.存儲數據.md ├── 04.並發下載.md ├── 05.解析動態內容.md ├── 06.表單交互和驗證碼處理.md ├── Scrapy爬蟲框架入門.md ├── Scrapy爬蟲框架分布式實現.md ├── Scrapy爬蟲框架高級應用.md ├── code │ ├── asyncio01.py │ ├── asyncio02.py │ ├── coroutine01.py │ ├── coroutine02.py │ ├── douban │ │ ├── douban │ │ │ ├── __init__.py │ │ │ ├── items.py │ │ │ ├── middlewares.py │ │ │ ├── pipelines.py │ │ │ ├── settings.py │ │ │ └── spiders │ │ │ │ ├── __init__.py │ │ │ │ └── movie.py │ │ └── scrapy.cfg │ ├── example01.py │ ├── example02.py │ ├── example03.py │ ├── example04.py │ ├── example05.py │ ├── example06.py │ ├── example07.py │ ├── example08.py │ ├── example09.py │ ├── example10.py │ ├── example10a.py │ ├── example11.py │ ├── example11a.py │ ├── example12.py │ ├── generator01.py │ ├── generator02.py │ ├── guido.jpg │ ├── image360 │ │ ├── image360 │ │ │ ├── __init__.py │ │ │ ├── items.py │ │ │ ├── middlewares.py │ │ │ ├── pipelines.py │ │ │ ├── settings.py │ │ │ └── spiders │ │ │ │ ├── __init__.py │ │ │ │ ├── image.py │ │ │ │ └── taobao.py │ │ └── scrapy.cfg │ ├── main.py │ ├── main_redis.py │ ├── myutils.py │ └── tesseract.png └── res │ ├── api-image360.png │ ├── baidu-search-taobao.png │ ├── chrome-developer-tools.png │ ├── crawler-workflow.png │ ├── douban-xpath.png │ ├── http-request.png │ ├── http-response.png │ ├── image360-website.png │ ├── postman.png │ ├── redis-aof.png │ ├── redis-bind.png │ ├── redis-database.png │ ├── redis-port.png │ ├── redis-rdb.png │ ├── redis-replication.png │ ├── redis-save.png │ ├── redis-security.png │ ├── redis-slow-log.png │ ├── scrapy-architecture.png │ └── tesseract.gif ├── Day76-90 ├── 数据处理和可视化.md └── 机器学习.md ├── Day91-100 └── 团队项目开发.md ├── PEP 8風格指南.md ├── Python參考書籍.md ├── Python慣例.md ├── README.md ├── res ├── abstraction-view.png ├── class-and-object.png ├── concurrency.png ├── encapsulation.png ├── int-is-comparation.png ├── modularity.png ├── multi-inheritance.png ├── object-roles.png ├── objects-collaborate.png ├── objects-lifetime.png ├── pycharm-activate.png ├── pycharm-create-launcher-script.png ├── pycharm-import-settings.png ├── pycharm-new-project.png ├── pycharm-plugins.png ├── pycharm-set-ui-theme.png ├── pycharm-welcome.png ├── pycharm-workspace.png ├── python-bj-salary.png ├── python-built-in-functions.png ├── python-cd-salary.png ├── python-job-all.png ├── python-job-chengdu.png ├── python-salary-beijing.png ├── python-salary-chengdu.png ├── python-salary-hangzhou.png ├── python-salary-shanghai.png ├── python-salary-shenzhen.png ├── python-salary.png ├── python-top-10.png ├── python-tutor-visualize.png ├── python-tutor-visualize2.png ├── result-of-dis.png ├── selenium-ide.png └── zen-of-python.png ├── 玩轉PyCharm(上).md ├── 用函數還是用複雜的表達式.md ├── 那些年我們踩過的那些坑.md └── 關於測試.md /.gitignore: -------------------------------------------------------------------------------- 1 | venv 2 | .idea 3 | *.pyc 4 | __pycache__ 5 | 6 | -------------------------------------------------------------------------------- /Day01-15/Day01/hello.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 第一個Python程序 - hello, world! 4 | 向偉大的Dennis M. Ritchie先生致敬 5 | 6 | Version: 0.1 7 | Author: 駱昊 8 | Date: 2018-02-26 9 | 10 | 請將該文件命名爲hello.py並在終端中通過下面的命令運行它 11 | python hello.py 12 | 13 | """ 14 | 15 | print('hello, world!') 16 | # print("你好,世界!") 17 | print('你好', '世界') 18 | print('hello', 'world', sep=', ', end='!') 19 | print('goodbye, world', end='!\n') 20 | -------------------------------------------------------------------------------- /Day01-15/Day01/res/python-idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day01/res/python-idle.png -------------------------------------------------------------------------------- /Day01-15/Day01/res/python-ipython.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day01/res/python-ipython.png -------------------------------------------------------------------------------- /Day01-15/Day01/res/python-jupyter-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day01/res/python-jupyter-1.png -------------------------------------------------------------------------------- /Day01-15/Day01/res/python-jupyter-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day01/res/python-jupyter-2.png -------------------------------------------------------------------------------- /Day01-15/Day01/res/python-pycharm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day01/res/python-pycharm.png -------------------------------------------------------------------------------- /Day01-15/Day01/res/python-sublime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day01/res/python-sublime.png -------------------------------------------------------------------------------- /Day01-15/Day02/centigrade.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 將華氏溫度轉換爲攝氏溫度 4 | F = 1.8C + 32 5 | 6 | Version: 0.1 7 | Author: 駱昊 8 | Date: 2018-02-27 9 | 10 | """ 11 | 12 | f = float(input('請輸入華氏溫度: ')) 13 | c = (f - 32) / 1.8 14 | print('%.1f華氏度 = %.1f攝氏度' % (f, c)) 15 | -------------------------------------------------------------------------------- /Day01-15/Day02/circle.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 輸入半徑計算圓的周長和面積 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-02-27 8 | 9 | """ 10 | 11 | import math 12 | 13 | radius = float(input('請輸入圓的半徑: ')) 14 | perimeter = 2 * math.pi * radius 15 | area = math.pi * radius * radius 16 | print('周長: %.2f' % perimeter) 17 | print('面積: %.2f' % area) 18 | -------------------------------------------------------------------------------- /Day01-15/Day02/leap.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 輸入年份 如果是閏年輸出True 否則輸出False 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-02-27 8 | 9 | """ 10 | 11 | year = int(input('請輸入年份: ')) 12 | # 如果代碼太長寫成一行不便於閱讀 可以使用\或()折行 13 | is_leap = (year % 4 == 0 and year % 100 != 0 or 14 | year % 400 == 0) 15 | print(is_leap) 16 | -------------------------------------------------------------------------------- /Day01-15/Day02/operator.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 運算符的使用 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-02-27 8 | 9 | """ 10 | 11 | a = 5 12 | b = 10 13 | c = 3 14 | d = 4 15 | e = 5 16 | a += b 17 | a -= c 18 | a *= d 19 | a /= e 20 | print("a = ", a) 21 | 22 | flag1 = 3 > 2 23 | flag2 = 2 < 1 24 | flag3 = flag1 and flag2 25 | flag4 = flag1 or flag2 26 | flag5 = not flag1 27 | print("flag1 = ", flag1) 28 | print("flag2 = ", flag2) 29 | print("flag3 = ", flag3) 30 | print("flag4 = ", flag4) 31 | print("flag5 = ", flag5) 32 | print(flag1 is True) 33 | print(flag2 is not False) 34 | -------------------------------------------------------------------------------- /Day01-15/Day02/string.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 字符串常用操作 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-02-27 8 | 9 | """ 10 | 11 | str1 = 'hello, world!' 12 | print('字符串的長度是:', len(str1)) 13 | print('單詞首字母大寫: ', str1.title()) 14 | print('字符串變大寫: ', str1.upper()) 15 | # str1 = str1.upper() 16 | print('字符串是不是大寫: ', str1.isupper()) 17 | print('字符串是不是以hello開頭: ', str1.startswith('hello')) 18 | print('字符串是不是以hello結尾: ', str1.endswith('hello')) 19 | print('字符串是不是以感歎號開頭: ', str1.startswith('!')) 20 | print('字符串是不是一感歎號結尾: ', str1.endswith('!')) 21 | str2 = '- \u9a86\u660a' 22 | str3 = str1.title() + ' ' + str2.lower() 23 | print(str3) 24 | -------------------------------------------------------------------------------- /Day01-15/Day02/variable1.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 使用變量保存數據並進行操作 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-02-27 8 | 9 | """ 10 | 11 | a = 321 12 | b = 123 13 | print(a + b) 14 | print(a - b) 15 | print(a * b) 16 | print(a / b) 17 | print(a // b) 18 | print(a % b) 19 | print(a ** b) 20 | -------------------------------------------------------------------------------- /Day01-15/Day02/variable2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 將input函數輸入的數據保存在變量中並進行操作 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-02-27 8 | 9 | """ 10 | 11 | a = int(input('a = ')) 12 | b = int(input('b = ')) 13 | print(a + b) 14 | print(a - b) 15 | print(a * b) 16 | print(a / b) 17 | print(a // b) 18 | print(a % b) 19 | print(a ** b) 20 | -------------------------------------------------------------------------------- /Day01-15/Day02/variable3.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 格式化輸出 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-02-27 8 | 9 | """ 10 | 11 | a = int(input('a = ')) 12 | b = int(input('b = ')) 13 | print('%d + %d = %d' % (a, b, a + b)) 14 | print('%d - %d = %d' % (a, b, a - b)) 15 | print('%d * %d = %d' % (a, b, a * b)) 16 | print('%d / %d = %f' % (a, b, a / b)) 17 | print('%d // %d = %d' % (a, b, a // b)) 18 | print('%d %% %d = %d' % (a, b, a % b)) 19 | print('%d ** %d = %d' % (a, b, a ** b)) 20 | -------------------------------------------------------------------------------- /Day01-15/Day02/variable4.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 檢查變量的類型 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-02-27 8 | 9 | """ 10 | 11 | a = 100 12 | b = 1000000000000000000 13 | c = 12.345 14 | d = 1 + 5j 15 | e = 'A' 16 | f = 'hello, world' 17 | g = True 18 | print(type(a)) 19 | print(type(b)) 20 | print(type(c)) 21 | print(type(d)) 22 | print(type(e)) 23 | print(type(f)) 24 | print(type(g)) 25 | -------------------------------------------------------------------------------- /Day01-15/Day02/variable5.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 類型轉換 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-02-27 8 | 9 | """ 10 | 11 | a = 100 12 | b = str(a) 13 | c = 12.345 14 | d = str(c) 15 | e = '123' 16 | f = int(e) 17 | g = '123.456' 18 | h = float(g) 19 | i = False 20 | j = str(i) 21 | k = 'hello' 22 | m = bool(k) 23 | print(a) 24 | print(type(a)) 25 | print(b) 26 | print(type(b)) 27 | print(c) 28 | print(type(c)) 29 | print(d) 30 | print(type(d)) 31 | print(e) 32 | print(type(e)) 33 | print(f) 34 | print(type(f)) 35 | print(g) 36 | print(type(g)) 37 | print(h) 38 | print(type(h)) 39 | print(i) 40 | print(type(i)) 41 | print(j) 42 | print(type(j)) 43 | print(k) 44 | print(type(k)) 45 | print(m) 46 | print(type(m)) 47 | -------------------------------------------------------------------------------- /Day01-15/Day03/.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day03/.py -------------------------------------------------------------------------------- /Day01-15/Day03/convert.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 英制單位英寸和公制單位厘米互換 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-02-28 8 | 9 | """ 10 | 11 | value = float(input('請輸入長度: ')) 12 | unit = input('請輸入單位: ') 13 | if unit == 'in' or unit == '英寸': 14 | print('%f英寸 = %f厘米' % (value, value * 2.54)) 15 | elif unit == 'cm' or unit == '厘米': 16 | print('%f厘米 = %f英寸' % (value, value / 2.54)) 17 | else: 18 | print('請輸入有效的單位') 19 | -------------------------------------------------------------------------------- /Day01-15/Day03/grade.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 百分制成績轉等級制成績 4 | 90分以上 --> A 5 | 80分~89分 --> B 6 | 70分~79分 --> C 7 | 60分~69分 --> D 8 | 60分以下 --> E 9 | 10 | Version: 0.1 11 | Author: 駱昊 12 | Date: 2018-02-28 13 | 14 | """ 15 | 16 | score = float(input('請輸入成績: ')) 17 | if score >= 90: 18 | grade = 'A' 19 | elif score >= 80: 20 | grade = 'B' 21 | elif score >= 70: 22 | grade = 'C' 23 | elif score >= 60: 24 | grade = 'D' 25 | else: 26 | grade = 'E' 27 | print('對應的等級是:', grade) 28 | -------------------------------------------------------------------------------- /Day01-15/Day03/piecewise.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 分段函數求值 4 | 3x - 5 (x > 1) 5 | f(x) = x + 2 (-1 <= x <= 1) 6 | 5x + 3 (x < -1) 7 | 8 | Version: 0.1 9 | Author: 駱昊 10 | Date: 2018-02-28 11 | 12 | """ 13 | 14 | x = float(input('x = ')) 15 | if x > 1: 16 | y = 3 * x - 5 17 | elif x >= -1: 18 | y = x + 2 19 | else: 20 | y = 5 * x + 3 21 | print('f(%.2f) = %.2f' % (x, y)) 22 | -------------------------------------------------------------------------------- /Day01-15/Day03/rolldice.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 擲骰子決定做什麽事情 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-02-28 8 | 9 | """ 10 | 11 | from random import randint 12 | 13 | face = randint(1, 6) 14 | if face == 1: 15 | result = '唱首歌' 16 | elif face == 2: 17 | result = '跳個舞' 18 | elif face == 3: 19 | result = '學狗叫' 20 | elif face == 4: 21 | result = '做俯臥撐' 22 | elif face == 5: 23 | result = '念繞口令' 24 | else: 25 | result = '講冷笑話' 26 | print(result) 27 | -------------------------------------------------------------------------------- /Day01-15/Day03/tax.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 輸入月收入和五險一金計算個人所得稅 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-02-28 8 | 9 | """ 10 | 11 | salary = float(input('本月收入: ')) 12 | insurance = float(input('五險一金: ')) 13 | diff = salary - insurance - 3500 14 | if diff <= 0: 15 | rate = 0 16 | deduction = 0 17 | elif diff < 1500: 18 | rate = 0.03 19 | deduction = 0 20 | elif diff < 4500: 21 | rate = 0.1 22 | deduction = 105 23 | elif diff < 9000: 24 | rate = 0.2 25 | deduction = 555 26 | elif diff < 35000: 27 | rate = 0.25 28 | deduction = 1005 29 | elif diff < 55000: 30 | rate = 0.3 31 | deduction = 2755 32 | elif diff < 80000: 33 | rate = 0.35 34 | deduction = 5505 35 | else: 36 | rate = 0.45 37 | deduction = 13505 38 | tax = abs(diff * rate - deduction) 39 | print('個人所得稅: ¥%.2f元' % tax) 40 | print('實際到手收入: ¥%.2f元' % (diff + 3500 - tax)) 41 | -------------------------------------------------------------------------------- /Day01-15/Day03/triangle.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 判斷輸入的邊長能否構成三角形 4 | 如果能則計算出三角形的周長和面積 5 | 6 | Version: 0.1 7 | Author: 駱昊 8 | Date: 2018-02-28 9 | 10 | """ 11 | 12 | import math 13 | 14 | a = float(input('a = ')) 15 | b = float(input('b = ')) 16 | c = float(input('c = ')) 17 | if a + b > c and a + c > b and b + c > a: 18 | print('周長: %f' % (a + b + c)) 19 | p = (a + b + c) / 2 20 | area = math.sqrt(p * (p - a) * (p - b) * (p - c)) 21 | print('面積: %f' % (area)) 22 | else: 23 | print('不能構成三角形') 24 | -------------------------------------------------------------------------------- /Day01-15/Day03/verify.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 用戶身份驗證 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-02-28 8 | 9 | """ 10 | 11 | # import getpass 12 | # from getpass import getpass 13 | # from getpass import * 14 | 15 | username = input('請輸入用戶名: ') 16 | password = input('請輸入口令: ') 17 | # 輸入口令的時候終端中沒有回顯 18 | # password = getpass.getpass('請輸入口令: ') 19 | if username == 'admin' and password == '123456': 20 | print('身份驗證成功!') 21 | else: 22 | print('身份驗證失敗!') 23 | -------------------------------------------------------------------------------- /Day01-15/Day04/for1.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 用for循環實現1~100求和 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-01 8 | 9 | """ 10 | 11 | sum = 0 12 | for x in range(1, 101): 13 | if x % 2 == 0: 14 | sum += x 15 | print(sum) 16 | -------------------------------------------------------------------------------- /Day01-15/Day04/for2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 用for循環實現1~100之間的偶數求和 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-01 8 | 9 | """ 10 | 11 | sum = 0 12 | for x in range(2, 101, 2): 13 | sum += x 14 | print(sum) 15 | -------------------------------------------------------------------------------- /Day01-15/Day04/for3.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 輸入非負整數n計算n! 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-01 8 | 9 | """ 10 | 11 | n = int(input('n = ')) 12 | result = 1 13 | for x in range(1, n + 1): 14 | result *= x 15 | print('%d! = %d' % (n, result)) 16 | -------------------------------------------------------------------------------- /Day01-15/Day04/for4.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 輸入一個正整數判斷它是不是素數 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-01 8 | 9 | """ 10 | 11 | from math import sqrt 12 | 13 | num = int(input('請輸入一個正整數: ')) 14 | end = int(sqrt(num)) 15 | is_prime = True 16 | for x in range(2, end + 1): 17 | if num % x == 0: 18 | is_prime = False 19 | break 20 | if is_prime and num != 1: 21 | print('%d是素數' % num) 22 | else: 23 | print('%d不是素數' % num) 24 | -------------------------------------------------------------------------------- /Day01-15/Day04/for5.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 輸入兩個正整數計算最大公約數和最小公倍數 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-01 8 | 9 | """ 10 | 11 | x = int(input('x = ')) 12 | y = int(input('y = ')) 13 | if x > y: 14 | (x, y) = (y, x) 15 | for factor in range(x, 0, -1): 16 | if x % factor == 0 and y % factor == 0: 17 | print('%d和%d的最大公約數是%d' % (x, y, factor)) 18 | print('%d和%d的最小公倍數是%d' % (x, y, x * y // factor)) 19 | break 20 | -------------------------------------------------------------------------------- /Day01-15/Day04/for6.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 打印各種三角形圖案 4 | 5 | * 6 | ** 7 | *** 8 | **** 9 | ***** 10 | 11 | * 12 | ** 13 | *** 14 | **** 15 | ***** 16 | 17 | * 18 | *** 19 | ***** 20 | ******* 21 | ********* 22 | 23 | Version: 0.1 24 | Author: 駱昊 25 | Date: 2018-03-01 26 | 27 | """ 28 | 29 | row = int(input('請輸入行數: ')) 30 | for i in range(row): 31 | for _ in range(i + 1): 32 | print('*', end='') 33 | print() 34 | 35 | for i in range(row): 36 | for j in range(row): 37 | if j < row - i - 1: 38 | print(' ', end='') 39 | else: 40 | print('*', end='') 41 | print() 42 | 43 | for i in range(row): 44 | for _ in range(row - i - 1): 45 | print(' ', end='') 46 | for _ in range(2 * i + 1): 47 | print('*', end='') 48 | print() 49 | -------------------------------------------------------------------------------- /Day01-15/Day04/while1.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 用while循環實現1~100求和 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-01 8 | 9 | """ 10 | 11 | sum = 0 12 | num = 1 13 | while num <= 100: 14 | sum += num 15 | num += 1 16 | print(sum) 17 | -------------------------------------------------------------------------------- /Day01-15/Day04/while2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 用while循環實現1~100之間的偶數求和 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-01 8 | 9 | """ 10 | 11 | sum = 0 12 | num = 2 13 | while num <= 100: 14 | sum += num 15 | num += 2 16 | print(sum) 17 | -------------------------------------------------------------------------------- /Day01-15/Day05/chicken.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 求解《百錢百雞》問題 4 | 1只公雞5元 1只母雞3元 3只小雞1元 用100元買100只雞 5 | 問公雞 母雞 小雞各有多少只 6 | 7 | Version: 0.1 8 | Author: 駱昊 9 | Date: 2018-03-02 10 | 11 | """ 12 | 13 | for x in range(0, 20): 14 | for y in range(0, 33): 15 | z = 100 - x - y 16 | if 5 * x + 3 * y + z / 3 == 100: 17 | print('公雞: %d只, 母雞: %d只, 小雞: %d只' % (x, y, z)) 18 | 19 | # 要理解程序背後的算法 - 窮舉法 20 | -------------------------------------------------------------------------------- /Day01-15/Day05/craps.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | Craps賭博遊戲 4 | 玩家搖兩顆色子 如果第一次搖出7點或11點 玩家勝 5 | 如果搖出2點 3點 12點 莊家勝 其他情況遊戲繼續 6 | 玩家再次要色子 如果搖出7點 莊家勝 7 | 如果搖出第一次搖的點數 玩家勝 8 | 否則遊戲繼續 玩家繼續搖色子 9 | 玩家進入遊戲時有1000元的賭注 全部輸光遊戲結束 10 | 11 | Version: 0.1 12 | Author: 駱昊 13 | Date: 2018-03-02 14 | 15 | """ 16 | 17 | from random import randint 18 | 19 | money = 1000 20 | while money > 0: 21 | print('你的總資産爲:', money) 22 | needs_go_on = False 23 | while True: 24 | debt = int(input('請下注: ')) 25 | if debt > 0 and debt <= money: 26 | break 27 | first = randint(1, 6) + randint(1, 6) 28 | print('玩家搖出了%d點' % first) 29 | if first == 7 or first == 11: 30 | print('玩家勝!') 31 | money += debt 32 | elif first == 2 or first == 3 or first == 12: 33 | print('莊家勝!') 34 | money -= debt 35 | else: 36 | needs_go_on = True 37 | 38 | while needs_go_on: 39 | current = randint(1, 6) + randint(1, 6) 40 | print('玩家搖出了%d點' % current) 41 | if current == 7: 42 | print('莊家勝') 43 | money -= debt 44 | needs_go_on = False 45 | elif current == first: 46 | print('玩家勝') 47 | money += debt 48 | needs_go_on = False 49 | 50 | print('你破産了, 遊戲結束!') 51 | -------------------------------------------------------------------------------- /Day01-15/Day05/fibonacci.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 輸出斐波那契數列的前20個數 4 | 1 1 2 3 5 8 13 21 ... 5 | 6 | Version: 0.1 7 | Author: 駱昊 8 | Date: 2018-03-02 9 | 10 | """ 11 | 12 | a = 0 13 | b = 1 14 | for _ in range(20): 15 | (a, b) = (b, a + b) 16 | print(a, end=' ') 17 | -------------------------------------------------------------------------------- /Day01-15/Day05/guess.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 猜數字遊戲 4 | 計算機出一個1~100之間的隨機數由人來猜 5 | 計算機根據人猜的數字分別給出提示大一點/小一點/猜對了 6 | 7 | Version: 0.1 8 | Author: 駱昊 9 | Date: 2018-03-02 10 | 11 | """ 12 | 13 | import random 14 | 15 | answer = random.randint(1, 100) 16 | counter = 0 17 | while True: 18 | counter += 1 19 | number = int(input('請輸入: ')) 20 | if number < answer: 21 | print('大一點') 22 | elif number > answer: 23 | print('小一點') 24 | else: 25 | print('恭喜你猜對了!') 26 | break 27 | print('你總共猜了%d次' % counter) 28 | if counter > 7: 29 | print('你的智商余額明顯不足') 30 | -------------------------------------------------------------------------------- /Day01-15/Day05/lily.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 找出100~999之間的所有水仙花數 4 | 水仙花數是各位立方和等於這個數本身的數 5 | 如: 153 = 1**3 + 5**3 + 3**3 6 | 7 | Version: 0.1 8 | Author: 駱昊 9 | Date: 2018-03-02 10 | 11 | """ 12 | 13 | for num in range(100, 1000): 14 | low = num % 10 15 | mid = num // 10 % 10 16 | high = num // 100 17 | if num == low ** 3 + mid ** 3 + high ** 3: 18 | print(num) 19 | -------------------------------------------------------------------------------- /Day01-15/Day05/palindrome.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 判斷輸入的正整數是不是回文數 4 | 回文數是指將一個正整數從左往右排列和從右往左排列值一樣的數 5 | 6 | Version: 0.1 7 | Author: 駱昊 8 | Date: 2018-03-02 9 | 10 | """ 11 | 12 | num = int(input('請輸入一個正整數: ')) 13 | temp = num 14 | num2 = 0 15 | while temp > 0: 16 | num2 *= 10 17 | num2 += temp % 10 18 | temp //= 10 19 | if num == num2: 20 | print('%d是回文數' % num) 21 | else: 22 | print('%d不是回文數' % num) 23 | -------------------------------------------------------------------------------- /Day01-15/Day05/perfect.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 找出1~9999之間的所有完美數 4 | 完美數是除自身外其他所有因子的和正好等於這個數本身的數 5 | 例如: 6 = 1 + 2 + 3, 28 = 1 + 2 + 4 + 7 + 14 6 | 7 | Version: 0.1 8 | Author: 駱昊 9 | Date: 2018-03-02 10 | 11 | """ 12 | import time 13 | import math 14 | 15 | start = time.clock() 16 | for num in range(1, 10000): 17 | sum = 0 18 | for factor in range(1, int(math.sqrt(num)) + 1): 19 | if num % factor == 0: 20 | sum += factor 21 | if factor > 1 and num / factor != factor: 22 | sum += num / factor 23 | if sum == num: 24 | print(num) 25 | end = time.clock() 26 | print("執行時間:", (end - start), "秒") 27 | 28 | # 通過比較上面兩種不同的解決方案的執行時間 意識到優化程序的重要性 29 | -------------------------------------------------------------------------------- /Day01-15/Day05/prime.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 輸出2~99之間的素數 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-02 8 | 9 | """ 10 | 11 | import math 12 | 13 | for num in range(2, 100): 14 | is_prime = True 15 | for factor in range(2, int(math.sqrt(num)) + 1): 16 | if num % factor == 0: 17 | is_prime = False 18 | break 19 | if is_prime: 20 | print(num, end=' ') 21 | -------------------------------------------------------------------------------- /Day01-15/Day05/table.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 輸出乘法口訣表(九九表) 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-02 8 | 9 | """ 10 | 11 | for i in range(1, 10): 12 | for j in range(1, i + 1): 13 | print('%d*%d=%d' % (i, j, i * j), end='\t') 14 | print() 15 | -------------------------------------------------------------------------------- /Day01-15/Day05/總結和練習.md: -------------------------------------------------------------------------------- 1 | ## 總結和練習 2 | -------------------------------------------------------------------------------- /Day01-15/Day06/function1.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 函數的定義和使用 - 計算組合數C(7,3) 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-05 8 | 9 | """ 10 | 11 | 12 | # 將求階乘的功能封裝成一個函數 13 | def factorial(n): 14 | result = 1 15 | for num in range(1, n + 1): 16 | result *= num 17 | return result 18 | 19 | 20 | print(factorial(7) // factorial(3) // factorial(4)) 21 | -------------------------------------------------------------------------------- /Day01-15/Day06/function2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 函數的定義和使用 - 求最大公約數和最小公倍數 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-05 8 | 9 | """ 10 | 11 | 12 | def gcd(x, y): 13 | if x > y: 14 | (x, y) = (y, x) 15 | for factor in range(x, 1, -1): 16 | if x % factor == 0 and y % factor == 0: 17 | return factor 18 | return 1 19 | 20 | 21 | def lcm(x, y): 22 | return x * y // gcd(x, y) 23 | 24 | 25 | print(gcd(15, 27)) 26 | print(lcm(15, 27)) 27 | -------------------------------------------------------------------------------- /Day01-15/Day06/function3.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | Python的內置函數 4 | - 數學相關: abs / divmod / pow / round / min / max / sum 5 | - 序列相關: len / range / next / filter / map / sorted / slice / reversed 6 | - 類型轉換: chr / ord / str / bool / int / float / complex / bin / oct / hex 7 | - 數據結構: dict / list / set / tuple 8 | - 其他函數: all / any / id / input / open / print / type 9 | 10 | Version: 0.1 11 | Author: 駱昊 12 | Date: 2018-03-05 13 | 14 | """ 15 | 16 | 17 | def myfilter(mystr): 18 | return len(mystr) == 6 19 | 20 | 21 | # help() 22 | print(chr(0x9a86)) 23 | print(hex(ord('駱'))) 24 | print(abs(-1.2345)) 25 | print(round(-1.2345)) 26 | print(pow(1.2345, 5)) 27 | fruits = ['orange', 'peach', 'durian', 'watermelon'] 28 | print(fruits[slice(1, 3)]) 29 | fruits2 = list(filter(myfilter, fruits)) 30 | print(fruits) 31 | print(fruits2) 32 | -------------------------------------------------------------------------------- /Day01-15/Day06/function4.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | Python常用模塊 4 | - 運行時服務相關模塊: copy / pickle / sys / ... 5 | - 數學相關模塊: decimal / math / random / ... 6 | - 字符串處理模塊: codecs / re / ... 7 | - 文件處理相關模塊: shutil / gzip / ... 8 | - 操作係統服務相關模塊: datetime / os / time / logging / io / ... 9 | - 進程和線程相關模塊: multiprocessing / threading / queue 10 | - 網絡應用相關模塊: ftplib / http / smtplib / urllib / ... 11 | - Web編程相關模塊: cgi / webbrowser 12 | - 數據處理和編碼模塊: base64 / csv / html.parser / json / xml / ... 13 | 14 | Version: 0.1 15 | Author: 駱昊 16 | Date: 2018-03-05 17 | 18 | """ 19 | 20 | import time 21 | import shutil 22 | import os 23 | 24 | seconds = time.time() 25 | print(seconds) 26 | localtime = time.localtime(seconds) 27 | print(localtime) 28 | print(localtime.tm_year) 29 | print(localtime.tm_mon) 30 | print(localtime.tm_mday) 31 | asctime = time.asctime(localtime) 32 | print(asctime) 33 | strtime = time.strftime('%Y-%m-%d %H:%M:%S', localtime) 34 | print(strtime) 35 | mydate = time.strptime('2018-1-1', '%Y-%m-%d') 36 | print(mydate) 37 | 38 | shutil.copy('/Users/Hao/hello.py', '/Users/Hao/Desktop/first.py') 39 | os.system('ls -l') 40 | os.chdir('/Users/Hao') 41 | os.system('ls -l') 42 | os.mkdir('test') 43 | -------------------------------------------------------------------------------- /Day01-15/Day06/function5.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 函數的參數 4 | - 默認參數 5 | - 可變參數 6 | - 關鍵字參數 7 | - 命名關鍵字參數 8 | 9 | Version: 0.1 10 | Author: 駱昊 11 | Date: 2018-03-05 12 | 13 | """ 14 | 15 | 16 | # 參數默認值 17 | def f1(a, b=5, c=10): 18 | return a + b * 2 + c * 3 19 | 20 | 21 | print(f1(1, 2, 3)) 22 | print(f1(100, 200)) 23 | print(f1(100)) 24 | print(f1(c=2, b=3, a=1)) 25 | 26 | 27 | # 可變參數 28 | def f2(*args): 29 | sum = 0 30 | for num in args: 31 | sum += num 32 | return sum 33 | 34 | 35 | print(f2(1, 2, 3)) 36 | print(f2(1, 2, 3, 4, 5)) 37 | print(f2()) 38 | 39 | 40 | # 關鍵字參數 41 | def f3(**kw): 42 | if 'name' in kw: 43 | print('歡迎你%s!' % kw['name']) 44 | elif 'tel' in kw: 45 | print('你的聯係電話是: %s!' % kw['tel']) 46 | else: 47 | print('沒找到你的個人信息!') 48 | 49 | 50 | param = {'name': '駱昊', 'age': 38} 51 | f3(**param) 52 | f3(name='駱昊', age=38, tel='13866778899') 53 | f3(user='駱昊', age=38, tel='13866778899') 54 | f3(user='駱昊', age=38, mobile='13866778899') 55 | -------------------------------------------------------------------------------- /Day01-15/Day06/function6.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 作用域問題 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-05 8 | 9 | """ 10 | 11 | 12 | # 局部作用域 13 | def foo1(): 14 | a = 5 15 | 16 | 17 | foo1() 18 | # print(a) # NameError 19 | 20 | # 全局作用域 21 | b = 10 22 | 23 | 24 | def foo2(): 25 | print(b) 26 | 27 | 28 | foo2() 29 | 30 | 31 | def foo3(): 32 | b = 100 # 局部變量 33 | print(b) 34 | 35 | 36 | foo3() 37 | print(b) 38 | 39 | 40 | def foo4(): 41 | global b 42 | b = 200 # 全局變量 43 | print(b) 44 | 45 | 46 | foo4() 47 | print(b) 48 | -------------------------------------------------------------------------------- /Day01-15/Day07/avgscore.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 輸入學生考試成績計算平均分 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-06 8 | 9 | """ 10 | 11 | 12 | def main(): 13 | number = int(input('請輸入學生人數: ')) 14 | names = [None] * number 15 | scores = [None] * number 16 | for index in range(len(names)): 17 | names[index] = input('請輸入第%d個學生的名字: ' % (index + 1)) 18 | scores[index] = float(input('請輸入第%d個學生的成績: ' % (index + 1))) 19 | total = 0 20 | for index in range(len(names)): 21 | print('%s: %.1f分' % (names[index], scores[index])) 22 | total += scores[index] 23 | print('平均成績是: %.1f分' % (total / number)) 24 | 25 | 26 | if __name__ == '__main__': 27 | main() 28 | -------------------------------------------------------------------------------- /Day01-15/Day07/dict1.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 定義和使用字典 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-06 8 | 9 | """ 10 | 11 | 12 | def main(): 13 | scores = {'駱昊': 95, '白元芳': 78, '狄仁傑': 82} 14 | print(scores['駱昊']) 15 | print(scores['狄仁傑']) 16 | for elem in scores: 17 | print('%s\t--->\t%d' % (elem, scores[elem])) 18 | scores['白元芳'] = 65 19 | scores['諸葛王朗'] = 71 20 | scores.update(冷面=67, 方啓鶴=85) 21 | print(scores) 22 | if '武則天' in scores: 23 | print(scores['武則天']) 24 | print(scores.get('武則天')) 25 | print(scores.get('武則天', 60)) 26 | print(scores.popitem()) 27 | print(scores.popitem()) 28 | print(scores.pop('駱昊', 100)) 29 | scores.clear() 30 | print(scores) 31 | 32 | 33 | if __name__ == '__main__': 34 | main() 35 | -------------------------------------------------------------------------------- /Day01-15/Day07/dict2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 字典的常用操作 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-06 8 | 9 | """ 10 | 11 | 12 | def main(): 13 | stu = {'name': '駱昊', 'age': 38, 'gender': True} 14 | print(stu) 15 | print(stu.keys()) 16 | print(stu.values()) 17 | print(stu.items()) 18 | for elem in stu.items(): 19 | print(elem) 20 | print(elem[0], elem[1]) 21 | if 'age' in stu: 22 | stu['age'] = 20 23 | print(stu) 24 | stu.setdefault('score', 60) 25 | print(stu) 26 | stu.setdefault('score', 100) 27 | print(stu) 28 | stu['score'] = 100 29 | print(stu) 30 | 31 | 32 | if __name__ == '__main__': 33 | main() 34 | -------------------------------------------------------------------------------- /Day01-15/Day07/fibonacci.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 生成斐波拉切數列 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-06 8 | 9 | """ 10 | 11 | 12 | def main(): 13 | f = [1 , 1] 14 | for i in range(2, 20): 15 | f += [f[i - 1] + f[i - 2]] 16 | # f.append(f[i - 1] + f[i - 2]) 17 | for val in f: 18 | print(val, end=' ') 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Day01-15/Day07/findmax.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 找出列表中最大或最小的元素 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-06 8 | 9 | """ 10 | 11 | 12 | def main(): 13 | fruits = ['grape', 'apple', 'strawberry', 'waxberry', 'pitaya'] 14 | # 直接使用內置的max和min函數找出列表中最大和最小元素 15 | # print(max(fruits)) 16 | # print(min(fruits)) 17 | max_value = min_value = fruits[0] 18 | for index in range(1, len(fruits)): 19 | if fruits[index] > max_value: 20 | max_value = fruits[index] 21 | elif fruits[index] < min_value: 22 | min_value = fruits[index] 23 | print('Max:', max_value) 24 | print('Min:', min_value) 25 | 26 | 27 | if __name__ == '__main__': 28 | main() 29 | # 想一想如果最大的元素有兩個要找出第二大的又該怎麽做 30 | -------------------------------------------------------------------------------- /Day01-15/Day07/list1.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 定義和使用列表 4 | - 用下標訪問元素 5 | - 添加元素 6 | - 刪除元素 7 | 8 | Version: 0.1 9 | Author: 駱昊 10 | Date: 2018-03-06 11 | 12 | """ 13 | 14 | 15 | def main(): 16 | fruits = ['grape', '@pple', 'strawberry', 'waxberry'] 17 | print(fruits) 18 | # 通過下標訪問元素 19 | print(fruits[0]) 20 | print(fruits[1]) 21 | print(fruits[-1]) 22 | print(fruits[-2]) 23 | # print(fruits[-5]) # IndexError 24 | # print(fruits[4]) # IndexError 25 | fruits[1] = 'apple' 26 | print(fruits) 27 | # 添加元素 28 | fruits.append('pitaya') 29 | fruits.insert(0, 'banana') 30 | print(fruits) 31 | # 刪除元素 32 | del fruits[1] 33 | fruits.pop() 34 | fruits.pop(0) 35 | fruits.remove('apple') 36 | print(fruits) 37 | 38 | 39 | if __name__ == '__main__': 40 | main() 41 | -------------------------------------------------------------------------------- /Day01-15/Day07/list2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 列表常用操作 4 | - 列表連接 5 | - 獲取長度 6 | - 遍曆列表 7 | - 列表切片 8 | - 列表排序 9 | - 列表反轉 10 | - 查找元素 11 | 12 | Version: 0.1 13 | Author: 駱昊 14 | Date: 2018-03-06 15 | 16 | """ 17 | 18 | 19 | def main(): 20 | fruits = ['grape', 'apple', 'strawberry', 'waxberry'] 21 | fruits += ['pitaya', 'pear', 'mango'] 22 | # 循環遍曆列表元素 23 | for fruit in fruits: 24 | print(fruit.title(), end=' ') 25 | print() 26 | # 列表切片 27 | fruits2 = fruits[1:4] 28 | print(fruits2) 29 | # fruit3 = fruits # 沒有複制列表只創建了新的引用 30 | fruits3 = fruits[:] 31 | print(fruits3) 32 | fruits4 = fruits[-3:-1] 33 | print(fruits4) 34 | fruits5 = fruits[::-1] 35 | print(fruits5) 36 | 37 | 38 | if __name__ == '__main__': 39 | main() 40 | -------------------------------------------------------------------------------- /Day01-15/Day07/list3.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 生成列表 4 | - 用range創建數字列表 5 | - 生成表達式 6 | - 生成器 7 | 8 | Version: 0.1 9 | Author: 駱昊 10 | Date: 2018-03-06 11 | 12 | """ 13 | 14 | 15 | # 生成Fibonacci序列的生成器 16 | def fib(n): 17 | a, b = 0, 1 18 | for _ in range(n): 19 | a, b = b, a + b 20 | yield a 21 | 22 | 23 | def main(): 24 | # 用range創建數值列表 25 | list1 = list(range(1, 11)) 26 | print(list1) 27 | # 生成表達式 28 | list2 = [x * x for x in range(1, 11)] 29 | print(list2) 30 | list3 = [m + n for m in 'ABCDEFG' for n in '12345'] 31 | print(list3) 32 | print(len(list3)) 33 | # 生成器(節省空間但生成下一個元素時需要花費時間) 34 | gen = (m + n for m in 'ABCDEFG' for n in '12345') 35 | print(gen) 36 | for elem in gen: 37 | print(elem, end=' ') 38 | print() 39 | gen = fib(20) 40 | print(gen) 41 | for elem in gen: 42 | print(elem, end=' ') 43 | print() 44 | 45 | 46 | if __name__ == '__main__': 47 | main() 48 | -------------------------------------------------------------------------------- /Day01-15/Day07/lottery.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 雙色球隨機選號程序 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-06 8 | 9 | """ 10 | 11 | from random import randrange, randint, sample 12 | 13 | 14 | def display(balls): 15 | """ 16 | 輸出列表中的雙色球號碼 17 | """ 18 | for index, ball in enumerate(balls): 19 | if index == len(balls) - 1: 20 | print('|', end=' ') 21 | print('%02d' % ball, end=' ') 22 | print() 23 | 24 | 25 | def random_select(): 26 | """ 27 | 隨機選擇一組號碼 28 | """ 29 | red_balls = [x for x in range(1, 34)] 30 | selected_balls = [] 31 | for _ in range(6): 32 | index = randrange(len(red_balls)) 33 | selected_balls.append(red_balls[index]) 34 | del red_balls[index] 35 | # 上面的for循環也可以寫成下面這行代碼 36 | # sample函數是random模塊下的函數 37 | # selected_balls = sample(red_balls, 6) 38 | selected_balls.sort() 39 | selected_balls.append(randint(1, 16)) 40 | return selected_balls 41 | 42 | 43 | def main(): 44 | n = int(input('機選幾注: ')) 45 | for _ in range(n): 46 | display(random_select()) 47 | 48 | 49 | if __name__ == '__main__': 50 | main() 51 | -------------------------------------------------------------------------------- /Day01-15/Day07/marquee.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 輸入學生考試成績計算平均分 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-06 8 | 9 | """ 10 | 11 | import os 12 | import time 13 | 14 | 15 | def main(): 16 | str = 'Welcome to 1000 Phone Chengdu Campus ' 17 | while True: 18 | print(str) 19 | time.sleep(0.2) 20 | str = str[1:] + str[0:1] 21 | # for Windows use os.system('cls') instead 22 | os.system('clear') 23 | 24 | 25 | if __name__ == '__main__': 26 | main() 27 | -------------------------------------------------------------------------------- /Day01-15/Day07/res/fibonacci-blocks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day07/res/fibonacci-blocks.png -------------------------------------------------------------------------------- /Day01-15/Day07/res/ipython-timeit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day07/res/ipython-timeit.png -------------------------------------------------------------------------------- /Day01-15/Day07/res/python-set.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day07/res/python-set.png -------------------------------------------------------------------------------- /Day01-15/Day07/scoretable.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 學生考試成績表 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-06 8 | 9 | """ 10 | 11 | 12 | def main(): 13 | names = ['關羽', '張飛', '趙雲', '馬超', '黃忠'] 14 | subjs = ['語文', '數學', '英語'] 15 | scores = [[0] * 3] * 5 16 | for row, name in enumerate(names): 17 | print('請輸入%s的成績' % name) 18 | for col, subj in enumerate(subjs): 19 | scores[row][col] = float(input(subj + ': ')) 20 | print(scores) 21 | # for row, name in enumerate(names): 22 | # print('請輸入%s的成績' % name) 23 | # scores[row] = [None] * len(subjs) 24 | # for col, subj in enumerate(subjs): 25 | # score = float(input(subj + ': ')) 26 | # scores[row][col] = score 27 | # print(scores) 28 | 29 | if __name__ == '__main__': 30 | main() 31 | -------------------------------------------------------------------------------- /Day01-15/Day07/set1.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 定義和使用集合 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-06 8 | 9 | """ 10 | 11 | 12 | def main(): 13 | set1 = {1, 2, 3, 3, 3, 2} 14 | print(set1) 15 | print('Length =', len(set1)) 16 | set2 = set(range(1, 10)) 17 | print(set2) 18 | set1.add(4) 19 | set1.add(5) 20 | set2.update([11, 12]) 21 | print(set1) 22 | print(set2) 23 | set2.discard(5) 24 | # remove的元素如果不存在會引發KeyError 25 | if 4 in set2: 26 | set2.remove(4) 27 | print(set2) 28 | # 遍曆集合容器 29 | for elem in set2: 30 | print(elem ** 2, end=' ') 31 | print() 32 | # 將元組轉換成集合 33 | set3 = set((1, 2, 3, 3, 2, 1)) 34 | print(set3.pop()) 35 | print(set3) 36 | 37 | 38 | if __name__ == '__main__': 39 | main() 40 | -------------------------------------------------------------------------------- /Day01-15/Day07/set2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 集合的常用操作 4 | - 交集 5 | - 並集 6 | - 差集 7 | - 子集 8 | - 超集 9 | 10 | Version: 0.1 11 | Author: 駱昊 12 | Date: 2018-03-06 13 | 14 | """ 15 | 16 | 17 | def main(): 18 | set1 = set(range(1, 7)) 19 | print(set1) 20 | set2 = set(range(2, 11, 2)) 21 | print(set2) 22 | set3 = set(range(1, 5)) 23 | print(set1 & set2) 24 | # print(set1.intersection(set2)) 25 | print(set1 | set2) 26 | # print(set1.union(set2)) 27 | print(set1 - set2) 28 | # print(set1.difference(set2)) 29 | print(set1 ^ set2) 30 | # print(set1.symmetric_difference(set2)) 31 | print(set2 <= set1) 32 | # print(set2.issubset(set1)) 33 | print(set3 <= set1) 34 | # print(set3.issubset(set1)) 35 | print(set1 >= set2) 36 | # print(set1.issuperset(set2)) 37 | print(set1 >= set3) 38 | # print(set1.issuperset(set3)) 39 | 40 | 41 | if __name__ == '__main__': 42 | main() 43 | -------------------------------------------------------------------------------- /Day01-15/Day07/tic-tac-toe.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 井字棋遊戲 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-06 8 | 9 | """ 10 | 11 | import os 12 | 13 | 14 | 15 | def print_board(board): 16 | print(board['TL'] + '|' + board['TM'] + '|' + board['TR']) 17 | print('-+-+-') 18 | print(board['ML'] + '|' + board['MM'] + '|' + board['MR']) 19 | print('-+-+-') 20 | print(board['BL'] + '|' + board['BM'] + '|' + board['BR']) 21 | 22 | 23 | def main(): 24 | init_board = { 25 | 'TL': ' ', 'TM': ' ', 'TR': ' ', 26 | 'ML': ' ', 'MM': ' ', 'MR': ' ', 27 | 'BL': ' ', 'BM': ' ', 'BR': ' ' 28 | } 29 | begin = True 30 | while begin: 31 | curr_board = init_board.copy() 32 | begin = False 33 | turn = 'x' 34 | counter = 0 35 | os.system('clear') 36 | print_board(curr_board) 37 | while counter < 9: 38 | move = input('輪到%s走棋, 請輸入位置: ' % turn) 39 | if curr_board[move] == ' ': 40 | counter += 1 41 | curr_board[move] = turn 42 | if turn == 'x': 43 | turn = 'o' 44 | else: 45 | turn = 'x' 46 | os.system('clear') 47 | print_board(curr_board) 48 | choice = input('再玩一局?(yes|no)') 49 | begin = choice == 'yes' 50 | 51 | 52 | if __name__ == '__main__': 53 | main() 54 | -------------------------------------------------------------------------------- /Day01-15/Day07/tuple.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 元組的定義和使用 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-06 8 | 9 | """ 10 | 11 | 12 | def main(): 13 | # 定義元組 14 | t = ('駱昊', 38, True, '四川成都') 15 | print(t) 16 | # 獲取元組中的元素 17 | print(t[0]) 18 | print(t[1]) 19 | print(t[2]) 20 | print(t[3]) 21 | # 遍曆元組中的值 22 | for member in t: 23 | print(member) 24 | # 重新給元組賦值 25 | # t[0] = '王大錘' # TypeError 26 | # 變量t重新引用了新的元組 原來的元組被垃圾回收 27 | t = ('王大錘', 20, True, '雲南昆明') 28 | print(t) 29 | # 元組和列表的轉換 30 | person = list(t) 31 | print(person) 32 | person[0] = '李小龍' 33 | person[1] = 25 34 | print(person) 35 | fruits_list = ['apple', 'banana', 'orange'] 36 | fruits_tuple = tuple(fruits_list) 37 | print(fruits_tuple) 38 | print(fruits_tuple[1]) 39 | 40 | 41 | if __name__ == '__main__': 42 | main() -------------------------------------------------------------------------------- /Day01-15/Day07/yanghui.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 輸出10行的楊輝三角 - 二項式的n次方展開係數 4 | 1 5 | 1 1 6 | 1 2 1 7 | 1 3 3 1 8 | 1 4 6 4 1 9 | ... ... ... 10 | 11 | 12 | Version: 0.1 13 | Author: 駱昊 14 | Date: 2018-03-06 15 | 16 | """ 17 | 18 | 19 | def main(): 20 | num = int(input('Number of rows: ')) 21 | yh = [[]] * num 22 | for row in range(len(yh)): 23 | yh[row] = [None] * (row + 1) 24 | for col in range(len(yh[row])): 25 | if col == 0 or col == row: 26 | yh[row][col] = 1 27 | else: 28 | yh[row][col] = yh[row - 1][col] + yh[row - 1][col - 1] 29 | print(yh[row][col], end='\t') 30 | print() 31 | 32 | 33 | if __name__ == '__main__': 34 | main() 35 | -------------------------------------------------------------------------------- /Day01-15/Day08/access.py: -------------------------------------------------------------------------------- 1 | class Test: 2 | 3 | def __init__(self, foo): 4 | self.__foo = foo 5 | 6 | def __bar(self): 7 | print(self.__foo) 8 | print('__bar') 9 | 10 | 11 | def main(): 12 | test = Test('hello') 13 | test._Test__bar() 14 | print(test._Test__foo) 15 | 16 | 17 | if __name__ == "__main__": 18 | main() 19 | -------------------------------------------------------------------------------- /Day01-15/Day08/circle.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 練習 4 | 修一個遊泳池 半徑(以米爲單位)在程序運行時輸入 遊泳池外修一條3米寬的過道 5 | 過道的外側修一圈圍牆 已知過道的造價爲25元每平米 圍牆的造價爲32.5元每米 6 | 輸出圍牆和過道的總造價分別是多少錢(精確到小數點後2位) 7 | 8 | Version: 0.1 9 | Author: 駱昊 10 | Date: 2018-03-08 11 | 12 | """ 13 | 14 | import math 15 | 16 | 17 | class Circle(object): 18 | 19 | def __init__(self, radius): 20 | self._radius = radius 21 | 22 | @property 23 | def radius(self): 24 | return self._radius 25 | 26 | @radius.setter 27 | def radius(self, radius): 28 | self._radius = radius if radius > 0 else 0 29 | 30 | @property 31 | def perimeter(self): 32 | return 2 * math.pi * self._radius 33 | 34 | @property 35 | def area(self): 36 | return math.pi * self._radius * self._radius 37 | 38 | 39 | if __name__ == '__main__': 40 | radius = float(input('請輸入遊泳池的半徑: ')) 41 | small = Circle(radius) 42 | big = Circle(radius + 3) 43 | print('圍牆的造價爲: ¥%.1f元' % (big.perimeter * 115)) 44 | print('過道的造價爲: ¥%.1f元' % ((big.area - small.area) * 65)) 45 | -------------------------------------------------------------------------------- /Day01-15/Day08/clock.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 定義和使用時鍾類 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-08 8 | 9 | """ 10 | 11 | import time 12 | import os 13 | 14 | 15 | class Clock(object): 16 | 17 | # Python中的函數是沒有重載的概念的 18 | # 因爲Python中函數的參數沒有類型而且支持缺省參數和可變參數 19 | # 用關鍵字參數讓構造器可以傳入任意多個參數來實現其他語言中的構造器重載 20 | def __init__(self, **kw): 21 | if 'hour' in kw and 'minute' in kw and 'second' in kw: 22 | self._hour = kw['hour'] 23 | self._minute = kw['minute'] 24 | self._second = kw['second'] 25 | else: 26 | tm = time.localtime(time.time()) 27 | self._hour = tm.tm_hour 28 | self._minute = tm.tm_min 29 | self._second = tm.tm_sec 30 | 31 | def run(self): 32 | self._second += 1 33 | if self._second == 60: 34 | self._second = 0 35 | self._minute += 1 36 | if self._minute == 60: 37 | self._minute = 0 38 | self._hour += 1 39 | if self._hour == 24: 40 | self._hour = 0 41 | 42 | def show(self): 43 | return '%02d:%02d:%02d' % (self._hour, self._minute, self._second) 44 | 45 | 46 | if __name__ == '__main__': 47 | # clock = Clock(hour=10, minute=5, second=58) 48 | clock = Clock() 49 | while True: 50 | os.system('clear') 51 | print(clock.show()) 52 | time.sleep(1) 53 | clock.run() 54 | -------------------------------------------------------------------------------- /Day01-15/Day08/guess.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 面向對象版本的猜數字遊戲 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-08 8 | 9 | """ 10 | 11 | from random import randint 12 | 13 | 14 | class GuessMachine(object): 15 | 16 | def __init__(self): 17 | self._answer = None 18 | self._counter = None 19 | self._hint = None 20 | 21 | def reset(self): 22 | self._answer = randint(1, 100) 23 | self._counter = 0 24 | self._hint = None 25 | 26 | def guess(self, your_answer): 27 | self._counter += 1 28 | if your_answer > self._answer: 29 | self._hint = '小一點' 30 | elif your_answer < self._answer: 31 | self._hint = '大一點' 32 | else: 33 | self._hint = '恭喜你猜對了' 34 | return True 35 | return False 36 | 37 | @property 38 | def counter(self): 39 | return self._counter 40 | 41 | @property 42 | def hint(self): 43 | return self._hint 44 | 45 | 46 | if __name__ == '__main__': 47 | gm = GuessMachine() 48 | play_again = True 49 | while play_again: 50 | game_over = False 51 | gm.reset() 52 | while not game_over: 53 | your_answer = int(input('請輸入: ')) 54 | game_over = gm.guess(your_answer) 55 | print(gm.hint) 56 | if gm.counter > 7: 57 | print('智商余額不足!') 58 | play_again = input('再玩一次?(yes|no)') == 'yes' 59 | -------------------------------------------------------------------------------- /Day01-15/Day08/hack.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 另一種創建類的方式 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-08 8 | 9 | """ 10 | 11 | 12 | def bar(self, name): 13 | self._name = name 14 | 15 | 16 | def foo(self, course_name): 17 | print('%s正在學習%s.' % (self._name, course_name)) 18 | 19 | 20 | def main(): 21 | Student = type('Student', (object,), dict(__init__=bar, study=foo)) 22 | stu1 = Student('駱昊') 23 | stu1.study('Python程序設計') 24 | 25 | 26 | if __name__ == '__main__': 27 | main() 28 | -------------------------------------------------------------------------------- /Day01-15/Day08/rect.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 定義和使用矩形類 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-08 8 | 9 | """ 10 | 11 | 12 | class Rect(object): 13 | """矩形類""" 14 | 15 | def __init__(self, width=0, height=0): 16 | """構造器""" 17 | self.__width = width 18 | self.__height = height 19 | 20 | def perimeter(self): 21 | """計算周長""" 22 | return (self.__width + self.__height) * 2 23 | 24 | def area(self): 25 | """計算面積""" 26 | return self.__width * self.__height 27 | 28 | def __str__(self): 29 | """矩形對象的字符串表達式""" 30 | return '矩形[%f,%f]' % (self.__width, self.__height) 31 | 32 | def __del__(self): 33 | """析構器""" 34 | print('銷毀矩形對象') 35 | 36 | 37 | if __name__ == '__main__': 38 | rect1 = Rect() 39 | print(rect1) 40 | print(rect1.perimeter()) 41 | print(rect1.area()) 42 | rect2 = Rect(3.5, 4.5) 43 | print(rect2) 44 | print(rect2.perimeter()) 45 | print(rect2.area()) 46 | -------------------------------------------------------------------------------- /Day01-15/Day08/res/object-feature.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day08/res/object-feature.png -------------------------------------------------------------------------------- /Day01-15/Day08/res/oop-zhihu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day08/res/oop-zhihu.png -------------------------------------------------------------------------------- /Day01-15/Day08/student.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 定義和使用學生類 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-08 8 | 9 | """ 10 | 11 | 12 | def _foo(): 13 | print('test') 14 | 15 | 16 | class Student(object): 17 | 18 | # __init__是一個特殊方法用於在創建對象時進行初始化操作 19 | # 通過這個方法我們可以爲學生對象綁定name和age兩個屬性 20 | def __init__(self, name, age): 21 | self.name = name 22 | self.age = age 23 | 24 | def study(self, course_name): 25 | print('%s正在學習%s.' % (self.name, course_name)) 26 | 27 | # PEP 8要求標識符的名字用全小寫多個單詞用下劃線連接 28 | # 但是很多程序員和公司更傾向於使用駝峰命名法(駝峰標識) 29 | def watch_av(self): 30 | if self.age < 18: 31 | print('%s只能觀看《熊出沒》.' % self.name) 32 | else: 33 | print('%s正在觀看島國愛情動作片.' % self.name) 34 | 35 | 36 | def main(): 37 | stu1 = Student('駱昊', 38) 38 | stu1.study('Python程序設計') 39 | stu1.watch_av() 40 | stu2 = Student('王大錘', 15) 41 | stu2.study('思想品德') 42 | stu2.watch_av() 43 | 44 | 45 | if __name__ == '__main__': 46 | main() -------------------------------------------------------------------------------- /Day01-15/Day08/test.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day08/test.py -------------------------------------------------------------------------------- /Day01-15/Day09/association.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 對象之間的關聯關係 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-12 8 | 9 | """ 10 | 11 | from math import sqrt 12 | 13 | 14 | class Point(object): 15 | 16 | def __init__(self, x=0, y=0): 17 | self._x = x 18 | self._y = y 19 | 20 | def move_to(self, x, y): 21 | self._x = x 22 | self._y = y 23 | 24 | def move_by(self, dx, dy): 25 | self._x += dx 26 | self._y += dy 27 | 28 | def distance_to(self, other): 29 | dx = self._x - other._x 30 | dy = self._y - other._y 31 | return sqrt(dx ** 2 + dy ** 2) 32 | 33 | def __str__(self): 34 | return '(%s, %s)' % (str(self._x), str(self._y)) 35 | 36 | 37 | class Line(object): 38 | 39 | def __init__(self, start=Point(0, 0), end=Point(0, 0)): 40 | self._start = start 41 | self._end = end 42 | 43 | @property 44 | def start(self): 45 | return self._start 46 | 47 | @start.setter 48 | def start(self, start): 49 | self._start = start 50 | 51 | @property 52 | def end(self): 53 | return self.end 54 | 55 | @end.setter 56 | def end(self, end): 57 | self._end = end 58 | 59 | @property 60 | def length(self): 61 | return self._start.distance_to(self._end) 62 | 63 | 64 | if __name__ == '__main__': 65 | p1 = Point(3, 5) 66 | print(p1) 67 | p2 = Point(-2, -1.5) 68 | print(p2) 69 | line = Line(p1, p2) 70 | print(line.length) 71 | line.start.move_to(2, 1) 72 | line.end = Point(1, 2) 73 | print(line.length) 74 | -------------------------------------------------------------------------------- /Day01-15/Day09/car1.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 屬性的使用 4 | - 訪問器/修改器/刪除器 5 | - 使用__slots__對屬性加以限制 6 | 7 | Version: 0.1 8 | Author: 駱昊 9 | Date: 2018-03-12 10 | 11 | """ 12 | 13 | 14 | class Car(object): 15 | 16 | __slots__ = ('_brand', '_max_speed') 17 | 18 | def __init__(self, brand, max_speed): 19 | self._brand = brand 20 | self._max_speed = max_speed 21 | 22 | @property 23 | def brand(self): 24 | return self._brand 25 | 26 | @brand.setter 27 | def brand(self, brand): 28 | self._brand = brand 29 | 30 | @brand.deleter 31 | def brand(self): 32 | del self._brand 33 | 34 | @property 35 | def max_speed(self): 36 | return self._max_speed 37 | 38 | @max_speed.setter 39 | def max_speed(self, max_speed): 40 | if max_speed < 0: 41 | raise ValueError('Invalid max speed for car') 42 | self._max_speed = max_speed 43 | 44 | def __str__(self): 45 | return 'Car: [品牌=%s, 最高時速=%d]' % (self._brand, self._max_speed) 46 | 47 | 48 | car = Car('QQ', 120) 49 | print(car) 50 | # ValueError 51 | # car.max_speed = -100 52 | car.max_speed = 320 53 | car.brand = "Benz" 54 | # 使用__slots__屬性限制後下面的代碼將産生異常 55 | # car.current_speed = 80 56 | print(car) 57 | # 如果提供了刪除器可以執行下面的代碼 58 | # del car.brand 59 | # 屬性的實現 60 | print(Car.brand) 61 | print(Car.brand.fget) 62 | print(Car.brand.fset) 63 | print(Car.brand.fdel) 64 | # 通過上面的代碼幫助學生理解之前提到的包裝器的概念 65 | # Python中有很多類似的語法糖後面還會出現這樣的東西 66 | -------------------------------------------------------------------------------- /Day01-15/Day09/car2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 屬性的使用 4 | - 使用已有方法定義訪問器/修改器/刪除器 5 | 6 | Version: 0.1 7 | Author: 駱昊 8 | Date: 2018-03-12 9 | 10 | """ 11 | 12 | 13 | class Car(object): 14 | 15 | def __init__(self, brand, max_speed): 16 | self.set_brand(brand) 17 | self.set_max_speed(max_speed) 18 | 19 | def get_brand(self): 20 | return self._brand 21 | 22 | def set_brand(self, brand): 23 | self._brand = brand 24 | 25 | def get_max_speed(self): 26 | return self._max_speed 27 | 28 | def set_max_speed(self, max_speed): 29 | if max_speed < 0: 30 | raise ValueError('Invalid max speed for car') 31 | self._max_speed = max_speed 32 | 33 | def __str__(self): 34 | return 'Car: [品牌=%s, 最高時速=%d]' % (self._brand, self._max_speed) 35 | 36 | # 用已有的修改器和訪問器定義屬性 37 | brand = property(get_brand, set_brand) 38 | max_speed = property(get_max_speed, set_max_speed) 39 | 40 | 41 | car = Car('QQ', 120) 42 | print(car) 43 | # ValueError 44 | # car.max_speed = -100 45 | car.max_speed = 320 46 | car.brand = "Benz" 47 | print(car) 48 | print(Car.brand) 49 | print(Car.brand.fget) 50 | print(Car.brand.fset) 51 | -------------------------------------------------------------------------------- /Day01-15/Day09/clock.py: -------------------------------------------------------------------------------- 1 | from time import time, localtime, sleep 2 | 3 | 4 | class Clock(object): 5 | """數字時鍾""" 6 | 7 | def __init__(self, hour=0, minute=0, second=0): 8 | self._hour = hour 9 | self._minute = minute 10 | self._second = second 11 | 12 | @classmethod 13 | def now(cls): 14 | ctime = localtime(time()) 15 | return cls(ctime.tm_hour, ctime.tm_min, ctime.tm_sec) 16 | 17 | def run(self): 18 | """走字""" 19 | self._second += 1 20 | if self._second == 60: 21 | self._second = 0 22 | self._minute += 1 23 | if self._minute == 60: 24 | self._minute = 0 25 | self._hour += 1 26 | if self._hour == 24: 27 | self._hour = 0 28 | 29 | def show(self): 30 | """顯示時間""" 31 | return '%02d:%02d:%02d' % \ 32 | (self._hour, self._minute, self._second) 33 | 34 | 35 | def main(): 36 | clock = Clock.now() 37 | while True: 38 | print(clock.show()) 39 | sleep(1) 40 | clock.run() 41 | 42 | 43 | if __name__ == '__main__': 44 | main() 45 | -------------------------------------------------------------------------------- /Day01-15/Day09/diamond.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 多重繼承 4 | - 菱形繼承(鑽石繼承) 5 | - C3算法(替代DFS的算法) 6 | 7 | Version: 0.1 8 | Author: 駱昊 9 | Date: 2018-03-12 10 | 11 | """ 12 | 13 | 14 | class A(object): 15 | 16 | def foo(self): 17 | print('foo of A') 18 | 19 | 20 | class B(A): 21 | pass 22 | 23 | 24 | class C(A): 25 | 26 | def foo(self): 27 | print('foo fo C') 28 | 29 | 30 | class D(B, C): 31 | pass 32 | 33 | 34 | class E(D): 35 | 36 | def foo(self): 37 | print('foo in E') 38 | super().foo() 39 | super(B, self).foo() 40 | super(C, self).foo() 41 | 42 | 43 | if __name__ == '__main__': 44 | d = D() 45 | d.foo() 46 | e = E() 47 | e.foo() 48 | -------------------------------------------------------------------------------- /Day01-15/Day09/multi.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 多重繼承 4 | - 通過多重繼承可以給一個類的對象具備多方面的能力 5 | - 這樣在設計類的時候可以避免設計太多層次的複雜的繼承關係 6 | 7 | Version: 0.1 8 | Author: 駱昊 9 | Date: 2018-03-12 10 | 11 | """ 12 | 13 | 14 | class Father(object): 15 | 16 | def __init__(self, name): 17 | self._name = name 18 | 19 | def gamble(self): 20 | print('%s在打麻將.' % self._name) 21 | 22 | def eat(self): 23 | print('%s在大吃大喝.' % self._name) 24 | 25 | 26 | class Monk(object): 27 | 28 | def __init__(self, name): 29 | self._name = name 30 | 31 | def eat(self): 32 | print('%s在吃齋.' % self._name) 33 | 34 | def chant(self): 35 | print('%s在念經.' % self._name) 36 | 37 | 38 | class Musician(object): 39 | 40 | def __init__(self, name): 41 | self._name = name 42 | 43 | def eat(self): 44 | print('%s在細嚼慢咽.' % self._name) 45 | 46 | def play_piano(self): 47 | print('%s在彈鋼琴.' % self._name) 48 | 49 | 50 | # 試一試下面的代碼看看有什麽區別 51 | # class Son(Monk, Father, Musician): 52 | # class Son(Musician, Father, Monk): 53 | 54 | 55 | class Son(Father, Monk, Musician): 56 | 57 | def __init__(self, name): 58 | Father.__init__(self, name) 59 | Monk.__init__(self, name) 60 | Musician.__init__(self, name) 61 | 62 | 63 | son = Son('王大錘') 64 | son.gamble() 65 | # 調用繼承自Father的eat方法 66 | son.eat() 67 | son.chant() 68 | son.play_piano() 69 | -------------------------------------------------------------------------------- /Day01-15/Day09/pet.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | 3 | 4 | class Pet(object, metaclass=ABCMeta): 5 | 6 | def __init__(self, nickname): 7 | self._nickname = nickname 8 | 9 | @abstractmethod 10 | def make_voice(self): 11 | pass 12 | 13 | 14 | class Dog(Pet): 15 | 16 | def make_voice(self): 17 | print('%s: 汪汪汪...' % self._nickname) 18 | 19 | 20 | class Cat(Pet): 21 | 22 | def make_voice(self): 23 | print('%s: 喵...喵...' % self._nickname) 24 | 25 | 26 | def main(): 27 | pets = [Dog('旺財'), Cat('凱蒂'), Dog('大黃')] 28 | for pet in pets: 29 | pet.make_voice() 30 | 31 | 32 | if __name__ == '__main__': 33 | main() 34 | -------------------------------------------------------------------------------- /Day01-15/Day09/res/uml-components.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day09/res/uml-components.png -------------------------------------------------------------------------------- /Day01-15/Day09/res/uml-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day09/res/uml-example.png -------------------------------------------------------------------------------- /Day01-15/Day09/shape.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 繼承的應用 4 | - 抽象類 5 | - 抽象方法 6 | - 方法重寫 7 | - 多態 8 | 9 | Version: 0.1 10 | Author: 駱昊 11 | Date: 2018-03-12 12 | 13 | """ 14 | 15 | from abc import ABCMeta, abstractmethod 16 | from math import pi 17 | 18 | 19 | class Shape(object, metaclass=ABCMeta): 20 | 21 | @abstractmethod 22 | def perimeter(self): 23 | pass 24 | 25 | @abstractmethod 26 | def area(self): 27 | pass 28 | 29 | 30 | class Circle(Shape): 31 | 32 | def __init__(self, radius): 33 | self._radius = radius 34 | 35 | def perimeter(self): 36 | return 2 * pi * self._radius 37 | 38 | def area(self): 39 | return pi * self._radius ** 2 40 | 41 | def __str__(self): 42 | return '我是一個圓' 43 | 44 | 45 | class Rect(Shape): 46 | 47 | def __init__(self, width, height): 48 | self._width = width 49 | self._height = height 50 | 51 | def perimeter(self): 52 | return 2 * (self._width + self._height) 53 | 54 | def area(self): 55 | return self._width * self._height 56 | 57 | def __str__(self): 58 | return '我是一個矩形' 59 | 60 | 61 | if __name__ == '__main__': 62 | shapes = [Circle(5), Circle(3.2), Rect(3.2, 6.3)] 63 | for shape in shapes: 64 | print(shape) 65 | print('周長:', shape.perimeter()) 66 | print('面積:', shape.area()) 67 | -------------------------------------------------------------------------------- /Day01-15/Day09/triangle.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 實例方法和類方法的應用 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-12 8 | 9 | """ 10 | 11 | from math import sqrt 12 | 13 | 14 | class Triangle(object): 15 | 16 | def __init__(self, a, b, c): 17 | self._a = a 18 | self._b = b 19 | self._c = c 20 | 21 | # 靜態方法 22 | @staticmethod 23 | def is_valid(a, b, c): 24 | return a + b > c and b + c > a and c + a > b 25 | 26 | # 實例方法 27 | def perimeter(self): 28 | return self._a + self._b + self._c 29 | 30 | # 實例方法 31 | def area(self): 32 | p = self.perimeter() / 2 33 | return sqrt(p * (p - self._a) * (p - self._b) * (p - self._c)) 34 | 35 | 36 | if __name__ == '__main__': 37 | # 用字符串的split方法將字符串拆分成一個列表 38 | # 再通過map函數對列表中的每個字符串進行映射處理成小數 39 | a, b, c = map(float, input('請輸入三條邊: ').split()) 40 | # 先判斷給定長度的三條邊能否構成三角形 41 | # 如果能才創建三角形對象 42 | if Triangle.is_valid(a, b, c): 43 | tri = Triangle(a, b, c) 44 | print('周長:', tri.perimeter()) 45 | print('面積:', tri.area()) 46 | # 如果傳入對象作爲方法參數也可以通過類調用實例方法 47 | # print('周長:', Triangle.perimeter(tri)) 48 | # print('面積:', Triangle.area(tri)) 49 | # 看看下面的代碼就知道其實二者本質上是一致的 50 | # print(type(tri.perimeter)) 51 | # print(type(Triangle.perimeter)) 52 | else: 53 | print('不能構成三角形.') 54 | -------------------------------------------------------------------------------- /Day01-15/Day10/gui1.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day10/gui1.py -------------------------------------------------------------------------------- /Day01-15/Day10/gui2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 使用tkinter創建GUI 4 | - 使用畫布繪圖 5 | - 處理鼠標事件 6 | 7 | Version: 0.1 8 | Author: 駱昊 9 | Date: 2018-03-14 10 | 11 | """ 12 | 13 | import tkinter 14 | 15 | 16 | def mouse_evt_handler(evt=None): 17 | row = round((evt.y - 20) / 40) 18 | col = round((evt.x - 20) / 40) 19 | pos_x = 40 * col 20 | pos_y = 40 * row 21 | canvas.create_oval(pos_x, pos_y, 40 + pos_x, 40 + pos_y, fill='black') 22 | 23 | 24 | top = tkinter.Tk() 25 | # 設置窗口尺寸 26 | top.geometry('620x620') 27 | # 設置窗口標題 28 | top.title('五子棋') 29 | # 設置窗口大小不可改變 30 | top.resizable(False, False) 31 | # 設置窗口置頂 32 | top.wm_attributes('-topmost', 1) 33 | canvas = tkinter.Canvas(top, width=600, height=600, bd=0, highlightthickness=0) 34 | canvas.bind('', mouse_evt_handler) 35 | canvas.create_rectangle(0, 0, 600, 600, fill='yellow', outline='white') 36 | for index in range(15): 37 | canvas.create_line(20, 20 + 40 * index, 580, 20 + 40 * index, fill='black') 38 | canvas.create_line(20 + 40 * index, 20, 20 + 40 * index, 580, fill='black') 39 | canvas.create_rectangle(15, 15, 585, 585, outline='black', width=4) 40 | canvas.pack() 41 | tkinter.mainloop() 42 | 43 | # 請思考如何用面向對象的編程思想對上面的代碼進行封裝 44 | -------------------------------------------------------------------------------- /Day01-15/Day10/gui3.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 使用tkinter創建GUI 4 | - 在窗口上制作動畫 5 | 6 | Version: 0.1 7 | Author: 駱昊 8 | Date: 2018-03-14 9 | 10 | """ 11 | 12 | import tkinter 13 | import time 14 | 15 | 16 | # 播放動畫效果的函數 17 | def play_animation(): 18 | canvas.move(oval, 2, 2) 19 | canvas.update() 20 | top.after(50, play_animation) 21 | 22 | 23 | x = 10 24 | y = 10 25 | top = tkinter.Tk() 26 | top.geometry('600x600') 27 | top.title('動畫效果') 28 | top.resizable(False, False) 29 | top.wm_attributes('-topmost', 1) 30 | canvas = tkinter.Canvas(top, width=600, height=600, bd=0, highlightthickness=0) 31 | canvas.create_rectangle(0, 0, 600, 600, fill='gray') 32 | oval = canvas.create_oval(10, 10, 60, 60, fill='red') 33 | canvas.pack() 34 | top.update() 35 | play_animation() 36 | tkinter.mainloop() 37 | 38 | # 請思考如何讓小球碰到屏幕的邊界就彈回 39 | # 請思考如何用面向對象的編程思想對上面的代碼進行封裝 40 | -------------------------------------------------------------------------------- /Day01-15/Day10/res/ball-game.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day10/res/ball-game.png -------------------------------------------------------------------------------- /Day01-15/Day10/res/ball.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day10/res/ball.png -------------------------------------------------------------------------------- /Day01-15/Day10/turtle1.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 用turtle模塊繪圖 4 | 這是一個非常有趣的模塊 它模擬一只烏龜在窗口上爬行的方式來進行繪圖 5 | 6 | Version: 0.1 7 | Author: 駱昊 8 | Date: 2018-03-14 9 | 10 | """ 11 | 12 | import turtle 13 | 14 | turtle.pensize(3) 15 | turtle.penup() 16 | turtle.goto(-180, 150) 17 | turtle.pencolor('red') 18 | turtle.fillcolor('yellow') 19 | turtle.pendown() 20 | turtle.begin_fill() 21 | for _ in range(36): 22 | turtle.forward(200) 23 | turtle.right(170) 24 | turtle.end_fill() 25 | turtle.mainloop() 26 | -------------------------------------------------------------------------------- /Day01-15/Day11/.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day11/.py -------------------------------------------------------------------------------- /Day01-15/Day11/csv1.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 讀取CSV文件 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-13 8 | 9 | """ 10 | 11 | import csv 12 | 13 | filename = 'example.csv' 14 | 15 | try: 16 | with open(filename) as f: 17 | reader = csv.reader(f) 18 | data = list(reader) 19 | except FileNotFoundError: 20 | print('無法打開文件:', filename) 21 | else: 22 | for item in data: 23 | print('%-30s%-20s%-10s' % (item[0], item[1], item[2])) 24 | -------------------------------------------------------------------------------- /Day01-15/Day11/csv2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 寫入CSV文件 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-13 8 | 9 | """ 10 | 11 | import csv 12 | 13 | 14 | class Teacher(object): 15 | 16 | def __init__(self, name, age, title): 17 | self.__name = name 18 | self.__age = age 19 | self.__title = title 20 | self.__index = -1 21 | 22 | @property 23 | def name(self): 24 | return self.__name 25 | 26 | @property 27 | def age(self): 28 | return self.__age 29 | 30 | @property 31 | def title(self): 32 | return self.__title 33 | 34 | 35 | filename = 'teacher.csv' 36 | teachers = [Teacher('駱昊', 38, '叫獸'), Teacher('狄仁傑', 25, '磚家')] 37 | 38 | try: 39 | with open(filename, 'w') as f: 40 | writer = csv.writer(f) 41 | for teacher in teachers: 42 | writer.writerow([teacher.name, teacher.age, teacher.title]) 43 | except BaseException as e: 44 | print('無法寫入文件:', filename) 45 | else: 46 | print('保存數據完成!') 47 | -------------------------------------------------------------------------------- /Day01-15/Day11/ex1.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 異常機制 - 處理程序在運行時可能發生的狀態 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-13 8 | 9 | """ 10 | 11 | input_again = True 12 | while input_again: 13 | try: 14 | a = int(input('a = ')) 15 | b = int(input('b = ')) 16 | print('%d / %d = %f' % (a, b, a / b)) 17 | input_again = False 18 | except ValueError: 19 | print('請輸入整數') 20 | except ZeroDivisionError: 21 | print('除數不能爲0') 22 | # 處理異常讓代碼不因異常而崩潰是一方面 23 | # 更重要的是可以通過對異常的處理讓代碼從異常中恢複過來 24 | -------------------------------------------------------------------------------- /Day01-15/Day11/ex2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 異常機制 - 處理程序在運行時可能發生的狀態 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-13 8 | 9 | """ 10 | 11 | input_again = True 12 | while input_again: 13 | try: 14 | a = int(input('a = ')) 15 | b = int(input('b = ')) 16 | print('%d / %d = %f' % (a, b, a / b)) 17 | input_again = False 18 | except (ValueError, ZeroDivisionError) as msg: 19 | print(msg) 20 | -------------------------------------------------------------------------------- /Day01-15/Day11/ex3.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 異常機制 - 處理程序在運行時可能發生的狀態 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-13 8 | 9 | """ 10 | 11 | import time 12 | import sys 13 | 14 | filename = input('請輸入文件名: ') 15 | try: 16 | with open(filename) as f: 17 | lines = f.readlines() 18 | except FileNotFoundError as msg: 19 | print('無法打開文件:', filename) 20 | print(msg) 21 | except UnicodeDecodeError as msg: 22 | print('非文本文件無法解碼') 23 | sys.exit() 24 | else: 25 | for line in lines: 26 | print(line.rstrip()) 27 | time.sleep(0.5) 28 | finally: 29 | # 此處最適合做善後工作 30 | print('不管發生什麽我都會執行') 31 | -------------------------------------------------------------------------------- /Day01-15/Day11/ex4.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 引發異常和異常棧 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-13 8 | 9 | """ 10 | 11 | 12 | def f1(): 13 | raise AssertionError('發生異常') 14 | 15 | 16 | def f2(): 17 | f1() 18 | 19 | 20 | def f3(): 21 | f2() 22 | 23 | 24 | f3() 25 | -------------------------------------------------------------------------------- /Day01-15/Day11/example.csv: -------------------------------------------------------------------------------- 1 | 4/5/2014 13:34,Apples,73 2 | 4/5/2014 3:41,Cherries,85 3 | 4/6/2014 12:46,Pears,14 4 | 4/8/2014 8:59,Oranges,52 5 | 4/10/2014 2:07,Apples,152 6 | 4/10/2014 18:10,Bananas,23 7 | 4/10/2014 2:40,Strawberries,98 8 | -------------------------------------------------------------------------------- /Day01-15/Day11/file1.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 從文本文件中讀取數據 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-13 8 | 9 | """ 10 | 11 | import time 12 | 13 | 14 | def main(): 15 | # 一次性讀取整個文件內容 16 | with open('致橡樹.txt', 'r', encoding='utf-8') as f: 17 | print(f.read()) 18 | 19 | # 通過for-in循環逐行讀取 20 | with open('致橡樹.txt', mode='r') as f: 21 | for line in f: 22 | print(line, end='') 23 | time.sleep(0.5) 24 | print() 25 | 26 | # 讀取文件按行讀取到列表中 27 | with open('致橡樹.txt') as f: 28 | lines = f.readlines() 29 | print(lines) 30 | 31 | 32 | if __name__ == '__main__': 33 | main() 34 | -------------------------------------------------------------------------------- /Day01-15/Day11/file2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 讀取圓周率文件判斷其中是否包含自己的生日 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-13 8 | 9 | """ 10 | 11 | birth = input('請輸入你的生日: ') 12 | with open('pi_million_digits.txt') as f: 13 | lines = f.readlines() 14 | pi_string = '' 15 | for line in lines: 16 | pi_string += line.strip() 17 | if birth in pi_string: 18 | print('Bingo!!!') 19 | -------------------------------------------------------------------------------- /Day01-15/Day11/file3.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 寫文本文件 4 | 將100以內的素數寫入到文件中 5 | 6 | Version: 0.1 7 | Author: 駱昊 8 | Date: 2018-03-13 9 | 10 | """ 11 | 12 | from math import sqrt 13 | 14 | 15 | def is_prime(n): 16 | for factor in range(2, int(sqrt(n)) + 1): 17 | if n % factor == 0: 18 | return False 19 | return True 20 | 21 | 22 | # 試一試有什麽不一樣 23 | # with open('prime.txt', 'a') as f: 24 | with open('prime.txt', 'w') as f: 25 | for num in range(2, 100): 26 | if is_prime(num): 27 | f.write(str(num) + '\n') 28 | print('寫入完成!') 29 | -------------------------------------------------------------------------------- /Day01-15/Day11/file4.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 讀寫二進制文件 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-13 8 | 9 | """ 10 | 11 | import base64 12 | 13 | with open('mm.jpg', 'rb') as f: 14 | data = f.read() 15 | # print(type(data)) 16 | # print(data) 17 | print('字節數:', len(data)) 18 | # 將圖片處理成BASE-64編碼 19 | print(base64.b64encode(data)) 20 | 21 | with open('girl.jpg', 'wb') as f: 22 | f.write(data) 23 | print('寫入完成!') 24 | -------------------------------------------------------------------------------- /Day01-15/Day11/json2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 寫入JSON文件 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-13 8 | 9 | """ 10 | 11 | import json 12 | 13 | teacher_dict = {'name': '白元芳', 'age': 25, 'title': '講師'} 14 | json_str = json.dumps(teacher_dict) 15 | print(json_str) 16 | print(type(json_str)) 17 | fruits_list = ['apple', 'orange', 'strawberry', 'banana', 'pitaya'] 18 | json_str = json.dumps(fruits_list) 19 | print(json_str) 20 | print(type(json_str)) 21 | -------------------------------------------------------------------------------- /Day01-15/Day11/mm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day11/mm.jpg -------------------------------------------------------------------------------- /Day01-15/Day11/res/file-open-mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day11/res/file-open-mode.png -------------------------------------------------------------------------------- /Day01-15/Day11/teacher.csv: -------------------------------------------------------------------------------- 1 | 骆昊,38,叫兽 2 | 狄仁杰,25,砖家 3 | -------------------------------------------------------------------------------- /Day01-15/Day11/致橡树.txt: -------------------------------------------------------------------------------- 1 | 我如果爱你 2 | 绝不学攀援的凌霄花 3 | 借你的高枝炫耀自己 4 | 5 | 我如果爱你 6 | 绝不学痴情的鸟儿 7 | 为绿荫重复单调的歌曲 8 | -------------------------------------------------------------------------------- /Day01-15/Day12/res/tel-start-number.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day12/res/tel-start-number.png -------------------------------------------------------------------------------- /Day01-15/Day12/str1.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 字符串常用操作 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-19 8 | 9 | """ 10 | 11 | import pyperclip 12 | 13 | # 轉義字符 14 | print('My brother\'s name is \'007\'') 15 | # 原始字符串 16 | print(r'My brother\'s name is \'007\'') 17 | 18 | str = 'hello123world' 19 | print('he' in str) 20 | print('her' in str) 21 | # 字符串是否只包含字母 22 | print(str.isalpha()) 23 | # 字符串是否只包含字母和數字 24 | print(str.isalnum()) 25 | # 字符串是否只包含數字 26 | print(str.isdecimal()) 27 | 28 | print(str[0:5].isalpha()) 29 | print(str[5:8].isdecimal()) 30 | 31 | list = ['床前明月光', '疑是地上霜', '舉頭望明月', '低頭思故鄉'] 32 | print('-'.join(list)) 33 | sentence = 'You go your way I will go mine' 34 | words_list = sentence.split() 35 | print(words_list) 36 | email = ' jackfrued@126.com ' 37 | print(email) 38 | print(email.strip()) 39 | print(email.lstrip()) 40 | 41 | # 將文本放入係統剪切板中 42 | pyperclip.copy('老虎不發貓你當我病危呀') 43 | # 從係統剪切板獲得文本 44 | # print(pyperclip.paste()) 45 | -------------------------------------------------------------------------------- /Day01-15/Day12/str2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 字符串常用操作 - 實現字符串倒轉的方法 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-19 8 | 9 | """ 10 | 11 | from io import StringIO 12 | 13 | 14 | def reverse_str1(str): 15 | return str[::-1] 16 | 17 | 18 | def reverse_str2(str): 19 | if len(str) <= 1: 20 | return str 21 | return reverse_str2(str[1:]) + str[0:1] 22 | 23 | 24 | def reverse_str3(str): 25 | # StringIO對象是Python中的可變字符串 26 | # 不應該使用不變字符串做字符串連接操作 因爲會産生很多無用字符串對象 27 | rstr = StringIO() 28 | str_len = len(str) 29 | for index in range(str_len - 1, -1, -1): 30 | rstr.write(str[index]) 31 | return rstr.getvalue() 32 | 33 | 34 | def reverse_str4(str): 35 | return ''.join(str[index] for index in range(len(str) - 1, -1, -1)) 36 | 37 | 38 | def reverse_str5(str): 39 | # 將字符串處理成列表 40 | str_list = list(str) 41 | str_len = len(str) 42 | # 使用zip函數將兩個序列合並成一個産生元組的疊代器 43 | # 每次正好可以取到一前一後兩個下標來實現元素的交換 44 | for i, j in zip(range(str_len // 2), range(str_len - 1, str_len // 2, -1)): 45 | str_list[i], str_list[j] = str_list[j], str_list[i] 46 | # 將列表元素連接成字符串 47 | return ''.join(str_list) 48 | 49 | 50 | if __name__ == '__main__': 51 | str = 'I love Python' 52 | print(reverse_str1(str)) 53 | print(str) 54 | print(reverse_str2(str)) 55 | print(str) 56 | print(reverse_str3(str)) 57 | print(str) 58 | print(reverse_str4(str)) 59 | print(str) 60 | print(reverse_str5(str)) 61 | print(str) 62 | # 提醒學生注意這是一個面試題: 寫出你能想到的實現字符串倒轉的代碼 63 | -------------------------------------------------------------------------------- /Day01-15/Day12/test3.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 驗證輸入用戶名和QQ號是否有效並給出對應的提示信息 4 | 5 | 要求: 6 | 用戶名必須由字母、數字或下劃線構成且長度在6~20個字符之間 7 | QQ號是5~12的數字且首位不能爲0 8 | 9 | """ 10 | 11 | import re 12 | 13 | 14 | def main(): 15 | username = input('請輸入用戶名: ') 16 | qq = input('請輸入QQ號: ') 17 | m1 = re.match(r'^[0-9a-zA-Z_]{6,20}$', username) 18 | if not m1: 19 | print('請輸入有效的用戶名.') 20 | m2 = re.match(r'^[1-9]\d{4,11}$', qq) 21 | if not m2: 22 | print('請輸入有效的QQ號.') 23 | if m1 and m2: 24 | print('你輸入的信息是有效的!') 25 | 26 | 27 | if __name__ == '__main__': 28 | main() 29 | 30 | -------------------------------------------------------------------------------- /Day01-15/Day12/test4.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | 4 | def main(): 5 | # 創建正則表達式對象 使用了前瞻和回顧來保證手機號前後不應該出現數字 6 | pattern = re.compile(r'(?<=\D)(1[38]\d{9}|14[57]\d{8}|15[0-35-9]\d{8}|17[678]\d{8})(?=\D)') 7 | sentence = ''' 8 | 重要的事情說8130123456789遍,我的手機號是13512346789這個靓號, 9 | 不是15600998765,也是110或119,王大錘的手機號才是15600998765。 10 | ''' 11 | # 查找所有匹配並保存到一個列表中 12 | mylist = re.findall(pattern, sentence) 13 | print(mylist) 14 | print('--------華麗的分隔線--------') 15 | # 通過疊代器取出匹配對象並獲得匹配的內容 16 | for temp in pattern.finditer(sentence): 17 | print(temp.group()) 18 | print('--------華麗的分隔線--------') 19 | # 通過search函數指定搜索位置找出所有匹配 20 | m = pattern.search(sentence) 21 | while m: 22 | print(m.group()) 23 | m = pattern.search(sentence, m.end()) 24 | 25 | 26 | if __name__ == '__main__': 27 | main() 28 | -------------------------------------------------------------------------------- /Day01-15/Day12/test5.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | 4 | def main(): 5 | sentence = '你丫是傻叉嗎? 我操你大爺的. Fuck you.' 6 | purified = re.sub('[操肏艹草曹]|fuck|shit|傻[比屄逼叉缺吊屌]|煞筆', 7 | '*', sentence, flags=re.IGNORECASE) 8 | print(purified) 9 | 10 | 11 | if __name__ == '__main__': 12 | main() 13 | -------------------------------------------------------------------------------- /Day01-15/Day13/asyncio1.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 異步I/O操作 - asyncio模塊 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-21 8 | 9 | """ 10 | 11 | import asyncio 12 | import threading 13 | # import time 14 | 15 | 16 | @asyncio.coroutine 17 | def hello(): 18 | print('%s: hello, world!' % threading.current_thread()) 19 | # 休眠不會阻塞主線程因爲使用了異步I/O操作 20 | # 注意有yield from才會等待休眠操作執行完成 21 | yield from asyncio.sleep(2) 22 | # asyncio.sleep(1) 23 | # time.sleep(1) 24 | print('%s: goodbye, world!' % threading.current_thread()) 25 | 26 | 27 | loop = asyncio.get_event_loop() 28 | tasks = [hello(), hello()] 29 | # 等待兩個異步I/O操作執行結束 30 | loop.run_until_complete(asyncio.wait(tasks)) 31 | print('game over!') 32 | loop.close() 33 | -------------------------------------------------------------------------------- /Day01-15/Day13/asyncio2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 異步I/O操作 - async和await 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-21 8 | 9 | """ 10 | 11 | import asyncio 12 | import threading 13 | 14 | 15 | # 通過async修飾的函數不再是普通函數而是一個協程 16 | # 注意async和await將在Python 3.7中作爲關鍵字出現 17 | async def hello(): 18 | print('%s: hello, world!' % threading.current_thread()) 19 | await asyncio.sleep(2) 20 | print('%s: goodbye, world!' % threading.current_thread()) 21 | 22 | 23 | loop = asyncio.get_event_loop() 24 | tasks = [hello(), hello()] 25 | # 等待兩個異步I/O操作執行結束 26 | loop.run_until_complete(asyncio.wait(tasks)) 27 | loop.close() 28 | -------------------------------------------------------------------------------- /Day01-15/Day13/asyncio3.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 異步I/O操作 - asyncio模塊 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-21 8 | 9 | """ 10 | 11 | import asyncio 12 | 13 | 14 | async def wget(host): 15 | print('wget %s...' % host) 16 | connect = asyncio.open_connection(host, 80) 17 | # 異步方式等待連接結果 18 | reader, writer = await connect 19 | header = 'GET / HTTP/1.0\r\nHost: %s\r\n\r\n' % host 20 | writer.write(header.encode('utf-8')) 21 | # 異步I/O方式執行寫操作 22 | await writer.drain() 23 | while True: 24 | # 異步I/O方式執行讀操作 25 | line = await reader.readline() 26 | if line == b'\r\n': 27 | break 28 | print('%s header > %s' % (host, line.decode('utf-8').rstrip())) 29 | writer.close() 30 | 31 | 32 | loop = asyncio.get_event_loop() 33 | # 通過生成式語法創建一個裝了三個協程的列表 34 | hosts_list = ['www.sina.com.cn', 'www.sohu.com', 'www.163.com'] 35 | tasks = [wget(host) for host in hosts_list] 36 | # 下面的方法將異步I/O操作放入EventLoop直到執行完畢 37 | loop.run_until_complete(asyncio.wait(tasks)) 38 | loop.close() 39 | -------------------------------------------------------------------------------- /Day01-15/Day13/coroutine1.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 使用協程 - 模擬快遞中心派發快遞 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-21 8 | 9 | """ 10 | 11 | from time import sleep 12 | from random import random 13 | 14 | 15 | def build_deliver_man(man_id): 16 | total = 0 17 | while True: 18 | total += 1 19 | print('%d號快遞員準備接今天的第%d單.' % (man_id, total)) 20 | pkg = yield 21 | print('%d號快遞員收到編號爲%s的包裹.' % (man_id, pkg)) 22 | sleep(random() * 3) 23 | 24 | 25 | def package_center(deliver_man, max_per_day): 26 | num = 1 27 | deliver_man.send(None) 28 | # next(deliver_man) 29 | while num <= max_per_day: 30 | package_id = 'PKG-%d' % num 31 | deliver_man.send(package_id) 32 | num += 1 33 | sleep(0.1) 34 | deliver_man.close() 35 | print('今天的包裹派送完畢!') 36 | 37 | 38 | dm = build_deliver_man(1) 39 | package_center(dm, 10) 40 | 41 | # 兩個函數雖然沒有調用關係但是創建快遞員的函數作爲一個協程協助了快遞中心函數完成任務 42 | # 想一想如果有多個快遞員的時候應該如何處理 43 | -------------------------------------------------------------------------------- /Day01-15/Day13/coroutine2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 使用協程 - 查看協程的狀態 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-21 8 | 9 | """ 10 | 11 | from time import sleep 12 | from inspect import getgeneratorstate 13 | 14 | 15 | def build_deliver_man(man_id): 16 | total = 0 17 | while True: 18 | total += 1 19 | print('%d號快遞員準備接今天的第%d單.' % (man_id, total)) 20 | pkg = yield 21 | print('%d號快遞員收到編號爲%s的包裹.' % (man_id, pkg)) 22 | sleep(0.5) 23 | 24 | 25 | def package_center(deliver_man, max_per_day): 26 | num = 1 27 | # 創建狀態(GEN_CREATED) - 等待開始執行 28 | print(getgeneratorstate(deliver_man)) 29 | deliver_man.send(None) 30 | # 挂起狀態(GEN_SUSPENDED) - 在yield表達式處暫停 31 | print(getgeneratorstate(deliver_man)) 32 | # next(deliver_man) 33 | while num <= max_per_day: 34 | package_id = 'PKG-%d' % num 35 | deliver_man.send(package_id) 36 | num += 1 37 | deliver_man.close() 38 | # 結束狀態(GEN_CLOSED) - 執行完畢 39 | print(getgeneratorstate(deliver_man)) 40 | print('今天的包裹派送完畢!') 41 | 42 | 43 | dm = build_deliver_man(1) 44 | package_center(dm, 10) 45 | -------------------------------------------------------------------------------- /Day01-15/Day13/generator1.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 生成器 - 生成器語法 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-21 8 | 9 | """ 10 | 11 | seq = [x * x for x in range(10)] 12 | print(seq) 13 | 14 | gen = (x * x for x in range(10)) 15 | print(gen) 16 | for x in gen: 17 | print(x) 18 | 19 | num = 10 20 | gen = (x ** y for x, y in zip(range(1, num), range(num - 1, 0, -1))) 21 | print(gen) 22 | n = 1 23 | while n < num: 24 | print(next(gen)) 25 | n += 1 26 | -------------------------------------------------------------------------------- /Day01-15/Day13/generator2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 生成器 - 使用yield關鍵字 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-21 8 | 9 | """ 10 | 11 | 12 | def fib(num): 13 | n, a, b = 0, 0, 1 14 | while n < num: 15 | yield b 16 | a, b = b, a + b 17 | n += 1 18 | 19 | 20 | for x in fib(20): 21 | print(x) 22 | -------------------------------------------------------------------------------- /Day01-15/Day13/multiprocess1.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 使用Process類創建多個進程 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-20 8 | 9 | """ 10 | 11 | # 通過下面程序的執行結果可以證實 父進程在創建子進程時複制了進程及其數據結構 12 | # 每個進程都有自己獨立的內存空間 所以進程之間共享數據只能通過IPC的方式 13 | 14 | 15 | from multiprocessing import Process, Queue 16 | from time import sleep 17 | 18 | 19 | def sub_task(string, q): 20 | number = q.get() 21 | while number: 22 | print('%d: %s' % (number, string)) 23 | sleep(0.001) 24 | number = q.get() 25 | 26 | 27 | def main(): 28 | q = Queue(10) 29 | for number in range(1, 11): 30 | q.put(number) 31 | Process(target=sub_task, args=('Ping', q)).start() 32 | Process(target=sub_task, args=('Pong', q)).start() 33 | 34 | 35 | if __name__ == '__main__': 36 | main() 37 | -------------------------------------------------------------------------------- /Day01-15/Day13/multiprocess2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 實現進程間的通信 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-20 8 | 9 | """ 10 | 11 | import multiprocessing 12 | import os 13 | 14 | 15 | def sub_task(queue): 16 | print('子進程進程號:', os.getpid()) 17 | counter = 0 18 | while counter < 1000: 19 | queue.put('Pong') 20 | counter += 1 21 | 22 | 23 | if __name__ == '__main__': 24 | print('當前進程號:', os.getpid()) 25 | queue = multiprocessing.Queue() 26 | p = multiprocessing.Process(target=sub_task, args=(queue,)) 27 | p.start() 28 | counter = 0 29 | while counter < 1000: 30 | queue.put('Ping') 31 | counter += 1 32 | p.join() 33 | print('子任務已經完成.') 34 | for _ in range(2000): 35 | print(queue.get(), end='') 36 | -------------------------------------------------------------------------------- /Day01-15/Day13/multiprocess3.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 創建進程調用其他程序 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-20 8 | 9 | """ 10 | 11 | import subprocess 12 | import sys 13 | 14 | def main(): 15 | # 通過sys.argv獲取命令行參數 16 | if len(sys.argv) > 1: 17 | # 第一個命令行參數是程序本身所以從第二個開始取 18 | for index in range(1, len(sys.argv)): 19 | try: 20 | # 通過subprocess模塊的call函數啓動子進程 21 | status = subprocess.call(sys.argv[index]) 22 | except FileNotFoundError: 23 | print('不能執行%s命令' % sys.argv[index]) 24 | else: 25 | print('請使用命令行參數指定要執行的進程') 26 | 27 | 28 | if __name__ == '__main__': 29 | main() 30 | -------------------------------------------------------------------------------- /Day01-15/Day13/multiprocess4.py: -------------------------------------------------------------------------------- 1 | from time import time 2 | 3 | 4 | def main(): 5 | total = 0 6 | number_list = [x for x in range(1, 100000001)] 7 | start = time() 8 | for number in number_list: 9 | total += number 10 | print(total) 11 | end = time() 12 | print('Execution time: %.3fs' % (end - start)) 13 | 14 | 15 | if __name__ == '__main__': 16 | main() -------------------------------------------------------------------------------- /Day01-15/Day13/multithread1.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 使用多線程的情況 - 模擬多個下載任務 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-20 8 | 9 | """ 10 | 11 | from random import randint 12 | from time import time, sleep 13 | import atexit 14 | import _thread 15 | 16 | 17 | def download_task(filename): 18 | print('開始下載%s...' % filename) 19 | time_to_download = randint(5, 10) 20 | print('剩余時間%d秒.' % time_to_download) 21 | sleep(time_to_download) 22 | print('%s下載完成!' % filename) 23 | 24 | 25 | def shutdown_hook(start): 26 | end = time() 27 | print('總共耗費了%.3f秒.' % (end - start)) 28 | 29 | 30 | def main(): 31 | start = time() 32 | # 將多個下載任務放到多個線程中執行 33 | thread1 = _thread.start_new_thread(download_task, ('Python從入門到住院.pdf',)) 34 | thread2 = _thread.start_new_thread(download_task, ('Peking Hot.avi',)) 35 | # 注冊關機鈎子在程序執行結束前計算執行時間 36 | atexit.register(shutdown_hook, start) 37 | 38 | 39 | if __name__ == '__main__': 40 | main() 41 | 42 | # 執行這裏的代碼會引發致命錯誤(不要被這個詞嚇到) 因爲主線程結束後下載線程再想執行就會出問題 43 | # 需要說明一下 由於_thread模塊屬於比較底層的線程操作而且不支持守護線程的概念 44 | # 在實際開發中會有諸多不便 因此我們推薦使用threading模塊提供的高級操作進行多線程編程 45 | -------------------------------------------------------------------------------- /Day01-15/Day13/multithread2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 使用多線程的情況 - 模擬多個下載任務 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-20 8 | 9 | """ 10 | 11 | from random import randint 12 | from threading import Thread 13 | from time import time, sleep 14 | 15 | 16 | def download_task(filename): 17 | print('開始下載%s...' % filename) 18 | time_to_download = randint(5, 10) 19 | sleep(time_to_download) 20 | print('%s下載完成! 耗費了%d秒' % (filename, time_to_download)) 21 | 22 | 23 | def main(): 24 | start = time() 25 | thread1 = Thread(target=download_task, args=('Python從入門到住院.pdf',)) 26 | thread1.start() 27 | thread2 = Thread(target=download_task, args=('Peking Hot.avi',)) 28 | thread2.start() 29 | thread1.join() 30 | thread2.join() 31 | end = time() 32 | print('總共耗費了%.3f秒' % (end - start)) 33 | 34 | 35 | if __name__ == '__main__': 36 | main() 37 | -------------------------------------------------------------------------------- /Day01-15/Day13/multithread3.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 使用多線程的情況 - 模擬多個下載任務 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-20 8 | 9 | """ 10 | 11 | from random import randint 12 | from time import time, sleep 13 | import threading 14 | 15 | 16 | class DownloadTask(threading.Thread): 17 | 18 | def __init__(self, filename): 19 | super().__init__() 20 | self._filename = filename 21 | 22 | def run(self): 23 | print('開始下載%s...' % self._filename) 24 | time_to_download = randint(5, 10) 25 | print('剩余時間%d秒.' % time_to_download) 26 | sleep(time_to_download) 27 | print('%s下載完成!' % self._filename) 28 | 29 | 30 | def main(): 31 | start = time() 32 | # 將多個下載任務放到多個線程中執行 33 | # 通過自定義的線程類創建線程對象 線程啓動後會回調執行run方法 34 | thread1 = DownloadTask('Python從入門到住院.pdf') 35 | thread1.start() 36 | thread2 = DownloadTask('Peking Hot.avi') 37 | thread2.start() 38 | thread1.join() 39 | thread2.join() 40 | end = time() 41 | print('總共耗費了%.3f秒' % (end - start)) 42 | 43 | 44 | if __name__ == '__main__': 45 | main() 46 | 47 | # 請注意通過threading.Thread創建的線程默認是非守護線程 48 | -------------------------------------------------------------------------------- /Day01-15/Day13/multithread4.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 使用多線程的情況 - 耗時間的任務在獨立的線程中執行 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-20 8 | 9 | """ 10 | 11 | import time 12 | import tkinter 13 | import tkinter.messagebox 14 | from threading import Thread 15 | 16 | 17 | def main(): 18 | 19 | class DownloadTaskHandler(Thread): 20 | 21 | def run(self): 22 | # 模擬下載任務需要花費10秒鍾時間 23 | time.sleep(10) 24 | tkinter.messagebox.showinfo('提示', '下載完成!') 25 | # 啓用下載按鈕 26 | button1.config(state=tkinter.NORMAL) 27 | 28 | def download(): 29 | # 禁用下載按鈕 30 | button1.config(state=tkinter.DISABLED) 31 | # 通過daemon參數將線程設置爲守護線程(主程序退出就不再保留執行) 32 | DownloadTaskHandler(daemon=True).start() 33 | 34 | def show_about(): 35 | tkinter.messagebox.showinfo('關於', '作者: 駱昊(v1.0)') 36 | 37 | top = tkinter.Tk() 38 | top.title('單線程') 39 | top.geometry('200x150') 40 | top.wm_attributes('-topmost', 1) 41 | 42 | panel = tkinter.Frame(top) 43 | button1 = tkinter.Button(panel, text='下載', command=download) 44 | button1.pack(side='left') 45 | button2 = tkinter.Button(panel, text='關於', command=show_about) 46 | button2.pack(side='right') 47 | panel.pack(side='bottom') 48 | 49 | tkinter.mainloop() 50 | 51 | 52 | if __name__ == '__main__': 53 | main() 54 | -------------------------------------------------------------------------------- /Day01-15/Day13/multithread5.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 多個線程共享數據 - 沒有鎖的情況 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-20 8 | 9 | """ 10 | 11 | from time import sleep 12 | from threading import Thread, Lock 13 | 14 | 15 | class Account(object): 16 | 17 | def __init__(self): 18 | self._balance = 0 19 | self._lock = Lock() 20 | 21 | def deposit(self, money): 22 | # 先獲取鎖才能執行後續的代碼 23 | self._lock.acquire() 24 | try: 25 | new_balance = self._balance + money 26 | sleep(0.01) 27 | self._balance = new_balance 28 | finally: 29 | # 這段代碼放在finally中保證釋放鎖的操作一定要執行 30 | self._lock.release() 31 | 32 | @property 33 | def balance(self): 34 | return self._balance 35 | 36 | 37 | class AddMoneyThread(Thread): 38 | 39 | def __init__(self, account, money): 40 | super().__init__() 41 | self._account = account 42 | self._money = money 43 | 44 | def run(self): 45 | self._account.deposit(self._money) 46 | 47 | 48 | def main(): 49 | account = Account() 50 | threads = [] 51 | # 創建100個存款的線程向同一個賬戶中存錢 52 | for _ in range(100): 53 | t = AddMoneyThread(account, 1) 54 | threads.append(t) 55 | t.start() 56 | # 等所有存款的線程都執行完畢∫ 57 | for t in threads: 58 | t.join() 59 | print('賬戶余額爲: ¥%d元' % account.balance) 60 | 61 | 62 | if __name__ == '__main__': 63 | main() 64 | -------------------------------------------------------------------------------- /Day01-15/Day13/multithread6.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 多個線程共享數據 - 有鎖的情況 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-20 8 | 9 | """ 10 | 11 | import time 12 | import threading 13 | 14 | 15 | class Account(object): 16 | 17 | def __init__(self): 18 | self._balance = 0 19 | self._lock = threading.Lock() 20 | 21 | def deposit(self, money): 22 | # 獲得鎖後代碼才能繼續執行 23 | self._lock.acquire() 24 | try: 25 | new_balance = self._balance + money 26 | time.sleep(0.01) 27 | self._balance = new_balance 28 | finally: 29 | # 操作完成後一定要記著釋放鎖 30 | self._lock.release() 31 | 32 | @property 33 | def balance(self): 34 | return self._balance 35 | 36 | 37 | if __name__ == '__main__': 38 | account = Account() 39 | # 創建100個存款的線程向同一個賬戶中存錢 40 | for _ in range(100): 41 | threading.Thread(target=account.deposit, args=(1,)).start() 42 | # 等所有存款的線程都執行完畢 43 | time.sleep(2) 44 | print('賬戶余額爲: ¥%d元' % account.balance) 45 | 46 | # 想一想結果爲什麽不是我們期望的100元 47 | -------------------------------------------------------------------------------- /Day01-15/Day13/res/macos-monitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day13/res/macos-monitor.png -------------------------------------------------------------------------------- /Day01-15/Day13/singlethread1.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 不使用多線程的情況 - 模擬多個下載任務 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-20 8 | 9 | """ 10 | 11 | from random import randint 12 | from time import time, sleep 13 | 14 | 15 | def download_task(filename): 16 | print('開始下載%s...' % filename) 17 | time_to_download = randint(5, 10) 18 | sleep(time_to_download) 19 | print('下載完成! 耗費了%d秒' % time_to_download) 20 | 21 | 22 | def main(): 23 | start = time() 24 | download_task('Python從入門到住院.pdf') 25 | download_task('Peking Hot.avi') 26 | end = time() 27 | print('總共耗費了%.2f秒.' % (end - start)) 28 | 29 | 30 | if __name__ == '__main__': 31 | main() 32 | -------------------------------------------------------------------------------- /Day01-15/Day13/singlethread2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 不使用多線程的情況 - 耗時間的任務阻塞主事件循環 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-20 8 | 9 | """ 10 | 11 | import time 12 | import tkinter 13 | import tkinter.messagebox 14 | 15 | 16 | def download(): 17 | # 模擬下載任務需要花費10秒鍾時間 18 | time.sleep(10) 19 | tkinter.messagebox.showinfo('提示', '下載完成!') 20 | 21 | 22 | def show_about(): 23 | tkinter.messagebox.showinfo('關於', '作者: 駱昊(v1.0)') 24 | 25 | 26 | def main(): 27 | top = tkinter.Tk() 28 | top.title('單線程') 29 | top.geometry('200x150') 30 | top.wm_attributes('-topmost', True) 31 | 32 | panel = tkinter.Frame(top) 33 | button1 = tkinter.Button(panel, text='下載', command=download) 34 | button1.pack(side='left') 35 | button2 = tkinter.Button(panel, text='關於', command=show_about) 36 | button2.pack(side='right') 37 | panel.pack(side='bottom') 38 | 39 | tkinter.mainloop() 40 | 41 | 42 | if __name__ == '__main__': 43 | main() 44 | 45 | 46 | # 在不使用多線程的情況下 一旦點擊下載按鈕 由於該操作需要花費10秒中的時間 47 | # 整個主消息循環也會被阻塞10秒鍾無法響應其他的事件 48 | # 事實上 對於沒有因果關係的子任務 這種順序執行的方式並不合理 49 | -------------------------------------------------------------------------------- /Day01-15/Day13/test2.py: -------------------------------------------------------------------------------- 1 | import time 2 | from threading import Thread, Lock 3 | 4 | 5 | class Account(object): 6 | 7 | def __init__(self, balance=0): 8 | self._balance = balance 9 | self._lock = Lock() 10 | 11 | @property 12 | def balance(self): 13 | return self._balance 14 | 15 | def deposit(self, money): 16 | # 當多個線程同時訪問一個資源的時候 就有可能因爲競爭資源導致資源的狀態錯誤 17 | # 被多個線程訪問的資源我們通常稱之爲臨界資源 對臨界資源的訪問需要加上保護 18 | if money > 0: 19 | self._lock.acquire() 20 | try: 21 | new_balance = self._balance + money 22 | time.sleep(0.01) 23 | self._balance = new_balance 24 | finally: 25 | self._lock.release() 26 | 27 | 28 | class AddMoneyThread(Thread): 29 | 30 | def __init__(self, account): 31 | super().__init__() 32 | self._account = account 33 | 34 | def run(self): 35 | self._account.deposit(1) 36 | 37 | 38 | def main(): 39 | account = Account(1000) 40 | tlist = [] 41 | for _ in range(100): 42 | t = AddMoneyThread(account) 43 | tlist.append(t) 44 | t.start() 45 | for t in tlist: 46 | t.join() 47 | print('賬戶余額: %d元' % account.balance) 48 | 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /Day01-15/Day14/chatclient.py: -------------------------------------------------------------------------------- 1 | from socket import socket 2 | from threading import Thread 3 | 4 | 5 | def main(): 6 | 7 | class RefreshScreenThread(Thread): 8 | 9 | def __init__(self, client): 10 | super().__init__() 11 | self._client = client 12 | 13 | def run(self): 14 | while running: 15 | data = self._client.recv(1024) 16 | print(data.decode('utf-8')) 17 | 18 | nickname = input('請輸入你的昵稱: ') 19 | myclient = socket() 20 | myclient.connect(('10.7.189.118', 12345)) 21 | running = True 22 | RefreshScreenThread(myclient).start() 23 | while running: 24 | content = input('請發言: ') 25 | if content == 'byebye': 26 | myclient.send(content.encode('utf-8')) 27 | running = False 28 | else: 29 | msg = nickname + ': ' + content 30 | myclient.send(msg.encode('utf-8')) 31 | 32 | 33 | if __name__ == '__main__': 34 | main() 35 | -------------------------------------------------------------------------------- /Day01-15/Day14/chatserver.py: -------------------------------------------------------------------------------- 1 | from socket import socket 2 | from threading import Thread 3 | 4 | 5 | def main(): 6 | 7 | class ClientHandler(Thread): 8 | 9 | def __init__(self, client): 10 | super().__init__() 11 | self._client = client 12 | 13 | def run(self): 14 | try: 15 | while True: 16 | try: 17 | data = self._client.recv(1024) 18 | if data.decode('utf-8') == 'byebye': 19 | clients.remove(self._client) 20 | self._client.close() 21 | break 22 | else: 23 | for client in clients: 24 | client.send(data) 25 | except Exception as e: 26 | print(e) 27 | clients.remove(self._client) 28 | break 29 | except Exception as e: 30 | print(e) 31 | 32 | server = socket() 33 | server.bind(('10.7.189.118', 12345)) 34 | server.listen(512) 35 | clients = [] 36 | while True: 37 | curr_client, addr = server.accept() 38 | print(addr[0], '連接到服務器.') 39 | clients.append(curr_client) 40 | ClientHandler(curr_client).start() 41 | 42 | 43 | if __name__ == '__main__': 44 | main() 45 | -------------------------------------------------------------------------------- /Day01-15/Day14/fileclient.py: -------------------------------------------------------------------------------- 1 | from socket import socket 2 | from json import loads 3 | from base64 import b64decode 4 | 5 | 6 | def main(): 7 | client = socket() 8 | client.connect(('192.168.1.2', 5566)) 9 | # 定義一個保存二進制數據的對象 10 | in_data = bytes() 11 | # 由於不知道服務器發送的數據有多大每次接收1024字節 12 | data = client.recv(1024) 13 | while data: 14 | # 將收到的數據拼接起來 15 | in_data += data 16 | data = client.recv(1024) 17 | # 將收到的二進制數據解碼成JSON字符串並轉換成字典 18 | # loads函數的作用就是將JSON字符串轉成字典對象 19 | my_dict = loads(in_data.decode('utf-8')) 20 | filename = my_dict['filename'] 21 | filedata = my_dict['filedata'].encode('utf-8') 22 | with open('/Users/Hao/' + filename, 'wb') as f: 23 | # 將base64格式的數據解碼成二進制數據並寫入文件 24 | f.write(b64decode(filedata)) 25 | print('圖片已保存.') 26 | 27 | 28 | if __name__ == '__main__': 29 | main() 30 | -------------------------------------------------------------------------------- /Day01-15/Day14/fileserver.py: -------------------------------------------------------------------------------- 1 | from socket import socket, SOCK_STREAM, AF_INET 2 | from base64 import b64encode 3 | from json import dumps 4 | from threading import Thread 5 | 6 | 7 | def main(): 8 | 9 | # 自定義線程類 10 | class FileTransferHandler(Thread): 11 | 12 | def __init__(self, cclient): 13 | super().__init__() 14 | self.cclient = cclient 15 | 16 | def run(self): 17 | my_dict = {} 18 | my_dict['filename'] = 'guido.jpg' 19 | # JSON是純文本不能攜帶二進制數據 20 | # 所以圖片的二進制數據要處理成base64編碼 21 | my_dict['filedata'] = data 22 | # 通過dumps函數將字典處理成JSON字符串 23 | json_str = dumps(my_dict) 24 | # 發送JSON字符串 25 | self.cclient.send(json_str.encode('utf-8')) 26 | self.cclient.close() 27 | 28 | # 1.創建套接字對象並指定使用哪種傳輸服務 29 | server = socket() 30 | # 2.綁定IP地址和端口(區分不同的服務) 31 | server.bind(('192.168.1.2', 5566)) 32 | # 3.開啓監聽 - 監聽客戶端連接到服務器 33 | server.listen(512) 34 | print('服務器啓動開始監聽...') 35 | with open('guido.jpg', 'rb') as f: 36 | # 將二進制數據處理成base64再解碼成字符串 37 | data = b64encode(f.read()).decode('utf-8') 38 | while True: 39 | client, addr = server.accept() 40 | # 用一個字典(鍵值對)來保存要發送的各種數據 41 | # 待會可以將字典處理成JSON格式在網絡上傳遞 42 | FileTransferHandler(client).start() 43 | 44 | 45 | if __name__ == '__main__': 46 | main() 47 | -------------------------------------------------------------------------------- /Day01-15/Day14/guido.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day14/guido.jpg -------------------------------------------------------------------------------- /Day01-15/Day14/mmdownloader.py: -------------------------------------------------------------------------------- 1 | from time import time 2 | from threading import Thread 3 | 4 | import requests 5 | 6 | 7 | class DownloadHanlder(Thread): 8 | 9 | def __init__(self, url): 10 | super().__init__() 11 | self.url = url 12 | 13 | def run(self): 14 | filename = self.url[self.url.rfind('/') + 1:] 15 | resp = requests.get(self.url) 16 | with open('/Users/Hao/Downloads/' + filename, 'wb') as f: 17 | f.write(resp.content) 18 | 19 | 20 | def main(): 21 | # 通過requests模塊的get函數獲取網絡資源 22 | resp = requests.get( 23 | 'http://api.tianapi.com/meinv/?key=772a81a51ae5c780251b1f98ea431b84&num=10') 24 | # 將服務器返回的JSON格式的數據解析爲字典 25 | data_model = resp.json() 26 | for mm_dict in data_model['newslist']: 27 | url = mm_dict['picUrl'] 28 | # 通過多線程的方式實現圖片下載 29 | DownloadHanlder(url).start() 30 | 31 | 32 | if __name__ == '__main__': 33 | main() 34 | -------------------------------------------------------------------------------- /Day01-15/Day14/res/TCP-IP-model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day14/res/TCP-IP-model.png -------------------------------------------------------------------------------- /Day01-15/Day14/res/after-browser.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day14/res/after-browser.jpg -------------------------------------------------------------------------------- /Day01-15/Day14/res/arpanet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day14/res/arpanet.png -------------------------------------------------------------------------------- /Day01-15/Day14/res/before-browser.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day14/res/before-browser.jpg -------------------------------------------------------------------------------- /Day01-15/Day14/res/browers.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day14/res/browers.jpg -------------------------------------------------------------------------------- /Day01-15/Day14/res/browser-market-place.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day14/res/browser-market-place.jpeg -------------------------------------------------------------------------------- /Day01-15/Day14/res/how-data-is-processed.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day14/res/how-data-is-processed.jpg -------------------------------------------------------------------------------- /Day01-15/Day14/res/osi_rm.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day14/res/osi_rm.gif -------------------------------------------------------------------------------- /Day01-15/Day14/res/osimodel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day14/res/osimodel.png -------------------------------------------------------------------------------- /Day01-15/Day14/res/tcpipprotocols.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day14/res/tcpipprotocols.png -------------------------------------------------------------------------------- /Day01-15/Day14/res/telnet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day01-15/Day14/res/telnet.png -------------------------------------------------------------------------------- /Day01-15/Day14/socket1.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 套接字 - 基於TCP協議創建時間服務器 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-22 8 | 9 | """ 10 | 11 | from socket import * 12 | from time import * 13 | 14 | server = socket(AF_INET, SOCK_STREAM) 15 | server.bind(('localhost', 6789)) 16 | server.listen() 17 | print('服務器已經啓動正在監聽客戶端連接.') 18 | while True: 19 | client, addr = server.accept() 20 | print('客戶端%s:%d連接成功.' % (addr[0], addr[1])) 21 | currtime = localtime(time()) 22 | timestr = strftime('%Y-%m-%d %H:%M:%S', currtime) 23 | client.send(timestr.encode('utf-8')) 24 | client.close() 25 | server.close() 26 | -------------------------------------------------------------------------------- /Day01-15/Day14/socket2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 套接字 - 基於TCP協議創建時間客戶端 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-22 8 | 9 | """ 10 | 11 | from socket import * 12 | 13 | client = socket(AF_INET, SOCK_STREAM) 14 | client.connect(('localhost', 6789)) 15 | while True: 16 | data = client.recv(1024) 17 | if not data: 18 | break 19 | print(data.decode('utf-8')) 20 | client.close() 21 | -------------------------------------------------------------------------------- /Day01-15/Day14/socket3.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 套接字 - 基於UDP協議Echo服務器 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-22 8 | 9 | """ 10 | 11 | from socket import * 12 | from time import * 13 | 14 | server = socket(AF_INET, SOCK_DGRAM) 15 | server.bind(('localhost', 6789)) 16 | while True: 17 | data, addr = server.recvfrom(1024) 18 | server.sendto(data, addr) 19 | server.close() 20 | -------------------------------------------------------------------------------- /Day01-15/Day14/socket4.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 套接字 - 基於UDP協議創建Echo客戶端 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-22 8 | 9 | """ 10 | 11 | from socket import * 12 | 13 | client = socket(AF_INET, SOCK_DGRAM) 14 | while True: 15 | data_str = input('請輸入: ') 16 | client.sendto(data_str.encode('utf-8'), ('localhost', 6789)) 17 | data, addr = client.recvfrom(1024) 18 | data_str = data.decode('utf-8') 19 | print('服務器回應:', data_str) 20 | if data_str == 'bye': 21 | break 22 | client.close() 23 | -------------------------------------------------------------------------------- /Day01-15/Day14/socket5.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | 使用socketserver模塊創建時間服務器 4 | 5 | Version: 0.1 6 | Author: 駱昊 7 | Date: 2018-03-22 8 | 9 | """ 10 | 11 | from socketserver import TCPServer, StreamRequestHandler 12 | from time import * 13 | 14 | 15 | class EchoRequestHandler(StreamRequestHandler): 16 | 17 | def handle(self): 18 | currtime = localtime(time()) 19 | timestr = strftime('%Y-%m-%d %H:%M:%S', currtime) 20 | self.wfile.write(timestr.encode('utf-8')) 21 | 22 | 23 | server = TCPServer(('localhost', 6789), EchoRequestHandler) 24 | server.serve_forever() 25 | -------------------------------------------------------------------------------- /Day01-15/Day14/timeclient.py: -------------------------------------------------------------------------------- 1 | from socket import socket 2 | 3 | 4 | def main(): 5 | client = socket() 6 | client.connect(('10.7.152.69', 6789)) 7 | print(client.recv(1024).decode('utf-8')) 8 | client.close() 9 | 10 | 11 | if __name__ == '__main__': 12 | main() 13 | -------------------------------------------------------------------------------- /Day01-15/Day14/timeserver.py: -------------------------------------------------------------------------------- 1 | from socket import socket, SOCK_STREAM, AF_INET 2 | from datetime import datetime 3 | 4 | 5 | def main(): 6 | # 1.創建套接字對象並指定使用哪種傳輸服務 7 | # family=AF_INET - IPv4地址 8 | # family=AF_INET6 - IPv6地址 9 | # type=SOCK_STREAM - TCP套接字 10 | # type=SOCK_DGRAM - UDP套接字 11 | # type=SOCK_RAW - 原始套接字 12 | server = socket(family=AF_INET, type=SOCK_STREAM) 13 | # 2.綁定IP地址和端口(區分不同的服務) 14 | server.bind(('192.168.1.2', 6789)) 15 | # 3.開啓監聽 - 監聽客戶端連接到服務器 16 | server.listen(512) 17 | print('服務器啓動開始監聽...') 18 | # 4.通過循環接收客戶端的連接並作出相應的處理(提供服務) 19 | while True: 20 | # accept方法是一個阻塞方法如果沒有客戶端連接到服務器 21 | # 這個方法就會阻塞代碼不會向下執行 22 | # accept方法返回元組其中的第一個元素是客戶端對象 23 | # 第二個元素是客戶端的地址(由IP和端口兩部分構成) 24 | client, addr = server.accept() 25 | print(str(addr) + '連接到了服務器.') 26 | # 5.發送數據 27 | client.send(str(datetime.now()).encode('utf-8')) 28 | # 6.斷開連接 29 | client.close() 30 | 31 | 32 | if __name__ == '__main__': 33 | main() 34 | -------------------------------------------------------------------------------- /Day16-20/Python語言進階.md: -------------------------------------------------------------------------------- 1 | ## Python進階知識 2 | 3 | -------------------------------------------------------------------------------- /Day21-30/example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 34 | 35 | 36 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /Day21-30/img/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day21-30/img/Thumbs.db -------------------------------------------------------------------------------- /Day21-30/img/a1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day21-30/img/a1.jpg -------------------------------------------------------------------------------- /Day21-30/img/a2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day21-30/img/a2.jpg -------------------------------------------------------------------------------- /Day21-30/img/a3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day21-30/img/a3.jpg -------------------------------------------------------------------------------- /Day21-30/qq_link.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 點我聊一聊 9 | 10 | -------------------------------------------------------------------------------- /Day21-30/res/browser-joke-1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day21-30/res/browser-joke-1.jpeg -------------------------------------------------------------------------------- /Day21-30/res/browser-joke-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day21-30/res/browser-joke-2.jpg -------------------------------------------------------------------------------- /Day21-30/res/browser-joke-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day21-30/res/browser-joke-3.jpg -------------------------------------------------------------------------------- /Day21-30/res/dom-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day21-30/res/dom-page.png -------------------------------------------------------------------------------- /Day21-30/res/dom-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day21-30/res/dom-tree.png -------------------------------------------------------------------------------- /Day31-35/res/Dennis-Ritchie.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day31-35/res/Dennis-Ritchie.jpg -------------------------------------------------------------------------------- /Day31-35/res/Ken-Thompson.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day31-35/res/Ken-Thompson.png -------------------------------------------------------------------------------- /Day31-35/res/Linus-Torvalds.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day31-35/res/Linus-Torvalds.jpg -------------------------------------------------------------------------------- /Day31-35/res/Stallman.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day31-35/res/Stallman.jpg -------------------------------------------------------------------------------- /Day31-35/res/Tanenbaum.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day31-35/res/Tanenbaum.jpg -------------------------------------------------------------------------------- /Day31-35/res/history-of-os.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day31-35/res/history-of-os.png -------------------------------------------------------------------------------- /Day31-35/res/history-of-unix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day31-35/res/history-of-unix.png -------------------------------------------------------------------------------- /Day31-35/res/linux-network-config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day31-35/res/linux-network-config.png -------------------------------------------------------------------------------- /Day36-40/NoSQL入門.md: -------------------------------------------------------------------------------- 1 | ## NoSQL入門 2 | 3 | ### NoSQL概述 4 | 5 | 6 | 7 | ### 主流NoSQL數據庫 8 | 9 | 10 | 11 | ### Redis概述 12 | 13 | 14 | 15 | ### MongoDB概述 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Day36-40/res/IMG_0358.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day36-40/res/IMG_0358.PNG -------------------------------------------------------------------------------- /Day36-40/res/IMG_0360.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day36-40/res/IMG_0360.png -------------------------------------------------------------------------------- /Day36-40/res/IMG_0361.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day36-40/res/IMG_0361.png -------------------------------------------------------------------------------- /Day36-40/res/IMG_0362.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day36-40/res/IMG_0362.png -------------------------------------------------------------------------------- /Day36-40/res/IMG_0363.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day36-40/res/IMG_0363.png -------------------------------------------------------------------------------- /Day36-40/res/IMG_0364.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day36-40/res/IMG_0364.png -------------------------------------------------------------------------------- /Day36-40/res/IMG_0365.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day36-40/res/IMG_0365.png -------------------------------------------------------------------------------- /Day36-40/res/IMG_0366.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day36-40/res/IMG_0366.png -------------------------------------------------------------------------------- /Day36-40/res/redis-data-type.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day36-40/res/redis-data-type.png -------------------------------------------------------------------------------- /Day36-40/關係型數據庫MySQL.md: -------------------------------------------------------------------------------- 1 | ## 關係型數據入門 2 | 3 | ### 關係型數據概述 4 | 5 | 1. 數據持久化。 6 | 2. 數據庫發展史。 7 | 3. 關係型數據庫特點。 8 | 4. E-R圖。 9 | 5. 關係型數據庫産品。 10 | 11 | ### MySQL簡介 12 | 13 | 1. 安裝和配置。 14 | 2. 常用命令。 15 | 16 | ### SQL詳解 17 | 18 | 1. DDL 19 | 2. DML 20 | 3. DQL 21 | 22 | ### Python數據庫編程 23 | 24 | 1. MySQLdb 25 | 2. PyMySQL 26 | 27 | ### ORM概述 28 | 29 | 30 | -------------------------------------------------------------------------------- /Day41-55/Django2實戰03.md: -------------------------------------------------------------------------------- 1 | ## Django 2.x實戰(03) - 視圖、模板和URL 2 | 3 | -------------------------------------------------------------------------------- /Day41-55/Django2實戰04.md: -------------------------------------------------------------------------------- 1 | ## Django 2.x實戰(04) - 表單的應用 2 | 3 | -------------------------------------------------------------------------------- /Day41-55/Django2實戰05.md: -------------------------------------------------------------------------------- 1 | ## Django 2.x實戰(05) - Cookie和會話 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Day41-55/Django2實戰06.md: -------------------------------------------------------------------------------- 1 | ## Django 2.x實戰(06) - 日志和緩存 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Day41-55/Django2實戰07.md: -------------------------------------------------------------------------------- 1 | ## Django 2.x實戰(07) - 文件上傳和通用視圖 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Day41-55/Django2實戰08.md: -------------------------------------------------------------------------------- 1 | ## Django 2.x實戰(08) - 用戶/角色/權限和中間件 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Day41-55/Django2實戰09.md: -------------------------------------------------------------------------------- 1 | ## Django 2.x實戰(09) - RESTful架構和應用(上) 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Day41-55/Django2實戰10.md: -------------------------------------------------------------------------------- 1 | ## Django 2.x實戰(10) - RESTful架構和應用(下) 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Day41-55/Django2项目实战.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/Django2项目实战.md -------------------------------------------------------------------------------- /Day41-55/car/car/__init__.py: -------------------------------------------------------------------------------- 1 | import pymysql 2 | 3 | pymysql.install_as_MySQLdb() -------------------------------------------------------------------------------- /Day41-55/car/car/urls.py: -------------------------------------------------------------------------------- 1 | """car URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/2.0/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.conf.urls import url 18 | 19 | from search import views 20 | 21 | urlpatterns = [ 22 | url(r'^search$', views.search), 23 | url(r'^search2$', views.ajax_search), 24 | url(r'^add', views.add), 25 | url(r'^admin/', admin.site.urls), 26 | ] 27 | -------------------------------------------------------------------------------- /Day41-55/car/car/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for car project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "car.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Day41-55/car/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "car.settings") 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError as exc: 10 | raise ImportError( 11 | "Couldn't import Django. Are you sure it's installed and " 12 | "available on your PYTHONPATH environment variable? Did you " 13 | "forget to activate a virtual environment?" 14 | ) from exc 15 | execute_from_command_line(sys.argv) 16 | -------------------------------------------------------------------------------- /Day41-55/car/search/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/car/search/__init__.py -------------------------------------------------------------------------------- /Day41-55/car/search/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from search.models import CarRecord 4 | 5 | 6 | class CarRecordAdmin(admin.ModelAdmin): 7 | 8 | list_display = ('carno', 'reason', 'date', 'punish', 'isdone') 9 | search_fields = ('carno', ) 10 | 11 | 12 | admin.site.register(CarRecord, CarRecordAdmin) 13 | -------------------------------------------------------------------------------- /Day41-55/car/search/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class SearchConfig(AppConfig): 5 | name = 'search' 6 | -------------------------------------------------------------------------------- /Day41-55/car/search/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11 on 2018-05-24 01:16 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | initial = True 11 | 12 | dependencies = [ 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='CarRecord', 18 | fields=[ 19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 20 | ('carno', models.CharField(max_length=7)), 21 | ('reason', models.CharField(max_length=50)), 22 | ('date', models.DateTimeField(db_column='happen_date')), 23 | ('punlish', models.CharField(max_length=50)), 24 | ('isdone', models.BooleanField(default=False)), 25 | ], 26 | options={ 27 | 'db_table': 'tb_car_record', 28 | }, 29 | ), 30 | ] 31 | -------------------------------------------------------------------------------- /Day41-55/car/search/migrations/0002_auto_20180524_1420.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11 on 2018-05-24 06:20 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('search', '0001_initial'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterModelOptions( 16 | name='carrecord', 17 | options={'ordering': ('-date',)}, 18 | ), 19 | migrations.RenameField( 20 | model_name='carrecord', 21 | old_name='punlish', 22 | new_name='punish', 23 | ), 24 | ] 25 | -------------------------------------------------------------------------------- /Day41-55/car/search/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/car/search/migrations/__init__.py -------------------------------------------------------------------------------- /Day41-55/car/search/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class CarRecord(models.Model): 5 | carno = models.CharField(max_length=7) 6 | reason = models.CharField(max_length=50) 7 | date = models.DateTimeField(db_column='happen_date', auto_now_add=True) 8 | punish = models.CharField(max_length=50) 9 | isdone = models.BooleanField(default=False) 10 | 11 | @property 12 | def happen_date(self): 13 | return self.date.strftime('%Y-%m-%d %H:%M:%S') 14 | """ 15 | return '%d年%02d月%02d日 %02d:%02d:%02d' % \ 16 | (self.date.year, self.date.month, self.date.day, 17 | self.date.hour, self.date.minute, self.date.second) 18 | """ 19 | 20 | class Meta: 21 | db_table = 'tb_car_record' 22 | ordering = ('-date', ) 23 | -------------------------------------------------------------------------------- /Day41-55/car/search/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Day41-55/car/static/images/icon-no.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Day41-55/car/static/images/icon-yes.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Day41-55/car/templates/add.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 添加 6 | 12 | 13 | 14 |

添加違章記錄

15 |
16 |

17 | {% for hint in hints %} 18 |

{{ hint }}
19 | {% endfor %} 20 |

21 |
22 | {% for field in f.visible_fields %} 23 |
24 | {{ field.label }} 25 | {{ field }} 26 | {% for error in field.errors %} 27 | {{ error }} 28 | {% endfor %} 29 |
30 | {% endfor %} 31 | {% csrf_token %} 32 | 33 |
34 | 35 | -------------------------------------------------------------------------------- /Day41-55/oa/hrs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/oa/hrs/__init__.py -------------------------------------------------------------------------------- /Day41-55/oa/hrs/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from hrs.models import Dept, Emp 4 | 5 | 6 | class DeptAdmin(admin.ModelAdmin): 7 | 8 | list_display = ('no', 'name', 'location') 9 | ordering = ('no', ) 10 | 11 | 12 | class EmpAdmin(admin.ModelAdmin): 13 | 14 | list_display = ('no', 'name', 'job', 'sal', 'dept') 15 | search_fields = ('name', 'job') 16 | ordering = ('dept', ) 17 | 18 | 19 | admin.site.register(Dept, DeptAdmin) 20 | admin.site.register(Emp, EmpAdmin) 21 | -------------------------------------------------------------------------------- /Day41-55/oa/hrs/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class HrsConfig(AppConfig): 5 | name = 'hrs' 6 | -------------------------------------------------------------------------------- /Day41-55/oa/hrs/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.0.5 on 2018-05-22 03:07 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | initial = True 10 | 11 | dependencies = [ 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='Dept', 17 | fields=[ 18 | ('no', models.IntegerField(primary_key=True, serialize=False)), 19 | ('name', models.CharField(max_length=20)), 20 | ('location', models.CharField(max_length=10)), 21 | ], 22 | options={ 23 | 'db_table': 'tb_dept', 24 | }, 25 | ), 26 | migrations.CreateModel( 27 | name='Emp', 28 | fields=[ 29 | ('no', models.IntegerField(primary_key=True, serialize=False)), 30 | ('name', models.CharField(max_length=20)), 31 | ('job', models.CharField(max_length=10)), 32 | ('mgr', models.IntegerField(null=True)), 33 | ('sal', models.DecimalField(decimal_places=2, max_digits=7)), 34 | ('comm', models.DecimalField(decimal_places=2, max_digits=7, null=True)), 35 | ('dept', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='hrs.Dept')), 36 | ], 37 | options={ 38 | 'db_table': 'tb_emp', 39 | }, 40 | ), 41 | ] 42 | -------------------------------------------------------------------------------- /Day41-55/oa/hrs/migrations/0002_auto_20180523_0923.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.0.5 on 2018-05-23 01:23 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('hrs', '0001_initial'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='dept', 15 | name='excellent', 16 | field=models.BooleanField(default=0, verbose_name='是否優秀'), 17 | ), 18 | migrations.AlterField( 19 | model_name='dept', 20 | name='location', 21 | field=models.CharField(max_length=10, verbose_name='部門所在地'), 22 | ), 23 | migrations.AlterField( 24 | model_name='dept', 25 | name='name', 26 | field=models.CharField(max_length=20, verbose_name='部門名稱'), 27 | ), 28 | migrations.AlterField( 29 | model_name='dept', 30 | name='no', 31 | field=models.IntegerField(primary_key=True, serialize=False, verbose_name='部門編號'), 32 | ), 33 | migrations.AlterField( 34 | model_name='emp', 35 | name='comm', 36 | field=models.DecimalField(blank=True, decimal_places=2, max_digits=7, null=True), 37 | ), 38 | migrations.AlterField( 39 | model_name='emp', 40 | name='mgr', 41 | field=models.IntegerField(blank=True, null=True), 42 | ), 43 | ] 44 | -------------------------------------------------------------------------------- /Day41-55/oa/hrs/migrations/0003_auto_20180524_1646.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.0.5 on 2018-05-24 08:46 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('hrs', '0002_auto_20180523_0923'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='emp', 16 | name='mgr', 17 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='hrs.Emp'), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /Day41-55/oa/hrs/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/oa/hrs/migrations/__init__.py -------------------------------------------------------------------------------- /Day41-55/oa/hrs/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # ORM - 對象關係映射 4 | # 對象模型 <---> 關係模型 5 | # 實體類 <---> 二維表 6 | # 屬性 <---> 列 7 | # 對象 <---> 記錄 8 | 9 | 10 | class Dept(models.Model): 11 | no = models.IntegerField(primary_key=True, verbose_name='部門編號') 12 | name = models.CharField(max_length=20, verbose_name='部門名稱') 13 | location = models.CharField(max_length=10, verbose_name='部門所在地') 14 | excellent = models.BooleanField(default=0, verbose_name='是否優秀') 15 | 16 | def __str__(self): 17 | return self.name 18 | 19 | class Meta: 20 | db_table = 'tb_dept' 21 | 22 | 23 | class Emp(models.Model): 24 | no = models.IntegerField(primary_key=True) 25 | name = models.CharField(max_length=20) 26 | job = models.CharField(max_length=10) 27 | mgr = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL) 28 | # mgr = models.IntegerField(null=True, blank=True) 29 | sal = models.DecimalField(max_digits=7, decimal_places=2) 30 | comm = models.DecimalField(max_digits=7, decimal_places=2, null=True, blank=True) 31 | dept = models.ForeignKey(Dept, on_delete=models.PROTECT) 32 | 33 | class Meta: 34 | db_table = 'tb_emp' 35 | -------------------------------------------------------------------------------- /Day41-55/oa/hrs/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Day41-55/oa/hrs/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from hrs import views 4 | 5 | urlpatterns = [ 6 | path('depts', views.depts, name='depts'), 7 | # url('depts/emps/(?P[0-9]+)', views.emps, name='empsindept'), 8 | path('depts/emps/', views.emps, name='empsindept'), 9 | path('deldept/', views.del_dept, name='ddel') 10 | ] 11 | -------------------------------------------------------------------------------- /Day41-55/oa/hrs/views.py: -------------------------------------------------------------------------------- 1 | from django.http import HttpResponse 2 | from django.shortcuts import render, redirect 3 | from django.db.models import ObjectDoesNotExist 4 | 5 | from json import dumps 6 | 7 | from hrs.models import Dept, Emp 8 | 9 | 10 | def index(request): 11 | ctx = { 12 | 'greeting': '你好,世界!' 13 | } 14 | return render(request, 'index.html', context=ctx) 15 | 16 | 17 | def del_dept(request, no='0'): 18 | try: 19 | Dept.objects.get(pk=no).delete() 20 | ctx = {'code': 200} 21 | except (ObjectDoesNotExist, ValueError): 22 | ctx = {'code': 404} 23 | return HttpResponse( 24 | dumps(ctx), content_type='application/json; charset=utf-8') 25 | # 重定向 - 給浏覽器一個URL, 讓浏覽器重新請求指定的頁面 26 | # return redirect(reverse('depts')) 27 | # return depts(request) 28 | 29 | 30 | def emps(request, no='0'): 31 | # no = request.GET['no'] 32 | # dept = Dept.objects.get(no=no) 33 | # ForeignKey(Dept, on_delete=models.PROTECT, related_name='emps') 34 | # dept.emps.all() 35 | # emps_list = dept.emp_set.all() 36 | # all() / filter() ==> QuerySet 37 | # QuerySet使用了惰性查詢 - 如果不是非得取到數據那麽不會發出SQL語句 38 | # 這樣做是爲了節省服務器內存的開銷 - 延遲加載 - 節省空間勢必浪費時間 39 | emps_list = list(Emp.objects.filter(dept__no=no).select_related('dept')) 40 | ctx = {'emp_list': emps_list, 'dept_name': emps_list[0].dept.name} \ 41 | if len(emps_list) > 0 else {} 42 | return render(request, 'emp.html', context=ctx) 43 | 44 | 45 | def depts(request): 46 | ctx = {'dept_list': Dept.objects.all()} 47 | return render(request, 'dept.html', context=ctx) 48 | -------------------------------------------------------------------------------- /Day41-55/oa/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "oa.settings") 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError as exc: 10 | raise ImportError( 11 | "Couldn't import Django. Are you sure it's installed and " 12 | "available on your PYTHONPATH environment variable? Did you " 13 | "forget to activate a virtual environment?" 14 | ) from exc 15 | execute_from_command_line(sys.argv) 16 | -------------------------------------------------------------------------------- /Day41-55/oa/oa/__init__.py: -------------------------------------------------------------------------------- 1 | import pymysql 2 | 3 | pymysql.install_as_MySQLdb() 4 | -------------------------------------------------------------------------------- /Day41-55/oa/oa/urls.py: -------------------------------------------------------------------------------- 1 | """oa URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/2.0/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path, include 18 | 19 | from hrs import views 20 | 21 | urlpatterns = [ 22 | path('', views.index), 23 | path('admin/', admin.site.urls), 24 | path('hrs/', include('hrs.urls')), 25 | ] 26 | -------------------------------------------------------------------------------- /Day41-55/oa/oa/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for oa project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "oa.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Day41-55/oa/static/images/mm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/oa/static/images/mm.jpg -------------------------------------------------------------------------------- /Day41-55/oa/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | {% load staticfiles %} 3 | 4 | 5 | 6 | 首頁 7 | 8 | 9 |

{{ greeting }}

10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /Day41-55/res/admin-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/res/admin-login.png -------------------------------------------------------------------------------- /Day41-55/res/admin-model-create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/res/admin-model-create.png -------------------------------------------------------------------------------- /Day41-55/res/admin-model-delete-and-update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/res/admin-model-delete-and-update.png -------------------------------------------------------------------------------- /Day41-55/res/admin-model-depts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/res/admin-model-depts.png -------------------------------------------------------------------------------- /Day41-55/res/admin-model-emps-modified.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/res/admin-model-emps-modified.png -------------------------------------------------------------------------------- /Day41-55/res/admin-model-emps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/res/admin-model-emps.png -------------------------------------------------------------------------------- /Day41-55/res/admin-model-read.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/res/admin-model-read.png -------------------------------------------------------------------------------- /Day41-55/res/admin-model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/res/admin-model.png -------------------------------------------------------------------------------- /Day41-55/res/admin-welcome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/res/admin-welcome.png -------------------------------------------------------------------------------- /Day41-55/res/django-index-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/res/django-index-1.png -------------------------------------------------------------------------------- /Day41-55/res/django-index-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/res/django-index-2.png -------------------------------------------------------------------------------- /Day41-55/res/er-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/res/er-graph.png -------------------------------------------------------------------------------- /Day41-55/res/http-request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/res/http-request.png -------------------------------------------------------------------------------- /Day41-55/res/http-response.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/res/http-response.png -------------------------------------------------------------------------------- /Day41-55/res/mvc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/res/mvc.png -------------------------------------------------------------------------------- /Day41-55/res/runserver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/res/runserver.png -------------------------------------------------------------------------------- /Day41-55/res/web-application.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/res/web-application.png -------------------------------------------------------------------------------- /Day41-55/shop/cart/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/shop/cart/__init__.py -------------------------------------------------------------------------------- /Day41-55/shop/cart/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from cart.models import Goods 4 | 5 | 6 | class GoodsAdmin(admin.ModelAdmin): 7 | 8 | list_display = ('id', 'name', 'price', 'image') 9 | search_fields = ('name', ) 10 | 11 | 12 | admin.site.register(Goods, GoodsAdmin) 13 | -------------------------------------------------------------------------------- /Day41-55/shop/cart/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CartConfig(AppConfig): 5 | name = 'cart' 6 | -------------------------------------------------------------------------------- /Day41-55/shop/cart/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.0.5 on 2018-05-25 06:28 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | initial = True 9 | 10 | dependencies = [ 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='Goods', 16 | fields=[ 17 | ('id', models.AutoField(db_column='gid', primary_key=True, serialize=False)), 18 | ('name', models.CharField(db_column='gname', max_length=50)), 19 | ('price', models.DecimalField(db_column='gprice', decimal_places=2, max_digits=10)), 20 | ('image', models.CharField(db_column='gimage', max_length=255)), 21 | ], 22 | options={ 23 | 'db_table': 'tb_goods', 24 | 'ordering': ('id',), 25 | }, 26 | ), 27 | ] 28 | -------------------------------------------------------------------------------- /Day41-55/shop/cart/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/shop/cart/migrations/__init__.py -------------------------------------------------------------------------------- /Day41-55/shop/cart/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class Goods(models.Model): 5 | """商品模型類""" 6 | 7 | id = models.AutoField(primary_key=True, db_column='gid') 8 | name = models.CharField(max_length=50, db_column='gname') 9 | price = models.DecimalField(max_digits=10, decimal_places=2, db_column='gprice') 10 | image = models.CharField(max_length=255, db_column='gimage') 11 | 12 | class Meta: 13 | 14 | db_table = 'tb_goods' 15 | ordering = ('id', ) 16 | -------------------------------------------------------------------------------- /Day41-55/shop/cart/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Day41-55/shop/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "shop.settings") 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError as exc: 10 | raise ImportError( 11 | "Couldn't import Django. Are you sure it's installed and " 12 | "available on your PYTHONPATH environment variable? Did you " 13 | "forget to activate a virtual environment?" 14 | ) from exc 15 | execute_from_command_line(sys.argv) 16 | -------------------------------------------------------------------------------- /Day41-55/shop/shop/__init__.py: -------------------------------------------------------------------------------- 1 | import pymysql 2 | 3 | pymysql.install_as_MySQLdb() 4 | -------------------------------------------------------------------------------- /Day41-55/shop/shop/urls.py: -------------------------------------------------------------------------------- 1 | """shop URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/2.0/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path 18 | 19 | from cart import views 20 | 21 | urlpatterns = [ 22 | path('', views.index), 23 | path('add_to_cart/', views.add_to_cart), 24 | path('show_cart', views.show_cart), 25 | path('admin/', admin.site.urls), 26 | ] 27 | -------------------------------------------------------------------------------- /Day41-55/shop/shop/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for shop project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "shop.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Day41-55/shop/static/images/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/shop/static/images/Thumbs.db -------------------------------------------------------------------------------- /Day41-55/shop/static/images/dolbee.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/shop/static/images/dolbee.jpg -------------------------------------------------------------------------------- /Day41-55/shop/static/images/lay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/shop/static/images/lay.jpg -------------------------------------------------------------------------------- /Day41-55/shop/static/images/noodle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/shop/static/images/noodle.jpg -------------------------------------------------------------------------------- /Day41-55/shop/static/images/oil.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/shop/static/images/oil.jpg -------------------------------------------------------------------------------- /Day41-55/shop/static/images/wang.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/shop/static/images/wang.jpg -------------------------------------------------------------------------------- /Day41-55/shop/static/images/wine.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/shop/static/images/wine.jpg -------------------------------------------------------------------------------- /Day41-55/shop/templates/cart.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 17 | 18 | 19 |
20 |

購物車列表

21 |
22 |
23 |
24 | 返回 25 |
26 | {% if cart %} 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | {% for item in cart.cart_items %} 36 | 37 | 38 | 39 | 40 | 41 | 44 | 45 | {% endfor %} 46 | 47 | 48 | 49 |
商品名稱商品單價商品數量商品總價操作
{{ item.goods.name }}¥{{ item.goods.price }}{{ item.amount }}¥{{ item.total }} 42 | 刪除 43 |
¥{{ cart.total }}元
50 | 清空購物車 51 | {% else %} 52 |

購物車中暫時沒有商品!

53 | {% endif %} 54 | 55 | -------------------------------------------------------------------------------- /Day41-55/shop/templates/goods.html: -------------------------------------------------------------------------------- 1 | 2 | {% load staticfiles %} 3 | 4 | 5 | 6 | 16 | 17 | 18 |
19 |

商品列表

20 |
21 |
22 |
23 | 查看購物車 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | {% for goods in goods_list %} 33 | 34 | 35 | 36 | 39 | 42 | 43 | {% endfor %} 44 |
商品名稱商品價格商品圖片操作
{{ goods.name }}¥{{ goods.price }} 37 | {{ goods.name }} 38 | 40 | 加入購物車 41 |
45 | 46 | -------------------------------------------------------------------------------- /Day41-55/shop_origin/cart/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/shop_origin/cart/__init__.py -------------------------------------------------------------------------------- /Day41-55/shop_origin/cart/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from cart.models import Goods 4 | 5 | 6 | class GoodsAdmin(admin.ModelAdmin): 7 | 8 | list_display = ('id', 'name', 'price', 'image') 9 | 10 | 11 | admin.site.register(Goods, GoodsAdmin) 12 | -------------------------------------------------------------------------------- /Day41-55/shop_origin/cart/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CartConfig(AppConfig): 5 | name = 'cart' 6 | -------------------------------------------------------------------------------- /Day41-55/shop_origin/cart/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.0.5 on 2018-05-25 05:11 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | initial = True 9 | 10 | dependencies = [ 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='Goods', 16 | fields=[ 17 | ('id', models.AutoField(db_column='gid', primary_key=True, serialize=False)), 18 | ('name', models.CharField(db_column='gname', max_length=50)), 19 | ('price', models.DecimalField(db_column='gprice', decimal_places=2, max_digits=10)), 20 | ('image', models.CharField(db_column='gimage', max_length=255)), 21 | ], 22 | options={ 23 | 'db_table': 'tb_goods', 24 | 'ordering': ('id',), 25 | }, 26 | ), 27 | ] 28 | -------------------------------------------------------------------------------- /Day41-55/shop_origin/cart/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/shop_origin/cart/migrations/__init__.py -------------------------------------------------------------------------------- /Day41-55/shop_origin/cart/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class Goods(models.Model): 5 | 6 | id = models.AutoField(primary_key=True, db_column='gid') 7 | name = models.CharField(max_length=50, db_column='gname') 8 | price = models.DecimalField(max_digits=10, decimal_places=2, db_column='gprice') 9 | image = models.CharField(max_length=255, db_column='gimage') 10 | 11 | class Meta: 12 | db_table = 'tb_goods' 13 | ordering = ('id',) 14 | -------------------------------------------------------------------------------- /Day41-55/shop_origin/cart/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Day41-55/shop_origin/cart/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | from cart.models import Goods 4 | 5 | 6 | def index(request): 7 | goods_list = list(Goods.objects.all()) 8 | return render(request, 'goods.html', {'goods_list': goods_list}) 9 | 10 | 11 | def show_cart(request): 12 | return render(request, 'cart.html') 13 | 14 | 15 | def add_to_cart(request, no): 16 | pass 17 | -------------------------------------------------------------------------------- /Day41-55/shop_origin/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "shop.settings") 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError as exc: 10 | raise ImportError( 11 | "Couldn't import Django. Are you sure it's installed and " 12 | "available on your PYTHONPATH environment variable? Did you " 13 | "forget to activate a virtual environment?" 14 | ) from exc 15 | execute_from_command_line(sys.argv) 16 | -------------------------------------------------------------------------------- /Day41-55/shop_origin/shop/__init__.py: -------------------------------------------------------------------------------- 1 | import pymysql 2 | 3 | pymysql.install_as_MySQLdb() -------------------------------------------------------------------------------- /Day41-55/shop_origin/shop/urls.py: -------------------------------------------------------------------------------- 1 | """shop URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/2.0/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path 18 | 19 | from cart import views 20 | 21 | urlpatterns = [ 22 | path('', views.index), 23 | path('show_cart', views.show_cart), 24 | path('add_to_cart/', views.add_to_cart), 25 | path('admin/', admin.site.urls), 26 | ] 27 | -------------------------------------------------------------------------------- /Day41-55/shop_origin/shop/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for shop project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "shop.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Day41-55/shop_origin/shop_create_sql.sql: -------------------------------------------------------------------------------- 1 | insert into tb_goods values 2 | (default, '乐事(Lay’s)无限薯片', 8.2, 'images/lay.jpg'), 3 | (default, '旺旺 仙贝 加量装 540g', 18.5, 'images/wang.jpg'), 4 | (default, '多儿比(Dolbee)黄桃水果罐头', 6.8, 'images/dolbee.jpg'), 5 | (default, '王致和 精制料酒 500ml', 7.9, 'images/wine.jpg'), 6 | (default, '陈克明 面条 鸡蛋龙须挂面', 1.0, 'images/noodle.jpg'), 7 | (default, '鲁花 菜籽油 4L', 69.9, 'images/oil.jpg'); -------------------------------------------------------------------------------- /Day41-55/shop_origin/static/images/dolbee.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/shop_origin/static/images/dolbee.jpg -------------------------------------------------------------------------------- /Day41-55/shop_origin/static/images/lay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/shop_origin/static/images/lay.jpg -------------------------------------------------------------------------------- /Day41-55/shop_origin/static/images/noodle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/shop_origin/static/images/noodle.jpg -------------------------------------------------------------------------------- /Day41-55/shop_origin/static/images/oil.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/shop_origin/static/images/oil.jpg -------------------------------------------------------------------------------- /Day41-55/shop_origin/static/images/wang.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/shop_origin/static/images/wang.jpg -------------------------------------------------------------------------------- /Day41-55/shop_origin/static/images/wine.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day41-55/shop_origin/static/images/wine.jpg -------------------------------------------------------------------------------- /Day41-55/shop_origin/templates/cart.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 17 | 18 | 19 |
20 |

購物車列表

21 |
22 |
23 |
24 | 返回 25 |
26 | {% if cart_items %} 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | {% for item in cart_items %} 36 | 37 | 38 | 39 | 40 | 41 | 44 | 45 | {% endfor %} 46 | 47 | 48 | 49 |
商品名稱商品單價商品數量商品總價操作
{{ item.name }}¥{{ item.unit_price }}{{ item.amount }}¥{{ item.total_price }} 42 | 刪除 43 |
¥{{ cart.total }}元
50 | 清空購物車 51 | {% else %} 52 |

購物車中暫時沒有商品!

53 | {% endif %} 54 | 55 | -------------------------------------------------------------------------------- /Day41-55/shop_origin/templates/goods.html: -------------------------------------------------------------------------------- 1 | 2 | {% load staticfiles %} 3 | 4 | 5 | 6 | 16 | 17 | 18 |
19 |

商品列表

20 |
21 |
22 |
23 | 查看購物車 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | {% for goods in goods_list %} 33 | 34 | 35 | 36 | 39 | 42 | 43 | {% endfor %} 44 |
商品名稱商品價格商品圖片操作
{{ goods.name }}¥{{ goods.price }} 37 | {{ goods.name }} 38 | 40 | 加入購物車 41 |
45 | 46 | -------------------------------------------------------------------------------- /Day56-65/Flask安装和入门.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day56-65/Flask安装和入门.md -------------------------------------------------------------------------------- /Day56-65/Flask项目实战.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day56-65/Flask项目实战.md -------------------------------------------------------------------------------- /Day56-65/使用Flask进行项目开发.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day56-65/使用Flask进行项目开发.md -------------------------------------------------------------------------------- /Day56-65/数据库操作.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day56-65/数据库操作.md -------------------------------------------------------------------------------- /Day56-65/模板的使用.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day56-65/模板的使用.md -------------------------------------------------------------------------------- /Day56-65/表单的处理.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day56-65/表单的处理.md -------------------------------------------------------------------------------- /Day66-75/06.表單交互和驗證碼處理.md: -------------------------------------------------------------------------------- 1 | ## 表單交互和驗證碼處理 2 | 3 | ### 提交表單 4 | 5 | #### 手動提交 6 | 7 | 8 | 9 | #### 自動提交 10 | 11 | 12 | 13 | ### 驗證碼處理 14 | 15 | #### 加載驗證碼 16 | 17 | 18 | 19 | #### 光學字符識別 20 | 21 | 光學字符識別(OCR)是從圖像中抽取文本的工具,可以應用於公安、電信、物流、金融等諸多行業,例如識別車牌,身份證掃描識別、名片信息提取等。在爬蟲開發中,如果遭遇了有文字驗證碼的表單,就可以利用OCR來進行驗證碼處理。Tesseract-OCR引擎最初是由惠普公司開發的光學字符識別係統,目前發布在Github上,由Google贊助開發。 22 | 23 | ![](./res/tesseract.gif) 24 | 25 | #### 改善OCR 26 | 27 | 28 | 29 | #### 處理更複雜的驗證碼 30 | 31 | 32 | 33 | #### 驗證碼處理服務 34 | 35 | -------------------------------------------------------------------------------- /Day66-75/Scrapy爬蟲框架分布式實現.md: -------------------------------------------------------------------------------- 1 | ## Scrapy爬蟲框架分布式實現 2 | 3 | ### 分布式爬蟲原理 4 | 5 | 6 | 7 | ### Scrapy分布式實現 8 | 9 | 1. 安裝Scrapy-Redis。 10 | 2. 配置Redis服務器。 11 | 3. 修改配置文件。 12 | - SCHEDULER = 'scrapy_redis.scheduler.Scheduler' 13 | - DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter' 14 | - REDIS_HOST = '1.2.3.4' 15 | - REDIS_PORT = 6379 16 | - REDIS_PASSWORD = '1qaz2wsx' 17 | - SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.FifoQueue' 18 | - SCHEDULER_PERSIST = True(通過持久化支持接續爬取) 19 | - SCHEDULER_FLUSH_ON_START = True(每次啓動時重新爬取) 20 | 21 | ### Scrapyd分布式部署 22 | 23 | 1. 安裝Scrapyd 24 | 2. 修改配置文件 25 | - mkdir /etc/scrapyd 26 | - vim /etc/scrapyd/scrapyd.conf 27 | 3. 安裝Scrapyd-Client 28 | - 將項目打包成Egg文件。 29 | - 將打包的Egg文件通過addversion.json接口部署到Scrapyd上。 30 | 31 | -------------------------------------------------------------------------------- /Day66-75/Scrapy爬蟲框架高級應用.md: -------------------------------------------------------------------------------- 1 | ## Scrapy爬蟲框架高級應用 2 | 3 | ### Spider的用法 4 | 5 | 在Scrapy框架中,我們自定義的蜘蛛都繼承自scrapy.spiders.Spider,這個類有一係列的屬性和方法,具體如下所示: 6 | 7 | 1. name:爬蟲的名字。 8 | 2. allowed_domains:允許爬取的域名,不在此範圍的鏈接不會被跟進爬取。 9 | 3. start_urls:起始URL列表,當我們沒有重寫start_requests()方法時,就會從這個列表開始爬取。 10 | 4. custom_settings:用來存放蜘蛛專屬配置的字典,這裏的設置會覆蓋全局的設置。 11 | 5. crawler:由from_crawler()方法設置的和蜘蛛對應的Crawler對象,Crawler對象包含了很多項目組件,利用它我們可以獲取項目的配置信息,如調用crawler.settings.get()方法。 12 | 6. settings:用來獲取爬蟲全局設置的變量。 13 | 7. start_requests():此方法用於生成初始請求,它返回一個可疊代對象。該方法默認是使用GET請求訪問起始URL,如果起始URL需要使用POST請求來訪問就必須重寫這個方法。 14 | 8. parse():當Response沒有指定回調函數時,該方法就會被調用,它負責處理Response對象並返回結果,從中提取出需要的數據和後續的請求,該方法需要返回類型爲Request或Item的可疊代對象(生成器當前也包含在其中,因此根據實際需要可以用return或yield來産生返回值)。 15 | 9. closed():當蜘蛛關閉時,該方法會被調用,通常用來做一些釋放資源的善後操作。 16 | 17 | ### 中間件的應用 18 | 19 | #### 下載中間件 20 | 21 | 22 | 23 | #### 蜘蛛中間件 24 | 25 | 26 | 27 | ### Scrapy對接Selenium 28 | 29 | 30 | 31 | ### Scrapy部署到Docker 32 | 33 | -------------------------------------------------------------------------------- /Day66-75/code/asyncio01.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | 3 | 4 | @asyncio.coroutine 5 | def countdown(name, num): 6 | while num > 0: 7 | print(f'Countdown[{name}]: {num}') 8 | yield from asyncio.sleep(1) 9 | num -= 1 10 | 11 | 12 | def main(): 13 | loop = asyncio.get_event_loop() 14 | tasks = [ 15 | countdown("A", 10), countdown("B", 5), 16 | ] 17 | loop.run_until_complete(asyncio.wait(tasks)) 18 | loop.close() 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Day66-75/code/asyncio02.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import aiohttp 3 | 4 | 5 | async def download(url): 6 | print('Fetch:', url) 7 | async with aiohttp.ClientSession() as session: 8 | async with session.get(url) as resp: 9 | print(url, '--->', resp.status) 10 | print(url, '--->', resp.cookies) 11 | print('\n\n', await resp.text()) 12 | 13 | 14 | def main(): 15 | loop = asyncio.get_event_loop() 16 | urls = [ 17 | 'https://www.baidu.com', 18 | 'http://www.sohu.com/', 19 | 'http://www.sina.com.cn/', 20 | 'https://www.taobao.com/', 21 | 'https://www.jd.com/' 22 | ] 23 | tasks = [download(url) for url in urls] 24 | loop.run_until_complete(asyncio.wait(tasks)) 25 | loop.close() 26 | 27 | 28 | if __name__ == '__main__': 29 | main() 30 | -------------------------------------------------------------------------------- /Day66-75/code/coroutine01.py: -------------------------------------------------------------------------------- 1 | from time import sleep 2 | 3 | 4 | def countdown_gen(n, consumer): 5 | consumer.send(None) 6 | while n > 0: 7 | consumer.send(n) 8 | n -= 1 9 | consumer.send(None) 10 | 11 | 12 | def countdown_con(): 13 | while True: 14 | n = yield 15 | if n: 16 | print(f'Countdown {n}') 17 | sleep(1) 18 | else: 19 | print('Countdown Over!') 20 | 21 | 22 | def main(): 23 | countdown_gen(5, countdown_con()) 24 | 25 | 26 | if __name__ == '__main__': 27 | main() 28 | -------------------------------------------------------------------------------- /Day66-75/code/coroutine02.py: -------------------------------------------------------------------------------- 1 | from time import sleep 2 | 3 | from myutils import coroutine 4 | 5 | 6 | @coroutine 7 | def create_delivery_man(name, capacity=1): 8 | buffer = [] 9 | while True: 10 | size = 0 11 | while size < capacity: 12 | pkg_name = yield 13 | if pkg_name: 14 | size += 1 15 | buffer.append(pkg_name) 16 | print('%s正在接受%s' % (name, pkg_name)) 17 | else: 18 | break 19 | print('=====%s正在派送%d件包裹=====' % (name, len(buffer))) 20 | sleep(3) 21 | buffer.clear() 22 | 23 | 24 | def create_package_center(consumer, max_packages): 25 | num = 0 26 | while num <= max_packages: 27 | print('快遞中心準備派送%d號包裹' % num) 28 | consumer.send('包裹-%d' % num) 29 | num += 1 30 | if num % 10 == 0: 31 | sleep(5) 32 | consumer.send(None) 33 | 34 | 35 | def main(): 36 | print(create_delivery_man.__name__) 37 | dm = create_delivery_man('王大錘', 7) 38 | create_package_center(dm, 25) 39 | 40 | 41 | if __name__ == '__main__': 42 | main() 43 | -------------------------------------------------------------------------------- /Day66-75/code/douban/douban/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/code/douban/douban/__init__.py -------------------------------------------------------------------------------- /Day66-75/code/douban/douban/items.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Define here the models for your scraped items 4 | # 5 | # See documentation in: 6 | # https://doc.scrapy.org/en/latest/topics/items.html 7 | 8 | import scrapy 9 | 10 | 11 | class DoubanItem(scrapy.Item): 12 | 13 | name = scrapy.Field() 14 | year = scrapy.Field() 15 | score = scrapy.Field() 16 | director = scrapy.Field() 17 | classification = scrapy.Field() 18 | actor = scrapy.Field() 19 | -------------------------------------------------------------------------------- /Day66-75/code/douban/douban/pipelines.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Define your item pipelines here 4 | # 5 | # Don't forget to add your pipeline to the ITEM_PIPELINES setting 6 | # See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html 7 | import pymongo 8 | 9 | from scrapy.exceptions import DropItem 10 | from scrapy.conf import settings 11 | from scrapy import log 12 | 13 | 14 | class DoubanPipeline(object): 15 | 16 | def __init__(self): 17 | connection = pymongo.MongoClient(settings['MONGODB_SERVER'], settings['MONGODB_PORT']) 18 | db = connection[settings['MONGODB_DB']] 19 | self.collection = db[settings['MONGODB_COLLECTION']] 20 | 21 | def process_item(self, item, spider): 22 | #Remove invalid data 23 | valid = True 24 | for data in item: 25 | if not data: 26 | valid = False 27 | raise DropItem("Missing %s of blogpost from %s" %(data, item['url'])) 28 | if valid: 29 | #Insert data into database 30 | new_moive=[{ 31 | "name":item['name'][0], 32 | "year":item['year'][0], 33 | "score":item['score'], 34 | "director":item['director'], 35 | "classification":item['classification'], 36 | "actor":item['actor'] 37 | }] 38 | self.collection.insert(new_moive) 39 | log.msg("Item wrote to MongoDB database %s/%s" % 40 | (settings['MONGODB_DB'], settings['MONGODB_COLLECTION']), 41 | level=log.DEBUG, spider=spider) 42 | return item 43 | 44 | -------------------------------------------------------------------------------- /Day66-75/code/douban/douban/spiders/__init__.py: -------------------------------------------------------------------------------- 1 | # This package will contain the spiders of your Scrapy project 2 | # 3 | # Please refer to the documentation for information on how to create and manage 4 | # your spiders. 5 | -------------------------------------------------------------------------------- /Day66-75/code/douban/douban/spiders/movie.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import scrapy 3 | from scrapy.selector import Selector 4 | from scrapy.linkextractors import LinkExtractor 5 | from scrapy.spiders import CrawlSpider, Rule 6 | 7 | from douban.items import DoubanItem 8 | 9 | 10 | class MovieSpider(CrawlSpider): 11 | name = 'movie' 12 | allowed_domains = ['movie.douban.com'] 13 | start_urls = ['https://movie.douban.com/top250'] 14 | rules = ( 15 | Rule(LinkExtractor(allow=(r'https://movie.douban.com/top250\?start=\d+.*'))), 16 | Rule(LinkExtractor(allow=(r'https://movie.douban.com/subject/\d+')), callback='parse_item'), 17 | ) 18 | 19 | def parse_item(self, response): 20 | sel = Selector(response) 21 | item = DoubanItem() 22 | item['name']=sel.xpath('//*[@id="content"]/h1/span[1]/text()').extract() 23 | item['year']=sel.xpath('//*[@id="content"]/h1/span[2]/text()').re(r'\((\d+)\)') 24 | item['score']=sel.xpath('//*[@id="interest_sectl"]/div/p[1]/strong/text()').extract() 25 | item['director']=sel.xpath('//*[@id="info"]/span[1]/a/text()').extract() 26 | item['classification']= sel.xpath('//span[@property="v:genre"]/text()').extract() 27 | item['actor']= sel.xpath('//*[@id="info"]/span[3]/a[1]/text()').extract() 28 | #i['domain_id'] = response.xpath('//input[@id="sid"]/@value').extract() 29 | #i['name'] = response.xpath('//div[@id="name"]').extract() 30 | #i['description'] = response.xpath('//div[@id="description"]').extract() 31 | return item 32 | 33 | -------------------------------------------------------------------------------- /Day66-75/code/douban/scrapy.cfg: -------------------------------------------------------------------------------- 1 | # Automatically created by: scrapy startproject 2 | # 3 | # For more information about the [deploy] section see: 4 | # https://scrapyd.readthedocs.io/en/latest/deploy.html 5 | 6 | [settings] 7 | default = douban.settings 8 | 9 | [deploy] 10 | #url = http://localhost:6800/ 11 | project = douban 12 | -------------------------------------------------------------------------------- /Day66-75/code/example03.py: -------------------------------------------------------------------------------- 1 | from bs4 import BeautifulSoup 2 | 3 | import requests 4 | 5 | import re 6 | 7 | 8 | def main(): 9 | # 通過requests第三方庫的get方法獲取頁面 10 | resp = requests.get('http://sports.sohu.com/nba_a.shtml') 11 | # 對響應的字節串(bytes)進行解碼操作(搜狐的部分頁面使用了GBK編碼) 12 | html = resp.content.decode('gbk') 13 | # 創建BeautifulSoup對象來解析頁面(相當於JavaScript的DOM) 14 | bs = BeautifulSoup(html, 'lxml') 15 | # 通過CSS選擇器語法查找元素並通過循環進行處理 16 | # for elem in bs.find_all(lambda x: 'test' in x.attrs): 17 | for elem in bs.select('a[test]'): 18 | # 通過attrs屬性(字典)獲取元素的屬性值 19 | link_url = elem.attrs['href'] 20 | resp = requests.get(link_url) 21 | bs_sub = BeautifulSoup(resp.text, 'lxml') 22 | # 使用正則表達式對獲取的數據做進一步的處理 23 | print(re.sub(r'[\r\n]', '', bs_sub.find('h1').text)) 24 | 25 | 26 | if __name__ == '__main__': 27 | main() 28 | -------------------------------------------------------------------------------- /Day66-75/code/example04.py: -------------------------------------------------------------------------------- 1 | from urllib.parse import urljoin 2 | 3 | import re 4 | import requests 5 | 6 | from bs4 import BeautifulSoup 7 | 8 | 9 | def main(): 10 | headers = {'user-agent': 'Baiduspider'} 11 | proxies = { 12 | 'http': 'http://122.114.31.177:808' 13 | } 14 | base_url = 'https://www.zhihu.com/' 15 | seed_url = urljoin(base_url, 'explore') 16 | resp = requests.get(seed_url, 17 | headers=headers, 18 | proxies=proxies) 19 | soup = BeautifulSoup(resp.text, 'lxml') 20 | href_regex = re.compile(r'^/question') 21 | link_set = set() 22 | for a_tag in soup.find_all('a', {'href': href_regex}): 23 | if 'href' in a_tag.attrs: 24 | href = a_tag.attrs['href'] 25 | full_url = urljoin(base_url, href) 26 | link_set.add(full_url) 27 | print('Total %d question pages found.' % len(link_set)) 28 | 29 | 30 | if __name__ == '__main__': 31 | main() 32 | -------------------------------------------------------------------------------- /Day66-75/code/example07.py: -------------------------------------------------------------------------------- 1 | import pymongo 2 | 3 | 4 | # BSON - Binary JSON - dict 5 | def main(): 6 | # client = pymongo.MongoClient('mongodb://120.77.222.217:27017') 7 | client = pymongo.MongoClient(host='120.77.222.217', port=27017) 8 | db = client.zhihu 9 | pages_cache = db.webpages 10 | """ 11 | pages_cache.insert_many([ 12 | {'_id': 1, 'url': 'http://www.baidu.com', 'content': 'shit'}, 13 | {'_id': 2, 'url': 'http://www.qq.com', 'content': 'another shit'}, 14 | {'_id': 3, 'url': 'http://www.qfedu.com', 'content': 'biggest shit'} 15 | ]) 16 | 17 | print(pages_cache.update({'_id': 5}, {'$set': {'content': 'hello, world!'}}, upsert=True)) 18 | # page_id = pages_cache.insert_one({'url': 'http://www.baidu.com', 'content': ''}) 19 | # print(page_id.inserted_id) 20 | # print(pages_cache.remove({'url': 'http://www.baidu.com'})) 21 | print(pages_cache.find().count()) 22 | for doc in pages_cache.find().sort('_id'): 23 | print(doc) 24 | """ 25 | pages_cache.insert_one({ 26 | 'url': 'http://www.baidu.com', 27 | 'content': 'bull shit!', 28 | 'owner': { 29 | 'name': 'Lee Yanhong', 30 | 'age': 50, 31 | 'idcard': '110220196804091203' 32 | } 33 | }) 34 | 35 | 36 | if __name__ == '__main__': 37 | main() 38 | -------------------------------------------------------------------------------- /Day66-75/code/example08.py: -------------------------------------------------------------------------------- 1 | import requests 2 | from bs4 import BeautifulSoup 3 | 4 | 5 | def main(): 6 | resp = requests.get('https://github.com/login') 7 | if resp.status_code != 200: 8 | return 9 | cookies = resp.cookies.get_dict() 10 | print(cookies) 11 | soup = BeautifulSoup(resp.text, 'lxml') 12 | utf8_value = \ 13 | soup.select_one('form input[name=utf8]').attrs['value'] 14 | authenticity_token_value = \ 15 | soup.select_one('form input[name=authenticity_token]').attrs['value'] 16 | data = { 17 | 'utf8': utf8_value, 18 | 'authenticity_token': authenticity_token_value, 19 | 'login': 'jackfrued@gmail.com', 20 | 'password': 'yourpassword' 21 | } 22 | resp = requests.post('https://github.com/session', 23 | data=data, cookies=cookies) 24 | print(resp.text) 25 | 26 | 27 | if __name__ == '__main__': 28 | main() 29 | -------------------------------------------------------------------------------- /Day66-75/code/example09.py: -------------------------------------------------------------------------------- 1 | import robobrowser 2 | 3 | 4 | def main(): 5 | b = robobrowser.RoboBrowser(parser='lxml') 6 | b.open('https://github.com/login') 7 | f = b.get_form(action='/session') 8 | f['login'].value = 'jackfrued@gmail.com' 9 | f['password'].value = 'yourpassword' 10 | b.submit_form(f) 11 | for a_tag in b.select('a[href]'): 12 | print(a_tag.attrs['href']) 13 | 14 | 15 | if __name__ == '__main__': 16 | main() 17 | -------------------------------------------------------------------------------- /Day66-75/code/example10.py: -------------------------------------------------------------------------------- 1 | import robobrowser 2 | 3 | 4 | def main(): 5 | b = robobrowser.RoboBrowser(parser='lxml') 6 | b.open('https://v.taobao.com/v/content/live?catetype=704&from=taonvlang') 7 | for img_tag in b.select('img[src]'): 8 | print(img_tag.attrs['src']) 9 | 10 | 11 | if __name__ == '__main__': 12 | main() 13 | -------------------------------------------------------------------------------- /Day66-75/code/example10a.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | from bs4 import BeautifulSoup 4 | 5 | 6 | def main(): 7 | resp = requests.get('https://v.taobao.com/v/content/live?catetype=704&from=taonvlang') 8 | soup = BeautifulSoup(resp.text, 'lxml') 9 | for img_tag in soup.select('img[src]'): 10 | print(img_tag.attrs['src']) 11 | 12 | 13 | if __name__ == '__main__': 14 | main() 15 | -------------------------------------------------------------------------------- /Day66-75/code/example11.py: -------------------------------------------------------------------------------- 1 | from bs4 import BeautifulSoup 2 | from selenium import webdriver 3 | from selenium.webdriver.common.keys import Keys 4 | 5 | 6 | def main(): 7 | driver = webdriver.Chrome() 8 | driver.get('https://v.taobao.com/v/content/live?catetype=704&from=taonvlang') 9 | elem = driver.find_element_by_css_selector('input[placeholder=輸入關鍵詞搜索]') 10 | elem.send_keys('運動') 11 | elem.send_keys(Keys.ENTER) 12 | soup = BeautifulSoup(driver.page_source, 'lxml') 13 | for img_tag in soup.body.select('img[src]'): 14 | print(img_tag.attrs['src']) 15 | 16 | 17 | if __name__ == '__main__': 18 | main() 19 | -------------------------------------------------------------------------------- /Day66-75/code/example11a.py: -------------------------------------------------------------------------------- 1 | from bs4 import BeautifulSoup 2 | from selenium import webdriver 3 | from selenium.webdriver.common.keys import Keys 4 | 5 | 6 | def main(): 7 | driver = webdriver.Chrome() 8 | driver.get('https://v.taobao.com/v/content/live?catetype=704&from=taonvlang') 9 | soup = BeautifulSoup(driver.page_source, 'lxml') 10 | for img_tag in soup.body.select('img[src]'): 11 | print(img_tag.attrs['src']) 12 | 13 | 14 | if __name__ == '__main__': 15 | main() 16 | -------------------------------------------------------------------------------- /Day66-75/code/example12.py: -------------------------------------------------------------------------------- 1 | import base64 2 | 3 | from PIL import Image, ImageFilter 4 | from pytesseract import image_to_string 5 | 6 | import requests 7 | from io import BytesIO 8 | 9 | 10 | def main(): 11 | guido_img = Image.open(open('guido.jpg', 'rb')) 12 | guido2_img = guido_img.filter(ImageFilter.GaussianBlur) 13 | guido2_img.save(open('guido2.jpg', 'wb')) 14 | 15 | img1 = Image.open(open('tesseract.png', 'rb')) 16 | img2 = img1.point(lambda x: 0 if x < 128 else 255) 17 | img2.save(open('tesseract2.png', 'wb')) 18 | 19 | print(image_to_string(img2)) 20 | 21 | resp = requests.get('https://pin2.aliyun.com/get_img?type=150_40&identity=mailsso.mxhichina.com&sessionid=k0xHyBxU3K3dGXb59mP9cdeTXxL9gLHSTKhRZCryHxpOoyk4lAVuJhgw==') 22 | img3 = Image.open(BytesIO(resp.content)) 23 | img3.save('captcha.jpg') 24 | print(image_to_string(img3)) 25 | print(base64.b64encode(resp.content)) 26 | 27 | 28 | if __name__ == '__main__': 29 | main() 30 | -------------------------------------------------------------------------------- /Day66-75/code/generator01.py: -------------------------------------------------------------------------------- 1 | def fib(): 2 | a, b = 0, 1 3 | while True: 4 | a, b = b, a + b 5 | yield a 6 | 7 | 8 | def even(gen): 9 | for val in gen: 10 | if val % 2 == 0: 11 | yield val 12 | 13 | 14 | def main(): 15 | gen = even(fib()) 16 | for _ in range(10): 17 | print(next(gen)) 18 | 19 | 20 | if __name__ == '__main__': 21 | main() 22 | -------------------------------------------------------------------------------- /Day66-75/code/generator02.py: -------------------------------------------------------------------------------- 1 | from time import sleep 2 | 3 | 4 | def countdown(n): 5 | while n > 0: 6 | yield n 7 | n -= 1 8 | 9 | 10 | def main(): 11 | for num in countdown(5): 12 | print(f'Countdown: {num}') 13 | sleep(1) 14 | print('Countdown Over!') 15 | 16 | 17 | if __name__ == '__main__': 18 | main() 19 | -------------------------------------------------------------------------------- /Day66-75/code/guido.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/code/guido.jpg -------------------------------------------------------------------------------- /Day66-75/code/image360/image360/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/code/image360/image360/__init__.py -------------------------------------------------------------------------------- /Day66-75/code/image360/image360/items.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Define here the models for your scraped items 4 | # 5 | # See documentation in: 6 | # https://doc.scrapy.org/en/latest/topics/items.html 7 | 8 | import scrapy 9 | 10 | 11 | class GoodsItem(scrapy.Item): 12 | 13 | price = scrapy.Field() 14 | deal = scrapy.Field() 15 | title = scrapy.Field() 16 | 17 | 18 | class BeautyItem(scrapy.Item): 19 | 20 | title = scrapy.Field() 21 | tag = scrapy.Field() 22 | width = scrapy.Field() 23 | height = scrapy.Field() 24 | url = scrapy.Field() 25 | -------------------------------------------------------------------------------- /Day66-75/code/image360/image360/pipelines.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Define your item pipelines here 4 | # 5 | # Don't forget to add your pipeline to the ITEM_PIPELINES setting 6 | # See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html 7 | import logging 8 | 9 | from pymongo import MongoClient 10 | from scrapy import Request 11 | from scrapy.exceptions import DropItem 12 | from scrapy.pipelines.images import ImagesPipeline 13 | 14 | 15 | logger = logging.getLogger('SaveImagePipeline') 16 | 17 | 18 | class SaveImagePipeline(ImagesPipeline): 19 | 20 | def get_media_requests(self, item, info): 21 | yield Request(url=item['url']) 22 | 23 | def item_completed(self, results, item, info): 24 | logger.debug('圖片下載完成!') 25 | if not results[0][0]: 26 | raise DropItem('下載失敗') 27 | return item 28 | 29 | def file_path(self, request, response=None, info=None): 30 | return request.url.split('/')[-1] 31 | 32 | 33 | class SaveToMongoPipeline(object): 34 | 35 | def __init__(self, mongo_url, db_name): 36 | self.mongo_url = mongo_url 37 | self.db_name = db_name 38 | self.client = None 39 | self.db = None 40 | 41 | def process_item(self, item, spider): 42 | return item 43 | 44 | def open_spider(self, spider): 45 | self.client = MongoClient(self.mongo_url) 46 | self.db = self.client[self.db_name] 47 | 48 | def close_spider(self, spider): 49 | self.client.close() 50 | 51 | @classmethod 52 | def from_crawler(cls, crawler): 53 | return cls(crawler.settings.get('MONGO_URL'), 54 | crawler.settings.get('MONGO_DB')) 55 | 56 | -------------------------------------------------------------------------------- /Day66-75/code/image360/image360/spiders/__init__.py: -------------------------------------------------------------------------------- 1 | # This package will contain the spiders of your Scrapy project 2 | # 3 | # Please refer to the documentation for information on how to create and manage 4 | # your spiders. 5 | -------------------------------------------------------------------------------- /Day66-75/code/image360/image360/spiders/image.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from json import loads 3 | from urllib.parse import urlencode 4 | 5 | import scrapy 6 | 7 | from image360.items import BeautyItem 8 | 9 | 10 | class ImageSpider(scrapy.Spider): 11 | name = 'image' 12 | allowed_domains = ['image.so.com'] 13 | 14 | def start_requests(self): 15 | base_url = 'http://image.so.com/zj?' 16 | param = {'ch': 'beauty', 'listtype': 'new', 'temp': 1} 17 | for page in range(10): 18 | param['sn'] = page * 30 19 | full_url = base_url + urlencode(param) 20 | yield scrapy.Request(url=full_url) 21 | 22 | def parse(self, response): 23 | model_dict = loads(response.text) 24 | for elem in model_dict['list']: 25 | item = BeautyItem() 26 | item['title'] = elem['group_title'] 27 | item['tag'] = elem['tag'] 28 | item['width'] = elem['cover_width'] 29 | item['height'] = elem['cover_height'] 30 | item['url'] = elem['qhimg_url'] 31 | yield item 32 | -------------------------------------------------------------------------------- /Day66-75/code/image360/image360/spiders/taobao.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from io import StringIO 3 | from urllib.parse import urlencode 4 | import re 5 | 6 | import scrapy 7 | 8 | from image360.items import GoodsItem 9 | 10 | 11 | class TaobaoSpider(scrapy.Spider): 12 | name = 'taobao' 13 | allowed_domains = ['www.taobao.com'] 14 | 15 | def start_requests(self): 16 | base_url = 'https://s.taobao.com/search?' 17 | params = {} 18 | for keyword in ['ipad', 'iphone', '小米手機']: 19 | params['q'] = keyword 20 | for page in range(10): 21 | params['s'] = page * 44 22 | full_url = base_url + urlencode(params) 23 | yield scrapy.Request(url=full_url, callback=self.parse) 24 | 25 | def parse(self, response): 26 | goods_list = response.xpath('//*[@id="mainsrp-itemlist"]/div/div/div[1]') 27 | for goods in goods_list: 28 | item = GoodsItem() 29 | item['price'] = goods.xpath('div[5]/div[2]/div[1]/div[1]/strong/text()').extract_first() 30 | item['deal'] = goods.xpath('div[5]/div[2]/div[1]/div[2]/text()').extract_first() 31 | segments = goods.xpath('div[6]/div[2]/div[2]/a/text()').extract() 32 | title = StringIO() 33 | for segment in segments: 34 | title.write(re.sub('\s', '', segment)) 35 | item['title'] = title.getvalue() 36 | yield item 37 | -------------------------------------------------------------------------------- /Day66-75/code/image360/scrapy.cfg: -------------------------------------------------------------------------------- 1 | # Automatically created by: scrapy startproject 2 | # 3 | # For more information about the [deploy] section see: 4 | # https://scrapyd.readthedocs.io/en/latest/deploy.html 5 | 6 | [settings] 7 | default = image360.settings 8 | 9 | [deploy] 10 | #url = http://localhost:6800/ 11 | project = image360 12 | -------------------------------------------------------------------------------- /Day66-75/code/myutils.py: -------------------------------------------------------------------------------- 1 | from functools import wraps 2 | 3 | 4 | def coroutine(fn): 5 | 6 | @wraps(fn) 7 | def wrapper(*args, **kwargs): 8 | gen = fn(*args, **kwargs) 9 | next(gen) 10 | return gen 11 | 12 | return wrapper 13 | -------------------------------------------------------------------------------- /Day66-75/code/tesseract.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/code/tesseract.png -------------------------------------------------------------------------------- /Day66-75/res/api-image360.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/res/api-image360.png -------------------------------------------------------------------------------- /Day66-75/res/baidu-search-taobao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/res/baidu-search-taobao.png -------------------------------------------------------------------------------- /Day66-75/res/chrome-developer-tools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/res/chrome-developer-tools.png -------------------------------------------------------------------------------- /Day66-75/res/crawler-workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/res/crawler-workflow.png -------------------------------------------------------------------------------- /Day66-75/res/douban-xpath.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/res/douban-xpath.png -------------------------------------------------------------------------------- /Day66-75/res/http-request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/res/http-request.png -------------------------------------------------------------------------------- /Day66-75/res/http-response.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/res/http-response.png -------------------------------------------------------------------------------- /Day66-75/res/image360-website.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/res/image360-website.png -------------------------------------------------------------------------------- /Day66-75/res/postman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/res/postman.png -------------------------------------------------------------------------------- /Day66-75/res/redis-aof.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/res/redis-aof.png -------------------------------------------------------------------------------- /Day66-75/res/redis-bind.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/res/redis-bind.png -------------------------------------------------------------------------------- /Day66-75/res/redis-database.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/res/redis-database.png -------------------------------------------------------------------------------- /Day66-75/res/redis-port.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/res/redis-port.png -------------------------------------------------------------------------------- /Day66-75/res/redis-rdb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/res/redis-rdb.png -------------------------------------------------------------------------------- /Day66-75/res/redis-replication.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/res/redis-replication.png -------------------------------------------------------------------------------- /Day66-75/res/redis-save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/res/redis-save.png -------------------------------------------------------------------------------- /Day66-75/res/redis-security.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/res/redis-security.png -------------------------------------------------------------------------------- /Day66-75/res/redis-slow-log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/res/redis-slow-log.png -------------------------------------------------------------------------------- /Day66-75/res/scrapy-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/res/scrapy-architecture.png -------------------------------------------------------------------------------- /Day66-75/res/tesseract.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day66-75/res/tesseract.gif -------------------------------------------------------------------------------- /Day76-90/数据处理和可视化.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day76-90/数据处理和可视化.md -------------------------------------------------------------------------------- /Day76-90/机器学习.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day76-90/机器学习.md -------------------------------------------------------------------------------- /Day91-100/团队项目开发.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/Day91-100/团队项目开发.md -------------------------------------------------------------------------------- /res/abstraction-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/abstraction-view.png -------------------------------------------------------------------------------- /res/class-and-object.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/class-and-object.png -------------------------------------------------------------------------------- /res/concurrency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/concurrency.png -------------------------------------------------------------------------------- /res/encapsulation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/encapsulation.png -------------------------------------------------------------------------------- /res/int-is-comparation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/int-is-comparation.png -------------------------------------------------------------------------------- /res/modularity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/modularity.png -------------------------------------------------------------------------------- /res/multi-inheritance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/multi-inheritance.png -------------------------------------------------------------------------------- /res/object-roles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/object-roles.png -------------------------------------------------------------------------------- /res/objects-collaborate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/objects-collaborate.png -------------------------------------------------------------------------------- /res/objects-lifetime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/objects-lifetime.png -------------------------------------------------------------------------------- /res/pycharm-activate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/pycharm-activate.png -------------------------------------------------------------------------------- /res/pycharm-create-launcher-script.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/pycharm-create-launcher-script.png -------------------------------------------------------------------------------- /res/pycharm-import-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/pycharm-import-settings.png -------------------------------------------------------------------------------- /res/pycharm-new-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/pycharm-new-project.png -------------------------------------------------------------------------------- /res/pycharm-plugins.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/pycharm-plugins.png -------------------------------------------------------------------------------- /res/pycharm-set-ui-theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/pycharm-set-ui-theme.png -------------------------------------------------------------------------------- /res/pycharm-welcome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/pycharm-welcome.png -------------------------------------------------------------------------------- /res/pycharm-workspace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/pycharm-workspace.png -------------------------------------------------------------------------------- /res/python-bj-salary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/python-bj-salary.png -------------------------------------------------------------------------------- /res/python-built-in-functions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/python-built-in-functions.png -------------------------------------------------------------------------------- /res/python-cd-salary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/python-cd-salary.png -------------------------------------------------------------------------------- /res/python-job-all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/python-job-all.png -------------------------------------------------------------------------------- /res/python-job-chengdu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/python-job-chengdu.png -------------------------------------------------------------------------------- /res/python-salary-beijing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/python-salary-beijing.png -------------------------------------------------------------------------------- /res/python-salary-chengdu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/python-salary-chengdu.png -------------------------------------------------------------------------------- /res/python-salary-hangzhou.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/python-salary-hangzhou.png -------------------------------------------------------------------------------- /res/python-salary-shanghai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/python-salary-shanghai.png -------------------------------------------------------------------------------- /res/python-salary-shenzhen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/python-salary-shenzhen.png -------------------------------------------------------------------------------- /res/python-salary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/python-salary.png -------------------------------------------------------------------------------- /res/python-top-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/python-top-10.png -------------------------------------------------------------------------------- /res/python-tutor-visualize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/python-tutor-visualize.png -------------------------------------------------------------------------------- /res/python-tutor-visualize2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/python-tutor-visualize2.png -------------------------------------------------------------------------------- /res/result-of-dis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/result-of-dis.png -------------------------------------------------------------------------------- /res/selenium-ide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/selenium-ide.png -------------------------------------------------------------------------------- /res/zen-of-python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonChen-TW/Python-100-Days_zh-tw/978e91fc3d29822add6ad3bb995897b60646603f/res/zen-of-python.png --------------------------------------------------------------------------------