Message Boards Message Boards

0
|
5053 Views
|
7 Replies
|
2 Total Likes
View groups...
Share
Share this post:

[?] Append statement and passing lists to functions to be manipulated?

Posted 7 years ago

I presume I must be doing something insane, but the incredibly simple code below simply refuses to work as I expected

chaintemp = {-10, 1, 2, 3, 4}
bet = chaintemp[[2]] + Last[chaintemp];
Print["bet = ", bet];
Print["chaintemp = ", chaintemp];
Append[chaintemp, bet];
Print["chaintemp after append = ", chaintemp];

This gives output

{-10, 1, 2, 3, 4}
bet = 5
chaintemp = {-10,1,2,3,4}
chaintemp after append = {-10,1,2,3,4}

The Append operation has not appended the new entry "5" to the end of the list variable chaintemp.

This is absolutely driving me utterly bonkers. I am using Mathematica 11 on a Windows 7.1 machine.

Please advise, thank you.

The question about how best to pass lists to functions for manipulation is in a post below.

POSTED BY: Will Ponder
7 Replies
Posted 7 years ago

Chi-Hsiang Wang.

Thanks again. Those are very useful revisions to my code. The functions do a lot more, so I can't use them directly, but I can use the improvements.

And I do normally put Module around the functions to create local variables confined to the function.

I have used the clear at the start, and you are right I should put that in the code as a matter of habit. When I was first learning mathematica the non-local variables and non-resetting of global variables on running the code were my biggest problems. Then I discovered how to fully use "-> " all the time so that I could cut down on setting variables.

The seems to be working wonderfully now. The code is a lot more complicated than the snippets I presented, but the snippets successfully represented the problems I was having.

The great thing about using Mathematica when messing around with numbers and lists is that one can plot and graph the results with such ease, hence I thought I would use this platform.

Thanks again.

POSTED BY: Will Ponder

The following is what I got after some revisions of your code:

UpperChain = {-10, 1, 2, 3, 4};
LowerChain = {-10, 1, 2, 3, 4};
SpinResult = 7;
Win[Chain_] := Append[Chain, Chain[[2]] + Chain[[-1]]];
Lose[Chain_] := Drop[Chain, -2];
If[SpinResult < 19,
  LowerChain = Win[LowerChain]; UpperChain = Lose[UpperChain],
  UpperChain = Win[UpperChain]; LowerChain = Lose[LowerChain]];
{UpperChain, LowerChain} // Column

And the result is

{-10, 1, 2}

{-10, 1, 2, 3, 4, 5}

One good practice is by doing what Henrik suggested that at the beginning, clear all the values of global variables. Another good way is to encapsulate the code in a Module or a Block, which makes the scope of the variables confined in the Module or the Block.

Good luck!

POSTED BY: Chi-Hsiang Wang
Posted 7 years ago

Henrik

Thank you so much, the code now seems to work.

I was aware one had to set attributes on the function, but I didn't have the confidence to just try it as I didn't really understand what HoldAll did.

Thanks you so much, I will read up further on this use of HoldAll and its ability to let functions to reference the original variables.

I need to find a decent tutorial on it.

Thank you again. And thanks again to Chi-Hsiang Wang.

POSTED BY: Will Ponder

Start your code with:

ClearAll["Global`*"]
SetAttributes[{Win, Lose}, HoldAll];

This way the argument does not get evaluated and you can actually use the symbol inside your functions.

POSTED BY: Henrik Schachner
Posted 7 years ago

I am going to test your patience as alas my problem is not quite solved.

I am doing list manipulation in a function that has a list passed to it from another function. So probably my main problem is one of passing by reference or value or not understanding how to manipulate variables. Apologies again if this in an insanely stupid question

A simplified version of the code

UpperChain = {-10, 1, 2, 3, 4}
LowerChain = {-10, 1, 2, 3, 4}
SpinResult = 7
If[ SpinResult < 19, 
  LowerChain = Win[LowerChain]; UpperChain = Lose[UpperChain];,
  UpperChain = Win[UpperChain]; LowerChain = Lose[LowerChain];
  ];

Win[Chain_] := (
  Bet = Chain[[2]] + Last[Chain];
  (*
  Next line generates an error "is not a variable with a value, so 
its value cannot be changed." I was hoping to end up with Chain={-10,1,2,3,4,5}
  *)
  AppendTo[Chain, Bet];
  (*
  If I use Chain=Append[Chain,
  Bet] this generates an error about the "shape" of the variable 
  *)
  Chain)

Lose[Chain_] := (
  (*
  Delete element 2 and the last element, 
  so that I hope to end up with chain = {-10,2,3}
  *)
  Chain = Delete[Chain, 2];
  Chain = Delete[Length[Chain]];

  Chain)

Hopefully you can see is that the functions "win" and "lose" simply take a parameter of a "chain" list and then attempt to add a member or delete a member.

So basically my question is, what is the best way to pass lists to functions ( or perhaps one might consider them procedures ) where they are manipulated, and the original list is then modified to reflect the result of the function's manipulation, including increasing and decreasing the length of the list. In C++ one would use linked lists and pointers, I was hoping to use the list manipulation code in Mathematica and pass the list as a parameter by reference and I understand with the use of HoldAll one can do something similar, but alas the HoldAll documentation doesn't really explain such an application.

POSTED BY: Will Ponder
Posted 7 years ago

Oh my goodness.

You have just saved me from going bonkers. Thank you so much. I must admit that I interpreted the help as "Append gives the expression..." as Append actually modifies the expression, but of course the form it takes is more useful.

Again, thank you so much for answering.

POSTED BY: Will Ponder

Please replace Append with AppendTo. If using Append, you need

chaintemp = Append[chaintemp, bet];

Hope this is helpful.

POSTED BY: Chi-Hsiang Wang
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract