marduc812 marduc812 - 4 months ago 9
Python Question

Check if there are different characters that are written once

I made a small script that opens a file, gets it's size and writes the size of the file in zeros or ones depending on what is needed.

def firstDeletion(filepath, txt):
multiplier = getSize(filepath)
with open(filepath, "w") as text_file:
text_file.write(multiplier * txt)


After that I want it to verify that there is only the given character in the file. The way I tried to do it is below, but I think my approach is wrong

def checkFile(file,phrase):
with open(file, 'r') as resultfile:
for line in resultfile:
if (not phrase) in resultfile: #if found character different than phrase in resultfile
return False
else:
return True #No other char found


I think that it checks if my given character isn't at all in the text file instead of checking if there is another character also. I tried reading a character a time and check if they match, but I'm getting an error. And I don't like this method since I'm afraid that if I do just read in case a file is large (like 1 or 2GB the script will crash because of the memory)

def checkFile(file,char):
letter = file.read(1)
if letter == char:
return True
else:
return False


The error i get is:
AttributeError: 'str' object has no attribute 'read'


I'm completely new to python and it's a little bit messed up in my mind sorry.

Answer

If it's just a single character you are concerned about (not a word or a phrase that can be broken between two lines), then you were very close with your first attempt.

def checkFile(file,phrase):
    with open(file, 'r') as resultfile:
        for line in resultfile:
            if not all(char == phrase for char in line): # here you need to work with line, not the file object
                return False
            else:  # This else is redundant, because you can only return from a function once
                return True

I rewrote this using a generator expression and improved Python style. You were shadowing the built-in name file and violating several PEP8 recommendations.

def only_char_in_file(fp, target_char):
    with open(fp) as result_file:
        return all(char == target_char for line in result_file for char in line.strip())

Update Both methods above process files lazily (only a single line is read into memory). If your file contains a single huge line, then you need a special way to treat it. This method will work significantly slower then the former two, because it implies a lot more IO and low-level stuff works slower in Python than high-level abstractions (because the later actually run in C). Anyway:

import os


def only_char_in_file(fp, target_char):
    with open(fp) as f:
        char = f.read(1)
        while char:
            if char not in (target_char, os.linesep):
                return False
            char = f.read(1)
        return True
Comments