8
$\begingroup$

I have defined a function as follows:

fDistance[pointA_, pointB_: {0, 0}, metric_: "taxi"] := 
 Module[{interval}, 
  If[metric == "taxi", 
   interval = 
    Abs[pointB[[1]] - pointA[[1]]] + Abs[pointB[[2]] - pointA[[2]]], 
   interval = 
    Sqrt[(pointB[[1]] - pointA[[1]])^2 + (pointB[[2]] - 
        pointA[[2]])^2]]; interval]

Then

fDistance[{3, 4}]
(*7; ok*)

fDistance[{3, 4}, {1, 2}, "euclid"]
(*2 Sqrt[2]; ok*)

But

fDistance[{3, 4}, "euclid"]
(*error message*)

How can I avoid that Mathematica assign the string literal 'euclid' to the variable pointB? It should have returned 5 as the output below shows

fDistance[{3, 4}, {0, 0}, "euclid"]
(*5*)

And as a second question: Is it possible to call the function in the following manner

fDistance[pointB={1, 2}, metric='normal', pointA={3, 4}]

that is, its arguments are paired with a keyword instead of being in the correct order according to the function denition?

Thank you very much.

$\endgroup$
12
$\begingroup$

You must add a restricting pattern to the second parameter. Define your function like this:

fDistance[pointA_, pointB : {_, _} : {0, 0}, metric_: "taxi"] := (* rest of code *)

fDistance[{3, 4}, "euclid"]
5

Recommended reading:


For your second point you should first familiarize yourself with:

Then return to the first link in this post for how this will relate to default arguments.

As a brief example of setting up your function to use only named options:

ClearAll[fDistance]

Options[fDistance] =
  {"pointA" -> {0, 0}, "pointB" -> {0, 0}, "metric" -> "taxi"};

fDistance[OptionsPattern[]] := Module[{pointA, pointB, metric},
  {pointA, pointB, metric} = OptionValue[{"pointA", "pointB", "metric"}];
  If[metric == "taxi", 
    Abs[pointB[[1]] - pointA[[1]]] + Abs[pointB[[2]] - pointA[[2]]], 
    Sqrt[(pointB[[1]] - pointA[[1]])^2 + (pointB[[2]] - pointA[[2]])^2]
  ]
]

fDistance[]
fDistance["pointA" -> {3, 4}]
fDistance["metric" -> "euclid", "pointA" -> {3, 4}]
0

7

5

This may also be of use and/or interest to you:

$\endgroup$
  • $\begingroup$ Thank you very much for your quick reply. Regarding the second question is it possible something like the following: fDistance[pointB={1, 2}, metric='normal', pointA={3, 4}] ? If yes how I should modify the definition of the function? $\endgroup$ – dimitris Feb 26 '17 at 0:34
  • $\begingroup$ @dimitris Sorry, I overlooked that in a hurry to answer. Yes, those are known as Options in Mathematica. Let me gather some links. $\endgroup$ – Mr.Wizard Feb 26 '17 at 0:36
  • $\begingroup$ No reason to apologize:-)! Take your time. Thanks also for the useful links. I think after almost 10 years I have to revisit verbeia.com/mathematica/tips/Tricks.html $\endgroup$ – dimitris Feb 26 '17 at 0:40
  • 1
    $\begingroup$ @dimitris In case you have somehow missed it be sure also to read: mathprogramming-intro.org/book/Book.html $\endgroup$ – Mr.Wizard Feb 26 '17 at 0:42
  • $\begingroup$ Definitely the Holy Grail of Mathematica Programming-)! $\endgroup$ – dimitris Feb 26 '17 at 0:46

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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