Is it possible to make an interactive Rake task? - rake

I want to run a Rake task that asks the user for input.
I know that I can supply input on the command line, but I want to ask the user if they are sure they want to proceed with a particular action in case they mistyped one of the values supplied to the Rake task.

Something like this might work
task :action do
STDOUT.puts "I'm acting!"
end
task :check do
STDOUT.puts "Are you sure? (y/n)"
input = STDIN.gets.strip
if input == 'y'
Rake::Task["action"].reenable
Rake::Task["action"].invoke
else
STDOUT.puts "So sorry for the confusion"
end
end
Task reenabling and invoking from How to run Rake tasks from within Rake tasks?

Here's an example without using another task.
task :solve_earth_problems => :environment do
STDOUT.puts "This is risky. Are you sure? (y/n)"
begin
input = STDIN.gets.strip.downcase
end until %w(y n).include?(input)
if input != 'y'
STDOUT.puts "So sorry for the confusion"
return
end
# user accepted, carry on
Humanity.wipe_out!
end

A handy feature for user input is to put it in a do..while loop, to only continue when a user has supplied valid input. Ruby doesn't explicitly have this construct, but you can achieve the same thing with begin and until. That would add to the accepted answer as follows:
task :action do
STDOUT.puts "I'm acting!"
end
task :check do
# Loop until the user supplies a valid option
begin
STDOUT.puts "Are you sure? (y/n)"
input = STDIN.gets.strip.downcase
end until %w(y n).include?(input)
if input == 'y'
Rake::Task["action"].reenable
Rake::Task["action"].invoke
else
# We know at this point that they've explicitly said no,
# rather than fumble the keyboard
STDOUT.puts "So sorry for the confusion"
end
end

You could also wrap this up in a service class so it can be unit-tested and used across your rake tasks:
# frozen_string_literal: true
class RakeConfirmDialog
def initialize(question)
#question = "#{question} (y/n)"
#answer = "".inquiry
end
def confirm!
prompt until (proceed? || abort?)
respond
proceed?
end
private
def prompt
STDOUT.puts #question
#answer = STDIN.gets.strip.downcase.inquiry
end
def respond
STDOUT.puts proceed? ? "Proceeding." : "Aborting."
end
def proceed?
#answer.y?
end
def abort?
#answer.n?
end
end
Then use it like so in your task:
next unless RakeConfirmDialog.new(
"About to close the Hellmouth forever. Are you sure you want 'Buffy the Vampire Slayer' to have a happy ending?"
).confirm!

Related

VBA macros for CATIA works on one computer, and doesn't work on another computer

I am not expert in Catia macros but I wrote one simple code and it works on my Catia but on other other computer it doesn't work.
The macro is about deleting deactivated bodies from the tree. PLEASE HELP. Here is the code:
Sub CATMain()
Set partDocument1 = CATIA.ActiveDocument
Set part1 = partDocument1.Part
'If Err.Number=0 Then
Dim selection1 'As Selection
Set selection1 = partDocument1.Selection
selection1.Search "CATPrtSearch.PartDesign Feature.Activity=FALSE"
'if no deactivated components then end program
If selection1.Count = 0 Then
MsgBox "No deactivated features."
Exit Sub
Else
'delete all deactivated components then update the part
selection1.Delete
part1.Update
End If
'error handling
'Else
' Msgbox "Not a part document! Open a single part document."
'End If
End Sub

Fish Shell: Conditional execution based on $status?

In the fish shell the syntax for conditionals is hard to find. Does anyone have a link to an explanation of how to write an if, with ands and ors?
In particular I would like to write
if not $status
do a command
end
To do a command when the previous command returned a non-success. How do I do that?
See http://fishshell.com/docs/current/commands.html#if and http://fishshell.com/docs/current/tutorial.html#tut_conditionals.
Fish's if structure looks like this:
if COMMAND
# do something if it succeeded
else
# do something if it failed ($status != 0)
end
Then there are also the not, and and or commands, that you can use like
if not COMMAND1; or COMMAND2
# and so on
If you really want to test a variable (e.g. $status), you need to use test as the command, like
if test $status -eq 0
Do keep in mind that $status changes after every command, so if you need to use the status of an earlier command (common in prompts) you need to do what Joachim Pileborg said, save it to another variable.
Also, test has some issues with quotes (because it's one of the few parts of fish to adhere to POSIX) - if in test $foo -eq 0 $foo is undefined, test will error out, and if it is undefined in test -n $foo, the test will be true (because POSIX demands that test with one argument be true).
As a sidenote, in fish versions before 2.3.0, you need to add begin and end around a condition with and or or because it was interpreted weirdly.
So you'd have to do
if begin COMMAND; or COMMAND2; end
# do something for status = 0
The shortest short form would be
the_previous_command; or do_a_command
# ..................^^^^^
Assuming you get your $status from "the_previous_command"
I use the status variable to display it on the prompt if it's non-zero. For that I use the following function:
function __pileon_status_prompt
set -l __status $status
if test $__status != 0
printf '[%s%s%s]' (set_color red) $__status (set_color normal)
end
end
As you can see I set a local variable to the value of $status and the check that variable in the condition.

What is the command and syntax for breaking/stopping a program in QBASIC?

I am currently writing a QBASIC program that runs an indefinite loop (while loop). However, if a certain condition is met, I want to exit the program. What command do I use, and also what is the syntax.
Thanks
ENDexits program, and clears all variables, which frees up memory.
STOPexits program, but retains the value of all variables, which makes it possible (in certain versions of QB) to continue execution at another point, by choosing Set next statement from the Debugmenu, and then Startfrom the Runmenu. END has the same effect as STOP + choosing Restart from the Runmenu once the program has terminated.
If you have a loop, and want to exit the program from inside it, you may use either
DO
IF condition THEN EXIT DO
LOOP
END
or
DO
IF condition THEN END
LOOP
You're looking for the END or SYSTEM statement. For example:
PRINT "Hello World!"
END
PRINT "This won't be printed."
If you're using regular old QBASIC/QuickBASIC, then you can ignore all of the QB64 details on the linked pages and just use either SYSTEM or END. Both will do the same thing for the most part.1
If you're using FreeBASIC, it's recommended to use END instead of SYSTEM since some things won't get cleaned up properly when you use SYSTEM. See SYSTEM for more information pertaining to FreeBASIC if that's what you're using.
1 The END statement when running the program using QB.EXE /RUN PROGRAM.BAS will print "Press any key to continue" before exiting to the QB/QBASIC environment. The SYSTEM statement when run the same way will simply return you to the DOS shell without any need for a key press. Also, typing SYSTEM in the "Immediate Window" of the QB/QBASIC environment will exit the environment and return to the DOS shell. Otherwise the two statements behave exactly the same in QB/QBASIC, whether for standalone (compiled) programs or .BAS modules.
You can keep any condition according to the need of your program. For eg:
CLS
LET a = 5
WHILE a > 0
PRINT a;
a = a - 1
WEND
END
Here, in the program while wends executes itself until a = 0. This will not run an infinite loop.
The answer is
exit();
to exit the program.

String inclusion in Fish Shell

I've looked at all the similar questions on Stack Overflow, and tried a bunch of stuff in their documentation. My present attempt is below.
What I'm trying to accomplish is differential behavior based on the computer user. I have a work computer and a home computer, and I want the work computer to go to a different directory when I enter "code" into the command line than the one I want when I enter it at home. I tried this (my work username is afk, home is sfk):
function code
set result (dirh)
if [contains "sfk" $result]
cd ~/rails
else if [contains "afk" $result]
cd ~/code
else
echo $result
end
end
Currently, this is griping that "Unknown command contains Users/sfk/.config/fish/" (My PWD is Users/sfk/.config/fish/ when I'm entering this). I think maybe contains is just for lists, but the docs aren't particularly clear about this? Any idea how I might do this?
EDIT
Just tried this, and while it no longer errors, it ends up in the else case, which it shouldn't, cause my user IS sfk, which IS included in the dirh string:
function code
set result (dirh)
if test (contains "sfk" $result)
cd ~/rails
else if test (contains "afk" $result)
cd ~/code
else
echo $result
end
end
As said above in the comments, that is the best solution for this specific use case. But to answer the question in case someone wants to do something else.
You are right about contains, that it does an exact match on list items. You could use the switch function instead. Which supports wild-card matching.
function code
set -l result (dirh)
switch $result
case '*sfk*'
cd ~/rails
case '*afk*'
cd ~/code
case '*'
echo $result
end
end

How to exit a matlab m-file (NOT the matlab itself) if the user enters bad inputs?

How to exit a matlab m-file (NOT the matlab itself) if the user enters bad inputs?
I know if a m-file goes wrong at run time we can press Ctrl-C to stop it. but I need a command to put it in my m-file to do so if something bad happens.
Please don't suggest 'exit' or 'quit' commands as they terminate the entire matlab and I don't want it.
I am not sure how you define "exit", but error seems to be the function you need.
y = input('Please input a non-negative number: ');
if(y<0)
error('input must be non-negative');
end
disp( sprintf('y=%f', y ) );
Hey I suppose you could use a try-catch combination to handle a somewhat unexpected error and do something about it.
As an example,
function [ output ] = test(input)
Bmat = [ 1 1 1 ] % Some matrix
try
input*B;
catch ME
disp(ME.message)
return; % This is the statement that exits your function
end
end
If you run
>> test([1 1 1])
It won't work since the variables 'input' and 'B' have mismatched inner dimensions, but the 'try' statement will throw an exception to 'catch', and do whatever you want from there. In this case, it will display an error message at the command line and exit the function.
The variable 'ME' here is just a MATLAB object for error handling, and ME.message stores a string containing the type of error the interpreter caught.
I just read your question again... I assume the command 'return' is probably what you are really after, you will be able use it to exit from any logic or loop statements, as well as functions.
You can read more about the 'return' command and error handling from the MATLAB documentation,
http://www.mathworks.com/access/helpdesk/help/techdoc/ref/return.html
You can just put a error command like error('bad user input') and it should stop the script.
Edit: alternatively, you could just refactor your code to not run unless you set the input flag to be true. Something like
inp = input('>', s)
if validateInput(inp)
%do you stuff here or call your main function
else
fprintf('Invalid input')
end