python自动化运维之路~DAY2

                                                       作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.字符编码与转码

1.什么是编码。

    基本概念很简单。首先,我们从一段信息即消息说起,消息以人类可以理解、易懂的表示存在。我打算将这种表示称为“明文”(plain text)。对于说英语的人,纸张上打印的或屏幕上显示的英文单词都算作明文。

其次,我们需要能将明文表示的消息转成另外某种表示,我们还需要能将编码文本转回成明文。从明文到编码文本的转换称为“编码”,从编码文本又转回成明文则为“解码”.

2.编码的历史演变。

ASCII编码:

     记住一句话:计算机中的所有数据,不论是文字、图片、视频、还是音频文件,本质上最终都是按照类似 01010101 的二进制存储的。再说简单点,计算机只懂二进制数字!所以,目的明确了:如何将我们能识别的符号唯一的与一组二进制数字对应上?于是美利坚的同志想到通过一个电平的高低状态来代指0或1,八个电平做为一组就可以表示出256种不同状态,每种状态就唯一对应一个字符,比如A--->00010001,而英文只有26个字符,算上一些特殊字符和数字,128个状态也够用了;每个电平称为一个比特为,约定8个比特位构成一个字节,这样计算机就可以用127个不同字节来存储英语的文字了。这就是ASCII编码。ASCII编码无法存中文哟!

GB2312编码:

     扩展ANSI编码 刚才说了,最开始,一个字节有八位,但是最高位没用上,默认为0;后来为了计算机也可以表示拉丁文,就将最后一位也用上了, 从128到255的字符集对应拉丁文啦。至此,一个字节就用满了! //GB2312 计算机漂洋过海来到中国后,问题来了,计算机不认识中文,当然也没法显示中文;而且一个字节所有状态都被占满了,万恶的帝国主义亡我之心不死啊!我党也是棒,自力更生,自己重写一张表,直接生猛地将扩展的第八位对应拉丁文全部删掉,规定一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,前面的一个字节(他称之为高字节)从0xA1用到0xF7,后面一个字节(低字节)从0xA1到0xFE,这样我们就可以组合出大约7000多个简体汉字了;这种汉字方案叫做 “GB2312”。GB2312 是对 ASCII 的中文扩展。

GBK和GB18030编码:

    但是汉字太多了,GB2312也不够用,于是规定:只要第一个字节是大于127就固定表示这是一个汉字的开始,不管后面跟的是不是扩展字符集里的内容。结果扩展之后的编码方案被称为 GBK 标准,GBK 包括了 GB2312 的所有内容,同时又增加了近20000个新的汉字(包括繁体字)和符号。

unicode编码:

  很多其它国家都搞出自己的编码标准,彼此间却相互不支持。这就带来了很多问题。于是,国际标谁化组织为了统一编码:提出了标准编码准则:UNICODE 。UNICODE是用两个字节来表示为一个字符,它总共可以组合出65535不同的字符,这足以覆盖世界上所有符号(包括甲骨文)

utf-8编码:

unicode都一统天下了,为什么还要有一个utf8的编码呢?unicode存数据不管是中文还是英文,默认都用2个字节来存取!大家想,对于英文世界的人们来讲,一个字节完全够了,比如要存储A,本来00010001就可以了,现在吃上了unicode的大锅饭,得用两个字节:00000000 00010001才行,浪费太严重!基于此,美利坚的科学家们提出了天才的想法:utf8.UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度,当字符在ASCII码的范围时,就用一个字节表示,所以是兼容ASCII编码的。这样显著的好处是,虽然在我们内存中的数据都是unicode,但当数据要保存到磁盘或者用于网络传输时,直接使用unicode就远不如utf8省空间啦!这也是为什么utf8是我们的推荐编码方式。

Unicode与utf8的关系:

    一言以蔽之:Unicode是内存编码表示方案(是规范),而UTF8是如何保存和传输Unicode的方案(是实现)这也是UTF8与Unicode的区别。

3.“万国码”

  我们在打开一个文件的时候,首先要对文件进行解码,然后才把数据进行打印出来,如果不指定打开的方式就会以系统默认的编码格式进行打开的哟,在python2.7中,系统默认的编码是ASCII,但是在3.0以上就默认使用的是utf-8编码打开。所以在打开文件的时候容易出现冲突,比如你的文件是以gbk格式存储的,但是我打开的方式是以utf-8的方式进行解码打开是会报错的哟!这一点大家要注意了哟!

所有的对象在转码之前都要被解码(decode)然后才能被转码(encode)哟!要注意的是在decode的同时,也会将bytes数据类型转换成str数据类型,在encode的同时,str也会跟着呗转换成bytes类型的哟!

#!/usr/bin/env python#_*_coding:gbk _*_ (这里仅仅是告诉文件的编码格式,也就是存入磁盘的时候应该保存的编码格式哟~不要和内存的编码【unicode】弄混了哟!)#__author__ = "yinzhengjie"

import sysprint(sys.getdefaultencoding()) #打印默认编码name = "尹正杰"  #这是定义的一个变量,是内存,所以该变量的编码格式是unicode,所以没有decode方法,因为它本身就是unicode编码的原因!print( name.encode("gbk")) #由于该变量本身就是unicode就不用decode了,直接encode解码成gbk [它是一个bytes类型,无法显示成汉字]print( name.encode("utf-8")) #将该变量转码成utf-8print( name.encode("utf-8").decode("utf-8").encode("gb2312")) #将该变量转换成gb2312,gb2312的编码在gbk中都是一样的,但是后者比前者范围更广哟,由于其实一个bytes类型,如果你想要将其转换成中文,直接解码一下就好使了,因为在encode的同事,这个变量的类型也跟着变了print( name.encode("utf-8").decode("utf-8").encode("gb2312").decode("gb2312")) #将bytes类型转换成str类型(我们此处可以这么理解,因为在python3中就有这么一个特性,在转码的时候会将类型也跟着变化!)

4.常见的编码问题

1>.cmd下的乱码问题

test.py

文件保存时的编码也会被保存为utf8。

问:什么在IDE下用2或3执行都没问题,在cmd.exe下3正确,2乱码呢?

答:我们在win下的终端即cmd.exe去执行,大家注意,cmd.exe本身也一个软件;当我们python2 hello.py时,python2解释器(默认ASCII编码)去按声明的utf8编码文件,而文件又是utf8保存的,所以没问题;问题出在当我们print'苑昊'时,解释器这边正常执行,也不会报错,只是print的内容会传递给cmd.exe用来显示,而在py2里这个内容就是utf8编码的字节数据,可这个软件默认的编码解码方式是GBK,所以cmd.exe用GBK的解码方式去解码utf8自然会乱码。

py3正确的原因是传递给cmd的是unicode数据,cmd.exe可以识别内容,所以显示没问题。

文件保存时的编码也为utf8。

改成这样后,cmd下用2也不会有问题了。

2>.open()中的编码问题

创建一个hello文本,保存成utf8:

为什么会报错呢?

因为你的win的操作系统安装时是默认的gbk编码,而linux操作系统默认的是utf8编码;

当执行open函数时,调用的是操作系统打开文件,操作系统用默认的gbk编码去解码utf8的文件,自然乱码。

解决办法:

查看效果:

如果你的文件保存的是gbk编码,在win 下就不用指定encoding了。

另外,如果你的win上不需要指定给操作系统encoding='utf8',那就是你安装时就是默认的utf8编码或者已经通过命令修改成了utf8编码。

注意:open这个函数在py2里和py3中是不同的,py3中有了一个encoding=None参数。

5.对比python2与python3的字符编码

先说python2

  1. py2里默认编码是ascii
  2. 文件开头那个编码声明是告诉解释这个代码的程序 以什么编码格式 把这段代码读入到内存,因为到了内存里,这段代码其实是以bytes二进制格式存的,不过即使是2进制流,也可以按不同的编码格式转成2进制流,你懂么?
  3. 如果在文件头声明了#_*_coding:utf-8*_,就可以写中文了, 不声明的话,python在处理这段代码时按ascii,显然会出错, 加了这个声明后,里面的代码就全是utf-8格式了
  4. 在有#_*_coding:utf-8*_的情况下,你在声明变量如果写成name=u"大保健",那这个字符就是unicode格式,不加这个u,那你声明的字符串就是utf-8格式
  5. utf-8 to gbk怎么转,utf8先decode成unicode,再encode成gbk

再说python3

  1. py3里默认文件编码就是utf-8,所以可以直接写中文,也不需要文件头声明编码了,干的漂亮
  2. 你声明的变量默认是unicode编码,不是utf-8, 因为默认即是unicode了(不像在py2里,你想直接声明成unicode还得在变量前加个u), 此时你想转成gbk的话,直接your_str.encode("gbk")即可以
  3. 但py3里,你在your_str.encode("gbk")时,感觉好像还加了一个动作,就是就是encode的数据变成了bytes里,我操,这是怎么个情况,因为在py3里,str and bytes做了明确的区分,你可以理解为bytes就是2进制流,你会说,我看到的不是010101这样的2进制呀, 那是因为python为了让你能对数据进行操作而在内存级别又帮你做了一层封装,否则让你直接看到一堆2进制,你能看出哪个字符对应哪段2进制么?什么?自己换算,得了吧,你连超过2位数的数字加减运算都费劲,还还是省省心吧。  
  4. 那你说,在py2里好像也有bytes呀,是的,不过py2里的bytes只是对str做了个别名,没有像py3一样给你显示的多出来一层封装,但其实其内部还是封装了的。 这么讲吧, 无论是2还是三, 从硬盘到内存,数据格式都是 010101二进制到-->b'\xe4\xbd\xa0\xe5\xa5\xbd' bytes类型-->按照指定编码转成你能看懂的文字

编码应用比较多的场景应该是爬虫了,互联网上很多网站用的编码格式很杂,虽然整体趋向都变成utf-8,但现在还是很杂,所以爬网页时就需要你进行各种编码的转换,不过生活正在变美好,期待一个不需要转码的世界。

最后,编码is a piece of fucking shit, noboby likes it.

二.集合的使用

#!/usr/bin/env python
#_*_conding:utf-8_*_
#__author__:yinzhengjie
 
#关系测试实现方式一
# list_num1 = [1,2,2,3,3,3,4,5,6]
# set_num1 = set(list_num1) #利用集合去重
# print(list_num1,set_num1)
# set_num2 = set([2,6,11,77,99,4])
# print(set_num2)
# print( set_num1.intersection(set_num2) ) #打印出2个集合的交集
# print(set_num1.union(set_num2)) #打印出2个集合的并集
# print(set_num1.difference(set_num2)) #打印出set_num1集合中有而set_num2中没有的元素,也就是取差集
# print(set_num2.difference(set_num1)) #打印出set_num2集合中有而set_num1中没有的元素
# print(set_num1.issubset(set_num2)) #判断set_num1是否是set_num2的子集,也就是set_num2是否包含set_num1,很显然不是,会返回False.
# set_num3 = {1,3,5} #定义一个集合
# print(type(set_num3)) #查看这个变量的类型
# print(set_num1.issuperset(set_num3)) #判断set_num1是否是set_num3的复集,也就是set_num1是否包含set_num3,很显然是的,会返回True.
# print(set_num1.symmetric_difference(set_num2)) #反向差集,也叫对称差集,将2个集合中的交集丢弃,把剩下的所有的打印出来
# set_num4 = set([7,8,9,6])
# print(set_num4.isdisjoint(set_num1)) #判断set_num4和set_num1是否有交集,如果是就返回False,如果没有就返回True.
 
#关系测试实现方式二,用运算符,但是无法用运算符表示子集。
# list_1 = set([1,2,3,4,5])
# list_2 = set([5,6,7,8])
# print(list_1 & list_2) #取交集
# print(list_1 | list_2) #取并集
# print(list_1 - list_2) #取差集,即在list_1中而不再list_2中
# print(list_2 ^ list_1) #取对称差集
 
 
 
#结合中的增删改查
name_set = set(["尹正杰","灵魂摆渡"])
# print(name_set)
# name_set.add("愤怒的小鸟") #添加一个元素到集合中
# print(name_set)
name_set.update([666,888,999]) #同时更新多个元素到集合中
print(name_set)
#print(6666 in name_set) #判断666这个字符串是否在name_set在这个集合中,如果是就返回True,如果不是就返回False;判断一个字符串是否在列表或者字典中也是可以用这种方法的
#print(name_set.pop()) #删除集合中的任意一个元素
print(name_set.remove(666)) #在name_set中删除一个“666”的元素,如果这个元素在name_set集合中存在,就会删除它,如果该集合不存在的话就会脚本报错
print(name_set.discard(888)) #在name_set中删除一个“888”的元素,它与remove方法唯一不同之处就是即使需要删除的元素(对象)不存在,也不会脚本报错的哟!
print(name_set)
 
 
三.文件的处理
打开文件的模式有:
        1>.r,只读模式(默认)
        2>.w,只写模式。【不可读;不存在则创建;存在则删除内容;】
        3>.追加模式。【可读;   不存在则创建;存在则只追加内容;】
"+" 表示可以同时读写某个文件:
        1>.r+,可读写文件。【可读;可写;可追加】
        2>.w+,写读
        3>.a+,同a
"U"表示在读取时,可以将 \r \n \r\n自动转换成 \n (与 r 或 r+ 模式同使用):
        1>.rU
2>.r+U
"b"表示处理二进制文件(如:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注)
        1>.rb
        2>.wb
        3>.ab
#!/usr/bin/env python
#_*_coding:utf-8_*_
#__author__:yinzhengjie
 
#data = open("简单爱歌词.txt","r",encoding="utf-8").read() #以只读的方式打开“简单爱歌词.txt”这个文件,如果不指定就默认以只读的方式打开,指定该文件的默认编码是"utf-8", 并将内容全部读取出来并复制给data这个变量,不建议这样用,如果文件较大读取比较慢,而且不方便对文件内容进行操作
#data = open("简单爱歌词.txt","r",encoding="utf-8") #以只读的方式打开“简单爱歌词.txt”这个文件
#data.read() #一次性读取所有的内容,注意,读取完毕后就到文件的结尾了,到了文件的结尾如果再执行一次这行代码的话,会没有输出的哟,因为它的光标已经到文件的结尾了,在往下读也是没有数据的
#f = open("简单爱歌词.txt",'w',encoding="utf-8") #重新新建一个文件,如果文件存在就回清空这个文件!强留建议这个选项要慎重的用啊!仅仅只有写的权限,没有读的权限,【f表示文件句柄(内存对象)赋值给f,这个文件句柄包含了文件名,文件大小,字符集以及它在硬盘上的起始位置;】
#f = open("简单爱歌词.txt",'a',encoding="utf-8") #以追加的方式打开一个文件,仅仅只有往文件追加的权限,无法读取文件的内容哟!
#f.write("\n") #往文件写入一个换行符号
#f.write("When i was young i listen to the radio") #往文件中写入一行字符串
#f.close()
#f = open("简单爱歌词.txt","r",encoding="utf-8")
# for i in range(10): #读取文件的前10行
# print(f.readline())
# for line in f.readlines(): #将文件中的每一行变成一个列表,会将所有的内容读取出来,这种方法适合读取小文件
# print(line.strip()) # 打印其中的每一行,并将空格或者换行符去掉
# f = open("简单爱歌词.txt","r",encoding="utf-8")
# for index,line in enumerate(f.readlines()): #读取文件的全部内容,这种方法建议不要使用,尽管能实现功能。在比较小的容量文件中用还看不出来它的速度慢,如果文件的大小想当打的话就显得非常差了!
# if index == 9:
# print("---------我是分割线-----------")
# continue
#
# print(line.strip())
# f = open("简单爱歌词.txt","r",encoding="utf-8")
# count = 0
# for line in f: #将这个文件变成一个迭代器的方式进行循环,这个是逐行处理文件内容的,不用一次性将文件内容读完再进行处理,再处理文件内容,这种处理文件的方法是最高效的。
# if count == 9:
# print('---------我是分割线----------')
# count += 1
# print(line.strip())
# continue
# print(line.strip())
# f = open("简单爱歌词.txt","r",encoding="utf-8") #文件句柄
# print(f.tell()) #打印出指针在文件中的所在的位置,刚刚打开一个文件的时候,位置应该是在“0”
# print(f.readline()) #只读取一行
# print(f.tell()) #打印出读取一行后,指针所停留的位置(这里我们可以理解我们在看电子书的时候用鼠标手动移动光标的位置一样。)
# f.seek(10)#将光标移动到指定的位置,如果在读的话会再这个位置往下读取。
# print(f.readline())
# print(f.encoding) #打印文件的编码
# print(f.fileno()) #打印出该文件句柄所在的编号,python读取文件并不是自己去读取的,而是调用操作系统的某个接口(这个接口是专门用来读取文件的)去读取文件的(系统会自动调用其IO为oython工作),
# print(f.isatty()) #开你是否是一个终端设备,做一些底层的东西,我们可以忽略
# print(f.seekable()) #判断这个文件是否可以移动,如果可以移动就返回True,否则就返回False,在linux中一切都是文件,包括终端设备,如果终端设备话是不可以移动的,会返回False
# print(f.readable()) #判断文件是否可读,如果能读就返回True,否则就返回False
# print(f.writable()) #判断文件是否可写,如果能写就返回True,否则就返回false
# print(f.flush()) #实时刷新内存中的数据到硬盘,其实默认情况下python再处理文件结束之后,需要close文件,然后才能将数据保存到硬盘,如果没有关闭文件的话,想要把数据保存就可以用flush强行将文件写入硬盘(也就是文件)中。为了更加形象的说明,我们可以一起看一下下面的这个例子,实现原理是一样的哟~
# import sys,time
# for i in range(50):#循环50次
# sys.stdout.write("#") #标准输出“#”
# sys.stdout.flush() #如果不加这一行的话会一次性答应出来50个,但是如果有了这一行的话会循环一次打印一次
# time.sleep(0.1) #每次循环的时候睡0.1s,这样便于我们看到打印"#"的流程。
# f = open("简单爱歌词.txt","a",encoding="utf-8")
# f.truncate(10) #从文件的开头开始数,从光标位置为10的位置往后统统截断,也就是删除后面的素有内容,如果不指定数字,默认从开始删除,也就是清空整个文件!
# f = open("简单爱歌词.txt","r+",encoding="utf-8") #以读和追加的方式打开文件,也就是能读能写的模式,但是写的时候不能插入到指定的位置,只能追加到文件的末尾
# f = open("简单爱歌词.txt","w+",encoding="utf-8") #和上面的打开方式是一样的,能写能读的方式,和上面 功能类似,建议用上面的
# f = open("简单爱歌词.txt","a+",encoding="utf-8") #和w+的方式一样的,同上,只是叫法不同。这个叫追加读写
# f = open("简单爱歌词.txt","rb") #以二进制(表示这个文件是以二进制编码的)只读的方式打开文件,也是可以读文件的内容的,但是读出来的内容每行都有“b”表示是一个字节类型,因为如果禁用二进制的话看起来会都是一串0和1组成的数字的。在网络传输的时候都是以二进制的形式传输的,(在python2.7中是可以用字符类型进行传输的,但是在3.0只能用二进制形式传输),比如迅雷下载的视频要是用二进制的格式传输,你就要用二进制的形式打开,用其他形势打开的话可能导致文件被损坏。 一起看一下对其的操作吧
# f = open("简单爱歌词.txt","wb") #以二进制的重定向方式打开,也就是清空整个文件内容的模式打开一个文件,如果文件不存在就创建,存在就清空
# f.write("hell world\n".encode()) #注意,这种以二进制形势打开的文件,在写东西的时候需要将字符串转换成字节
# f.close()
# f = open("简单爱歌词.txt","ab") #以二进制的追加的方式打开,文件的处理方法还是和上面的例子一样,在处理文件的时候以二进制的方式打开的,需要注意在网文件里写的时候需要对字符串进行转码。
 
 
 
#文件修改,将第一个文件的内容读取出来,并将内容更改后重新写入新的文件中
# f = open("简单爱歌词.txt","r",encoding="utf-8")
# f_new = open("简单爱歌词.txt.new","w",encoding="utf-8")
# for line in f:
# if "说不上为什么" in line:
# line = line.replace("说不上为什么","不晓得为啥子") #字符串的重命名
# f_new.write(line)
# f.close()
# f_new.close()
 
#如果您担心自己每次在处理文件的时候都忘记关闭,或者是关闭起来比较麻烦的话。可以用with方法,这个用法现在是越来越广泛了
# with open("简单爱歌词.txt","r",encoding="utf-8") as f:
# for line in f:
# print(line.strip())
#也可以同时打开多个文件进行处理
with open("简单爱歌词.txt","r",encoding="utf-8") as f,\
open("简单爱歌词.txt.new","r",encoding="utf-8") as f2 :
for line in f:
print(line.strip())
for line in f2:
print(line.strip())
 
学完文件的处理,我们应该可以做一个用python来实现替换的功能,用法类似于sed的某一个小功能,哈哈~代码如下:

 1 #!/usr/bin/env python
 2 # _*_coding:utf-8_*_
 3 # __author__:yinzhengjie
 4
 5 import sys, os
 6
 7 old_string = sys.argv[1]
 8 new_string = sys.argv[2]
 9 file = sys.argv[3]
10
11 old_file = open(file, "r", encoding="utf-8")  #打开源文件
12 new_file = open("file_bak", "w", encoding="utf-8") #打开一个新的文件
13 for i in old_file:
14     if old_string in i:
15         i = i.replace(old_string, new_string)  #字符串的替换功能。
16     new_file.write(i)
17
18 old_file.close()
19 new_file.close()  #关闭文件
20 os.rename("file_bak",file)

View Code

需要用python3.5环境

 
 三级菜单流程图如下:
代码如下:注意运行环境是linux操作系统并且解释器为python3.5版本

  1 #!/usr/bin/env python
  2 #_*_coding:utf-8_*_
  3
  4 import sys,time
  5
  6 city_info = {
  7     "北京":{
  8         "东城区":{
  9             "旅游景点":{
 10                 "老舍纪念馆":{
 11                     "介绍":"就是我们从小学到大学都要在课文里提到的一个作者哟"
 12                 },
 13                 "故宫":{
 14                     "介绍":"我去~我上次的地方是天安门,我以为天安门就是故宫呢!"
 15                 }
 16             }
 17         },
 18         "西城区":{
 19             "旅游景点":{
 20                 "北京海洋馆":{
 21                     "简介":"是亚洲第一、世界内陆最大、设施最先进的海洋馆。坐落在北京动物园内,南倚长河、毗邻北京展览馆、天文馆和首都体育馆,交通极为便利。占地12万平方米,建筑面积4.2万平方米,集观赏、科普教育和休闲娱乐为一体,是目前世界最大的内陆水族馆。该馆的总建筑面积达4.2万平方米,绿化面积达8万多平方米。场馆外形采用了别具一格的“海螺”形状,色彩以蓝色和橘红色为基本色调,分别代表了神秘浩瀚的海洋和海洋生物无穷无尽的生命力。其内部设计也别具匠心,屋顶均为网架结构,并采用蓝色和黄色进行装饰,将一个蔚蓝色的世界呈现在人们面前。北京海洋馆以“陶怡大众、教益学生、维系生态”为宗旨。馆内共分六个不同内容的展示场馆、分别命名为雨林奇观、触摸池、海底环游、鲨鱼馆、鲸豚湾和海洋剧院。置身其中,人们不但可以领略不同种类的海洋生物,还可亲身感受人类与海洋的关系。馆内展出各种鱼类达数万尾,其中海洋观赏鱼类及淡水观赏鱼类近千余种。"
 22                 },
 23                 "人民大会堂":{
 24                     "简介":"人民大会堂位于北京市中心天安门广场西侧,西长安街南侧。人民大会堂是中国全国人民代表大会开会的地方,是全国人民代表大会和全国人大常委会的办公场所。是党、国家和各人民团体举行政治活动的重要场所,也是中国国家领导人和人民群众举行政治、外交、文化活动的场所。"
 25                 },
 26                 "北京动物园":{
 27                     "简介":"北京动物园位于北京市西城区西直门外大街,占地面积约86公顷,水面8.6公顷。是中国最大的城市动物园。北京动物园原名农事实验场、天然博物院、万牲园、西郊公园,是中国开放最早、动物种类最多的动物园,从清光绪三十二年(1906年)至今已有逾百年的历史。"
 28                 },
 29             }
 30         },
 31          "丰台区":{
 32              "旅游景点":{
 33                  "卢沟桥":{
 34                      "简介":"永定河上的卢沟桥,在北京附近,修建于公元1189到1192年间。桥长265米,整座桥由11个半圆形的石拱组成。"
 35                  },
 36                  "北京世界公园":{
 37                      "简介":" 集世界名胜于一体的北京世界公园,位于北京丰台区花乡大堡台,总面积46.7公顷,距市中心16公里,距北京西客站8公里,紧邻花乡森林公园。"
 38                  },
 39                  "石景山区":{
 40                      "心得":"给我的感觉就是寺庙聚集地区啊,哈哈"
 41                  },
 42              }
 43          },
 44         "朝阳区":{
 45             "旅游景点":{
 46                 "北京奥林匹克公园":{
 47                     "简介":"北京奥林匹克公园位于北京市朝阳区,地处北京城中轴线北端,北至清河南岸,南至北土城路,东至安立路和北辰东路,西至林翠路和北辰西路,总占地面积11.59平方千米,集中体现了“科技、绿色、人文”三大理念,是融合了办公、商业、酒店、文化、体育、会议、居住多种功能的新型城市区域。"
 48                 },
 49                 "国家体育馆":{
 50                     "简介":"建筑面积8.09万平方米,可容纳1.8万人。在奥运期间主要承担竞技体操、蹦床和手球比赛项目。奥运会后,国家体育馆作为北京市一流体育设施,将成为提供多功能服务的市民活动中心。介绍  国家体育馆国位于奥林匹克公园中心区的南部,与“鸟巢”和“水立方”和国家会议中心比邻而居。"
 51                 },
 52                 "朝阳公园":{
 53                     "简介":"国家4A级旅游景区。位于北京市朝阳区的中部繁华地段,多条公交线路可达。"
 54                 },
 55                 "国家游泳中心(水立方)":{
 56                     "简介":"国家游泳中心又被称为“水立方”,位于北京奥林匹克公园内,是北京为2008年夏季奥运会修建的主游泳馆,也是2008年-标志性建筑物之一。它的设计方案,是经全球设计竞赛产生的“水的立方”方案。其与国家体育场(俗称鸟巢)分列于北京城市中轴线北端的两侧,共同形成相对完整的北京历史文化名城形象。"
 57                 },
 58                 "奥林匹克公园网球场":{
 59                     "简介":"位于北京奥林匹克公园内,北邻北五环路,东邻北辰西路,西临白庙村路,南侧为射箭场。总建筑面积26514平方米,总坐席数17400个。2008年-网球比赛将在这里举行。"
 60                 },
 61                 "大望京公园":{
 62                     "简介":"大望京公园位于朝阳区崔各庄乡辖区内,北靠北小河,东南临京顺路,东北至五环路,西接望京规划路。总占地面积334000平方米,其中陆地面积310633平方米(绿地面积261608平方米,园路及铺装49025平方米),水面面积23367平方米。大望京是具有悠久历史的区域。大望京比北京的历史还要长几百年。"
 63                 },
 64                 "潘家园旧货市场":{
 65                     "简介":"潘家园又有“鬼市”之称。说起“鬼市”还要追溯到清末民初。当时国运衰落,许多达官显贵家道中落,便偷拿了家中的古玩站街变卖。毕竟这是件有-份的事,只能选在凌晨三四点打着灯笼交易。”有多年摆摊经验的霍老不胜唏嘘,“想当年,‘鬼市’上还脱手些来路不明的物件,因为都有着不可言说的秘密,大多只能贱价出售。‘鬼市出好货’的传闻也就传开了。”现在虽然不需要躲躲藏藏、掩人耳目,但是凌晨四点开市的传统被延续了下来。"
 66                 },
 67             }
 68         }
 69     },
 70     "陕西":{
 71         "西安市":{
 72             "旅游景点":{
 73                 "兵马俑":{
 74                     "简介":"现在秦始皇帝陵博物院是通票(包括秦始皇兵马俑博物馆、秦始皇陵、秦始皇陵遗址公园、百戏俑坑博物馆、石铠甲博物馆。遗址公园内有摆渡车,游客可免费乘坐,来往兵马俑和丽园之间)。"
 75                 },
 76                 "华清池":{
 77                     "注意":"在临潼吃饭时小心被宰,吃饭前先看好菜单价格。"
 78                 },
 79                 "华山":{
 80                     "简介":"乘“亚洲第一索道”游西岳华山   翠华山"
 81                 },
 82                 "碑林博物馆":{
 83                     "注意":"可以顺着碑林南围墙一直往西走到书院门步行街(书院门步行街都是书法和一些手工制品,一般看看就行了,不要买。如果实在想买的话,只调一些小玩意买,小心被宰哟)到南门,从南门上明城墙。"
 84                 }
 85             }
 86         },
 87         "安康市":{
 88             "旅游景点":{
 89                 "南宫山":{
 90                     "简介":"南宫山还算不错,我们去的那天观音望海下面全是雾,漂亮极了。走在玻璃栈道上,我一点也没觉得害怕"
 91                 }
 92             }
 93         }
 94     }
 95
 96 }
 97
 98 while True:
 99     for i in city_info:
100         print(i)
101     choice = input("\033[32;1mPlease select the area you want to visit, press 'q' or 'Q' to exit the program >>:\033[0m").strip()
102     if choice == "q" or choice == "Q":
103          break
104     elif choice not in  city_info:
105         print("\033[31;1m                    The data you entered is invalid,Please enter the following list of areas\033[0m")
106         continue
107     if  choice in   city_info:
108         while True:
109             for i2 in city_info[choice]:
110                 print("\t",i2)
111             choice2 = input("\033[32;1mPlease choose the autonomous area want to go to,Press :'b' or 'B' to return, press 'q' or 'Q' to exit the program >>:\033[0m").strip()
112             if  choice2 == "b":
113                     break
114             elif choice2 == "q" or choice2 == "Q":
115                 sys.exit()
116             elif choice2 not in city_info[choice]:
117                 print("\033[31;1m                    The data you entered is invalid,Please enter the following list of areas\033[0m")
118                 continue
119             if choice2 in city_info[choice]:
120                 while True:
121                     for i3 in city_info[choice][choice2]:
122                         print("\t\t", i3)
123                     choice3 = input("\033[32;1mPlease choose the things you are interested in,Press :'b' or 'B' to return, press 'q' or 'Q' to exit the program >>:\033[0m").strip()
124                     if choice3 == "b":
125                         break
126                     elif choice3 == "q" or choice3 == "Q":
127                         sys.exit()
128                     elif choice3 not in city_info[choice][choice2]:
129                         print(
130                             "\033[31;1m                    The data you entered is invalid,Please enter the following list of areas\033[0m")
131                         continue
132                     if choice3 in city_info[choice][choice2]:
133                         while True:
134                             for i4 in city_info[choice][choice2][choice3]:
135                                 print(i4)
136                             choice4 = input("\033[32;1mPlease choose the scenic spots you want to visit,Press :'b' or 'B' to return, press 'q' or 'Q' to exit the program >>:\033[0m").strip()
137                             if choice4 == "b":
138                                 break
139                             elif choice4 == "q" or choice4 == "Q":
140                                 sys.exit()
141                             elif choice4 not in city_info[choice][choice2][choice3]:
142                                 print(
143                                     "\033[31;1m                    The data you entered is invalid,Please enter the following list of areas\033[0m")
144                                 continue
145                             if choice4 in city_info[choice][choice2][choice3]:
146                                 while True:
147                                     for i5 in city_info[choice][choice2][choice3][choice4]:
148                                         print(i5)
149                                     choice5 = input("\033[32;1mPlease select the information to change the line,Press :'b' or 'B' to return, press 'q' or 'Q' to exit the program >>:\033[0m").strip()
150                                     if choice5 == "b":
151                                         break
152                                     elif choice5 == "q" or choice5 == "Q":
153                                         sys.exit()
154                                     elif choice5 not in city_info[choice][choice2][choice3][choice4]:
155                                         print(
156                                             " \033[31;1m                   The data you entered is invalid,Please enter the following list of areas\033[0m")
157                                         continue
158                                     if choice5 in   city_info[choice][choice2][choice3][choice4]:
159                                         print(city_info[choice][choice2][choice3][choice4][choice5])
160                                         for i in range(5):
161                                             print("\033[35;1m已经是字典的底层了哟~请安Q或者B进行操作,%s秒后返回上级清单\033[0m" % (5-i))
162                                             time.sleep(1)

View Code

 
购物车流程图:

代码如下:

 1 #!/usr/bin/env python
 2 #coding:utf-8
 3 #__author__:yinzhengjie
 4 import time,sys
 5 sale_list = [
 6     ('watch',3188),
 7     ('ipad mini',4588),
 8     ('macbook air',6988),
 9     ("摩托车",3290),
10     ("电动自行车",3199),
11     ("锂电池自行车",2488),
12     ("自行车",340),
13     ("咖啡",85),
14     ("奶茶",56),
15     ("彩电",3199),
16     ("冰箱",6599),
17     ("洗衣机",3499),
18     ("男士羽绒服",799)
19 ]
20 shopping_list = []
21 total_consumption = 0
22 customer_deposit = input("请问您有多少存款>>:   ")
23 if  customer_deposit.isdigit():
24     customer_deposit = int(customer_deposit)
25     print()
26 while True:
27     for index, item in enumerate(sale_list):
28         print(index, item)
29     user_choice = input("请选择相应的序列号来挑选商品>>:  ")
30     if  user_choice.isdigit():
31         user_choice = int(user_choice)
32         if  user_choice < len(sale_list) and user_choice >= 0:
33             purchase_items = sale_list[user_choice]
34             if  purchase_items[1] <= customer_deposit:
35                 shopping_list.append(purchase_items)
36                 customer_deposit -= purchase_items[1]
37                 total_consumption += purchase_items[1]
38                 print(purchase_items[1])
39                 print(total_consumption)
40                 print("已经订单的商品:'%s'" % purchase_items[0] )
41                 print("")
42                 continue_shopping = input("请问是否要继续购物呢(按任意键继续,按'Q'或者'q'停止购物)>>:    ")
43                 if  continue_shopping == "q":
44                     for i in shopping_list:
45                         print("您已经订单的商品‘%s’,需要花费‘%s’元人名币" % (i[0],i[1]))
46                     print("您的存款是\033[31;1m%s\033[0m" % (customer_deposit + purchase_items[1]))
47                     print("共需要消费\033[31;1m%s\033[0m人民币" % total_consumption)
48                     spend=input("是否确认购买物品(按任意键退出退出程序,按'y'确认结账)")
49                     if spend == "y":
50
51                         print("欢迎来到尹正杰商城进行消费!当前您的余额是:\033[31;1m'%s'\033[0m" %customer_deposit)
52                         sys.exit()
53                     else:
54                         print("退出商城")
55                         sys.exit()
56
57             else:
58                 print("\033[41;1m您的余额只剩【%s】啦,还买个毛线啊\033[0m" % customer_deposit)
59         else:
60             print("                            对不起您输入的序列号不正确!请重新输入!!!   ")
61             print("")
62             time.sleep(2)
63             continue

购物车

 
 
 
 
引用:http://www.cnblogs.com/yuanchenqi/articles/5956943.html

python自动化运维之路~DAY2相关推荐

  1. 【Python自动化运维之路Day2】

    1. 常量命名规则 在Python中,会在变量命名上标明某变量是常量,通常采用全是大写的方式来标明,如: CONNECT= '127.0.0.1' PORT = '3306' 2.Python编译 p ...

  2. 开启Python自动化运维之路

    关于Python的入门,推荐Dive into Python及廖雪峰的Python教程. 第一个程序 学一门语言,按惯例都要先来一个Hello World! 代码高亮效果 代码如下: print(&q ...

  3. python自动化运维之路~DAY1

    python自动化运维之路~DAY1 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.文件大小单位单位换算 我们一起看一下下面的图: 没错,都是数字,而且这些数字都是二进制的数字 ...

  4. python自动化运维之路~DAY6

    python自动化运维之路~DAY6 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.  如果你想开发一款游戏,会存在角色的混搭的情况,这个时候"面向对象过程"就出 ...

  5. 【Python自动化运维之路Day6】

    1.递归思考题,阶乘 使用递归方式(函数)计算: 1*2*3*4*5*6*7*8*9*10的值 def func(num):if num==1:return 1return num*func(num- ...

  6. 有赞MySQL自动化运维之路—ZanDB

    有赞MySQL自动化运维之路-ZanDB 一.前言 在互联网时代,业务规模常常出现爆发式的增长.快速的实例交付,数据库优化以及备份管理等任务都对DBA产生了更高的要求,单纯的凭借记忆力去管理那几十套D ...

  7. Python自动化运维-丁志文-专题视频课程

    Python自动化运维-4561人已学习 课程介绍         本职业规划路线是专门为从事运维开发的同学准备的,并且是严格按照企业需求的标准定制的学习路线.路线中包含python基础和进阶,lin ...

  8. 云计算Python自动化运维开发实战 三、python文件类型

    为什么80%的码农都做不了架构师?>>>    云计算Python自动化运维开发实战 三.python文件类型 导语: python常用的有3种文件类型 1. 源代码     py ...

  9. 2018python培训-2018年5月python自动化运维开发课程新班正式开课!

    2018年5月python自动化运维开发课程新班正式开课! 作者: 更新时间::2018-05-16 新推出的ansible是新出现的 自动化 运维工具 , 基于Python研发 . 糅合了众多老牌运 ...

  10. 云计算开发教程:Python自动化运维开发实战流程控制

    今天这篇文章是给大家分享一些云计算开发教程,今天讲解的是:Python自动化运维开发实战流程控制. Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. P ...

最新文章

  1. Flutter 网络请求库http
  2. C语言\b回退一格!多点的!_只愿与一人十指紧扣_新浪博客
  3. Codeforces Round #462 (Div. 2)题解
  4. C# 与 VC Dll 传输信息
  5. 10月数据库排行:Microsoft SQL Server分数增加最多
  6. 梯度 cv2.sobel_TensorFlow 2.0中连续策略梯度的最小工作示例
  7. java8 supplyasync_java – 为什么CompletableFuture.supplyAsync成功随...
  8. tensorflow 入门笔记(二)
  9. ORB-SLAM2双目开源框架 (3) LocalMapping解析
  10. C# Invoke 使用 异步委托
  11. paip.输入法编程--词频调整原则--发音长度优先
  12. html 画excel表格边框,只需五分钟!用Excel做出美观的表格
  13. 韩顺平零基础循序渐进学Java——自学笔记
  14. Electron打包方式
  15. 前端框架React Js入门教程【转】
  16. 计算机无法设置双屏显示,电脑双屏显示怎么设置?
  17. DBMS的完整性违约处理机制
  18. TC---教学知识与能力
  19. access数据库出现操作必须使用一个可更新的查询的解决办法
  20. android pad查看cpu,苹果还是安卓?一图教你如何选择适合自己的平板

热门文章

  1. wxPython下载安装教程
  2. linux更新war包操作步骤,关于Linux系统下基于Tomcat部署和升级war包的详细过程
  3. 电脑测试软件 免安装,Keyboard Test Utility:电脑必备键盘测试软件,小体积、免安装...
  4. [笔记] 当当音乐人:免费将Midi转化为WAV
  5. 数字证书及其认证过程
  6. 【Matlab水果识别】RGB+HSV水果成熟度分级系统【含GUI源码 825期】
  7. python程序分析csv文件并绘制趋势图
  8. 【C++】【内存】系列三:内存优化
  9. vue 中的const {XXX } =this 的作用效果
  10. 一些在线图片处理工具收集