Read text from screen with OCR python - python

I developed this script in SIKULI, but I would like to add more functions and I'm thinking about using Python and learning the language.
SIKULI has OCR but still contains some bugs, not performing so well. Likewise I would like to use OCR/tesseract/pytesseract in python.
The idea of ​​this script is to make you heal in a game, according to the current % of health, reading the number of the current health bar vs the total value it has.
After reading this number, a calculation is performed with the result in %.
Could you help me fix this script by inserting the necessary libraries and tweaking the code to make it work in Python?
#==Config HP==
Healing_1 = 95
Hk_healing_1 = '5'
Healing_2 = 65
Hk_healing_2 = '1'
Healing_3 = 30
Hk_healing_3 = '3'
#==Code==
while True:
GAME = App("GAME")
GAME.focus()
Settings.OcrTextRead = True
#==hp==
hp = Region(88,28,191,23)
hp = hp.text()
hp2 = hp.replace(",","")
X = hp2.split("/")
try:
check_hp = float(X[0]) / float(X[1]) * 100
except:
type(Hk_healing_3)
#==hp check==
if check_hp < 100:
if check_hp <= Healing_3:
type(Hk_healing_3)
elif check_hp <= Healing_2:
type(Hk_healing_2)
elif check_hp <= Healing_1:
type(Hk_healing_1)
else:
pass
Just for information, this function should identify the text in a region of the screen. The text of the screen, will be displayed as xxxx/xxxx (current value / total value) - it's could be other format as x/x, xx/xx, xxx/xxx, xxxx/xxxx, xxxxx/xxxxx, x/xxxx, x/xxxxxxx ...
The text will be split to perform the calculation (% of current value).

Related

Getting the results simultaneously from different sources

python newbie here!
I am trying to write a small program for myself which is basically getting price information from different exchanges and comparing them, so far it is working great but honestly, I want to make it better in terms of performance and efficiency.
What I mean by efficiency is my program is checking prices step by step and printing the results. My question is can I convert it to checking the prices simultaneously from different exchanges and print them all at the same time?
Below is the part of the code that I wrote:
#Novadax
symbol_novadax = coin_list[i] + "_USDT"
response_novadax = requests.get('https://api.novadax.com/v1/market/ticker?symbol=' + symbol_novadax)
novadax_dic = json.loads(response_novadax.content)
try:
if "ask" in novadax_dic["data"]:
novadax_bid_price = float(novadax_dic["data"]["bid"])
print("novadax_bid_price "+str(novadax_bid_price))
novadax_ask_price = float(novadax_dic["data"]['ask'])
print("novadax_ask_price " + str(novadax_ask_price))
if (max_bid_val < novadax_bid_price):
max_bid_val = novadax_bid_price
max_bid_place = "novadax"
if (min_ask_val > novadax_ask_price):
min_ask_val = novadax_ask_price
min_ask_place = "novadax"
except:
print(coin_list[i] + " not in novadax")
if is_run == False:
telegram_send.send(messages=["False novadax"], parse_mode=None)
break
#ZT
symbol_zt = coin_list[i] + "_USDT"
response_zt = requests.get('https://www.ztb.im/api/v1/tickers')
zt_dic = json.loads(response_zt.content)
# print(next(item for item in zt_dic["ticker"] if item["symbol"] == symbol_zt))
try:
if "buy" in next(item for item in zt_dic["ticker"] if item["symbol"] == symbol_zt):
zt_bid_price = float(next(item for item in zt_dic["ticker"] if item["symbol"] == symbol_zt)["buy"])
print("zt_bid_price "+str(zt_bid_price))
zt_ask_price = float(next(item for item in zt_dic["ticker"] if item["symbol"] == symbol_zt)['sell'])
print("zt_ask_price " + str(zt_ask_price))
if (max_bid_val < zt_bid_price):
max_bid_val = zt_bid_price
max_bid_place = "zt"
if (min_ask_val > zt_ask_price):
min_ask_val = zt_ask_price
min_ask_place = "zt"
except:
print(coin_list[i] + " not in zt")
if is_run == False:
telegram_send.send(messages=["False zt"], parse_mode=None)
break
my input is something like that:
zt_bid_price = 0.12
zt_ask_price = 0.14
novadax_bid_price = 0.13
novadax_ask_price= 0.14
To be more clear, I am not getting those results at the same time. I mean it prints in order and I am planning to add more exchanges in the future which means if I decide to print everything at the end of the code that will give me slightly old data. Does anyone have any idea about how can I solve this problem?
Thanks in advance!
Depending on your implementation you can use multi-processing to keep each ticker going. However there is overhead for each process which depending on your system, may or may not lag. You could have all the processes(tickers) running and either on a signal or on a time interval, have each simultaneously poll their source (with time stamp) and return their data.
There is a learning curve. The line below will get you started.
from multiprocessing import Pool

Always go to the closest number compatible with the target song's BPM

A program I'm developing involves a function that adjusts the BPM (beats per minute) of one song to the BPM of another target song.
The issue is, sometimes adjusting the song to the exact BPM of the target song isn't a good idea, as the first song may be sped up or slowed down too much, so it sounds too fast or too slow. In these situations, it makes sense to adjust the BPM of the song to another closer BPM that is still compatible with the target song's BPM.
Here's an example:
BPM of song 1: 150BPM
BPM of target song: 84BPM
In this case, slowing down a 150BPM song to 84BPM isn't very practical - the audio will become too distorted and sound weird. It makes more sense to adjust song 1 to 168BPM - double the BPM of the target song, as this requires significantly less modification to song 1, and will sound more natural.
Looking at the same example switched around:
BPM of song 1: 84BPM
BPM of target song: 150BPM
In this case, it makes sense to slow song 1 down to 75BPM, half of 150, rather than speeding the song all the way up to 150.
In this program, the BPMs of song 1 and the target song differ based on what songs it is given (obviously). What is want this function to do is always go to the closest number compatible with the target BPM - what's the math I need? I'm using Python. I've had a huge headache today making the rest of the whole program.
I think you have all you need. You can figure it out as a human, so put that into code. The problem often is that you don't exactly know what you're doing, because you're too used to it.
Let's get started with a function definition:
def targetbpm(bpmPlaying: int, bpmTarget: int) -> int:
pass
And the given expected outcomes of the two examples you provided
assert(targetbpm(150, 84) == 168)
assert(targetbpm(84, 150) == 75)
Let's tackle the first assertion. What options are there? As you said, you could go to 84, but it would be better to double that.
def targetbpm(bpmPlaying: int, bpmTarget: int) -> int:
choices = [bpmTarget, bpmTarget*2]
Which one to choose? The one with the minimum difference to what is currently playing. So let's get these differences and the minimum of these:
bpmdiff = [abs(bpmPlaying - choice) for choice in choices]
minimum = min(bpmdiff)
Now let's go back to the original choices and select the corresponding one
index = bpmdiff.index(minimum)
return choices[index]
Now you'll find that the second assertion is not passing yet. The reason is that you have another choice here: half the BPM. So let's add that:
choices = [bpmTarget, bpmTarget*2, bpmTarget // 2]
Problem solved.
This would be one quick way to do it.
def get_BPM_multiple(base, target):
distance = abs(target - base)
multiple = 1
for i in range(2, 8): # 8 or whatever
if base < target:
newdist = abs(target - base * i)
else:
newdist = abs(target - base / i)
if newdist < distance:
distance = newdist
multiple = i
else:
break
if base < target:
print(f"Multiply base {base}BPM by {multiple}: {base * multiple}BPM, "
f"close to target {target}BPM.")
return base * multiple
else:
print(f"Divide base {base}BPM by {multiple}: {base / multiple}BPM, "
f"close to target {target}BPM.")
return base / multiple
get_BPM_multiple(base=300, target=84)
# Divide base 300BPM by 4: 75.0BPM, close to target 84BPM.
get_BPM_multiple(base=84, target=150)
# Multiply base 84BPM by 2: 168BPM, close to target 150BPM.

How to add a video timeline in discord.py?

So i was using Rythm bot in discord and while using the command {prefix}np i noticed that there is video duration display. Please view the given image.
IMAGE
I wanna know how to do it in discord.py, it might be useful for me. When you seek a specific time frame, it should display the timeline with correct ratio and proportion(i exactly don't know how to explain it but you get it right). I tried doing myself and i failed. so any help would be appreciated :)
First, you have to determine the length of the song, the current play length, and how many characters long your answer should be.
Now you have to determine the location of the play sign (current_length).
You can do that by doing the same as if you wanted to calculate a percentage, but instead of 100% maximum you want the character length (20 in this case) as maximum:
current_length = display_length / total_seconds * current_seconds
You also have to convert current_length to an integer so you can determine its loaction in the display_string
So, putting that into code:
total_seconds = 217
current_seconds = 132
display_string = ""
display_length = 20
current_length = int(display_length / total_seconds * current_seconds)
for i in range(display_length):
if i == current_length:
display_string += ">"
else:
display_string += "-"
print(display_string)

Find the speed of download for a progressbar

I'm writing a script to download videos from a website. I've added a report hook to get download progress. So, far it shows the percentage and size of the downloaded data. I thought it'd be interesting to add download speed and eta.
Problem is, if I use a simple speed = chunk_size/time the speeds shown are accurate enough but jump around like crazy. So, I've used the history of time taken to download individual chunks. Something like, speed = chunk_size*n/sum(n_time_history).
Now it shows a stable download speed, but it is most certainly wrong because its value is in a few bits/s, while the downloaded file visibly grows at a faster pace.
Can somebody tell me where I'm going wrong?
Here's my code.
def dlProgress(count, blockSize, totalSize):
global init_count
global time_history
try:
time_history.append(time.monotonic())
except NameError:
time_history = [time.monotonic()]
try:
init_count
except NameError:
init_count = count
percent = count*blockSize*100/totalSize
dl, dlu = unitsize(count*blockSize) #returns size in kB, MB, GB, etc.
tdl, tdlu = unitsize(totalSize)
count -= init_count #because continuation of partial downloads is supported
if count > 0:
n = 5 #length of time history to consider
_count = n if count > n else count
time_history = time_history[-_count:]
time_diff = [i-j for i,j in zip(time_history[1:],time_history[:-1])]
speed = blockSize*_count / sum(time_diff)
else: speed = 0
n = int(percent//4)
try:
eta = format_time((totalSize-blockSize*(count+1))//speed)
except:
eta = '>1 day'
speed, speedu = unitsize(speed, True) #returns speed in B/s, kB/s, MB/s, etc.
sys.stdout.write("\r" + percent + "% |" + "#"*n + " "*(25-n) + "| " + dl + dlu + "/" + tdl + tdlu + speed + speedu + eta)
sys.stdout.flush()
Edit:
Corrected the logic. Download speed shown is now much better.
As I increase the length of history used to calculate the speed, the stability increases but sudden changes in speed (if download stops, etc.) aren't shown.
How do I make it stable, yet sensitive to large changes?
I realize the question is now more math oriented, but it'd be great if somebody could help me out or point me in the right direction.
Also, please do tell me if there's a more efficient way to accomplish this.
_count = n if count > n else count
time_history = time_history[-_count:]
time_weights = list(range(1,len(time_history))) #just a simple linear weights
time_diff = [(i-j)*k for i,j in zip(time_history[1:], time_history[:-1],time_weights)]
speed = blockSize*(sum(time_weights)) / sum(time_diff)
To make it more stable and not react when download spikes up or down you could add this as well:
_count = n if count > n else count
time_history = time_history[-_count:]
time_history.remove(min(time_history))
time_history.remove(max(time_history))
time_weights = list(range(1, len(time_history))) #just a simple linear weights
time_diff = [(i-j)*k for i,j in zip(time_history[1:], time_history[:-1],time_weights)]
speed = blockSize*(sum(time_weights)) / sum(time_diff)
This will remove highest and lowest spike in time_history which will make number displayed more stable. If you want to be picky, you probably could generate weights before removal, and then filter mapped values using time_diff.index(min(time_diff)).
Also using non-linear function (like sqrt()) for weights generation will give you better results. Oh and as I said in comments: adding statistical methods to filter times should be marginally better, but I suspect it's not worth overhead it would add.

To/From Paging in Python

All,
This may be a pretty novice question but I am stuck on how to do this in Python. What I need to do is, set the to and from params when requesting data from Panaramio.
http://www.panoramio.com/map/get_panoramas.php?set=public&from=0&to=100&minx=-180&miny=-90&maxx=180&maxy=90&size=medium&mapfilter=true
Panoramio only allows you to return 100 records at a time so I need to build out the url string to show the advancement of the sets of 100. eg. 101-200, 201-300, etc. Is there an example anywhere that will show me how to do this type of paging using Python?
Thanks,
Adam
UPDATE:
The following example seems to do what I want it to do. Now I have to figure out how to do the actual iteration from 101-200, 201-300, etc...From there I can take those values and build out my query string. Does this make sense?
def counter(low, high):
current = low
while current <= high:
yield current
current += 100
if __name__ == '__main__':
for c in counter(100, 200):
print c
UPDATE #2: I was making it harder than it should have been
def counter(low, high):
while low <= high:
yield low, high
low += 100
high += 100
for i in counter(1, 100):
print i
for number in range(1, 301, 100):
low = number
high = low + 100

Categories