Mathematica 9 is now available
Services & Resources / Wolfram Forums / MathGroup Archive
-----

MathGroup Archive 2009

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

Search the Archive

Re: Basic questions on list manipulation in the

  • To: mathgroup at smc.vnet.net
  • Subject: [mg95672] Re: Basic questions on list manipulation in the
  • From: "Drago Ganic" <dganic at vodatel.net>
  • Date: Sat, 24 Jan 2009 06:20:53 -0500 (EST)
  • References: <200901211145.GAA12433@smc.vnet.net> <gl9n4c$as3$1@smc.vnet.net>

Hi,
What you want is basically the relational database update/modify operator in 
Mathematica and this whole area is IMHO Mathematica's weakness since V1. 
There is no build-in function for this and related operations and area of 
computer science (DatabaseLink` stores the data externally, so I don't count 
it here). The list structure and operations are too general for a large 
class of applications and a less general but powerfull structure for 
tables/relations is needed.

The closest thing done in this regard was Roman E. Maeder's article in the 
Mathematica Journal and the chapter "Databases" in his books:
- The Mathematica Programmer, 1994
- Computer Science with Mathematica, 2000

In those books the (same) package Database` is developed and documented. 
Maeder showed the way how this operation should be implemented in Mathematica , but did not work out the details (operators like Sort, Group, Delete, Insert 
etc.)

In your example (and ever imaginable similar example according to relational 
database theory), the data should be presented in a table form (matrix with 
header row) which lists all the attributes of your entities and where some 
attributes identify your entities (so called keys) while all other just 
describe it. But it is important that for many purposes keys can be used as 
all other attributes. For example the set to be updated can be defined in 
any way, not only via the key.

In your example sym would be the key (e.g. Name), where val1, val2 and val3 
would be the other attributes (e.g. height, weight, salary etc.).


We load the package:
In[1]: = <<Database`

Create the table/relation:
In[2]:= rel= tbl= newRelation[
    {sym, val1, val2, val3},{
    {sym1, 20, 300, 1000},
    {sym2, 50, 500, 20000}
}]
Out[2]= R[{sym,val1,val2,val3},{{sym1,20,300,1000},{sym2,50,500,20000}}]

The Modify function from the package modifies *all* data:
In[3]:=   Modify [ val1 = "Hello", tbl ]
Out[3] = 
R[{sym,val1,val2,val3},{{sym1,Hello,300,1000},{sym2,Hello,500,20000}}]

To modify/update a subset of the data, we overload Modify:
In[4]:=   Modify [ val1 = "Hello", {rel, sym == sym1} ]
Out[4] = R[{sym,val1,val2,val3},{{sym1,Hello,300,1000},{sym2,50,500,20000}}]

Here is the code of the overloaded function:

Modify[ assignment_, {rel_Symbol, cond_} ] :=
 Module[ {temp, rest},
    temp = Select[ rel, cond ];
    rest = Complement[ rel, temp ];
    Modify[ assignment, temp ];
    rel = Union [ temp, rest ]
 ]

Notes:
- the package Database` must be slightly modified for Mathematica versions above 5.1 
(because of new build-in functions Tuples, InputField)
- notice the nice set/relation-oriented programming style in Modify. No 
positional notation, no pure functions (# &) etc.
- the condition could be any predicate .. like Sqrt[val2] > 100 not just 
simple ones like sym == sym1

Best regards from Croatia,
Drago Ganic


"DrMajorBob" <btreat1 at austin.rr.com> wrote in message 
news:gl9n4c$as3$1 at smc.vnet.net...
> For instance,
>
> ct = {{sym1 -> {val1 -> 20, val2 -> 300,
>       val3 -> 1000}}, {sym2 -> {val1 -> 50, val2 -> 500,
>       val3 -> 20000}}};
>
> changeVal[ct_, who_, class_, amt_] :=
>  ct /. Rule[who, {a___, Rule[class, _], b___}] :>
>    Rule[who, {a, Rule[class, amt], b}]
>
> ct = changeVal[ct, sym2, val1, "hello"]
>
> {{sym1 -> {val1 -> 20, val2 -> 300,
>     val3 -> 1000}}, {sym2 -> {val1 -> "hello", val2 -> 500,
>     val3 -> 20000}}}
>
> If you don't like the assignment construct "ct = changeVal[..]", an
> alternative is
>
> ct = {{sym1 -> {val1 -> 20, val2 -> 300,
>       val3 -> 1000}}, {sym2 -> {val1 -> 50, val2 -> 500,
>       val3 -> 20000}}};
>
> Clear[changeVal]
> SetAttributes[changeVal, HoldFirst]
> changeVal[ct_, who_, class_, amt_] :=
>  ct = ct /.
>    Rule[who, {a___, Rule[class, _], b___}] :>
>     Rule[who, {a, Rule[class, amt], b}]
>
> changeVal[ct, sym2, val1, "hello"];
> ct
>
> {{sym1 -> {val1 -> 20, val2 -> 300,
>     val3 -> 1000}}, {sym2 -> {val1 -> "hello", val2 -> 500,
>     val3 -> 20000}}}
>
> If you want changeVal to treat ct as a global, not an argument (never
> recommended), then:
>
> ct = {{sym1 -> {val1 -> 20, val2 -> 300,
>       val3 -> 1000}}, {sym2 -> {val1 -> 50, val2 -> 500,
>       val3 -> 20000}}};
>
> Clear[changeVal]
> changeVal[who_, class_, amt_] :=
>  ct = ct /.
>    Rule[who, {a___, Rule[class, _], b___}] :>
>     Rule[who, {a, Rule[class, amt], b}]
>
> changeVal[sym2, val1, "hello"];
> ct
>
> {{sym1 -> {val1 -> 20, val2 -> 300,
>     val3 -> 1000}}, {sym2 -> {val1 -> "hello", val2 -> 500,
>     val3 -> 20000}}}
>
> Bobby
>
> On Wed, 21 Jan 2009 05:45:28 -0600, <dangerrity at gmail.com> wrote:
>
>> Hello,
>>
>> I have some basic questions about using lists in Mathematica.
>> Specifically I have a table that serves as sort of a database with the
>> following structure:
>>
>> ct = {
>>           { sym1 -> {val1->20, val2->300, val3->1000, ... },
>>           { sym2 -> {val1->50, val2->500, val3->20000,...},
>>           ...
>>        }
>>
>> sym1, sym2, ... are people and val1, val2 ... represent attributes of
>> each person.
>>
>> Now I'm trying to go in and modify values.  I can do it, but I think
>> not well and I think with a "programming language" mindset instead of
>> a "Mathematica mindset."
>>
>> Here is my specific question.  In order to change a specific value in
>> the list above (valxxx) for a given individual (symxxx), I created
>> this function:
>>
>> changeVal[ who_, class_, amnt_ ] := (
>>     ct[[ Position[ ct, who ][[ 1, 1 ]], 2 ]] =
>>     ReplacePart[ ct[[ Position[ ct, who ][[ 1, 1 ]], 2 ]],
>>      Position[ ct[[ Position[ ct, who ][[ 1, 1 ]] ]], class ][[ 1,
>> 2 ]] -> (class -> amnt) ]
>> );
>>
>> Now I know there is a better way than that using list manipulation and
>> patterns.  Can some of you experienced pros help me out?  I call this
>> "write only" code because I don't know that I could explain it once
>> it's written.
>>
>> Perhaps a more fundamental question: is this the right way to store
>> data in lists?  Or would it be better to just have the values and
>> reference them by index number?
>>
>> Thanks for your patience with a simple question.
>>
>>
>
>
>
> -- 
> DrMajorBob at longhorns.com
> 



  • Prev by Date: Re: Mathematica Animation Drives Me Crazy!
  • Next by Date: Timing of N[ Factorial[4000000], 18]
  • Previous by thread: Re: Basic questions on list manipulation in the
  • Next by thread: Re: Issue with Sum Version7