0

I created the following class to generate prime numbers in python:

class primeGen:
    def __init__(self, maxNum):
        self.allNum = [0]*(maxNum+1)
        self.allNum[0], self.allNum[1] = 1, 1
        self.primeNum = []
        for i in range(2, int(math.sqrt(maxNum))+1):
            if self.allNum[i] is 0:
                for j in range(i*i, len(self.allNum), i):
                    self.allNum[j] = 1
        for i in range(maxNum):
            if self.allNum[i] is 0:
                self.primeNum.append(i)

    def print(self):
        print(self.primeNum)

Is there a way to avoid using self parameter in functions multiple times? Like, instead of using self.primeNum every time, can I use only primeNum ?

Atulya Jha
  • 153
  • 1
  • 2
  • 10
  • 1
    Could you use temporary local variables and then assign it to the class variable at the end? – Random Davis Oct 19 '20 at 15:45
  • sometimes it is OK to try - and if you fail is not such a big deal - so just go ahead and remove self. from self.allNum and see what happens for yourself - rest assured, your computer won't explode... – pygri Oct 19 '20 at 15:47
  • How else would Python understand that you are referring to an `instance variable`? – PM 77-1 Oct 19 '20 at 15:50
  • You have to rewrite your class anyway. What's the use of the print function? It would be much better if you just created a ``generator`` instead of printing a list of primes. Have a look: https://docs.python.org/3/howto/functional.html#generators – Yaroslav Nikitenko Oct 19 '20 at 15:52
  • Your [mre] should always include any imports - `import math` in this case. – wwii Oct 19 '20 at 15:52
  • Related: [What is the purpose of the word 'self'?](https://stackoverflow.com/questions/2709821/what-is-the-purpose-of-the-word-self) – wwii Oct 19 '20 at 15:57
  • 1
    It would be good to add that you use the sieve of Eratosthenes. Also call the values `True` and `False` instead of 1 and 0 - to improve readability. – Yaroslav Nikitenko Oct 19 '20 at 15:58

3 Answers3

2

In Python, self is used to reference the current instance. Unless you need to keep those values as attributes of your primeGen instances, you can just remove them. You can read more about it here.

Example:

class primeGen:
    def __init__(self, maxNum):
        allNum = [0]*(maxNum+1)
        allNum[0], allNum[1] = 1, 1
        self.primeNum = []
        for i in range(2, int(math.sqrt(maxNum))+1):
            if allNum[i] is 0:
                for j in range(i*i, len(allNum), i):
                    allNum[j] = 1
        for i in range(maxNum):
            if allNum[i] is 0:
                self.primeNum.append(i)

    def print(self):
        print(self.primeNum)

Edit: as correctly pointed out by @wwii in their answer, maybe you don't need a class at all.

  • 1
    And the specific choice of "`self`" is just a convention, too. It is not a language keyword, though this is a point of some confusion. If you instead name the first parameter of the method "`me`", for example, then that is the variable by which the method would access the instance on which it is invoked. – John Bollinger Oct 19 '20 at 15:58
1

Is there a way to avoid using self parameter in functions multiple times

Instead of using a class, get your functionality from a function.

import math
def primeGen(maxNum):
    allNum = [0]*(maxNum+1)
    allNum[0], allNum[1] = 1, 1
    primeNum = []
    for i in range(2, int(math.sqrt(maxNum))+1):
        if allNum[i] is 0:
            for j in range(i*i, len(allNum), i):
                allNum[j] = 1
    for i in range(maxNum):
        if allNum[i] is 0:
            primeNum.append(i)
    return primeNum

q20 = primeGen(20)
print(q20)       
q5 = primeGen(5)
print(q5)       
wwii
  • 23,232
  • 7
  • 37
  • 77
0

In your case you can create only self.primeNum. This is the only variable used by other function members of the cass.

Do you really need all other variables to be fields of the class? They look like temporary variables. You don't need to add them to the class.

Yaroslav Nikitenko
  • 1,695
  • 2
  • 23
  • 31