I have a set of data like this:
I love
Hong Kong
I love Hong Kong and Japan.
and Japan.
test.
just a
This is just a test.
I would like to keep the longest ones while removing those partially matched with them. the desired result:
I love Hong Kong and Japan.
This is just a test.
but the actual result is
I love
I love Hong Kong and Japan.
This is just a test.
Here are my code in AHK:
FileEncoding, UTF-8
FileSelectFile, FileName
FileRead, Var, %FileName%
lines_master := StrSplit(Var, "`r`n")
l :=lines_master.MaxIndex()
lines_temp :=[]
Remaining_List =
count_match = 0
While l > 1
{
for i, element in lines_master
{
if (i == 1)
{
master :=element
}
Else
{
if !InStr(master, element)
{
lines_temp.Insert(element)
count_match := count_match + 1
}
}
}
x := l - 1
if (count_match == x)
{
lines_temp.Insert(master)
}
else
{
Remaining_List .=master . "`r`n"
}
count_match = 0
lines_master :=lines_temp
lines_temp :=[]
l :=lines_master.MaxIndex()
}
FileAppend, %Remaining_List%, F:\result.txt, UTF-8
Exit
if I sort the list by length in words, it works. However, I would like to know how to refine the code and make it work no matter what order the list of strings is in.
thank you.
Related
i wanna click a random button 50 times from a list unless it is 1 only click it once, its always going to the else even if key is 1
!F2::
breakvar = 1
return
!F1::
loop
{
Random, var, 1,7
keyList = {1},{2},{3},{w},{a},{s},{d}
StringSplit, KeyAry, KeyList, `,,%A_Space%
key := KeyAry%var%
loop 50
{
; i've tryied:
;(%key% = "1")
;(key = 1)
;(key = {1})
; but with out success
if (key = "1")
{
Send, %key%
break
}
else
{
Send, %key%
Sleep, 100
}
}
if breakvar = 1
break
}
breakvar = 0
return
also is there a better way to achieve what i am trying to do?
thx
Your main mistake was that you indeed didn't manage to get the if statement corrent. The right one would've been if (key = "{1}").
But really, I don't know why you even had the { }, it's a common mistake I see from nearly every beginner, I wonder where it comes from.
You're only supposed to use { } for escaping or if the special notation is needed for something such as {space}. Read more from the documentation.
Here's a cleaned up script with all other weirdness removed as well:
KeyList := StrSplit("1,2,3,{space},+1,w,🐈", ",") ; +1 is shift + 1 (whatever key that will produce in your keyboard layout)
!F2::BreakVar := true
!F1::
loop
{
Random, index, 1, 7
key := KeyList[index]
loop 2
{
SendInput, % key
if (key = "1")
break
Sleep, 100
}
if (BreakVar)
break
}
BreakVar := false
return
To be totally correct, I should say that you shouldn't loop under hotkeys and should use a timer instead, but I wont add that in to confuse you. This should be fine as well, if you have problems with hotkeys after this, you can look into a timer approach yourself or ask help here.
I am trying to determine if all the files/folders present in a directory have a ascending order numbering pattern at same place throughout in their name
If the numbers were always present at a constant place in every case , this would have been super easy
ls $HOME/dir
1. Some String
2. Some String- Part 4
3. Some String- Part 5
Here i would just simply use something like
ls $HOME/dir | sort -V | grep -Eo '^[0-9]'
The command will output 1 2 3 and The files/folders have ascending order numbering pattern is a easy conclusion
Now there are 2 problems here :
Its not necessary that these numbers would always be at start like above
There could be sometimes random numbers in between
==========================================
ls $HOME/dir
Lecture 1 - Some String
Lecture 2 - Some String - Part 4
Lecture 3 - Some String - Part 5
Expected Output - 1 2 3
I main thing is that i need grep to only output numbers if they are present in ascending order at the very same position in filenames throughout
==========================================
ls $HOME/dir
1. Some String
Some String - Part 2
Some String - Part 3
For something like this , grep shouldn't output anything at all because even though it has ascending numbers in name, they are not present at same place throughout
==========================================
PS / The 'Some String' part in all my example would be different for each file/folders. Only the position of the ascending numbers being constant (If any ) is to be considered
One More final example
ls $HOME/dir
CB) Lecture 1 xyz
CB) Lecture 2 abc-part 8
CB) Lecture 3 pqr-part 9
Expected Output - 1 2 3
Here is one solution using AWK:
printnumbers.awk
BEGIN {
numberRegex = "[0-9]+([^A-Za-z0-9]|$)"
}
NR == 1 {
numberPos = match($0, numberRegex)
}
match($0, numberRegex) == numberPos {
matchedString = substr($0, RSTART, RLENGTH)
match(matchedString, "[0-9]+")
result = result substr(matchedString, RSTART, RLENGTH) "\n"
next
}
{
result = ""
exit 1
}
END {
printf("%s", result)
}
Then run
$ ls $HOME/dir | sort -V | awk -f printnumbers.awk
Edit 2021-05-14
A second approach is to split each line into fields with non-digits as separators. Then each field is either a number or an empty string. For each line we check the fields to see if a sequence of consecutive numbers starting from one is formed.
Here is the logic:
BEGIN {
FS = "[^0-9]+"
}
{
for (i = 1; i <= NF; i++) {
numbersConsecutive[i] = ($i == NR) && ((NR == 1) || numbersConsecutive[i])
}
if (NF > numbersConsecutiveLen) {
numbersConsecutiveLen = NF
}
}
END {
consecutiveNumbersFound = 0
for (i = 1; i <= numbersConsecutiveLen; i++) {
if (numbersConsecutive[i]) {
consecutiveNumbersFound = 1
}
}
if (consecutiveNumbersFound) {
for (i = 1; i <= NR; i++) {
print i
}
}
}
I am reading a file that contain 277272 lines with Int triples (s,p,o) like:
2,126088,113358
2,126101,126102
2,126106,126107
2,126111,126112
2,126128,126129
2,126136,126137
2,126141,126142
2,126146,126147
4,1,3
4,7,8
4,15,16
4,26,27
4,41,94825
4,63,15764
4,68,69
4,89,94836
4,90,91
4,93,94
4,105,94844
this triples are order by s and then by p. I write the following code that search a value by s, and once find the value I write a conditional to filter by p.
def SP_O (yi:Int, zi:Int):List[Vector[Int]]={
val file = new RandomAccessFile("patSPO.dat", "r")
var lengthfile = (file.length().asInstanceOf[Int])
var initpointer = lengthfile/2
while (band == true){
var p = bs.firstvalue(initpointer,"patSPO.dat") // p es la lista del valor del predicado con su respectivo puntero
var newpointer = p(0)
var subj = p(1)
//Comienzo el analisis para saber si el predicado es igual al del BGP
if (subj == yi){
// Hay que imprimir los valores de la presente linea
if (firsttime == true){
val fields = bs.getvalueSP_O(newpointer,zi)
if (fields.size != 0){
S_POlistbuffer += fields
//yld(Record(fields, schema))
}
firsttime = false
pointerad = newpointer
pointerat = newpointer
} // Ahora tengo que analizar si hay valores atras o adelante
while (boolad == true || boolat == true){
if (boolat == true) {
//Valores para atras
pointerat -= 6
if (pointerat <= 0) {
pointerat = 0
boolat = false
}
p = bs.firstvalue(pointerat, "patSPO.dat") // p ds la lista del valor del sujeto en pointerat y da su respectivo pointer
if (p(1) == yi) {
val fields = bs.getvalueSP_O(p(0),zi)
if (fields.size != 0){
S_POlistbuffer += fields
//yld(Record(fields, schema))
}
} else {
boolat = false
}
}
if (boolad == true){ //valores par adelante
p = bs.nextvalue(pointerad,"patSPO.dat")
if (p(1)==yi){
val fields = bs.getvalueSP_O(p(0),zi)
pointerad = p(0)
if (fields.size != 0){
S_POlistbuffer += fields
//yld(Record(fields, schema))
}
}else{
boolad = false
}
}
if (boolad == false && boolat == false){
band = false
}
}
}
else if ( subj > yi ){
initpointer = initpointer/2
}
else if ( subj < yi) {
initpointer = (initpointer*6)/4
}
}
val listf:List[Vector[Int]] = S_POlistbuffer.toList
listf
}
The general idea is that the code start looking the value from the half of the file, with the filerandomaccess, then I should extract the first value of the line, and compare with the value that I need, once I find the correct value I must analyze if the next line also has the correct value, in paralell I analyze the line before to the line that I choose in order to see if that line also is a correct value. For each line that match I analyze if the second value is the correct. If the line match I extract the o value, and I store it in a List.
The problem is when I am printing the result, this take so much time. However I developed this another solution that runs over the whole file:
while (in.hasNext) {
val s = in.next(',').toInt
val p = in.next(',').toInt
val o = in.next('\n').toInt
//val fields = schema map (n => in.next(if (n == schema.last) '\n' else ','))
if (p == yi && s == xi){
val fields = schema map (n => o)
yld(Record(fields, schema))
}
}
With this code I run over the whole file and I get the results faster than the first code. My big question is why if the first code in the best of the cases just run a portion of the file is to slow than the second code that run over the whole file? Is there another way to write this code with a better performance?
The time of the first code execution is like 750 seconds, the second code takes like 10 seconds.
There's two important pieces of information that I think you missed here :
There's no such thing as reading a file "in parallel". Even nowadays, a lot of disk reading is spinning the damn disk until it's in the correct position, and read. So, you can multi thread all you want, the more concurrent disk access you do, the worst read performance you get. A simplified view is that every time you go "backwards", you actually make your disk do a full spin forward to get to that previous line !
Reading from disk sequentially is multiple orders of magnitude faster than random disk access. This is correlated to 1, but really, reading a file line by line is the perfect way to access a disk ! And as it turns out, it's what your naive version do !
Which leads me to believe those are the logical next steps :
Apply your smart algorithm to the file having previously loaded it in memory
Compare again with the naive version
Find no significant difference
Conclude that your workflow is definitely I/O bound, and stop trying to optimize the part that doesn't matter in it !
Note that your mileage may vary if you have a SSD (I assumed not, since there's really no way I can think of a SSD would need 750 seconds to random access lines in it).
So I'm reading characters into a string in Javascript. I want the user to be able to delete characters they have stored, much as one would do in word processing.
function Update() {
if (Input.GetKeyDown("return")) c+= "\n";
if (Input.GetKeyDown("tab")) c+= " ";
if (Input.GetKeyDown("backspace")) c = c.Substring(0, c.Length - 1);
if (Input.inputString.Length != 0)
{
c += Input.inputString;
guiText.text = c;
}
}
The issue I'm running into is that after hitting backspace once, it stops going further back- I can only delete one character. For example, were I to type "example", and then hit backspace twice, I would have "exampl", whereas I would want to have "examp".
I'd love some help on figuring out where I'm going wrong here :) Thanks!
Full code in your question would have been better, You are storing one character at a time right? Try
function Update() {
if (Input.GetKeyDown("return")) c+= "\n";
else if (Input.GetKeyDown("tab")) c+= " ";
else if (Input.GetKeyDown("backspace")) c = c.Substring(0, c.Length - 1);
else if (Input.inputString.Length != 0) c += Input.inputString;
guiText.text = c;
}
What are valid bee sting expressions within an extended quote?
rule set_persistents {
select when pageview ".*"
noop();
always {
ent:ecount += 1 from 1;
app:acount += 1 from 1;
}
}
rule test_bee_stings {
select when pageview ".*"
pre {
sum = ent:ecount + app:acount;
content = <<
sum is #{sum}<br/>
sum + 1 is #{sum+1}<br/>
ecount is #{ent:ecount}<br/>
acount is #{app:acount}
>>;
}
notify("Results", content) with sticky = true;
}
When I run this I get nothing (never see the notify box). If I remove the ecount and acount lines I get
sum is 2
sum + 1 is 21
What bee sting expressions are valid within an extended quote? Is it any different for a normal quoted string?
Variables used in beestings in extended quotes should already have an assigned value and not be an expression. This is because beestings in extended quotes are evaluated on the client side and not the server side. I would also, for the previously explained reason, advise against using 'sum+1' in a beesting even though it currently works for endpoints that understand JavaScript.
Here is how I would write what you are trying to do:
ruleset a60x546 {
meta {
name "extended-quotes-beesting"
description <<
extended-quotes-beesting
>>
author "Mike Grace"
logging on
}
rule test_bee_stings {
select when pageview ".*"
pre {
ecount = ent:ecount + 1;
acount = app:acount + 1;
sum = ecount + acount;
sumplus = sum + 1;
content = <<
sum is #{sum}<br/>
sum + 1 is #{sumplus}<br/>
ecount is #{ecount}<br/>
acount is #{acount}
>>;
}
{
notify("Results", content) with sticky = true;
}
always {
ent:ecount += 1 from 1;
app:acount += 1 from 1;
}
}
}
action shot of app run several times on example.com using bookmarklet:
*I would also advise against using a previous rules postlude to modify app and entity variables that you then use in the next rule expecting it to be incremented. While what you did works it's semantically messy and would probably be a bit cleaner the way I have demonstrated.
**should be taken with a grain of salt since this is only one crazy guy's opinion. : )*