我正在创建一个程序,用户可以输入4到5000之间的偶数,程序将输出一对素数对列表,这些素数总和了输入中提供的数字。
我的程序可以很好地将所有素数放在一个列表中并检查输入是4到5000之间的偶数。对于小输入它可以很好地工作但是对于较大的输入它表示“列表索引不在范围“我不明白为什么。
这是我使用的代码:(添加评论以帮助)
ColorChangingLabel
对于少数人来说这很有效。例如
//
// CustomLabel.swift
// CustomLabel
//
// Created by Duncan Champney on 4/20/17.
// Copyright © 2017 Duncan Champney. All rights reserved.
//
import UIKit
let labelColorChangedNotice: NSNotification.Name = NSNotification.Name("labelColorChangedNotice")
let textColorKey = "textColor"
let backgroundColorKey = "backgroundColor"
class CustomLabel: UILabel {
static var classLabelColorChangeObserver: Any!
static var startingTextColor: UIColor?
static var startingTextBGColor: UIColor?
override class func initialize() {
//Have the CustomLabel class add an observer to record changes to the text color and/or background color even if there are no CustomLabel instances on-screen.
classLabelColorChangeObserver = NotificationCenter.default.addObserver(forName: labelColorChangedNotice,
object: nil,
queue: nil ) {
notification in
if let textColor = notification.userInfo?[textColorKey] as? UIColor {
CustomLabel.startingTextColor = textColor
}
if let backgroundColor = notification.userInfo?[backgroundColorKey] as? UIColor {
CustomLabel.startingTextBGColor = backgroundColor
}
}
}
var labelColorChangeObserver: Any?
override init(frame: CGRect) {
super.init(frame: frame)
labelColorChangeObserver = addLabelColorChangedObserver()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
labelColorChangeObserver = addLabelColorChangedObserver()
}
deinit {
if let labelColorChangeObserver = labelColorChangeObserver {
NotificationCenter.default.removeObserver(observer: labelColorChangeObserver)
}
}
func addLabelColorChangedObserver() {
if let startingTextColor = CustomLabel.startingTextColor {
self.textColor = startingTextColor
}
if let startingTextBGColor = CustomLabel.startingTextBGColor {
self.backgroundColor = startingTextBGColor
}
labelColorChangeObserver = NotificationCenter.default.addObserver(forName: labelColorChangedNotice,
object: nil,
queue: nil ) {
[weak self] //Use a capture list to avoid a retain cycle
notification in
//Once we're in the notification's closure, capture self strongly, or bail if it's nil.
guard let strongSelf = self else {
return
}
//If we've been given a textColor, install it in the label.
if let textColor = notification.userInfo?[textColorKey] as? UIColor {
strongSelf.textColor = textColor
}
//If we've been given a backgroundColor, install it in the label.
if let backgroundColor = notification.userInfo?[backgroundColorKey] as? UIColor {
strongSelf.backgroundColor = backgroundColor
}
}
}
}
但是对于像800这样的更大的数字(实际上它的任何数字,如果有帮助的话,由于某种原因超过668)那么它会说“IndexError:list index out of range”
global prime_numbers
prime_numbers=[]
user_number=0
def start():
for i in range(5000):
prime_test(i)
def prime_test(a):
global prime_numbers
x = True
for i in range(2, a):
while x:
if a%i == 0:
x = False
break
else:
x = True
break
if x==True and a!=0 and a!=1:
prime_numbers.append(a)
#print(prime_numbers[int(len(prime_numbers)-1)])#
#prints last digit/\ /\ /\ (for testing purposes)#
if a==4999:
user_input()
def user_input():
user_number=input('please enter a whole even number between 4 and 5000: ')
#checks if user input is valid#
try:
#checks for a number#
user_number=float(user_number)
#checks for an integar#
if user_number!=int(user_number):
print('that is not a whole number')
user_input()
#checks for an even number#
a=(user_number/2)
if a!=int(a):
print('that is not an even number')
user_input()
#checks it is inbetween 4 and 5000#
elif user_number<4:
print('that is not greater than or equal to 4')
user_input()
elif user_number>5000:
print('that is not less than or equal to 5000')
user_input()
#if it is a valid input it procedes to the next section#
else:
q=int(user_number)
goldbergs_conjecture(q)
#the bit that checks to see if it is a number#
except ValueError:
print('that is not a number')
user_input()
def goldbergs_conjecture(q):
global prime_numbers
for i in range(q):
#serches for the first prime number in the list then the second ect...#
x=prime_numbers[i]
#y= user input minus a prime number form the list#
y=q-x
#if y is also in the list then it must be prime also so these are printed#
if y in prime_numbers and x<(q/2):
print(str(x) + ' + ' + str(y))
#had to add this seperatly because if they were the same then this /\/\ didnt catch them#
if y==x:
print(str(x) + ' + ' + str(y))
#gives the user something to look at whilst the list is generating#
print('loading...')
start()
我不知道为什么在668之后这不起作用。
答案 0 :(得分:2)
您正在goldbergs_conjecture()
上方range(q)
),x=prime_numbers[i]
,可以是4..5000。
但您正在寻找此值:prime_numbers
这是prime_numbers
列表的索引。
range(q)
列表不能保证与prime_numbers
一样长,因为(根据定义)更少素数而不是给定范围内的整数。
在请求输入之前,请尝试打印for prime in prime_numbers:
if prime >= q:
break
... do something with prime
列表的长度。我打赌它接近668.
相反,您可以尝试以下方式:
q
覆盖小于{{1}}的所有素数。
答案 1 :(得分:0)
它会中断,因为0到5000之间的素数小于5000(如果你在讲述错误的条件时没有犯错,那么它可能小于668)。我建议使用第59行使用范围(len(prime_numbers))而不是范围(q)(你也可以使用enumerate
函数)
答案 2 :(得分:0)
所以,我最重要的建议:除非你真的需要,否则不要使用try。它会隐藏代码错误。除非你真的需要,否则避免全局变量。它会让你的大脑在一段时间后头晕。
在你的代码中,第二个罪是问题的根源。您正在运行范围(q)中的for循环,该循环指向prime_numbers [i]。绑定这些索引意味着两个列表需要具有相同的大小,或者primenumber应该小于q。在print(i)
循环的开头写for i in range(q)
并打印(len(prime_numbers))。当我&gt;你会看到脚本中断LEN(prime_numbers)
要避免尝试,请为输入编写正则表达式。 要避免全局,请将列表作为函数参数传递,或在prime_number列表上运行循环。
希望这有帮助。