我的 python 在基数之间转换数字的代码有几个错误。可能出了什么问题,我怎样才能找到它们?

My python code that converts numbers between bases has several errors. What could be wrong and how can I find them?

我的程序是一个将数字从一个基数转换为另一个基数的函数。它需要三个参数:初始值,初始值的基数,然后是要转换成的基数。

这个东西有几个错误。首先,它不会接受任何包含 cnum 字母的值。我不知道为什么。而且我似乎无法弄清楚如何强制将参数 'cnum' 识别为函数调用中的字符串。我必须在代码本身中将其转换为函数。

此外,我无法使后半部分(将数字转换为最终基数的部分)正常工作。它要么给我一个无限循环(出于某种原因我无法弄清楚),要么它不进行完整的计算。这个,如果我输入 fconbase(100, 10, 12) 应该将 100 从 base 10 转换为 base 12。它只会吐出 8。答案应该是 84.

这是我的全部功能。

    #delcaring variables

cnum=0 #number to be converted
cbase1=0 #base the number is written in
cbase2=0 #base the number will be converted to
cnumlen=0 #number of digits
digitNum=0 #used to fetch out each digit one by one in order
exp=0 #used to calculate position in result
currentDigit="blank" #stores the digit that's been pulled from the string
result=0 #stores the result of internal calculations
decimalResult=0 #stores cnum as a base 10 number
finalResult=0 #the final result of the conversion

def fconbase(cnum, cbase1, cbase2):
    #converts number into base 10, because the math must be done in base 10
    #resets variables used in calculations
    exp=0
    result=0
    decimalResult=0
    currentDigit="blank"
    cnumlen=len(str(cnum)) #finds length of cnum, stays constant
    digitNum=cnumlen #sets starting placement
    while exp<cnumlen:
        currentDigit=str(cnum)[digitNum-1:digitNum]
        #the following converts letters into their corresponding integers
        if currentDigit=="a" or currentDigit=="A":
            currentDigit="10"
        if currentDigit=="b" or currentDigit=="B":
            currentDigit="11"
        if currentDigit=="c" or currentDigit=="C":
            currentDigit="12"
        if currentDigit=="d" or currentDigit=="D":
            currentDigit="13"
        if currentDigit=="e" or currentDigit=="E":
            currentdigit="14"
        if currentDigit=="f" or currentDigit=="F":
            currentDigit="15"
        result=int(currentDigit)
        decimalResult=decimalResult+result*(cbase1**exp)
        exp=exp+1
        digitNum=digitNum-1
    #this part converts the decimal number into the target base
    #resetting variables again
    exp=0
    result=0
    finalResult=""
    while int(decimalResult)>(cbase2**exp):
        exp=exp+1
    exp=exp-1
    while int(decimalResult)/cbase2**exp!=int(decimalResult):
        result=int(decimalResult/(cbase2**exp))
        if result==10:
            result="a"
        if result==11:
            result="b"
        if result==12:
            result="c"
        if result==13:
            result="d"
        if result==14:
            result="e"
        if result==15:
            result="f"
        finalResult=str(finalResult)+str(result)
        decimalResult=decimalResult%cbase2**exp
        exp=exp+1
    print(finalResult)

下面是等式后半部分应该发生的情况:

程序求解cbase2^exp。 Exp 从 0 开始。如果该数字小于 decimalResult,则它将 exp(onent) 增加 1 并再次尝试,直到产生大于 decimalResult 的数字。

然后,它将 decimalResult 除以 cbase2^exp。它将 10 到 15 之间的数字转换为字母(对于大于 10 的基数),然后将结果附加到最终结果。它应该将结果连接在一起以形成打印的最终结果。我不明白为什么它不这样做。

为什么它没有生成正确的结果,为什么我不能在函数调用中输入字符串?

你应该使用第一步找到的exp:

while int(decimalResult)>=(cbase2**exp):
    exp=exp+1
exp -= 1
while exp >= 0:
    ...
    finalResult=str(finalResult)+str(result)
    decimalResult=decimalResult%cbase2**exp
    exp -= 1

首先,不需要代码的整个第一部分,因为 int 函数会为您完成。您可以这样做,而不是所有这些。

int(cnum, base=cbase1)

这会将 cnum 从 cbase1 转换为基数 10。

第二部分可能会进入无限循环,因为在底部,它说

exp = exp + 1

什么时候该说

exp = exp - 1

因为您想从(例如)5^2 到 5^0。

结果没有最后一位是因为它在 exp = 0 时跳出循环。 它实际上并没有将数字添加到结果中。一个简单的解决方法是

finalResult = str(finalResult) + str(decimalResult)

在不讨论您的代码的具体问题的情况下,正如您所说的那样,我将简要回答标题中的实际问题

What could be wrong and how can I find [the errors in my code]?

与其将你的代码视为一个你必须同时盯着看并理解所有内容的大型复杂函数(我很少能在我自己的内部大脑缓存中同时保存超过 10 行代码),不如尝试打破它分成小块 "first I do this and expect this result. Then I take that result and do this to it, and expect another result."

从您对问题的描述来看,您似乎已经在这么想了,但是您仍然丢弃了这么一大块代码,并且似乎在努力找出问题的确切位置。很多初学者会写一大堆代码,然后把它当作一个黑盒子来测试。像 "I'm not getting the right answer and I don't know where the problem begins." 这就是学习良好的调试技巧至关重要的地方。

我会首先将事情分解成更小的部分,然后在交互式 Python 提示符下尝试。为不同的变量输入虚拟值,并确保一小段代码(1 到 5 行左右,小到易于推理)完全按照您对变量的不同值的预期执行。

如果这没有帮助,那么对于初学者来说,通常适用于初学者和高级开发人员的行之有效的方法是用 print 语句来打乱您的代码。在您认为有必要的许多地方,放置一条语句来打印一个或多个变量的值。喜欢print("exp = %s; result = %s" % (exp, result)。把这个放在你需要的地方,在执行过程中跟踪一些变量的值。查看它从哪里开始给出没有意义的答案。

虽然有时候这很难做到。您可能无法猜出放置 print 语句的最有效位置,甚至无法猜出打印的重要内容。在这种情况下(在大多数情况下是 IMO),使用像 Python 内置于 pdb 中的交互式调试器会更有效。有很多很好的学习资源 pdb 但基础知识不应该花太长时间才能掌握,并且会让您省去很多麻烦。

pdb 将 运行 您的代码 line-by-line,在每一行之后停止(并且在循环中它将逐步执行循环中的每个循环),允许您检查的内容每个变量在前进到下一行之前。这使您能够完全检查代码的每个部分是否按照您的预期进行,并且应该可以帮助您查明许多问题区域。