Python 理解一个例子

Python 理解一个例子,python,pseudocode,Python,Pseudocode,我正在学习Python,遇到了这个例子,有人能用简单的英语(或伪代码)逐行解释一下它在做什么吗 非常感谢它正在迭代猪和鸡的所有可能组合(具有指定数量的头),直到找到一个具有正确数量的腿,然后返回猪和鸡的数量。如果它通过每个组合都没有找到有效的答案,则返回[None,None]表示失败。本质上,solve是对鸡和猪的每个可能组合进行迭代,当它找到匹配项时,返回。) NumChickens+NumPigs必须等于NumHeads,因此它会检查从0到NumHeads的每个NumChickens(这就是

我正在学习Python,遇到了这个例子,有人能用简单的英语(或伪代码)逐行解释一下它在做什么吗


非常感谢

它正在迭代猪和鸡的所有可能组合(具有指定数量的头),直到找到一个具有正确数量的腿,然后返回猪和鸡的数量。如果它通过每个组合都没有找到有效的答案,则返回[None,None]表示失败。

本质上,
solve
是对鸡和猪的每个可能组合进行迭代,当它找到匹配项时,返回。)

NumChickens+NumPigs必须等于NumHeads,因此它会检查从0到NumHeads的每个NumChickens(这就是范围(0,NumHeads+1)所做的),并将NumPigs设置为NumHeads NumChickens


从这里开始,只需将脚的数量相乘,看看它们是否匹配。

solve
就是计算出在给定的头和腿数量下,总共需要多少只小鸡(1头,2条腿)和多少头猪(1头,4条腿)

它使用了一种“蛮力”,即最简单的方法:

  • 它甚至尝试了可能的数量 小鸡从一无所有到尽可能多 被指定为头数 (这就是循环
    的作用
    范围内的numChicks(0,numHeads+
    1) :
    ,因为
    范围
    给出整数 从包含的起始值开始 (不包括期末价值)
  • 对于每个给定的
    numChicks
    ,它计算 会有多少头猪给你 要求的总人数,由 语句
    numPigs=numHeads-numChicks
  • 然后计算总共有多少条腿 那些小鸡和小猪到了
    totLegs=4*numPigs+2*numChicks
  • 然后检查
    totLegs
    是否相等 请求的号码:如果是,则返回 包含两项的列表,其中 解决问题的小鸡和小猪
  • 最后,如果它“跌入谷底” 未返回的
    for
    循环 一个值,它知道没有解决方案, 并表示通过返回一个列表 其两项中的每一项都是
    None
barnYard
只需将解决方案委托给
solve
,并以可读的方式打印出来,可以是“无解决方案”,也可以是装饰精美的小鸡和小猪数量

现在,为了继续前进,问问自己
solve
是否可以更高效地编写。显然,如果支腿的数量少于头部数量的两倍,或者超过头部数量的四倍,或者是奇数,那么就没有解决方案——也许
solve
可以测试这些情况并立即返回
[None,None]
。你能把它编码成


这可能并不明显,但头和腿的数量的每一个其他组合都有一个解决方案——有一种方法可以通过算术找到它,而不需要循环。想想看,也许借助于小学-中学代数…

基本上,它试图找出问题的答案,“如果谷仓里有X头和Y腿,那么谷仓里有多少鸡和猪?”范围(0,numHeads+1)内的numChicks的
代码创建了一个变量numChicks,并从numChicks=0循环到numChicks=numHeads。(注意:范围函数不包括最高值)


对于每个数量的numChicks,它会检查numChicks和相应的numPigs值是否具有正确的numLegs值。numHeads总是正确的,因为numChicks+numPigs=numHeads,但是numLegs会根据分布情况而变化——因此循环也是如此。如果在任何一点上找到了解决方案(当totLegs==numLegs时),则返回该值。如果完成了整个循环,但没有找到解决方案,则返回列表[None,None],这意味着此输入没有解决方案。

Alex Martelli提到了一个代数解决方案,为了完整性,我将在这里包括它。它可以用联立方程组计算出来。作为一个简单的数学解,它可能更快,至少对于大量的腿和头来说是如此:-)

让我们:

  • H
    为头数
  • L
    为支腿数
  • C
    是小鸡的数量;及
  • P
    是清管器的数量
给定
C
p
,我们可以使用以下公式计算其他两个变量:

def solve(numLegs, numHeads):
    for numChicks in range(0, numHeads + 1):
        numPigs = numHeads - numChicks
        totLegs = 4*numPigs + 2*numChicks
        if totLegs == numLegs:
            return [numPigs, numChicks]
    return [None, None]

def barnYard(heads, legs):
    pigs, chickens = solve(legs, heads)
    if pigs == None:
        print "There is no solution."
    else:
        print 'Number of pigs: ', pigs
        print 'Number of Chickens: ', chickens
我将在下面的计算中详细说明每一步。有数学倾向的人无疑可以指出,这些步骤可以结合起来,但我更喜欢明确。从(1)中,我们可以计算:

H =  C +  P (1)
L = 2C + 4P (2)
并将其替换为(2):

现在有两个公式,一个可以计算头和腿的小鸡数量
(4)
,另一个可以计算头和小鸡的猪数量
(3)

下面是Python代码,通过适当的检查确保您不允许使用一些更奇怪的数学解,比如2个头和7条腿给我们一头猪半和半只小鸡,或者1个头和12条腿给5头猪和-4只小鸡:-)

def solve(numLegs,numHeads):
#使用公式(这些公式构成整数)。
小鸡=numHeads*2-int(numLegs/2)
猪=人头-小鸡
#不允许动物数量为负数。
如果小鸡<0或小猪<0:
返回[无,无]
#不要让动物分居。
如果小鸡*2+小猪*4!=numLegs:
返回[无,无]
如果小鸡+猪!=numHeads:
返回[无,无]
返回[猪,小鸡]
当然,如果你通过分数的头或腿,所有的赌注都是无效的。这是一个完整的测试程序,您可以尝试各种值,以确保两种方法返回相同的值:

def solve (numLegs, numHeads):
    # Use the formulae (these make integers).
    chicks = numHeads * 2 - int (numLegs / 2)
    pigs = numHeads - chicks

    # Don't allow negative number of animals.
    if chicks < 0 or pigs < 0:
        return [None, None]

    # Don't allow fractional animals.
    if chicks * 2 + pigs * 4 != numLegs:
        return [None, None]
    if chicks + pigs != numHeads:
        return [None, None]

    return [pigs, chicks]
导入系统 def使用(原因): “打印”错误:%s
    L = 2C + 4P
=>  L = 2C + 4(H - C)   [substitute H-C for P]
=>  L = 2C + 4H - 4C    [expand 4(H-C) to 4H-4C]
=>  L = 4H - 2C         [combine 2C-4C into -2C]
=>  0 = 4H - 2C - L     [subtract L from both sides]
=> 2C = 4H - L          [add 2C to both sides]
=>  C = 2H - L/2        [divide both sides by 2] (4)
def solve (numLegs, numHeads):
    # Use the formulae (these make integers).
    chicks = numHeads * 2 - int (numLegs / 2)
    pigs = numHeads - chicks

    # Don't allow negative number of animals.
    if chicks < 0 or pigs < 0:
        return [None, None]

    # Don't allow fractional animals.
    if chicks * 2 + pigs * 4 != numLegs:
        return [None, None]
    if chicks + pigs != numHeads:
        return [None, None]

    return [pigs, chicks]
import sys

def usage (reason):
    print "Error: %s"%(reason)
    print "Usage: solve <numHeads> <numLegs>"
    sys.exit (1);

def solve1 (numLegs, numHeads):
    for numChicks in range (0, numHeads + 1):
        numPigs = numHeads - numChicks
        totLegs = 4 * numPigs + 2 * numChicks
        if totLegs == numLegs:
            return [numPigs, numChicks]
    return [None, None]

def solve2 (numLegs, numHeads):
    chicks = numHeads * 2 - int (numLegs / 2)
    pigs = numHeads - chicks
    if chicks < 0 or pigs < 0:           return [None, None]
    if chicks * 2 + pigs * 4 != numLegs: return [None, None]
    if chicks + pigs != numHeads:        return [None, None]
    return [pigs, chicks]

if len (sys.argv) != 3:
    usage ("Wrong number of parameters (%d)"%(len (sys.argv)))

try:    heads = int (sys.argv[1])
except: usage ("Invalid <numHeads> of '%s'"%(sys.argv[1]))

try:    legs = int (sys.argv[2])
except: usage ("Invalid <numLegs> of '%s'"%(sys.argv[2]))

print "[pigs, chicks]:"
print "  ", solve1 (legs, heads)
print "  ", solve2 (legs, heads)