Len功能不像预期的那样行为

发布于 2025-02-05 12:03:50 字数 2087 浏览 1 评论 0原文

我正在构建一个函数,该函数正在基于传递的标签的dist上应用AWS实例。

预期行为: 当传递多个test_customer_id时,该函数应返回标签的字典:

{'foo': 'bar', 'Account': 'shared'}

单位测试功能的当前行为仅返回:

{'foo': 'bar', 'Account': [['test_customer_id1', 'test_customer_id2']]} 

我该如何解决此问题?

def get_acct_value(tags, customer_id, ceid):
    customer_id = [customer_id]
    
    if "Account" in tags:
        if tags["Account"] == customer_id:
            pass
        else:
            if len(customer_id) > 1:
                tags["Account"] = "shared"
            elif len(customer_id) == 1:
                tags["Account"] = customer_id
            else:
                raise exceptions.CustomerNotFoundError(f"No customer(s) found on {ceid}")
    else:
        if len(customer_id) > 1:
            tags["Account"] = "shared"
        elif len(customer_id) == 1:
            tags["Account"] = customer_id
        else:
            raise exceptions.CustomerNotFoundError(f"No customer(s) found on {ceid}")
    return tags

单元测试:

TAGS_NO_VALUE = {'foo': 'bar'}
TEST_CUSTOMER_ID_LIST = ["test_customer_id1", "test_customer_id2"]
TEST_CEID = "test_ceid"


def test_get_account_value_customer_list():
    response = tagging.get_acct_value(TAGS_NO_VALUE, TEST_CUSTOMER_ID_LIST, TEST_CEID)

    print(response)

其他单元测试:

所有三个测试都应返回:{'accult':customer_id,'foo':'bar'}

TEST_CUSTOMER_ID = "test_customer_id"
TAGS_UNEXPECTED_VALUE = {'Account': '', 'foo': 'bar'} 
TAGS_EXPECTED_VALUE = {'Account': customer_id, 'foo': 'bar'} 

def test_get_acct_value_no_value():

    response = tagging.get_acct_value(TAGS_NO_VALUE, 
TEST_CUSTOMER_ID, TEST_CEID)

    print(response)


def test_get_acct_value_unexpected_value():

    response = tagging.get_acct_value(TAGS_UNEXPECTED_VALUE, TEST_CUSTOMER_ID, TEST_CEID)

    print(response)

def test_get_acct_value_expected_value():

    response = tagging.get_acct_value(TAGS_EXPECTED_VALUE, TEST_CUSTOMER_ID, TEST_CEID)

    print(response)

I'm building a function that's applying an additional tag to an aws instance based on a dict of tags that are passed in.

Expected behavior:
When more than one TEST_CUSTOMER_ID is are passed in, the function should return the following dictionary of tags:

{'foo': 'bar', 'Account': 'shared'}

The current behavior of the unit test function is only returning:

{'foo': 'bar', 'Account': [['test_customer_id1', 'test_customer_id2']]} 

How can I fix this?

def get_acct_value(tags, customer_id, ceid):
    customer_id = [customer_id]
    
    if "Account" in tags:
        if tags["Account"] == customer_id:
            pass
        else:
            if len(customer_id) > 1:
                tags["Account"] = "shared"
            elif len(customer_id) == 1:
                tags["Account"] = customer_id
            else:
                raise exceptions.CustomerNotFoundError(f"No customer(s) found on {ceid}")
    else:
        if len(customer_id) > 1:
            tags["Account"] = "shared"
        elif len(customer_id) == 1:
            tags["Account"] = customer_id
        else:
            raise exceptions.CustomerNotFoundError(f"No customer(s) found on {ceid}")
    return tags

Unit test:

TAGS_NO_VALUE = {'foo': 'bar'}
TEST_CUSTOMER_ID_LIST = ["test_customer_id1", "test_customer_id2"]
TEST_CEID = "test_ceid"


def test_get_account_value_customer_list():
    response = tagging.get_acct_value(TAGS_NO_VALUE, TEST_CUSTOMER_ID_LIST, TEST_CEID)

    print(response)

Other unit tests:

All three tests should return: {'Account': customer_id, 'foo': 'bar'}

TEST_CUSTOMER_ID = "test_customer_id"
TAGS_UNEXPECTED_VALUE = {'Account': '', 'foo': 'bar'} 
TAGS_EXPECTED_VALUE = {'Account': customer_id, 'foo': 'bar'} 

def test_get_acct_value_no_value():

    response = tagging.get_acct_value(TAGS_NO_VALUE, 
TEST_CUSTOMER_ID, TEST_CEID)

    print(response)


def test_get_acct_value_unexpected_value():

    response = tagging.get_acct_value(TAGS_UNEXPECTED_VALUE, TEST_CUSTOMER_ID, TEST_CEID)

    print(response)

def test_get_acct_value_expected_value():

    response = tagging.get_acct_value(TAGS_EXPECTED_VALUE, TEST_CUSTOMER_ID, TEST_CEID)

    print(response)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

翻身的咸鱼 2025-02-12 12:03:51

我认为您在这里很复杂。让我们以不同的方式打破此功能:

def get_acct_value(tags, customer_ids, ceid):
    if len(customer_ids) == 0:
        raise exceptions.CustomerNotFoundError(f"No customer(s) found on {ceid}")
    tag = "shared" if len(customer_ids) > 1 else customer_ids[0]
    tags["Account"] = tag
    return tags

首先,我们知道,如果customer_ids列表为空,我们应该提出例外。 首先执行此操作。它被标记为“界限检查”,应在尝试处理任何数据之前完成 - 这样您就不必在代码的每个分支上重做它。

其次,我们知道,如果列表大于一个,我们希望我们的标签被“共享”,这意味着我们有一个以上的客户ID。如果我们的列表大于一个,则将其设置为具有名称tag的临时变量。如果列表正是一个,我们将其设置为唯一可用的客户ID。

最后,我们进行实际工作 - 将帐户设置为我们选择的标签。如果Len(customer_ids)> 1 else customer_id [0] 。

值得注意的是,您的近端问题是customer_ids类型必须在中传递,必须是列表。如果这是一个孤独的价值,那么您会遇到问题。您尝试通过将其投入到列表中来解决此问题,但是如果您想接受列表或单个值,最好做类似的事情:

customer_ids = customer_ids if isinstance(customer_ids, list) else [customer_ids]

这将导致这样的事情:

def get_acct_value(tags, customer_ids, ceid):
    customer_ids = list() if customer_ids is None else customer_ids
    customer_ids = customer_ids if isinstance(customer_ids, list) else [customer_ids]
    print(f"type={type(customer_ids)} {customer_ids=}")
    if len(customer_ids) == 0:
        raise exceptions.CustomerNotFoundError(f"No customer(s) found on {ceid}")
    tags["Account"] = "shared" if len(customer_ids) > 1 else customer_ids[0]
    return tags

我添加了初始检查为了customer_ids确保它不是none,它会破坏您的第二个检查(如果不是一个,则将值转换为列表),因为list(列表)(无)投掷typeerror

请注意,我会尽快命名此函数update_account_tags()或类似的内容,因为它返回没有值,只是标签字典,该字典的帐户具有更新的值。

一些指导:如果您发现自己进行检查,如果a在b中,则b是字典,并且您打算用a做某事,最好的事情要做的是使用字典的函数get()

v = b.get(a, my_default)

my_default这可以是您想要的,默认情况下是none。因此,这些都是等效的:

v = b.get(a)
v = b[a] if a in b else None

其次,如果您发现自己正在进行这样的检查的情况:

if tags["Account"] == customer_id:
    pass
else:
   tags["Account"] = customer_id

您也可以简单地做到这一点:

tags["Account"] = customer_id

结果是相同的,并且在计算上同样复杂。 (如果customer_id被替换为get_customer_id()之类的函数,这可能不是完全正确的,但是作为第一个本能,它会做得很好。)

I think you're complicating yourself a great deal here. Let's break out this function differently:

def get_acct_value(tags, customer_ids, ceid):
    if len(customer_ids) == 0:
        raise exceptions.CustomerNotFoundError(f"No customer(s) found on {ceid}")
    tag = "shared" if len(customer_ids) > 1 else customer_ids[0]
    tags["Account"] = tag
    return tags

First, we know that if customer_ids, a list, is empty, we should raise an exception. Do this first. It's labelled 'bounds checking', and should be done before you try and process any data - that way you don't have to redo it on every branch of your code.

Secondly, we know that if the list is greater than one, we want our tag to be 'shared', meaning we have more than one customer id. Let's set a temporary variable with the name tag with 'shared' if we have a list greater than one. If the list is exactly one, we set it to the only available customer id.

Finally, we do the actual work - setting the account to the tag we have selected. Lines 4 and five could be combined to tags["Account"] = "shared" if len(customer_ids) > 1 else customer_id[0].

Notably, your proximal issue is that the type of customer_ids being passed in must be a list. If it is a solitary value then you'll have an issue. You try to solve this by just casting it to a list, but if you want to accept either a list or a single value, you're better doing something like this:

customer_ids = customer_ids if isinstance(customer_ids, list) else [customer_ids]

This would result in something like:

def get_acct_value(tags, customer_ids, ceid):
    customer_ids = list() if customer_ids is None else customer_ids
    customer_ids = customer_ids if isinstance(customer_ids, list) else [customer_ids]
    print(f"type={type(customer_ids)} {customer_ids=}")
    if len(customer_ids) == 0:
        raise exceptions.CustomerNotFoundError(f"No customer(s) found on {ceid}")
    tags["Account"] = "shared" if len(customer_ids) > 1 else customer_ids[0]
    return tags

I've added an initial check for customer_ids to ensure it is not None, which would break your second check (to convert the value to a list if it is not one), since list(None) throws a TypeError.

Note that I would sooner name this function update_account_tags() or something like that, since it returns no value, just a dictionary of tags, which has an updated value for account.

Some guidance: if you find yourself doing a check, if a in b, where b is a dictionary, and you're planning to do something with a, the best thing to do is use the dictionary's function get().

v = b.get(a, my_default)

my_default here can be whatever you want, and by default is None. So these are equivalent:

v = b.get(a)
v = b[a] if a in b else None

Secondly, if you find yourself in a situation where you're doing a check like this:

if tags["Account"] == customer_id:
    pass
else:
   tags["Account"] = customer_id

You might as well simply do this:

tags["Account"] = customer_id

The result is the same, and it's equally computationally complex. (If customer_id is replaced with a function like get_customer_id() this may not be entirely true, but as a first instinct it'll do you well.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文