Python 计算对象属性对应的所有未知值所需的case(或if/else)语句的最小数目是多少?

Python 计算对象属性对应的所有未知值所需的case(或if/else)语句的最小数目是多少?,python,data-structures,Python,Data Structures,考虑一个直角三角形,它具有 斜边(边) 相邻(侧面) 对面(侧面) 区域 给定这些属性中的任意2个,总是可以计算其他2个属性的值。我的问题是,最有效/最优雅的方法是什么 目前,我能想到的唯一方法是使用(4C2)*2=12个case语句,每个语句都与可能提供的输入的可能组合有关 例如,使用python时,您可能会遇到如下情况 class RightAngleTriangle(): def __init__(this, propertyType1, propertyValue1, pr

考虑一个直角三角形,它具有

  • 斜边(边)
  • 相邻(侧面)
  • 对面(侧面)
  • 区域

给定这些属性中的任意2个,总是可以计算其他2个属性的值。我的问题是,最有效/最优雅的方法是什么

目前,我能想到的唯一方法是使用(4C2)*2=12个case语句,每个语句都与可能提供的输入的可能组合有关

例如,使用python时,您可能会遇到如下情况

class RightAngleTriangle():
    def __init__(this, propertyType1, propertyValue1, propertyType2, propertyValue2):
        this.adjacent = 0
        this.opposite = 0
        this.hypotenuse = 0
        this.area = 0
    if (propertyType1 == "adjacent" and propertyType2 == "opposite"):
        this.adjacent = propertyValue1
        this.opposite = propertyValue2
        this.hypotenuse = (propertyValue1**2 + propertyValue2**2)**0.5
        this.area = (propertyValue1 * propertyValue2)/2
    elif (propertyType1 == "opposite" and propertyType2 == "adjacent"):
        this.adjacent = propertyValue2
        this.opposite = propertyValue1
        this.hypotenuse = (propertyValue1**2 + propertyValue2**2)**0.5
        this.area = (propertyValue1 * propertyValue2)/2
    elif (propertyType1 == "adjacent" and propertyType2 == "hypotenuse"):
        this.adjacent = propertyValue1
        this.hypotenuse = propertyValue2
        this.opposite = (propertyValue2**2 + propertyValue1**2)**0.5
        this.area = (this.opposite * this.adjacent)/2
……等等

然后,您可以创建三角形对象,并使用如下代码(在本例中为python)打印其四个属性

t1 = RightAngleTriangle("adjacent", 10, "opposite", 12)
print(t1.adjacent)
print(t1.opposite)
print(t1.hypotenuse)
print(t1.area)

这太可怕了。这个问题有没有更简单的解决方案?

是的,至少有两个-一个使用args,一个使用关键字args。因此:

class RightAngleTriangle():
    def __init__(self, *args):
        self.adjacent = 0
        self.opposite = 0
        self.hypotenuse = 0
        self.area = 0
        for property_type, property_value in zip(args[::2], args[1::2]):
            setattr(self, property_type, property_value)
        if not self.adjacent:
           # calculate
        elif not self.opposite:
           # calculate
        elif not self.hypotenuse:
           # calculate
        self.area = (this.opposite * this.adjacent) / 2
这将适用于您当前的输入,但我们同意,这仍然不是非常优雅的解决方案。那么,让我们使用kwargs:

class RightAngleTriangle():
    def __init__(self, adjacent=0, opposite=0, hypotenuse=0):
        self.adjacent = adjacent
        self.opposite = opposite
        self.hypotenuse = hypotenuse
        self.area = 0
        if not self.adjacent:
           # calculate
        elif not self.opposite:
           # calculate
        elif not self.hypotenuse:
           # calculate
        self.area = (this.opposite * this.adjacent) / 2
现在您可以简单地将此代码称为:
t1=直角三角形(相邻=10,相反=12)

“更优雅”不可避免地是基于观点的,但我会使用和。也许看看。好吧,你可以通过对给定的数据进行排序,将案例数量减半——如果
propertyType1>propertyType2
,然后交换类型和值。这样,您就不必同时实现相邻/相反和相反/相邻。然而,您是否不需要在每次计算中使用case语句来推断哪些信息可用于进行计算?好的一点是,在这种情况下,我做了一个乐观的假设,即用户将正确地提供至少两个值。然而,如果在计算之前,我们检查最多一个变量等于0,那么我们就可以轻松地使用剩余的两个变量来计算最后的缺失-我们将知道它们是提供的。例如,
如果sum([v==0,表示[self.nextant,self.reversion,self.斜边]])>1:raise ValueError(“无法计算!”)
然后进行计算。再次欢呼-但将有2个缺失值(该区域也是一个潜在输入)!这意味着我们无法通过检查单个0来推断输入。好的,从你的例子中,我假设该区域在任何时候都不是输入。我会重新考虑,并尝试回来为答案进行适当的编辑。