【问题标题】:why does this python while loop not work in the program?为什么这个 python while 循环在程序中不起作用?
【发布时间】:2019-08-19 22:48:23
【问题描述】:

我正在尝试运行以下文章中的程序:

https://blockgeeks.com/guides/python-blockchain-2/

我已将所有代码复制到我的 Spyder IDE 中。当我运行它时,会有一个 while 循环开始要求用户从它打印的选项列表中选择一个数字。

选择数字后,程序应执行请求的操作。当我选择它时,它只是循环回到 while 循环的开头。

它似乎忽略了 while 循环中的其余代码(if 语句部分)。

令人困惑的是,如果我从程序中获取 while 循环中使用的部分代码并单独运行它们,它们就会起作用,即,如果我运行以下代码并选择数字 1,它将运行if 语句。

为什么 if 语句会在这里运行,而不是在主程序中?

#function 1:
def get_user_choice():

   user_input = input("enter a number: ")

   return user_input

#function 2:
def get_transaction_value():

   tx_recipient = input('Enter the recipient of the transaction: ')

   tx_amount = float(input('Enter your transaction amount '))

   return tx_recipient, tx_amount

while True:
   print("Choose an option")

   print('Choose 1 for adding a new transaction')

   print('Choose 2 for mining a new block')

   print('Choose 3 for printing the blockchain')

   print('Choose anything else if you want to quit')

   user_choice = get_user_choice()



   if user_choice == '1':
       tx_data = get_transaction_value()
       print(tx_data)

更新: 抱歉,我意识到我可能不是很清楚问题是什么。

以上代码是整个程序代码的一部分,独立于主程序运行。

下面的代码是链接中文章的整个程序。它包括程序中的所有代码。如果我运行这个主程序,while 循环不使用 if 语句。在我选择 1、2 或 3 后,它似乎只是直接跳出循环(任何其他数字都应该跳出循环)。

这是一个屏幕截图链接,显示了我为选项选择数字 1 后控制台的外观。

https://ibb.co/RNy2r0m

# Section 1
import hashlib

import json



reward = 10.0



genesis_block = {

   'previous_hash': '',

   'index': 0,

   'transaction': [],

   'nonce': 23

}

blockchain = [genesis_block]

open_transactions = []

owner = 'Blockgeeks'



def hash_block(block):

   return hashlib.sha256(json.dumps(block).encode()).hexdigest()

# Section 2
def valid_proof(transactions, last_hash, nonce):

   guess = (str(transactions) + str(last_hash) + str(nonce)).encode()

   guess_hash = hashlib.sha256(guess).hexdigest()

   print(guess_hash)

   return guess_hash[0:2] == '00'



def pow():

   last_block = blockchain[-1]

   last_hash = hash_block(last_block)

   nonce = 0

   while not valid_proof(open_transactions, last_hash, nonce):

       nonce += 1

   return nonce

# Section 3
def get_last_value():

   """ extracting the last element of the blockchain list """

   return(blockchain[-1])



def add_value(recipient, sender=owner, amount=1.0):

   transaction = {'sender': sender,

   'recipient': recipient,

   'amount': amount}

   open_transactions.append(transaction)

# Section 4

def mine_block():

   last_block = blockchain[-1]

   hashed_block = hash_block(last_block)

   nonce = pow()

   reward_transaction = {

           'sender': 'MINING',

           'recipient': owner,

           'amount': reward

       }

   open_transactions.append(reward_transaction)

   block = {

       'previous_hash': hashed_block,

       'index': len(blockchain),

       'transaction': open_transactions,

       'nonce': nonce

   }

   blockchain.append(block)

# Section 5

def get_transaction_value():

   tx_recipient = input('Enter the recipient of the transaction: ')

   tx_amount = float(input('Enter your transaction amount '))

   return tx_recipient, tx_amount



def get_user_choice():

   user_input = input("Please give your choice here: ")

   return user_input

# Section 6

def print_block():

   for block in blockchain:

       print("Here is your block")

       print(block)

# Section 7

while True:

   print("Choose an option")

   print('Choose 1 for adding a new transaction')

   print('Choose 2 for mining a new block')

   print('Choose 3 for printing the blockchain')

   print('Choose anything else if you want to quit')

   user_choice = get_user_choice()



   if user_choice == 1:

       tx_data = get_transaction_value()

       recipient, amount = tx_data

       add_value(recipient, amount=amount)

       print(open_transactions)



   elif user_choice == 2:

       mine_block()



   elif user_choice == 3:

       print_block()



   else:

       break


  [1]: https://i.stack.imgur.com/FIrn7.png

【问题讨论】:

  • 你能显示你的控制台输出吗?
  • 另外,请告诉我们您使用的是 Python 2 还是 Python 3。它们各自的 input() 函数存在差异。
  • 上面的代码只处理选项1,但是如果用户输入了1,函数get_transaction_value就会被调用。那你的问题是什么?
  • 我怀疑 OP 使用的是 Python 2。它的 input() 解释用户输入的内容并返回(数字)1 而不是纯字符串。实际上,当用户在该上下文中输入 1 时,1 == '1' 甚至都不匹配。
  • 您的更新部分因类似原因而失败,反之亦然。在 Python 3 中,input() 返回一个字符串。您将此字符串与数字进行比较,数字始终为False(它可能在 Javascript 中以这种方式工作,但在 Python 中则不然)。请改用user_choice == '1'(注意引号)。

标签: python while-loop


【解决方案1】:

在比较值时,Python 在数据类型方面比其他一些语言采取了更强硬的路线。这意味着 Python 中没有字符串会等于数字。

或者换句话说,"1" == 1 将是False

这意味着您必须考虑在 Python 3 中您会收到来自 input() 的字符串(在 Python 2 中不一定如此)。

您可以直接将其与另一个字符串进行比较:

user_choice = input()

if user_choice == "1":
    print("You chose item 1")

或者你可以先把它转成数字再和数字比较:

user_choice = int(input())

if user_choice == 1:
    print("You chose item 1")

请注意,在前一种情况下,如果用户输入额外的空格,它可能不可靠,而在后一种情况下,如果用户不输入整数(或什至什么都不输入),它会异常大声地失败。

如有必要,这两种方式都可以通过额外的代码来处理。在前一种情况下,您可以使用user_input = input().strip() 去除空格,在后一种情况下,您可以使用try ... except ... 块捕获异常。

【讨论】:

    【解决方案2】:

    您只处理了user_choice == '1' 的案件。如果输入 1 以外的任何值,程序会将控制权返回到 while 循环的开头。

    我建议您使用调试器查看 if 条件之前的 user_choice 是什么。如果没有,请使用打印。

    print("user_choice: {}, type: {}".format(user_choice, type(user_choice))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-18
      • 1970-01-01
      • 1970-01-01
      • 2015-11-16
      • 2016-07-23
      • 2023-02-11
      相关资源
      最近更新 更多