女神博客链接:https://www.cnblogs.com/Eva-J/articles/11266790.html?tdsourcetag=s_pcqq_aiomsg#_label6

# 1.注册一个账号,创建一个自己的博客主页
# 你的博客主页贴给我们的
# 每一周-两周 有一篇产出

# 2.递归函数 - 三级菜单
# 递归函数 - 二分查找

# 3.random 实现一个验证码,可以是4位或者6位,可以是纯数字,数字+字母


# 大作业:re模块和正则表达式 循环 不推荐用递归
exp = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
# exp = 2*3
# exp = 2+3
# exp = 2-3
# exp = 2/3

# 2+3*5

# print(eval(exp))
# 通过正则表达式 匹配出"内部不再有小括号的表达式" 9-10/3 + 7 /3*99/4*2998 +10 * 568/14
# 匹配第一个乘法或者除法 '2*5'
# 计算这个表达式的结果
# 循环一直到所有的乘除法都计算完毕

# 处理加减法
# 匹配第一个乘法或者除法 '2*5'
# 计算这个表达式的结果
# 循环一直到加减法也都计算完毕

# 基本需求 :只考虑整数 和 加减乘除四则运算
# 进阶需求 :考虑小数 和 加减乘除+()

# -*- coding:utf-8 -*-
# caiqinxiong
#蔡亲雄的博客:https://www.cnblogs.com/hulk-1029/

menu = {
    '北京': {
        '海淀': {
            '五道口': {
                'soho': {},
                '网易': {},
                'google': {}
            },
            '中关村': {
                '爱奇艺': {},
                '汽车之家': {},
                'youku': {},
            },
            '上地': {
                '百度': {},
            },
        },
        '昌平': {
            '沙河': {
                '老男孩': {},
                '北航': {},
            },
            '天通苑': {},
            '回龙观': {},
        },
        '朝阳': {},
        '东城': {},
    },
    '上海': {
        '闵行': {
            "人民广场": {
                '炸鸡店': {}
            }
        },
        '闸北': {
            '火车战': {
                '携程': {}
            }
        },
        '浦东': {},
    },
    '山东': {},
}
choise_list = []
def threeLevelMenu(menu):
    '''
    三级菜单
    :param menu:
    :return:
    '''
    while True:
        # 打印字典
        print('~'*20)
        for name in menu:
            print(name)

        choise = input('请选择:').strip()
        if choise in menu.keys() and menu[choise]:
            if not choise in choise_list:
                choise_list.append(choise)
            threeLevelMenu(menu[choise]) # 递归调用,相当于循环,调用了几次,就需要几个return才能结束。
        elif 'B' == choise.strip().upper():
            #print(choise_list)
            if len(choise_list) == 0:
                print('~' * 20)
                print('\033[31;1m已经是最顶层啦!\033[0m')
            else:
                print('~' * 20)
                print('\033[34;1m返回上层啦!\033[0m')
                choise_list.pop()
                return choise
        elif 'Q' == choise.strip().upper():
            print('\033[36;5m谢谢使用!\033[5m')
            exit(-1)
        else:
            try: # 处理key值异常 # 可以用字典的get方法
                if menu[choise] == {}:
                    print('~' * 20)
                    print('\033[31;1m已经是最底层啦!返回上层按b,退出按q!\033[0m')
            except:
                print('输入有误,请重新输入!')


if __name__ == '__main__':
    print('~' * 20)
    print('\033[36;5m欢迎使用三级菜单小程序!\033[5m')
    threeLevelMenu(menu)
三级菜单_递归
# -*- coding: utf-8 -*-
# 2019/8/5 11:07
#参考女神博客链接:https://www.cnblogs.com/Eva-J/articles/7197403.html

def binary_search(num,list_info,start=None,end=None):
    '''
    二分查找
    :param num:要查找的数
    :param list_info:列表信息
    :param start: 搜索开始index值
    :param end:搜索结束index值
    :return:搜索到时返回该数在列表中的index值,否则返回None
    '''
    start = start if start else 0 # 三元运算,如果搜索开始位置不为零,则将新值赋给start。
    end = end if end is not None else len(list_info) - 1 # 三元运算,如果搜索结束位置不为空,则将列表最后的索引值给end,len(list_info) - 1为list最后的索引值,因为index从0开始
    mid = (end - start)//2 + start # 获取中间位置的index值,这里用了地板除,确保能获取到整数。
    if start > end: # 搜索开始index值大于结束index值,说明已将list搜索完成。
        return None
    elif list_info[mid] > num : # 如果中间索引的数大于要搜索的数,则要查找的数在二分的前面,将mid-1赋值给end。再继续递归查找。
        return binary_search(num,list_info,start,mid-1) # 递归调用
    elif list_info[mid] < num: # 如果中间索引的数小于要搜索的数,则要查找的数在二分的后面,将mid-1赋值给start。再继续递归查找。
        return binary_search(num,list_info,mid+1,end) # 递归调用
    elif list_info[mid] == num: # 如果中间索引的数刚好等于要搜索的数,则返回搜索结果。
        return mid

while True:
    list_info = [2,3,5,7,9,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88,93,100]
    print('列表信息如下:\n',list_info)
    choise = input('请输入要查找的数:').strip()
    if choise.isdigit():
        choise = int(choise)
        ret = binary_search(choise,list_info)
        if ret != None:
            print('\033[31;1m%s\033[0m在搜索列表里的第\033[31;1m%s\033[0m个位置!' % (choise,list_info.index(choise)+1))
        else:
            print('\033[31;1m%s\033[0m不在搜索列表里' % choise)
        break
    else:
        print('输入有误,请重新输入!')
二分查找_递归
# -*- coding: utf-8 -*-
# 2019/8/5 13:56
# 参考女神博客链接:https://www.cnblogs.com/Eva-J/articles/11266790.html?tdsourcetag=s_pcqq_aiomsg#_label6
import random

# 女神版
def verification_code():
    '''生成随机验证码'''
    code = ''  # 初始化验证码的值为空
    for i in range(4):  # 循环获取4个随机数,生成4位随机验证码
        num = random.randint(0, 9)  # 生成0-9的随机数
        alf = chr(random.randint(65, 90))  # 随机生成大小写字母,通过字母的ascii值获取
        tmp = random.choice([num, alf])  # 随机在数字和字母中获取一位字符
        # code = "".join([code, str(tmp)])  # 将随机获取的字符拼接
        code +=str(tmp)

    return code

yan = verification_code()
print("生成的4位随机验证码为:", yan)

# 小白版
yan=''
for i in range(4):
    #current=random.randint(0,9) #生成0-9的随机数
    current=random.randrange(0,4) # 生成0-4的随机数,如果和i相等,随机添加字母或数字
    if current == i:
        tmp = chr(random.randint(65,90))
    else:
        tmp = random.randint(0,9)
    yan+=str(tmp)
print("生成的4位随机验证码为:", yan)
生成随机验证码
# -*- coding: utf-8 -*-
__author__ = 'caiqinxiong_cai'
# 2019/8/2 17:00
import re


def multiply_divide_compute(exp):
    '''乘除计算'''
    num_list = re.split("[*/]", exp)  # 根据*或/号切割式子,得到各个数字的list,如['7/3*99/4*2998']切割后为['7', '3', '99', '4', '2998']
    symbol = re.findall("[*/]", exp)  # 再获取一一对应的计算符号,['/', '*', '/', '*']
    ret = float(num_list[0])  # 从左到右依次计算,list第一个值赋给ret,然后去*或/下一个数,返回计算结果。
    for n in range(1, len(num_list)):
        if symbol[n - 1] == "*":
            ret *= float(num_list[n])
        elif symbol[n - 1] == "/":
            ret /= float(num_list[n])
    return ret


def add_subtract_compute(symbol, num_list):
    '''计算加减'''
    ret = float(num_list[0])  # 从左到右依次计算,list第一个值赋给ret,然后去+或-下一个数,返回计算结果。
    for n in range(1, len(num_list)):
        if symbol[n - 1] == "+":
            ret += float(num_list[n])
        elif symbol[n - 1] == "-":
            ret -= float(num_list[n])
    return ret


def change_symbol(exp):
    '''处理符号'''
    exp = exp.replace("++", "+")
    exp = exp.replace("+-", "-")
    exp = exp.replace("-+", "-")
    exp = exp.replace("--", "+")
    exp = exp.replace("- -", "+")
    exp = exp.replace("+ -", "-")
    return exp


def reduction_formula(symbol, multiply_divide):
    '''还原算式'''
    # 处理乘除算式中前面带负号的情况
    if len(multiply_divide[0].strip()) == 0:  # 切割后的list第一个值如果为空,则为负号,如-40/5切割后为['', '40/5']
        multiply_divide[1] = symbol[0] + multiply_divide[1]
        del multiply_divide[0]  # 把list的第一个空值删除掉
        del symbol[0]  # 负号已经拼接到上面的式子里了,所以要删除掉多余的负号。
    # 处理乘除算式中后面带负号的情况
    for index, f in enumerate(multiply_divide):
        # 9-2*5/3+7/3*99/4*-2998 +10 * 568/14 切割后为['9', '2*5/3 ', ' 7 /3*99/4*', '2998 ', '10 * 568/14 '],循环list处理。
        f = f.strip()  # 去除算式中的左右空格
        if f.endswith("*") or f.endswith("/"):  # 如果以*或/结尾的式子,说明后面带-号被切割了,给还原一下。
            multiply_divide[index] = multiply_divide[index] + symbol[index] + multiply_divide[
                index + 1]  # 如:['', '40/', '5']还原为 ['-40/-5']
            del multiply_divide[index + 1]  # 将已拼接的值删除掉
            del symbol[index]  # 对应的负号也删除掉
    return symbol, multiply_divide


def compute(exp):
    '''计算'''
    # 先计算乘除,后算加减。
    multiply_divide = re.split("[+-]", exp)  # 按+或-切割,取出乘除算式,返回list。-40/5切割后为['', '40/5'],-40/-5切割后为['', '40/', '5']
    symbol = re.findall("[+-]", exp)  # 获取所有的+和—号,返回list,和上面的split的个数对应。-40/-5得到的值为['-', '-']
    symbol, multiply_divide = reduction_formula(symbol, multiply_divide)  # 调用符号处理函数,返回处理后的结果。
    # 开始计算乘除
    for index, f in enumerate(multiply_divide):  # 可能有多个,循环计算,如['9', '2*5/3 ', ' 7 /3*99/4*-2998 ', '10 * 568/14 ']
        if re.search("[*/]", f):  # 只计算乘除的式子,没有返回None。
            multiply_divide[index] = multiply_divide_compute(f)  # 调用乘除计算函数,每次传入的是只带*或/的式子,将计算结果返回对应的list中,如['-40/5']计算完返回['-8.0']

    # 开始计算加减
    # print(symbol,multiply_divide) #如['-', '+', '+'] ['9', 3.3333333333333335, -173134.50000000003, 405.7142857142857]
    ret = add_subtract_compute(symbol, multiply_divide)  # 将对应的+-符号和计算完乘除后的list再进行加减运算,返回最终的计算结果。
    return ret


def main(exp):
    '''主控制逻辑'''
    while True:
        parentheses = re.search("\([^()]*\)", exp)  # [^()]*表示不包含任意一个口号,既匹配最里层的括号,从右往左,匹配第一个。
        # print(parentheses) # 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
        if parentheses != None:
            f = parentheses.group().strip("()")  # 去掉拓号,只保留算式。
            ret = compute(f)  # 计算括号里的式子并返回计算结果
            exp = exp.replace(parentheses.group(), str(ret))  # 计算完成后,把括号里的内容替换成计算结果
            exp = change_symbol(exp)  # 一个括号计算完成后可能产生负号,处理+-号,例如计算完第一个括号的结果为-8.0,1 - 2 * ( (60-30 +-8.0 * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) ),带了+-号。
        else:
            ret = compute(exp) # 没有括号了,直接计算剩下的数即可
            return ret


if __name__ == '__main__':
    # exp = '(-40/5)'
    # exp = '( 7 /3*99/4*2998 )'
    # exp = '(9-2*5/3 + 7 /3*99/4*-2998 +10 * 568/14 )'
    exp = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
    ret = main(exp)
    print('算式%s的计算结果为:\n%s' % (exp, ret))
计算器

 

posted on 2019-08-06 14:50  雨之夜&秋  阅读(100)  评论(0)    收藏  举报