Quick selection script issue - windows

I have this autohotkey script that points to the entire word by pointing to the first word and if the cursor scrolls 110px in one direction. The code uses Ctrl + Shift + {Right} to select the next words, but for the previous words you can't use Ctrl + Shift + {Left} because the current word is deselected.
How could I solve this problem so that it selects well in this direction?
#If WinActive("ahk_exe chrome.exe") && A_Cursor = "IBeam" ; Is in Chrome and cursor is on text field
~LButton::
Click
MouseGetPos, x1
SetTimer, Check, 100
SoundBeep, 1500
KeyWait, LButton
SetTimer, Check, Off
SoundBeep, 1000
Return
#If
Check:
MouseGetPos, x2
f := Floor(Abs((x2 - x1) / 110)) ; calculate if the pointer have travel 110px
Switch
{
Case x2 > x1: Send ^+{Right %f%}
Case x2 < x1: Send % "{Right}^+{Left " f + 1 "}" ;Does not allow selecting the previous word while keeping the current word selected
}
Return

Related

Optimising PixelSearch

I need to optimise this AHK script, currently the script runs in around 2 seconds. I would ultimately like it to run >1 second, the best case would be 0.6 seconds. The basic functionality is the script is clicking on red boxes, of which there can be between 2 - 8. I'd love some help on ways to increase the speed of this script if possible.
Thanks, code below.
1::
; Activate the target window
WinActivate, Paint
; Define the search area
SearchLeft := 1047
SearchTop := 572
SearchRight := 1222
SearchBottom := 650
SetDefaultMouseSpeed, 0
; Start the timer
StartTime := A_TickCount
; Loop through all pixels in the search area and click on them
Loop {
; Search for the next pixel
PixelSearch, Px, Py, SearchLeft, SearchTop, SearchRight, SearchBottom, 0x0000FF, RGBFast, Fastest
if (ErrorLevel = 0) {
; Click on the pixel
Click, %Px%, %Py%, 1
}
else {
; If no pixel is found, exit the loop
break
}
}
; Calculate the elapsed time
ElapsedTime := A_TickCount - StartTime
; Output the elapsed time as a message box
MsgBox, % "Script completed in " . ElapsedTime . " milliseconds."
3::ExitApp

Select whole words when mouse hovers over- Autohotkey

If the cursor is of the IBeam type and the F20 key is pressed and dragged, the text is selected with the shortcut Ctrl + Shift + right (or in the direction to which it is moved) .
Is there any way of doing this? https://imgur.com/a/Rqrfwjk
I have this code but it is based on the number of pixels moved and not on whether the cursor is over a word
#If WinActive("ahk_exe chrome.exe") && A_Cursor = "IBeam"
~LButton::
Click
MouseGetPos, x1
SetTimer, Check, 100
SoundBeep, 1500
KeyWait, LButton
SetTimer, Check, Off
SoundBeep, 1000
Return
#If
Check:
MouseGetPos, x2
f := Floor(Abs((x2 - x1) / 110))
Switch
{
Case x2 > x1: Send ^+{Right %f%}
Case x2 < x1: Send % "{Right}^+{Left " f + 1 "}"
}
Return

Caesar's cypher encryption algorithm

Caesar's cypher is the simplest encryption algorithm. It adds a fixed value to the ASCII (unicode) value of each character of a text. In other words, it shifts the characters. Decrypting a text is simply shifting it back by the same amount, that is, it substract the same value from the characters.
My task is to write a function that:
accepts two arguments: the first is the character vector to be encrypted, and the second is the shift amount.
returns one output, which is the encrypted text.
needs to work with all the visible ASCII characters from space to ~ (ASCII codes of 32 through 126). If the shifted code goes outside of this range, it should wrap around. For example, if we shift ~ by 1, the result should be space. If we shift space by -1, the result should be ~.
This is my MATLAB code:
function [coded] = caesar(input_text, shift)
x = double(input_text); %converts char symbols to double format
for ii = 1:length(x) %go through each element
if (x(ii) + shift > 126) & (mod(x(ii) + shift, 127) < 32)
x(ii) = mod(x(ii) + shift, 127) + 32; %if the symbol + shift > 126, I make it 32
elseif (x(ii) + shift > 126) & (mod(x(ii) + shift, 127) >= 32)
x(ii) = mod(x(ii) + shift, 127);
elseif (x(ii) + shift < 32) & (126 + (x(ii) + shift - 32 + 1) >= 32)
x(ii) = 126 + (x(ii) + shift - 32 + 1);
elseif (x(ii) + shift < 32) & (126 + (x(ii) + shift - 32 + 1) < 32)
x(ii) = abs(x(ii) - 32 + shift - 32);
else x(ii) = x(ii) + shift;
end
end
coded = char(x); % converts double format back to char
end
I can't seem to make the wrapping conversions correctly (e.g. from 31 to 126, 30 to 125, 127 to 32, and so on). How should I change my code to do that?
Before you even start coding something like this, you should have a firm grasp of how to approach the problem.
The main obstacle you encountered is how to apply the modulus operation to your data, seeing how mod "wraps" inputs to the range of [0 modPeriod-1], while your own data is in the range [32 126]. To make mod useful in this case we perform an intermediate step of shifting of the input to the range that mod "likes", i.e. from some [minVal maxVal] to [0 modPeriod-1].
So we need to find two things: the size of the required shift, and the size of the period of the mod. The first one is easy, since this is just -minVal, which is the negative of the ASCII value of the first character, which is space (written as ' ' in MATLAB). As for the period of the mod, this is just the size of your "alphabet", which happens to be "1 larger than the maximum value, after shifting", or in other words - maxVal-minVal+1. Essentially, what we're doing is the following
input -> shift to 0-based ("mod") domain -> apply mod() -> shift back -> output
Now take a look how this can be written using MATLAB's vectorized notation:
function [coded] = caesar(input_text, shift)
FIRST_PRINTABLE = ' ';
LAST_PRINTABLE = '~';
N_PRINTABLE_CHARS = LAST_PRINTABLE - FIRST_PRINTABLE + 1;
coded = char(mod(input_text - FIRST_PRINTABLE + shift, N_PRINTABLE_CHARS) + FIRST_PRINTABLE);
Here are some tests:
>> caesar('blabla', 1)
ans =
'cmbcmb'
>> caesar('cmbcmb', -1)
ans =
'blabla'
>> caesar('blabla', 1000)
ans =
'5?45?4'
>> caesar('5?45?4', -1000)
ans =
'blabla'
We can solve it using the idea of periodic functions :
periodic function repeats itself every cycle and every cycle is equal to 2π ...
like periodic functions ,we have a function that repeats itself every 95 values
the cycle = 126-32+1 ;
we add one because the '32' is also in the cycle ...
So if the value of the character exceeds '126' we subtract 95 ,
i.e. if the value =127(bigger than 126) then it is equivalent to
127-95=32 .
&if the value is less than 32 we subtract 95.
i.e. if the value= 31 (less than 32) then it is equivalent to 31+95
=126..
Now we will translate that into codes :
function out= caesar(string,shift)
value=string+shift;
for i=1:length(value)
while value(i)<32
value(i)=value(i)+95;
end
while value(i)>126
value(i)=value(i)-95;
end
end
out=char(value);
First i converted the output(shift+ text_input) to char.
function coded= caesar(text_input,shift)
coded=char(text_input+shift);
for i=1:length(coded)
while coded(i)<32
coded(i)=coded(i)+95;
end
while coded(i)>126
coded(i)=coded(i)-95;
end
end
Here Is one short code:
function coded = caesar(v,n)
C = 32:126;
v = double(v);
for i = 1:length(v)
x = find(C==v(i));
C = circshift(C,-n);
v(i) = C(x);
C = 32:126;
end
coded = char(v);
end

VBA permutations of undetermined number of variables

Recently I am trying to get the permutation of undetermined number of variables. For undetermined I mean I was aiming to create an input box for users to put in the number.
Start from simple. Originally I was aiming to get a 4 digits permutations with each digit have different number of variables, i.e. 1st digit can only be A,B,C,D; 2nd digit be E,F; 3rd digit be G, H etc. Code are below:
Sub Permut()
Count = 1
For a = 1 To 4
For b = 1 To 2
For c = 1 To 2
For d = 1 To 2
For e = 1 To 2
'chr(97) is the alphabet "a"
Cells(Count, 1) = Chr(96 + a) & Chr(96 + Len(a) + b) & Chr(96 + Len(a) + Len(b) + c) & _
Chr(96 + Len(a) + Len(b) + Len(c) + d) & Chr(96 + Len(a) + Len(b) + Len(c) + Len(d) + e)
Count = Count + 1
Next
Next
Next
Next
Next
End Sub
This will give you 64 different combinations without repetition.
Just wondering is there a way to generalize this process so that people can choose how many variables in total as well as within each digit?
Thank you.
Here is a solution, where you would pass the Permut function the minimum value for each of the characters (digits) as one string, and the maximum characters also as a string. Both strings should have an equal number of characters of course:
Function Permut(min, max)
Dim str, nxt, count
str = min
count = 1
Do While str < max
Cells(count, 1) = str
count = count + 1
nxt = ""
For i = Len(str) To 1 Step -1
If Mid(str, i, 1) < Mid(max, i, 1) Then
nxt = ChrW(AscW(Mid(str, i, 1))+1) & nxt
Exit For
End If
nxt = Mid(min, i, 1) & nxt
Next
str = Left(str, Len(str) - Len(nxt)) & nxt
Loop
Cells(count, 1) = str
End Sub
You would call it like this:
Permut "abc", "bcf"
That example would produce this list on your sheet:
abc
abd
abe
abf
acc
acd
ace
acf
bbc
bbd
bbe
bbf
bcc
bcd
bce
bcf
How to Execute This with User Input and Button Click
If you want to call this code in response to an event, such as a button click, and want to pass it the contents of two cells where the user would first enter the min and max strings, then follow these steps:
Place an ActiveX command button on your sheet (put it somewhere in D1 to leave room for some other stuff)
Double click it to generate the empty click event handler. If that does not work, go to the code window and select the name of the button from the drop-down at the top of the window, and select Click from the next drop down.
Complete the code of that event handler as follows (I assume the button is called CommandButton1, but don't change the generated name):
Code:
Private Sub CommandButton1_Click()
Permut Range("B1"), Range("C1")
End Sub
This code assumes the user has to enter the min and max digits/characters in cells B1 and C1. The A column is of course reserved for the output of the code.
For a more complete explanation on how to add a command button and attach code to its click event, read "Add a command button (ActiveX control)" in the Office manual.
credit to the answer from trincot above.
I have tried to run the code with a bit modification coz I am not sure how to get set value into cells (0,1). It keeps saying error. But If I change the starting point to Cells(1,1) then I will miss the last permutation. So I just add an additional if statement to get the code work as I want.
Function Permut(min, max)
Dim str, nxt, count
str = min
count = 1
Do While str < max
Cells(count, 1) = str
count = count + 1
nxt = ""
For i = Len(str) To 1 Step -1
If Mid(str, i, 1) < Mid(max, i, 1) Then
'asc("a")=97; chr(97) ="a"
nxt = Chr(AscW(Mid(str, i, 1)) + 1) & nxt
Exit For
End If
nxt = Mid(min, i, 1) & nxt
Next
str = Left(str, Len(str) - Len(nxt)) & nxt
If str = max Then
Cells(count, 1) = str
End If
Loop
End Function

Why must I push IBAction Button twice for action to occur?

I'm making an app that does a calculation when the IBAction button is pressed. It works fine, but I have to press it twice for the Action to occur. Anyone have experience with this? Below is some code from the #IBAction button in question:
#IBAction func CalculateGPA(sender: AnyObject) {
gpa = (gp + gp2 + gp3
+ gp4 + gp5 + gp6
+ gp7) / (ch + ch2
+ ch3 + ch4 + ch5
+ ch6 + ch7)
gpaLabel.text = NSString(format: " Your GPA is %.2f", gpa) as String
//added if textField == ">9" after first submission
if textField1.text == "10"{
gpaLabel.text = "Enter 1-9 Credit Hours"
}
if textField2.text == "10"{
gpaLabel.text = "Enter 1-9 Credit Hours"
}
And for your info, this Button makes a calculation and changes the input of a label. My guess why I have to press it twice is that the first press does the calculation, the second press changes the label to show the result.
First of all, the formula that you are using to calculate GPA is incorrect. You should not add up total grades and divide by total credit hours as it appears that you are doing. You have to multiply each grade by the the number of credit hours, add that up, then divide by total credit hours:
gpa = (gp * ch + gp2 * ch2 + gp3 * ch3 + gp4 * ch4 +
gp5 * ch5 + gp6 * ch6 + gp7 * ch7) /
(ch + ch2 + ch3 + ch4 + ch5 + ch6 + ch7)
Also, you might want to use an array in a for loop so that if the number of classes changes you can process any number of classes. Imagine if you had 100 classes, putting all this in a giant statement would be silly and time-consuming:
gpa = (gp * ch + gp2 * ch2 + gp3 * ch3 + gp4 * ch4 +
gp5 * ch5 + gp6 * ch6 + gp7 * ch7 ... gp100 * ch100) /
(ch + ch2 + ch3 + ch4 + ch5 + ch6 + ch7 + ... ch100)
Instead say:
var numerator: Int = 0
var totalCh : Int = 0
var gpa : Double = 0.0
// gp and ch should be arrays that are instance variables;
// they should already be filled in either in this function or
// from another location
for (var i: Int = 0; i < gp.count; i++) {
numerator += gp [i] * ch [i]
totalCh += ch [i]
}
if (totalCh > 0) {
gpa = Double (numerator) / Double (totalCh)
} else {
gpa = 0.0 // can't divide by 0. Might want an error message to user here
}
// ...
Also, you should do your validation of user input at the top of your function instead of after you have done the calculation. If the user made an error, you should give some feedback to the user on what he did wrong and how to fix it (as you have done), but do not do the calculation at all until all validations are good.
To answer your original question, we need to see all the code for that function. If textfield1 and textfield2 are filled elsewhere, it would help to see where they fit in.
It is possible that you don't have the IBAction hooked up correctly to your button. Go into the Connections Inspector and click on the button in your StoryBoard, and make a screenprint of what you see and post it here so that we can check to see if you did the connections correctly.
However, since you have to press the button twice to see any results, there is a higher probability that you failed to initialize something, so it had a value of zero or null the first time you pressed the button, but then it got initialized by the end of the function, so when you pressed the button again, it did the calculation and entered an answer into the label.
To see exactly what is going on, you should try stepping through the debugger. If you don't have any experience with that, you could put a bunch of print statements at key locations in your IBAction function to see what is being calculated and to see what statements are executing and to make sure that the function got started at all; at least enter one at the beginning of the function that says "entering IBAction calculateGPA".

Resources