I have made a simple script application which accepts radius as input from user and calculates and displays area of circle based on input:
-- initializing radius variable to some text
set radius to "Some text"
repeat until class of radius is number
-- asking user for radius
display dialog "Enter radius: " default answer "" buttons {"Done"} default button 1
set userInput to text returned of result
-- try to check if user enters radius as number
try
-- converting input from user to number
set radius to userInput as number
-- if input is found as number then below code is executed
-- obtaining radius from handler
set circleArea to calculateCircleArea(radius)
-- displaying radius and area of circle obtained to user
display dialog "Circle area for radius: " & radius & " is: " & circleArea buttons {"OK"} default button 1
end try
end repeat
-- handler definition
on calculateCircleArea(parameterRadius)
set areaOfCircle to pi * (parameterRadius ^ 2)
end calculateCircleArea
When I executed the above script and entered some text for the first time, it again asked me to enter the radius, this time I entered some number and it displayed the area of circle but it again started asking for radius as input from user.
Can anyone suggest me where I am wrong in the above script?
Thanks,
Miraaj
repeat until class of radius is integer or class of radius is real
Related
i'm trying to make a Nurikabe puzzle with Ruby GTK and i'm having trouble creating button signals dynamically.
Basically, i have a matrix, some boxes have a number ( clicking them won't do anything), others can have one of 3 states (white, black or unplayed). The matrix can have different sizes so i did this :
def construction
# we get the width and height of the matrix
taille_hauteur = ##partie.grilleEnCours.hauteur
taille_largeur = ##partie.grilleEnCours.largeur
#boutons = {}
#We create a table which will include all of our buttons (one for each box of our matrix)
table = Table.new(taille_hauteur,taille_largeur,false)
# we go through our matrix
for i in 0..taille_largeur-1
for j in 0..taille_hauteur-1
# if the box has a number, we create a button with that number as a label
if ##partie.grilleEnCours.matriceCases[i][j].is_a?(CaseNombre)
# we add this button to a hash
#boutons[[i,j]] = Button.new(:label=> ##partie.grilleEnCours.matriceCases[i][j].to_s)
table.attach(#boutons[[i,j]], i, i+1, j, j+1)
else
# otherwise,we create and add a button to the hash without a label
#boutons[[i,j]] = Button.new()
# we create a signal, changing the state of the box of the matrix at the same coordinates as the button
#boutons[[i,j]].signal_connect('clicked'){
puts "#{i} #{j}"
# we change the box's state of the matrix
##partie.clicSurCase(i,j)
puts ##partie.grilleEnCours
# here we are just changing the label corresponding to the box's state
if(##partie.grilleEnCours.matriceCases[i][j].etat==0)
lab = ""
elsif (##partie.grilleEnCours.matriceCases[i][j].etat==1)
lab = "Noir"
else
lab = "Point"
end
#boutons[[i,j]].set_label(lab)
}
table.attach(#boutons[[i,j]], i, i+1, j, j+1)
end
end
end
#object.add(table)
end
The problem is, doing this, when we click any button, it will change the last box of the matrix and the last button's label (bottom right). I believe this is because Integers are objects in Ruby so clicking a button will change the box's state and button's state at the coordinates (i,j) (which are matrix height-1, matrix width-1) and not the values i and j had when we created the signal.
I have no idea how to link a button to a specific box of the matrix (knowing matrixes can have multiple sizes), could you help me on this one ?
It is quite hard to read such a large block of code - maybe start by chopping it into logic-based functions?
It will clear the code up.
you don't need to set "lab =" in each branch of if - just:
lab = if (i==1)
1
else
2
end
in additions - use "case" in this case. Once you split the code up - you will(probably) find the issue you have.
it will be easier to debbug.
I'm adding labels to a plot. I've followed this tutorial for moving label to best position with the mouse and was glad to discover label can be rewritten at mouse position.
But once it's done, I haven't found any way to get the text value of the label if one wants to move the label at a later time (if in need to adjust position more accurately when zooming say) without copying/pasting the label's text.
In the script, the text is entered and kept around, but I would like to move the label with its id only and get the text or any other way to move the label.
gnuplot> set label 1 "square" at 0,0
> show label
label 1 "square" at (0.00000, 0.00000, 0.00000)
> moveLabel(labelId, text) = sprintf('call "label_loop.gnu" "%s" "%d"', text, labelId)
> eval moveLabel(1, "square") -> should be: eval moveLabel(1)
'label_loop.gnu' for gnuplot-5.0 is the comment part.
Since you mention that you want to call the function just as eval moveLabel(1), I assume that the label has been previously set within your script using set label .... If this is the case, you could modify label_loop.gnu as:
#make sure that label_number is an integer and not a string so that
#it is not "misinterpreted" in "set label"
label_number = int(ARG1);
pause mouse any "adjust label"
#any other button will quit the loop
if( MOUSE_BUTTON == 1 ) {
#using ARG1 instead of label_number or int(ARG1) would
#create a new label with the content of ARG1 as its text
set label label_number at MOUSE_X,MOUSE_Y
print "\n moved label ".ARG1." to position: ",MOUSE_X,MOUSE_Y
replot
call 'label_loop.gnu' ARG1
}
and then use it from the main script for example as:
set term x11
set mouse
set label 1 "square" at 0,0
moveLabel(labelId) = sprintf('call "label_loop.gnu" "%d"', labelId)
plot x
eval moveLabel(1)
The "trick" here is that if you call the set label command without any text, Gnuplot just updates the position and keeps the text as it was...
What I'm trying to make is this:
set retry to true
repeat while retry is true
display dialog "In the next window you'll have to choose a color!" buttons {"Cancel", "COLORR!"} cancel button 1 default button 2
set Chosencolor1 to (choose color)
display dialog "The chosen color is: " & Chosencolor1 & " Is this right?" buttons {"NO", "YES"}
if the button returned of the result is "no" then
set retry to true
display dialog "Retry is now: " & retry
else
set retry to false
display dialog "Retry is now: " & retry
end if
end repeat
end
But when I run this code it will return a color code in numbers. But what I want is that it will return a color name like: light blue, blue, green etc.
The only way I know is to do something like:
if the chosencolor1 is "000" then
set the chosencolor1 to "Black"
end if
end
is there any other, more simple way to do this? Or is this just not possible?
Thanks for reading,
Jort
From the AppleScript Language Guide for choose color:
Result The selected color, represented as a list of three integers
from 0 to 65535 corresponding to the red, green, and blue components
of a color; for example, {0, 65535, 0} represents green.
As you have surmised, the only way to get a textual response is to program it yourself using the values of the list that your user chooses.
Here is a very simple example that adds all the values of the chosen RGB integers, and determines if it closer to black or white:
set myColor to choose color
display dialog ("You have chosen: " & my fetchColorName(myColor))
to fetchColorName(clst)
set totalColorValue to ((item 1 of clst) + (item 2 of clst) + (item 3 of clst))
set blackWhiteMidpoint to (196605 / 2)
if totalColorValue < blackWhiteMidpoint then
set colorName to "A color closer to black than white."
else
set colorName to "A color closer to white than black."
end if
return colorName
end fetchColorName
The first part of this script finds the art size and returns with the size in inches -
I want this to then ask what size to make the width then enter the number and have Illustrator scale the art to the width in the returned dialog.
I'm trying to figure out where the calculation is off here.
It seemed at first the scale percentage would be correct but to enlarge the
percentage must be over 100 % (i.e. 125% or 150% etc.)
I can't get the script to compile with an else between my if's so I'm sure I'm missing something here.
tell application "Adobe Illustrator"
activate
tell document 1
--define Spot1
set docColorSpace to color space
if (docColorSpace is CMYK) then
set SpotColor1 to {cyan:21.0, magenta:0, yellow:100.0, black:0.0}
else
set SpotColor1 to {red:206.0, green:219.0, blue:41.0}
end if
--color change first
set (path items whose fill color is not SpotColor1)'s fill color to SpotColor1
--get current size
set tempGroup to make new group item with properties {name:"TempGroup"} -- Create a temporary container group
duplicate every page item to beginning of group item "TempGroup" -- copy instances to it
set {w, h} to {width, height} of tempGroup -- get properties
delete tempGroup
display dialog "Width of Art: " & (w / 72) & return & "Height of Art: " & (h / 72)
--change to desired size PROBLEM SECTION
set newWidth to text returned of (display dialog "Please enter Art Width:" default answer "100")
tell application "Adobe Illustrator"
set artWidth to width of tempGroup
set sizeDifference to (newWidth / artWidth) * 100
try
if newWidth is equal to artWidth then
set scalePercentage to 100
end if
if newWidth is greater than artWidth then
set scalePercentage to (100 + sizeDifference)
end if
if newWidth is less than artWidth then
set scalePercentage to (100 - sizeDifference)
end if
end tell
end
I appreciate any suggestions. I realize javascript is probably the way to go with Illustrator
but am trying to saw my way through understanding some applescripts before moving on to something more advanced. Thanks in advance.
I found the answer after playing with the math.
The problem was Illustrator doesn't deal with inches only points
hence the (w/72) (h/72) portion when it gets the size.
72 points = 1 inch so the math had to convert points to inches.
like so
tell application "Adobe Illustrator"
activate
tell document 1
--get current size
set tempGroup to make new group item with properties {name:"TempGroup"} -- Create a temporary container group
duplicate every page item to beginning of group item "TempGroup" -- copy instances to it
set {w, h} to {width, height} of tempGroup -- get properties
delete tempGroup
display dialog "Width of Art: " & (w / 72) & return & "Height of Art: " & (h / 72)
--resize
set newWidth to text returned of (display dialog "Please enter Art Width:" default answer "10")
set artWidth to width of tempGroup
set sum to (artWidth / newWidth * 100)
set scalePercentage to (72 / sum * 10000)
scale tempGroup horizontal scale scalePercentage vertical scale scalePercentage
end tell
end tell
end
I have such code:
a=5;
b=a;
c=10;
u = (0:0.05*pi:2*pi)'; %'
v = [0:0.05*pi:2*pi];
X = a*sin(u)*cos(v);
Y = a*sin(u)*sin(v);
Z = c*cos(u)*ones(size(v));
Z(Z>0)=0; % cut upper
V1=4/3*pi*a*b*c;
d=1/2;
e=2^d;
a2=a/e;
b2=a/e;
c2=c;
V2=4/3*pi*a2*b2*c2;
X2 = a2*sin(u)*cos(v);%-2.5;
Y2 = b2*sin(u)*sin(v);
Z2 = c2*cos(u)*ones(size(v));%+0.25;
Z2(Z2>0)=0; % cut
h=1/3;
for j = 1:20
k1=(sin(pi*j/20)+0.5)^h;
a=a*k1;
c=c*k1;
X = a*sin(u)*cos(v);
Y = a*sin(u)*sin(v);
Z = c*cos(u)*ones(size(v));
Z(Z>0)=0;
a2=a2*k1;
b2=a2*k1;
c2=c2*k1;
X2 = a2*sin(u)*cos(v)+5;%-2.5;
Y2 = b2*sin(u)*sin(v);
Z2 = c2*cos(u)*ones(size(v));%+0.25;
Z2(Z2>0)=0;
hS1=surf(X,Y,Z);
alpha(.11)
hold on
hS2=surf(X2,Y2,Z2);
hold off
axis([-20 20 -20 20 -20 20]);
F(j) = getframe;
end
movie(F,4)
I have to input parameters a,b,c from the keyboard. I've made GUI & tried to do it by using "Edit text" with a function below, but it's not working((.
I can't understand what's the problem with it.
function a_edit_Callback(hObject, eventdata, handles)
user_entry = str2double(get(hObject,'string'));...
a=user_entry;
The problem is that your callback function executing your code is not 'seeing' the parameters you defined in your edit text callbacks. You need to establish your variables in the subfunction, since they aren't global.
Using guide, set up a uicontrol button to click when you've entered your parameters into your uicontrol edit text boxes. Under the callback of your button, place your above code, with the following at the top:
a=str2double(get(handles.a_edit,'String'));
b=str2double(get(handles.b_edit,'String'));
c=str2double(get(handles.c_edit,'String'));
This will pull in the current strings of your edit text uicontrols. (Assuming you've assigned the tag format x_edit for each of the edit text boxes in guide.)
EDIT:
Open the figure you already created with the edit text boxes. Next, check to make sure each of your text boxes have the tag a_edit, b_edit, c_edit by using the property inspector. Then create a button using guide, and open the property inspector by double clicking on it. Find the 'tag' field, and name it run. Save your figure, and open the corresponding M-file.
Next, find the line with run_Callback(hObject, eventdata, handles). Place the following under it:
a=str2double(get(handles.a_edit,'String'));
b=str2double(get(handles.b_edit,'String'));
c=str2double(get(handles.c_edit,'String'));
%# Add the rest of your code from above verbatim, minus the first three lines
This should be the ONLY code you add to the auto-generated M-file - don't mess with anything else until you get this much working. If you don't want the animation popping up randomly in your figure window, you can add a set of axes using guide as well.
From the looks of the code, it appears to be a 'script' and not a 'function'.
Did you just want a 'dialog (built-in GUI dialog)'? If so, you can add the following at the beginning of your script:
prompt = {'Enter the parameter value "a":','Enter the parameter value
"b":','Enter the parameter value "c":'};
dlg_title = 'Input the Parameter Values';
num_lines = 1;
def = {'5','5','10'};
answer = inputdlg(prompt,dlg_title,num_lines,def);
a=answer{1};a=str2double(a);
b=answer{2};b=str2double(b);
c=answer{3};c=str2double(c);
% Y.T.