How to skew random choice probability towards one option? - python-3.x

I am using the random library in python to select win or lose.
import random
choice = random.choice(['win','lose'])
Is there anyway I can say set the probability in the code to say I want more lose than win everytime the code runs?

Well, #CloC is technically right, you could do that, but better use the standard Python library as it is designed, less code, less bugs
F.e., sampling with probability of Win being 60%
v = random.choices(["Win", "Lose"], weights=[60, 40], k=1)

A way to control random (which wont be random...) would be to:
Generate a number between 1 and 100:
n = random.randint(1,101)
and then compare it with the percentage of win/loses you want :
chances_to_win = 51 # 50%
if n < chances_to_win:
print(str(chances_to_win-1) +"% chances to Win")
choice = "Win"
else:
print(str(100-(chances_to_win-1)) +"% chances to Lose")
choice = "Lose"
That way, you can control what is the percentage of wins and loses.

Related

z3py solver.check() goes from "sat" to "unknown" when I increase length of Bitvector

I want to factor a number n with Bitvectors in Z3. I use Bitvectores because I want to constrain single bits in p an q. This simple example does work and the solver returns "sat".
from z3 import *
Bits = 32
n = 12
p_vec = BitVec('p', Bits)
q_vec = BitVec('q', Bits)
n_vec = BitVecVal(n,Bits)
s = Solver()
s.add(p_vec * q_vec == n_vec)
s.add(p_vec > 1, q_vec > 1)
s.add(BVMulNoOverflow(p_vec,q_vec,False))
print (s.check())
But now I want to factor another number n with 4096 Bits. So I changend Bits=4096 in the example and used the same numbers. The solver give me now "unknow" instead of "sat".
It seems the solver discontinues at some point. Do I have to change some solver settings or is there an other approach to do that.
When I run your program with Bits = 4096, it does not say unknown. It simply does not finish quickly (I waited for a few minutes), and I wouldn't expect it to.
Bitvector solver is complete. That is, if you wait long enough, it'll eventually return sat or unsat, assuming you do not run out of memory (and patience). For this problem, however, the amount you'll wait might be practically infinite, and you'll most likely run out of memory on your computer long before that happens. So, I'm not sure how you're getting that unknown. Maybe you're using some timeout options, or something else you're not showing here.
You can try adding constraints of the form: p_vec < n and q_vec < p_vec to break symmetries. And it could indeed help in some cases since n is a constant. But this is in general futile, and for any reasonable bit size for use in cryptographic practice, the solver will practically loop forever.
Factorization is a hard problem for obvious reasons and an SMT solver is definitely not the right tool for it. See here for an earlier discussion: Bitvector function Z3

How to make multiple objects work at same time?

I have been using Python to control some instruments, which I created a Class for. I have multiple instruments of the same kind, so my script has multiple instances of the same class.
Let's say the class is Arm, and it has methods move_left, move_right and reset. Right now I have script like this:
arm1 = Arm()
arm2 = Arm()
arm1.move_left()
arm2.move_left()
arm1.move_right()
arm2.move_right()
arm1.reset()
arm2.reset()
It's completely in serial. I have to wait for arm1 to finish move_left, then start arm2 to move_left. This is very inefficient. I would like arm1 and arm2 to move at the same time. They don't have to be exact same time, because arm1 and arm2 are quite independent and there's not much synchronization requirement. I just don't want to waste time in the serialization in the code.
I've done some searching and learned a little about threading, but what I found is all about putting a function in a Thread target, which doesn't really apply to my situation here.
One way to approach the problem would be to implement a state machine. That is, instead of defining the problem through commands like move_left() and move_right(), instead you can have some variables that represent the final position that you want each arm to end up at, and a second set of variables that represent the current position of the arm. Then at each time-step, you simply move the arms by a small amount towards their target-destination.
Here's a very simple toy program to demonstrate the idea. Note that it moves each "arm" by no more than 0.1 units every 100mS time-step (you can of course use any time-step and maximum-movement values you want instead):
import time
class Robot:
def __init__(self):
self._leftArmCurrentPos = 0.0
self._leftArmTargetPos = 0.0
self._rightArmCurrentPos = 0.0
self._rightArmTargetPos = 0.0
def setLeftArmTargetPos(self, newPos):
self._leftArmTargetPos = newPos
def setRightArmTargetPos(self, newPos):
self._rightArmTargetPos = newPos
# Returns the closest value to (deltaVal) in the range [-0.1, +0.1]
def clamp(self, deltaVal):
aLittleBit = 0.1 # or however much you want
if (deltaVal > aLittleBit):
return aLittleBit
elif (deltaVal < -aLittleBit):
return -aLittleBit
else:
return deltaVal
def moveArmsTowardsTargetPositions(self):
leftArmDelta = self.clamp(self._leftArmTargetPos - self._leftArmCurrentPos)
if (leftArmDelta != 0.0):
self._leftArmCurrentPos += leftArmDelta
print("Moved left arm by %f towards %f, new left arm pos is %f" % (leftArmDelta, self._leftArmTargetPos, self._leftArmCurrentPos))
rightArmDelta = self.clamp(self._rightArmTargetPos - self._rightArmCurrentPos)
if (rightArmDelta != 0.0):
self._rightArmCurrentPos += rightArmDelta
print("Moved right arm by %f towards %f, new right arm pos is %f" % (rightArmDelta, self._rightArmTargetPos, self._rightArmCurrentPos))
if __name__ == "__main__":
r = Robot()
r.setLeftArmTargetPos(10.0)
r.setRightArmTargetPos(-3.0)
while True:
r.moveArmsTowardsTargetPositions()
time.sleep(0.1)
A nice side-effect of this approach is that you if change your mind at any time about where you want the arms to be, you can simply call setLeftArmTargetPos() or setRightArmTargetPos() to give the arms new/different destination values, and they will immediately start moving from (wherever they currently are at) towards the new target positions -- there's no need to wait for them to arrive at the old destinations first.

Can One Decrease Overall Accuracy in Python?

I'm making a program to calculate primes, and I look at the remainder of the possible prime I'm testing and all the primes I have so far, but stop if I get to the point where I am comparing the PossPrime to anything above its square root. (I can explain this if needed). I don't care about any digits after the decimal point of the sqrt; is there a way to tell Python not to bother calculating those?
And, is there a way to integrate that aspect (only testing the primes under it until I get to the sqrt) into the for loop?
#There's some boring setup before here that isn't problematic.
while True:
PossWasDivis = False #initialize the var (used to convey if the possible prime was divis)
sqrtP = int(sqrt(PossPrime))
for iterationOfArray in range(2, sqrtP):
# print ("Comparing: (", PossPrime, "% (", GlobPrimeList [iterationOfArray],")) == 0")
if (PossPrime % (GlobPrimeList [iterationOfArray])) == 0:
# print(PossPrime, "was divisable by", GlobPrimeList[iterationOfArray],"! Breaking for loop")
PossWasDivis = True
break
if (GlobPrimeList [iterationOfArray]) > sqrtP:
break
if PossWasDivis == False: # Occurs when none of the tested #s are divis
GlobPrimeList.append (PossPrime)
f.write(str(PossPrime)+'\n')
#Switch between incramenting PossPrime between 2 and 4
if PossPrimeStat == 2:
PossPrimeStat = 4
PossPrime += 4
else: # if PossPrimeStat == 4:
PossPrimeStat = 2
PossPrime += 2
The GlobPrimeList has some primes preloaded in it to start out with and continues finding more indefinitely until I cancel the program.
I don't care about any digits after the decimal point of the sqrt; is there a way to tell Python not to bother calculating those?
Nope.
math.sqrt() works with floating-point values. The precision you get is baked right in to the math.
Python does contain functions for "arbitrary-precision" math, where you can specify how much precision you will get... but those functions are much slower than the functions that operate on float values. If you want faster code, you will be using float values, and there is no way to tell Python not compute the whole value.

Audio analysis to detect low volume periods

i have a sequence of audio files (they are currently both wav and mp3). These files consist of a beep, a pause and then the reply of a person. I need to find the reaction time between the beep and the person replying. There is a lot of data so i would like to make a program that could do this for me. Does anyone have any idea what language this could be done in, or know of any existing programs that will do this. I have looked into the wave tool in python, and can't seem to find any data that represents the low moments.
i program to function like this:
wav = open(wave file)
chunk = getNextChunk(wav)
volume = analyse(chunk)
check against threshold
if silent period, check for loud period
find difference
log time in seconds
Can anyone help me with this, i know its a very open ended question, but i have no idea where to start with this, i've programmed in java and python among others, but will use whats best, same with the sound format. Would it also be better to make the files mono?
Thanks for your help!
As to your choise of language I would personally choose Matlab. However it costs money, and as you already have experience with python the numpy module might be the right thing for you.
Based on your description of your problem, this could be one approach:
Load wav
Find envelope and smooth with a fast time constant
Threshold
Find time for beep
Find time for response
Calculate difference
Going to mono will be fine and reduce your amount of data at the same time.
I have found a solution that works, although my algorithm for detecting audio is pretty lousy, and is not very accurate. The amplitude or frequency of the sound seems to be visible, so the more digits a number has, the louder it is. I detect long sequences of digits to determine this, but one digit that doesnt fit the pattern and the cycle resets. Would be better to dermine based on the difference between the previous digits.
import wave, struct, logging
# open up a wave
w = wave.open('wavefile.WAV', 'rb')
length = w.getnframes()
rate = w.getframerate()
logging.basicConfig(filename='example.log',level=logging.DEBUG)
count = 0
start = 1
end = 0
startData = 0
endData = 0
for i in range(0,length):
waveData = w.readframes(1)
data = struct.unpack("<h", waveData)
if (start == 1):
if (len(str(int(data[0])))>=len(str(1234))):
count=count+1
else:
count=0
if (count == 100):
startData=i-100
print("Start "+str(startData/float(rate)))
count = 0
start = 0
end = 1
if (end == 1):
if (len(str(int(data[0])))<=len(str(12))):
count=count+1
else:
count=0
if (count == 10):
endData=i-10
print("End "+str(endData/float(rate)))
count = 0
start = 1
end = 0
frames=endData-startData
duration=frames/float(rate)
print("Duration: "+str(duration))

How to avoid impression bias when calculate the ctr?

When we train a ctr(click through rate) model, sometimes we need calcute the real ctr from the history data, like this
#(click)
ctr = ----------------
#(impressions)
We know that, if the number of impressions is too small, the calculted ctr is not real. So we always set a threshold to filter out the large enough impressions.
But we know that the higher impressions, the higher confidence for the ctr. Then my question is that: Is there a impressions-normalized statistic method to calculate the ctr?
Thanks!
You probably need a representation of confidence interval for your estimated ctr. Wilson score interval is a good one to try.
You need below stats to calculate the confidence score:
\hat p is the observed ctr (fraction of #clicked vs #impressions)
n is the total number of impressions
zα/2 is the (1-α/2) quantile of the standard normal distribution
A simple implementation in python is shown below, I use z(1-α/2)=1.96 which corresponds to a 95% confidence interval. I attached 3 test results at the end of the code.
# clicks # impressions # conf interval
2 10 (0.07, 0.45)
20 100 (0.14, 0.27)
200 1000 (0.18, 0.22)
Now you can set up some threshold to use the calculated confidence interval.
from math import sqrt
def confidence(clicks, impressions):
n = impressions
if n == 0: return 0
z = 1.96 #1.96 -> 95% confidence
phat = float(clicks) / n
denorm = 1. + (z*z/n)
enum1 = phat + z*z/(2*n)
enum2 = z * sqrt(phat*(1-phat)/n + z*z/(4*n*n))
return (enum1-enum2)/denorm, (enum1+enum2)/denorm
def wilson(clicks, impressions):
if impressions == 0:
return 0
else:
return confidence(clicks, impressions)
if __name__ == '__main__':
print wilson(2,10)
print wilson(20,100)
print wilson(200,1000)
"""
--------------------
results:
(0.07048879557839793, 0.4518041980521754)
(0.14384999046998084, 0.27112660859398174)
(0.1805388068716823, 0.22099327100894336)
"""
If you treat this as a binomial parameter, you can do Bayesian estimation. If your prior on ctr is uniform (a Beta distribution with parameters (1,1)) then your posterior is Beta(1+#click, 1+#impressions-#click). Your posterior mean is #click+1 / #impressions+2 if you want a single summary statistic of this posterior, but you probably don't, and here's why:
I don't know what your method for determining whether ctr is high enough, but let's say you're interested in everything with ctr > 0.9. You can then use the cumulative density function of the beta distribution to look at what proportion of probability mass is over the 0.9 threshold (this will just be 1 - the cdf at 0.9). In this way, your threshold will naturally incorporate uncertainty about the estimate because of limited sample size.
There are many ways to calculate this confidence interval. An alternative to the Wilson Score is the Clopper-Perrson interval, which I found useful in spreadsheets.
Upper Bound Equation
Lower Bound Equation
Where
B() is the the Inverse Beta Distribution
alpha is the confidence level error (e.g for 95% confidence-level, alpha is 5%)
n is the number of samples (e.g. impressions)
x is the number of successes (e.g. clicks)
In Excel an implementation for B() is provided by the BETA.INV formula.
There is no equivalent formula for B() in Google Sheets, but a Google Apps Script custom function can be adapted from the JavaScript Statistical Library (e.g search github for jstat)

Resources