Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am interested in making a simple accounting style line calculator that allows me to interact with it something like this:

In[]:   4 + 5
Out[]:  9
In[]:   +3
Out[]:  12
In[]:   *2
Out[]:  24
In[]:   /4
Out[]:  6

In the front end, I can do this with:

$PreRead = (ReplaceAll[#, {"*" :> "% *", "+" :> "% +", "-" :> "% - ", 
 "/" :> "% /"}] &)

(And stop it by $PreRead =.) which works nicely, however I would like to use the numberpad, and the + key on the number pad starts a free form input.

So, I thought I'd be sneaky and open up a kernel window. Sadly, the above assignment of $PreRead doesn't seem to execute in the Kernel, even though it looks like the variable has been assigned properly.

I'm interested in why $PreRead isn't behaving the same in the Kernel window as it would in the FrontEnd, and it wouldn't hurt to know if it is possible to shut off the keymapping of the numberpad + key to free form input.

share|improve this question
    
$PreRead does not seem to work in a kernel window on mac, on versions 9.0.1 and 10.3. I guess it never worked in versions in between. – Jacob Akkerboom Nov 24 '15 at 13:30

This doesn't seem to work on Mac


You can check with $PreRead = Echo (or Print in case of V<10.3) that +1 returns RowBox[{+,1}] in FrontEnd and "+1" in Kernel.

So the solution is to use:

$PreRead = StringReplace[#, StartOfString ~~ op : "*" | "+" | "-" | "/" :> "%" <> op] &

enter image description here

share|improve this answer
    
Hmm, for me setting a value to $PreRead does nothing in the kernel. – Jacob Akkerboom Nov 24 '15 at 12:32
    
@JacobAkkerboom why you people are still using Macs? :P – Kuba Nov 24 '15 at 12:38
    
I would switch to windows, but the Timing is bad ;) – Jacob Akkerboom Nov 24 '15 at 12:40
    
@JacobAkkerboom I suppose that withput $PreRead you need to combine $Pre and $SyntaxHandler. Does $SyntaxHandler work for you e.g. when you type *1? – Kuba Nov 24 '15 at 13:48
    
ah yes, I had already checked $SyntaxHandler. That one does work. So you mean to cause a syntax error using $Pre? Ingenious, but quite hacky too :). – Jacob Akkerboom Nov 24 '15 at 14:03

My definition of $Pre does not work as intended.See also edits of this answer. I originally intended a solution similar to that in Kuba's answer. I got confused because $PreRead does not do anything for me in a kernel window, which also seems to be the case for the OP, but not for Kuba.

The kernel does not deal with boxes. In the front end $PreRead is applied to the boxes corresponding to the line (cell) that is evaluating. In the kernel there are no boxes, the inputted command is regarded as a string. $PreRead does not seem to do anything in a kernel window.

You can use $Pre instead. Possibly it is more convenient to parse strings, though here I will present a solution that is as close as possible to your original solution.

Note that your definition of $PreRead does not work as you report

$PreRead = (ReplaceAll[#, {"*" :> "% *", "+" :> "% +", "-" :> "% - ", 
     "/" :> "% /"}] &)
4 + 5
5+4 %3

I think the following is a correct definition.

myPreRead =
  ReplaceAll[#,
    {op : "*" | "+" | "-" | "/", sq___} :> {"%", op, sq}
    ] &;

Here is a definition of $Pre that let's myPreRead do the work all the work.

myPre =
 Function[
  expr,
  ToExpression[#, StandardForm] &@
   myPreRead@MakeBoxes@expr
  ,
  HoldAll
  ]

Examples

myPre[+1]
myPre[4+5]
% + 1
9
share|improve this answer
    
Thanks Jacob, for having a look at my problem here. Your function myPre doesn't seem to work as intended on the RPi version. If I do something like $Pre = ToString[#]& I would hope to capture the user input as a string; however it looks like *2 is parsed (and throws an error) prior to being converted to a string. – bobthechemist Nov 29 '15 at 17:27
    
@bobthechemist yes, you are right. I just tested if $PreRead works on a RPi, but apparently it doesn't. What you see in the answer is really an afterthought, when what I expected didn't work. Maybe I'll try to make something work using pipes. – Jacob Akkerboom Nov 30 '15 at 20:40

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.