Keep input from evaluating in a pop-up box? - wolfram-mathematica

I have the following mma code:
$ButtonOptions = {Method -> "Queued"};
Button["Get List of IDs",
ai = ToString#Input["Please Enter ID#s", {}];
ai = StringReplace["ai", "\[Times]" -> ","];
Print#ai,
Background -> Yellow, Sequence ## $ButtonOptions
]
I need users to input multiple ID numbers in those brackets when the input window pops up. They like to use Excel and paste in a column, but this results in a new paragraph for each ID number (which Mathematica converts to a space, and then to multiplication, and then it multiplies all the IDs together). I need some way to keep the input from evaluating when they enter it without having Hold actually show up in the input box so the StringReplace operation will work and get rid of all the line breaks before Mathematica multiplies the IDs together.

How about something using InputString?
Button["Get List of IDs",
ai = InputString["Please Enter ID#s", {}];
ai = DeleteCases[StringSplit[ai, WhitespaceCharacter | ","], ""];
Print[ai],
Method -> "Queued"]
Of course, you probably want to have more checks on the types of Ids. In the above code I used StringSplit to separate the string at spaces, tabs, newlines and commas - but this is probably a bit too simplistic and not robust enough for real life use.

Related

SPSS syntax for naming individual analyses in output file outline

I have created syntax in SPSS that gives me 90 separate iterations of general linear model, each with slightly different variations fixed factors and covariates. In the output file, they are all just named as "General Linear Model." I have to then manually rename each analysis in the output, and I want to find syntax that will add a more specific name to each result that will help me identify it out of the other 89 results (e.g. "General Linear Model - Males Only: Mean by Gender w/ Weight covariate").
This is an example of one analysis from the syntax:
USE ALL.
COMPUTE filter_$=(Muscle = "BICEPS" & Subj = "S1" & SMU = 1 ).
VARIABLE LABELS filter_$ 'Muscle = "BICEPS" & Subj = "S1" & SMU = 1 (FILTER)'.
VALUE LABELS filter_$ 0 'Not Selected' 1 'Selected'.
FORMATS filter_$ (f1.0). FILTER BY filter_$.
EXECUTE.
GLM Frequency_Wk6 Frequency_Wk9
Frequency_Wk12 Frequency_Wk16
Frequency_Wk20
/WSFACTOR=Time 5 Polynomial
/METHOD=SSTYPE(3)
/PLOT=PROFILE(Time)
/EMMEANS=TABLES(Time)
/CRITERIA=ALPHA(.05)
/WSDESIGN=Time.
I am looking for syntax to add to this that will name this analysis as: "S1, SMU1 BICEPS, GLM" Not to name the whole output file, but each analysis within the output so I don't have to do it one-by-one. I have over 200 iterations at times that come out in a single output file, and renaming them individually within the output file is taking too much time.
Making an assumption that you are exporting the models to Excel (please clarify otherwise).
There is an undocumented command (OUTPUT COMMENT TEXT) that you can utilize here, though there is also a custom extension TEXT also designed to achieve the same but that would need to be explicitly downloaded via:
Utilities-->Extension Bundles-->Download And Install Extension Bundles--->TEXT
You can use OUTPUT COMMENT TEXT to assign a title/descriptive text just before the output of the GLM model (in the example below I have used FREQUENCIES as an example).
get file="C:\Program Files\IBM\SPSS\Statistics\23\Samples\English\Employee data.sav".
oms /select all /if commands=['output comment' 'frequencies'] subtypes=['comment' 'frequencies']
/destination format=xlsx outfile='C:\Temp\ExportOutput.xlsx' /tag='ExportOutput'.
output comment text="##Model##: This is a long/descriptive title to help me identify the next model that is to be run - jobcat".
freq jobcat.
output comment text="##Model##: This is a long/descriptive title to help me identify the next model that is to be run - gender".
freq gender.
output comment text="##Model##: This is a long/descriptive title to help me identify the next model that is to be run - minority".
freq minority.
omsend tag=['ExportOutput'].
You could use TITLE command here also but it is limited to only 60 characters.
You would have to change the OMS tags appropriately if using TITLE or TEXT.
Edit:
Given the OP wants to actually add a title to the left hand pane in the output viewer, a solution for this is as follows (credit to Albert-Jan Roskam for the Python code):
First save the python file "editTitles.py" to a valid Python search path (for example (for me anyway): "C:\ProgramData\IBM\SPSS\Statistics\23\extensions")
#editTitles.py
import tempfile, os, sys
import SpssClient
def _titleToPane():
"""See titleToPane(). This function does the actual job"""
outputDoc = SpssClient.GetDesignatedOutputDoc()
outputItemList = outputDoc.GetOutputItems()
textFormat = SpssClient.DocExportFormat.SpssFormatText
filename = tempfile.mktemp() + ".txt"
for index in range(outputItemList.Size()):
outputItem = outputItemList.GetItemAt(index)
if outputItem.GetDescription() == u"Page Title":
outputItem.ExportToDocument(filename, textFormat)
with open(filename) as f:
outputItem.SetDescription(f.read().rstrip())
os.remove(filename)
return outputDoc
def titleToPane(spv=None):
"""Copy the contents of the TITLE command of the designated output document
to the left output viewer pane"""
try:
outputDoc = None
SpssClient.StartClient()
if spv:
SpssClient.OpenOutputDoc(spv)
outputDoc = _titleToPane()
if spv and outputDoc:
outputDoc.SaveAs(spv)
except:
print "Error filling TITLE in Output Viewer [%s]" % sys.exc_info()[1]
finally:
SpssClient.StopClient()
Re-start SPSS Statistics and run below as a test:
get file="C:\Program Files\IBM\SPSS\Statistics\23\Samples\English\Employee data.sav".
title="##Model##: jobcat".
freq jobcat.
title="##Model##: gender".
freq gender.
title="##Model##: minority".
freq minority.
begin program.
import editTitles
editTitles.titleToPane()
end program.
The TITLE command will initially add a title to main output viewer (right hand side) but then the python code will transfer that text to the left hand pane output tree structure. As mentioned already, note TITLE is capped to 60 characters only, a warning will be triggered to highlight this also.
This editTitles.py approach is the closest you are going to get to include a descriptive title to identify each model. To replace the actual title "General Linear Model." with a custom title would require scripting knowledge and would involve a lot more code. This is a simpler alternative approach. Python integration required for this to work.
Also consider using:
SPLIT FILE SEPARATE BY <list of filter variables>.
This will automatically produce filter labels in the left hand pane.
This is easy to use for mutually exclusive filters but even if you have overlapping filters you can re-run multiple times (and have filters applied to get as close to your desired set of results).
For example:
get file="C:\Program Files\IBM\SPSS\Statistics\23\Samples\English\Employee data.sav".
sort cases by jobcat minority.
split file separate by jobcat minority.
freq educ.
split file off.

How to program faster, (generate code from a pattern?)

I frequently run into problems that could be solved with automating code writing, but aren't long enough to justify it as tediously entering each piece is faster.
Here is an example:
Putting lists into dictionaries and things like this. Converting A into B.
A
hotdog HD
hamburger HB
hat H
B
def symbolizeType
case self.type
when "hotdog"
return "HD"
when "hamburger"
return "HB"
when "hat"
return "H"
end
Sure I could come up with something to do this automatically, but it would only make sense if the list was 100+ items long. For a list of 10-20 items, is there a better solution than tediously typing? This is a Ruby example, but I typically run into cases like this all the time. Instead of a case statement, maybe it's a dictionary, maybe it's a list, etc.
My current solution is a python template with the streaming input and output already in place, and I just have to write the parsing and output code. This is pretty good, but is there better? I feel like this would be something VIM macro would excel at, but I'm that experienced with VIM. Can VIM do this easily?
For vim, it'd be a macro running over a list of space separated pairs of words, inserting the first 'when "' bit, the long form word 'hotdog', the ending quote, a newline and 'return "', and then the abbreviation and then final quote, then going back to the list and repeating.
Starting with a register w of:
when "
register r of:
return "
an initial list of:
hotdog HD
hamburger HB
hat H
and a starting file of:
def symbolizeType
case self.type
"newline here"
you can use the following macro at the start of the initial list:
^"ayeeeb"byeo"wp"apa"^Mrb"j
where ^M is a newline.
I do this frequently, and I use a single register and a macro, so I'll share.
Simply pick a register, record your keystrokes, and then replay your keystrokes from the register.
This is a long explanation, but the process is extremely simple and intuitive.
Here are the steps that I would take:
A. The starting text
hotdog HD
hamburger HB
hat H
B. Insert the initial, non-repetitive lines preceding the text to transform
def symbolizeType
case self.type
hotdog HD
hamburger HB
hat H
C. Transform the first line, while recording your keystrokes in a macro
This step I'll write out in detailed sub-steps.
Place the cursor on the first line to transform ("hotdog") and type qa to begin recording your keystrokes as a macro into register a.
Type ^ to move the cursor to the start of the line
Type like you normally would to transform the line to what you want, which for me comes out looking like the following macro
^i^Iwhen "^[ea"^[ldwi^M^Ireturn "^[ea"^[j
Where ^I is Tab, ^[ is Esc, and ^M is Enter.
After the line is transformed to your liking, move your cursor to the next line that you want to transform. You can see this in the macro above with the final j at the end.
This will allow you to automatically repeat the macro while it cycles through each repetitive line.
Stop recording the macro by typing q again.
You can then replay the macro from register a as many times as you like using a standard vim count prefix, in this case two consecutive times starting from the next line to transform.
2#a
This gives the following text
def symbolizeType
case self.type
when "hotdog"
return "HD"
when "hamburger"
return "HB"
when "hat"
return "H"
D. Finally, insert the ending non-repetitive text
def symbolizeType
case self.type
when "hotdog"
return "HD"
when "hamburger"
return "HB"
when "hat"
return "H"
end
Final Comments
This works very quick for any random, repetitive text, and I find it very fluent.
Simply pick a register, record your keystrokes, and then replay your keystrokes from the register.
For things like this I have a few ways of making it easier. One is to use an editor like Sublime Text that allows you to multi-edit a number of things at once, so you can throw in markup with a few keystrokes and convert that into a Hash like:
NAME_TO_CODE = {
hotdog: 'HD',
hamburger: 'HB',
hat: 'H'
}
Not really a whole lot changed there. Your function looks like:
def symbolize_type(type)
NAME_TO_CODE[type.to_sym]
end
Defining this as a data structure has the bonus of being able to manipulate it:
CODE_TO_NAME = NAME_TO_CODE.invert
Now you can do this:
def unsymbolize_type(symbol)
CODE_TO_NAME[symbol.to_s]
end
You can also get super lazy and just parse it on the fly:
NAME_TO_CODE = Hash[%w[
hotdog HD
hamburger HB
hat H
].each_slice(2).to_a]
snippets are like the built-in :abbreviate on steroids, usually with parameter insertions, mirroring, and multiple stops inside them. One of the first, very famous (and still widely used) Vim plugins is snipMate (inspired by the TextMate editor); unfortunately, it's not maintained any more; though there is a fork. A modern alternative (that requires Python though) is UltiSnips. There are more, see this list on the Vim Tips Wiki.
There are three things to evaluate: First, the features of the snippet engine itself, second, the quality and breadth of snippets provided by the author or others; third, how easy it is to add new snippets.

Import Subtitles in Processing

I am working on this sketch on Processing which gets the videofeed from my webcam/smartphone and shows it when running. I want to import an .srt converted to txt subtitles file from a film to it. I can see that the text file has all these numbers that stand for the start and end subtitle frame before the actual text.
Here's an example:
{9232}{9331}Those swings are dangerous.|Stay off there. I haven't fixed them yet.
{9333}{9374}I think you're gonna live.
What I would like to do is to figure outa code that will
use the numbers and set them as start/end frames to run at the right time as in the film
display the subtitles
figure out how the '|'sign can be used as a symbol to trigger in the script the change of line.
I guess that might already be quite complicated but I just wanted to check whether someone has done anything similar in the past..
I guess what I want to do is save me from doing the whole
if ((current_frame > 9232) && ((current_frame < 9331)) {
text("Those swings are dangerous.", 200, 500/2);
text("Stay off there. I haven't fixed them yet..", 200, (500/2 + 35));
}
thing for each subtitle...
I am quite new to processing so not that familiar with many commands apart from 'for' and 'if', a newbie at importing .txt files and an ignoramus in working with arrays. But I really want to find a nice way in the last two bits..
Any help in any form will be greatly appreciated :)
Cheers,
George
For displaying the appropriate subtitle, you could do something like the following (explanation below, sorry in advance for the wall of text):
String[] subtitles = loadStrings("subtitles.txt");
int currentFrame = 0;
int subtitleIndex = -1;
int startFrame = -1, endFrame = -1;
int fontSize = 10; //change to suit your taste
String[] currentSubtitle;
...
//draw loop start:
//video drawing code goes here
if(currentFrame > endFrame){ //update which subtitle is now/next
subtitleIndex++;
startFrame = int(subtitles[subtitleIndex].split("\\}\\{")[0].substring(1));
endFrame = int(subtitles[subtitleIndex].split("\\}\\{")[1].split("\\}")[0]);
currentSubtitle = subtitles[subtitleIndex].split("\\}")[2].split("\\|");
}
if(currentFrame >= startFrame && currentFrame <= endFrame){
for(int i = 0; i < currentSubtitle.length; i++){
text(currentSubtitle[i], width/2, height - fontSize * (currentSubtitle.length - i));
}
}
currentFrame++;
//draw loop end
Probably that looks pretty intimidating to you, so here's some walk-through commentary. Your program will be a type of state machine. It will either be in the state of displaying a subtitle, or not. We'll keep this in mind later when we're designing the code. First, you need to declare and initialize your variables.
The first line uses the loadStrings() function, which reads through a text file and returns a String array where each element in the array is a line in the file. Of course, you'll need to change the filename to fit your file.
Your code uses a variable called current_frame, which is a very good idea, but I've renamed it to currentFrame to fit the java coding convention. We'll start at zero, and later on our code will increment it on every frame display. This variable will tell us where we are in the subtitle sequence and which message should be displayed (if any).
Because the information for what frame each subtitle starts and ends on is encoded in a string, it's a bit tricky to incorporate it into the code. For now, let's just create some variables that represent when the "current" subtitle-- the subtitle that we're either currently displaying or will be displaying next-- starts and ends. We'll also create an index to keep track of which element in the subtitles array is the "current" subtitle. These variables all start at -1, which may seem a bit odd. Whereas we initialized currentFrame to 0, these don't really have a real "initial" value, at least not for now. If we chose 0, then that's not really true, because the first subtitle may not (probably doesn't) begin and end at frame 0, and any other positive number doesn't make much sense. -1 is often used as a dummy index that will be replaced before the variable actually gets used, so we'll do that here, too.
Now for the final variable: currentSubtitle. The immediate thought would be to have this be a plain String, not a String array. However, because each subtitle may need to be split on the pipe (|) symbols, each subtitle may actually represent several lines of text, so we'll create an array just to be safe. It's possible that some subtitles may be a single-element array, but that's fine.
Now for the hard part!
Presumably, your code will have some sort of loop in it, where on each iteration the pertinent video frame is drawn to the screen and (if the conditions are met), the subtitle is drawn over top of it. I've left out the video portion, as that's not part of your question.
Before we do anything else, we need to remember that some of our variables don't have real values yet-- all those -1s from before need to be set to something. The basic logic of the drawing loop is 1) figure out if a subtitle needs to be drawn, and if so, draw it, and 2) figure out if the "current" subtitle needs to be moved to the next one in the array. Let's do #2 first, because on the first time through the loop, we don't know anything about it yet! The criterion (in general) for moving to the next subtitle is if we're past the end of the current one : currentFrame > endFrame. If that is true, then we need to shift all of our variables to the next subtitle. subtitleIndex is easy, we just add one and done. The rest are... not as easy. I know it looks disgusting, but I'll talk about that at the end so as to not break the flow. Skip ahead to the bottom if you just can't wait :)
After (if necessary) changing all of the variables so that they're relevant to the current subtitle, we need to do some actual displaying. The second if statement checks to see if we're "inside" the frame-boundaries of the current subtitle. Because the currentSubtitle variable can either refer to the subtitle that needs to be displayed RIGHT NOW, or merely just the next one in the sequence, we need to do some checking to determine which one it is for this frame. That's the second if statement-- if we're past the start and before the end, then we should be displaying the subtitle! Recall that our currentSubtitle variable is an array, so we can't just display it directly. We'll need to loop through it and display each element on a separate line. You mentioned the text() command, so I won't go too in depth here. The tricky bit is the y-coordinate of the text, since it's supposed to be on multiple lines. We want the first element to be above the second, which is above the third, etc. To do that, we'll have the y-coordinate depend on which element we're on, marked by i. We can scale the difference between lines by changing the value of fontSize; that'll just be up to your taste. Know that the number you set it to will be equal to the height of a line in pixels.
Now for the messy bit that I didn't want to explain above. This code depends on String's split() method, which is performed on the string that you want split and takes a string as a parameter that instructs it how to split the string-- a regex. To get the startFrame out of a subtitle line in the file, we need to split it along the curly braces, because those are the dividers between the numbers. First, we'll split the string everywhere that "}{" occurs-- right after the first number (and right before the second). Because split() returns an array, we can reference a single string from it using an index between square braces. We know that the first number will be in the first string return by splitting on "}{", so we'll use index 0. This will return (for example) "{1234", because split() removes the thing you're splitting on. Now we need to just take the substring that occurs after the first character, convert it to an int using int(), and we're done!
For the second number, we can take a similar approach. Let's split on "}{" again, only we'll take the second (index 1) element in the returned array this time. Now, we have something like "9331}Those swings are dang...", which we can split again on "}", choose the first string of that array, convert to int, and we're done! In both of these cases, we're using subtitles[subtitleIndex] as the original String, which represents the raw input of the file that we loaded using loadStrings() at the beginning. Note that during all this splitting, the original string in subtitles is never changed-- split(), substring(), etc only return new sequences and don't modify the string you called it on.
I'll leave it to you to figure out how the last line in that sequence works :)
Finally, you'll see that there are a bunch of backslashes cluttering up the split() calls. This is because split() takes in a regex, not a simple string. Regexs use a lot of special notation which I won't get into here, but if you just passed split() something like "}{", it would try to interpret it and it would not behave as expected. You need to escape the characters, telling split() that you don't want them to be interpreted as special and you just want the characters themselves. To do that, you use a backlash before any character that needs to be escaped. However, the backslash itself is yet another special character, so you need to escape it, too! This results in stuff like "\\{" -- the first backslash escapes the second one, which escapes whatever the third character is. Note that the | character also needs to be escaped.
Sorry for the wall of text! It's nice to see questions asked intelligently and politely, so I thought I'd give a good answer in return.

Java applet - Real-time textfield input verification

I'm trying to develop an input real-time verification on a textfield in a Java applet.
The idea would be to have an input field that, if empty, once the user clicks in it it would show something like "0,00". Once the user starts to press the keys, only numbers should be accepted, and it would start to fill the text like this (imagine I input the numbers:
1,2,3,4,5,6):
"0,01" -> "0,12" -> "1,23" -> "12,34" -> "123,45" -> "1.234,56".
If the field is not empty the user can change the values but there will always be a "," dividing the decimal numbers.
I've been able to allow only numbers to be accepted but how can produce this kind of behavior? I know this may be a very specific question but any links or examples would be much appreciated. Thank you.
You will have to provide an input handler, that not only filters the input, but also calls a preset callback (made by you), that will update the required field in the way you want it to be updated.
You can use some functions, that can format numbers, given a specific format.
Basically, just keep a count on number of digits, already input, then parse it as a plain integer then multiply it by a power of 10, derived from the format, in your example would be something like 10 raised to the power of (numberOfInputDigits -2).

Have problems designing input and output for a calculator app

I am writing a button calculator. I have the code split into model, view and a controller. The model knows nothing about formatting, it is only concerned with numbers. All formatting is done in the view. The model gets its input as keypresses, each keypress is a part of an enum:
typedef enum {
kButtonUnknown = 0,
kButtonMemoryClear = 100,
kButtonMemoryPlus = 112,
kButtonMemoryMinus = 109,
kButtonMemoryRecall = 114,
kButtonClear = 99,
…
};
When the user presses a button (say 1), the model receives a button code (kButtonNum1), adds the corresponding number to a string input buffer ("1") and updates the numeric output value (1.0). The controller then passes the numeric output value to the view that formats it (1).
This is all plain, simple and clean, but does not really work. The problem is that when user enters a part of a number (say 0.00, going to enter 0.001), the input does not survive the way through model to view and the display says 0 instead of 0.00. I know why this happens ("0.00"::string parses to 0::double and that gets formatted as 0). What I don’t know is how to design the calculator so that the code stays clean and simple and the numbers will show up on screen exactly as the user types them.
I’ve already come with some kind of solution, but that’s essentially a hack and breaks the beautiful and simple flow from the calculator model to the display.
Ideas?
Current solution keeps track of the calculator state. If the calculator is building a number, I take the calculator input buffer (a string) and directly set the display contents (also a string). Otherwise I take the proper path, ie. take the numeric calculator output, pass it to the view as a double and the view uses its internal formatter to create a string for the display. Example input:
input | display | mode
------+---------+------------
0 | 0 | from string
0. | 0. | from string
0.0 | 0.0 | from string
0.0+ | 0 | from number
This is ugly. (1) The calculator has to expose its input buffer and state. (2) The view has to expose its display and allow setting its contents directly using a string. (3) I have to duplicate some of the formatting code to format the string I got from the calculator input buffer. If user enters 12345.000, I have to display 12,345.000 and therefore I’ve got to have a commification code for strings. Yuck.
On my calculator (HP48SX) the numbers in the display are formatted according to the settings for displaying numbers. Right now, if I enter 0.00 (or any variant thereof) it is displayed as 0.0000. Perhaps you could separate display (ie formatting) from internal number representation ? In terms of MVC I guess that this would be implemented as state in the C.
EDIT in response to OP's comment. I don't fully understand the limitations of what you call a button calculator so you're on your own there. As for separation, I would design the calculator such that:
Model is always working with whatever you use for representing numbers: floats, doubles, decimals, what-have-you.
View is always working with strings which present numbers nicely and allow users to enter as they wish.
Controller translates from string to number, from number to string. In my original suggestion I envisaged that Controller itself would be stateful (storing current-numeric-format for example) and be addressable from the buttons. But you seem to have ruled that out.
Your problem, as I see it, is that if you don't store this state somewhere then you have no way of telling the calculator to use anything other than a fixed* format for displaying any number entered. By fixed* I mean a very limited form of flexibility, such as always displaying the number of decimal digits that were in the most recently entered number, rather than absolutely fixed such as 12 digits, no more and no less.
At last I’ve found a nicer solution. I have added an inputHint property to the formatter object that takes care of the output formatting in the view. This input hint receives the value of the calculator input buffer and affects the formatting. If there is a decimal dot in the input hint, the formatter is forced to always keep the decimal dot in output, therefore solving the case of "0." being formatted as "0". And if the input contains some fraction digits, the formatter is forced to keep the same number of fraction digits in output (solves the case of "0.00" being formatted as "0").
I still have to expose the calculator input buffer and state, but I don’t have to expose the view’s display as string and don’t have to maintain the duplicate formatting code path for strings.

Resources