python编程学习——第九周

第九周

python学习笔记和做的一些习题 (python编程快速上手——让繁琐工作自动化)

第十四章 处理CSV文件和JSON数据

CSV模块

CSV 表示“Comma-Separated Values(逗号分隔的值)”,CSV 文件是简化的电子表格,保存为纯文本文件。
CSV 文件是简单的,缺少 Excel 电子表格的许多功能。例如,CSV 文件中:
• 值没有类型,所有东西都是字符串;
• 没有字体大小或颜色的设置;
• 没有多个工作表;
• 不能指定单元格的宽度和高度;
• 不能合并单元格;
• 不能嵌入图像或图表。

Reader对象:要用 csv 模块从 CSV 文件中读取数据,需要创建一个 Reader 对象。Reader 对象让你迭代遍历 CSV 文件中的每一行。
python编程学习——第九周_第1张图片
既然已经将 CSV 文件表示为列表的列表,就可以用表达式 exampleData [row] [col] 来访问特定行和列的值。其中,row 是 exampleData 中一个列表的下标, col 是该列表中你想访问的项的下标。
python编程学习——第九周_第2张图片
python编程学习——第九周_第3张图片

在 for 循环中,从 Reader 对象读取数据 :
python编程学习——第九周_第4张图片

Writer对象:
Writer 对象让你将数据写入 CSV 文件。要创建一个 Writer 对象,就使用 csv.writer()函数。
Writer 对象的 writerow()方法接受一个列表参数。列表中的每个词,放在输出的 CSV 文件中的一个单元格中。writerow()函数的返回值,是写入文件中这一行的字 符数(包括换行字符)。
python编程学习——第九周_第5张图片
在这里插入图片描述

delimiter 和 lineterminator 关键字参数 :
如果你希望用制表符代替逗号来分隔单元格,并希望有两倍行距。在默认情况下,CSV 文件的分隔符是逗号。行终止字符是出现在行末的字符。默 认情况下,行终止字符是换行符。可以利用 csv.writer()的 delimiter 和 lineterminator 关键字参数,将这些字符改成不同的值。
python编程学习——第九周_第6张图片
python编程学习——第九周_第7张图片

项目:从CSV文件中删除表头

总的来说,该程序必须做到以下几点:
• 找出当前工作目录中的所有 CSV 文件。
• 读取每个文件的全部内容。
• 跳过第一行,将内容写入一个新的 CSV 文件。
在代码层面上,这意味着该程序需要做到以下几点:
• 循环遍历从 os.listdir()得到的文件列表,跳过非 CSV 文件。
• 创建一个 CSV Reader 对象,读取该文件的内容,利用 line_num 属性确定要跳 过哪一行。
• 创建一个 CSV Writer 对象,将读入的数据写入新文件。

import csv,os
os.makedirs('headerRemoved', exist_ok=True)
# 循环遍历每个CSV文件
for csvFilename in os.listdir('.'):
    if not csvFilename.endswith('.csv'):
        continue     #跳过拓展名不是CSV的文件
    print('Removing header from ' + csvFilename + '...')

# 读入CSV文件
csvRows = []
csvFileObj = open(csvFilename)
readerObj = csv.reader(csvFileObj)
#循环会遍历 CSV Reader 对象返回所有行,除了第一行,所有行都会添加到csvRows。
for row in readerObj:
    #Reader 对象的 line_num 属性可以用来确定当前读入的是 CSV 文件的哪一行。 
    if readerObj.line_num == 1:   
        continue      #跳过第一行
csvRows.append(row)
csvFileObj.close()

# 写入 CSV 文件,没有第一行
    #将列表写入 headerRemoved 中的一个 CSV 文件。这将覆盖原来的文件
    csvFileObj = open(os.path.join('headerRemoved', csvFilename), 'w',
                      newline='')
    csvWriter = csv.writer(csvFileObj)
    #循环遍历存储在 csvRows 中的子列表,将每个子列表 写入该文件
    for row in csvRows:
        csvWriter.writerow(row)
        csvFileObj.close()

JSON模块

JSON 是一种格式,它以 JavaScript 源代码的形式,将信息保存在纯文本文件中。JSON 不能存储每一种 Python 值,它只能包含以下数据类型的值:字符串、整型、浮点型、布尔型、列表、字典和NoneType。

用 loads()函数读取 JSON :
要将包含 JSON 数据的字符串转换为 Python 的值,就将它传递给 json.loads()函数 ,调用 loads(),向它传入一个 JSON 数据字符串。请注 意,JSON 字符串总是用双引号。它将该数据返回为一个 Python 字典。:
python编程学习——第九周_第8张图片
用 dumps 函数写出 JSON :
json.dumps()函数将一个 Python 值 转换成 JSON 格式的数据字符串。该值只能是以下基本 Python 数据类型之一:字典、列表、整型、浮点型、字符 串、布尔型或 None:
python编程学习——第九周_第9张图片

项目:取得当前的天气数据

该程序将执行以下操作:
• 从命令行读取请求的位置。
• 从 OpenWeatherMap.org 下载 JSON 天气数据。
• 将 JSON 数据字符串转换成 Python 的数据结构。
• 打印今天和未来两天的天气。
因此,代码需要完成以下任务:
• 连接 sys.argv 中的字符串,得到位置。
• 调用 requests.get(),下载天气数据。
• 调用 json.loads(),将 JSON 数据转换为 Python 数据结构。
• 打印天气预报。

import json, requests, sys
##从命令行参数获取位置

#命令行参数存储在 sys.argv 列表里,sys.argv 中至少有一个元素 
if len(sys.argv) < 2:
    #如果只有一个元素,程序向用户提供“Usage(用法)”信息
    print('Usage: quickWeather.py location')
    sys.exit()
#调用 join()方法,将 sys.argv中除第一 个字符串以外的字符串连接起来。
location = ' '.join(sys.argv[1:]) 
##下载 JSON 数据
#将 location 中保存的字符串插入 URL 字符串的那个位置
url ='http://api.openweathermap.org/data/2.5/forecast/daily?q=%s&cnt=3' % (location)
#将 url 传入 requests.get(),requests.get()调用返回一个 Response 对象
response = requests.get(url)
#可以通过调用 raise_for_status()来检查错误
response.raise_for_status() 

##加载 JSON 数据
weatherData = json.loads(response.text)
##打印天气
#代码将 weatherData['list']保存在变量 w 中
w = weatherData['list'] print('Current weather in %s:' % (location))
print(w[0]['weather'][0]['main'], '-', w[0]['weather'][0]['description'])
print() print('Tomorrow:')
print(w[1]['weather'][0]['main'], '-', w[1]['weather'][0]['description'])
print()
print('Day after tomorrow:')
print(w[2]['weather'][0]['main'], '-', w[2]['weather'][0]['description']) 

第十五章 保持时间、计划任务和启动程序

time模块

time.time()函数 :time.time()函数返回自那一刻以来的秒数,是一个浮点值。这个数字称为 UNIX 纪元时间戳。
在这里插入图片描述
返回值是 Unix 纪元的那一刻与 time.time()被调用的那一刻之间的秒数。
其中 Unix 纪元是编程中经常参考的时间:1970 年 1 月 1 日 0 点,即协调世界时(UTC)。

import time
#定义了函数 calcProd(),循环遍历 1 至 99999 的整数,返回它们的乘积。
def calcProd():
     product = 1
     for i in range(1, 100000):
         product = product * i
     return product 

#调用 time.time(),将结果保存在 startTime 中。
startTime = time.time()
prod = calcProd()
#调用 calcProd() 后,我们再次调用 time.time(),将结果保存 endTime 中
endTime = time.time()
#打印 calcProd() 返回的乘积的长度
print('The result is %s digits long.' % (len(str(prod))))
#打印运行 calcProd()的时间
print('Took %s seconds to calculate.' % (endTime - startTime)) 

运行结果为:
在这里插入图片描述
time.sleep()函数 :
如果需要让程序暂停一下,就调用 time.sleep()函数,并传入希望程序暂停的秒数。
for 循环将打印 Tick,暂停一秒钟,打印 Tock,暂停一秒钟,打印 Tick, 暂停,如此继续,直到 Tick 和 Tock 分别被打印 3 次。
输入 time.sleep(5) ,会在 5 秒后才看 到下一个提示符(>>>)。
python编程学习——第九周_第10张图片

数字四舍五入

用 Python 内置的 round()函数将小数点后有许多数字的浮点值缩短,该函数按照指定的精度 四舍五入到一个浮点数。只要传入要舍入的数字,再加上可选的第二个参数,指明 需要传入到小数点后多少位。如果省略第二个参数,round()将数字四舍五入到最接 近的整数:
python编程学习——第九周_第11张图片

项目:超级秒表

你的程序需要完成:
• 记录从按下回车键开始,每次按键的时间,每次按键都是一个新的“单圈”。
• 打印圈数、总时间和单圈时间。
这意味着代码将需要完成以下任务:
• 在程序开始时,通过调用 time.time()得到当前时间,将它保存为一个时间戳。 在每个单圈开始时也一样。
• 记录圈数,每次用户按下回车键时加 1。
• 用时间戳相减,得到计算流逝的时间。
• 处理 KeyboardInterrupt 异常,这样用户可以按 Ctrl-C 退出。

import time

#显示程序的指令
print('Press ENTER to begin. Afterwards, press ENTER to "click" the stopwatch.Press Ctrl-C to quit.')
input()      # 按回车开始
print('Started.')
startTime = time.time()   # 获得第一圈的开始时间
lastTime = startTime
#将圈数设为1
lapNum = 1

#记录并打印单圈时间
try:
     while True:
         input()
         #计算该圈花了多少时间
         lapTime = round(time.time() - lastTime, 2)
         #计算总共流逝的时间
         totalTime = round(time.time() - startTime, 2)
         #我们打印出圈数,消耗的总时间和单圈时间
         print('Lap #%s: %s (%s)' % (lapNum, totalTime, lapTime), end='')
         lapNum += 1
         lastTime = time.time() # reset the last lap time
except KeyboardInterrupt:
    #当 Ctrl-C 按下并引发异常时,程序执行转向 except 子句,打印 Done
    print('\nDone.')

datetime 模块

datetime 模块有自己的datetime 数据类型。datetime 值表示一个特定的时刻。
python编程学习——第九周_第12张图片
Unix 纪元时间戳可以通过datetime.datetime.fromtimestamp(),转换为datetime 对象。datetime 对象的日期和时间将根据本地时区转换:
在这里插入图片描述
timedelta 数据类型 :
创建 timedelta 对象,就用 datetime.timedelta()函数。datetime.timedelta()函数 接受关键字参数weeks、days、hours、minutes、seconds、milliseconds 和 microseconds。 没有 month 和 year 关键字参数,因为“月”和“年”是可变的时间,依赖于特定月 份或年份。timedelta 对象拥有的总时间以天、秒、微秒来表示。这些数字分别保存 在 days、seconds 和 microseconds 属性中。total_seconds()方法返回只以秒表示的时 间。将一个 timedelta 对象传入 str(),将返回格式良好的、人类可读的字符串表示。

python编程学习——第九周_第13张图片
算术运算符可以用于对 datetime 值进行日期运算:
python编程学习——第九周_第14张图片
利用+和-运算符,timedelta 对象与 datetime 对象或其他 timedelta 对象相加或相减。利用*和/运算符,timedelta 对象可以乘以或除以整数或浮点数。
python编程学习——第九周_第15张图片
暂停直至特定日期 :
time.sleep()方法可以暂停程序若干秒。利用一个 while 循环,可以让程序暂停, 直到一个特定的日期。

import datetime 
import time 
halloween2016 = datetime.datetime(2016, 10, 31, 0, 0, 0) 
while datetime.datetime.now() < halloween2016:
     time.sleep(1) 
 

将 datetime 对象转换为字符串 :利用 strftime()方 法,可以将 datetime 对象显示为字符串。
strftime()指令 :

strftime()指令 含义
%Y 带世纪的年份,例如’2014’
%y 不带世纪的年份,‘00’至’99’(1970 至 2069)
%m 数字表示的月份, ‘01’至’12’
%B 完整的月份,例如’November’
%b 简写的月份,例如’Nov’
%d 一月中的第几天,‘01’至’31’
%j 一年中的第几天,‘001’至’366’
%w 一周中的第几天,‘0’(周日)至’6’(周六)
%A 完整的周几,例如’Monday’
%a 简写的周几,例如’Mon’
%H 小时(24 小时时钟),‘00’至’23’
%I 小时(12 小时时钟),‘01’至’12’
%M 分,‘00’至’59’
%s 秒,‘00’至’59’
%p ‘AM’或’PM’
%% 就是’%'字符

向 strftime()传入一个定制的格式字符串,其中包含格式化指定(以及任何需要 的斜线、冒号等),strftime()将返回一个格式化的字符串,表示 datetime 对象的信息。
python编程学习——第九周_第16张图片
将字符串转换成 datetime 对象 :
如果有一个字符串的日期信息,需要将它转换为 datetime 对象,就用 datetime.datetime.strftime()函数。
python编程学习——第九周_第17张图片

多线程

多线程是什么?打个比方:多线程的程序就像是有多个“手指”。每个“手指”能够移动到控制流语句定义的下一行代码,但这些“手指”可以在程序的不同地方,同时执行不同的代码行。

像线程的目标函数传递参数:
如果想在新线程中运行的目标函数有参数,可以将目标函数的参数传入 threading.Thread()。
python编程学习——第九周_第18张图片
将 args=[‘Cats’, ‘Dogs’, ‘Frogs’]传入 threading.Thread()。为了确保关键字参数 sep=’ & '传递给新线程 中的 print(),我们将 kwargs={‘sep’: '& ‘}传入 threading.Thread()。 threadObj.start()调用将创建一个新线程来调用 print()函数,它会传入’Cats’、 ‘Dogs’和’Frogs’作为参数,以及’ & '作为 sep 关键字参数。但是最后一行的结果位置,,,,不知道怎么解释

并发问题:可以轻松地创建多个新线程,让它们同时运行。但多线程也可能会导致所谓的并发问题。
并发问题的产生:如果这些线程同时读写变量,导致互相干扰,就会发生并发问题。
并发问题特点:并发问题可能很难一致地重现,所以难以调试。

从python中启动其他程序

利用内建的 subprocess 模块中的 Popen()函数,Python 程序可以启动计算机中的 其他程序。如果想在 Python 脚本中启动一个外部程序,就将该程序的文件名传递给 subprocess.Popen()(在 Windows 中,右键点击该应用程序的开始菜单项,然后选择 “属性”,查看应用程序的文件名。)

向 Popen()传递命令行参数 :用 Popen()创建进程时,可以向进程传递命令行参数。要做到这一点,向 Popen() 传递一个列表,作为唯一的参数。该列表中的第一个字符串是要启动的程序的可执 行文件名,所有后续的字符串将是该程序启动时,传递给该程序的命令行参数。实 际上,这个列表将作为被启动程序的 sys.argv 的值。

Task Scheduler、launchd 和 cron :这些工具文档齐全,而且可靠,它们都允许 你安排应用程序在特定的时间启动。

用 Python 打开网站 :webbrowser.open()函数可以从程序启动 Web 浏览器,打开指定的网站;用 subprocess.Popen()打开浏览器应用程序。

运行其他 Python 脚本 :可以在 Python 中启动另一个 Python 脚本,就像任何其他的应用程序一样。只需向 Popen()传入 python.exe 可执行文件,并将想运行的.py 脚本的文件名作为它的参数。

用默认的应用程序打开文件 :利用 Popen(),Python 也可以用这种方式打开文件。 每个操作系统都有一个程序,其行为等价于双击文档文件来打开它。在 Windows 上,是start 程序。
python编程学习——第九周_第19张图片

项目:简单的倒计时程序

程序要做到:
• 从 60 倒数。
• 倒数至 0 时播放声音文件(alarm.wav)。
这意味着代码将需要做到以下几点:
• 在显示倒计时的每个数字之间,调用 time.sleep()暂停一秒。
• 调用 subprocess.Popen(),用默认的应用程序播放声音文件。

import time, subprocess
#创建变量 timeleft,保存倒计时剩下的秒数
timeLeft = 60
while timeLeft > 0:
    #显示剩余次数
    print(timeLeft, end='')
    #暂停一秒钟
    time.sleep(1)
    #再减少 timeleft 变量的值
    timeLeft = timeLeft - 1

#在倒计时结束时,播放声音文件。
subprocess.Popen(['start', 'alarm.wav'], shell=True) 

你可能感兴趣的:(python编程学习——第九周)