I using PixelSearch function, I know how to find 1 pixel that match to my criteria, but the problem is that I would like to find all pixels of specific color and add this to array, so after I can use it to rand one and click on it.
Source code:
Local $aCoord = PixelSearch(0, 0, $clientSize[0], $clientSize[1], 0x09126C, 10, 1, $hWnd)
If Not #error Then
; add to array and search next
Else
GUICtrlSetData($someLabel, "Not Found")
EndIf
I want to find ALL PIXELS, not one "the first". How can I do this? Am I missing something?
This can't be done using PixelSearch because it stops executing when a matching pixel is found.
It can be done by looping PixelGetColor over your area. Something like:
For $x = 0 To $clientSize[0] Step 1
For $y = 0 To $clientSize[1] Step 1
If PixelGetColor($x,$y,$hWnd) = 0x09126C Then
;Add $x and $y to Array using _ArrayAdd() (or whatever you prefer)
EndIf
Next
Next
This might feel slower than PixelSearch because it now has to scan the entire area, instead of stopping at the first match, but it shouldn't be, since PixelSearch is based on the same principle.
Related
I am building a file-based index for the sorted haveibeenpwned passwords text file and it got me wondering what's the fastest way to do this?
I figured a good way to build a quickly grep-able index would be split the sorted file into 256 files named with the first two hex digits (i.e. FF.txt, FE.txt, etc). I found ripgrep rg to be about 5 times faster than grep on my computer. So I tried something like this:
for i in {255..0}
do
start=$(date +%s)
hex="$(printf '%02x' $i | tr [:lower:] [:upper:])"
rg "^$hex" pwned-passwords-ntlm-ordered-by-hash-v4.txt > ntlm/$hex-ntlm.txt
echo 0x$hex completed in $(($(date +%s) - $start)) seconds
done
This is the fastest solution I could come up with. ripgrep is able to create each file in 25 seconds. So I'm looking at about 100 minutes to create this index. When I split the job in half, and run them in parallel, each pair of files is created in 80 seconds. So it seems best to just let ripgrep work its magic and work in series.
Obviously, I won't be indexing this list too often, but it's just fun to think about. Any thoughts on a faster way (aside from using a database) to index this file?
ripgrep, like any other tool that's able to work with unsorted input files at all, is the wrong tool for this job. When you're trying to grep sorted inputs, you want something that can bisect your input file to find a position in logarithmic time. For big enough inputs, even a slow O(log n) implementation will be faster than a highly optimized O(n) one.
pts-line-bisect is one such tool, though of course you're also welcome to write your own. You'll need to write it in a language with full access to the seek() syscall, which is not exposed in bash.
You are reading through the file 256 times, doing a full file scan every time. Consider an approach that reads the file once, writing each line into an open file descriptor. I'm thinking python would be an easy choice of implementation (if that's your thing). You could optimize by keeping the file open until you hit a new hex code at the beginning of the line. If you want to be even more clever, there is no need to go through the sorted file line by line. Based on Charles Duffy's hint, you could create a heuristic for sampling the file (using seek()) to get to the next hex value. Once the program has found the byte offset of the next hex value, the block of bytes can be written to the new file. However, since this is tagged as 'bash' let's keep the solution set in that domain:
while
read line
do
hex=${line:0:2}
echo $line >> ntlm/$hex-ntlm.txt
done < pwned-passwords-ntlm-ordered-by-hash-v4.txt
I wrote a Python3 script that solves fast binary-search lookups in the hash file without having to create an index. It doesn't directly address your question (indexing) but probably solves the underlying problem that you wanted to solve with an index - to quickly look up individual hashes. This script checks hundreds of passwords in seconds.
import argparse
import hashlib
parser = argparse.ArgumentParser(description='Searches passwords in https://haveibeenpwned.com/Passwords database.')
parser.add_argument('passwords', metavar='TEST', type=str, help='text file with passwords to test, one per line, utf-8')
parser.add_argument('database', metavar='DATABASE', type=str, help='the downloaded text file with sha-1:count')
args = parser.parse_args()
def search(f: object, pattern: str) -> str:
def search(left, right: int) -> str:
if left >= right:
return None
middle = (left + right) // 2
if middle == 0:
f.seek(0, 0)
test = f.readline()
else:
f.seek(middle - 1, 0)
_ = f.readline()
test = f.readline()
if test.upper().startswith(pattern):
return test
elif left == middle:
return None
elif pattern < test:
return search(left, middle)
else:
return search(middle, right)
f.seek(0, 2)
return search(0, f.tell())
fsource = open(args.passwords)
fdatabase = open(args.database)
source_lines = fsource.readlines()
for l in source_lines:
line = l.strip()
hash_object = hashlib.sha1(line.encode("utf-8"))
pattern = hash_object.hexdigest().upper()
print("%s:%s" % (line, str(search(fdatabase, pattern)).strip()))
fsource.close()
fdatabase.close()
I am trying to create a New variable "X", from Variables "A" "B" and "C".
This is the code that I am using.
I only get the first option "VAS_USAGE=1", the other options are lost.
What I wanted was for VAS_USAGE to have 1 to 6 values.
What am I doing wrong?
```
compute VAS_USAGE=0.
DO IF ((VAS1=1) AND (VAS2=1) AND (VAS3=1)).
COMPUTE VAS_USAGE=1.
ELSE IF ((VAS1=1) AND (VAS2=1) AND (VAS3=0)).
COMPUTE VAS_USAGE=2.
ELSE IF ((VAS1=1) AND (VAS2=0) AND (VAS3=1)).
COMPUTE VAS_USAGE=3.
ELSE IF ((VAS1=1) AND (VAS2=0) AND (VAS3=0)).
COMPUTE VAS_USAGE=4.
ELSE IF ((VAS1=0) AND (VAS2=0) AND (VAS3=1)).
COMPUTE VAS_USAGE=5.
ELSE IF ((VAS1=0) AND (VAS2=0) AND (VAS3=0)).
COMPUTE VAS_USAGE=6.
END IF.
EXECUTE.```
This is how the nested table looks like. This is what I was expecting to get.
This is what I got.
1.00 = 63
As suggested by #user45392 I would check if the answers 'yes' and 'no' are indeed coded as 1 and 0.
In any case I would suggest avoiding the complex 'do if' scheme which might be prone to errors and harder to debug. For example, you could create VAS_USAGE like this:
compute VAS_USAGE = 100*VAS1 + 10*VAS2 + VAS3.
Or if you want to stick to the specific values you gave in your post, add this:
recode VAS_USAGE (111=1)(110=2)(101=3)(100=4)(1=5)(0=6).
Also if you just want a simple index from 1 to 8 you can do this:
compute VAS_USAGE = 4*VAS1 + 2*VAS2 + VAS3 + 1.
I am writing a simple code in matlab which has the purpose of creating the histogram of a grayscale image without using the function hist. I am stuck at the point in which mathlab displays the error "Subscript indices must either be real positive integers or logicals." Can you help me finding where is the wrong indices?
indirizzo='file.jpg';
immagine=imread(indirizzo);
immaginebn=rgb2gray(immagine);
n=zerps(0,255);
for x=0:255;
numeroennesimo=sum(sum(immaginebn==x));
n(x)=numeroennesimo;
end
plot(x,n)
you cant use 0 as index. Either make n(x+1) or for x = 1:256 and substract the 1 in your comparison. And there is a typo, I guess it means zeros instead of zerps, which also doesnt work with a 0. And one more, your plot will also not work as the x has only a size of 1 while n is an array of 266 and for a histogram I would use a barplot instead.
indirizzo='file.jpg';
immagine=imread(indirizzo);
immaginebn=rgb2gray(immagine);
n=zeros(1,256);
for x=0:255;
numeroennesimo=sum(sum(immaginebn==x-1));
n(x+1)=numeroennesimo;
end
bar(0:255,n)
or
indirizzo='file.jpg';
immagine=imread(indirizzo);
immaginebn=rgb2gray(immagine);
n=zeros(1,256);
xplot=zeros(1,256);
for x=1:256;
numeroennesimo=sum(sum(immaginebn==x-1));
n(x)=numeroennesimo;
xplot(x) = x-1;
end
plot(xplot,n)
I'm running some array jobs on a PBS system (although hopefully no knowledge of PBS systems is needed to answer my question!). I've got 24 runs, but I want to split them up into 5 sub-jobs each, so I need to run my script 120 times.
After giving the PBS option of -t 1-120, I can get the current job-array ID using $PBS_ARRAYID. However, I want to create some output files. It would be best if these output files used the ID that it would have had if there were only 24 runs, together with a sub-run identifier (e.g. output-1a.txt, output-1b.txt ... output-1e.txt, output-2a.txt).
What I therefore need is a way of calculating a way to get the ID (in the range 1-24) together with the sub-run identifier (presumably in a set of if-statements), which can be used in a shell-script. Unfortunately, neither my maths nor my Unix knowledge is quite good enough to figure this out. I assume that I'll need something to do with the quotient/remainder based on the current $PBS_ARRAYID relative to either 120 or 24, but that's as far as I've got...
You just need a little modular division. A quick simulation of this in Ruby would be:
p = Array.new;
(1..120).each {|i| p[i] = "Run #{1+(i/5)}-#{((i%5)+96).chr}" }
What this says is simply that the run should start at 1 and increment after each new section of five, and that the trailing sub-run should be the ascii character represented by 96 plus the position of the sub-run (eg, 97 == 'a').
Here it is in Bash:
#!/bin/bash
chr() {
local tmp
[ ${1} -lt 256 ] || return 1
printf -v tmp '%03o' "$1"
printf \\"$tmp"
}
for ((i = 0; i < ${#ARP[*]}; i++))
do
charcode=$((($i % 5)+97))
charachter=$(chr "$charcode")
echo "Filename: output-$((($i/5)+1))$charachter"
done
I just used ARP as the name of the array, but you can obviously substitute that. Good luck!
I wrote a Secret Santa program (ala Ruby Quiz...ish), but occasionally when the program runs, I get an error.
Stats: If there's 10 names in the pot, the error comes up about 5% of the time. If there's 100 names in the pot, it's less than 1%. This is on a trial of 1000 times in bash. I've determined that the gift arrays are coming up nil at some point, but I'm not sure why or how to avoid it.
Providing code...
0.upto($lname.length-1).each do |i|
j = rand($giftlname.length) # should be less each time.
while $giftlname[j] == $lname[i] # redo random if it picks same person
if $lname[i] == $lname.last # if random gives same output again, means person is left with himself; needs to switch with someone
$giftfname[j], $fname[i] = $giftfname[i], $fname[j]
$giftlname[j], $lname[i] = $giftlname[i], $lname[j]
$giftemail[j], $email[i] = $giftemail[i], $email[j]
else
j = rand($giftlname.length)
end
end
$santas.push('Santa ' + $fname[i] + ' ' + $lname[i] + ' sends gift to ' + $giftfname[j] + ' ' + $giftlname[j] + ' at ' + '<' + $giftemail[j] + '>.') #Error here, something is sometimes nil
$giftfname.delete_at(j)
$giftlname.delete_at(j)
$giftemail.delete_at(j)
end
Thanks SO!
I think your problem is right here:
$giftfname[j], $fname[i] = $giftfname[i], $fname[j]
Your i values range between zero to the last index in $fname (inclusive) and, presumably, your $giftfname starts off as a clone of $fname (or at least another array with the same length). But, as you spin through the each, you're shrinking $giftfname so $giftfname[i] will be nil and the swap operation above will put nil into $giftfname[j] (which is supposed to be a useful entry of $giftfname). Similar issues apply to $giftlname and $giftemail.
I'd recommend using one array with three element objects (first name, last name, email) instead of your three parallel arrays. There's also a shuffle method on Array that might be of use to you:
Start with an array of people.
Make copy of that array.
Shuffle the copy until it is different at every index from that original array.
Then zip the together to get your final list of giver/receiver pairs.
Figured it out and used the retry statement. the if statement now looks like this (all other variables have been edited to be non-global as well)
if lname[i] == lname.last
santas = Array.new
giftfname = fname.clone
giftlname = lname.clone
giftemail = email.clone
retry
That, aside from a few other edits, created the solution I needed without breaking apart the code too much again. Will definitely try out mu's solution as well, but I'm just glad I have this running error-free for now.