Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

This is a prototype of a grading scheme. In reality it is bigger. The 10 pts in initPtsPartA comes from the school.

The output cell should be deployed as a CDF file for the teacher. The teacher enters the points of the students and get a final mark.

I have two questions.

1) How can I limit the InputField to allow for integer numbers between 0 and 10? If I enter anything else, say a negative number or a symbol, it should be cleared automatically.

2) In the Code Snippet section "Why don't the calculations work?" you see expressions with Dynamic variables which I need to work with. What is wrong? What is the solution?

DynamicModule[{
  mark4 = 1/3, mark3 = 0.51, mark2 = 0.68, mark1 = 0.80,
  initPtsPartA = {{10, 8, 10, 6}, {10, 5, 10, 5}, {10, 7, 10, 1}},
  initPtsStudent, initPtsSchool, initPtsPartSum, numTable, 
  SchoolAPts, StudentAPts, StudentMinAchieved
  }, 

 numTable[x_, y_ /; OddQ[y]] := initPtsPartA[[x, y]];
 numTable[x_, y_ /; EvenQ[y]] := InputField[Dynamic@initPtsPartA[[x, y]],
   Number, ContinuousAction -> True, FieldSize -> 1];

 initPtsPartSum[x_, y_, col_] := Dynamic@Total[initPtsPartA[[x ;; y, col]]];

 SchoolAPts = (Total[initPtsPartA[[1 ;; 3, #]]] &) /@ {1, 3};
 StudentAPts = (initPtsPartSum[1, 3, #] &) /@ {2, 4};

(* CODE SNIPPET, part of a longer program with `Graphics` involved. *)

Column[{Grid[
    Append[ Array[numTable, {3, 4}], (initPtsPartSum[1, 3, #] &) /@ 
      Range[4]]],

   {"Just Testing Values:", initPtsPartSum[1, 3, 1], 
    initPtsPartSum[1, 3, 2], initPtsPartSum[1, 3, 3], 
    initPtsPartSum[1, 3, 4], "Student Pts only:", StudentAPts},

   {"Why don't the calculations work?", 
    Dynamic[5*initPtsPartSum[1, 3, 2] + 10],   
    Dynamic[initPtsPartSum[1, 3, 4] > 30], 
    Dynamic[ Total[(initPtsPartSum[1, 3, #] &) /@ Range[4]]  ], 
    Dynamic[(Total@StudentAPts)]/(Total@SchoolAPts)},

   {"Why don't the calculations work?", 
    StudentMinAchieved = 
     Dynamic[(StudentAPts[[1]]/SchoolAPts[[1]] > 
         mark4) && (StudentAPts[[2]]/SchoolAPts[[2]] > mark4)]}
   }]
 ]
share|improve this question

1 Answer 1

  1. Use something like

    SetAttributes[restrictedInputField, HoldFirst];
    restrictedInputField[expr_] := 
       InputField[Dynamic[expr, (If[0 <= # < 10, expr = #] &)], Number, FieldSize -> 1];
    

    and do not use ContinuousAction -> True (if there is a way to make it work with it, I don't know it). Your code will then look like:

    numTable[x_, y_ /; EvenQ[y]] := 
       restrictedInputField[initPtsPartA[[x, y]]];
    

    and you can make restrictedInputField also local to your DynamicModule. The price to pay is that the input gets updated only after either Enter is perssed (after the number is typed in), or the focus leaves the input field. To my mind, this is acceptable, but of course you may have different opinion.

  2. Do not use Dynamic in

    initPtsPartSum[x_, y_, col_] := Dynamic@Total[initPtsPartA[[x ;; y, col]]];
    

    instead, use simply:

    initPtsPartSum[x_, y_, col_] := Total[initPtsPartA[[x ;; y, col]]];
    

    By wrapping Dynamic around it, you prevent any arithmetic with it, since the Dynamic wrapper stays wrapped around your expression in all arithmetic etc operations you perform later.

share|improve this answer
    
What is the issue with ContinuousAction->True Leonid? –  Rojo Nov 24 '12 at 20:28
    
@Rojo I don't know, it just didn't work for me. When enabled in my version of the code, it prevented me from changing the original value in an input field. I did not look very hard at it though, perhaps I overlooked something obvious. –  Leonid Shifrin Nov 24 '12 at 21:14
1  
Oh, well, you can't delete because when you delete the value it becomes Null (which is allowed even when you only allow Number) and Null isn't 0 <= # < 10 &. But allowing for Null fixes it in my machine. Also, you could select the digit before typing the new one so you don't go through Null –  Rojo Nov 24 '12 at 21:48
    
@Rojo Good point, thanks. I will edit the post some time soon to incorporate this. –  Leonid Shifrin Nov 25 '12 at 12:16
    
@LeonidShifrin I think I got the solution to the InputField problem. Please try InputField[Dynamic[x, If[0 <= # <= 12, x = #, Null] &], Number, ContinuousAction -> True, FieldSize -> 2] and in an extra input cell Dynamic@x Use always tab to edit the input field. Entering 22 makes Dynamic x to 2, a value which does not destroy some lines down in my code. –  Reinhard Simonovits Nov 27 '12 at 15:10

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.