Circles touching edges - python

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 nr
def touch_sides(disk, radius, x, y):
for disk in disksdescription:
for left in disk.values()[2]:
if x <= radius:
left = True
else:
left = False
for right in disk.values()[3]:
if x >= 1-radius:
right = True
else:
right = False
def run_code():
radius = 0.1
coordinates = nr.uniform(size=(1,2))
print coordinates
disksdescription = []
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.

Related

In functions that call a check function, where should the error message be generated/printed/sent?

I have started questioning if the way I handle errors is correct or pythonic. The code scenarios below are easy in nature, whilst the actual use would be more in line with discord.py and PRAW (reddit). The boolean indicates success, and the message returned is a message summarising the exception triggered.
Which of the following scenarios (WITH VERY SIMPLIFIED FUNCTIONS) is the proper pythonic way of doing it, or is there none? Or one I haven't thought of/learned yet?
Scenario 1: Main function returns on false from check function, but check function prints message
def main_function():
# calls the check function
success = check_function(1, 2)
if not success:
return
def check_function(intone, inttwo):
if intone != inttwo:
print("Not the same")
return False
return True
Scenario 2: The main functions prints an error message based on boolean returned from check function
def main_function():
# calls the check function
success = check_function(1, 2)
if not success:
print("Failure, not the same")
return
def check_function(intone, inttwo):
if intone != inttwo:
return False
return True
Scenario 3: The check function returns a boolean and a generated error message which the main function prints if false.
def main_function():
# calls the check function
success, error = check_function(1, 2)
if not success:
print(error)
return
def check_function(intone, inttwo):
if intone != inttwo:
return False, "Not the same"
return True
Obviously, the coding I'm doing that made me think about this is slightly more complicated, but I believe the examples are carried over.
If sounds like you are used to outputting a Boolean for whether things went well or not.
If an error occurs, then you output False, or True.
Additionally, if there is an an error, you are using print() statements to display the error.
An example of pseudo-code using an approach similar to yours is shown below:
# define function for baking a cake:
def make_a_pancake():
"""
outputs an ordered pair (`ec`, cake)
`ec` is an error code
If `ec` is zero, then `cake` is a finished cake
ERROR CODES:
0 - EVERYTHING WENT WELL
1 - NO MIXING BOWLS AVAILABLE
2 - WE NEED TO GET SOME EGGS
3 - WE NEED TO GET SOME FLOUR
"""
# IF THERE IS A MIXING BOWL AVAILABLE:
# GET OUT A MIXING BOWL
if kitchen.has(1, "bowl"):
my_bowl = kitchen.pop(1, "bowl")
else: # no mixing bowl available
print("WE NEED A MIXING BOWL TO MAKE A CAKE")
return 1 # NO MIXING BOWL IS AVAILABLE
# IF THERE ARE EGGS AVAILABLE:
# PUT THE EGGS INTO THE BOWL
if kitchen.has(6, "eggs"):
my_eggs = kitchen.pop(6, "eggs")
my_bowl.insert(my_eggs)
else: # OUT OF EGGS
print("RAN OUT OF EGGS. NEED MORE EGGS")
return 2
# IF THERE IS WHEAT FLOUR AVAILABLE:
# put 2 cups of flour into the bowl
if len(kitchen.peek("flour")) > 0:
f = kitchen.pop("flour", 2, "cups")
my_bowl.insert(f)
else:
print("NOT ENOUGH FLOUR IS AVAILABLE TO MAKE A CAKE")
RETURN 3, None
# stir the eggs and flour inside of the bowl
# stir 3 times
for _ in range(0, 3):
bowl.stir()
# pour the cake batter from the bowl into a pan
my_batter = bowl.pop()
pan.push(my_batter)
# cook the cake
stove.push(pan)
stove.turn_on()
stove.turn_off()
the_cake = pan.pop()
return err_code, the_cake
The code above is similar to the way code was written many decades ago.
Usually,
0 is interpreted as False
1, 2, 3, etc... are all True.
It might be confusing that 0 means no error occurred
However,
There is only one way for things to go right.
There are many ways for things to go wrong.
Every program written in python, Java, C++, C#, etc... will give the operating system (Microsoft windows, Linux, etc...) an error code when the whole program is done running.
A "clear" error flag (zero) is good.
An error flag of 1, 2, 3, ..., 55, ... 193, etc... is bad.
The most pythonic way to handle printing error messages is something you have not learned about yet.
It is called, exception handling
It looks like the following:
class NO_MORE_EGGS(Exception):
pass
def cook_omelet():
# if (THERE ARE NO EGGS):
# raise an exception
if(kitchen.peek("eggs") < 1):
msg = "you cannot make an omelet without breaking some eggs"
raise NO_MORE_EGGS(msg)
pan.push(eggs)
# cook the cake
stove.push(pan) # `push` means `insert` or `give`
stove.turn_on()
stove.turn_off()
pan = stove.pop()
the_omelet = pan.pop()
return the_omelet
Ideally, a function is like a small component in a larger machine.
For example, a car, or truck, contains many smaller components:
Alternators
Stereos (for music)
Radiator (to lower the engine temperature)
Brake-pads
Suppose that Bob designs a stereo for a car made by a company named "Ford."
Ideally, I can take the stereo Bob designed put the stereo in a design for a different car.
A function is also like a piece of equipment in a kitchen.
Examples of kitchen equipment might be:
A rice-cooker
A toaster
A kitchen sink
Suppose that you design a rice-cooker which works in Sarah's kitchen.
However, your rice-cooker does not work in Bob's kitchen.
That would be a very badly designed rice-cooker.
A well designed rice-cooker works in anybody's kitchen.
If you write a function in Python, then someone else should be able to use the function you wrote in somebody else's code.
For example, suppose you write a function to calculate the volume of a sphere.
If I cannot re-use your function in someone else's computer program, then you did a bad job writing your function.
A well-written function can be used in many, many, many different computer programs.
If you write a function containing print statements, that is a very bad idea.
Suppose you make a website to teach children about math.
Children type the radius of a sphere into the website.
The website calculates the volume of the sphere.
The website prints "The volume of the sphere is 5.11 cubic meters"
import math
def calc_sphere_vol(radius):
T = type(radius)
rad_cubed = radius**T(3)
vol = T(4)/T(3)*T(math.pi)*rad_cubed
print("the volume of the sphere is", vol)
return vol
In a different computer program, people want to calculate the radius of a sphere, quickly and easily without seeing any message printed to the console.
Maybe calculating the volume of a sphere is one tiny step on the way to a larger more complicated result.
A function should only print message to the console if the person using the function given the function permission to do so.
Suppose that:
you write some code.
you post your code on Github
I download your code from Github.
I should be able to run your code without seeing a single print statement (if I want to).
I should not have to re-write your code to turn-off the print statements.
Imagine that you were paid to design next year's model of some type of car.
You should not have to look inside the radio/stereo-system.
IF you are designing a large system, you should not have to see what is inside each small component.
A computer program is too big and complicated to re-write the code inside of the existing functions.
Imagine pieces of a computer program as small black cubes, or boxes.
Each box has input USB ports.
Each box has output USB ports.
I should be able to plug in any wires I want into the small box you designed and built.
I should never have to open up the box and re-wire the inside.
A computer programmer should be able to change where output from a function goes without modifying the code inside of that function.
print statements are very very bad.
I would avoid option 1 in the majority of cases. By having it do the reporting, you're limiting how it can be used in the future. What if you want this function to be used in a tkinter app later? Is printing still appropriate? If the function's job is to do a check, it should just do the check. The caller can figure out how they want to use the returned boolean.
Options 2 and 3 are both viable, but which you'd use would depend on the case.
If there's exactly one way in which a function can fail, or all different failures should be treated the same, a simple False is fine, since False implies the single failure reason.
If there's multiple distinct ways in which a function can fail, returning some failure indicator that allows for multiple reasons would be better. A return of type Union[bool, str] may be appropriate for some cases; although I don't thinks strings make for good error types since they can be typo'd. I think a tuple of Union[bool, ErrorEnum] would be better; where ErrorEnum is some enum.Enum that can take a restricted set of possible values.
Options 3 bears a weak resemblence to Haskell's Maybe and Either types. If you're interested in different ways of error-handling, seeing how the "other side of the pond" handles errors may be enlightening. Here's a similar example to what you have from the Either link:
>>> import Data.Char ( digitToInt, isDigit )
>>> :{
let parseEither :: Char -> Either String Int
parseEither c
| isDigit c = Right (digitToInt c)
| otherwise = Left "parse error"
>>> :}
parseEither returns either a parsed integer, or a string representing an error.

How do I stop my backtracking algorithm once I find and answer?

I have wrote this code for solving a problem given to me in class, the task was to solve the "toads and frogs problem" using backtracking. My code solves this problem but does not stop once it reaches the solution (it keeps printing "states" showing other paths that are not a solution to the problem), is there a way to do this?. This is the code:
def solution_recursive(frogs):
#Prints the state of the problem (example: "L L L L _ R R R R" in the starting case
#when all the "left" frogs are on the left side and all the "right" frogs are on
#the right side)
show_frogs(frogs)
#If the solution is found, return the list of frogs that contains the right order
if frogs == ["R","R","R","R","E","L","L","L","L"]:
return(frogs)
#If the solution isn't the actual state, then start (or continue) recursion
else:
#S_prime contains possible solutions to the problem a.k.a. "moves"
S_prime = possible_movements(frogs)
#while S_prime contains solutions, do the following
while len(S_prime) > 0:
s = S_prime[0]
S_prime.pop(0)
#Start again with solution s
solution_recursive(s)
Thanks in advancement!
How do I stop my backtracking algorithm once I find an answer?
You could use Python exception facilities for such a purpose.
You could also adopt the convention that your solution_recursive returns a boolean telling to stop the backtrack.
It is also a matter of taste or of opinion.
I'd like to expand a bit on your recursive code.
One of your problems is that your program displays paths that are not the solutions. This is because each call to solution_recursive starts with
show_frogs(frogs)
regardless of whether frogs is the solution or not.
Then, you say that the program is continuing even after the solution has been found. There are two reasons for this, the first being that your while loop doesn't care about whether the solution has been found or not, it will go through all the possible moves:
while len(S_prime) > 0:
And the other reason is that you are reinitializing S_prime every time this function is called. I'm actually quite amazed that it didn't enter an infinite loop just checking the first move over and over again.
Since this is a problem in class, I won't give you an exact solution but these problems need to be resolved and I'm sure that your teaching material can guide you.

handle trajectory singularity: delete photons causing error

I am coding a black hole (actually photons orbiting a black hole) and I need to handle an exception for radius values that are smaller than the limit distance
I've tried using if and while True
def Hamiltonian(r, pt, pr, pphi):
H = (-((1-rs/r)**-1)*(pt**2)/2 + (1-rs/r)*(pr**2)/2 + (pphi**2)/(2* (r**2)))
if np.amax(H) < 10e-08:
print("Your results are correct")
else:
print("Your results are wrong")
return(H)
def singularity(H, r):
if (r).any < 1.5*rs:
print(H)
else:
print("0")
return(H, r)
print(Hamiltonian(r00, pt00, pr00, pphi00))
I'd like to handle the case r < 1.5*rs so that I don't have the division error message and weird orbits anymore. So far my code doesn't change anything to the problem, I still get this error message :
"RuntimeWarning: divide by zero encountered in true_divide
H = (-((1-rs/r)**-1)*(pt**2)/2 + (1-rs/r)*(pr**2)/2 + (pphi**2)/(2*(r**2)))"
and my orbits are completely wrong (for example my photon should go right in the black hole, but since there's a singularity at r < 1.5*rs, they go in and leave again and so on)
I'd like to delete the photons causing the problem but I don't know how, can anyone please help me?
I think you mention that we do not know exactly what goes on at a singularity. Any answer provided here most likely would not be accurate, but let's just assume that you know the behavior/dynamics at the near 0 neighborhood. I do not know how you are calling the Hamiltonian function but I can imagine you are doing it one of two ways.
You have a pre-defined loop that loops through each value you are passing into the function and outputting the resulting H for each value in that pre-defined loop.
You are passing in vectors of the same length and doing element by element math in the H function.
In the first case, you could either do a pre-check and write a new function for the near 0 behavior and call that new function if you are in the near zero neighborhood. You could also just have the check in the hamiltonian function itself and call the new function if you are in the near 0 neighborhood. This latter method is what I would prefer as it keeps the front-end (the best word I have for it) fairly clean and encapsulates the logic/math in your Hamiltonian function. In your comments you say you want to delete the photon within some radius, and that would be extremely easy to do with this method by just terminating the for loop by breaking out at that time step and plotting what you had until that time step.
In the second case, you would have to manually build the new vector by having checks throughout your vectors if they fall within the singularity neighborhood. This would be a little more difficult and would depend on the shape of your inputs and doing element by element math is more difficult to debug in my opinion.

How can I avoid recursion between move generation and check validation in python chess implementation?

I'm currently working on a simple python 3 implementation of a chess game where legal moves can be calculated and things like check, checkmate, and stalemate can be determined. I've encountered a logic error which results in recursion and I'm not sure how I change my current approach to avoid this.
I've got some pseudo-code here (my actual code several hundred lines long and it would be impractical to paste it all for a logic problem).
Where am I going wrong with my thought process behind this code?
class ChessBoard:
def get_position():
# returns fen of position
def set_position(position_code):
# sets the board's position and values using the fen code given
# assume its white's turn right now
def calculate_moves():
# uses vectors to calculate moves for all pieces
for each_move in candidate_moves:
if passes_all_general_conditions:
# now I need to check if the potential
# legal move will leave the user in check
# obviously if the white king can be taken in the next turn
# by the other color then the move cannot be considered legal
temp_board = ChessBoard()
temp_board.set_position(self.get_position())
temp_board.make_move(the_selected_move_that_needs_checking)
if not temp_board.incheck():
# add move to list of legal moves
def incheck():
# player is in check if a piece can take it on the next turn
# don't I need to know what moves can be made before I can know if its check??
# let k equal the current turn (or half-turn as chess players call it)
# in order to calculate the moves for position at turn k
# the moves for position k + 1 must be known
# obviously this just enters infinite recursion
It looks like incheck() is not implemented. The default return value of a python method is the None type.
>>> not None == True
True
So the deepest-nested conditional in your loop always evaluates to True.
I appreciate that you didn't copy paste you whole code, but it would have been useful to at least show SOME part of it, in order to fix your issue.
Since I cannot debug your code without seeing it, I will just make a guess:
I think you use calculate_moves() in incheck(), and incheck to verify wether calculated_moves are legal ones.
If you do that, you have got two options:
-Split calculate_moves into two functions: one generates pseudo legals, and the other then controls these pseudolegals on legality. You will just ave to replace calculate_moves() in incheck() by calculate_pseudolegals(). This approach is a little bit inefficient though.
-The more efficient solution is to fully delete your incheck() routine and write a new, efficient one. There you would replace the king you wish to test on check by every figure of its own color onece, and then test if it could hit a figure of the same type of the opponent. If it can, your king is in check. Be aware that you will still need a calculate_pseudolegals() function for this to work.

How to try all possible paths?

I need to try all possible paths, branching every time I hit a certain point. There are <128 possible paths for this problem, so no need to worry about exponential scaling.
I have a player that can take steps through a field. The player
takes a step, and on a step there could be an encounter.
There are two options when an encounter is found: i) Input 'B' or ii) Input 'G'.
I would like to try both and continue repeating this until the end of the field is reached. The end goal is to have tried all possibilities.
Here is the template, in Python, for what I am talking about (Step object returns the next step using next()):
from row_maker_inlined import Step
def main():
initial_stats = {'n':1,'step':250,'o':13,'i':113,'dng':0,'inp':'Empty'}
player = Step(initial_stats)
end_of_field = 128
# Walk until reaching an encounter:
while player.step['n'] < end_of_field:
player.next()
if player.step['enc']:
print 'An encounter has been reached.'
# Perform an input on an encounter step:
player.input = 'B'
# Make a branch of player?
# perform this on the branch:
# player.input = 'G'
# Keep doing this, and branching on each encounter, until the end is reached.
As you can see, the problem is rather simple. Just I have no idea, as a beginner programmer, how to solve such a problem.
I believe I may need to use recursion in order to keep branching. But I really just do not understand how one 'makes a branch' using recursion, or anything else.
What kind of solution should I be looking at?
You should be looking at search algorithms like breath first search (BFS) and depth first search (DFS).
Wikipedia has this as the pseudo-code implementation of BFS:
procedure BFS(G, v) is
let Q be a queue
Q.enqueue(v)
label v as discovered
while Q is not empty
v← Q.dequeue()
for all edges from v to w in G.adjacentEdges(v) do
if w is not labeled as discovered
Q.enqueue(w)
label w as discovered
Essentially, when you reach an "encounter" you want to add this point to your queue at the end. Then you pick your FIRST element off of the queue and explore it, putting all its children into the queue, and so on. It's a non-recursive solution that is simple enough to do what you want.
DFS is similar but instead of picking the FIRST element form the queue, you pick the last. This makes it so that you explore a single path all the way to a dead end before coming back to explore another.
Good luck!

Categories