How to add new features to my Hangman game? - macos

I am working on a game, Hangman. I have the code down, I just want to display the word if you lose. How can I do that?
hangman's init()--by Londres on Stack Overflow
script hangman
property stdin : missing value
property stdout : missing value
property dict : missing value
on init()
--starting up the game
set stdin to parent's hangmanStdin's alloc()'s init()
set stdout to parent's hangmanStdout's alloc()'s init()
set dict to parent's hangmanDictionary's alloc()'s init()
my mainLoop()
end init
on mainLoop()
repeat --endless
set option to stdin's getOptions("Lobby", "What would you like to do?", {"New Game", "Quit"})
if option is "New Game" then
set difficulty to stdin's getOptions("New Game", "Choose your difficulty", {"Normal", "Easy", "Hard"})
--replace this line with an automatic word generator
set x to parent's hangmanGame's alloc()'s initWithWordAndDifficulty(dict's getWord(), difficulty)
if x's startgame() is false then
return
else
stdout's printf("You've scored " & x's score & " points.")
end if
--game is over so clear it
set x to missing value
else
exit repeat
end if
end repeat
end mainLoop
on shouldTerminate()
return true
end shouldTerminate
on alloc()
copy me to x
return x
end alloc
end script
script hangmanGame
property parent : hangman
property wordToGuess : missing value
property maxFaults : missing value
property usedChars : missing value
property faults : missing value
property score : 0
on initWithWordAndDifficulty(theWord, theDifficulty)
if theDifficulty = "Hard" then
set my maxFaults to 5
else if theDifficulty = "Normal" then
set my maxFaults to 8
else --easy or any other value will be handled as easy
set my maxFaults to 12
end if
set my wordToGuess to theWord
set my usedChars to {}
set my faults to 0
set my score to 0
return me
end initWithWordAndDifficulty
on startgame()
repeat --endless
set __prompt to "Faults Left: " & maxFaults - faults & return & "The Word: " & my makeHiddenField()
set c to parent's stdin's getChar(__prompt)
if c = false then
return false
end if
--first check if getChar did give us any result
if length of c is not 0 then
--check if teh character is valid
if c is in "abcdefghijklmnopqrstuvwxyz" then
--check if we already checked this before
if c is not in my usedChars then
set end of my usedChars to c
--check if player guessed wrong character
if c is not in wordToGuess then
set faults to faults + 1
end if
end if
end if
end if
--check if player guessed all characters of word
if my wordGuessed() then
set my score to ((25 * (26 / (length of my usedChars))) as integer)
return true
end if
--check if player reached the max faults he's allowed to make
if my faults = my maxFaults then
return 0
end if
end repeat
end startgame
on wordGuessed()
repeat with aChar in every text item of my wordToGuess
if aChar is not in my usedChars then
return false
end if
end repeat
return true
end wordGuessed
on makeHiddenField()
set characterArray to {}
repeat with aChar in every text item of my wordToGuess
if aChar is in my usedChars then
set end of characterArray to aChar as string
else
set end of characterArray to "_"
end if
end repeat
set AppleScript's text item delimiters to space
set hiddenField to characterArray as string
set AppleScript's text item delimiters to ""
return hiddenField
end makeHiddenField
end script
script hangmanDictionary
property parent : hangman
property wordsPlayed : missing value
property allWords : missing value
on init()
set wordsPlayed to {}
--try to get more words from a file for example
set allWords to {"Hangman", "Police", "Officer", "Desktop", "Pencil", "Window", "Language", "Wealthy", "Trauma", "Spell", "Rival", "Tactical", "Thin", "Salty", "Bluish", "Falcon", "Distilery", "Ballistics", "Fumbling", "Limitless", "South", "Humble", "Foreign", "Affliction", "Retreat", "Agreeable", "Poisoner", "Flirt", "Fearsome", "Deepwater", "Bottom", "Twisted", "Morsel", "Filament", "Winter", "Contempt", "Drimys", "Grease", "Awesome", "Compulsive", "Crayon", "Prayer", "Blonde", "Backbone", "Dreamland", "Ballet", "Continuous", "Aerobatic", "Hideous", "Harmonic", "Lottery", "Encrypt", "Cable", "Aluminium", "Hunter", "National", "Hunter", "Mechanical", "Deadbeat", "Opposition", "Threat", "Decadent", "Gazelle", "Guild", "Authoritive", "Deliverance", "Severe", "Jerid", "Alarm", "Monochrome", "Cyanide", "External", "Potential", "Section", "Innocent", "Drifting", "Amnesia", "Domino", "Flimsy", "Flamethrowing", "Advocate", "Hirsute", "Brother", "Ephemeral", "Brutal", "Decade", "Drauma", "Dilemma", "Exquisite", "Glimmer", "Fugitive", "Digital", "Associate", "Ambivalent", "Ambulatory", "Apology", "Brawler", "Molecular", "Insurance", "Contractual", "Initial", "Calibration", "Heretical", "Disclosure", "Guerilla", "Dismember", "Minimal", "Altercation", "Eastern", "Integrate", "Femur", "Metallic", "Ambition", "Auxiliary", "Esoteric", "Converse", "Accepting", "Juvenile", "Efficacious", "Complex", "Imperil", "Division", "Onerous", "Astonish", "Scandalous", "Quaint", "Dominate", "Contrary", "Conspiracy", "Earthquake", "Embarrassment", "Exclude", "Ambiguous", "Captivate", "Compliance", "Migration", "Embryo", "Abandon", "Conservation", "Appreciate", "Applaud", "Pension", "Voyage", "Influence", "Consensus", "Incapable", "Economy", "Parameter", "Contrast", "Sensitive", "Meadow", "Chimney", "Familiar", "Serious", "Credibility", "Infrastructure", "Museum", "Relinquish", "Merit", "Coalition", "Retirement", "Transaction", "Official", "Composer", "Magnitude", "Committee", "Privilege", "Diamond", "Obligation", "Transition", "Jockey", "Reinforce", "Conflict", "Offensive", "Detective", "Effective", "Detector"}
return me
end init
on getWord()
set randomNr to (random number from 1 to (length of (my allWords))) as integer
--you could do somethinh here when a word is used again
return item randomNr of my allWords as string
end getWord
end script
script hangmanStdin
property parent : hangman
on init()
return me
end init
on getChar(__prompt)
set x to display dialog __prompt buttons {"Go", "Quit"} default button "Go" default answer ""
if button returned of x = "Quit" then
return false
end if
if length of x's text returned = 0 then
return ""
end if
return character 1 of x's text returned
end getChar
on getOptions(__title, __message, __options)
return button returned of (display alert __title message __message buttons __options default button 1)
end getOptions
end script
script hangmanStdout
property parent : hangman
on init()
return me
end init
on printf(__message)
display dialog __message buttons {"OK"} default button 1
end printf
end script
How can I make it so if you lose the game, not only does it say the you got 0 points but also say the word that they missed. I'm trying my best to get this done. It's a project that I'm doing to get the basics of coding. Took me awhile.

You are only checking the return result from hangmanGame’s startGame() handler for false or otherwise, but the handler returns 0 if all the faults are used. You could add an additional check in there, but the easiest way would probably be to add a dialog in the startGame() comparison, for example:
if my faults = my maxFaults then
display dialog "The word was " & quoted form of wordToGuess
return 0
end if

Related

Adding a feature to this Hangman Game

I have a hangman game and I am having trouble adding in a feature. I want to make it if the whole word is guessed, it will display "You guessed the word!!!", but I cant seem to find a spot to put it. This is the code
hangman's init()
script hangman
property stdin : missing value
property stdout : missing value
property dict : missing value
on init()
--starting up the game
set stdin to parent's hangmanStdin's alloc()'s init()
set stdout to parent's hangmanStdout's alloc()'s init()
set dict to parent's hangmanDictionary's alloc()'s init()
my mainLoop()
end init
on mainLoop()
repeat --endless
set option to stdin's getOptions("Lobby", "What would you like to do?", {"New Game", "Quit"})
if option is "New Game" then
set difficulty to stdin's getOptions("New Game", "Choose your difficulty", {"Normal", "Easy", "Hard"})
--replace this line with an automatic word generator
set x to parent's hangmanGame's alloc()'s initWithWordAndDifficulty(dict's getWord(), difficulty)
if x's startgame() is false then
return
else
stdout's printf("You've scored " & x's score & " points.")
end if
--game is over so clear it
set x to missing value
else
exit repeat
end if
end repeat
end mainLoop
on shouldTerminate()
return true
end shouldTerminate
on alloc()
copy me to x
return x
end alloc
end script
script hangmanGame
property parent : hangman
property wordToGuess : missing value
property maxFaults : missing value
property usedChars : missing value
property faults : missing value
property score : 0
on initWithWordAndDifficulty(theWord, theDifficulty)
if theDifficulty = "Hard" then
set my maxFaults to 5
else if theDifficulty = "Normal" then
set my maxFaults to 8
else --easy or any other value will be handled as easy
set my maxFaults to 10
end if
set my wordToGuess to theWord
set my usedChars to {}
set my faults to 0
set my score to 0
return me
end initWithWordAndDifficulty
on startgame()
repeat --endless
set __prompt to "Faults Left: " & maxFaults - faults & return & "The Word: " & my makeHiddenField()
set c to parent's stdin's getChar(__prompt)
if c = false then
return false
end if
--first check if getChar did give us any result
if length of c is not 0 then
--check if teh character is valid
if c is in "abcdefghijklmnopqrstuvwxyz" then
--check if we already checked this before
if c is not in my usedChars then
set end of my usedChars to c
--check if player guessed wrong character
if c is not in wordToGuess then
set faults to faults + 1
end if
end if
end if
end if
--check if player guessed all characters of word
if my wordGuessed() then
set my score to ((25 * (26 / (length of my usedChars))) as integer)
return true
end if
--check if player reached the max faults he's allowed to make
if my faults = my maxFaults then
display dialog "The word was " & quoted form of wordToGuess
return 0
end if
end repeat
end startgame
on wordGuessed()
repeat with aChar in every text item of my wordToGuess
if aChar is not in my usedChars then
return false
end if
end repeat
return true
end wordGuessed
on makeHiddenField()
set characterArray to {}
repeat with aChar in every text item of my wordToGuess
if aChar is in my usedChars then
set end of characterArray to aChar as string
else
set end of characterArray to "_"
end if
end repeat
set AppleScript's text item delimiters to space
set hiddenField to characterArray as string
set AppleScript's text item delimiters to ""
return hiddenField
end makeHiddenField
end script
script hangmanDictionary
property parent : hangman
property wordsPlayed : missing value
property allWords : missing value
on init()
set wordsPlayed to {}
--try to get more words from a file for example
set allWords to {"Hangman", "Police", "Officer", "Desktop", "Pencil", "Window", "Language", "Wealthy", "Trauma", "Spell", "Rival", "Tactical", "Thin", "Salty", "Bluish", "Falcon", "Distilery", "Ballistics", "Fumbling", "Limitless", "South", "Humble", "Foreign", "Affliction", "Retreat", "Agreeable", "Poisoner", "Flirt", "Fearsome", "Deepwater", "Bottom", "Twisted", "Morsel", "Filament", "Winter", "Contempt", "Drimys", "Grease", "Awesome", "Compulsive", "Crayon", "Prayer", "Blonde", "Backbone", "Dreamland", "Ballet", "Continuous", "Aerobatic", "Hideous", "Harmonic", "Lottery", "Encrypt", "Cable", "Aluminium", "Hunter", "National", "Hunter", "Mechanical", "Deadbeat", "Opposition", "Threat", "Decadent", "Gazelle", "Guild", "Authoritive", "Deliverance", "Severe", "Jerid", "Alarm", "Monochrome", "Cyanide", "External", "Potential", "Section", "Innocent", "Drifting", "Amnesia", "Domino", "Flimsy", "Flamethrowing", "Advocate", "Hirsute", "Brother", "Ephemeral", "Brutal", "Decade", "Drauma", "Dilemma", "Exquisite", "Glimmer", "Fugitive", "Digital", "Associate", "Ambivalent", "Ambulatory", "Apology", "Brawler", "Molecular", "Insurance", "Contractual", "Initial", "Calibration", "Heretical", "Disclosure", "Guerilla", "Dismember", "Minimal", "Altercation", "Eastern", "Integrate", "Femur", "Metallic", "Ambition", "Auxiliary", "Esoteric", "Converse", "Accepting", "Juvenile", "Efficacious", "Complex", "Imperil", "Division", "Onerous", "Astonish", "Scandalous", "Quaint", "Dominate", "Contrary", "Conspiracy", "Earthquake", "Embarrassment", "Exclude", "Ambiguous", "Captivate", "Compliance", "Migration", "Embryo", "Abandon", "Conservation", "Appreciate", "Applaud", "Pension", "Voyage", "Influence", "Consensus", "Incapable", "Economy", "Parameter", "Contrast", "Sensitive", "Meadow", "Chimney", "Familiar", "Serious", "Credibility", "Infrastructure", "Museum", "Relinquish", "Merit", "Coalition", "Retirement", "Transaction", "Official", "Composer", "Magnitude", "Committee", "Privilege", "Diamond", "Obligation", "Transition", "Jockey", "Reinforce", "Conflict", "Offensive", "Detective", "Effective", "Detector", "Abhorrent", "Fragile", "Feigned", "Addition", "Jealous", "Irritating", "Grotesque", "Hesitant", "Adaptable", "Highfalutin", "Defiant", "Ceaseless", "Aquatic", "Voracious", "Separate", "Phobic", "Scientific", "Cluttered", "Intelligent", "Garrulous", "Rhetorical", "Obtainable", "Bawdy", "Outstanding", "Synonymous", "Gleaming", "Ambitious", "Agonizing", "Fallacious", "Lamister", "Fugitive", "Individualism", "Archaic", "Paramount", "Pannose", "Pretermit", "Retorse", "Versability", "Demonomancy", "Vagile", "Reflation", "Foliate", "Guignol", "Agacerie", "Theopneustic", "Glumiferous", "Optative", "Scrivello", "Unifarious", "Ordonnance", "Dithyrambic", "Locative", "Locomotive", "Mirabilia", "Keyline", "Mellification", "Theomicrist", "Ireless", "Commonition", "Dragoon", "Webster", "Utinam", "Obumbrate", "Inceptive"}
return me
end init
on getWord()
set randomNr to (random number from 1 to (length of (my allWords))) as integer
--you could do somethinh here when a word is used again
return item randomNr of my allWords as string
end getWord
end script
script hangmanStdin
property parent : hangman
on init()
return me
end init
on getChar(__prompt)
set x to display dialog __prompt buttons {"Go", "Quit"} default button "Go" default answer ""
if button returned of x = "Quit" then
return false
end if
if length of x's text returned = 0 then
return ""
end if
return character 1 of x's text returned
end getChar
on getOptions(__title, __message, __options)
return button returned of (display alert __title message __message buttons __options default button 1)
end getOptions
end script
script hangmanStdout
property parent : hangman
on init()
return me
end init
on printf(__message)
display dialog __message buttons {"OK"} default button 1
end printf
end script
This is similar to your other topic, you just need to follow the flow of your script.
In the hangmanGame script’s startGame() handler, you are using the wordGuessed() handler to determine if the word was guessed, so the dialog can go where you are getting that result, for example:
if my wordGuessed() then
display dialog "You guessed the word!!!"
set my score to ((25 * (26 / (length of my usedChars))) as integer)
return true
end if

Get start of line without taking soft line breaks into account

In a RichTextBox, when sending EM_LINEINDEX to get the index of the first character of a line, the index will be affected by soft line breaks. Consider the following text box:
Calling SendMessage hWnd, EM_LINEINDEX, 1, 0 will result in 25, while I would expect it to return 45 (line 1 should be "this is another line" not "and continues here").
Is there a way to get the real first char index of the second line using WinAPI calls?
This is from a working program. I play with right margin.
Sub mnuWordWrap_Click()
'On Error Resume Next
If txtNote.RightMargin = 0 Then
txtNote.RightMargin = &HFFFE&
mnuWordWrap.Checked = False
Else
txtNote.RightMargin = 0
mnuWordWrap.Checked = True
End If
txtNote.SetFocus
txtNote_SelChange
End Sub
In another program I do this, though this is Vista's RTF window (not a control so not the old ANSI version of RTF as in VB6)
If mnuViewWordWrap.Checked = True Then
Ret = SendMessageByVal(gRtfHwnd, EM_SETTARGETDEVICE, GetDC(gRtfHwnd), -1800)
If Ret = 0 Then ReportError "Form Resize", "Set Target Device"
Else
Ret = SendMessageByVal(gRtfHwnd, EM_SETTARGETDEVICE, GetDC(gRtfHwnd), 4000000)
If Ret = 0 Then ReportError "Form Resize", "Set Target Device"
End If

Photoshop Javascript: How to get / set current tool?

How does one get / set the current tool using Javascript in Photoshop?
#target photoshop
if (app.currentTool == BRUSH_TOOL) {
app.currentTool = ERASE_TOOL;
} else {
app.currentTool = BRUSH_TOOL;
}
I found a solution, but I wish it was simpler. Basically I'm using this to select the brush tool and toggle the eraser tool, using only one button. That way I only have to use one button on my Wacom Tablet.
#target photoshop
if (getTool() == 'paintbrushTool') {
setTool('eraserTool');
} else {
setTool('paintbrushTool');
}
// https://forums.adobe.com/thread/579195
function getTool(){
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("capp"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var cTool = typeIDToStringID(executeActionGet(ref).getEnumerationType(stringIDToTypeID('tool')));
return cTool;
}
// https://www.ps-scripts.com/viewtopic.php?f=68&t=11342&p=152772
function setTool(tool) {
var desc9 = new ActionDescriptor();
var ref7 = new ActionReference();
ref7.putClass( app.stringIDToTypeID(tool) );
desc9.putReference( app.charIDToTypeID('null'), ref7 );
executeAction( app.charIDToTypeID('slct'), desc9, DialogModes.NO );
}
// Tool names (use quoted strings, e.g. 'moveTool')
// moveTool
// marqueeRectTool
// marqueeEllipTool
// marqueeSingleRowTool
// marqueeSingleColumnTool
// lassoTool
// polySelTool
// magneticLassoTool
// quickSelectTool
// magicWandTool
// cropTool
// sliceTool
// sliceSelectTool
// spotHealingBrushTool
// magicStampTool
// patchSelection
// redEyeTool
// paintbrushTool
// pencilTool
// colorReplacementBrushTool
// cloneStampTool
// patternStampTool
// historyBrushTool
// artBrushTool
// eraserTool
// backgroundEraserTool
// magicEraserTool
// gradientTool
// bucketTool
// blurTool
// sharpenTool
// smudgeTool
// dodgeTool
// burnInTool
// saturationTool
// penTool
// freeformPenTool
// addKnotTool
// deleteKnotTool
// convertKnotTool
// typeCreateOrEditTool
// typeVerticalCreateOrEditTool
// typeCreateMaskTool
// typeVerticalCreateMaskTool
// pathComponentSelectTool
// directSelectTool
// rectangleTool
// roundedRectangleTool
// ellipseTool
// polygonTool
// lineTool
// customShapeTool
// textAnnotTool
// soundAnnotTool
// eyedropperTool
// colorSamplerTool
// rulerTool
// handTool
// zoomTool
It's simpler in AppleScript. This is my little library script that I use with my Wacom:
-- put into ~/Library/Script\ Libraries
-- use as set currentTool to script "Photoshop_ScriptLibrary"'s toggleCurrentTool("lassoTool", "eraserTool")
on writeVar(theName, theVar)
do shell script "echo " & theVar & " > /tmp/" & theName & ".txt"
end writeVar
on readVar(theName)
try
return do shell script "cat /tmp/" & theName & ".txt"
end try
return ""
end readVar
on getGroupPath()
set thelayer to ""
tell application "Adobe Photoshop CC 2019" to tell the current document
set thelayer to current layer
end tell
return thelayer
end getGroupPath
on getCurrentTool()
tell application "Adobe Photoshop CC 2019" to return current tool
end getCurrentTool
on deselect()
tell application "Adobe Photoshop CC 2019" to tell the current document to deselect
setFeathered(false)
end deselect
on toggleCurrentTool(tool1, tool2)
setFeathered(false)
set currentTool to tool1
tell application "Adobe Photoshop CC 2019"
if current tool is equal to currentTool then set currentTool to tool2
set current tool to currentTool
end tell
return currentTool
end toggleCurrentTool
on getAllLayers(layerName)
set allLayerNames to {}
tell application "Adobe Photoshop CC 2019"
set allLayers to the layers of current document
repeat with thelayer in allLayers
set theName to the name of thelayer
if theName starts with the first word of layerName then set end of allLayerNames to theName
end repeat
end tell
return allLayerNames
end getAllLayers
on getPrevLayer(targetLayerName, currentLayer)
set currentLayerId to id of currentLayer
tell application "Adobe Photoshop CC 2019"
return the first art layer of the current document whose name is targetLayerName and id is not currentLayerId
return the first art layer of the current document whose name is targetLayerName
end tell
end getPrevLayer
on getPrevious(layerName)
set suffix to the last word of layerName
set suffixlength to get (length of suffix) + 2
log "getPrevious(" & layerName & "), suffix: " & suffix
-- remove the last word from the layer name. Unless we're dealing with numbered copies
set targetLayerName to (text 1 thru (-1 * suffixlength)) of layerName
-- first: Check if layer name ends in number. If number > 2, we want the layer with the next-smaller number
-- WIP copy 16 -> WIP copy 15
-- WIP copy 1 -> WIP copy
-- second: If the layer does not end in a number,
try
set thenumber to (suffix as number)
if thenumber is greater than 2 then set targetLayerName to targetLayerName & " " & thenumber - 1
on error -- if layer doesn't end in a number: remove "copy"
if layerName ends with "copy" then set targetLayerName to text 1 thru -6 of layerName
end try
return targetLayerName
end getPrevious
on getPreviousLayer(currentLayer)
return getPrevLayer((getPrevious(name of currentLayer)), currentLayer)
end getPreviousLayer
on getFeathered()
return "true" is equal to readVar("feathered")
end getFeathered
on setFeathered(b)
writeVar("feathered", b)
end setFeathered
on isOnLayerMask()
try
set windowName to ""
tell application "System Events" to tell process "Adobe Photoshop CC 2019"
tell (1st window whose value of attribute "AXMain" is true)
set windowName to value of attribute "AXTitle"
end tell
end tell
end try
return windowName contains "Layer Mask"
end isOnLayerMask
on isSelected()
try
tell application "Adobe Photoshop CC 2019" to tell current document
set props to properties of selection
if bounds of props is not equal to missing value then return true
end tell
end try
return false
end isSelected
on tryFeather()
if getFeathered() or not isSelected() then return
try
tell application "Adobe Photoshop CC 2019" to tell current document
feather selection by 5
end tell
setFeathered(true)
on error
setFeathered(false)
end try
end tryFeather
on tryBlur(_radius)
if isSelected() then
try
tell application "Adobe Photoshop CC 2019" to tell current document
filter current layer using gaussian blur with options {radius:_radius}
end tell
end try
end if
end tryBlur
you can try to use photoshop-python-api
from photoshop import Session
with Session() as ps:
print(ps.app.currentTool)
https://github.com/loonghao/photoshop-python-api
Old question, but still relevant so I wanted to simplify it further. The OP was on the right track with the code, it needed only the necessary string values for various tools, which were provided by #skibulk above.
According to the Photoshop Javascript Reference PDF, currentTool is a read-write string property of the Application object. This means we can get the value of the current tool, but also set the value of the current tool.
#target photoshop
if (app.currentTool == "paintbrushTool") {
app.currentTool = "eraserTool";
} else {
app.currentTool = "paintbrushTool";
}
// Tool names (use quoted strings, e.g. 'moveTool')
// moveTool
// marqueeRectTool
// marqueeEllipTool
// marqueeSingleRowTool
// marqueeSingleColumnTool
// lassoTool
// polySelTool
// magneticLassoTool
// quickSelectTool
// magicWandTool
// cropTool
// sliceTool
// sliceSelectTool
// spotHealingBrushTool
// magicStampTool
// patchSelection
// redEyeTool
// paintbrushTool
// pencilTool
// colorReplacementBrushTool
// cloneStampTool
// patternStampTool
// historyBrushTool
// artBrushTool
// eraserTool
// backgroundEraserTool
// magicEraserTool
// gradientTool
// bucketTool
// blurTool
// sharpenTool
// smudgeTool
// dodgeTool
// burnInTool
// saturationTool
// penTool
// freeformPenTool
// addKnotTool
// deleteKnotTool
// convertKnotTool
// typeCreateOrEditTool
// typeVerticalCreateOrEditTool
// typeCreateMaskTool
// typeVerticalCreateMaskTool
// pathComponentSelectTool
// directSelectTool
// rectangleTool
// roundedRectangleTool
// ellipseTool
// polygonTool
// lineTool
// customShapeTool
// textAnnotTool
// soundAnnotTool
// eyedropperTool
// colorSamplerTool
// rulerTool
// handTool
// zoomTool

Why is this VBS code skipping the first condition?

The following must work in qtp so i can not use WScript.Echo. The following code have to ask for an integer between 1 to 10 inclusive using an inputbox. If nothing entered the it has to give a message "Aborted".
If anything else entered then it has to say what is the problem and ask again for the number until I abort by cancel or by entering nothing. I have the following code but it looks like it is skipping the first condition and goes to the first else in the loop:
Option Explicit
Dim vNum, sNum, nNum
Do
vNum = InputBox("Please enter an integer between 1 and 10 inclusive")
If IsEmpty(vNum) Then
msgbox("Aborted")
Exit Do
Else
sNum = Trim(vNum)
If "" = sNum Then
vNum=Inputbox("Empty string")
Else
If IsNumeric(sNum) Then
nNum = CDbl(sNum)
If nNum <> Fix(nNum) Then
vNum=inputbox("Not an Integer")
Else
If nNum < 1 Or nNum > 10 Then
vNum=inputbox ("Not in range")
Else
msgbox nNum,("number ok")
Exit Do
End If
End If
Else
vNum= inputbox ("Not a number")
End If
End If
End If
Loop
msgbox ("Done")
You could loop and change the instruction message each time:
Dim vNum, instruction
instruction = "Please enter an integer between 1 and 10 inclusive"
Do
vNum = InputBox(instruction)
If vNum = False Then
MsgBox "Aborted"
Exit Do
ElseIf CStr(Trim(vNum)) = "" Then
instruction = "Empty string"
ElseIf Not IsNumeric(vNum) Then
instruction = "Not an integer"
ElseIf IsNumeric(vNum) And vNum < 1 Or vNum > 10 Then
instruction = "Not in range"
ElseIf IsNumeric(vNum) And vNum > 0 And vNum < 11 Then
MsgBox "Number OK"
Exit Do
Else
instruction = "Invalid Entry"
End If
Loop
This is what help says.
If the user clicks OK or presses ENTER, the InputBox function returns whatever is in the text box. If the user clicks Cancel, the function returns a zero-length string ("").
So you aren't testing for a empty, or zero length, string. It is a valid string, just empty.
Also from Help the meaning of Empty in VBS, which has nothing to do with what's in a string.
Empty
The Empty keyword is used to indicate an uninitialized variable value. This is not the same thing as Null.
Update
HELP IS NOT WRONG. InputBox returns a zero length string just like the docs say.
A uninitialized variable HAS A VALUE (for numbers, dates, and strings)
0 for numbers
1899 sometime for dates
and a zero length string for strings (and a string of spaces for fixed length strings).
HELP IS NOT a TECHNICAL REFERENCE
Help is a CONTRACTUAL document describing behaviour not implementation. As in the COM philosophy.
This is known as LET COERCION. And why x=65:Msgbox x works. There are two variables there.
From VBA Implementers Guidelines
The semantics of Empty Let-coercion depend on the destination’s declared type: Source
Any numeric type - The result is 0.
Boolean - The result is False.
Date - The result is 12/30/1899 00:00:00.
String - The result is a 0-length string.
String * length - The result is a string containing length spaces.
Any class or Object - Runtime error 424 (Object required) is raised. -
Any other type except Variant - Runtime error 13 (Type mismatch) is raised.

Remove the desired content from a text

I would like to get a working code to simply remove from a text line a specific part that always begins with "(" and finish with ")".
Sample text : Hello, how are you (it is a question)
I want to remove this part: "(it is a question)" to only keep this message "Hello, how are you"
Lost...
Thanks
One way using Regular Expressions;
input = "Hello, how are you (it is a question)"
dim re: set re = new regexp
with re
.pattern = "\(.*\)\s?" '//anything between () and if present 1 following whitespace
.global = true
input = re.Replace(input, "")
end with
msgbox input
If the part to be removed is always at the end of the string, string operations would work as well:
msg = "Hello, how are you (it is a question)"
pos = InStr(msg, "(")
If pos > 0 Then WScript.Echo Trim(Left(msg, pos-1))
If the sentence always ends with the ( ) section, use the split function:
line = "Hello, how are you (it is a question)"
splitter = split(line,"(") 'splitting the line into 2 sections, using ( as the divider
endStr = splitter(0) 'first section is index 0
MsgBox endStr 'Hello, how are you
If it is in the middle of the sentence, use the split function twice:
line = "Hello, how are you (it is a question) and further on"
splitter = split(line,"(")
strFirst = splitter(0) 'Hello, how are you
splitter1 = split(line,")")
strSecond = splitter1(UBound(Splitter1)) 'and further on
MsgBox strFirst & strSecond 'Hello, how are you and further on
If there is only one instance of "( )" then you could use a '1' in place of the UBound.
Multiple instances I would split the sentence and then break down each section containing the "( )" and concatenate the final sentence.

Resources