I am struggling with a program to tell whether a created disk touches the edge of a predefined box. The parser keeps saying things such as
NameError: global name 'disksdescription' is not defined
Warning: variable 'left' is assigned to, but never used
The code so far is:
import numpy.random as nrdef touch_sides(disk, radius, x, y):for disk in disksdescription:for left in disk.values()[2]:if x <= radius:left = Trueelse:left = Falsefor right in disk.values()[3]:if x >= 1-radius:right = Trueelse:right = False def run_code():radius = 0.1coordinates = nr.uniform(size=(1,2))print coordinatesdisksdescription = []for row in range(0, coordinates):x = coordinates[row, 0]y = coordinates[row, 1]disksdescription.append({'x': x, 'y': y, 'left': left, 'right': right})touch_sides(coordinates, radius, x, y)print disksdescription
Overview
You have quite a few basic problems in this code. I'm going to back off and try to solve a couple of your process problems.
Most of all, I strongly recommend that you adopt incremental programming: write a few lines of code, just a single step or two of logic. Then test that until you're sure it does what you want. Only then do you write more code.
The advantage of this is that problems are usually easy to debug: only the new 2-5 lines are suspect. Contrast this with your current situation: you have several errors; fixing any one of them won't give you an appreciably better result, so it's hard for you to learn what you did wrong until you get all of them at once.
What is a function?
Think of it like some sort of security set-up, perhaps like the pass-through window to a diner's kitchen. The server sticks an order (slip of paper) through the window. When the cook is done, plates of food come back. All of the communication goes through that window. When we ask for an omelet, for all we know, the cook is slicing meat bits off a full side of beef on a rotisserie ... or nuking some frozen stuff. Can't see it, can't tell; that's a separate room with opaque walls.
Which means what to me?
You have three "rooms" in your program: the (trivial) main program, run_code, and touch_sides. None of them can see inside the others. The variable left in run_code has no relation to the variable left in touch_sides. These are entirely separate entities, no more connected than, say, Kim Jong Il and Kim Kardashian.
In particular, the first line of touch_sides is an ultimate huh? moment for the Python compiler. There is no defined thing called diskdescription. Farther down, you spend work to get values for left and right, but then you don't slide them back through the window. run_code has no idea that you did anything useful in there.
What to fix
- Go back and do the simple exercises that you skipped. Their purpose was to keep you from making all these mistakes at once. Write trivial functions and trivial calls. Learn to use the input parameters and return values.
- Practice incremental programming. Comment out the bodies of your functions. Now, run the program, a simple call to run_code(). It won't do anything, but it does so without error.
- Next, put "stub" code into touch_sides: don't compute anything, but print the parameter values. Ignore the input parameters and return False for left and right. Add code to run_code that calls touch_sides and prints the results.
At this point, you know that you can reliably pass values between the functions. Now you can add the actual code.
What else?
Get comfortable with the concept of a boolean expression. Learn that your original code
if x <= radius:left = True
else:left = False
Reduces directly to
left = (x <= radius) # the parentheses aren't necessary
- Note that you have two variables, left and right, which are trying to describe properties of a list of disks.
- Note that these are the same variables that you're using to iterate through a list of coordinates. They can't do both at once -- make a couple more storage areas, such as left_touches and right_touches.
That should be enough for now. Live Long, And Program.