improving a function in python - function

I created this function to figure out if betting either side of proposition bet on how many 3 pointers there will be in a particular basketball game is profitable. I project how many total three pointers will be made pjTotal3s and the standard deviation pjGame3STD earlier in the code. The threes_over is the the number given to me by the betting site for which I try to find if the total number of threes will be over or under that number. In this case it is 14.5.
threes_over = 14.5
def overunder(n):
over_count = 0
under_count = 0
push_count = 0
overodds = 0
underodds = 0
for i in range(n):
if round(np.random.normal(pjTotal3s,pjGame3STD)) > threes_over:
over_count = over_count + 1
if round(np.random.normal(pjTotal3s,pjGame3STD)) < threes_over:
under_count = under_count +1
if round(np.random.normal(pjTotal3s,pjGame3STD)) == threes_over:
push_count = push_count + 1
return over_count, under_count, push_count
Then I simulate it a 100,000 overunder(100000) times and it gives me how many times the number of three pointers will be over, under or equal to the number given. This works fine but I still have to more work to do to find if it is a profitable bet.
Assuming that this the output (57550, 42646, 0) I have to manually input it like so and do more to find out if either side of the bet is worthwhile.
over_count = 57550
under_count = 42646
over = 1/(over_count / (over_count + under_count))
under = 1/ (under_count / (over_count + under_count))
over_odds_given = 1.77
under_odds_given = 2.05
overedge = 1/over * over_odds_given - 1
underedge = 1/under * under_odds_given - 1
print overedge, underedge
How do I combine the second set of calculations into the same function as the first. I would like to avoid having to manually input the results of the first function in order to save time and avoid inputting a wrong number.

If you really want the second bit of code in the same function as the first, you could just paste all but the part where you set the over_count and under_count into the function...
def overunder(n):
over_count = 0
under_count = 0
push_count = 0
overodds = 0
underodds = 0
for i in range(n):
if round(np.random.normal(pjTotal3s,pjGame3STD)) > threes_over:
over_count = over_count + 1
if round(np.random.normal(pjTotal3s,pjGame3STD)) < threes_over:
under_count = under_count +1
if round(np.random.normal(pjTotal3s,pjGame3STD)) == threes_over:
push_count = push_count + 1
over = 1/(over_count / float(over_count + under_count))
under = 1/ (under_count / float(over_count + under_count))
over_odds_given = 1.77
under_odds_given = 2.05
overedge = 1/over * over_odds_given - 1
underedge = 1/under * under_odds_given - 1
print overedge, underedge
return over_count, under_count, push_count
Or, probably better, you could put the second bit of code (overedge, underedge) into a separate function and pass it the results from overunder:
def edges(over_count, under_count, push_count):
over = 1/(over_count / float(over_count + under_count))
under = 1/ (under_count / float(over_count + under_count))
over_odds_given = 1.77
under_odds_given = 2.05
overedge = 1/over * over_odds_given - 1
underedge = 1/under * under_odds_given - 1
print overedge, underedge
And then call it with the results from overunder:
c = overunder(100000)
edges(c[0],c[1],c[2])

Related

No results for the web-scrapping from autoscout24

I have a code to retreive data from autoscout24.com for my thesis which I will be working on used car analytics. However, I cannot retreive data and loops do not end. I do not understand the reason behind it. Can anyone help me? Here is the code.
brand = \[\]
model = \[\]
price = \[\]
total = \[\]
a = 101
k = 100
l = 20000 # calculates between € 0 - € 2.000.000
j = 1
while j \<= l:
i = 1
website = 'https://www.autoscout24.com/lst?sort=price&desc=0&cy=NL&atype=C&ustate=N%2CU&damaged_listing=exclude&powertype=kw&pricefrom=' + str(a) + '&priceto=' + str(a+k-1) + '&search_id=2gfy6suaasl&page='
a = a + k
j = j + 1
while i <= 20:
website = website + str(i)
response = requests.get(website)
soup = BeautifulSoup(response.content, 'html.parser')
results = soup.find_all('div', {'class' : 'ListItem_wrapper__J_a_C'})
i = i + 1
for result in results:
brand.append(result.find('h2').get_text())
model.append(result.find('span', {'class':'ListItem_version__jNjur'}).get_text())
price.append(result.find('p', {'class':'Price_price__WZayw'}).get_text().strip())
total.append(result.find('div', {'class':'VehicleDetailTable_container__mUUbY'}).get_text())
I used my computer, I used Google CoLab; however, I could not reach anything at all. If you do this manually, you can reach the data; but no results if you do it in a loop.

Lua Function stuck in a loop

I'm using the standard lua 5.4.4 distribution and interpreter, no libraries, etc.
I'm attempting to write a script to evaluate user defined values of the Collatz Conjecture
(TLDR at the bottom)
I want the script to read a user input (this part works so I didn't include it)
and based on that input, set a starting number (ognumber), and a range of numbers to try
then, i want it to iterate through every number between the ognumber and the range (in increments of 1)
for every iteration, i want it to check if each number is odd or even, do some math with the result being "newnumber", then set number = newnumber to try the result of the previous operation.
The problem I'm facing is that when I call the function, it doesn't end.
it gets stuck continuously trying the same number, it doesn't return number, and it doesn't set number = newnumber.
function isodd(number, newnumber, ResultsPath, results)
newnumber = math.floor(number * 3 + 1)
print(number..' x 3 + 1 = '..newnumber)
local writetoresultsfile = io.open(ResultsPath..'3n+1-'..results..'.xml', 'a')
writetoresultsfile:write(' '..number..' x 3 + 1 = '..newnumber..'\n')
writetoresultsfile:close()
number = math.floor(newnumber)
return number
end
function iseven(number, newnumber, ResultsPath, results)
newnumber = math.floor(number / 2)
print(number..' / 2 = '..newnumber)
local writetoresultsfile = io.open(ResultsPath..'3n+1-'..results..'.xml', 'a')
writetoresultsfile:write(' '..number..' / 2 = '..newnumber..'\n')
writetoresultsfile:close()
number = math.floor(newnumber)
return number
end
for number = ognumber, range, 1 do
local writetoresultsfile = io.open(ResultsPath..'3n+1-'..results..'.xml', 'a')
writetoresultsfile:write(' <List name = "Attempt '..ognumber..'"> \n')
writetoresultsfile:close()
print('Trying '..number)
while(number > 1) do
if(number % 2 ~= 0) then
isodd(number, newnumber, ResultsPath, results)
else
iseven(number, newnumber, ResultsPath, results)
end
end
ognumber = ognumber + 1
number = ognumber
end
if(ognumber == range + 1) then
local resultsfile = io.open(ResultsPath..'3n+1-'..results..'.xml', 'a')
resultsfile:write(' </Table>\n')
resultsfile:write('</Data>\n')
resultsfile:close()
end
This is what shows up when I run the script using function()
This script works, but I wanted to achieve the same thing using functions
for number = ognumber, range, 1 do
local writetoresultsfile = io.open(ResultsPath..'3n+1-'..results..'.xml', 'a')
writetoresultsfile:write(' <List name = "Attempt '..ognumber..'"> \n')
writetoresultsfile:close()
print('Trying '..number)
while(number > 1) do
if(number % 2 ~= 0) then
newnumber = math.floor(number * 3 + 1)
print(number..' x 3 + 1 = '..newnumber)
local writetoresultsfile = io.open(ResultsPath..'3n+1-'..results..'.xml', 'a')
writetoresultsfile:write(' '..number..' x 3 + 1 = '..newnumber..'\n')
writetoresultsfile:close()
number = newnumber
else
newnumber = math.floor(number / 2)
print(number..' / 2 = '..newnumber)
local writetoresultsfile = io.open(ResultsPath..'3n+1-'..results..'.xml', 'a')
writetoresultsfile:write(' '..number..' / 2 = '..newnumber..'\n')
writetoresultsfile:close()
number = newnumber
end
end
ognumber = ognumber + 1
number = ognumber
end
if(ognumber == range + 1) then
local resultsfile = io.open(ResultsPath..'3n+1-'..results..'.xml', 'a')
resultsfile:write(' </Table>\n')
resultsfile:write('</Data>\n')
resultsfile:close()
end
This is what it shows when I don't use function()
Edit: This Script works using the advice Shingo gave me
function isodd(number, ResultsPath, results)
newnumber = math.floor(number * 3 + 1)
print(number..' x 3 + 1 = '..newnumber)
local writetoresultsfile = io.open(ResultsPath..'3n+1-'..results..'.xml', 'a')
writetoresultsfile:write(' '..number..' x 3 + 1 = '..newnumber..'\n')
writetoresultsfile:close()
number = math.floor(newnumber)
return number
end
function iseven(number, ResultsPath, results)
newnumber = math.floor(number / 2)
print(number..' / 2 = '..newnumber)
local writetoresultsfile = io.open(ResultsPath..'3n+1-'..results..'.xml', 'a')
writetoresultsfile:write(' '..number..' / 2 = '..newnumber..'\n')
writetoresultsfile:close()
number = math.floor(newnumber)
return number
end
for number = ognumber, range, 1 do
local writetoresultsfile = io.open(ResultsPath..'3n+1-'..results..'.xml', 'a')
writetoresultsfile:write(' <List name = "Attempt '..ognumber..'"> \n')
writetoresultsfile:close()
print('Trying '..number)
while(number > 1) do
if(number % 2 ~= 0) then
number = isodd(number, ResultsPath, results)
else
number = iseven(number, ResultsPath, results)
end
end
ognumber = ognumber + 1
number = ognumber
end
if(ognumber == range + 1) then
local resultsfile = io.open(ResultsPath..'3n+1-'..results..'.xml', 'a')
resultsfile:write(' </Table>\n')
resultsfile:write('</Data>\n')
resultsfile:close()
end
TLDR about the Collatz Conjecture for those interested:
The Collatz Conjecture states that for any positive integer, if you apply 2 rules to it, will always return to 1.
The rules are: if the previous number is even, the next number is one half of the previous number. If the previous number is odd, the next number is 3 times the previous number plus 1
Although you return number from the function, it won't be updated out of the scope, you need accept it like this (same as iseven):
number = isodd(number, newnumber, ResultsPath, results)
Moreover newnumber is only used inside the function, so it's not necessary to be an argument. The function could be change to:
function isodd(number, ResultsPath, results)
local newnumber = math.floor(number * 3 + 1)

Applying my function to every position in a Numpy array

I am attempting to apply my CasinoTime function to each position in my array per sweep. The function currently does this but chooses a position at random and can only do one position per sweep. The output looks something like this:
Starting Configuration: [[ 1 -1 1 1 -1 -1 1 1 1 -1]]
0: [[ 1 -1 1 1 -1 -1 1 1 1 -1]] Energy: [-2] Spin: 0.2
1: [[ 1 -1 1 1 1 -1 1 1 1 -1]] Energy: [[-10]] Spin: 0.4
2: [[ 1 -1 1 1 1 -1 1 1 1 -1]] Energy: [[-10]] Spin: 0.4
3: [[-1 -1 1 1 1 -1 1 1 1 -1]] Energy: [[-2]] Spin: 0.2
As you can see, it only alters one position at a time. Ideally my function will run through every position in my array (per sweep) and change the values which meet the criteria. This is a simulation of A Monte Carlo/Metropolis Algorithm. I have attempted to use a map function to apply my function to my array however this does not seem to work. Any help is greatly appreciated and I have attached my code below!
import numpy as np
N = 10
J = 1
H = 2
def calcEnergy(config, J, H):
energy = 0
for i in range(config.size):
spin = config[i]
neighbour = config[(i + 1) % N]
energy = energy - J * (spin * neighbour) - H * neighbour
return energy
def ChangeInEnergy(J, H, spin, spinleft, spinright):
dE = 2 * H * spin + 2 * J * spin * (spinleft + spinright)
return dE
def CasinoTime(sweeps, beta, J, H, debug=False):
config = np.random.choice([-1, 1], (N, 1))
averagespins = []
if debug is True:
print("Starting Configuration:", (np.transpose(config)))
runningenergy = calcEnergy(config, J, H)
for i in range(sweeps):
spinlocation = np.random.randint(N)
spin = config[spinlocation]
spinright = config[(spin + 1) % N]
spinleft = config[(spin - 1) % N]
dE = ChangeInEnergy(J, H, spin, spinleft, spinright)
r = np.random.random()
if r < min(1, np.exp(-beta * dE)):
config[spinlocation] *= -1
runningenergy = runningenergy + dE
else:
pass
averagespin = config.mean()
if debug and i % 1 == 0:
print("%i: " % i, np.transpose(config), "Energy:", runningenergy, "Spin:", averagespin)
return averagespins
averagespins = CasinoTime(sweeps=20, beta=0.1, J=1, H=2, debug=True)

Need help stopping functions in corona

I'm trying to stop 3 animations in my function when it reaches a certain point and then have a message display "Animations Stopped".
How would I do this? I know about display.NewText() but how would I go about stopping the animations and getting the message to pop up at the same time?
Here is the function I'm trying to stop.
WIDTH = display.contentWidth
HEIGHT = display.contentHeight
--displays background
local s = display.newImageRect("space.png" ,1136, 640)
s.x = 900/2
s.y = 500/2
--display main ship
local r = display.newImageRect("ship.png", 70, 70)
r.x = 20
r.y = 450
local minions = {}
function createMinions()
local x = 40
local y = 120
for n = 1, 20 do -- displays 20 minions
local minion = display.newImageRect("minion.png", 50, 50)
minion.x = x
minion.y = y
minions[n] = minion
x = x + 60 -- next enemy will be to the right
if x >= WIDTH then -- start a new row if necessary
y = y + 60 -- seperation between minions
x = 40
end
end
end
--display mothership
m = display.newImageRect("mothership.png", 150, 150)
m.x = 160
m.y = 10
function nextFrame()
-- begins movements of main ship to right
r.x = r.x + 5
if r.x > 350 then
r.x = -100
end
-- begins movement of minions to the left
for i = 1, 20 do
local minion = minions[i]
minion.x = minion.x - 8
if minion.x < -100 then
minion.x = 400
end
end
--begins movement of mothership towards small ship
m.y = m.y + 10
if m.y > 460 then
m.y = -100
end
--stops all animations
if m.y > 450 then
--r.x = r.x + 0
--m.y = m.y + 0
--minion.x = minion.x + 0
local s = true
--displays game over text
s = display.newText("Game Over", WIDTH/2, 400, native, 30)
end
end
createMinions()
Runtime:addEventListener( "enterFrame", nextFrame )
--hides status bar
display.setStatusBar( display.HiddenStatusBar )
Just to make it very short -
This is the code specific to your problem.
if(m.y < 450) then YOURCODE else DISPLAYTEXTCODE end
For future I suggest people to look at:
Corona Docs: API > Libraries > Transition > To - To move display objects.
and
Corona Docs: APi > Types > EventListener > addEventListener - To trigger code based on events.

Spawn Function in Corona SDK

Okay so I kind of am almost there but need a little push:
My dustbins spawn but there are a few to begin with like I want and then after about 30 seconds of the numbers of dustbins increasing there are 1000's all clumped together.. What can i do to alter my function so that its only ever a few at a time:
function spawnDustbin()
dustbin = {}
for i = 1,800 do
dustbin[i] = display.newImage("dustbin.png")
dustbin[i].xScale = 0.55
dustbin[i].yScale = 0.55
dustbin[i].y = 555
dustbin[i].x = (math.random(1000,1500) * i)
dustbin[i].speed = 4
physics.addBody( dustbin[i], "static", { friction=1.0, density=1.0, bounce=0, radius=30,} )
dustbin[i].enterFrame = moveDustbin
Runtime:addEventListener("enterFrame", dustbin[i])
end
end
and the movedustbin function simply moves the dustbin in the negative x direction:
function moveDustbin(self,event)
if self.x < -2560 then
self.x = 2560
else
self.x = self.x - val
end
end
First 20ish seconds:
http://i.stack.imgur.com/7iEeP.png
After 20 seconds:
http://i.stack.imgur.com/aae0D.png
Thank you very much
James
That "spawnDustbin" function above is spawning 800 dustbins every frame. That will really crush your performance, and I am pretty certain you don't want to create that many objects every frame.
You might want to do something like this:
local dustbin = {}
local i = 0
local function spawnDustbin()
i = i+1
dustbin[i] = display.newImage("dustbin.png")
dustbin[i].xScale = 0.55
dustbin[i].yScale = 0.55
dustbin[i].y = 555
dustbin[i].x = (math.random(1000,1500) * i)
dustbin[i].speed = 4
physics.addBody( dustbin[i], "static", { friction=1.0, density=1.0, bounce=0, radius=30,} )
dustbin[i].enterFrame = moveDustbin
Runtime:addEventListener("enterFrame", dustbin[i])
end
timer.performWithDelay(500, spawnDustbin, 10)
YMMV but that will spawn 10 dustbins in 5 seconds.