freeCodeCamp----arithmetic_arranger练习

目录

1 题目

2 指定要求

3 思路分析

3.1 拆分输入参数

3.2 判断是否满足打印条件

3.3 打印排版(对齐)

3.4 第二个参数为True

3.5 arithmetic_arranger函数

3 arithmetic_arranger.py

4 常见的报错


1 题目

简单说就是打印加减运算的竖式计算

2 指定要求

  1. 两个参数,第一个参数为要计算的数据,第二个参数为bool值,TRUE需要同时打印竖式的计算结果,FALSE则不需要;
  2. 一次最多输入5组数据,超过则返回:Error: Too many problems.
  3. 运算符仅支持加减法,其他返回:Error: Operator must be '+' or '-'.
  4. 输入计算的数据(operand)仅支持数字,否则返回:Error: Numbers must only contain digits.
  5. 最大支持4位数的运算,否则返回:Error: Numbers cannot be more than four digits.

3 思路分析

大体思路就是先写个打印一个竖式的函数basic_num(),然后arithmetic_arranger()根据传入的参数,依次调用打印的函数basic_num(),

3.1 拆分输入参数

根据测试用例分析思路:

arithmetic_arranger(["32 + 8", "1 - 3801", "9999 + 9999", "523 - 49"], True)

先不考虑第二个参数,将第一个参数当成一个二维数组blocks=[block1,block2,block3...]且长度不能超过5,即len(blocks)<5;  

arithmetic_arranger(blocks,result)

此时第一个参数中block的每个元素都是string类型(例如:"32 + 8"),将每个string按空格依次拆分成operand[0]、operator和operand[1],并存入block数组中(例:block = [ 32 , '+' , 8 ] ),其中operand只能是数字,且最大是4位数len(operand)<4,operator只能是+或者-号;

此时:

block=[operand[0],operator,operand[1]]

3.2 判断是否满足打印条件

先判断是否满足条件,一旦不满足后续的代码均不用执行,直接打印错误。

输入计算的数据(operand)仅支持数字,否则返回:Error: Numbers must only contain digits.

# 若operand超过2个或者operator超过一个,说明有非数字输入
    if len(operand) > 2 or len(operator) > 1:
        return "Error: Numbers must only contain digits."

最大支持4位数的运算,否则返回:Error: Numbers cannot be more than four digits.

# operand本身长度就2,里面有2个数字,operand[0]和operand[1]
    # 两个数字最大都只接受4位数的运算,长度超过4位就报错
    if len(operand[0]) > 4 or len(operand[1]) > 4:
        return "Error: Numbers cannot be more than four digits."

运算符仅支持加减法,其他返回:Error: Operator must be '+' or '-'.

# 运算符只支持+和-
# 这里使用operator[0]的原因是,operator本身是个数组,operator[0]是个元素,且是个字符串
    if operator[0] not in ('+', '-'):
        return "Error: Operator must be '+' or '-'."

剩下两个要求,需要在上层arithmetic_arranger()函数中判断。

3.3 打印排版(对齐)

一个竖式显示大概是下面这样的:

 

我们将显示分成4行,宽度定为最大数字宽度再加两位即 maxlen+2 ,一个留给运算符,另一位作为空格,防止有进位产生。

第一行是operand[0];第二行是operator[0]+空格+operand[1];第三行是分割线'-',长度为maxlen+2,第四行是计算的结果(如果有的话),这四行都需要靠右对齐。

block = [operand[0].rjust(maxlen + 2), operator[0]+' '+operand[1].rjust(maxlen), '-'*(maxlen+2)]

3.4 第二个参数为True

此时给block添加第四行

block.append(str(int(operand[0]) + int(operand[1])).rjust(maxlen + 2))

添加的一行分两种情况,运算符为+或者-,步骤都是先根据运算符计算结果,然后长度maxlen+2,靠右对齐。

不用担心结果超过6位的情况,因为rjust()函数中,若指定的长度小于字符串的长度则返回原字符串。

3.5 arithmetic_arranger函数

基本打印函数完成后,arithmetic_arranger根据传入的参数依次调用,在调用前需要先判断传入的数据,一次最多输入5组数据,超过则返回:Error: Too many problems.

这个不难,判断长度即可。

接下来就是判断第二个参数是否为True,若是,basic_num()打印函数就是4行,包括结果行,否则就是3行。

没什么可写的,注意的点有:

1.竖式虽然是竖着显示的,但是打印时是横着打印的,第一行就是第一个竖式的第一行+第二个竖式的第一行+第三个竖式的第一行+……依次是第二行;

2.两个竖式之间应该添加4个空格作为分隔,具体加在哪个位置,见源码;

3.每一行结束记得添加换行符,不然全部堆在一行显然是不正确的;

3 arithmetic_arranger.py

arithmetic_arranger.py源码见下文

内容有参考博主:FreeCodeCamp----Scientific Computing with Python Projects----Arithmetic Formatter_m0_43406494的博客-CSDN博客AssignmentStudents in primary school often arrange arithmetic problems vertically to make them easier to solve. For example, “235 + 52” becomes: 235+ 52-----Create a function that receives a list of strings that are arithmetic problems and returns https://blog.csdn.net/m0_43406494/article/details/112731471?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163633257116780264054904%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=163633257116780264054904&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-1-112731471.first_rank_v2_pc_rank_v29&utm_term=Students+in+primary+school+often+arrange+arithmetic+problems+vertically+to+make+them+easier+to+solve.+For+example%2C+%22235+%2B+52%22+becomes%3A&spm=1018.2226.3001.4187


注释已经写的很明白了,如下: 

# def arithmetic_arranger(problems):


#     return arranged_problems
# 引入 re 模块使 Python 语言拥有全部的正则表达式功能
import re
# 单个problem的函数,多个problems时可依次调用此函数,a的形式为'21 + 23'
def basic_num(a, xxx):
    # re.findall(pattern, string)
    # 在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。
    # operand筛选出数字
    # operator找出运算符号
    operand = re.findall(r'\d+', a)
    operator = re.findall(r'[^\d ]', a)

    # 根据题意分析:
    # 若operand超过2个或者operator超过一个,说明有非数字输入
    if len(operand) > 2 or len(operator) > 1:
        return "Error: Numbers must only contain digits."

    # operand本身长度就2,里面有2个数字,operand[0]和operand[1]
    # 两个数字最大都只接受4位数的运算,长度超过4位就报错
    if len(operand[0]) > 4 or len(operand[1]) > 4:
        return "Error: Numbers cannot be more than four digits."

    # 运算符只支持+和-
    if operator[0] not in ('+', '-'):
        return "Error: Operator must be '+' or '-'."

    # 找出最大长度,为后面对齐做准备
    # 用最大长度加两位宽度,一位留给运算符,一位作为空格防止加法进位和减法出现负数的情况
    maxlen = max(len(operand[0]), len(operand[1]))

    # rjust()返回一个原字符串右对齐,并使用fillchar填充至长度width的新字符串
    # 如果指定的长度小于字符串的长度则返回原字符串
    # width--指定填充后的总长度;fillchar--填充的字符,默认为空格
    # str.rjust(width[, fillchar])
    # 输出block分成三行显示:
    # 第一行为第一个数字operand[0],长度为maxlen+2(多出来的两位,一个给运算符,另一个用作空格),靠右对齐
    # 第二行开头就是运算符operator[0],接着是空格,最后是第二个数字,长度为maxlen,靠右对齐
    # 第三行全部为'-',作为分割线,长度为maxlen+2,靠右对齐
    # 注意这里operator是一个数组,要拼接的话必须使用里面的元素
    block = [operand[0].rjust(maxlen + 2), operator[0]+' '+operand[1].rjust(maxlen), '-'*(maxlen+2)]

    # 如果第二个参数为TRUE,就需要将block添加一行
    # 添加的一行分两种情况,运算符为+或者-,步骤都是先根据运算符计算结果,然后长度maxlen+2,靠右对齐
    # 不用担心结果超过6位的情况,因为rjust()函数中,若指定的长度小于字符串的长度则返回原字符串
    if xxx == True:
        if operator[0] == '+':
            block.append(str(int(operand[0]) + int(operand[1])).rjust(maxlen + 2))
        if operator[0] == '-':
            block.append(str(int(operand[0]) - int(operand[1])).rjust(maxlen + 2))
    # print(block)
    return block

# 定义竖式函数
# 思路如下:
# 先判断第一个参数中元素是否超过5个,若超过,返回错误(题目要求一次最多计算5个竖式)
# 遍历problems中的所有元素,basic_num函数,返回的block依次存入blocks数组中,
def arithmetic_arranger(problems, result = False):
    if len(problems) > 5:
        return "Error: Too many problems."
    if result:
        count = 4
    else:
        count = 3
    # 定义二维数组blocks,因为里面的每个元素block都是一维数组
    blocks = []
    for s in problems:
        blocks.append(basic_num(s, result))
        # 若出现报错,则直接退出,输出错误内容
        # 这里需要主意的是,判断的是blocks[-1],因为错误可能出现在第一组或者最后一组,不管哪个位置都是最后一个元素
        # 同时判断blocks[-1]的类型是否为字符串,因为正确情况下的是list
        print(blocks)
        if (type(blocks[-1]) == str):
            return blocks[-1]
    arranged_problems = ''
    for i in range(count):
        for j in blocks:
            arranged_problems += j[i]+(' '*4)
            # 下面的判断是为了到每一行结尾时,不添加上一步的空格
            if j == blocks[-1]:
              arranged_problems = arranged_problems[0:-4] #不包含-4位置
        arranged_problems += '\n'
    # 使用[0:-1]是为了去掉最后一行的空行
    return arranged_problems[0:-1]


# if __name__ == "__main__":
#     print(arithmetic_arranger(["11222 + 815", "454 - 8125", "123 - 49", "888 - 40", "653 + 87"], True))




4 常见的报错

  1. Error的打印,注意连空格和标点符号都要和题目要求保持一致,不然测试时会出错,找半天找不到问题所在;
  2. 注意隐藏的空格,比如每一行结尾是不是也加上了4个空格?测试的时候也不能通过的;
  3. 注意最后一行的空行,需要去掉,不然也不能通过测试;
  4. 第二个参数需要设置默认值为False,避免未给定第二个参数时报错。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值