Python 命令行编程

今天分享又来了呀。ღ( ´・ᴗ・` ) 一起学习进步ღゝ◡╹)ノ♡

摘要:最近在开发etl工具,其中使用到了Python命令行编程,记录一下。

IMDG:

加油,好好学习,天天向上~ 

Q:

IMDG 重要性?

pycharm中用Terminal打开,这个目录就是项目所在的目录
D:\PythonCode\blibli\WorkTool>


Python运行程序的指令
D:\PythonCode\blibli\WorkTool>python start.py


传入第一个 参数指令
D:\PythonCode\blibli\WorkTool>python start.py hello

1 命令行编程

import sys
# 命令行编程
# 标准库 sys

# 1构建程序的框架 增加一个info指令
print('wtt')
print(sys.argv)

在终端中运行:
D:\PythonCode\blibli\WorkTool>python start.py
wtt
['start.py']

D:\PythonCode\blibli\WorkTool>python start.py hello
wtt
['start.py', 'hello']   可以看见,这是一个列表,列表里面每个元素都是字符串。第一个元素是我们程序的名字。

D:\PythonCode\blibli\WorkTool>python start.py hello word python
wtt
['start.py', 'hello', 'word', 'python']
import sys
# 命令行编程
# 标准库 sys

# 1构建程序的框架 增加一个info指令
print('wtt')
print(sys.argv)
programName=sys.argv[0] #程序的名字,保存为一个变量
print(programName)

终端执行:
D:\PythonCode\blibli\WorkTool>python start.py
wtt
['start.py']
start.py
# 工作情况分析

import sys
# 命令行编程
# 标准库 sys

# 1构建程序的框架 增加一个info指令
programName=sys.argv[0] #程序的名字,保存为一个变量

if len(sys.argv) >1:
    pass
else:
    print("命令使用:")
    print("\tpython %s 命令[params]" % programName)
---------------------------------
D:\PythonCode\blibli\WorkTool>python start.py
命令使用:
        python start.py 命令[params]
# 工作情况分析
import sys
# 命令行编程
# 标准库 sys

# 1构建程序的框架 增加一个info指令
programName = sys.argv[0]  # 程序的名字,保存为一个变量

def do_info():
    '''info指令'''
    pass

if len(sys.argv) > 1:
    command = sys.argv[1]
    print("command = %s" % command)
    if command == "info":
        do_info()# 如果命令是info,我想调用函数,执行info要做的事情
else:
    print("命令使用:")
    print("\tpython %s 命令[params]" % programName)
    print("\tpython %s info" % programName)

start1.py

# 工作情况分析
import sys
import xlrd #读取excel的第三方库

# 命令行编程
# 标准库 sys

# 1构建程序的框架 增加一个info指令

# 2给info指令增加第一个参数的实现,传入filepath;输出数据包含的月份信息

def __loadWorkList(filePath): # 私有方法,读取我们的工作簿
     wb =xlrd.open_workbook(filename=filePath)
     sheet =wb.sheet_by_index(0) #打开第一个sheet

     res=[] # 我们要获得结果,结果应该是一个list

     for i in range(sheet.nrows)[2:-1]:  #对列表进行切片。从第3行开始到倒数第二行。前面去掉2行,后面去掉一行
         #sheet.row_values(i) #获取每一行的值
         # print(sheet.row_values(i))

         res.append(sheet.row_values(i))
     return res

def do_info():
    """info指令"""
    _help ='正确的指令输入格式: python %s info filepath' %programName  # 字符串,来提示用户输入正确的命令行格式

    if len(sys.argv) >2:  # 传入的第二个指令参数,我希望是程序的路径
        filePath = sys.argv[2]
        # print(filePath) # 这行是用来测试是否获取到传入的路径的

        res =__loadWorkList(filePath)

        # months= [r[3][:7] for r in res]  # 数据日期:2020-06,2020-06,2020-06,2020-06,2020-06,2020-06
        months= {r[3][:7] for r in res}  #数据日期: 2020 - 06   推导式写法,每一行拿出来,每一行都是一个列表。取出列表的第三项,截取第三项的前7位。外面符合是{},那就是集合推导式

        # print(months)   #['2020-06', '2020-06', '2020-06']   {'2020-06'}
        print('数据日期:'+','.join(months))   #字符串的join方法,将序列中的每一个元素用,拼接起来
    else:
        print(_help)

programName=sys.argv[0]

if len(sys.argv) > 1:
    command =sys.argv[1]
    # print('command =%s'%command)
    if command=='info':
        do_info()
else:
    print('命令使用方法:')
    print("\tpython %s COMMAND [PARAMS] " % programName)
    print("\tpython %s info " % programName)

学会封装函数,让每一个函数专注于某一项功能。

知道每个函数是用来解决什么问题的。

start2.py

时间戳 代表1970年1月1日0时,到现在这个时间的间隔秒数

# 工作情况分析
import sys
import xlrd
import re

# 命令行编程

# 1 构建程序的框架 增加一个info指令
# 2 给info指令增加第一个参数的实现, filepath命令行参数。输出数据包含的月份信息
# 3 给info指令增加第二个参数        month命令行参数。   规定格式:yyyy-mm格式的字符串  表示年和月 输出每个人工作统计结果

def __loadWorkList(filePath):
    wb =xlrd.open_workbook(filename=filePath)
    sheet =wb.sheet_by_index(0)
    res=[]
    for i in range(sheet.nrows)[2:-1]:
        #print(sheet.row_values(i))
        res.append(sheet.row_values(i))
    return res

def calworktimes(date,begin,end):        # 3个形参和一个返回值
    """函数逻辑:通过日期、签到、签退时间,计算当天的加班的分钟"""
    return 1

def creatPersonData(filePath,month):
    res = __loadWorkList(filePath) # 读取内容之后,循环遍历文件的内容
    #首先要筛选,这个month的行
    res =[line for line in res if line[3][:7] ==month]  # 拿到Excel中 每一行的第三位元素(列) 截取前七位
    # print(res)

    username=None # 先把变量给定义出来,定义为临时变量
    user ={} # 用字典数据结构来保存这个人的信息
    userDataList=[] # 列表,存放所有人的记录

    for r in res:  # 遍历所有记录
        if username ==r[0]:  # 还是这个人  相同的姓名
            # 累计当前人的数据
            if r[8] =='正常' and r[9] =='正常':    # Excel中第8和9个元素(从0开始)  签到状态为‘正常’
                user ['zc'] =user ['zc']+1  # 正常 + 1
            else:
                user['qt'] = user['qt']+1  # 其他 +1

            # 没换人时,把数据给累积起来
            user ['addwork'] =user ['addwork'] +calworktimes(r[3],r[4],r[5])  # Excel处理加班时长   后面是个函数,加班时间和3个字段有关 日期、签到、签退  所以我们要传入这3个参数

        else:   # 换人了
            if username:   # 不是第一行的情况,才保存  等价于 if username !=None:
                userDataList.append(user)  # 保存   上一个人的数据  到列表中 。假如username是null,还是临时变量的时候,是不能够保存的

            # 初始化个人数据
            user ={'name':r[0],'zc':0,'qt':0,'addwork':0} # 人名 正常的天数 不正常天数 加班小时数         进行一个数据结构的封装
        username =r[0]

    for u in userDataList:
        print(u)

def do_info():
    """info指令"""
    _help ='请输入正确格式的指令: python %s info filePath [YYYY-MM]' %programName
    if len(sys.argv) >2:
        filePath = sys.argv[2]

        if len(sys.argv)>3:  #输入的第3个命令行参数   info filePath month
            month =sys.argv[3]
            print(month)
            # 统计每个人的工作数据    使用正则表达式来看看输入的参数是否满足格式的要求!
            if not re.match(r'^\d{4}-\d{2}$',month):   # 结果是false的情况下    检查月份的格式  \d表示一个数字 {4}重复4次
                print(_help) # 打印提示信息
                return # 程序一定要结束
            else:
                creatPersonData(filePath,month) # 函数   从filePath这个文件里读取month这个月份的数据

        else:
            res =__loadWorkList(filePath)
            months= {r[3][:7] for r in res}  # 推导式写法
            print('数据日期:'+','.join(months))
    else:
        print(_help)
        return #因为输出不符合我们的预期,我们一定要return来使程序结束

programName=sys.argv[0]

if len(sys.argv) > 1:
    command =sys.argv[1]
    # print('command =%s'%command)
    if command=='info':
        do_info()
else:
    print('命令使用方法:')
    print("\tpython %s COMMAND [PARAMS] " % programName)
    print("\tpython %s info FILEPATH [YYYY-MM] " % programName)

start3.py

import sys
import xlrd
import re
import datetime
# 命令行编程
# 标准库 sys

# 1 构建程序的框架 增加一个info指令
# 2 给info指令增加第一个参数的实现, filepath输出数据包含的月份信息
# 3 给info指令增加第二个参数        month 是一个yyyy-mm格式的字符串表示年和月 输出每个人工作统计结果
# 4 完善加班时间统计的方法

def __loadWorkList(filePath):
    wb = xlrd.open_workbook(filename=filePath)
    sheet = wb.sheet_by_index(0)
    res = []
    for i in range(sheet.nrows)[2:-1]:
        # print(sheet.row_values(i))
        res.append(sheet.row_values(i))
    return res

def calworktimes(date, begin, end):
    """通过日期、签到、签退时间,计算当天的加班的分钟"""
    # 我们要知道这个日期是工作日还是休息日
    # 加上int(),把返回的字符串转换成整数
    week = int(datetime.datetime.strptime(date, '%Y-%m-%d').strftime(
        '%w'))  # strptime()把字符串转换成时间戳,并且 转换成格式化时间   最后是转换成星期几,星期天是0  星期一是1

    minute = 0
    if 0 < week < 6:  # 周一到周五  也就是工作日
        if re.match(r'^\d{2}:\d{2}:\d{2}$', end):  # 判断时间格式是否正确

            b_time = datetime.datetime.strptime('17:30:00', '%H:%M:%S')  # 开始时间
            e_time = datetime.datetime.strptime(end, '%H:%M:%S')  # 结束时间

            if e_time > b_time:
                minute = (e_time - b_time).seconds // 60  # 拿到 加班的 间隔的秒数,除以60  拿到分钟
    else:  # 非工作日
        if re.match(r'^\d{2}:\d{2}:\d{2}$', begin) and re.match(r'^\d{2}:\d{2}:\d{2}$', end):  # 判断时间格式是否正确
            b_time = datetime.datetime.strptime(begin, '%H:%M:%S')
            e_time = datetime.datetime.strptime(end, '%H:%M:%S')

            if e_time > b_time:
                minute = (e_time - b_time).seconds // 60

    return minute  # 返回直接的加班时间

# calworktimes('2020-07-31',None,None)
# sys.exit(0)

def creatPersonData(filePath, month):
    res = __loadWorkList(filePath)
    res = [line for line in res if line[3][:7] == month]
    print(len(res))

    username = None
    user = {}
    userDataList = []
    for r in res:  # 遍历所有记录
        if username == r[0]:  # 还是这个人
            # 累计当前人的数据
            if r[8] == '正常' and r[9] == '正常':
                user['zc'] = user['zc'] + 1
            else:
                user['qt'] = user['qt'] + 1

            user['addwork'] = user['addwork'] + calworktimes(r[3], r[4], r[5])
        else:  # 换人了
            if username:  # 不是第一行的情况,才保存
                userDataList.append(user)  # 保存上一个人的数据

            # 初始化个人数据
            user = {'name': r[0], 'zc': 0, 'qt': 0, 'addwork': 0}
        username = r[0]

    with open('data/' + month + '.txt', 'w') as df:  #保存下来,在当前目录下,子目录data,以month为名字的txt文件。覆盖内容w。
        for u in userDataList: # u 是一个对象,还不能直接往文件里写入。需要格式化下
            linestr = '{}|{}|{}|{}'.format(u['name'], u['zc'], u['qt'], u['addwork'])  # 用 |进行分割
            df.write(linestr + '\n') # 每行有换行符

def do_info():
    """info指令"""
    _help = '指令格式: python %s info FILEPATH [YYYY-MM]' % programName
    if len(sys.argv) > 2:
        filePath = sys.argv[2]

        if len(sys.argv) > 3:
            month = sys.argv[3]
            # 统计每个人的工作数据
            if not re.match(r'^\d{4}-\d{2}$', month):  # 检查月份的格式
                print(_help)
                return
            else:
                creatPersonData(filePath, month)

        else:
            res = __loadWorkList(filePath)
            months = {r[3][:7] for r in res}  # 推导式写法
            print('数据日期:' + ','.join(months))
    else:
        print(_help)
        return

programName = sys.argv[0]

if len(sys.argv) > 1:
    command = sys.argv[1]
    # print('command =%s'%command)
    if command == 'info':
        do_info()
else:
    print('命令使用方法:')
    print("\tpython %s COMMAND [PARAMS] " % programName)
    print("\tpython %s info FILEPATH [YYYY-MM] " % programName)

注意,出现报错

FileNotFoundError: [Errno 2] No such file or directory: 'data/2020-06.txt'

解决方法:
自己在项目中新建个文件夹 data。

python start3.py info e:\6.xls 2020-06

start4.py

# 工作情况分析
import sys
import xlrd
import re
import datetime


# 命令行编程
# 标准库 sys


# 1 构建程序的框架 增加一个info指令
# 2 给info指令增加第一个参数的实现, filepath输出数据包含的月份信息
# 3 给info指令增加第二个参数        month 是一个yyyy-mm格式的字符串表示年和月 输出每个人工作统计结果
# 4 完善加班时间统计的方法
# 5 增加对假期特殊的处理


__以下是对数据获取和加工的功能的代码___


def __loadWorkList(filePath):
    wb =xlrd.open_workbook(filename=filePath)
    sheet =wb.sheet_by_index(0)
    res=[]
    for i in range(sheet.nrows)[2:-1]:
        # print(sheet.row_values(i))
        res.append(sheet.row_values(i))
    return res


def loadHoliday():
    res =[]
    with open('data/holiday.txt','r') as hf :  # 读取出来
        for line in hf.readlines():
            _holiday =line.split('|')[0]
            _week = line.split('|')[1]
            _type = line.split('|')[2].strip()  # 去掉回车符号


            #周一到周五,并且是休息日
            if (0<int(_week)<6 and _type.lower() =="h") or \
                    ((int(_week)==0 or int(_week)==6) and _type.lower())=='w': # 周六 周日 工作日
                res.append(_holiday)
    return res


def calworktimes(date,begin,end):
    """通过日期、签到、签退时间,计算当天的加班的分钟"""
    # 我们要知道这个日期是工作日还是休息日
    week =int(datetime.datetime.strptime(date,'%Y-%m-%d').strftime('%w'))
    minute =0
    holidays =loadHoliday()
    # 周一到周五 非休息日   和   周六周日 的工作日
    if (0< week <6 and date not in holidays) or ((week==0 or week==6) and date in holidays):  # 不在假期的列表里        满足这些条件的,就是  工作日
        if re.match(r'^\d{2}:\d{2}:\d{2}$',end):
            b_time =datetime.datetime.strptime('17:30:00','%H:%M:%S')
            e_time =datetime.datetime.strptime(end,'%H:%M:%S')


            if e_time>b_time:
                minute =(e_time-b_time).seconds //60


            minute = minute if minute > 60 else 0  # 三元表达式   只有加班时间大于60分钟才算加班,否则时长就是0


    else:
        if re.match(r'^\d{2}:\d{2}:\d{2}$',begin) and re.match(r'^\d{2}:\d{2}:\d{2}$', end):
            b_time = datetime.datetime.strptime(begin, '%H:%M:%S')
            e_time = datetime.datetime.strptime(end, '%H:%M:%S')


            if e_time>b_time:
                minute =(e_time-b_time).seconds //60


            minute = minute if minute <480 else 480  # 非工作日,做多加班480分钟


    return minute


# calworktimes('2020-07-31',None,None)
# sys.exit(0)


def creatPersonData(filePath,month):
    res = __loadWorkList(filePath)
    res =[line for line in res if line[3][:7] ==month]
    # print(res)


    username=None
    user ={}
    userDataList=[]
    for r in res:  # 遍历所有记录
        if username ==r[0]:  # 还是这个人
            # 累计当前人的数据
            if r[8] =='正常' and r[9] =='正常':
                user ['zc'] =user ['zc']+1
            else:
                user['qt'] = user['qt']+1


            user ['addwork'] =user ['addwork'] +calworktimes(r[3],r[4],r[5])
        else:   # 换人了
            if username:   # 不是第一行的情况,才保存
                userDataList.append(user)  # 保存上一个人的数据


            # 初始化个人数据
            user ={'name':r[0],'zc':0,'qt':0,'addwork':0}
        username =r[0]
    with open('data/'+month+'.txt','w') as df:
        for u in userDataList:
            linestr ='{}|{}|{}|{}'.format(u['name'],u['zc'],u['qt'],u['addwork'])
            df.write(linestr+'\n')


def do_info():
    """info指令"""
    _help ='指令格式: python %s info FILEPATH [YYYY-MM]' %programName
    if len(sys.argv) >2:
        filePath = sys.argv[2]


        if len(sys.argv)>3:
            month =sys.argv[3]
            # 统计每个人的工作数据
            if not re.match(r'^\d{4}-\d{2}$',month):   # 检查月份的格式
                print(_help)
                return
            else:
                creatPersonData(filePath,month)


        else:
            res =__loadWorkList(filePath)
            months= {r[3][:7] for r in res}  # 推导式写法
            print('数据日期:'+','.join(months))
    else:
        print(_help)
        return


def do_addholiday():   # 增加节假日
    _help ='正确的指令格式: python %s addholiday YYYY-MM-DD TYPE(w:上班 h:休息)'%programName
    if len(sys.argv) >3:
        _holiday =sys.argv[2]  #下划线开头,明确表示这个是局部变量
        _type =sys.argv[3]


        if not re.match(r'^\d{4}-\d{2}-\d{2}$',_holiday):  # 检查月份的格式   如果不是我们希望的日期参数格式
            print(_help)
            return
        if _type.lower() !='w' and _type.lower() !='h':  # 让type不区分大小写
            print(_help)
            return
    else:
        print(_help)
        return
    # 将新增的日期放置文件的末尾  希望有个文件来存储我们节假日的信息
    holiday_file ='data/holiday.txt'


    with open(holiday_file,'a+') as hf :  # 往文件的末尾去添加
        hf.write('{}|{}|{}\n'.format(_holiday,datetime.datetime.strptime(_holiday,'%Y-%m-%d').strftime('%w'),_type)) # 往文件的最后一行追加  并且增加每行数据时添加换行符
        print('增加新的假日:{}{}'.format(_holiday,_type))


def do_listholiday():
    with open('data/holiday.txt','r') as hf:   # 只读的方式打开文件
        for line in hf.readlines():
            print('日期:{} 星期 {}{}'.format(line.split('|')[0],line.split('|')[1],
                                        '工作日' if line.split('|')[2].strip()=='w' else "休息日")) # 根据w或者其他的字符,写文字  工作日  or   休息日


programName=sys.argv[0]


if len(sys.argv) > 1:
    command =sys.argv[1]
    # print('command =%s'%command)
    if command=='info':
        do_info()
    elif command=='addholiday':
        do_addholiday()
    elif command == 'listholiday':
        do_listholiday()
else:
    print('命令使用方法:')
    print("\tpython %s COMMAND [PARAMS] " % programName)
    print("\tpython %s info FILEPATH [YYYY-MM] " % programName)
    print("\tpython %s addholiday YYYY-MM-DD TYPE(w:上班 h:休息)] " % programName)
    print("\tpython %s listholiday " % programName)


- END -

本文为原创文章

❤:在这里跟我一起学习技术、职场、人生、原理、健身、摄影、生活等知识吧!

❤: 欢迎点个关注一起学习,进步充实人生。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值