'''
1.用户输入一个手机号码,判断这个手机号码是移动、联通、电信
'''
movePhone    = ['134','139','147','150'] #移动
unicomPhone  = ['130','131','132','186'] #联通
telecomPhone = ['133','349','153','180'] #电信
tel = input('请输入要查询的手机号:')
if len(tel) == 11: #判断长度
    if tel.isdigit():#判断纯数字
        fen = tel[:3]#手机号前三位
        if fen in movePhone:
            print ('此号码为移动号码:' + tel)
        elif fen in unicomPhone:
            print ('此号码为联通号码:' + tel)
        elif fen in telecomPhone:
            print ('此号码为电信号码:' + tel)
        else:
            print ('无此号段!')
    else:
        print ('电话号码中包含非法字符!')
else:
    print ('手机号码长度输入有误,必须是11位!')


2.冒泡排序
#相邻元素对比,大的值往后移
"""
第一次对比:6次 [1,2,0,4,5,13,  18]  每次最后大的数下一轮不需要在对比
第二次对比:5次 [1,0,2,4,5,  13,18]
第三次对比:4次 [0,1,2,4,  5,13,18]
第四次对比:3次 [0,1,2,  4,5,13,18]
第五次对比:2次 [0,1,  2,4,5,13,18]
第六次对比:1次 [0,  1,2,4,5,13,18]
"""
alist = [1,5,2,0,4,18,13] #对比6次
for i in range(0,len(alist)-1): #i = 0 1 2 3 4 5 6
    for j in range(0,len(alist)-1-i):#i=0  j=0 1 2 3 4 5
        if alist[j]>alist[j+1]:
            alist[j],alist[j+1]=alist[j+1],alist[j]
print(alist)
3.新建一个列表,每次找到最小的,append插入到新列表中,排序
'''
第一次对比:4次 [3,9,7,2,1] 最小的1
第二次对比:3次 [9,7,3,  2,1] 最小2
第三次对比:2次 [9,7,   3,2,1] 最小3
第四次对比:1次 [9,7,3,2,1]  最下7
'''
alist = [3,2,9,7,1]
newList = []
for i in range(0,len(alist)-1): #i:0,1,2
    for j in range(0,len(alist)-1-i):
        if alist[j]<alist[j+1]:
            alist[j],alist[j+1]=alist[j+1],alist[j]
    newList.append(alist[len(alist)-i-1])
newList.append(alist[0])
print (newList)

4.九九乘法表
'''
     1       2      3        4       5
1  1*1=1
2  1*2=2   2*2=4
3  1*3=3   2*3=6   3*3=9
4  1*4=4   2*4=8   3*4=12   4*4=16
5  1*5=5   2*5=10  3*5=15   4*5=20   5*5=25
for i in range(1,6):#外循环5次,表示行数
    1*行数
    1*行数  2*行数
    1*行数  2*行数  3*行数
'''
def jiu_test(n):
    if n <=9:
        for i in range(1,n+1):#i代表行数,赋值1-9
            for j in range(1,i+1): #j代表了行数乘以的那个数
                print ("{}*{}={}\t".format(j,i,(i*j)),end="")
            print ()
    else:
        print("输入错误,只能输入1-9!")

jiu_test(9)
5.自定义异常,抛出用raise
class  NameLongError(Exception):
    pass
class NameShortError(Exception):
    pass
def inputName():
    name = input("请输入用户名:")#5-10位
    if len(name) > 10:
        raise NameLongError
    elif len(name) < 5:
        raise NameShortError
try:
    inputName()
except NameLongError:
    print ("您输入的用户名太长")
except NameShortError:
    print("您输入的用户名太短")
已经知道的异常:
import traceback
while  True:
    num = input('input a number:')
    try:
        print('10000/%s=%s'%(num,10000.0/int(num)))
    except ZeroDivisionError as e :
        print(traceback.format_exc())
    else: #没有异常则会执行else,有异常直接执行相应的异常
        print("没有异常我就会被执行!")
    finally: #一定会被执行
        print("我一定会被执行的!")
6.格式化输出1
''''
现有一个游戏系统的日志文件,记录内容的字符串 的格式 如下所示
A girl come in, the name is Jack, level 955;
其中包含的 the name is 后面会跟着人名,随后紧跟一个逗号, 这是固定的格式。
其它部分可能都是会变化的,比如,可能是下面这些
A old lady come in, the name is Mary, level 94454
A pretty boy come in, the name is Patrick, level 194
请大家实现一个函数,名为getName,如下所示
def getName(srcStr):
    函数体
该函数的参数srcStr 是上面所描述的格式字符串(只处理一行),该函数需要将其中的人名获取出来,并返回
比如 调用 getName('A old lady come in, the name is Mary, level 94454')
返回结果应该是 'Mary'
'''
def getName(srcStr):
    name = srcStr.strip().split("the name is ")[1].split(',')[0]
    return name
srcStr = "A old lady come in, the name is Mary, level 94454"
result = getName(srcStr)
print(result)
7.格式化输出2
'''
2.--用户输入的信息是jack green,21;mike mos,9
输出结果:jack green: 21
学生的姓名要求左对齐,宽度为20,年龄信息右对齐,宽度为2,不足0补齐
   1--接受用户输入 info=input('请输入学生信息:') -- str
   2--提取数据:名字+年龄
      1--独立每一个学生的信息 templist = info.split(;) --list
      2-获取每一个学生的姓名和年龄 for 遍历
          for one in templist: #--jack green,  21
      3-对每一个提取姓名和年龄
          name,age = one.split(',')
   3--按照格式输出
      print('{:<20}:{:0>2};'.format(name,age))
'''
info = "aa,12;bb,4"
#info = input('请输入学生的信息,格式为:"姓名,年龄;姓名,年龄;..."')
templist = info.split(';')
#del templist[-1] #删除最后一段切下来的空内容
for one in templist:
    #方法一:
    # temp = one.split(',')
    # name = temp[0].strip()
    # age = temp[1].strip()
    #方法二:
    name,age = one.split(',')
    name = name.strip()
    age = age.strip()
    print ('{:<12}:{:0>2};'.format(name,age))
8.格式化输出3
'''
存在文件:
log = "f2014000019/i_21sdad.jpeg   1122   wewqda\t" \
      "f2014222211/i_2121asd.json   223   dsadas\t"\
      "f2014111111/i_2121aaa.ipeg   33   asddad"\
      "f20142323323/i_231azxs.json  444  sdsaf"
需要得到结果: 统计每一种类型文件大小累加
jpeg  1155
json 477
1-获取每一行文件信息的:类型 大小
2-对相同类型文件进行统计累加
'''
log = "f2014000019/i_21sdad.jpeg 1122 wewqda\t" \
      "f2014222211/i_2121asd.json 223 dsadas\t"\
      "f2014111111/i_2121aaa.jpeg 33 asddad\t"\
      "f20142323323/i_231azxs.json 444 sdsaf"
lineslist = log.split('\t')#获取每一行的内容
jpeg_count=0
json_count =0
for one in lineslist: #循环分割后的每一行
    fileType = one.split(' ')[0].split('.')[1].strip()
    fileSize = int(one.split(' ')[1].strip())
    if fileType == "jpeg":
        jpeg_count+=fileSize
    elif fileType == "json":
        json_count+=fileSize
    else:
        print('wu')

print('{}:{}'.format("jpeg",jpeg_count))
print('{}:{}'.format("json",json_count))
9.文件操作
'''
现有一个数据库记录文件(见附件0005_1.txt),保存了学生课程签到的数据库记录。 内容格式如下 ,
('2017-03-13 11:50:09', 271, 131),
('2017-03-14 10:52:19', 273, 131),
('2017-03-13 11:50:19', 271, 126),
每一行记录保存了学生的一次签到信息。
每一次签到信息的记录,分为三个部分, 分别是签到时间、签i到课程的d号、签到学生的id号
要求大家实现下面的函数。其中参数fileName为数据库记录文件路径,
输出结果是将数据库记录文件中的学生签到信息保存在一个字典对象中,并作为返回值返回。
def putInfoToDict(fileName):
要求返回的字典对象的格式是这样的:
key 是各个学生的id号, value是 该学生的签到信息
   其中value,里面保存着该学生所有签到的信息
       其中每个签到的信息是字典对象,有两个元素: key 是lessonid 的记录课程id,key是checkintime的 记录签到时间
比如,对于上面的示例中的3条记录,相应的返回结果如下:
{
    131: [
        {'lessonid': 271,'checkintime':'2017-03-13 11:50:09'},
        {'lessonid': 273,'checkintime':'2017-03-14 10:52:19'},
    ],
    126: [
        {'lessonid': 271,'checkintime':'2017-03-13 11:50:19'},
    ],
}
'''
def putInfoToDict(fileName):
    resList = {}
    fo = open(fileName)# 读取文件中的文件
    lines = fo.read().splitlines()#读取所有行信息
    fo.close() #关闭文件
    #遍历每一行的元素,获取学生ID,课程ID,时间
    for one in lines:#('2017-03-13 11:50:19', 271, 126),
        #替换得到字符串准备进行切割,'2017-03-13 11:50:19', 271, 126,
        info = one.replace('(','').replace(')','').replace(';',',').strip()
        # print(info)
        #,号进行切割,得到字典,删除最后一个空元素
        temp = info.split(',')
        del temp[-1]
        # print(temp)
        #获取时间,课程ID,学生ID
        time = temp[0].strip()
        courseId = int(temp[1].strip())
        stuId = int(temp[2].strip())
        # print(time,courseId,stuId)
        #如果学生ID不存在,则新增;存在,则增加信息
        if stuId not in resList: #键值对,左边stuId键=值,列表中套了一个字典
            resList[stuId] = [{'lessonid':courseId,'checkintime':time}]
        else:
            resList[stuId].append(({'lessonid':courseId,'checkintime':time}))
    return resList
print (putInfoToDict("d://005_1.txt"))
10.登录操作
'''
例如:passwd={"admin":123321,"user1":123456}
1.设计一个登陆的程序,不同的用户名和对应密码存在一个字典里,
输入正确的用户名和密码去登录,
2.首先输入用户名,如果用户名不存在或者为空,则一直提示输入用户名
3.当用户名正确的时候,提示输入密码,如果密码跟用户名不匹配,则提示密码错误请重新输入
如果密码输入错误超过三次,中断程序运行
当输入密码错误时,提示还有几次机会
用户名和面膜输入成功的时候,提示登录成功!
'''
info = {"admin":'123321',"user1":'123'}
flag = True  #登录成功,跳出循环标志
count = 0 # 计算每次密码输错的次数
userId = input("请输入用户名: ")  # 提示输入用户名
while flag:
    if len(userId) > 0 and userId in info:
        # password = int(input("请输入密码"))
        password = input("请输入密码: ")
        while True:
            # print(type(userId),type(password),type(info[userId]))
            if password == info[userId]:
                print("登录成功")
                flag = False  # 登录成功,结束程序
                break
            else:
                count += 1
                if count == 3:
                    print("密码输入错误次数达到上限,程序结束。 ")
                    flag = False
                    break
                print (f"不好意思,您还有{3-count}次机会")
                password = input("请重新输入正确的密码: ")
    else:
        userId = input("用户名输入有误,请重新输入用户名: ")
11.统计出不同类型的文件的大小总和
log = '''
f20180111014341/i_51a7hC3W.jpeg    169472 FrITJxleSP7wUD-MWw-phL_KP6Eu   15156063244230469  image/jpeg 0  
f20180111014341/j_R0Hpl4EG.json    1036   ForGzwzV3e-uR3_UzvppJs1VgfQG   15156064773253144  application/json   0  
f20180111020739/i_0TDKs0rD.jpeg    169472 FrITJxleSP7wUD-MWw-phL_KP6Eu   15156076847077556  image/jpeg 0  
f20180111020739/j_JFO6xiir.json    1040   FmUhTchdLOd7LBoE8OXzPLDKcW60   15156077904192983  application/json   0  
f20180111090619/i_1BwNksbL.jpg 49634  FtXBGmipcDha-67WQgGQR5shEBu2   15156329458714950  image/jpeg 0  
f20180111090619/i_3BKlsRaZ.jpg 30152  FoWfMSuqz4TEQl5FT-FY5wqu5NGf   15156330575626044  image/jpeg 0
'''
logLines = log.strip().split('\n')
dict = []
size = 0
for one in logLines:
    a = 0
    name = one.strip().split('\t')[0].split('.')[-1]#取文件类型
    size = int(one.strip().split('\t')[1].strip())#取文件大小
    for temp in dict: #类型和大小在列表dict中)
        if temp[0] == name:#文件类型相同,则大小自加
           temp[1] += size
           a = 1
    if a == 0:
        dict.append([name, size])
print(dict)
12.排序
'''
请定义一个函数 mySort,参数为一个列表,参数列表中的元素都是整数.
mySort 函数需要将参数列表中的元素按从小到大排序,最终返回一个新的list。
请按下面算法的思路实现函数:
1. 创建一个新的列表newList
2. 先找出所有元素中最小的,append在newList里面
3. 再找出剩余的所有元素中最小的,append在newList里面
4. 依次类推,直到所有的元素都放到newList里面
第一次: 6 in data  1  data=6,2,4,89
第二次:2 in data  2  data= 6,4,89
第三次:  4 in data  4 data = 6,89
'''
方法一:
def mySort(data):
    newList = [] #存放排序好的列表
    for i in range(0,len(data)):
        newList.append(min(data)) #将最小值添加到newList列表中
        data.remove(min(data)) #删除最小值
    return newList
list = [6,2,4,89,1,1,3]
print(mySort(list))

方法二:
def sort(inList):
    newList = []
    # 设计一个循环,每个循环做如下事情(直到 inlist 没有元素):
    #     找出当前inlist中所有元素中最小curMin的,append在newList里面
    #     inList 去掉 curMin
    while len(inList) > 0:
        theMin = inList[0] # 记录当前循环最小元素
        minIdx = 0   # 记录当前最小元素的下标
        idx = 0      # 指向当前元素下标
        for one in inList: #循环遍历每个列表中的元素,列表为删除后的新列表
            if theMin > one: #如果每个新列表中第一个元素大于后面的元素,则
                theMin = one
                minIdx = idx
            idx += 1
        inList.pop(minIdx)
        newList.append(theMin)
    return newList
print (sort([3,1,2,5,7,34,23,55,56,2,3,4]))
13.格式化输出4
'''
现有文件1(如下,请保存到文件file1.txt中), 记录了公司员工的薪资,其内容格式如下
name: Jack   ;    salary:  12000
 name :Mike ; salary:  12300
name: Luk ;   salary:  10030
  name :Tim ;  salary:   9000
name: John ;    salary:  12000
name: Lisa ;    salary:   11000
每个员工一行,记录了员工的姓名和薪资,
每行记录 原始文件中并不对齐,中间有或多或少的空格
现要求实现一个python程序,计算出所有员工的税后工资(薪资的90%)和扣税明细,
以如下格式存入新的文件 file2.txt中,如下所示
name: Jack   ;    salary:  12000 ;  tax: 1200 ; income:  10800
name: Mike   ;    salary:  12300 ;  tax: 1230 ; income:  11070
name: Luk    ;    salary:  10030 ;  tax: 1003 ; income:   9027
name: Tim    ;    salary:   9000 ;  tax:  900 ; income:   8100
name: John   ;    salary:  12000 ;  tax: 1200 ; income:  10800
name: Lisa   ;    salary:  11000 ;  tax: 1100 ; income:   9900
'''
with open(r"D:\file1.txt") as f1,open(r"D:\file2.txt",'w+') as f2:
    file1 = (f1.read().splitlines()) # 取出每一行的内容,返回list列表
    for i in file1:#读取file1文件中的每一行
        #获取每一行的姓名和工资
        name = i.split(';')[0].split(':')[1].strip()
        salary = int(i.split(';')[1].split(':')[1].strip())
        #计算扣税金额和实际收入
        tax = int(salary*0.1)
        income = int(salary*0.9)
        #每一行拼接一定的格式
        # outFile = "name:{:8};salary:{:^8};tax:{:^8};income:{:^8}\n".format(name,salary,tax,income)
        outFile = f"name:{name:8};  salary:{salary:^8};  tax:{tax:^8};  income:{income:^8}\n"
        #写入到f2文件中
        f2.write(outFile)
        #print(outFile)
    f2.flush()
14.习题
题目一:
'''
请写一个函数remainder,参数是两个数字,请计算返回这两个数字相除的余数
比如
remainder(1, 3) ➞ 1
'''
def remainder(a,b):
    return a%b
result = remainder(4,2)
print (result)
题目二:
'''
农场上有3种动物:鸡、奶牛、猪
请写一个函数animals,该函数有3个参数,分别是鸡、奶牛、猪的个数,请计算返回这么多的动物总共有多少条腿
比如
animals(2, 3, 5) ➞ 36
'''
def animals(J,N,Z):
    return J*2+(N+Z)*4
print(animals(2,3,5))
题目三:
'''
请写一个函数reverse,参数是一个列表,该函数返回一个新的列表, 新列表中元素是参数列表的倒序。
'''
def newReverse(info): #传入一个列表
    #为了不改变原列表的值,则遍历输出一个新列表
    newInfo = []
    for i in info:
        newInfo.append(i)
    print(f"新列表为:{newInfo}")
    newInfo.reverse() #将新列表翻转
    return newInfo #返回翻转以后的列表

info = [15,67,34,2]
newList = newReverse(info)
print(f"翻转以后的列表:{newList}\n旧列表:{info}")
题目四:
'''
请写一个函数reverse,参数是一个列表,该函数将列表中的所有元素倒序排列并返回
比如
reverse([1, 2, 3, 4]) ➞ [4, 3, 2, 1]
reverse([9, 9, 2, 3, 4]) ➞ [4,3, 2, 9, 9]
reverse([]) ➞ []
'''
def reverseTest(info):
    info.reverse()
    return info
info = [3,5,6,7]
print(reverseTest(info))
题目五:
'''
请写一个函数is_symmetrical,参数是1个数字,请返回该数字是否对称
比如
is_symmetrical(7227) ➞ True
is_symmetrical(12567) ➞ False
奇数:-- 去掉中间的len//2
2222227222222  13//2=6 [:6][6+1:]  -- pop(len//2) #去掉中间的得到新的字符串
偶数:
p1 = [:len//2]
p2 = [len//2::-1]
判断p1==p2:等于则对称,否则不对称
'''
def is_symmertrical(para):
    stringTest = str(para)
    lenght = len(stringTest)//2 # 输入字符串的长度
    if len(stringTest)%2 != 0: #判断等于奇数
        stringTest = stringTest[:lenght]+stringTest[lenght+1:]

    str1 = stringTest[:len(stringTest)//2]
    str2 = stringTest[len(stringTest)//2::][::-1]
    if str1 == str2:
        return ("对称")
    else:
        return ("不对称")
par = 9999
result = is_symmertrical(par)
print (f"{par}:数字{result}")
题目六:
'''
请写一个函数tri_area,参数是三角形的底和高,请计算返回三角形面积
比如:
tri_area(3, 2) ➞ 3 = 1/2*3*2
tri_area(7, 4) ➞ 14 = 1/2*7*4
'''
def tri_area(weight,height):#传入三角形的底和高
    return 1/2*weight*height

result = tri_area(3,5)
print(f"三角形的面积是:{result}")

15.面向对象
'''
1-动物园里面有10个房间,房间号从1到10
2-在游戏开始的时候,系统随机在10个房间放入老虎或者羊
3-随机给出房间号,要求游戏者选择敲门还是喂食
    1-randint(0,9)
4-敲门--只是个特权!可以不操作
    roar()---weight -= 5
5-喂食一定需要游戏者给出
6-游戏3分钟结束后,显示每个房间的动物和他们的体重
'''
class Tiger:#老虎类
    classname = 'tiger' #静态属性--类属性--整个类
    def __init__(self,weight=200):#初始化方法--构造方法
        self.weight = weight
    def roar(self):#叫声
        self.weight -= 5
        print ("wow!")
    def feed(self,food):#实例方法--带必填形参
        if food == '肉':
            self.weight += 10
            print("恭喜你,喂食正确!")
        else:
            self.weight -= 10
            print("抱歉,喂食错误!")

class Sheep():#羊类
    classname = 'sheep' #静态属性--类属性--整个类
    def __init__(self,weight=100):#初始化方法--构造方法
        self.weight = weight
    def roar(self):#叫声
        self.weight -= 5
        print ("mie!")
    def feed(self,food):#实例方法--带必填形参
        if food == '草':
            self.weight += 10
            print("恭喜你,喂食正确!")
        else:
            self.weight -= 10
            print("抱歉,喂食错误!")

class Room():#房间-类
    classname = 'room'
    def __init__(self,num,animal):
        self.num = num
        self.animal = animal

#对以上事物,进行关系组网!
from random import randint
import time
rooms = [] #空列表,存放房间实例-房间号和动物
for one in range(0,10):
    if randint(0,1) == 1:
        animal = Tiger()
    else:
        animal = Sheep()
    roomsObject = Room(one,animal)
    rooms.append(roomsObject)

startTime = time.time() #游戏开始计时
while True:
    currentTime = time.time()#游戏结束计时
    if currentTime - startTime >= 30:#大于30秒游戏结束
        print("游戏超过3分钟,游戏结束!")
        for one in rooms:
            print("第{}个房间,动物是{},体重是{}斤"
                  .format(one.num+1,one.animal.classname,one.animal.weight))
            pass
        break
    #显示随机房间号
    roomNum = randint(1,10)
    room = rooms[roomNum-1]
    isSelect = input("该房间号为{},是否需要敲门:y/n?".format(roomNum))
    if isSelect.strip() =='y' or isSelect.strip() =='n':
        if isSelect.strip() == 'y':#选择特例,让动物叫后喂食
            room.animal.roar()
        feedFood = input('请给该房间的动物喂食:肉/草?')
        if feedFood.strip()=='肉' or feedFood.strip()=='草':
            room.animal.feed(feedFood.strip())
        else:
            print('喂食食物错误!')
            continue
    else:
        print("您输入有误,进行下一次游戏!")
        continue

16. 列表去重
     方法一:将列表转化成集合,利用集合的方法set,在强制转换成列表list
list1 = [1,2,3,4,5,6,5,4,6,7,8,9]
print(list(set(list1)))
方法二:通过列表中索引(index)的方法保证去重后的顺序不变
list1 = [1,2,3,4,5,6,7,4,5,3,9]
new_list1 = list(set(list1))
new_list1.sort(key=list1.index)
print (new_list1)

以上两种list去重方法就是常用的去重方法,需要注意的是面试时如果要求保证列表的顺序时,注意set方法通过索引也能保证顺序性。