AHK Remove every second char from variable - string

I need a code on AHK
I have a variable look like this:
CYOMYACHOAYJGUGRYYQNYB
I need to get this:
YMAHAJURYNB
I meen, i need every second char from a variable. Thank in advance

Var := "CYOMYACHOAYJGUGRYYQNYB"
Loop, Parse, Var ; retrieves each character from the variable, one at a time
{
If (Mod(A_Index, 2) = 0) ; If A_Index is even (the remainder after division by 2 is 0)
NewVar .= A_LoopField ; add the retrieved character to the new variable
}
MsgBox %NewVar%

This works for me. I am using bit wise to determine if the index of the array of letters, given to me by StrSplit(TestString), is even or odd as I loop through them. I used this forum post for the bitwise logic. Then I concatenate if the line is even. So if index&1=0 will be true when the number is even, thus giving me every other letter to concatenate into NewString with this line NewString=%NewString%%letter%. Feel free to uncomment out the message box lines by removing the ; to better see how the loop parses the array.
TestString := "ABCD"
word_array := StrSplit(TestString)
NewString:=""
For index, letter in word_array{
if index&1=0
{
;MsgBox, %letter% added
NewString=%NewString%%letter%
;Msgbox, %NewString%
}
}
MsgBox, %NewString%

As you don't specify any language, I'll answer in pseudocode:
set counter to 1
set result to empty string
for every char in string:
if counter is even:
append char to result
increment counter by 1

user3419297 beat me to it, but mine is even easier:
InputBox, x, What Variable?, Enter Variable:
loop, % StrLen(x)
If mod(A_Index,2)=0
y.=substr(x,A_Index,1)
msgbox %y%
Clipboard := y
You input the variable in a dialog, and the result is shown, and put in clipboard. Hth,
EDIT: I like the bitwise logic from Zack Tarr! Substitute for the "if" above:
If A_Index&1=0
The rest is the same.

Related

Is there a way to get increment counter from a Python 'for' loop with decrement range?

I read everyone uses enumerate, but I don't think I know how to use it in my code. I want to print the value of an alphabet in a string according to alphabet order and the next character will increment the value by 1 and I want to start it from the last character in the string.
I can solve the code, but how can I replace the counter i without using i = i+1 to make this code a bit shorter? Is there a way to implement something in the for loop?
This is my code:
def project(r):
i = 0
for char in range(len(r),0,-1):
print(ord(r[char-1])-96+i)
i=i+1
project(str(input()).lower())
For example, if I insert a string such as "sad", the output will be [4,2,21] because d = 4, a = 1, s = 19.
Is there a way to implement the counter without initializing i?
According to your question what I can understand is you want to use enumerate to get your result.
You can simply do as below:
def project(r):
for (i, char) in enumerate(r, 0):
print(ord(r[-i-1])-96+i)
project(str(input()).lower())
And the enumerate() method adds a counter to an iterable and returns it in a form of an enumerate object.
Syntax: enumerate(iterable, start)
Here 0 is the default value of start which you can give according to your requirement. For example, if you want your counter to start from 100, then you can do like enumerate(iterable, 100).
In the above code, I have used enumerate() function and initialized the counter from 0 and as you want to display from the last, I used -ve index to get the last item in a list.
And as I initialized the counter 0 so how can I get the items from last? For that, I subtract the index by -1 like r[-i-1]. So for the first iteration the i value becomes 0, so r[-i-1] becomes r[-0-1] which is r[-1] and on the second iteration, i becomes 1, so r[-i-1] becomes r[-1-1]which isr[-2]` which result second last item. Similarly it goes on.
For more information about enumeration, please check the below link so you can get a clear idea.
Python enumerate()
13. Enumerate
Dcoder14, actually I want to make my code a bit shorter. Even there is a way other than enumerate, but still thank you very much... I used your code, but I edited it a little bit to make it one line shorter...
This is my code:
def project(r):
for (i, char) in enumerate(r, 0):
print(str(ord(r[-i-1])-96+i))
project(str(input()).lower())
If you want to make it shorter, you can use the decrement char value since we can get an increment by subtracting the length of the string (input) with char in the for loop.
For example, this is my code:
def project(r):
for char in range(len(r),0,-1):
print(ord(r[char-1])-96+(len(r)-char))
project(str(input()).lower())

Split string in Lua and print selected keys

I'm looking for a little help with splitting a string using Lua and printing selected parts of it. I have this code so far:
b = "an example string"
for i in string.gmatch(b, "%w+") do
print(i)
end
Output is...
an
example
string
How do I go about printing only bits of the result?
I've tried the following but just returns a list of "nils":
b = "an example string"
for i in string.gmatch(b, "%w+") do
print(i[1])
end
So if I wanted to print:
string
example
How would this work? I was pretty sure I just added the value assigned to the key that is in memory, like [0] or [1]. But I must be wrong..
In this use case the sample text will remain the same, only time stamps will change in the string. I just need to reorder the words.
Any help is greatly appreciated :)
The best way I can find is to use the loop to store the matches in an array. Then you can access them with literal indexes:
b = "an example string"
local words = {}
for i in string.gmatch(b, "%w+") do
table.insert(words, i)
end
print(words[3])
print(words[2])
In addition to the existing (probably perferable) answer, you could also do some manual work with a counter:
counter = 0
for i in string.gmatch(b, "%w+") do
counter = counter + 1
if counter > 1 then print(i) end
end
Or, here's a one-liner (that wouldn't scale with larger strings though and also doesn't insert a newline between second and third word):
print(string.match(b, "%w+%s+(%w+)%s+(%w+)"))

Exercice with type String in Pascal

(Translated from German to Englisch)
I need help in this exercise :
Thread: String processing The user can make simple changes to an input sentence.
conditions
The program displays a menu for the user to select the following action. This is also displayed again after the action has been completed until the user terminates the program (a loop is therefore required).
The menu contains the following items, which should be executed when the specified letter is entered:
A. Enter the sentence
B. Determine the number of words
C. Determine the number of characters that are less than their sequence character
D. Replace all the words in the sentence with their uppercase initials
X. end
If the user enters a different letter, nothing happens or the menu is output again.
If the menu item A is selected, a prompt is issued to enter a set which is read into a string variable. This variable can not be changed by the actions of menu items B, C and D! Possibly. A copy of the set has to be prepared beforehand in another string variable.
In menu point B the number of all words in the block is to be counted. For simplicity, you can assume that there is always one space between two words. At the beginning and end of the sentence there are no spaces. The number of words is output after the calculation (e.g., "The set is 4 words").
If the user executes menu item C, the set is traversed character-by-character, and for each character it is checked whether it is smaller than its trailing character. Here is a simple character comparison (you can also write directly something like '1' <'d'). The number of characters so found is then output (e.g., "13 characters found in the sentence less than the trailing character").
In menu item D, the sentence is traversed and every word contained in it is replaced by its upper-case initial character. The capitalization is of course only made if the first character is a letter, otherwise the character remains unchanged. You can assume that the sentence never starts or ends with a space. Between two words there is always exactly one space and so it should be between the initial letters. For example, from "123 good mood" becomes "1 G L".
It is not permissible here to build up a completely new string piece by piece! Instead, you should work in a loop on a copy of the original sentence with pos, copy, length, delete and insert! It is also forbidden to "gather" the initial characters all at the beginning or end of the string; These should be inserted directly into the string at the position of the corresponding word!
Furthermore, a string can not be accessed at menu point D, because the work with string routines is to be practised explicitly here. Menu items B, C and D may only be selectable if a record has already been entered. Otherwise nothing happens or a fault message is entered when entering B, C or D in the menu and the menu is output again.
Each call to the menu items B, C or D will always work on the original set entered by the user and not on a set that has already been altered by previously executed menu items!
By entering the menu item A again, the entered block can be overwritten by a new one.
With an 'X' the user can terminate the program.
Use wherever it is the predefined string functions and do not write it yourself with difficulty loops, etc.! However, the use of the strreplace or reverseString functions is forbidden!
Here's my work till now, I only have problems with part D:
program Project2;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
const
lz = ' ';
var
Satz: string;
Buchstabe: char;
i, p, j, zaehler2, index, count: integer;
writeln('A) Write Sentence');
readln(Satz);
'D':
begin
index := 2;
insert(lz, Satz, length(Satz)+1);
count := (pos(lz,Satz));
repeat
delete(Satz, index,(count - index));
index := index + 2;
count := pos(lz,copy(Satz,index,(length(Satz)-index)))+index-1;
until ;
writeln(uppercase(Satz));
end
I'm glad you've found your own solution, well done!
While you've been doing that, I've been writing the answer below and, as I
have finished it, I thought I'd post it here to show you another way
to go about the problem of extracting words from a string. There are
dozens of ways of doing that task, but I hope the one I've used is fairly
easy to follow.
Maybe the reason you were having a problem with this is that your string-indexing
expressions are a bit too complicated. I bet if you come back to your code in 6 months
it will take you a while to figure out what it is supposed to be doing and longer
to tell whether it is actually doing it. The key to avoiding problems like that
is to break your code up into chucks which are easier to follow and easier
to test. So instead of just telling you what your repeat condition should be,
I'll show you a way which is easier to follow.
The first thing to do is to extract a singe word from the input. So, first thing
I've written is a function, ExtractFirstWord which returns the first word in
the input string, whether or not the input includes spaces, and also returns
a Remainder string which is what is left or the input string after the first
word (and any spaces immediately following it have been removed). This is done
using some simple while loops which are coded to skip over the leading spaces
and then build a string from the non-space characters which follow.
Code
const
lz = ' ';
var
Satz: string;
FirstWord : String;
Remainder : String;
function ExtractFirstWord(const InputStr : String; var Remainder : String) : String;
var
P : Integer;
WordStart : Integer;
begin
Result := '';
P := 1;
// The following skips over any spaces at the start of InputStr
while (P <= Length(InputStr)) and (InputStr[P] = lz) do
Inc(P);
// Now we know where the first word starts
WordStart := P;
// Now we can get the first word, if there is one
while (P <= Length(InputStr)) and (InputStr[P] <> lz) do
Inc(P);
Result := Copy(InputStr, WordStart, P - WordStart);
Remainder := Copy(InputStr, P, Length(InputStr));
// the following is one way to remove spaces at the start of Remainder
while (Length(Remainder) > 0) and (Remainder[1] = lz) do
Delete(Remainder, 1, Length(lz));
// instead you could do something simlar to the first `while` loop above
end;
begin
Satz := ' cat dog ';
repeat
FirstWord := ExtractFirstWord(Satz, Remainder);
FirstWord := UpperCase(FirstWord);
Satz := Remainder;
writeln('First word: ', FirstWord, ' remainder: ', Remainder);
until Remainder = '';
readln;
end.
This particular way of doing it is not an ideal fit with the other requirements
specified in your task but should be easily adaptable to them. E.g, the upper-casing of words could be done "in place" on the input string by upper-casing the current character of it in the second While loop.
Btw, if you are using Delphi or Free Pascal/Lazarus, there is a much simpler
way of extracting the words from a string. It uses a TStringList. Try
looking it up in the online help and have a thing about how you might use it
to do the task.

AHK: Remove Text From String This Word To The First Line Break

I work at a doctors office doing billing, and I've run into a problem. Because of an issue with the way the EMR (electronic medical record) program works, immunization codes don't always make it into the chart. In order to compensate for this, I have AHK also search for the name of the immunization (dangerous, I know). Just until recently, this was working fine, until one of the doctors canceled an order for an immunization. This threw a false positive because of the failsafe I included for the charts without the code (IMM94, and IMM97). I need to remove, from a very large string, everything after the word "CANCELED: " to the first line break that occurs after that word. I created a rather pretty string clipping function to do most of this kind of stuff, but it's taking issue with finding the line break because there are so many. The test case I'm working with is:
Assessment and Plan:
Need for prophylactic vaccination and inoculation against influenza (tab) CANCELED: Influenza, High Dose (65+) (newline)
Prediabetes Work on weight loss and exercise
Osteopenia Exercise and vit d and b 12
There's a lot of stuff both above this, and below this, but I want to extract ALL instances from my string of the word "CANCELED: " to the first line break after it.
This is what I'm trying, along with my function. It's not working, and in fact, it's duplicating the line beginning with "1. ":
^L::
lString := ClipBoard
If lString Contains Canceled
fString := ClipString(lString, "CANCELED: ", "`n")
Clipboard := fString
Return
ClipString(lString, aMarker, bMarker, Only := 0)
{
If (Only = 1)
Return SubStr(SubStr(lString, 1, InStr(lString, bMarker)+StrLen(bMarker)-1), InStr(lString, aMarker))
Else
Return SubStr(lString, 1, InStr(lString, aMarker)-StrLen(aMarker)) . SubStr(lString, InStr(lString, bMarker)+StrLen(bMarker))
}
Strips "cancelled:" and any text following it from each line in clipboard
Program:
Clipboard := RegExReplace(Clipboard, "im)\s*CANCELLED:.*\R?", "`r`n")
Sample Input:
alpha
beta cancelled: ABC asldkfalsd
delta
gamma omega CANCELLed: zeta
theta
Sample Output:
alpha
beta
delta
gamma omega
theta
Got it figured out. I'll comment it to help anyone who has this issue. I love how compact you can get functions usually, but this piece really needed a couple more lines than I'd like. If anyone can get it down to less, and have it still work, let me know!
^L::
ClipBoard := ClipString(ClipBoard, "Canceled: ", "`n",2) ;This is the function call here.
;The first parameter is the string to do stuff to, the second is what to cut out of the
;string, and the third parameter is how far after that piece to cut, so if you wrote
;Canceled: thenawholebunchofstuffthena newline, it'd remove all of it except for the
;newline. The third parameter is which mode to put ClipString to.
Return
ClipString(lString, aMarker, bMarker, Mode := 0) ;already explained above.
;Mode defaults to zero because I call the zero mode a lot.
{
If (Mode = 0) ;Mode Zero returns the ONLY the section from the original string
;between aMarker and bMarker.
Return SubStr(lString, 1, InStr(lString, aMarker)-StrLen(aMarker)) . SubStr(lString, InStr(lString, bMarker)+StrLen(bMarker))
Else If (Mode = 1) ;Mode One returns the original string with the section between aMarker
;and bMarker removed.
Return SubStr(SubStr(lString, 1, InStr(lString, bMarker)+StrLen(bMarker)-1), InStr(lString, aMarker))
Else If (Mode = 2) ;Mode Two returns the original string with all instances of aMarker
;to bMarker removed. I.E. Every occurrence of aMarker will be removed to bMarker.
{
aString := lString
StringReplace, aString, aString, %aMarker%, %aMarker%, UseErrorLevel ;Count how many
;instances of aMarker are in the original string.
CanCnt := Errorlevel ;actual count of # of aMarkers
Loop, %CanCnt% ;loop as many times as there are aMarkers
{
aString := SubStr(aString, 1, InStr(aString, aMarker)-1) . SubStr(SubStr(aString, InStr(aString, aMarker)), InStr(SubStr(aString, InStr(aString, aMarker)), bMarker)-1)
;this is a tad complicated. The first part before the concatenate takes the string, and
;keeps from the start point to the first aMarker. The concatenate adds the substring of the
;substring between aMarker and the end of the string, and the location of the substring in
;aString from the occurrence of aMarker to one position before the start of bMarker.
;An easier way to read this would be to replace "SubStr(aString, InStr(aString, aMarker))
;with a variable like bString. It shortens it up quite a bit.
}
Return aString
}
}

Finding consecutive characters in an array

I have a boolean function that evaluates a 1d array of characters. It has two parameters: a 1d array of characters , and a char c. I want the function to return true if the given char c appears at least four consecutive times within the given array, otherwise it will return false.
I don't know how to start or complete this function at all. Please help! Thanks.
I hope I'm not doing you're homework for you ;). So here's the sudo-code for this problem to help you get started
The first thing you would want is the method header that returns a boolean, and has a parameter for an array of characters and a char
The next step would be to create a counter and run a loop to sift threw every character in the array. Every time you encounter that specific character in the array you would add one to the counter, if the next character isn't the one you want then you would reset the counter to 0. Then add a conditional in the loop to check if the counter reaches 4, if so you would return true. If it never reaches 4 then you would want to return false. Go ahead and try to code that up and see if you get it.
Simple problem. If this is your homework then you shouldn't be doing this. Your question needs to be changed. Firstly give it a try before asking and then once you are done trying you can post the errors or the snippets of codes that you are unsure of and then ask for help. Else you are not going to learn anything. Got a simple solution to your problems. I'm not going to give you the complete solution but instead a guide to help you with your question.
In my opinion string is always a better choice to use instead of char because of the functions that come with that package. Char is just plain old annoying (again in my opinion) unless your question or whatever you are doing this program for requires you to use char.
First,
Create your main program -> create your array and initialize it if you want or you can prompt the user for their input. whichever works.
use the "bool" data type to create your Boolean variable.
Prompt the user to input the char value to check for.
Now call the function and provide the parameters. I'm guessing the function is where you are stuck with so i'm going to provide you the snippets from the code that i wrote for this question.
bool check(char* <array_name>, char* <array_name>) //for the array list and the
//value to check for
{
int size;
size = strlen(<array_name>); //to get the size of the array (array list)
int counter=0; //to keep count of the occurrence of the char to check
for(int x=0; x<size; x++) //ar = array list and token = char to check
{
if(ar[x]==token[0]) //check for each iteration if token is in ar[x]
counter++; //if it is then counter increases by 1
else
counter = 0; //To reset the value to 0 if its not consecutive.
if(counter == 4) //to stop the loop when 4 consecutive values has been found.
break;
}
if(counter >= 4) //as per your requirement 4 or above
return true;
else
return false;
}
EDIT: This is to check the values just until 4 consecutive values of what you are searching for is found and to end the loop. If you want it in a different way then please feel free to comment on this answer. You can always add another counter or anything at all to check how many consecutive times the value is found. For example 1,1,1,1,2,3,4,1,1,1,1,2,3,4,1,1,1,1,2,3,4.
The counter for that will be 3 since it happens 3 times with each time repeating the same value for 4 times consecutively.
If this is your homework then you better study properly because it's a really simple problem and your shouldn't be asking for a solution but instead ask for guidance and try first.
Good luck! If you need further clarification or help just comment on this.

Resources