I'm trying to use autohotkey to gather a chuck of data from a website and then click a certain spot on the website depending on what the text is. I'm able to get it to actually pick up the value but when it comes to the if statement it won't seem to process and yields no error message. Here is a quick sample of my code, there is about 20 if statement values so for brevity sake I've only included a few of the values.
GuessesLeft = 20
Errorcount = 0
;triple click and copy text making a variable out of the clipboard
;while (GuessesLeft!=0) part of future while loop
;{ part of future while loop
click 927,349
click 927,349
click 927,349
Send ^c
GetValue = %Clipboard%
if ( GetValue = "Frontal boss")
{
click 955,485
Guessesleft -= 1
}
else if ( GetValue = "Supraorbital Ridge")
{
click 955,571
Guessesleft -= 1
}
;....ETC
else
{
Errorcount += 1
}
;} part of future while loop
Any tips on what I might be doing wrong. Ideally I'd use a case statement but AHK doesn't seem to have them.
Wait a second -- you are triple clicking to highlight a full paragraph and copying that to the clipboard and checking to see if the entirety of the copied portion is the words in the if statement, right? And your words in the copied portion have quotes around them? Probably you will have to trim off any trailing spaces and/or returns:
GetValue = % Trim(Clipboard)
If that doesn't work, you may even have to shorten the length of the copied text by an arbitrary character or two:
GetValue = % SubStr(Clipboard, 1, (StrLen(Clipboard)-2))
Now, if I am wrong, and what you are really looking for is the words from the if statement wherever they may be in a longer paragraph -- and they are not surrounded by quotes, then you will want something like:
IfInString, Clipboard, Frontal boss
Or, if the quotes ARE there,
IfInString, Clipboard, "Frontal boss"
Hth,
Related
Getting stuck on how to read and pretty up these values from a multiline cell via arrayformula.
Im using regex as preceding line can vary.
just formulas please, no custom code
The first column looks like a set of these:
```
[config]
name = the_name
texture = blah.dds
cost = 1000
[effect0]
value = 1000
type = ATTR_A
[effect1]
value = 8
type = ATTR_B
[feature0]
name = feature_blah
[components]
0 = comp_one,1
[resources]
res_one = 1
res_five = 1
res_four = 1
<br/>
Where to be useful elsewhere, at minimum it needs each [tag] set ([effect\d], [feature\d], ect) to be in one column each, for example the 'effects' column would look like:
ATTR_A:1000,ATTR_B:8
and so on.
Desired output can also be seen in the included spreadsheet
<br/>
<b>Here is the example spreadsheet:</b>
https://docs.google.com/spreadsheets/d/1arMaaT56S_STTvRr2OxCINTyF-VvZ95Pm3mljju8Cxw/edit?usp=sharing
**Current REGEXREPLACE**
Kinda works, finds each 'type' and 'value' great, just cant figure out how to extract just that from the rest, tried capture (and non-capturing) groups before and after but didnt work
=ARRAYFORMULA(REGEXREPLACE($A3:$A,"[\n.][effect\d][\n.](.)\n(.)","1:$1 2:$2"))
**Current SUBSTITUTE + REGEXEXTRACT + REGEXREPLACE**
A different approach entirely, also kinda works, longer form though and left with having to parse the values out of that string, where got stuck again. Idea was to use this to simplify, then regexreplace like above. Getting stuck removing content around the final matches though, and if can do that then above approach is fine too.
// First ran a substitute
=ARRAYFORMULA(SUBSTITUTE(SUBSTITUTE($A3:$A,char(10),";"),";;",char(10)))
// Then variation of this (gave up on single line 'effect/d' so broke it up to try and get it working)
=ARRAYFORMULA(IF(A3:A<>"",IFERROR(REGEXEXTRACT(A3:A,"(?m)^(?:[effect0]);(.)$")&";;")&""&IFERROR(REGEXEXTRACT(A3:A,"(?m)^(?:[effect1]);(.)$")&";;")&""&IFERROR(REGEXEXTRACT(A3:A,"(?m)^(?:[effect2]);(.)$")&";;"),""))
// Then use regexreplace like above
=ARRAYFORMULA(REGEXREPLACE($B3:$B,"value = (.);type = (.);;","1:$1 2:$2"))
**--EDIT--**
Also, as my updated 'Desired Output' sheet shows (see timestamped comment below), bonus kudos if you can also extract just the values of matching 'type's to those extra columns (see spreadsheet).
All good if you cant though, just realized would need that too for lookups.
**--END OF EDIT--**
<br/>
Ive tried dozens of things, discarding each in turn, had a quick look in version history to grab out two promising attempts and shared them in separate sheets.
One of these also used SUBSTITUTE to simplify input column, im happy for a solution using either RAW or the SUBSTITUTE results.
<br/>
**Potentially Useful links:**
https://github.com/google/re2/wiki/Syntax
<br/>
<b>Just some more words:</b>
I also have looked at dozens of stackoverflow and google support pages, so tried both REGEXEXTRACT and REGEXREPLACE, both promising but missing that final tweak. And i tried dozens of tweaks already on both.
Any help would be great, and hopefully help others in future since examples with spreadsheets are great since every new REGEX seems to be a new adventure ;)
<br/>
P.S. if we can think of better title for OP, please say in comment or your answer :)
paste in B3:
=ARRAYFORMULA(SUBSTITUTE(TRIM(TRANSPOSE(QUERY(TRANSPOSE(
IF(C3:E<>"", C2:E2&":"&C3:E, )),,999^99))), " ", ", "))
paste in C3:
=ARRAYFORMULA(IFNA(REGEXEXTRACT($A3:$A, "(\d+)\ntype = "&C2)))
paste in D3:
=ARRAYFORMULA(IFNA(REGEXEXTRACT($A3:$A, "(\d+)\ntype = "&D2)))
paste in E3:
=ARRAYFORMULA(IFNA(REGEXEXTRACT($A3:$A, "(\d+)\ntype = "&E2)))
paste in F3:
=ARRAYFORMULA(IFNA(REGEXEXTRACT(A3:A, "\[feature\d+\]\nname = (.*)")))
paste in G3:
=ARRAYFORMULA(IFNA(REGEXEXTRACT(A3:A, "\[components\]\n\d+ = (.*)")))
paste in H3:
=ARRAYFORMULA(IFNA(REGEXREPLACE(INDEX(SPLIT(REGEXEXTRACT(
REGEXREPLACE(A3:A, "\n", ", "), "\[resources\], (.*)"), "["),,1), ", , $", )))
spreadsheet demo
This was a fun exercise. :-)
Caveat first: I have added some "input data". Examples:
[feature1]
name = feature_active_spoiler2
[components]
0 = spoiler,1
1 = spoilerA, 2
So the output has "extra" output.
See the tab ADW's Solution.
Can someone help with my code searching for a partial match. I seem to be stuck here.
I would like type only the first few letters in a combo-box, hit enter, and store whatever I have typed as a variable. Then I want to check my variable against my list for the closest name that matches what I have typed. That becomes the new variable. How do I do this?
#singleInstance, Force
list =
(
Phone Numbers
Important People
Modification
Traffic Data
Tasks
Tracker
)
Gui, +alwaysontop
Gui +Delimiter`n
Gui, Add, ComboBox, vMyVar w200 h110 CHOOSE1 sort, % LIST
Gui, Add, Button, gGO Default x+5 w60 h20 , GO
Gui, show, y200, What do you want now?!
return
; Type first couple letters in box hit enter
GO:
Gui, Submit, nohide
Loop, parse, List, `n
{
; Search LIST for nearest match
;First partial match found
; MyVar := "A_loopfield"
MsgBox % InStr(A_loopfield, DoThis)
}
if MyVar = Phone Numbers
; Msgbox or Function ETC..
Try
#singleInstance, Force
list =
(
Phone Numbers
Important People
Modification
Traffic Data
Tasks
Tracker
)
Gui, +alwaysontop
Gui +Delimiter`n
Gui, Add, ComboBox, vMyVar w200 h110 CHOOSE1 sort, % LIST
Gui, Add, Button, gGO Default x+5 w60 h20 , GO
Gui, show, y200, What do you want now?!
return
; Type first couple letters in box hit enter
GO:
Gui, Submit, nohide
GuiControlGet, text_typed,, ComboBox1
StringLen, length, text_typed ; retrieves the count of how many characters are in the text typed
Loop, parse, List, `n
{
If (SubStr(A_LoopField, 1, length) = text_typed)
{
GuiControl, Choose, MyVar, %A_LoopField%
If (A_LoopField = "Phone Numbers")
MsgBox, Item 1
; ...
If (A_LoopField = "Traffic Data")
MsgBox, Item 6
break
}
}
return
on oneButtonClicked_(sender)
set faceNumber's setStringValue() to faceNumber's stringValue() & "1"
end oneButtonClicked_
I get this error: "Can’t make «class ocid» id «data optr000000000058B37BFF7F0000» into type list, record or text. (error -1700)"
faceNumber is a label and when the user clicks the button, I want to add string of "1" to it. So for example, if the user clicked the button 5 times
stringValue returns an NSString(wrong answer) CFString. You have to make a real AppleScript String to use it.
BTW your code set faceNumber's setStringValue() is not correct. The reasons are:
The Cocoa handlers are always using the underscore.
If you use the setter setStringValue() you don't need to use set x to
If you want to use setStringValue() you must give the parameter between the parentheses
Now put everything together:
on oneButtonClicked_(sender)
faceNumber's setStringValue_((faceNumber's stringValue) as string & "1")
end oneButtonClicked_
or (to have it clearer):
on oneButtonClicked_(sender)
tell faceNumber
set currentValue to (its stringValue) as string
setStringValue_(currentValue & "1")
end tell
end oneButtonClicked_
I hope you like the answer, after pressing the button twice you have an 11 at the end of the label.
Cheers, Michael / Hamburg
I'm pulling my hair out over this one! I'm using ColdFusion to generate .rtf files like the one below for printing Avery mailing labels. For some reason, a space appears before each name in the first column, but only after the first row. This has me stumped because I've looked at the source being generated and don't see an extra character before the name, even though when I open the .rtf in a text editor I can delete the character manually to fix this. Can anyone tell me why that extra space is there? You can download the actual .rtf file at this URL:
http://www.bitmojo.com/Avery-Label-Test.rtf
Well I guess I can't post images...feel free to ask for a link if you need clarification.
Adding this here since it was too long for a comment:
I'm using the CF_AVERYRTF.CFM custom tag from over ten years ago...hasn't been updated since to my knowledge. I'll edit my question to add the code that actually generates and saves out the RTF. It uses cfsavecontent, cfscript and writeoutput to create the variable that gets saved to disk as the .rtf file, and when I cfdump that variable before the .rtf gets written to disk I don't see any extra characters before the names, but when I open the .rtf file source in my code editor I see a space before each name, and when I open the .rtf in the text editor on my mac I only see spaces before the names in the first column after the first row...that's what's driving me crazy, seeing different things depending on where and how I'm looking at the data...that's why I posted the example file, so someone could take a look and at least verify what I'm seeing. Here's an image of the symptom as it appears on my Mac (spaces circled)
screen shot http://www.bitmojo.com/Avery-Label-Screen-Shot.png
Also here's the code that generates the data:
<cfsavecontent variable="ThisTag.GeneratedRTF">
<cfscript>
// open RTF document with header information
writeOutput("{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss Helvetica;}{\f2\fswiss Impact;}{\f3\froman Times New Roman;}}");
writeOutput("{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\red255\green255\blue255;}");
writeOutput("{\info{\title VFIVE Label Generator (#request.rtfLabels.labeltitle# Output)}{\author cf_averyRTF $Revision: 1.17 $}{\operator cf_averyRTF resides at http://rtf.vfive.com}{\*\company VFIVE (http://www.vfive.com)}{\creatim\yr#Year(now())#\mo#Month(now())#\dy#Day(now())#\hr#Hour(now())#\min#Minute(now())#}{\version1}{\edmins0}{\nofpages1}{\nofwords0}{\nofchars0}{\nofcharsws0}{\vern1000}}\paperw#request.rtfLabels.paperw#\paperh#request.rtfLabels.paperh#\margl#request.rtfLabels.margl#\margr#request.rtfLabels.margr#\margt#request.rtfLabels.margt#\margb#request.rtfLabels.margb#");
if (Attributes.landscape)
{
writeOutput("\landscape");
}
writeOutput("\gutter#request.rtfLabels.gutter# \widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\horzdoc \jexpand\viewkind1\viewscale#request.rtfLabels.viewscale#\nolnhtadjtbl \fet0\sectd \linex#request.rtfLabels.linex#\sectdefaultcl");
// loop over each row in the dataset
for (ii = 1; ii LTE arrayLen(thisTag.assocAttribs); ii = ii + 1)
{
// if this is the first cell of a row, create the row (like <tr>)
if (NOT ((ii + request.rtfLabels.columns - 1) MOD request.rtfLabels.columns))
{
// output the <tr>-like row start, cellBoundary
writeOutput("\trowd \trrh#request.rtfLabels.trrhcell#\trkeep" & cellBoundary);
// output row setup (align, indent, etc)
writeOutput(" \pard\plain \q#request.rtfLabels.textalign# \li#request.rtfLabels.li#\ri#request.rtfLabels.ri#\widctlpar\intbl\faauto \f#request.rtfLabels.defaultfontface#\fs20\lang1033\langfe1033");
}
// output each individual cell header (like <td>)
writeOutput("{\#request.rtfLabels.bold#\fs#request.rtfLabels.defaultfontsize#\f#request.rtfLabels.defaultfontface# ");
// output barcode on top if appropriate
if (len(trim(thisTag.assocAttribs[ii].zipCode)) AND thisTag.assocAttribs[ii].barPos EQ "top")
{
writeOutput("{\field\flddirty{\*\fldinst { BARCODE }{\lang1024\langfe1024\noproof #ThisTag.AssocAttribs[ii].zipcode#}{\\u }}{\fldrslt }}\par");
}
// loop over the lines of content in this cell
for (jj = 1; jj LTE arrayLen(ThisTag.AssocAttribs[ii].arrCell); jj = jj + 1)
{
// content to be displayed?
if (len(trim(thisTag.assocAttribs[ii].arrCell[jj].content)) OR NOT thisTag.assocAttribs[ii].stripBlankLines)
{
// are we bolding this line of content?
if (thisTag.assocAttribs[ii].arrCell[jj].bold)
{
writeOutput("\b");
}
else
{
writeOutput("\b0");
}
writeOutput("\fs#ThisTag.AssocAttribs[ii].arrCell[jj].fs#\f#ThisTag.AssocAttribs[ii].arrCell[jj].f##ThisTag.AssocAttribs[ii].arrCell[jj].content#");
if (jj LT arrayLen(ThisTag.AssocAttribs[ii].arrCell))
{
writeOutput("\par");
}
}
}
// close out cell (like a </td>)
writeOutput("}{\fs#request.rtfLabels.defaultfontsize#\f#request.rtfLabels.defaultfontface# ");
// output barcode on bottom if appropriate
if (len(trim(thisTag.assocAttribs[ii].zipCode)) AND thisTag.assocAttribs[ii].barPos EQ "bottom")
{
writeOutput(" {\field\flddirty{\*\fldinst { BARCODE }{\lang1024\langfe1024\noproof #ThisTag.AssocAttribs[ii].zipcode#}{\\u }}{\fldrslt }}");
}
// prepare to close this cell </td>
writeOutput("\cell } ");
// close this cell out like a </td>
if (ii MOD request.rtfLabels.columns)
{
writeOutput(" \pard \q#request.rtfLabels.textalign# \li#request.rtfLabels.li#\ri#request.rtfLabels.ri#\widctlpar\intbl\faauto {\cell }");
}
else
{
writeOutput("\pard\plain \q#request.rtfLabels.textalign# \li#request.rtfLabels.li#\ri#request.rtfLabels.ri#\widctlpar\intbl\aspalpha\aspnum\faauto\adjustright \fs#request.rtfLabels.defaultfontsize#\f#request.rtfLabels.defaultfontface#\lang1033\langfe1033");
}
// if this is the last cell of a row, end it (like a </tr>) --->
if (NOT (ii MOD request.rtfLabels.columns))
{
// start close: output code + cellCloser + " \row }"
writeOutput("\pard\plain \q#request.rtfLabels.textalign# \li#request.rtfLabels.li#\ri#request.rtfLabels.ri#\widctlpar\intbl\aspalpha\aspnum\faauto\adjustright \fs#request.rtfLabels.defaultfontsize#\f#request.rtfLabels.defaultfontface#\lang1033\langfe1033 {\trowd \trrh#request.rtfLabels.trrhcell#\trkeep " & cellCloser & " \row }#chr(13)##chr(10)#");
// add an extra spacer row?
if (request.rtfLabels.useSpacer)
{
// output complete spacerRow as defined above
writeOutput(spacerRow);
}
}
// end of outer for loop
}
// close out document
writeOutput("\pard \q#request.rtfLabels.textalign# \li#request.rtfLabels.li#\ri#request.rtfLabels.ri#\widctlpar\aspalpha\aspnum\faauto\adjustright { \par }{ \par }}");
</cfscript>
</cfsavecontent>
We can't say much about this without seeing code. Added to what #Miguel-F said, if you're using any of your own functions in this process, have they got output="false" specified?
CF has a nasty habit of haemorrhaging whitespace (like from your source code's indentation) unless you specifically control it. This doesn't cause a problem (other than bloat) for rendered HTML as the HTML spec says it ought to be ignored, so the browser does so. This is not the case for other file formats.
It will almost certainly be your code's white space bleeding through.
One fairly easy way of dealing with this is to use CFScript rather than tags, wherever possible (which is reasonable advice as a matter of course anyhow, do keep your code clear and concise).
UPDATE
If you are using a custom tag, make sure you have <cfsilent> tags around the call to it, and around everything within it which emits anything. Custom tags are terrible for emitting spurious whitespace.
This resolved itself now that I've upgraded to ColdFusion 2016, so I'm going to write it off as a bug in ColdFusion that was solved by Adobe.
Currently I am working very basic game using the C++ environment. The game used to be a school project but now that I am done with that programming class, I wanted to expand my skills and put some more flourish on this old assignment.
I have already made a lot of changes that I am pleased with. I have centralized all the data into folder hierarchies and I have gotten the code to read those locations.
However my problem stems from a very fundamental flaw that has been stumping me.
In order to access the image data that I am using I have used the code:
string imageLocation = "..\\DATA\\Images\\";
string bowImage = imageLocation + "bow.png";
The problem is that when the player picks up an item on the gameboard my code is supposed to use the code:
hud.addLine("You picked up a " + (*itt)->name() + "!");
to print to the command line, "You picked up a Bow!". But instead it shows "You picked up a ..\DATA\Images\!".
Before I centralized my data I used to use:
name_(item_name.substr(0, item_name.find('.')))
in my Item class constructor to chop the item name to just something like bow or candle. After I changed how my data was structured I realized that I would have to change how I chop the name down to the same simple 'bow' or 'candle'.
I have changed the above code to reflect my changes in data structure to be:
name_(item_name.substr(item_name.find("..\\DATA\\Images\\"), item_name.find(".png")))
but unfortunately as I alluded to earlier this change of code is not working as well as I planned it to be.
So now that I have given that real long winded introduction to what my problem is, here is my question.
How do you extract the middle of a string between two sections that you do not want? Also that middle part that is your target is of an unknown length.
Thank you so very much for any help you guys can give. If you need anymore information please ask; I will be more than happy to upload part or even my entire code for more help. Again thank you very much.
In all honeasty, you're probably approaching this from the wrong end.
Your item class should have a string "bow", in a private member. The function Item::GetFilePath would then (at runtime) do "..\DATA\Images\" + this->name + ".png".
The fundamental property of the "bow" item object isn't the filename bow.png, but the fact that it's a "bow". The filename is just a derived proerty.
Assuming I understand you correctly, the short version of your question is: how do I split a string containing a file path so I have removed the path and the extension, leaving just the "title"?
You need the find_last_of method. This gets rid of the path:
std::size_type lastSlash = filePath.find_last_of('\\');
if (lastSlash == std::string::npos)
fileName = filePath;
else
fileName = filePath.substr(lastSlash + 1);
Note that you might want to define a constant as \\ in case you need to change it for other platforms. Not all OS file systems use \\ to separate path segments.
Also note that you also need to use find_last_of for the extension dot as well, because filenames in general can contain dots, throughout their paths. Only the very last one indicates the start of the extension:
std::size_type lastDot = fileName.find_last_of('.');
if (lastDot == std::string::npos)
{
title = fileName;
}
else
{
title = fileName.substr(0, lastDot);
extension = fileName.substr(lastDot + 1);
}
See http://msdn.microsoft.com/en-us/library/3y5atza0(VS.80).aspx
using boost filesystem:
#include "boost/filesystem.hpp"
namespace fs = boost::filesystem;
void some_function(void)
{
string imageLocation = "..\\DATA\\Images\\";
string bowImage = imageLocation + "bow.png";
fs::path image_path( bowImage );
hud.addLine("You picked up a " + image_path.filename() + "!"); //prints: You picked up a bow!
So combining Paul's and my thoughts, try something like this (broken down for readability):
string extn = item_name.substr(item_name.find_last_of(".png"));
string path = item_name.substr(0, item_name.find("..\\DATA\\Images\\"));
name_ = item_name.substr( path.size(), item_name.size() - extn.size() );
You could simplify it a bit if you know that item name always starts with "..DATA" etc (you could store it in a constant and not need to search for it in the string)
Edit: Changed extension finding part to use find_last_of, as suggested by EarWicker, (this avoids the case where your path includes '.png' somewhere before the extension)
item_name.find("..\DATA\Images\") will return the index at which the substring "..\DATA\Images\" starts but it seems like you'd want the index where it ends, so you should add the length of "..\DATA\Images\" to the index returned by find.
Also, as hamishmcn pointed out, the second argument to substr should be the number of chars to return, which would be the index where ".png" starts minus the index where "..\DATA\Images\" ends, I think.
One thing that looks wrong is that the second parameter to substr should be the number of chars to copy, not the position.