[Date Index]
[Thread Index]
[Author Index]
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**
| |