首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >不断计算素数块

不断计算素数块
EN

Code Review用户
提问于 2016-07-13 21:39:12
回答 1查看 69关注 0票数 1
代码语言:javascript
运行
复制
import math
import time
import sys
import random
import os

def isPrime(number):
    if number % 2 != 0:
        for i in range (3,math.floor(number**0.5)+1,2):
            if number % i == 0:
                return False
    else:
        if number != 2:
            return False
    return True

def makeListInts(lst):
    for item in range(len(lst)):
        try:
            lst[item] = int(lst[item])
        except:
            try:
                lst[item] = float(lst[item])
            except:
                pass
    return lst

def getData():
    with open('CurrentProgress.txt') as data:
        return makeListInts([line[:-1].split(': ')[1] for line in data.readlines()])

def setData(data, ID):
    titles = [
    'Start: ' + str(data[1] + 1),
    'End: ' + str(data[1] + data[2]),
    'Step: ' + str(data[2]),
    'Time: ' + str(time.time()),
    'IDsRegistered: ' + ID]
    with open('CurrentProgress.txt','w') as data:
        for item in titles:
            data.write(str(item)+'\n')

def checkFileProgress(data):
    files = os.listdir('Calculated Primes/')                    #List all primes files
    filesStripped = [int(i.split('-')[1][:-4]) for i in files]  #Get the end numbers of each file
    filesStripped.sort()                                        # and sort
    diffs = [filesStripped[i+1] - filesStripped[i] for i in range(len(filesStripped)-1)]
    lastFileEnd = filesStripped[-1]
    #print (diffs, sum(diffs) / len(diffs))
    if max(diffs) != sum(diffs) / len(diffs):  #If there is one that should not be there (max != avg)
        indx = diffs.index(max(diffs))
        print (indx)
        data = [filesStripped[indx-1] + 1, filesStripped[indx-1] + data[2], data[2], data[3],data[4]] #Go back to there
        setData(data,data[-1])
    elif lastFileEnd + 1 != data[0]:  # Otherwise, if the last file is before the recoreded end , go back there
        data = [lastFileEnd - data[2] + 1, lastFileEnd, data[2], data[3], data[4]]
        setData(data, data[-1])

def setMyID(currentIDs):
    possibleIDs = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']
    if currentIDs == ' ':
        return possibleIDs[0]
    else:
        try:
            return possibleIDs[possibleIDs.index(currentIDs[-1]) + 1]
        except IndexError:
            return False

def removeMyID(data,ID):
    ID = data[-1].replace(ID,'')
    setData(data, ID)
    print ()


def writePrimes(listOfPrimes, data):
    direc = 'Calculated Primes/'
    with open(direc + 'Primes' + str(data[0]) + '-' + str(data[1]) + '.txt','w') as primes:
        for prime in listOfPrimes:
            primes.write(str(prime) + '\n')

def checkTime(dataTime):
    if dataTime + 1 > time.time():
        sleepTime = round(random.random()+1,3) #01179107383 James
        print ('Sleeping for ' + str(sleepTime) + ' to avoid collisions')
        time.sleep(sleepTime);
        return False
    else:
        return True

def makeBar(barWidth,data):
    print ('Calculating primes between ' + str(data[0]) + ' and ' + str(data[1]) + ':')
    sys.stdout.write("[%s]" % (" " * barWidth))
    sys.stdout.flush()
    sys.stdout.write("\b" * (barWidth+1)) # return to start of line, after '['

def updateBar():
    sys.stdout.write("==")
    sys.stdout.flush()

def closeBar():
    sys.stdout.write("\n")

def main(ID):
    data = getData()
    if checkTime(data[3]):
        barWidth = 40
        if ID in data[-1]:
            ID = data[-1]
        else:
            ID = data[-1] + ID
        setData(data,ID)
        makeBar(barWidth, data)
        listOfPrimes = []
        for number in range(data[0],data[1]):
            result = isPrime(number)
            if (number - 1) % round(data[2] / (barWidth / 2)) == 0:
                updateBar()
            if result:
                listOfPrimes += [number]
        writePrimes(listOfPrimes, data)
        closeBar()
    else:
        main(ID)

def setup():
    data = getData()
    if data[-1] == ' ':
        checkFileProgress(data)
    if checkTime(data[3]):
        ID = setMyID(data[-1])
        print (ID)
        if ID:
            try:
                while True:
                    main(ID)
            except KeyboardInterrupt:
                data = getData()
                removeMyID(data,ID)
                quit('Saving and Exiting')
        else:
            quit('Already 12 programs running')
    else:
        setup()

setup()

下面是它访问的文件(CurrentProgress.txt):

代码语言:javascript
运行
复制
Start: 381000001
End: 382000000
Step: 1000000
Time: 1468445801.017807
IDsRegistered:  

文件的最后一行有两个尾随空格。

它有一个ID函数,允许来自A的任何ID。如果已经有12,则阻止脚本运行。每个脚本都等待一个随机的时间来避免与其他脚本的冲突(无论如何,这是不可能的)。当脚本终止时,ID将被移除。因为文件是在计算完成之前更新的,所以当运行第一个脚本时,它会将文件设置为下一个块(通过检查文件)。这只发生在第一个脚本(即接受ID A的脚本)。同样,它检查块是否被跳过(如果脚本以错误的顺序终止)并跳回那里。

我意识到这段代码相当长(150行),所以如果你想选择一个函数来复习,它仍然会帮助我学习!

EN

回答 1

Code Review用户

发布于 2016-07-13 22:51:54

我将从几个项目和一个函数开始。

  • 我建议您对所有变量和函数使用小写。
  • 我还建议您在函数中使用小写和下划线,这样在大多数情况下都更容易阅读。您可以阅读python样式指南这里,以获得更多与其他python代码匹配的信息和建议。
  • 使变量名具有描述性将大大有助于使代码更容易理解,您可以在代码中使用所有的单词数据,但这是一个非常通用的单词。也许你可以试试writePrimes(listOfPrimes, data):而不是write_primes(prime_list, filename_list)
  • 不幸的是,代码现在很难理解,我认为为变量和方法提供更多的描述性名称将使我们更清楚地了解您在这里要做的事情。
  • 请注意,如果要列出大列表,我建议您使用xrange而不是range,因为xrange是懒惰的评估,范围在运行时对序列进行评估。
  • 最后一个注意事项,对于计算素数--通常是回忆录--最简单的方法是快速计算素数列表(尽管还有其他几种方法可以做到这一点)。以防你不知道想让你知道。

对于我选择的函数setData

代码语言:javascript
运行
复制
def setData(data, ID):
    titles = [
    'Start: ' + str(data[1] + 1),
    'End: ' + str(data[1] + data[2]),
    'Step: ' + str(data[2]),
    'Time: ' + str(time.time()),
    'IDsRegistered: ' + ID]
    with open('CurrentProgress.txt','w') as data:
        for item in titles:
            data.write(str(item)+'\n')

应分成两部分:

代码语言:javascript
运行
复制
def get_titles(data, id):
    return [
      'Start: {0}'.format(data[1] + 1),
      'End: {0}'.format(data[1] + data[2]),
      'Step: {0}'.format(data[2]),
      'Time: {0}'.format(time.time()),
      'IDsRegistered: ' + id]

def write_file(data, id):
"""Writes a file full of prime numbers

   data is a list consisting of a start and a step value,
   id is the name of the file registered"""
    with open('CurrentProgress.txt','w') as out_file:
        for item in get_titles(data, id):
            out_file.write(str(item)+'\n')

总之,我认为如果您始终在代码中使用更多的描述性名称,如果参数或方法名称不明确,则会更容易地查看哪些函数可以模块化,并给您提供更好的代码回顾。

编辑:还有一个功能

代码语言:javascript
运行
复制
def checkFileProgress(data):
    files = os.listdir('Calculated Primes/')                    #List all primes files
    filesStripped = [int(i.split('-')[1][:-4]) for i in files]  #Get the end numbers of each file
    filesStripped.sort()                                        # and sort
    diffs = [filesStripped[i+1] - filesStripped[i] for i in range(len(filesStripped)-1)]
    lastFileEnd = filesStripped[-1]
    #print (diffs, sum(diffs) / len(diffs))
    if max(diffs) != sum(diffs) / len(diffs):  #If there is one that should not be there (max != avg)
        indx = diffs.index(max(diffs))
        print (indx)
        data = [filesStripped[indx-1] + 1, filesStripped[indx-1] + data[2], data[2], data[3],data[4]] #Go back to there
        setData(data,data[-1])
    elif lastFileEnd + 1 != data[0]:  # Otherwise, if the last file is before the recoreded end , go back there
        data = [lastFileEnd - data[2] + 1, lastFileEnd, data[2], data[3], data[4]]
        setData(data, data[-1])

遵循上述同样的指导方针,可以这样写:

代码语言:javascript
运行
复制
def get_last_number(file):
    return int(file.split('-')[1][:-4])

def get_sorted_file_numbers(files):
    files_stripped = [get_last_number(i) for file in files]  # get the last number of each file
    files_stripped.sort()                                       # and sort
    return files_stripped

def get_diffs(file_numbers)
    return [file_numbers[i+1] - file_numbers[i] for i in range(len(file_numbers)-1)]

def get_file_data(diffs, file_numbers):
    last_file_number = file_numbers[-1]
    if max(diffs) != sum(diffs) / len(diffs):  #If there is one that should not be there (max != avg)
        indx = diffs.index(max(diffs))
        print (indx)
        data = [file_numbers[indx-1] + 1, 
                file_numbers[indx-1] + file_numbers[2],
                file_numbers[2], 
                file_numbers[3],
                file_numbers[4]] #Go back to there
        return data
    elif last_file_number = file_numbers[-1] + 1 != file_numbers[0]:  # Otherwise, if the last file is before the recoreded end , go back there
        data = [last_file_number - file_numbers[2] + 1,
                last_file_number,
                file_numbers[2],
                file_numbers[3],
                file_numbers[4]]
        return data

def checkFileProgress(data):
    files = os.listdir('Calculated Primes/')                    #List all primes files
    file_numbers = get_sorted_file_numbers(files)
    diffs = get_diffs(file_numbers)
    prime_data = get_file_data(diffs, file_numbers)
    write_file(prime_data, prime_data[-1])

使您的代码模块化允许它是一个接一个的可测试性。然后,您只需使用一个小的差异和file_numbers列表来测试file_numbers。以确保您获得的数据是正确的。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/134809

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档