Generation of vertices
You could use itertools.product to generate vertices. You can replace:
for i in range(0,2**n):
temp = list(bin(i))
while len(temp) < n:
vertices = list(itertools.product('10', repeat=n))
jedi_gif = "/home/asus/Arief_tempo/images/random/jedi.gif"
It's unclear why this image has an absolute path but no others do. They should probably all be relative, as the other three are.
Especially if this is for a tutorial, you need to add docstrings to all of your functions.
can use ...
Way too many comments. They should teach proper use of comments in school, instead of just saying "put comments everywhere!".
Good comments should say why. Comments that say what simply shouldn't exist.
This is probably the worst:
} // end method main
The comment basically says "this is a scope-ending brace".
Single-letter identifiers aren't all that ...
There are a few things that stick out to me Omer:
You should learn the more advanced usage of the print statement (and potentially begin using the print function instead). In may places you have the value of a computation stored in a variable, e.g., var, and you print that and then an explanation. It would be potentially easier for a user to read if you ...
Readability would be greatly enhanced by splitting the code into stanzas, using more line breaks, and adding comments.
Why do you like drawing backwards? Going forward is much easier to understand. The first two lines inside the procedure, for example, could be replaced by this code, which draws a counterclockwise path going forward, rather than a ...
This library does a lot of different, mostly unrelated things. I would consider breaking it up into at least two different libraries. Math and Physics. Math could potentially be broken down into Math and Geometry as well. Perhaps creating a Trigometry group would be overkill. Maybe not.
Your code looks nice and seems to be fully PEP 8 compliant indeed. The fact that you have 1 blank line between functions except in one place where you have 2 puzzles me a bit but that's not a huge issue.
You can actually make your code much easier. Here are a individual steps, you'll find the final code at the end.
Notice that you call turtle.forward(step) ...
Just general style
What the other comment said is true, the style can be improved here.
meaningful names (Calling arguments arg is not so helpful :) For
the mathematical stuff, there are often already established names
for the parameters to functions which you can use.)
logging is ok with print, but I would not introduce additional
parameters for it. (...
There should be a blank line between two method definitions.
Also, some blank lines inside of the methods would give the code room to breathe, and allow you to visually separate individual "steps" from each other, for example in your main method:
int n = Integer.parseInt(args);
double step = Double.parseDouble(args);
Turtle turtle =...
A few pointers:
Use meaningful variable, function and method names. dass(self, arg, arg1, arg2, ans, args, args1, args2): gives me no information about what parameters the method expects or what it does with them, and as you haven't included docstrings I have to read through the code and figure it out. Defining domain-specific terms like AAS/ASA/SSS/etc. ...
You should be using the Command pattern instead of having methods for each command type. This will give you separation of concerns, undo/redo functionality, and a cleaner separation of code. You'll need one interface and 11 implementations. You could also do it in a busy enum, but the separate classes are probably better.
You should have one model class that ...
Your code reads well and is easily understandable. On top of also finding that you might have too much constant (more on that in a little bit), I just have a few nitpicks:
whitespace in expressions is weird sometimes;
a docstring would help understanding the recursion involved in snowflake_edge;
you don't need the newline continuation (\) inside parenthesis,...
I think the only thing I do not remember the reason for is the repeats of 'pu pd' but I think it was to ensure that the pen is up.
Indeed, pu is for penup and pd is for pendown. Luckily you remembered what the rest of the instructions do; if you would have used the long versions instead, jumping back into that old code, and just plain reading it, would have ...
I would highly recommend that you read PEP 8, the Python style guide.
There are a couple rules you are breaking.
From the Imports section:
Wildcard imports (from <module> import *) should be avoided, as they make it unclear which names are present in the namespace, confusing both readers and many automated tools.
You should instead use import ...
Just a note of something that was particularly jarring when viewing your code; for stylistic reasons, you shouldn't have spaces on either side of the arguments:
turtle.register_shape( jedi_gif )
Instead you want:
This is covered in PEP 8 in the section Whitespace in Expressions and Statements. It's good to follow PEP 8 ...
one [class] for Game which is the super class
What you probably mean is that it is the class that controls everything and such is on top of the logical class hierarchy. But when talking about super classes, you usually mean classes from which other classes inherit and thus are on top of (or further up) the inheritance hierarchy. In your code ...
This is very inefficient:
if((x in range(8)) and (y in range(8))):
The range(8) creates a generator of values 0..7, which will be iterated until a match is found. For example, whenever this function gets called with an invalid x value, x in range(8) will iterate over 0..7 ...
Your function kind-of works as intended, except the obvious deviation occurring at the crossings of rings. However, you can only draw the logo at one specific size and you need a heck of a lot of code to do it.
Let's start with a little clean-up and I'll explain the how and the why afterwards:
OFFSET = 165
HALF_OFFSET = OFFSET/2
BORDER = 10
Couple performance and code style related notes:
if you can define something outside/before a loop, do so. For example, there is no need to define linSys inside the loops
follow the PEP8 naming guidelines - in particular, the fractal class name should start with a capital letter - Capital; linSys should be lin_sys
I would also improve on the way you define ...
For each shape, you have this kind of code to generate the movement "recipe":
axiom = ...
for _ in range(self.num):
replacement = 'some fixed string'
axiom = axiom.replace(pattern, replacement)
axiom = axiom.replace(pattern2, replacement2)
This can be generalized with a helper function that takes as parameters axiom and a list of pattern-...
draw_turtle_screensaver() is rather tedious, with many variables and some repetitive code. For example, you have red, green, blue, as well as their new_… counterparts. The code to manipulate those three color channels is written in triplicate. Furthermore, the color-changing code is somewhat copy-and-pasted from the color-initialization code.
I think that you can simplify the simulation like this without losing any clarity:
def go(heading, step_size):
def random_walk(step_size, steps):
# Assumes turtle.mode('standard')
DIRECTIONS = (EAST, NORTH, WEST, SOUTH) = (0, 90, 180, 270)
for _ in range(...
All of the go_* functions are implemented with the same code. The only difference is the value passed to setheading(). You could create one common implementation and replace them with calls to that function.
def go(step, heading):
Extracting repeated code will ...
In essence, the code is well designed. You’ve split the code into simple, reusable functions and the logic is clear.
But there are still improvements to be made:
You relly on the global variable board, which is a bad habit to get into. Instead, pass it as parameter, even for your draw_chess_board function;
The check for the square_color == 'black' feels ...
Nice. I only have three comments.
In draw_polygon() use a for loop rather than an explicit counter:
def draw_polygon(a_turtle, length, sides):
for counter in range(sides):
a_turtle.right(360 / sides)
Add comments and/or docstrings. These will help you when you look at the code in the future.
For these kinds ...
I'm a python beginner,so at the moment I can only see that you can slightly improve your code using range in the function draw_polygon, so instead of
counter = 0
while (counter < sides):
a_turtle.right(360 / sides)
counter = counter + 1
You can rewrite it in this way avoiding multiple divisions ...
All I'm asking for is your overall opinion of how it was done and how it works.
Not good. Your code breaks almost any rule generally agreed about good code. But don't be sad, you are lucky because you can now learn some good principles and write better code in the future.
from turtle import *
from random import *
from tkinter import *
I like the concept of the question (using a domain-specific language to specify a fractal) and your implementation. An object-oriented rewrite could make it better, but it's not bad as it is.
l_system() could be better written as
def l_system(V, w, P, n):
cmd_seq = w
for _ in range(n):
cmd_seq = itertools.chain(*(P.get(cmd, cmd) for ...
Overall looks pretty good, but here are a few suggestions:
Read PEP 8; there are still a few areas where you could tidy up. In particular: two lines between function definitions, ALL CAPS variables are only global constants, sorting of imports at the top of the file.
In the constructor for your MyTurtle class, you should use super() to call the parent ...