繁体   English   中英

有没有Pythonic方法来处理这种范围映射

[英]Is there a Pythonic way of handling this sort of range mapping

请问这可以更加Pythonic吗?

if joyx > 50:
   joyx = 100
elif joyx < -50:
   joyx = -100
else:
   joyx = 0

你可以用math.copysignabs函数来编写它:

In [30]: from math import copysign

In [31]: joyx = copysign(100, joyx) if abs(joyx) > 50 else 0

例:

In [32]: joyx = lambda x: copysign(100, x) if abs(x) > 50 else 0

In [33]: joyx(51), joyx(-51), joyx(50), joyx(-50), joyx(0)
Out[33]: (100.0, -100.0, 0, 0, 0)

在我看来,你拥有的是完美的Pythonic。

因为你使用的是小于和大于比较,所以我们无法通过使用字典或我能想到的任何其他技巧来改善这一点。

我想你可以把它考虑到一个函数中,然后调用函数:

def clean_up_joystick(x, y, xbound, ybound, on_value):
    if x > xbound:
        x = on_value
    elif x < -xbound:
        x = -on_value
    else:
        x = 0
    if y > ybound:
        y = on_value
    elif y < -ybound:
        y = -on_value
    else:
        y = 0
    return (x, y)

对于一个实际的程序,我建议你应该创建一个管理操纵杆的类,并使用你想要用于任何特定操纵杆的边界值来初始化类。

也许是这样的:

class Joystick(object):
    def __init__(self,
            x_low=-50, x_high=50,
            y_low=-50, y_high=50,
            on_value=100):
        self.x_low = x_low
        self.x_high = x_high
        self.y_low = y_low
        self.y_high = y_high
        self.on_value = on_value

    def read(self):
        # do something here that reads the joystick value
        # joystick value saved in x, y variables
        x, y = 0,0  # dummy init for example

        if x > self.x_high:
            x = self.on_value
        elif x < -self.x_low:
            x = -self.on_value
        else:
            x = 0
        if y > self.x_high:
            y = self.on_value
        elif y < self.x_low:
            y = -self.on_value
        else:
            y = 0
        return (x, y)

j = Joystick()
x, y = j.read()

然后在您的实际程序中,您只需使用j.read()来读取操纵杆并清理输入数据。 如果你需要改变它的工作方式,你就有一个地方(班级)。 只需确保为每个实际操纵杆设置不同的类实例,以便在有不同操纵杆的情况下清理它们。

也许你会发现这更像pythonic:

def get(joyx):
   joyx_min = -200
   joyx_max = 200
   from collections import namedtuple
   wheel_section = namedtuple("wheel_section", "min, max, output_value")
   roulette_wheel = [ wheel_section(joyx_min, -50, -100),  wheel_section(-50,51,0), wheel_section(51, joyx_max,100) ]
   for section in roulette_wheel:
     if  section.min <= joyx <  section.max:
       return section.output_value
   return 255

你的代码是轮盘赌算法的一个非常简化的版本。 我不确定你应该真的做它的全尺寸版本。

更新

使用下限算法的明显更短,更漂亮的版本:

from bisect import bisect_left

# an intentionally larger: maps also 50 and -50 for demonstrational purposes.
data = { -200 : -100, -100 : -50, -50 : 0, 50 : 50, 220 : 100 }
keys = list(data.keys())


print data[  keys[ bisect_left(keys, -79)  ]  ] # prints -100
print data[  keys[ bisect_left(keys,  15)  ]  ] # prints 0
print data[  keys[ bisect_left(keys,  67)  ]  ] # prints 50
print data[  keys[ bisect_left(keys,  250) ]  ] # prints 100

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM