Why does thinkscript throw these issues when I try to create a counter? - thinkscript

When I try to create a counter and increment it in an if-else statement the thinkscript compiler throws confusing errors which tell me it's not allowed, yet I've seen this done in several examples. They even have a reserved word: rec in order to allow for incrementing counters.
score = score + 1; produces: # Already assigned: Score at...
rec score = score + 1; produces: # identifier already used: score at ...
# not allowed inside an IF/THEN/ELSE statement
#
# TD Ameritrade IP Company, Inc. (c) 2017-2019
#
input price = close;
input length = 9;
input displace = 0;
def score = 0;
def smavrgg = Average(price[-displace], length);
def expMvAvrg = ExpAverage(price[-displace], length);
plot SMA = smavrgg;
SMA.SetDefaultColor(GetColor(1));
plot AvgExp = expMvAvrg;
AvgExp.SetDefaultColor(GetColor(1));
# 1 if uptrend, 0 if downtrend
def lastTrendisUp = (close[0] - close[1]) > 0 ;
def secondLastTrendisUP = (close[1] - close[2]) > 0;
def thirdLastTrendisUP = (close[2] - close[3]) > 0;
def fourthLastTrendisUP = (close[3] - close[4]) > 0;
input lookback = 5;
# defines intBool (array) that indicates whether one or the other crossed.
def bull_cross = SMA crosses above AvgExp;
def bear_cross = AvgExp crosses below SMA;
# returns the highest value in the data array for the lookback.
# so [0, 1, 0, 0] means a cross happened within the last units. and 1 will be returned.
if (bull_cross[0] or bear_cross[0]) then {
if lastTrendisUp {
# Already assigned: Score at...
score = score + 1;
# identifier already used: score at ...
# not allowed inside an IF/THEN/ELSE statement
rec score = score + 1;
} else {
}
} else if (bull_cross[1] or bear_cross[1]) {
if secondLastTrendisUP {
} else {
}
} else if (bull_cross[2] or bear_cross[2]) {
if thirdLastTrendisUP {
} else {
}
} else if (bull_cross[3] or bear_cross[3]) {
if fourthLastTrendisUP {
} else {
}
} else if (bull_cross[4] or bear_cross[4]) {
} else {
}
# If most recent cross happened in the last 4
# and most recent cross occured on a green candle.
def bull_lookback = Highest(bull_cross, lookback);
def bear_lookback = Highest(bear_cross, lookback);
# def think = if bull_lookback or bear_lookback
plot signal = if bull_lookback then 2 else if bear_lookback then 1 else 0;
signal.AssignValueColor(if signal == 2 then Color.DARK_GREEN else if signal == 1 then Color.DARK_RED else Color.DARK_ORANGE);
AssignBackgroundColor(if signal == 2 then Color.DARK_GREEN else if signal == 1 then Color.DARK_RED else Color.DARK_ORANGE);

Once you define a variable in Thinkscript and assign it, it's only valid for one bar, it behaves as a constant so it can't be reassigned. I'm pretty sure you can't even place a Def command into a conditional, just like in most codes. In order to create a 'dynamic' SCORE, you need to assign the dynamic value in the same line you instantiate. You don't need
def score = 0;
since when you define the variable, it will have a zero value anyway.
You also don't the extra variables for the 'trendisup' placeholders, because really
secondLastTrendisUp
is the same as saying
lastTrendisUp[1]
because it was already computed in the last bar.
You can accomplish the counter without the extra variables using a FOLD statement, like this:
def score= fold index=0 to 4
with p=0
do p + ((bearcross[index] or bullcross[index]) and lastTrendisUp[index]);
This will add one to the score each time the conditions are true, and assign the total to the SCORE variable. I think this is what you would like to accomplish, I can't tell, since you never show what you're doing with the score variable later on... If you are looking to just find out if bullcross or bearcross condition and also the lasttrendisup condition evaluates to true in any of the last five bars, then you add 'while p=0' above the with, and it will return a one to SCORE as soon as it encounters the first true instance.

counter to increase a variable by 1, on each bar:
score = score[1] + 1;
the [1] means, go get the value from that variable from 1 bar ago.

The answer is that variables in thinkscript cannot be changed.

Related

If value of POST = "0" then $Vid = "$row['video']

if ($_POST['video'] == '0 lets say') {the $vid=$row['video']}
how would i define this correctly
so that i can set the value of video in the initial post form
as 0 lets say or any other number,
and on recieving the value through If isset$post
- if the value actually equals "0 lets say"
then $vid can = $row['video']
Basically
how can this be achieved,... thank you
if ($_POST['video'] == '0') {
$videoID = $vid;
} else {
$videoID = $videoID;
}
sorry i should of looked around 1st. but thanks for any interest...

Matlab Codegen build error

I am trying to convert the below Matlab code into C++ using codegen. However it fails at build and I get the error:
"??? Unless 'rows' is specified, the first input must be a vector. If the vector is variable-size, the either the first dimension or the second must have a fixed length of 1. The input [] is not supported. Use a 1-by-0 or 0-by-1 input (e.g., zeros(1,0) or zeros(0,1)) to represent the empty set."
It then points to [id,m,n] = unique(id); being the culprit. Why doesn't it build and what's the best way to fix it?
function [L,num,sz] = label(I,n) %#codegen
% Check input arguments
error(nargchk(1,2,nargin));
if nargin==1, n=8; end
assert(ndims(I)==2,'The input I must be a 2-D array')
sizI = size(I);
id = reshape(1:prod(sizI),sizI);
sz = ones(sizI);
% Indexes of the adjacent pixels
vec = #(x) x(:);
if n==4 % 4-connected neighborhood
idx1 = [vec(id(:,1:end-1)); vec(id(1:end-1,:))];
idx2 = [vec(id(:,2:end)); vec(id(2:end,:))];
elseif n==8 % 8-connected neighborhood
idx1 = [vec(id(:,1:end-1)); vec(id(1:end-1,:))];
idx2 = [vec(id(:,2:end)); vec(id(2:end,:))];
idx1 = [idx1; vec(id(1:end-1,1:end-1)); vec(id(2:end,1:end-1))];
idx2 = [idx2; vec(id(2:end,2:end)); vec(id(1:end-1,2:end))];
else
error('The second input argument must be either 4 or 8.')
end
% Create the groups and merge them (Union/Find Algorithm)
for k = 1:length(idx1)
root1 = idx1(k);
root2 = idx2(k);
while root1~=id(root1)
id(root1) = id(id(root1));
root1 = id(root1);
end
while root2~=id(root2)
id(root2) = id(id(root2));
root2 = id(root2);
end
if root1==root2, continue, end
% (The two pixels belong to the same group)
N1 = sz(root1); % size of the group belonging to root1
N2 = sz(root2); % size of the group belonging to root2
if I(root1)==I(root2) % then merge the two groups
if N1 < N2
id(root1) = root2;
sz(root2) = N1+N2;
else
id(root2) = root1;
sz(root1) = N1+N2;
end
end
end
while 1
id0 = id;
id = id(id);
if isequal(id0,id), break, end
end
sz = sz(id);
% Label matrix
isNaNI = isnan(I);
id(isNaNI) = NaN;
[id,m,n] = unique(id);
I = 1:length(id);
L = reshape(I(n),sizI);
L(isNaNI) = 0;
if nargout>1, num = nnz(~isnan(id)); end
Just an FYI, if you are using MATLAB R2013b or newer, you can replace error(nargchk(1,2,nargin)) with narginchk(1,2).
As the error message says, for codegen unique requires that the input be a vector unless 'rows' is passed.
If you look at the report (click the "Open report" link that is shown) and hover over id you will likely see that its size is neither 1-by-N nor N-by-1. The requirement for unique can be seen if you search for unique here:
http://www.mathworks.com/help/coder/ug/functions-supported-for-code-generation--alphabetical-list.html
You could do one of a few things:
Make id a vector and treat it as a vector for the computation. Instead of the declaration:
id = reshape(1:prod(sizI),sizI);
you could use:
id = 1:numel(I)
Then id would be a row vector.
You could also keep the code as is and do something like:
[idtemp,m,n] = unique(id(:));
id = reshape(idtemp,size(id));
Obviously, this will cause a copy, idtemp, to be made but it may involve fewer changes to your code.
Remove the anonymous function stored in the variable vec and make vec a subfunction:
function y = vec(x)
coder.inline('always');
y = x(:);
Without the 'rows' option, the input to the unique function is always interpreted as a vector, and the output is always a vector, anyway. So, for example, something like id = unique(id) would have the effect of id = id(:) if all the elements of the matrix id were unique. There is no harm in making the input a vector going in. So change the line
[id,m,n] = unique(id);
to
[id,m,n] = unique(id(:));

Loop problems Even Count

I have a beginner question. Loops are extremely hard for me to understand, so it's come to me asking for help.
I am trying to create a function to count the amount of even numbers in a user input list, with a negative at the end to show the end of the list. I know I need to use a while loop, but I am having trouble figuring out how to walk through the indexes of the input list. This is what I have so far, can anyone give me a hand?
def find_even_count(numlist):
count = 0
numlist.split()
while numlist > 0:
if numlist % 2 == 0:
count += 1
return count
numlist = raw_input("Please enter a list of numbers, with a negative at the end: ")
print find_even_count(numlist)
I used the split to separate out the indexes of the list, but I know I am doing something wrong. Can anyone point out what I am doing wrong, or point me to a good step by step explanation of what to do here?
Thank you guys so much, I know you probably have something more on your skill level to do, but appreciate the help!
You were pretty close, just a couple of corrections:
def find_even_count(numlist):
count = 0
lst = numlist.split()
for num in lst:
if int(num) % 2 == 0:
count += 1
return count
numlist = raw_input("Please enter a list of numbers, with a negative at the end: ")
print find_even_count(numlist)
I have used a for loop rather than a while loop, stored the outcome of numlist.split() to a variable (lst) and then just iterated over this.
You have a couple of problems:
You split numlist, but don't assign the resulting list to anything.
You then try to operate on numlist, which is still the string of all numbers.
You never try to convert anything to a number.
Instead, try:
def find_even_count(numlist):
count = 0
for numstr in numlist.split(): # iterate over the list
num = int(numstr) # convert each item to an integer
if num < 0:
break # stop when we hit a negative
elif num % 2 == 0:
count += 1 # increment count for even numbers
return count # return the total
Or, doing the whole thing in one line:
def find_even_count(numlist):
return sum(num % 2 for num in map(int, numlist.split()) if num > 0)
(Note: the one-liner will fail in cases where the user tries to trick you by putting more numbers after the "final" negative number, e.g. with numlist = "1 2 -1 3 4")
If you must use a while loop (which isn't really the best tool for the job), it would look like:
def find_even_count(numlist):
index = count = 0
numlist = list(map(int, numlist.split()))
while numlist[index] > 0:
if numlist[index] % 2 == 0:
count += 1
index += 1
return count

Log base 2 calculation in python

I am trying to calculate the average disorder in ID trees. My code is below:
Republican_yes = yes.count('Republican')
Democrat_yes = yes.count('Democrat')
Republican_no = no.count('Republican')
Democrat_no = no.count('Democrat')
Indep_yes = yes.count('Independent')
Indep_no = no.count('Independent')
disorder_yes= Republican_yes/len(yes)*(math.log(float(Republican_yes)/len(yes),2))+ Democrat_yes/len(yes)*(math.log(float(Democrat_yes)/len(yes),2))+Indep_yes/len(yes)*(math.log(float(Indep_yes)/len(yes),2))
disorder_no= Republican_no/len(no)*(math.log(float(Republican_no)/len(no),2))+Democrat_no/len(no)*(math.log(float(Democrat_no)/len(no),2))+Indep_no/len(no)*(math.log(float(Indep_no)/len(no),2))
avgdisorder = -len(yes)/(len(yes)+len(no))*disorder_yes - len(no)/(len(yes)+len(no))*disorder_no
return avgdisorder
why do I keep getting math domain error?
Check if the lengths are 0 or not, else you will get MathError.
if len(yes):
disorder_yes= Republican_yes/len(yes)*(math.log(float(Republican_yes)/len(yes),2))+ Democrat_yes/len(yes)*(math.log(float(Democrat_yes)/len(yes),2))+Indep_yes/len(yes)*(math.log(float(Indep_yes)/len(yes),2))
if len(no):
disorder_no= Republican_no/len(no)*(math.log(float(Republican_no)/len(no),2))+Democrat_no/len(no)*(math.log(float(Democrat_no)/len(no),2))+Indep_no/len(no)*(math.log(float(Indep_no)/len(no),2))
if len(yes) or len(no):
avgdisorder = -len(yes)/(len(yes)+len(no))*disorder_yes - len(no)/(len(yes)+len(no))*disorder_no
If you want, you can always add the else clause for all 3 if statements as per your requirement.

Scala spec unit tests

I ve got the following class and I want to write some Spec test cases, but I am really new to it and I don't know how to start. My class do loke like this:
class Board{
val array = Array.fill(7)(Array.fill(6)(None:Option[Coin]))
def move(x:Int, coin:Coin) {
val y = array(x).indexOf(None)
require(y >= 0)
array(x)(y) = Some(coin)
}
def apply(x: Int, y: Int):Option[Coin] =
if (0 <= x && x < 7 && 0 <= y && y < 6) array(x)(y)
else None
def winner: Option[Coin] = winner(Cross).orElse(winner(Naught))
private def winner(coin:Coin):Option[Coin] = {
val rows = (0 until 6).map(y => (0 until 7).map( x => apply(x,y)))
val cols = (0 until 7).map(x => (0 until 6).map( y => apply(x,y)))
val dia1 = (0 until 4).map(x => (0 until 6).map( y => apply(x+y,y)))
val dia2 = (3 until 7).map(x => (0 until 6).map( y => apply(x-y,y)))
val slice = List.fill(4)(Some(coin))
if((rows ++ cols ++ dia1 ++ dia2).exists(_.containsSlice(slice)))
Some(coin)
else None
}
override def toString = {
val string = new StringBuilder
for(y <- 5 to 0 by -1; x <- 0 to 6){
string.append(apply(x, y).getOrElse("_"))
if (x == 6) string.append ("\n")
else string.append("|")
}
string.append("0 1 2 3 4 5 6\n").toString
}
}
Thank you!
I can only second Daniel's suggestion, because you'll end up with a more practical API by using TDD.
I also think that your application could be nicely tested with a mix of specs2 and ScalaCheck. Here the draft of a Specification to get you started:
import org.specs2._
import org.scalacheck.{Arbitrary, Gen}
class TestSpec extends Specification with ScalaCheck { def is =
"moving a coin in a column moves the coin to the nearest empty slot" ! e1^
"a coin wins if" ^
"a row contains 4 consecutive coins" ! e2^
"a column contains 4 consecutive coins" ! e3^
"a diagonal contains 4 consecutive coins" ! e4^
end
def e1 = check { (b: Board, x: Int, c: Coin) =>
try { b.move(x, c) } catch { case e => () }
// either there was a coin before somewhere in that column
// or there is now after the move
(0 until 6).exists(y => b(x, y).isDefined)
}
def e2 = pending
def e3 = pending
def e4 = pending
/**
* Random data for Coins, x position and Board
*/
implicit def arbitraryCoin: Arbitrary[Coin] = Arbitrary { Gen.oneOf(Cross, Naught) }
implicit def arbitraryXPosition: Arbitrary[Int] = Arbitrary { Gen.choose(0, 6) }
implicit def arbitraryBoardMove: Arbitrary[(Int, Coin)] = Arbitrary {
for {
coin <- arbitraryCoin.arbitrary
x <- arbitraryXPosition.arbitrary
} yield (x, coin)
}
implicit def arbitraryBoard: Arbitrary[Board] = Arbitrary {
for {
moves <- Gen.listOf1(arbitraryBoardMove.arbitrary)
} yield {
val board = new Board
moves.foreach { case (x, coin) =>
try { board.move(x, coin) } catch { case e => () }}
board
}
}
}
object Cross extends Coin {
override def toString = "x"
}
object Naught extends Coin {
override def toString = "o"
}
sealed trait Coin
The e1 property I've implemented is not the real thing because it doesn't really check that we moved the coin to the nearest empty slot, which is what your code and your API suggests. You will also want to change the generated data so that the Boards are generated with an alternation of x and o. That should be a great way to learn how to use ScalaCheck!
I suggest you throw all that code out -- well, save it somewhere, but start from zero using TDD.
The Specs2 site has plenty examples of how to write tests, but use TDD -- test driven design -- to do it. Adding tests after the fact is suboptimal, to say the least.
So, think of the most simple case you want to handle of the most simple feature, write a test for that, see it fail, write the code to fix it. Refactor if necessary, and repeat for the next most simple case.
If you want help with how to do TDD in general, I heartily endorse the videos about TDD available on Clean Coders. At the very least, watch the second part where Bob Martin writes a whole class TDD-style, from design to end.
If you know how to do testing in general but are confused about Scala or Specs, please be much more specific about what your questions are.