Generating pattern similar to QR code using strings

Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
3
down vote
favorite
I wrote this class to generate a random "image," similar to a QR code, using strings. How can I make it better (I am a beginner in programming)?
import random
""" N is the length of squared field to be generated"""
class genImg():
def __init__(self, N):
self.N = N
self.field =
def genField(self):
for i in range(self.N):
row =
for j in range(self.N):
row.append("|-|")
self.field.append(row[:])
def getField(self):
return self.field
def fillField(self):
field = self.getField()
result = ""
for i in field:
row = ""
for j in i:
randNum = random.randint(1,100)
if randNum % 2 == 0 or randNum % 3 == 0:
j = '|0|'
row += str(j) + " "
result += row[:-1] + "n"
print(result)
python ascii-art
add a comment |Â
up vote
3
down vote
favorite
I wrote this class to generate a random "image," similar to a QR code, using strings. How can I make it better (I am a beginner in programming)?
import random
""" N is the length of squared field to be generated"""
class genImg():
def __init__(self, N):
self.N = N
self.field =
def genField(self):
for i in range(self.N):
row =
for j in range(self.N):
row.append("|-|")
self.field.append(row[:])
def getField(self):
return self.field
def fillField(self):
field = self.getField()
result = ""
for i in field:
row = ""
for j in i:
randNum = random.randint(1,100)
if randNum % 2 == 0 or randNum % 3 == 0:
j = '|0|'
row += str(j) + " "
result += row[:-1] + "n"
print(result)
python ascii-art
1
Can you add an example output? I think it will make the question more attractive.
â Mathias Ettinger
Jun 27 at 16:48
add a comment |Â
up vote
3
down vote
favorite
up vote
3
down vote
favorite
I wrote this class to generate a random "image," similar to a QR code, using strings. How can I make it better (I am a beginner in programming)?
import random
""" N is the length of squared field to be generated"""
class genImg():
def __init__(self, N):
self.N = N
self.field =
def genField(self):
for i in range(self.N):
row =
for j in range(self.N):
row.append("|-|")
self.field.append(row[:])
def getField(self):
return self.field
def fillField(self):
field = self.getField()
result = ""
for i in field:
row = ""
for j in i:
randNum = random.randint(1,100)
if randNum % 2 == 0 or randNum % 3 == 0:
j = '|0|'
row += str(j) + " "
result += row[:-1] + "n"
print(result)
python ascii-art
I wrote this class to generate a random "image," similar to a QR code, using strings. How can I make it better (I am a beginner in programming)?
import random
""" N is the length of squared field to be generated"""
class genImg():
def __init__(self, N):
self.N = N
self.field =
def genField(self):
for i in range(self.N):
row =
for j in range(self.N):
row.append("|-|")
self.field.append(row[:])
def getField(self):
return self.field
def fillField(self):
field = self.getField()
result = ""
for i in field:
row = ""
for j in i:
randNum = random.randint(1,100)
if randNum % 2 == 0 or randNum % 3 == 0:
j = '|0|'
row += str(j) + " "
result += row[:-1] + "n"
print(result)
python ascii-art
edited Jun 27 at 16:57
200_success
123k14143399
123k14143399
asked Jun 27 at 16:05
ralmeida094
295
295
1
Can you add an example output? I think it will make the question more attractive.
â Mathias Ettinger
Jun 27 at 16:48
add a comment |Â
1
Can you add an example output? I think it will make the question more attractive.
â Mathias Ettinger
Jun 27 at 16:48
1
1
Can you add an example output? I think it will make the question more attractive.
â Mathias Ettinger
Jun 27 at 16:48
Can you add an example output? I think it will make the question more attractive.
â Mathias Ettinger
Jun 27 at 16:48
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
4
down vote
You are doing unnecessary work by first looping over each row and each column to initialise the field to empty squares; and then looping over each row and each column to change the state based on a random condition. You can do it in one looping by assigning the "empty" or "filled" state based on said condition.
And while we're at it, you could simplify the condition as there is exactly 67 numbers that are either multiple of two or three between 1 and 100. So you could at least test if randNum <= 67 which would yield the same probability. But this probability is pretty close to $frac23$ so we can come up with an other approach: use a tupple composed of two " filled" patterns and an "empty" one and use random.choice instead.
You could also benefit a lot from the str.join method instead of concatenating the chosen pattern and a separator to a temporary string. It will help improve your memory usage. Just put the selected patterns in a list and use the join method of your separator to create the whole string at once. Better yet, join over a list-comprehension or a generator expression.
Lastly, you don't need a class to solve this problem as you don't have any state. The various attributes are only there to store temporary variables. A simple function will do:
import random
def generate_image(size, *, filled='|0|', empty='|-|'):
patterns = filled, filled, empty
return 'n'.join(
' '.join(random.choice(patterns) for _ in range(size))
for _ in range(size)
)
if __name__ == '__main__':
print(generate_image(20))
What is the advantage of taking more positional arguments and throwing them away with*? Does it guarantee thatfilledandemptycan only ever be passed as keyword arguments?
â Graipher
Jun 27 at 18:56
2
@Graipher This is keyword-only arguments syntax (aka PEP3102)
â Mathias Ettinger
Jun 27 at 18:59
add a comment |Â
up vote
2
down vote
genField()generates an empty field. My first assumption given it's name is that it generates a random field. Call it something likegenEmptyField()to make this clearer.fillField()does not work unlessgenField()is called first. CallgenField()at the begining offillField(). This will also ensure
that subsequent calls tofillField()are still random.fillField()does the work of both generating the code and printing
it. Seperate these into two seperate functions.Make a method
__str__(self)ofgenImg()that returns the string representation of the image, so that the codes that you generate can be printed, rather than them doing the printing.Consider calling
fillField()in__init__()so that the user always has a useful image.If you want a uniform random image,
randNum % 2 == 0 or randNum % 3 == 0can be replaced byrandom.getrandbits(1)In order to seperate generation and representation, consider storing the array of points as bools and then convert them to the string of your choice in
__str__(). This makes changing your output format much simpler if you want to do that later.self.field.append(row[:])is slower and harder to understand thanself.field.extend(row[:])The name
genImgimplies that this class generates images. In reality this class is an image and provides methods for generation. Consider naming it something likeImage. It is generally a good idea to name your classes with nouns rather than verbs (i.e.ImgGeneratorrather thangenImg)
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
4
down vote
You are doing unnecessary work by first looping over each row and each column to initialise the field to empty squares; and then looping over each row and each column to change the state based on a random condition. You can do it in one looping by assigning the "empty" or "filled" state based on said condition.
And while we're at it, you could simplify the condition as there is exactly 67 numbers that are either multiple of two or three between 1 and 100. So you could at least test if randNum <= 67 which would yield the same probability. But this probability is pretty close to $frac23$ so we can come up with an other approach: use a tupple composed of two " filled" patterns and an "empty" one and use random.choice instead.
You could also benefit a lot from the str.join method instead of concatenating the chosen pattern and a separator to a temporary string. It will help improve your memory usage. Just put the selected patterns in a list and use the join method of your separator to create the whole string at once. Better yet, join over a list-comprehension or a generator expression.
Lastly, you don't need a class to solve this problem as you don't have any state. The various attributes are only there to store temporary variables. A simple function will do:
import random
def generate_image(size, *, filled='|0|', empty='|-|'):
patterns = filled, filled, empty
return 'n'.join(
' '.join(random.choice(patterns) for _ in range(size))
for _ in range(size)
)
if __name__ == '__main__':
print(generate_image(20))
What is the advantage of taking more positional arguments and throwing them away with*? Does it guarantee thatfilledandemptycan only ever be passed as keyword arguments?
â Graipher
Jun 27 at 18:56
2
@Graipher This is keyword-only arguments syntax (aka PEP3102)
â Mathias Ettinger
Jun 27 at 18:59
add a comment |Â
up vote
4
down vote
You are doing unnecessary work by first looping over each row and each column to initialise the field to empty squares; and then looping over each row and each column to change the state based on a random condition. You can do it in one looping by assigning the "empty" or "filled" state based on said condition.
And while we're at it, you could simplify the condition as there is exactly 67 numbers that are either multiple of two or three between 1 and 100. So you could at least test if randNum <= 67 which would yield the same probability. But this probability is pretty close to $frac23$ so we can come up with an other approach: use a tupple composed of two " filled" patterns and an "empty" one and use random.choice instead.
You could also benefit a lot from the str.join method instead of concatenating the chosen pattern and a separator to a temporary string. It will help improve your memory usage. Just put the selected patterns in a list and use the join method of your separator to create the whole string at once. Better yet, join over a list-comprehension or a generator expression.
Lastly, you don't need a class to solve this problem as you don't have any state. The various attributes are only there to store temporary variables. A simple function will do:
import random
def generate_image(size, *, filled='|0|', empty='|-|'):
patterns = filled, filled, empty
return 'n'.join(
' '.join(random.choice(patterns) for _ in range(size))
for _ in range(size)
)
if __name__ == '__main__':
print(generate_image(20))
What is the advantage of taking more positional arguments and throwing them away with*? Does it guarantee thatfilledandemptycan only ever be passed as keyword arguments?
â Graipher
Jun 27 at 18:56
2
@Graipher This is keyword-only arguments syntax (aka PEP3102)
â Mathias Ettinger
Jun 27 at 18:59
add a comment |Â
up vote
4
down vote
up vote
4
down vote
You are doing unnecessary work by first looping over each row and each column to initialise the field to empty squares; and then looping over each row and each column to change the state based on a random condition. You can do it in one looping by assigning the "empty" or "filled" state based on said condition.
And while we're at it, you could simplify the condition as there is exactly 67 numbers that are either multiple of two or three between 1 and 100. So you could at least test if randNum <= 67 which would yield the same probability. But this probability is pretty close to $frac23$ so we can come up with an other approach: use a tupple composed of two " filled" patterns and an "empty" one and use random.choice instead.
You could also benefit a lot from the str.join method instead of concatenating the chosen pattern and a separator to a temporary string. It will help improve your memory usage. Just put the selected patterns in a list and use the join method of your separator to create the whole string at once. Better yet, join over a list-comprehension or a generator expression.
Lastly, you don't need a class to solve this problem as you don't have any state. The various attributes are only there to store temporary variables. A simple function will do:
import random
def generate_image(size, *, filled='|0|', empty='|-|'):
patterns = filled, filled, empty
return 'n'.join(
' '.join(random.choice(patterns) for _ in range(size))
for _ in range(size)
)
if __name__ == '__main__':
print(generate_image(20))
You are doing unnecessary work by first looping over each row and each column to initialise the field to empty squares; and then looping over each row and each column to change the state based on a random condition. You can do it in one looping by assigning the "empty" or "filled" state based on said condition.
And while we're at it, you could simplify the condition as there is exactly 67 numbers that are either multiple of two or three between 1 and 100. So you could at least test if randNum <= 67 which would yield the same probability. But this probability is pretty close to $frac23$ so we can come up with an other approach: use a tupple composed of two " filled" patterns and an "empty" one and use random.choice instead.
You could also benefit a lot from the str.join method instead of concatenating the chosen pattern and a separator to a temporary string. It will help improve your memory usage. Just put the selected patterns in a list and use the join method of your separator to create the whole string at once. Better yet, join over a list-comprehension or a generator expression.
Lastly, you don't need a class to solve this problem as you don't have any state. The various attributes are only there to store temporary variables. A simple function will do:
import random
def generate_image(size, *, filled='|0|', empty='|-|'):
patterns = filled, filled, empty
return 'n'.join(
' '.join(random.choice(patterns) for _ in range(size))
for _ in range(size)
)
if __name__ == '__main__':
print(generate_image(20))
edited Jun 27 at 18:10
answered Jun 27 at 17:13
Mathias Ettinger
21.7k32875
21.7k32875
What is the advantage of taking more positional arguments and throwing them away with*? Does it guarantee thatfilledandemptycan only ever be passed as keyword arguments?
â Graipher
Jun 27 at 18:56
2
@Graipher This is keyword-only arguments syntax (aka PEP3102)
â Mathias Ettinger
Jun 27 at 18:59
add a comment |Â
What is the advantage of taking more positional arguments and throwing them away with*? Does it guarantee thatfilledandemptycan only ever be passed as keyword arguments?
â Graipher
Jun 27 at 18:56
2
@Graipher This is keyword-only arguments syntax (aka PEP3102)
â Mathias Ettinger
Jun 27 at 18:59
What is the advantage of taking more positional arguments and throwing them away with
*? Does it guarantee that filled and empty can only ever be passed as keyword arguments?â Graipher
Jun 27 at 18:56
What is the advantage of taking more positional arguments and throwing them away with
*? Does it guarantee that filled and empty can only ever be passed as keyword arguments?â Graipher
Jun 27 at 18:56
2
2
@Graipher This is keyword-only arguments syntax (aka PEP3102)
â Mathias Ettinger
Jun 27 at 18:59
@Graipher This is keyword-only arguments syntax (aka PEP3102)
â Mathias Ettinger
Jun 27 at 18:59
add a comment |Â
up vote
2
down vote
genField()generates an empty field. My first assumption given it's name is that it generates a random field. Call it something likegenEmptyField()to make this clearer.fillField()does not work unlessgenField()is called first. CallgenField()at the begining offillField(). This will also ensure
that subsequent calls tofillField()are still random.fillField()does the work of both generating the code and printing
it. Seperate these into two seperate functions.Make a method
__str__(self)ofgenImg()that returns the string representation of the image, so that the codes that you generate can be printed, rather than them doing the printing.Consider calling
fillField()in__init__()so that the user always has a useful image.If you want a uniform random image,
randNum % 2 == 0 or randNum % 3 == 0can be replaced byrandom.getrandbits(1)In order to seperate generation and representation, consider storing the array of points as bools and then convert them to the string of your choice in
__str__(). This makes changing your output format much simpler if you want to do that later.self.field.append(row[:])is slower and harder to understand thanself.field.extend(row[:])The name
genImgimplies that this class generates images. In reality this class is an image and provides methods for generation. Consider naming it something likeImage. It is generally a good idea to name your classes with nouns rather than verbs (i.e.ImgGeneratorrather thangenImg)
add a comment |Â
up vote
2
down vote
genField()generates an empty field. My first assumption given it's name is that it generates a random field. Call it something likegenEmptyField()to make this clearer.fillField()does not work unlessgenField()is called first. CallgenField()at the begining offillField(). This will also ensure
that subsequent calls tofillField()are still random.fillField()does the work of both generating the code and printing
it. Seperate these into two seperate functions.Make a method
__str__(self)ofgenImg()that returns the string representation of the image, so that the codes that you generate can be printed, rather than them doing the printing.Consider calling
fillField()in__init__()so that the user always has a useful image.If you want a uniform random image,
randNum % 2 == 0 or randNum % 3 == 0can be replaced byrandom.getrandbits(1)In order to seperate generation and representation, consider storing the array of points as bools and then convert them to the string of your choice in
__str__(). This makes changing your output format much simpler if you want to do that later.self.field.append(row[:])is slower and harder to understand thanself.field.extend(row[:])The name
genImgimplies that this class generates images. In reality this class is an image and provides methods for generation. Consider naming it something likeImage. It is generally a good idea to name your classes with nouns rather than verbs (i.e.ImgGeneratorrather thangenImg)
add a comment |Â
up vote
2
down vote
up vote
2
down vote
genField()generates an empty field. My first assumption given it's name is that it generates a random field. Call it something likegenEmptyField()to make this clearer.fillField()does not work unlessgenField()is called first. CallgenField()at the begining offillField(). This will also ensure
that subsequent calls tofillField()are still random.fillField()does the work of both generating the code and printing
it. Seperate these into two seperate functions.Make a method
__str__(self)ofgenImg()that returns the string representation of the image, so that the codes that you generate can be printed, rather than them doing the printing.Consider calling
fillField()in__init__()so that the user always has a useful image.If you want a uniform random image,
randNum % 2 == 0 or randNum % 3 == 0can be replaced byrandom.getrandbits(1)In order to seperate generation and representation, consider storing the array of points as bools and then convert them to the string of your choice in
__str__(). This makes changing your output format much simpler if you want to do that later.self.field.append(row[:])is slower and harder to understand thanself.field.extend(row[:])The name
genImgimplies that this class generates images. In reality this class is an image and provides methods for generation. Consider naming it something likeImage. It is generally a good idea to name your classes with nouns rather than verbs (i.e.ImgGeneratorrather thangenImg)
genField()generates an empty field. My first assumption given it's name is that it generates a random field. Call it something likegenEmptyField()to make this clearer.fillField()does not work unlessgenField()is called first. CallgenField()at the begining offillField(). This will also ensure
that subsequent calls tofillField()are still random.fillField()does the work of both generating the code and printing
it. Seperate these into two seperate functions.Make a method
__str__(self)ofgenImg()that returns the string representation of the image, so that the codes that you generate can be printed, rather than them doing the printing.Consider calling
fillField()in__init__()so that the user always has a useful image.If you want a uniform random image,
randNum % 2 == 0 or randNum % 3 == 0can be replaced byrandom.getrandbits(1)In order to seperate generation and representation, consider storing the array of points as bools and then convert them to the string of your choice in
__str__(). This makes changing your output format much simpler if you want to do that later.self.field.append(row[:])is slower and harder to understand thanself.field.extend(row[:])The name
genImgimplies that this class generates images. In reality this class is an image and provides methods for generation. Consider naming it something likeImage. It is generally a good idea to name your classes with nouns rather than verbs (i.e.ImgGeneratorrather thangenImg)
edited Jun 27 at 18:16
Daniel
4,1132836
4,1132836
answered Jun 27 at 16:48
Peter
59410
59410
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f197359%2fgenerating-pattern-similar-to-qr-code-using-strings%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
Can you add an example output? I think it will make the question more attractive.
â Mathias Ettinger
Jun 27 at 16:48