MathGroup Archive 2005

[Date Index] [Thread Index] [Author Index]

Search the Archive

'Good' or 'Proper' Mathematica coding habits question

  • To: mathgroup at smc.vnet.net
  • Subject: [mg62028] 'Good' or 'Proper' Mathematica coding habits question
  • From: "Matt" <anonmous69 at netscape.net>
  • Date: Wed, 9 Nov 2005 03:46:04 -0500 (EST)
  • Sender: owner-wri-mathgroup at wolfram.com

Hello,
  Due to the great help I've received from here, I've made limited
progress with Mathematica.  As I continue my journey, I am trying to adopt the
philosophy:  "When working with Mathematica, shy away from your long-learned
habits of using loops, and instead try a functional or rule-based
approach."  To this end, I have coded up a few functions, which I'd
appreciate any feedback on, as to whether I'm breaking an inviolate
rule of Mathematica, or I'm using an egregious memory model, I'm duplicating
some functionality that already exists in Mathematica proper, etc.  Please bear
in mind that I am by training and thought process an assembly and C/C++
developer that worries about details such as whether to use
post-increment or post-increment when dealing with objects due to the
unnecessary construction of temporary objects on the stack.  I want to
learn good Mathematica habits from the get-go.

Here are the functions with short explanations for each:

Cell[TextData[{
  "extractNthElementFromEachSublistOfList takes as its first argument \
a list of lists, e.g. of the form {{",
  Cell[BoxData[
      FormBox[
        SubscriptBox["l", "x"], TraditionalForm]]],
  ", ",
  Cell[BoxData[
      FormBox[
        SubscriptBox["l", "y"], TraditionalForm]]],
  "}, {",
  Cell[BoxData[
      FormBox[
        SubscriptBox["l", "x"], TraditionalForm]]],
  ", ",
  Cell[BoxData[
      FormBox[
        SubscriptBox["l", "y"], TraditionalForm]]],
  "}, {",
  Cell[BoxData[
      FormBox[
        SubscriptBox["l", "x"], TraditionalForm]]],
  ", ",
  Cell[BoxData[
      FormBox[
        SubscriptBox["l", "y"], TraditionalForm]]],
  "}, {",
  Cell[BoxData[
      FormBox[
        SubscriptBox["l", "x"], TraditionalForm]]],
  ", ",
  Cell[BoxData[
      FormBox[
        SubscriptBox["l", "y"], TraditionalForm]]],
  "}} where each x and y subscript could denote any positive integer \
values to select from the set defined by 'l', and where 'l' could be \
an atomic object, or it could be itself an object with a head of List \
and an integer that specifies which element from each sublist to add \
to a list.  This function will extract the nth element from each \
sublist of the input list and place it into a list and then return \
the flattened version of that list"
}], "Text"]

Cell[BoxData[{
    RowBox[{
      RowBox[{"Clear", "[",
        RowBox[{
        "extractNthElementFromEachSublistOfList", ",", "testRun"}],
        "]"}], ";"}], "\[IndentingNewLine]",
    RowBox[{
      RowBox[{
        RowBox[{"extractNthElementFromEachSublistOfList", "[",
          RowBox[{"x_List", ",", "index_Integer", ",",
            RowBox[{"debugOn", ":",
              RowBox[{
                RowBox[{"(",
                  RowBox[{"_", "?",
                    RowBox[{"(",
                      RowBox[{
                        RowBox[{
                        "#", " ", "\[Element]", " ", "Booleans"}],
                        " ", "&"}], ")"}]}], ")"}], ":",
                "False"}]}]}], "]"}], " ", ":=", " ",
        RowBox[{"Module", "[", "\[IndentingNewLine]",
          RowBox[{
            RowBox[{"{",
              RowBox[{
                RowBox[{"tempList", " ", "=", " ",
                  RowBox[{"{", "}"}]}], ",", "error", ",",
                RowBox[{"noError", "=", "True"}], ",", "ret"}], "}"}],
             ",", "\[IndentingNewLine]",
            RowBox[{
              RowBox[{"If", "[",
                RowBox[{
                  RowBox[{"debugOn", " ", "\[Equal]", " ", "True"}],
                  ",", "\[IndentingNewLine]",
                  RowBox[{"error", "=",
                    RowBox[{"Catch", "[",
                      RowBox[{
                        RowBox[{
                          RowBox[{"(",
                            RowBox[{
                              RowBox[{"If", "[",
                                RowBox[{
                                  RowBox[{"(",
                                    RowBox[{
                                      RowBox[{"bool", " ", "=", " ",
                                        RowBox[{
                                        RowBox[{
                                        "Length", "[", "#", "]"}],
                                        " ", "<", " ",
                                        RowBox[{
                                        "Abs", "[", "index",
                                        "]"}]}]}], ";",
                                      RowBox[{"Print", "[",
                                        RowBox[{
                                        "\"\<bool = \>\"", ",",
                                        "bool"}], "]"}], ";",
                                      "bool"}], ")"}], ",",
                                  RowBox[{
                                    RowBox[{"noError", "=", "False"}],
                                     ";",
                                    RowBox[{
                                    "Throw", "[", "#", "]"}]}]}],
                                "]"}], ";",
                              RowBox[{"tempList", " ", "=", "  ",
                                RowBox[{"{",
                                  RowBox[{"tempList", ",",
                                    RowBox[{"#", "[",
                                      RowBox[{"[", "index", "]"}],
                                      "]"}]}], "}"}]}]}], ")"}], " ",
                          "&"}], " ", "/@", " ", "x"}], "]"}]}], ",",
                  "\[IndentingNewLine]",
                  RowBox[{"error", "=", "\[IndentingNewLine]",
                    RowBox[{"Catch", "[",
                      RowBox[{
                        RowBox[{
                          RowBox[{"(",
                            RowBox[{
                              RowBox[{"If", "[",
                                RowBox[{
                                  RowBox[{
                                    RowBox[{"Length", "[", "#", "]"}],
                                     " ", "<", " ",
                                    RowBox[{
                                    "Abs", "[", "index", "]"}]}], ",",

                                  RowBox[{
                                    RowBox[{"noError", "=", "False"}],
                                     ";",
                                    RowBox[{
                                    "Throw", "[", "#", "]"}]}]}],
                                "]"}], ";",
                              RowBox[{"tempList", " ", "=", "  ",
                                RowBox[{"{",
                                  RowBox[{"tempList", ",",
                                    RowBox[{"#", "[",
                                      RowBox[{"[", "index", "]"}],
                                      "]"}]}], "}"}]}]}], ")"}], " ",
                          "&"}], " ", "/@", " ", "x"}], "]"}]}]}],
                "\[IndentingNewLine]", "]"}], ";",
              "\[IndentingNewLine]",
              RowBox[{"If", "[",
                RowBox[{
                  RowBox[{"noError", "\[Equal]", "False"}], ",",
                  "\[IndentingNewLine]",
                  RowBox[{"ret", " ", "=", " ",
                    RowBox[{"\"\<An index of \>\"", "<>", " ",
                      RowBox[{"ToString", "[", "index", "]"}], "<>",
                      "\"\< is out of bounds for sublist \>\"", "<>",

                      RowBox[{"ToString", "[", "error", "]"}]}]}],
                  ",", "\[IndentingNewLine]",
                  RowBox[{"ret", " ", "=",
                    RowBox[{"Flatten", "[", "tempList", "]"}]}]}],
                "]"}], ";", "\[IndentingNewLine]", "ret"}]}],
          "\[IndentingNewLine]", "]"}]}],
      ";"}], "\[IndentingNewLine]",
    RowBox[{
      RowBox[{
        RowBox[{"testRun", "[",
          RowBox[{"debugOn", ":",
            RowBox[{
              RowBox[{"(",
                RowBox[{"_", "?",
                  RowBox[{"(",
                    RowBox[{
                      RowBox[{
                      "#", " ", "\[Element]", " ", "Booleans"}], " ",
                      "&"}], ")"}]}], ")"}], ":", "False"}]}], "]"}],
        ":=",
        RowBox[{"Module", "[",
          RowBox[{
            RowBox[{"{",
              RowBox[{
                RowBox[{"testList", " ", "=", " ",
                  RowBox[{"{",
                    RowBox[{
                      RowBox[{"{",
                        RowBox[{"1", ",", "2"}], "}"}], ",", " ",
                      RowBox[{"{",
                        RowBox[{"1", ",", "3"}], "}"}], ",", " ",
                      RowBox[{"{",
                        RowBox[{"1", ",", "4"}], "}"}], ",", " ",
                      RowBox[{"{",
                        RowBox[{"1", ",", "5"}], "}"}], ",", " ",
                      RowBox[{"{",
                        RowBox[{"1", ",", "6"}], "}"}]}], "}"}]}],
                ",",
                RowBox[{"unaryList", "=",
                  RowBox[{"{",
                    RowBox[{
                    "1", ",", "2", ",", "3", ",", "4", ",", "5", ",",
                      "6"}], "}"}]}]}], "}"}], ",",
            "\[IndentingNewLine]",
            RowBox[{
              RowBox[{"Print", "[",
                RowBox[{
                "extractNthElementFromEachSublistOfList", "[",
                  RowBox[{"testList", ",", "1", ",", "debugOn"}],
                  "]"}], "]"}], ";", "\[IndentingNewLine]",
              RowBox[{"Print", "[",
                RowBox[{
                "extractNthElementFromEachSublistOfList", "[",
                  RowBox[{"testList", ",",
                    RowBox[{"-", "2"}], ",", "debugOn"}], "]"}],
                "]"}], ";",
              RowBox[{"(*",
                RowBox[{
                "this", " ", "is", " ", "equivalent", " ", "to", " ",
                  "using", " ", "an", " ", "index", " ",
                  RowBox[{"of", " ", "'"}],
                  RowBox[{"1", "'"}]}], "*)"}], "\[IndentingNewLine]",

              RowBox[{"Print", "[",
                RowBox[{
                "extractNthElementFromEachSublistOfList", "[",
                  RowBox[{"testList", ",", "2", ",", "debugOn"}],
                  "]"}], "]"}], ";"}]}], "\[IndentingNewLine]",
          "]"}]}], ";"}], "\[IndentingNewLine]",
    RowBox[{"testRun", "[", "]"}]}], "Input"]

Cell["\<\
findLeastOrGreatest is used to find within a given list of lists the \
least or greatest value in a column dictated by pos.  Whether the \
least or greatest is determined is controlled by an optional \
parameter, 'greaterThan', which if given explicitly as 'False' will \
find the least value.\
\>", "Text"]

Cell[BoxData[{
    RowBox[{
      RowBox[{"Clear", "[",
        RowBox[{"findLeastOrGreatest", ",", "testRun"}], "]"}],
      ";"}], "\[IndentingNewLine]",
    RowBox[{
      RowBox[{
        RowBox[{"findLeastOrGreatest", "[",
          RowBox[{
            RowBox[{"inList_List", "?",
              RowBox[{"(",
                RowBox[{
                  RowBox[{"(",
                    RowBox[{
                      RowBox[{"Depth", "[", "#", "]"}], "\[Equal]",
                      "3"}], ")"}], " ", "&"}], ")"}]}], ",", " ",
            RowBox[{"pos", ":",
              RowBox[{"(",
                RowBox[{"_Integer", "?",
                  RowBox[{"(",
                    RowBox[{
                      RowBox[{
                        RowBox[{"Positive", "[", "#", "]"}], " ", "&&",
                         " ",
                        RowBox[{"#", " ", "<", " ", "3"}]}], "&"}],
                    ")"}]}], ")"}]}], ",",
            RowBox[{"greaterThan", ":",
              RowBox[{
                RowBox[{"(",
                  RowBox[{"_", "?",
                    RowBox[{"(",
                      RowBox[{
                        RowBox[{
                        "#", " ", "\[Element]", " ", "Booleans"}],
                        " ", "&"}], ")"}]}], ")"}], ":", "True"}]}]}],
           "]"}], " ", ":=", " ",
        RowBox[{"Module", "[",
          RowBox[{
            RowBox[{"{",
              RowBox[{"op", "=", "GreaterEqual"}], "}"}], ",",
            "\[IndentingNewLine]",
            RowBox[{
              RowBox[{"If", "[",
                RowBox[{
                  RowBox[{
                  "False", " ", "\[Equal]", " ", "greaterThan"}], ",",

                  RowBox[{"op", "=", "Less"}]}], "]"}], ";",
              "\[IndentingNewLine]",
              RowBox[{"IntegerPart", "[",
                RowBox[{
                  RowBox[{"Fold", "[",
                    RowBox[{
                      RowBox[{
                        RowBox[{"If", "[",
                          RowBox[{
                            RowBox[{"op", "[",
                              RowBox[{
                                RowBox[{"#1", "[",
                                  RowBox[{"[", "pos", "]"}], "]"}],
                                ",", " ",
                                RowBox[{"#2", "[",
                                  RowBox[{"[", "pos", "]"}], "]"}]}],
                              "]"}], ",", "#1", ",", "#2"}], "]"}],
                        " ", "&"}], ",",
                      RowBox[{"inList", "[",
                        RowBox[{"[", "1", "]"}], "]"}], ",",
                      "inList"}], "]"}], "[",
                  RowBox[{"[", "pos", "]"}], "]"}], "]"}]}]}],
          "\[IndentingNewLine]", "]"}]}],
      ";"}], "\[IndentingNewLine]",
    RowBox[{
      RowBox[{
        RowBox[{"testRun", "[", "]"}], ":=",
        RowBox[{"Module", "[",
          RowBox[{
            RowBox[{"{",
              RowBox[{"testList", " ", "=", " ",
                RowBox[{"{",
                  RowBox[{
                    RowBox[{"{",
                      RowBox[{"1", ",", "2"}], "}"}], ",", " ",
                    RowBox[{"{",
                      RowBox[{"1", ",", "3"}], "}"}], ",", " ",
                    RowBox[{"{",
                      RowBox[{"1", ",", "4"}], "}"}], ",", " ",
                    RowBox[{"{",
                      RowBox[{"1", ",", "5"}], "}"}], ",", " ",
                    RowBox[{"{",
                      RowBox[{"1", ",", "6"}], "}"}]}], "}"}]}],
              "}"}], ",", "\[IndentingNewLine]",
            RowBox[{
              RowBox[{"Print", "[",
                RowBox[{"findLeastOrGreatest", "[",
                  RowBox[{"testList", ",", "1"}], "]"}], "]"}], ";",
              "\[IndentingNewLine]",
              RowBox[{"Print", "[",
                RowBox[{"findLeastOrGreatest", "[",
                  RowBox[{"testList", ",", "2", ",", "False"}], "]"}],
                 "]"}], ";", "\[IndentingNewLine]",
              RowBox[{"Print", "[",
                RowBox[{"findLeastOrGreatest", "[",
                  RowBox[{"testList", ",", "2"}], "]"}], "]"}],
              ";"}]}], "\[IndentingNewLine]", "]"}]}],
      ";"}], "\[IndentingNewLine]",
    RowBox[{"testRun", "[", "]"}]}], "Input"]

Here is a table of 20 pairs of numbers.
values = Table[{Random[Real, {-2, 2}] i, Random[Real, {-2,2}] i}, {i,
1, 20}];

I want to extract all elements from 'values' where each of the values
of a particular element are negative.  This was my first approach:
negElems = {};
(If[Negative[#[[1]]] && Negative[#[[2]]], negElems = {negElems, #}]) &
/@ values
negElems
Flatten[%]
Partition[%, 2]

I didn't like that approach particularly because it created a
'temporary' list with many Nulls embedded in it.  So, then I tried a
Fold approach:

negElems = {};
Fold[If[Negative[#2[[1]]] && Negative[#2[[2]]], negElems = {negElems,
#2}, negElems] &, values[[1]], values];
Flatten[%]
Partition[%, 2]

That seems 'nicer', but I'm sure there's even better and more efficient
ways of doing this (or perhaps, what I've done is as bad as bad can
be).

All feedback is appreciated.

Thanks,

Matt


  • Prev by Date: Re: Converting Rationals into Reals
  • Next by Date: Re: ((a&&b)||c)==((a||c)&&(b||c))
  • Previous by thread: feature request: invert plot axes
  • Next by thread: Re: 'Good' or 'Proper' Mathematica coding habits question