Keeping the variable 's value in recursive function, python 3.3 - function

I managed to do it, some other way.
but I have a question, I had this code before
def jumphunt(start, mylist, count = 0):
if count < len(mylist):
place = mylist[start]
print(place)
if place == 0:
return True
elif start >= len(mylist) or start < 0:
return False
move_left = (start - place)
move_right = (start + place)
return jumphunt(move_right, mylist, count+1) or jumphunt(move_left, mylist, count+1)
else:
return False
but for some reason it's not trying both ways
to get to the last item on the list.
for example: [1,2,2,3,4,5,3,2,1,7,0] and ,start=mylist[0]
it supposed to jump like this (from 1-2-4-1-left to 2-left to 5-right to 0)
but it keeps trying to go right and then index is out of range etc.
I thought that if u use return of or this or that, it will try both until it reaches True, why won't it work here?
Thanks!

Include the value you want to keep as a default parameter for the method, like this:
def my_func(int, list, i=0):
a = (i + int)
if int == 0:
return True
elif a > len(list):
i -= int
else:
i += int
int = list[i]
my_func(int, list, i)
Bear in mind that it may not even always be possible to arrive at the end of the list doing the jumping pattern you describe, and even if it is possible, this method may choose the wrong branch.
A better algorithm would look like this:
def branching_search(list, start):
marks = [0]*len(list)
pos = start
while list[pos]!=0:
marks[pos]++
if marks[pos] % 2 == 0 and pos + list[pos] < len(list):
pos += list[pos]
elif marks[pos] % 2 == 1 and pos - list[pos] >= 0:
pos -= list[pos]
else:
return False
if all(item == 0 or item > 1 for item in list)
return False
return True
This way, if it comes to an item that it has already visited, it will decide to go the opposite direction that it went last time. Also, if it comes to an item that it can't leave without going out-of-bounds, or if there is not way to get to the end, it will give up and return.
EDIT: I realized there are a number of flaws in this algorithm! Although it is better than the first approach, it is not guaranteed to work, although the reasons are somewhat complicated.
Just imagine this array (the unimportant elements are left blank):
1, 2, , 5, , , , , 5, 0
The first two elements would get only one mark (thus the loop checking condition would not work), but it would still get stuck looping between the two fives.
Here is a method that will always work:
def flood_search(list):
marks = [[]]*len(list)
marks[0] = [0]
still_moving = True
while still_moving:
still_moving = False
for pos in range(0,len(list)):
if marks[pos]:
if pos + list[pos] < len(list) and not marks[pos + list[pos]]:
marks[pos + list[pos]] = marks[pos] + [list[pos]];
pos += list[pos]
still_moving = True
if pos - list[pos] >= 0 and not marks[pos - list[pos]]:
marks[pos - list[pos]] = marks[pos] + [-list[pos]];
pos -= list[pos]
still_moving = True
return marks[-1]
This works by taking every possible branch at the same time.
You can also use the method to get the actual route taken to get to the end. It can still be used as a condition, since it returns an empty list if no path is found (a falsy value), or a list containing the path if a path is found (a truthy value).
However, you can always just use list[-1] to get the last item.

Related

Substituting multiple inputs for a function with one function?

I am trying to see if I can simplify input by using a function that produces more than one output for use with another function. Is there any way I can do this? Do I HAVE to make a function to return single variables for each input?
--here is a snippet of what im trying to do (for a game)
--Result is the same for game environment and lua demo.
en = {
box ={x=1,y=2,w=3}
}
sw = {
box = {x=1,y=2,w=3}
}
function en.getbox()
return en.box.x,en.box.y,en.box.w,en.box.w
end
function sw.getbox()
return sw.box.x,sw.box.y,sw.box.w,sw.box.w
end
function sw.getvis()
return true
end
function CheckCollision(x1,y1,w1,h1, x2,y2,w2,h2)
return x1 < x2+w2 and
x2 < x1+w1 and
y1 < y2+h2 and
y2 < y1+h1
end
if CheckCollision(en.getbox(),sw.getbox()) == true then
if sw.getvis() == true then
en.alive = false
end
end
print(tostring(en.alive))
I am expecting the enemy (en) to die (en.alive = false) but I am getting the error: input:25: attempt to perform arithmetic on a nil value (local 'w2')
You can find an explaination for the issue you are seeing here: Programming in Lua: 5.1 – Multiple Results
I suggest you read the whole page but here is a relevant section
A function call that is not the last element in the list always produces one result:
x,y = foo2(), 20 -- x='a', y=20
x,y = foo0(), 20, 30 -- x=nil, y=20, 30 is discarded
I suggest the following changes to get your code working. wrap your output from getbox into a table with clear keys that make it easy to understand.
function en.getbox()
return {
x = en.box.x,
y = en.box.y,
w = en.box.w,
h = en.box.w
}
end
function sw.getbox()
return {
x = sw.box.x,
y = sw.box.y,
w = sw.box.w,
h = sw.box.w
}
end
function CheckCollision(o1, o2)
return o1.x < o2.x + o2.w and
o2.x < o1.x + o1.w and
o1.y < o2.y + o2.h and
o2.y < o1.y + o1.h
end
Alternatively you can wrap the output of getbox "on the fly" like:
function CheckCollision(o1, o2)
return o1[1] < o2[1] + o2[3] and
o2[1] < o1[1] + o1[3] and
o1[2] < o2[2] + o2[4] and
o2[2] < o1[2] + o1[4]
end
if CheckCollision({en.getbox()}, {sw.getbox()}) == true then
if sw.getvis() == true then
en.alive = false
end
end
I do strongly encourage the first option over the last. The last option leads to code that is harder to follow and should be accompanied by clear comments explaining it.

Program won't call correct function based on input. No idea what I'm missing

EDIT: After playing around a bit in main(), it seems like the program is choosing whichever function is being called in the if/elif block regardless of input. I have no idea why it started doing this after working fine
I've gone over and over my code, and I can't figure out what I'm not seeing.
It's a number sequence game, and it asks the user to choose a difficulty between easy and hard. It was working just fine at one point, but now no matter what is selected, it goes to easy mode each time. Even you hit enter without any input at all.
#main program function and difficulty selection
def main():
print('-----------------------------------------------')
print('Please choose a difficulty.')
difficulty = str(input('(e)asy|(h)ard: '))
print('-----------------------------------------------')
if difficulty == 'easy'or'e':
easy()
elif difficulty == 'hard'or'h':
hard()
Then I have a function for easy and one for hard.
Hard is just the easy function, with only a change to the size of the sequence generated and nothing else. I've gone over each block and nothing is changed that would affect which function is called.
It happens regardless of how many times the game is played, so it has to be something wrong with my main() function
The rest of the code is here if that helps, maybe I'm missing something obvious.
import random
def easy():
print ('Easy Mode','\n')
#Generates inital number, step value, and upper limit
num_sequence = 5
numbers = random.randint(1,101)
step = random.randint(1,20)
#Accumulates and prints all but last number in sequence
for num_generated in range (1, num_sequence):
print(numbers)
numbers = numbers + step
#Sets tries allowed and subtracts wrong attempts
guesses = 3
while guesses > 0:
user_num = int(input('Next Number: '))
guesses = guesses - 1
if user_num != numbers:
if guesses == 0:
break
else:
print('Try Again (Attempts Remaining:', guesses,')')
if user_num == numbers:
break
#Prints appropriate message based on game results
if user_num == numbers:
print ('Correct','\n')
if user_num != numbers:
print ('Attempts Exceeded: The answer was',numbers,'\n')
#block for hard difficulty (same as above, sequence size changed to 4)
def hard():
print ('Hard Mode','\n')
num_sequence = 4
#main program function and difficulty selection
def main():
print('-----------------------------------------------')
print('Please choose a difficulty.')
difficulty = str(input('(e)asy|(h)ard: '))
print('-----------------------------------------------')
if difficulty == 'easy'or'e':
easy()
elif difficulty == 'hard'or'h':
hard()
#block for replay selection
replay = 'y'
while replay == 'y':
main()
replay = input('Play again? (y)|(n): ',)
print ('\n')
if replay == 'n':
print('-----------------------------------------------')
print('Goodbye!')
print('-----------------------------------------------')
break
hard() is the same code as easy() line for line after those first few
When you are making a compound comparison (using the or) both sides of the condition must be complete. In other words,
if difficulty == 'easy'or difficulty == 'e':
easy()
elif difficulty == 'hard'or difficulty == 'h':
hard()
Otherwise you are saying "if difficulty == 'easy' >> which is false, then assign difficulty to 'e'" which was not the intent.

how to get absolute value without 'abs' function?

def my_abs(value):
"""Returns absolute value without using abs function"""
if value < 5 :
print(value * 1)
else:
print(value * -1)
print(my_abs(3.5))
that's my code so far but the quiz prints, for example -11.255 and 200.01 and wants the opposite for example it wants 11.255 back and -200.01
What does 5 have to do with absolute value?
Following your logic:
def my_abs(value):
"""Returns absolute value without using abs function"""
if value <= 0:
return value * -1
return value * 1
print(my_abs(-3.5))
>> 3.5
print(my_abs(3.5))
>> 3.5
Other, shorter solutions also exist and can be seen in the other answers.
The solutions so far don't take into account signed zeros. In all of them, an input of either 0.0 or -0.0 will result in -0.0.
Here is a simple and (as far as I see) correct solution:
def my_abs(value):
return (value**2)**(0.5)
A simple solution for rational numbers would be
def my_abs(value):
if value<0:
return -value
return value
Why do you want to check if value < 5?
Anyways, to replicate the abs function:
def my_abs(value):
return value if value >=0 else -1 * value
A fun one.
if (number < 0) returns a boolean but when you do math with it it's a 1 or 0. Below written as (a<0)
When the number is less than 0, we can get its positive value by adding 2 times the negative of itself. or just subtract itself twice written as (-a-a)
so when our condition fails it returns 0 which when multiplied by anything is zero so we don't add anything to our original number.
if our condition passes, we'll get a 2 times the positive so we can add to our original.
here's the code, the number you're trying to get absolute value is a in this case
a = a + (a<0) * (-a-a)
This runs slower than the built in abs() call.
I thought it was faster but it was buggy in my code when I timed it.
the fastest seem to be the if (a<0) then a = -a
num = float(input("Enter any number: "))
if num < 0 :
print("Here's the absolute value: ", num*-1)
elif num == 0 :
print("Here's the absolute value: 0")
elif num > 0 :
print("Here's the absolute value: ", num)

Using a variable in a SQLAlchemy filter

I want to use a variable like this :
myVariable = 0.5
myQuery.filter(myTable.column1 == myVariable*myTable.column2)
I have then no results when I apply all() to myQuery.
If I replace the variable with its value, it is OK.
queryBidOffer = session.query(BidOffer.id, BidOffer.price, BidOffer.qmin, BidOffer.qmax)
queryBidOffer = queryBidOffer.join(Equipment).filter(BidOffer.equipment==Equipment.id, Equipment.equipment_type.in_(['L','P','W','M']))
queryBidOffer_day = queryBidOffer.filter(BidOffer.day == day)
queryBidOffer_hour = queryBidOffer_day.filter(BidOffer.start_hour == timeSlice)
queryBidOffer_hour = queryBidOffer_hour.join(EquipmentDayHour, BidOffer.equipment == EquipmentDayHour.equipment)
queryBidOffer_hour = queryBidOffer_hour.filter(EquipmentDayHour.day == day)
queryBidOffer_hour = queryBidOffer_hour.filter(EquipmentDayHour.hour == timeSlice)
factor1 = 1.00 - 0.07
queryBidOffer_hour = queryBidOffer_hour.filter(BidOffer.equipment == EquipmentDayHour.equipment, factor1*func.abs(EquipmentDayHour.ref_prog) == 930)
The problem is with the two last lines (factor1).
In the last line, if I replace factor1 by its value, it is OK.
IEEE floating point numbers as used by Python, and many databases do not always work as your school math. The reason why 0.93 worked was that that was the bitwisely exact value that you had originally stored in database. But slight error appears in the subtraction.
See this for example:
>>> print "%0.64f" % (1.0 - 0.07)
0.9299999999999999378275106209912337362766265869140625000000000000
>>> print "%0.64f" % (0.93)
0.9300000000000000488498130835068877786397933959960937500000000000
Read more here How should I do floating point comparison and then for very in depth essay you could read What Every Computer Scientist Should Know About Floating-Point Arithmetic...
One solution could be to use decimal.Decimal in Python and Numeric in SQL.
I've just tested out something similar to the code you are describing, but get results whether I use a variable or a literal:
myVariable = 0.5
myQuery.filter(myTable.column1 == myVariable*myTable.column2).all()
vs.
myQuery.filter(myTable.column1 == 0.5*myTable.column2).all()
Can you post up the literal SQL that is being genarated? i.e. the results of
print myQuery
for both of those?

function to return index of largest neighbor

F# function
Problem:
given a list of items e.g.:
["5";"10";"2";"53";"4"]
and a Search Index, I require a function such that it compares the current given index against its neighbor, returning the largest index
Example:
Given Index 1 will return Index value 2 (because 10 is greater than 5).
Given Index 4 will return Index 4 (because 53 is greater than 4)
Currently this is my function. It does not compile:
let GetMaxNode (x:Array) Idx = if x.[Idx] > x.[Idx+1] then Idx else If x.[Idx] < x.[Idx+1] then Idx+1
The errors I'm getting for all the x' are:
The field, constructor or member 'Item' is not defined (FS0039)
And also the second If:
The value or constructor 'If' is not defined (FS0039)
I suspect I'm still thinking in a procedural way, I was thinking about using pattern matching, however I was not confident enough with the syntax to try it.
Please can you also explain the answer as well, as I'm trying to learn F#, just the solution will not help me much.
Here's some code based on yours:
let GetMaxNode (x:_[]) idx =
if x.[idx] > x.[idx+1] then
idx
elif x.[idx] < x.[idx+1] then
idx+1
else
idx // same, return this one
The main changes are
to declare an array type, say <typename> []. In this case, we don't care about the type, so I use _ as a "don't care, please go infer the right thing for me" type variable.
"else if" is spelled elif in F#
need an else case for if equal
It is difficult to write solution to your problem in a functional style, because your problem is defined in terms of indices - when using functional data structures, such as lists, you don't usually refer to the elements by their index.
A functional version of your question would be, for example, to create a list that contains true when the element at the current position is larger than the next one and false when it is smaller. For your data this would give:
let data = [ 5; 10; 2; 53; 4 ]
let res = [ false; true; false; true; ] // no item to compare '4' with
This can be solved quite nicely using a recursive function that walks through the list and pattern matching (because pattern matching works much better with functional lists than with arrays)
let rec getMaxNodes data =
match data with
// list has at least two elements and current is larger
| current::next::other when current >= next ->
// process the rest of the list
let rest = (getMaxNodes (next::other))
// return 'true' followed by recursively processed rest of the list
true::rest
// list has at least two elements and current is smaller
| current::next::rest ->
// same as the previous case, but we return false
false::(getMaxNodes (next::rest))
| _ ->
// one element (so we cannot compare it with the next one)
// or empty list, so we return empty list
[]
getMaxNodes data
Here's the pattern matching version of Brian's answer.
let GetMaxNode (x:_[]) idx =
match idx with
| idx when x.[idx] > x.[idx+1] -> idx
| idx when x.[idx] < x.[idx+1] -> idx + 1
| idx -> idx // same, return this one
You may also see a syntax shortcut as you look at more F# code. The below code is functionally exactly the same as the above code.
let GetMaxNode (x:_[]) = function
| idx when x.[idx] > x.[idx+1] -> idx
| idx when x.[idx] < x.[idx+1] -> idx + 1
| idx -> idx // same, return this one
Whenever you start talking about indices, you are best sticking with Arrays or ResizeArrays; F# lists are not well-suited for operations on indices since they are singly-linked head to tail. That being said, it is not too difficult to write this algorithm in a purely functional way by moving through the list using a recursive loop and keeping track of the current index and current element.
let find elements index =
//a local tail-recursive function hides implementation details
//(cur::tail) is a pattern match on the list, i is the current index position
let rec loop (cur::tail) i =
if i = index then //when the current index matches the search index
if cur >= tail.Head then i //compare cur to tail.Head (which is next)
else (i+1)
else loop tail (i+1) //else continue
loop elements 0 //the entry point of loop and our return value
Use a list of ints instead of strings to get the results you expect (since "10" is actually less than "5"):
> let x = [5;10;2;53;4];;
> find x 0;;
val it : int = 1
> find x 1;;
val it : int = 1
> find x 2;;
val it : int = 3
> find x 3;;
val it : int = 3