【问题标题】:can this code be shortened or improved? [closed]可以缩短或改进此代码吗? [关闭]
【发布时间】:2013-11-05 03:41:59
【问题描述】:

这可以缩短/改进吗?我正在尝试在 python 中制作密码检查器。

是否可以将 if 放入 for 循环中?如果有,怎么做?

pw = input("Enter password to test: ")

caps = sum(1 for c in pw if c.isupper())
lower = sum(1 for c in pw if c.islower())
nums = sum(1 for c in pw if c.isnumeric())

scr = ['weak', 'medium', 'strong']
r = [caps, lower, nums]


if len(pw) < 6:
    print("too short") 
elif len(pw) > 12:
    print("too long")

if caps >= 1:
    if lower >= 1:
        if nums >= 1:
            print(scr[2])
        elif nums < 1:
            print("your password is " + scr[1])
    elif lower < 1:
        print("your password strength is " + scr[0])
elif caps < 1:
    print("your password strength is " + scr[1])

感谢您的任何建议:D

【问题讨论】:

  • codereview.stackexchange.com 应该是这个位置。这两个问题的答案我确定是肯定的,它可以缩短和改进
  • scr[1] 绝对没有比'medium' 更简单或更有意义。 (如果你想让你的字符串可本地化......有更好的方法来做到这一点。)
  • 这个问题似乎是题外话,因为它是关于审查工作代码。请改用Code Review
  • @abarnert:我怀疑我们对什么是“工作代码”有不同的看法:)
  • @TimPietzcker:嗯,他假设他的代码是正确的,只是要求我们简化它。

标签: python passwords


【解决方案1】:

我会修复那个嵌套的 if 语句。

scr = ['weak', 'medium', 'strong'] # if you want to keep this fine
# but I suggest you do something like this:
_WEAK = scr[0] 
_MEDIUM = scr[1]
_STRONG = scr[2]
if caps >= 1 and lower >= 1 and nums >= 1:
   print(_STRONG)
elif caps < 1:
    print("your password strength is " + _MEDIUM)
elif lower < 1:
   print("your password strength is " + _WEAK)
elif nums < 1:
   print("your password is " + _MEDIUM)

【讨论】:

  • 但这是一个不同的逻辑。并不是说 OP 的逻辑有任何意义,但这也没有。
【解决方案2】:
caps = sum(1 for c in pw if c.isupper())

可以是:

caps = sum(c.isupper() for c in pw)

if caps >= 1:

可以是:

if caps:

显着的改进:底部的if/elif块可以通过这样做完全删除

i_strength = sum(map(bool,[caps,lower,nums])) - 1 #or sum(map(bool,r)) - 1
print('your password is {}'.format(scr[i_strength]))

解释:map(bool,[caps,lower,nums]) 累加每个caps,lower,nums 非零的次数。将它们与sum 相加会为您提供“力量”,您已经方便地将其放入列表中,可以通过索引访问。

所有这些改进都利用了 Python 中的“虚假”概念,也就是布尔上下文中的对象值。一般空和零的东西是False,布尔求和相当于加一加零,这样就行了。


当然,除了检查它们是否为非零之外,您似乎没有任何关于上/下/数字计数的事情。所以清理只是

caps = any(c.isupper() for c in pw)
...

然后

i_strength = sum([caps,lower,nums]) -1

【讨论】:

  • ...像这样,密码强度检查更有意义。干得好!
【解决方案3】:

我将忽略一般问题,“可以缩短或改进此代码”,因为这是Code Review 的问题。但是你也有一个具体的问题:

是否可以将 if 放入 for 循环中?如果有,怎么做?

它们可以,但你必须将它们变成可以放入迭代器中的东西,比如函数,我真的认为在这种情况下你不想这样做。

让我们从一个更简单的例子开始,只有一系列线性检查:

checks = [
    ((lambda caps, lower, num: caps >= 1 and lower >= 1 and nums >= 1), 2),
    ((lambda caps, lower, num: caps < 1), 1),
    ((lambda caps, lower, num: lower < 1), 0),
    ((lambda caps, lower, num: num < 1), 1)
]
for check, value in checks:
    if check(caps, lower, num):
        print('your password strength is ' + scr[value])
        break

您可以改为将检查条件置于某种编码数据形式中,并将if check(…) 替换为对条件的数据驱动检查。例如:

checks = [
    ((1, 1, 1), 2),
    ((-1, 0, 0), 1),
    ((0, -1, 0), 0),
    ((0, 0, -1), 1)
]
for check, value in checks:
    for value, condition in zip((caps, lower, num), check):
        if condition == -1 and value >= 1 or condition == 1 and value < 1:
            break
    else:
        print('your password strength is ' + scr[value])
        break

但我认为这更不可读。有很多这样的事情是有意义的用例——例如,假设你想为每个 x 值评估 40 个多项式;您将每个多项式存储为系数列表,并具有像这样的通用“评估多项式”逻辑。但这不是其中一种情况。

无论如何,这已经很丑陋了。如果你想要嵌套检查,你将需要一个嵌套结构,你可能想要递归处理。

【讨论】:

    猜你喜欢
    • 2011-05-27
    • 1970-01-01
    • 2012-12-07
    • 2020-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多