如何实现判断功能

Yanni / 2023-07-29 / 原文

如何实现判断功能

1.先大体将条件列出来,然后想清楚要进行的操作是什么,把代码连带问题询问GPT

import json

str = '{"Keyword":"GZM",' \
      '"S_No":"16",' \
      '"S_Name":"12011",' \
      '"S_mc_name":"二煤",' \
      '"S_Cg_h":4.5,' \
      '"S_cmfs":"综采",' \
      '"S_Fm_h":0,' \
      '}' # 这是一个json的字符串


class TBase(object): # 定义了一个类
    def __init__(self): # 类的初始化
        self.Visible = True # self.表示调用自己的变量
        self.Enabled = True
        self.Keyword = ''
        self.Name = ''

    def Base_Input(self, str):
        data = json.loads(str) # 把json的字符串赋给一个实体,json.loads()是一个用于解析JSON字符串的函数,它接受一个JSON格式的字符串作为参数,并返回一个对应的Python对象。

要实现:如何判断上述代码块中str里面的变量有keyword,如果有就赋给self.keyword如果没有就退出程序

以下为询问gpt后得到的结果

import json
import sys

str_value = '{"Keyword":"GZM",' \
      '"S_No":"16",' \
      '"S_Name":"12011",' \
      '"S_mc_name":"二煤",' \
      '"S_Cg_h":4.5,' \
      '"S_cmfs":"综采",' \
      '"S_Fm_h":0' \
      '}'

class TBase(object):
    def __init__(self):
        self.Visible = True
        self.Enabled = True
        self.Keyword = ''
        self.Name = ''

    def Base_Input(self, input_str):
        data = json.loads(input_str)
        if 'Keyword' in data:
            self.Keyword = data['Keyword']
        else:
            sys.exit("关键字丢失,程序退出")
            
# 举例
obj = TBase()
obj.Base_Input(str_value)

# 现在可以访问 obj.Keyword 属性来获取值
print(obj.Keyword)

这个例子已经给好了,下面就可以修改自己的代码了

import json
import sys


class TBase(object):
    def __init__(self):
        self.Age = 0
        self.Height = 0.0
        self.Keyword = ''  # *
        self.Name = ''

    def Base_Input(self, input_str):
        data = json.loads(input_str)
        # 如何判断str里面的变量有keyword,如果有就赋给self.keyword如果没有则退出
        if 'Keyword' in data:
            self.Keyword = data['Keyword']
        else:
            sys.exit("Error:Keyword丢失")  # Keyword如果没有,就退出

        if 'Name' in data:
            self.Name = data['Name']
        else:
            print("Error:Name丢失")
            self.Name = '张三'  # Name如果没有,就给它赋个初值

        if 'Height' in data:
            self.Height = data['Height']
        else:
            print("Error:Height丢失")
            self.Height = 1.7  # Height如果没有,就给它赋个初值

        if 'Age' in data:
            if 1 <= data['Age'] <= 100:
                self.Age = data['Age']
            else:
                print("Error: Age超出范围")
                self.Age = 20
        else:
            print("Error: Age丢失")
            self.Age = 20  # Age如果没有,就给它赋个初值


t_base = TBase()
str_value = '{"Keyword":"GZM",' \
            '"Name":"李四",' \
            '"Height":"1.6",' \
            '"Age":170' \
            '}'

t_base.Base_Input(str_value)
# 现在可以访问 obj.Keyword 属性来获取值
print({
    'Keyword': t_base.Keyword,
    'Name': t_base.Name,
    'Height': t_base.Height,
    'Age': t_base.Age
})

这里介绍一下三元表达式

value_if_true if condition else value_if_false

比如上述代码判断Keyword可以转化为:

self.Keyword = data['Keyword'] if ('Keyword' in data) else exit("Error:Keyword丢失")

解读:如果关键字在data里,就把关键字的值赋给Keyword,否则就退出并返回错误信息(Error:Keyword丢失),三元表达式的前面是成功的操作,中间是条件,后面是错误的结果

这仅仅是画好了例子的样子,接下来才是运用它,照着它的样子来写其他的代码

一些代码的解读:
self.S_cmfs = data['S_cmfs'] if ('S_cmfs' in data) else exit('报错:采煤方式不能为空')
# 如果S_cmfs的值为空或找不到S_cmfs该变量,则直接退出程序并报错
self.S_Fm_h = data['S_Fm_h'] if ('S_Fm_h' in data) else 0.0
# 如果S_Fm_h的值为空或找不到S_Fm_h该变量,则为其赋个初值0.0
  • 上述两种方法的区别就在于,一种是程序直接不能运行下去,直接报错退出,另一种则是为其赋值,保证这个程序能进行下去,且赋的值一般的合理的。
def S2_Input(self, input_str):

        Gzm_info = input_str.replace('GZM:', '').split(',')
  • S2_Input(self, input_str)是一个方法,它接受一个字符串 input_str 作为参数,

首先,使用 input_str.replace('GZM:', '') 将字符串中的 ‘GZM:’ 替换为空字符串,也就是去掉(GZM:)然后使用 split(',') 方法将剩下的字符串按照逗号进行拆分,得到一个包含拆分后的子字符串的列表,赋值给变量 Gzm_info

def S2_Input(self, input_str):
    Gzm_info = input_str.replace('GZM:', '').split(',')
str2_1 = "GZM:16,12011,二煤,4.5,综采,0,3.4,600,214,1640,100,1,25,20000,0.3,2,3"

这种是文本字符串输入的方法,同理代码表示将(GZM:)去掉,并使用 split(',') 方法将剩下的字符串按照逗号进行拆分的功能,这种方法在进行判断操作时,采用顺序的方法来对一个一个变量判断

        if len(Gzm_info) < 17:
            exit("报错:缺少必要的变量")
        try:
            self.S_No = Gzm_info[0].strip()
            self.S_Name = Gzm_info[1].strip()
            self.S_mc_name = Gzm_info[2].strip()
            self.S_Cg_h = float(Gzm_info[3])

其中,strip()方法表示将空格去掉

        if str.startswith("{") and str.endswith("}"):
            # 第一种,json输入方法
            if not self.Ex_Gzm.Base_Input(str): sys.exit()

这种是json结构输入的方法,startswith()函数是用于检查一个字符串是否以指定的前缀开头的方法。它接受一个参数作为前缀,并返回一个布尔值,表示字符串是否以该前缀开头

执行完Base_Input函数后,返回值是true,第二行代码表示,如果不是真的,则直接退出程序

def value_ES_Input(self, data):
    self.value_S_Input(data)
  • self.value_S_Input(data)继承value_ES_Input(self, data)的一些方法,作用是如果两个方法内有重复的变量,则ES_input方法中可以不用写这些变量,直接使用S_input方法里的就行,这就是继承的好处
# 将S_cmfs的字符串转换为数值
    def Get_CmFs_StrtoValue(self, Cmfs_Hanzi): # Cmfs_Hanzi是形参,也是自变量,self.S_cmfs是因变量
        if Cmfs_Hanzi == '普采':
            self.S_cmfs = 1
        elif Cmfs_Hanzi == '综采':
            self.S_cmfs = 2
        else:
            self.S_cmfs = 3
# 将S_cmfs的数值转换为字符串
    def Get_CmFs_ValuetoStr(self, Cmfs_Shuzi):
        if Cmfs_Shuzi == 1:
            self.S_cmfs = '普采'
        elif Cmfs_Shuzi == 2:
            self.S_cmfs = '综采'
        else:
            self.S_cmfs = '综放'
  • 对于以上两个新定义的函数,实现的功能是S_cmfs变量的字符串和数值的相互转换,如果输入的是汉字字符串,则转换为数值;反之亦然。

对于如何调用函数,在input函数里面要把所有的变量和函数都写进去

def value_S_Input(self, data):
    self.S_Cg_h = data['S_Cg_h'] if ('S_Cg_h' in data) else exit('报错:采煤高度不能为空') # 三元表达式
    self.S_cmfs = data['S_cmfs'] if ('S_cmfs' in data) else exit('报错:采煤方式不能为空')
    self.S_Fm_h = data['S_Fm_h'] if ('S_Fm_h' in data) else 0.0
    self.S_qj = data['S_qj'] if ('S_qj' in data) else 0.0
    self.ModeftyInitData() # 在input函数里写进一些函数   
def ModeftyInitData(self): # 对于这个函数,它没有参数,它相当于大哥,它里面的一些函数(例如Get_CmFs_StrtoValue)就是它的小弟,它派小弟去执行一些功能,就不需要传参了,这就实现了一步步的调用,注意验证各函数之间是否引用正确,点击函数能否跳转到该函数的方法里去
    self.S_No = '新工作面' if (self.S_No == '') else self.S_No
    self.S_mc_name = '1' if (self.S_mc_name == '') else self.S_mc_name
    
    self.Get_CmFs_StrtoValue(self.S_cmfs) # 函数小弟 

再举一个相同的例子:

    def Cal_Quality_x(self, R_kyqd_str, Quality_d_str, Quality_f_str): # 这个函数使用了三个参数
        # 抗压强度的对岩石质量的隶属度
        self.U_R = 0.312 * math.pow((10 * R_kyqd_str), 0.269) - 1 # (10 * R_kyqd_str)的结果的0.269次幂,math.pow表示数学里的幂函数,在使用的时候要先import math
        if self.U_R < 0.1: # self.U_R这个变量在一开始变量定义的时候需要加上这个变量,即定义函数类型
            self.U_R = 0.1
        elif self.U_R > 1:
            self.U_R = 1
        self.U_R = round(self.U_R, 3) # round(self.U_D, 3) 表示将 self.U_D 的值保留三位小数,round()是一个内置函数,用于对数字进行四舍五入的取舍
        
        # 分层厚度对岩石质量的隶属度
        self.U_D = 3.7457 * math.pow(math.e, -1.4587 / (Quality_d_str + 1)) - 1
        if self.U_D < 0.1: # self.U_D这个变量在一开始变量定义的时候需要加上这个变量,即定义函数类型
            self.U_D = 0.1
        elif self.U_D > 1:
            self.U_D = 1
        self.U_D = round(self.U_D, 3)
        
        # 节理间隙对岩石质量的隶属度
        self.U_F = 3.7457 * math.pow(math.e, -1.4587 / (Quality_f_str + 1)) - 1
        if self.U_F < 0.1: # self.U_F这个变量在一开始变量定义的时候需要加上这个变量,即定义函数类型
            self.U_F = 0.1
        elif self.U_F > 1:
            self.U_F = 1
        self.U_F = round(self.U_F, 3)
def ModeftyInitData(self): # 对于这个函数,它是大哥,不用定义参数,只需放一些函数就行
    self.Cal_Quality_d(self.R_kyqd)
    self.Cal_Quality_f(self.Quality_d)
    self.Cal_Quality_x(self.R_kyqd, self.Quality_d, self.Quality_f)
def Ys_Input(self, yc_info):
        if len(yc_info) < 11:
            return False
            sys.exit("岩层信息字段不足!")
        else:
            self.Yc_No = int(yc_info[0]) # 字符串里的第一个元素
            self.R_Name = yc_info[1].strip() # 字符串里的第二个元素
            self.R_h = float(yc_info[2])
            
            self.ModeftyInitData() # 实现函数的调用
函数调用的两种方法
def Call_Jisuan_Step(self): # 大哥
    if self.R_kyqd > 0:
        self.Cal_Step_Coeff(self.R_kyqd)
        self.Cal_Quality_d(self.R_kyqd)
        self.Cal_Quality_f(self.Quality_d)
        self.Cal_Quality_x(self.R_kyqd, self.Quality_d, self.Quality_f)
	else:
    	self.U_Q = 0.5
        
        
def Cal_Step_Coeff(self, R_kyqd_str): # 小弟
    if R_kyqd_str <= 20:
        self.Step_coeff = 0.282
    else R_kyqd_str <= 30:
        self.Step_coeff = 0.3
def Cal_Quality_d(self, R_kyqd_str): # 小弟
    if R_kyqd_str <= 10:
        self.Quality_d = 0.1
    else R_kyqd_str <= 20:
        self.Quality_d = 0.3
def Cal_Quality_f(self, Quality_d_str): # 小弟
    if Quality_d_str <= 0.7:
        self.Quality_f = -0.389 * math.sqrt(
            Quality_d_str) + 0.786 * Quality_d_str + 0.175
    else:
        self.Quality_f = Quality_d_str - 0.1
def Cal_Quality_x(self, R_kyqd_str, Quality_d_str, Quality_f_str): # 小弟
    self.U_R = 0.312 * math.pow((10 * R_kyqd_str), 0.269) - 1
    if self.U_R < 0.1:
        self.U_R = 0.1
    else self.U_R > 1:
        self.U_R = 1

一种就是上述的大哥小弟方法(注意大哥它只是一个过程,所以它是不需要参数的,它只负责派小弟去执行,关于小弟是如何实现某些功能的它一概不管,而小弟它要用参数去实现一些功能,所以小弟他们是需要有参数的),另一种是寻找一个代理人,通过代理人的继承,然后用代理人点出来的方法(注意,如果是一个类里面的函数,在调用时可以直接使用,直接self.就可以找到这个函数,如果是调用另一个文件里面的类里面的函数则就需要找代理人来继承那个类了)

class TYc_Strata(TRock):
    ...
    def Yc_Input(self, yc_info):
    # 检查岩层信息字段是否为空
    if len(yc_info) < 11:
        return False
    else:
        self.Ys_Input(yc_info)
        return True

假如要调用input方法,可以这样做:

yc = TYc_Strata() # 类的实例化
if yc.Yc_Input(yc_info): # 通过yc实现函数的调用
    # 岩层数据修订
    yc.Modefty_Yc() # 通过yc实现函数的调用

yc就是一个代理人,它通过类的实例化,相当于继承了TYc_Strata()这个类的一些函数和变量,那么它就可以调用这些函数和变量了,通过代理人的名称和.的方式,找到这个方法,实现调用的功能;同样地,Modefty_Yc这个函数也在 TYc_Strata()这个类里面,通过yc也实现了对于函数的调用

再举一个通过代理人实现函数调用的例子:

self.Ex_Yl = TYl_Beam() # 第一步,找个代理人,实现继承的功能
self.Ex_Yl.Cal_Beam_Def()  # 第二步,函数调用

然后就能找到这个函数了

def Cal_Beam_Def(self):
    if len(self.Beam_Def) == 0:
        # 先判断列表是否为空
        for i in range(5):
            if i < len(self.Beam_Def):  # 如果当前位置被占用
                self.Beam_Def[i].Yl_Input()
            else:
                self.Beam_Def.append(TYl_Beam())  # 如果未被占用,则将一个新创建的 TYl_Beam 对象添加到 self.Beam_Def 列表
                self.Beam_Def[i].Yl_Input()

            if i < len(self.Beam_step):
                self.Beam_step[i].Yl_Input()
            else:
                self.Beam_step.append(TYl_Beam())
                self.Beam_step[i].Yl_Input()

这里强调一点——在向空列表里append即添加东西的时候,先保证列表是空的,即列表清零操作,以防止后续多次操作时出现问题

for循环函数
    def Cal_Beam_Def(self):
        for i in range(5): 
            if i < len(self.Beam_Def): # 判断i的位置有没有被占用,如果被占用,则执行下面的操作,注意len这个方法表示当前列表被占用的位置数,而不是定义的列表的长度
                self.Beam_Def[i].Yl_Input()
            else:
                self.Beam_Def.append(TYl_Beam())  # 没有被占用,则将一个新创建的 TYl_Beam 类添加到 self.Beam_Def 列表
                self.Beam_Def[i].Yl_Input() # 再执行input这一步

            if i < len(self.Beam_step):
                self.Beam_step[i].Yl_Input()
            else:
                self.Beam_step.append(TYl_Beam())
                self.Beam_step[i].Yl_Input()
        # print(self.Beam_step[1].Start_YC_No) # 用于测试的,将Input函数添加个参数i,并将Start_YC_No这个变量的值赋为i,通过比较print里的变量的值与实际输出的值是否一致,就可以测试整个过程是否正确
        # print(self.Beam_Def[2].Start_YC_No) 
两种不同的for循环函数
for i in range(5):

在这行代码中,range(5) 是一个函数调用,它返回一个由整数 0, 1, 2, 3, 4 组成的范围对象。这个范围对象代表了一个左闭右开的区间,从 0 开始,但不包含结束值 5

for k in range(1, 5):

在这行代码中,range(1,5) 是一个函数调用,它返回一个由整数 1, 2, 3, 4 组成的范围对象。这个范围对象代表了一个左闭右开的区间,即包含起始值 1,但不包含结束值 5

传参

外部在调用Cal_Step_Coeff这个函数时,使用的参数为self.R_kyqd

self.Cal_Step_Coeff(self.R_kyqd)

而到这个函数里面会发现这个函数的参数叫R_kyqd_str,这就叫传参,就是在函数内部它叫这个名字,到了函数调用的地方它叫另一个名字,传参的好处就是,假如说在外部函数调用的时候发现这个函数写错了,那么只需要将调用地方的函数名改了即可,不影响函数体内部的参数,因为它只在该函数内部叫这个名字

def Cal_Step_Coeff(self, R_kyqd_str):
    if R_kyqd_str <= 20:
        self.Step_coeff = 0.282
    elif R_kyqd_str <= 30:
        self.Step_coeff = 0.3
    elif R_kyqd_str <= 50:
        self.Step_coeff = 0.35
    elif R_kyqd_str <= 70:
        self.Step_coeff = 0.4
    else:
        self.Step_coeff = 0.5
数组

一维数组:在Python中,可以使用列表来表示一维数组

x = [0,0,0,0,0]
x = [0 for _ in range(5)] # 这种方式对于元素较多时比较友好

多维数组:推荐np.zeros方法,使用之前安装numpy库,并导入,其中dtype是定义数组数据类型的

import numpy as np

x_list = np.zeros((4, 5), dtype=int)
print(x_list)

输出结果为:

[[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 0]]

数组清理:x.clear()方法

self.Beam_Def.clear()  # 列表清理
列表的使用
def Zk_Output(self):
    self.zk_info_list.clear() # 第一,使用列表前先清理,保证后续append时列表是空的
    self.yc_out_list.clear()
    # 存储钻孔信息到字典
    zk_info_dict = {
        'Zk_No': self.Zk_No,
        'Zk_name': self.Zk_name,
        'Zk_Yc_Count': self.Zk_Yc_Count
    }
    self.zk_info_list.append(zk_info_dict) # 将字典加到zk_info_list这个列表里

    for yc in self.yc_class_list:
        self.yc_out_list.append(yc.Yc_Output())

    data = self.zk_info_list + self.yc_out_list
    return data

for yc in self.yc_class_list: 遍历self.yc_class_list列表中的每个yc元素

self.yc_out_list.append(yc.Yc_Output()):调用yc.Yc_Output()方法,并将返回值添加到yc_out_list这个列表里去

数学函数的使用
import math

self.U_R = round(self.U_R, 3)
self.Quality_f = -0.389 * math.sqrt(Quality_d_str) + 0.786 * Quality_d_str + 0.175
self.U_R = 0.312 * math.pow((10 * R_kyqd_str), 0.269) - 1

在Python中,round()函数表示将一个数字四舍五入到指定的小数位数

sqrt() 函数用于计算一个数字的平方根

pow() 函数用于计算给定底数的指定指数次幂,代码表示(10 * R_kyqd_str)结果的0.269次幂