PythonDabbler
PythonDabbler

Reputation: 3

.txt File Not Reading and Writing Correctly in Python 3.3.3

Anyway, I have been trying to read and write to a text file in Python 3.3.3, and it has not been working. My code is as follows:

import math
pFile=open('/Users/Username/Desktop/Programming:Design/Program Access Files/primes.txt')
pList=[]
for line in pFile:
    pList=pList+(int(line.strip()))
def testPrime(num,pList):
    if num<=1:
        return False
    testList=[]
    place=0
    sqrt=math.sqrt(num)-((math.sqrt(num))%1)
    p=pList[place]
    while p<=sqrt:
        testList.append(p)
        place=place+1
        p=pList[place]
    for i in testList:
        if i%num==0:
            return False
    return True
print('Hello and Welcome to the Prime Finder 000!')
end=int(input('What integer would you like me to go to today?'))
for j in range(pList[-1],end+1):
    if testPrime(j,pList)==True:
        pList.append(j)
        print(j)
pFile.close()
pFile=open('/Users/Username/Desktop/Programming:Design/Program Access Files/primes.txt','w')
for k in pList:
    pFile.write(str(k))
    pFile.write('\r\n')
pFile.close()

This program is supposed to search through all positive integers to find prime numbers. The text file I am trying to store found primes in is 'primes.txt', in the directory shown when I try to open it. However, something must be wrong with my method of reading the file, namely this:

pFile=open('/Users/Username/Desktop/Programming:Design/Program Access Files/primes.txt')
    pList=[]
    for line in pFile:
        pList=pList+(int(line.strip()))

I am certain that my function for finding primes works, but they are not storing correctly. Currently, what the program does is wipes the text file 'primes.txt' and prints out every number from 2 to the number inputted by the user as a prime, in an order I haven't found yet.

Upvotes: 0

Views: 1320

Answers (2)

dawg
dawg

Reputation: 103744

I have (roughly) rewritten your example to show you what are considered better idioms.

First, your prime finder probably is great by I used one based on testing just a single number:

def isprime(n):
    '''check if integer n is a prime'''
    # make sure n is a positive integer
    n = abs(int(n))
    # 0 and 1 are not primes
    if n < 2:
        return False
    # 2 is the only even prime number
    if n == 2: 
        return True    
    # all other even numbers are not primes
    if not n & 1: 
        return False
    # range starts with 3 and only needs to go up the squareroot of n
    # for all odd numbers
    for x in range(3, int(n**0.5)+1, 2):
        if n % x == 0:
            return False
    return True

Next, I don't know what is in your source file. Here I just took you same question of 'how far' and then show what is a better way to read and write that file:

print('Hello and Welcome to the Prime Finder 000!')
end=int(input('What integer would you like me to go to today?'))

with open('/tmp/nums.txt', 'w') as fout:
    for n in range(1,end+1):
        fout.write('{}\n'.format(n))

Finally, read the file in of integers 2-end and test each for primality in turn. Write the primes to a new file prime.txt:

with open('/tmp/nums.txt') as f, open('/tmp/primes.txt', 'w') as fout:
    for n in f:
        n=int(n)
        if isprime(n):
            print(n)
            fout.write('{}\n'.format(n))

If you want to have a list of primes, here is how you append to the list:

primes=[]        
with open('/tmp/nums.txt') as f:
    for n in f:
        n=int(n)
        if isprime(n):
            print(n)
            primes.append(n)

Several things to note:

  1. Use of with keyword to open a file. Your file will automatically close at the end.
  2. The file is used as an iterator since there is no reason to read the entire file into memory in this case
  3. There is no need to do int(line.strip()) for each line with a carriage return. int strips the whitespace first so int('12\r\n') works fine
  4. pList+(int(line.strip())) is probably a TypeError since you cannot concatenate an int to a list. Use pList.append(int(line)) instead.

Upvotes: 0

catwalker333
catwalker333

Reputation: 223

Ya, as @maurelio79 and @DSM said, looks like you're reading from and writing to the same file here and you're adding an int to list...which should be impossible. Also, using with to open files is cleaner:

pList = []
with open(fle_path, 'r') as fle:
   for line in fle:
      pList.append(int(line.rstrip("\n")))


#find and append new primes to pList using pList.append(<new prime>)


with open(fle_path, 'a') as fle: 
   for item in pList:
      fle.write(str(item)+"\n")

Use 'r' to read the file, 'w' to start a with a blank file every time, use 'a' to append to the existing file. You can use the same file, but use the 'a' argument to append newly found primes.

Using with statements automatically closes the file when it exists the loop.

Upvotes: 1

Related Questions