Text class in Python Here is a class named Text, which takes a string as its argument of its constructor. It has property-methods to get the words in the string and also the frequency of alphabets occuring in it.

The words property result in all words in the string. It works as follows, after using the .split method, there is a possibility that a "word" is of the form ,word or word. or ,word. etc. So to encounter this we check each end using .isalpha.

We also have find_words method, which has words as its inputs. This method will summarize the frequencies of a set of words.

How can I write this better to:


The level of a library/package (I don't really understand the techniques for this)
More efficient and readable (using re module is last option)
More functional, but compact




#Author: Arief. A

example = "This is an example, an Anonymous text.\
 This text has 59 letters or numbers.";


class Text:

    def __init__(self, input_text):
        self.text = input_text;

    def show(self):
        print(self.text);

    def as_list(self):
        return list(self.text);

    def get_length(self):
        return len(self.text);

    def count_char(self, char):
        return self.text.count(char);

    @property          
    def letter_freqs(self):
        letters="abcdefghijklmnopqrstuvwxyz";
        res={i: self.count_char(i) \
             for i in letters};
        caps={i.capitalize(): self.count_char(i.capitalize()) \
             for i in letters};
        res.update(caps);
        return res

    @property   
    def words(self):
        raw=self.text.split();
        for i in range(len(raw)):
            if not raw[i][0].isalpha():
                raw[i]=raw[i][1:];
            if not raw[i][-1].isalpha():
                raw[i]=raw[i][0:-1];
        [raw.remove('') for i in range(raw.count(''))];
        return raw            

    def swap_first(word):
        swaped=word[0].swapcase();
        res=swaped+word[1:];
        return res

    def find_words(self, *args):
        return {i: self.words.count(i)\
                      +self.words.count(Text.swap_first(i))\
                      for i in args};


Example

text_obj=Text(example);
text_obj.show();
print(text_obj.as_list());
print(text_obj.get_length());
print(text_obj.count_char("a"));
print(text_obj.words)
print(text_obj.find_words("Anonymous", "Text","This"));


Output



This is an example, an Anonymous text. This text has 59 letters or numbers.
['T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', 'n', ' ', 'e', 'x', 'a', 'm', 'p', 'l', 'e', ',', ' ', 'a', 'n', ' ', 'A', 'n', 'o', 'n', 'y', 'm', 'o', 'u', 's', ' ', 't', 'e', 'x', 't', '.', ' ', 'T', 'h', 'i', 's', ' ', 't', 'e', 'x', 't', ' ', 'h', 'a', 's', ' ', '5', '9', ' ', 'l', 'e', 't', 't', 'e', 'r', 's', ' ', 'o', 'r', ' ', 'n', 'u', 'm', 'b', 'e', 'r', 's', '.']
75
4
['This', 'is', 'an', 'example', 'an', 'Anonymous', 'text', 'This', 'text', 'has', 'letters', 'or', 'numbers']
{'This': 2, 'Text': 2, 'Anonymous': 1}
Instead of letters="abcdefghijklmnopqrstuvwxyz"; use a built-in constant:

letters = string.letters;

The code only inspects first and last character of the word. It means that aaa.bbb will be treated as a single word. Is this an intent?
split(sep) allows a string of separators. Calling it with

raw = self.text.split(string.punctuation + string.whitespace)


eliminates the need to inspect individual words. If you still want to inspect them, a loop for i in range(len(raw)): should be written more idiomatically as

for word in raw:


(you don't really need i anywhere in the loop).