Variable assignment in recursive make call - makefile

I have a simple Makefile as below:
VAR += 4 5 6
default:
#echo "$(VAR)"
a:
VAR="1 2 3" make
b:
make VAR="1 2 3"
make a works as expected and print 1 2 3 4 5 6, but make b only print 1 2 3. I thought this two variants are identical.
The question is: Why is that so?

To quote from the GNU make manual:
If a variable has been set with a command argument, then ordinary
assignments in the makefile are ignored.
You can change that with the overridedirective:
override VAR += 4 5 6

Related

makefile variable automatically assignment with index

I have a question about variable assignments in makefile.
given 2 lists of the same size as below :
(there are no any characters or string match between 2 lists)
index := 1 2 3 4 5
objects := one_obj two_obj three_obj four_obj five_obj
and I need some index to be active, for example, 1 and 3
act_idx := 1 3
all :
#echo act_obj = $(act_obj)
how should I assign $(act_obj) to get the output as "act_obj = one_obj three_obj" after I type "make all" in shell ?
Something like this should do the trick:
act_obj := $(foreach I,$(act_idx),$(filter $I_%,$(objects)))
Based on the adjusted question you can do something like this:
act_obj := $(foreach I,$(act_idx),$(word $I,$(objects)))
You can probably work this out yourself from the set of functions described in the GNU make manual.
The GNUmake library at https://github.com/markpiffer/gmtt was originally written with this exact use case in mind (it grew into a everything-but-the-kitchen-sink, but oh well).
The formulation for the selection process which you are basically needing here is done with the relational table idiom. You produce a table as GNUmake string list and execute a select statement which mimicks a simple SQL select.
include gmtt/gmtt.mk
# define a table with 2 columns (no empty cells allowed!)
define object_tbl :=
2
key1 one_obj
key2 two_obj
key3 three_obj
key4 four_obj
key5 five_obj
endef
act_keys := key1 key3
# SELECT column 2 FROM object_tbl WHERE column 1 is found in act_keys
objects := $(call select,2,$(object_tbl),$$(filter $$1,$(act_keys)))
$(info $(objects))
Output:
one_obj three_obj
make: *** No targets. Stop.
More complex clauses (using arithmetic e.g.) are also possible.

Nested level logic

I have to write a logic for a problem and use it on a landing page. I am unable to write it.
1 - IT 1
2 - IT 1
3 - IT 1
4 - IT 2
5 - IT 2
6 - IT 2
7 - IT 2
8 - IT 3
9 - IT 4
Problem Statement:
-Till someone is selecting 1 or 2 or 3, only IT 1 is suggested
-When someone chooses 4 or 5 or 6 or 7 and anything with value 3 or below , IT 2 is suggested
-When someone chooses 8 or or 8 + anything below 8 then IT 3 is suggested
-When someone chooses 9 and anything with a value below 9 then IT 4 is suggested.
I was using if condition but it seems that whenever IT2 is satisfied IT3 is also satisfied. How to write the logic?
https://jsfiddle.net/bhanusingh/7fxet35h/9/
Don't nest your ifs. Just write four ifs like in your problem description and make a helper function to make it easier to read.
Below is a pseudo code where numbers represent references to checkboxes. isAnySelected is a helper function that takes a list of checkbox references and returns true if any of those checkboxes are checked.
if (isAnySelected([1,2,3]) )
return IT1
if (isAnySelected([4,5,6,7]) AND isAnySelected([1,2,3]) )
return IT2
if (isAnySelected([8]) AND NOT isAnySelected([9]))
return IT3
if (isAnySelected([9]) AND isAnySelected([1,2,3,4,5,6,7,8]))
return IT4
Note that I added "not 9" rule to #3 so that 8 and 9 selected produces IT4
Solved on Reddit: https://www.reddit.com/r/learnprogramming/comments/bpukvf/i_got_a_very_complex_problem_for_me_i_can_only/enxst62?utm_source=share&utm_medium=web2x

(GNU) Forth Local Variable Behavior

I was just learning about local variables for word definitions in Forth. I happen to use GNU Forth (gforth). I was looking at the question and answer, Forth local variable assigning variables and was struggling with the behavior of the given answer. When I tried it, I was getting an underflow unless I had four cells on the stack.
Consider this simple example:
: foo { a b } a b + . ;
This word will take the top two stack cells, store them in the local variables a and b, put a and b (in that order) back on the stack, add them, pop and display the result, and emit a carriage return. It works as I would expect, leaving nothing on the stack when it completes:
: foo { a b } a b + . cr ; ok
1 3 foo 4
ok
.s <0> ok
Now I'd like to try a local variable which is not taken from the stack originally:
: foo { a b | c } a b + to c c . cr ;
I would expect this to behave similarly but use the local variable c. This word would take the top two stack cells, store them in the local variables a and b, put a and b (in that order) back on the stack, add them, pop the result and store it in c, push c back onto the stack, then pop and display the top stack cell and emit a carriage return.
This one doesn't work as I would have expected. Here are my results:
: foo { a b | c } a b + to c c . cr ; ok
1 3 foo
:3: Stack underflow
1 3 >>>foo<<<
Backtrace:
$7F2B572EA1F0 >
Hm, ok, why is there an underflow? Let's try an additional cell on the stack:
1 3 5 foo
:4: Stack underflow
1 3 5 >>>foo<<<
Backtrace:
$7F2B572EA1F8 >l
Still an underflow! Let's try another:
1 3 5 7 foo 4
ok
.s <0> ok
No more underflow. The word foo has consumed all of the cells, but the top two don't appear to be used anywhere. The result 4, which is the sum of the first two cells on the stack, is what I would have expected when I originally tried 1 3 foo.
I have been trying to find some good documentation regarding the local variable behavior, but the manual is very terse on this topic. Can someone explain what is happening here?
Per the comment thread to the question, there is a bug in local variable handling in the "current release", version 0.7.3 (7/9/2014) which has been resolved in a later development release. Downloading, building, and using version 0.7.9_20180319 indicated that the problem was resolved. Thanks to Lars Brinkhoff for pointing out the resolution.

spss search for value in dataset

I'd like to find any cases of a value (e.g., 0) in any cell in an SPSS database. What syntax would accomplish this?
(I came across a python script but don't have that option.)
It is still not very clear how you want to select those cases. But the below syntax will list in the output any cases which have ate least one "0" in any of the variables var1,var2 or var3. I am assuming CaseID is the case identifier variable.
TEMPORARY.
SELECT IF ANY(0,var1,var2,var3).
LIST CaseID var1 var2 var3.
You can use as many variables as you want in the ANY function, and also on the LIST command.
The following syntax will create a list of appearances of 0 within your data - In a separate file:
First creating some fake data to demonstrate on.
data list list/ID (a6) test1 to test6 (6f2).
begin data
ID_001 2 3 2 3 0 3
ID_002 3 4 0 4 3 4
ID_003 0 4 2 4 2 4
ID_004 7 0 1 2 8 3
ID_005 5 5 5 0 5 5
ID_006 4 5 4 5 4 0
end data.
dataset name origData.
Now to create the list:
dataset copy ForList.
dataset activate ForList. /* the list will be created from a copy of the data.
varstocases /make vals from test1 to test6/index testNum(vals).
select if vals=0.
You can use the list in the new file, or put it in the output window:
list ID testNum.

Why do tabulate or summarize not take into account missing values when implemented inside a program?

As an illustrative example, suppose this is your dataset:
cat sex age
1 1 13
1 0 14
1 1 .
2 1 23
2 1 45
2 1 15
If you want to create a table of frequencies between cat and sex, you tabulate these two variables and you get the following result:
tab cat sex
| sex
cat | 0 1 | Total
-----------+----------------------+----------
1 | 1 2 | 3
2 | 0 3 | 3
-----------+----------------------+----------
Total | 1 5 | 6
I am writing a Stata program where the three variables are involved, i.e. cat, sex and age. Getting the matrix of frequencies for the first two variables is just an intermediate step that I need for further computation.
cap program drop myexample
program def myexample, rclass byable(recall) sortpreserve
version 14
syntax varlist [aweight iweight fweight] [if] [in] [ , AGgregate ]
args var1 var2 var3
tempname F
marksample touse
set more off
if "`aggregate'" == "" {
local var1: word 1 of `varlist'
local var2: word 2 of `varlist'
local var3: word 3 of `varlist'
qui: tab `var1' `var2' [`weight' `exp'] if `touse', matcell(`F') label matcol(`var2')
mat list `F'
}
end
However, when I run:
myexample cat sex age
I get this result which is not what I expected:
__000001[2,2]
c1 c2
r1 1 1
r2 0 3
That is, given that age contains a missing value, even if it is not directly involved in the tabulation, the program ignores the missing value and does not take into account that observation. I need to get the result of the first tabulation. I have tried using summarize instead, but the same problem arises. When implemented inside the program, missing values are not counted.
You are complaining about behaviour which you built into your own program. The responsibility and the explanation are in your hands.
The effect of
marksample touse
followed by calling up a command with the qualifier
if `touse'
is to ignore missing values. marksample by default marks as "to use" those observations in which all variables specified have non-missing values; the other observations are marked as to be ignored. It also takes account of any if or in qualifiers and any zero weights.
It's also true, as #Noobie explains, that omitting missing values from a tabulation is default for tabulate in any case.
So, to get the result you want you'd need to modify your marksample call to
marksample touse, novarlist
and to call up tabulate with the missing option (if it's compulsory) or to allow users to specify a missing option which you then pass to tabulate.
You also ask about summarize. By design that command ignores missing values. I don't know what you would expect summarize to do about them. It could report a count of missing values. If you want that, several other commands will oblige, such as codebook or missings (Stata Journal). You can always include a report on missings in your program, such as using count to count the missings and display the result.
I understand your program to be very much work in progress, so won't comment on details you don't ask about.
This is caused by marksample. Rule 5 in help mark states
The marker variable is set to 0 in observations for which any of the
numeric variables in varlist contain a numeric missing value.
You should use the novarlist option. According to the help file,
novarlist is for use with marksample. It specifies that missing values
among variables in varlist not cause the marker variable to be set to 0.
if I understand well you want tab to include missing values? If so, you just have to ask for it
tab myvar1 myvar2, mi
from the documentation
missing : treat missing values like other values

Resources