为什么这两种距离转换方法会产生不同的输出?

问题描述 投票:0回答:1

我正在尝试清理我编写的一些代码。该代码用于转换距离单位。例如,米到千米或几秒到AU。在下面的代码中,有两个实现;第一个实现是我在第二个实现中清理代码的失败尝试。第二种实现可以正常工作,但是我尝试在代码中使用更少的重复性,同时仍保持可读性。

在下面的代码中,仅转换距离单位(我计划以后再添加其他类型的单位转换)。首先,单位相对于一米按比例缩放。由此确定所有其他单位转换(因为AU --> m转换将比1000转换大AU --> km倍,其中10001 km / 1 m的大小。

class UnitConversions():

    def __init__(self):
        self.base_units = ('m', 'km', 'AU', 'LY', 'pc')
        self.base_values = (1, 1000, 1.496e11, 9.461e15, 3.086e16)

    @property
    def first_distance_conversion_factors(self):
        res = {}
        res['m'] = dict(zip(self.base_units, self.base_values))
        for outer_key in self.base_units:
            if outer_key != 'm':
                res[outer_key] = {inner_key : value / res['m'][inner_key] for inner_key, value in res['m'].items()}
        return res

    @property
    def second_distance_conversion_factors(self):
        """ """
        res = {}
        res['m'] = {'m' : 1, 'km' : 1000, 'AU' : 1.496e11, 'LY' : 9.461e15, 'pc' : 3.086e16}
        res['km'] = {key : value / res['m']['km'] for key, value in res['m'].items()}
        res['AU'] = {key : value / res['m']['AU'] for key, value in res['m'].items()}
        res['LY'] = {key : value / res['m']['LY'] for key, value in res['m'].items()}
        res['pc'] = {key : value / res['m']['pc'] for key, value in res['m'].items()}
        return res

    def first_convert_distance(self, distance, original_unit, prime_unit='m'):
        """ """
        conversion_factor = self.first_distance_conversion_factors[prime_unit][original_unit]
        return distance * conversion_factor

    def second_convert_distance(self, distance, original_unit, prime_unit='m'):
        """ """
        conversion_factor = self.second_distance_conversion_factors[prime_unit][original_unit]
        return distance * conversion_factor

UC = UnitConversions()
distance = 5

for original_unit in UC.base_units:
    for prime_unit in UC.base_units:
        # res = UC.first_convert_distance(distance, original_unit, prime_unit)
        res = UC.second_convert_distance(distance, original_unit, prime_unit)
        print('\n {} {} = {} {}'.format(distance, original_unit, res, prime_unit))

我已经注释掉第一种方法,因为它不起作用。运行上面的代码(使用第二种方法)将输出以下输出:

 5 m = 5 m

 5 m = 0.005 km

 5 m = 3.342245989304813e-11 AU

 5 m = 5.284853609555015e-16 LY

 5 m = 1.6202203499675955e-16 pc

 5 km = 5000 m

 5 km = 5.0 km

 5 km = 3.342245989304813e-08 AU

 5 km = 5.284853609555016e-13 LY

 5 km = 1.6202203499675955e-13 pc

 5 AU = 748000000000.0 m

 5 AU = 748000000.0 km

 5 AU = 5.0 AU

 5 AU = 7.906140999894303e-05 LY

 5 AU = 2.4238496435515228e-05 pc

 5 LY = 4.7305e+16 m

 5 LY = 47305000000000.0 km

 5 LY = 316209.89304812835 AU

 5 LY = 5.0 LY

 5 LY = 1.5328904731043422 pc

 5 pc = 1.543e+17 m

 5 pc = 154300000000000.0 km

 5 pc = 1031417.1122994652 AU

 5 pc = 16.309058239086777 LY

 5 pc = 5.0 pc

如果运行第一种方法(错误的方法),那么将输出以下输出:

 5 m = 5 m

 5 m = 5.0 km

 5 m = 5.0 AU

 5 m = 5.0 LY

 5 m = 5.0 pc

 5 km = 5000 m

 5 km = 5.0 km

 5 km = 5.0 AU

 5 km = 5.0 LY

 5 km = 5.0 pc

 5 AU = 748000000000.0 m

 5 AU = 5.0 km

 5 AU = 5.0 AU

 5 AU = 5.0 LY

 5 AU = 5.0 pc

 5 LY = 4.7305e+16 m

 5 LY = 5.0 km

 5 LY = 5.0 AU

 5 LY = 5.0 LY

 5 LY = 5.0 pc

 5 pc = 1.543e+17 m

 5 pc = 5.0 km

 5 pc = 5.0 AU

 5 pc = 5.0 LY

 5 pc = 5.0 pc

我不知道这两种实现方式为何/为什么不同。我猜想它与字典理解计数元素的顺序有关。但是我什至不确定这是否正确。有人可以帮助我理解为什么这两种方法没有相同的输出吗?

python-3.x dictionary numbers nested-loops dictionary-comprehension
1个回答
1
投票

您的索引已关闭

@property
def first_distance_conversion_factors(self):
    res = {}
    res['m'] = dict(zip(self.base_units, self.base_values))
    for outer_key in self.base_units:
        if outer_key != 'm':
            res[outer_key] = {inner_key : value / res['m'][inner_key]   # outer_key here 
                              for inner_key, value in res['m'].items()}
    return res

使用:

@property
def first_distance_conversion_factors(self):
    res = {}
    res['m'] = dict(zip(self.base_units, self.base_values))
    for outer_key in self.base_units: 
        if outer_key != 'm':
            res[outer_key] = {inner_key : value / res['m'][outer_key] 
                              for inner_key, value in res['m'].items()}
    return res

with:

UC = UnitConversions()
distance = 5

for original_unit in UC.base_units:
    for prime_unit in UC.base_units:
        res = UC.first_convert_distance(distance, original_unit, prime_unit)
        print('{} {} = {} {}'.format(distance, original_unit, res, prime_unit), 
              end = " ..... ")
        res = UC.second_convert_distance(distance, original_unit, prime_unit)
        print('{} {} = {} {}'.format(distance, original_unit, res, prime_unit))

打印:

5 m = 5 m ..... 5 m = 5 m
5 m = 0.005 km ..... 5 m = 0.005 km
5 m = 3.342245989304813e-11 AU ..... 5 m = 3.342245989304813e-11 AU
5 m = 5.284853609555015e-16 LY ..... 5 m = 5.284853609555015e-16 LY
5 m = 1.6202203499675955e-16 pc ..... 5 m = 1.6202203499675955e-16 pc
5 km = 5000 m ..... 5 km = 5000 m
5 km = 5.0 km ..... 5 km = 5.0 km
5 km = 3.342245989304813e-08 AU ..... 5 km = 3.342245989304813e-08 AU
5 km = 5.284853609555016e-13 LY ..... 5 km = 5.284853609555016e-13 LY
5 km = 1.6202203499675955e-13 pc ..... 5 km = 1.6202203499675955e-13 pc
5 AU = 748000000000.0 m ..... 5 AU = 748000000000.0 m
5 AU = 748000000.0 km ..... 5 AU = 748000000.0 km
5 AU = 5.0 AU ..... 5 AU = 5.0 AU
5 AU = 7.906140999894303e-05 LY ..... 5 AU = 7.906140999894303e-05 LY
5 AU = 2.4238496435515228e-05 pc ..... 5 AU = 2.4238496435515228e-05 pc
5 LY = 4.7305e+16 m ..... 5 LY = 4.7305e+16 m
5 LY = 47305000000000.0 km ..... 5 LY = 47305000000000.0 km
5 LY = 316209.89304812835 AU ..... 5 LY = 316209.89304812835 AU
5 LY = 5.0 LY ..... 5 LY = 5.0 LY
5 LY = 1.5328904731043422 pc ..... 5 LY = 1.5328904731043422 pc
5 pc = 1.543e+17 m ..... 5 pc = 1.543e+17 m
5 pc = 154300000000000.0 km ..... 5 pc = 154300000000000.0 km
5 pc = 1031417.1122994652 AU ..... 5 pc = 1031417.1122994652 AU
5 pc = 16.309058239086777 LY ..... 5 pc = 16.309058239086777 LY
5 pc = 5.0 pc ..... 5 pc = 5.0 pc

可能更好地进行测试(如果您不编写real测试,则::

for original_unit in UC.base_units:
    for prime_unit in UC.base_units:
        m1 = UC.first_convert_distance(distance, original_unit, prime_unit)
        m2 = UC.second_convert_distance(distance, original_unit, prime_unit)
        assert m1 == m2, f"{m1} != {m2} for {original_unit} to {prime_unit}" 

..仅在出现问题时才发出输出

© www.soinside.com 2019 - 2024. All rights reserved.