How to compare to macros in latex - if-statement

I want to compare two macros \Lgiii with the one read in as #1 in a macro called fex
\def\fex(#1,#2)
ifx\Lgiii#1
do something
else
do something else
fi
However this does not seem to work and maybe someone has a quick solution to this.

In order to compare macros, you need to store the argument inside some macro; this allows you to use \ifx:
\documentclass{article}
\def\fex(#1,#2){%
\def\Lgi{#1}% Store first argument in \Lgi
\ifx\Lgiii\Lgi
do something
\else
do something else
\fi
}
\def\Lgiii{something \relax + 2}
\begin{document}
\fex(this,that)
\fex(something \relax + 2,that)
\fex(something \relax +2,that)
\end{document}

Related

TACL How to use multiple Arguments

I was wondering if we have any TACL experts out there can can help me answer probably a very basic question.
How do you inject multiple arguments into you routine.
This is what I have currently so far
[#CASE [#ARGUMENT / VALUE job_id/number /minimum [min_job], maximum [max_job]/
otherwise]
|1|#output Job Number = [job_id]
|otherwise|
#output Bad number - Must be a number between [min_job] & [max_job]
#return
]
I have been told you need to use a second #ARGUMENT statement to get it to work but I have had no such luck getting it to work. And the PDF guides don't help to much.
Any ideas/answers would be great
Thanks.
The #CASE statement isn't required if your arguments are positional and of one type (i.e. you know what you are getting and in what order). In that case you can just use a sequence of #ARGUMENT statements to get the arguments.
In your example #ARGUMENT accepts either a number in a range or anything else - the OTHERWISE bit. The #CASE statement then tells you which of those two you got, 1 or 2.
#ARGUMENT can do data validation for you (you may recognize the output from some of the TACL routines that come with the operating system).
So you can write something like this:
SINK [#ARGUMENT / VALUE job_id/number /minimum [min_job], maximum [max_job]/]
The SINK just tosses away the expansion of the #ARGUMENT, you don't need it since you only accept a number and fail otherwise.
I figured out a way but idk if it is the best way to do it.
It seems that for one an Argument statement needs to always be in a #CASE statement so all I basically did was mirror the above and just altered it for text rather than use integer.
If you know of any other/better ways let me know :)
It find it best to use CASE when you have multiple types of argument
input to process. Kind of mocked up how I would see multiple argument
types being used in the context that you shared with the CASE
expression:
?TACL ROUTINE
#FRAME
#PUSH JOB_ID MIN_JOB MAX_JOB
#SETMANY MIN_JOB MAX_JOB , 1 3
[#DEF VALID_KEYWORDS TEXT |BODY| THISJOB THATJOB SOMEOTHERJOB]
[#CASE
[#ARGUMENT/VALUE JOB_ID/
NUMBER/MINIMUM [MIN_JOB],MAXIMUM [MAX_JOB]/
KEYWORD/WORDLIST [VALID_KEYWORDS]/
STRING
OTHERWISE
]
| 1 |
#OUTPUT VALID JOB NUMBER = [JOB_ID]
| 2 |
#OUTPUT VALID KEYWORD = [JOB_ID]
| 3 |
#OUTPUT VALID STRING = [JOB_ID]
| OTHERWISE |
#OUTPUT NOT A NUMBER, KEYWORD, OR A STRING
#OUTPUT MUST BE ONE OF:
#OUTPUT A NUMBER IN THE RANGE OF: [MIN_JOB] TO [MAX_JOB]
#OUTPUT A KEYWORD IN THIS LIST: [VALID_KEYWORDS]
#OUTPUT OR A STRING OF CHARACTERS
#RETURN
]
#OUTPUT
#OUTPUT NOW WE ARE USING ARGUMENT [JOB_ID] !!!
TIME
#UNFRAME

Only one IF ELSE statement working SAS

Can someone explain to me why only the first IF ELSE statement in my code works? I am trying to combine multiple variables into one.
DATA BCMasterSet2;
SET BCMasterSet;
drop PositiveLymphNodes1;
if PositiveLymphNodes1 = "." then PositiveLymphNodes =
put(PositiveLymphNodes2, 2.);
else PositiveLymphNodes = PositiveLymphNodes1;
if PositiveLymphNodes2 = "." then new_posLymph = put(PositiveLymphNodes,
2.);
else new_posLymph = PositiveLymphNodes2;
RUN;
Here is a nice screenshot of what the incorrect output looks like:OUTPUT
Thanks!
Hard to say without seeing all of your data, but I have a suspicion: is positivelymphnodes1 character or numeric? Is it ever actually equal to "."?
If you are trying to say "if PositiveLymphNodes1 is missing", then you can say that this way:
if missing(positivelymphnodes1) then ...
You can also do the same thing using coalesce or coalescec (the latter is character, the former numeric, in its return value). It chooses the first nonmissing argument. - so if the first argument is missing, it chooses the second.
positiveLymphNodes = coalescec(PositiveLymphNodes1, put(positiveLymphNodes2,2.));
new_posLymph = coalescec(positiveLymphNodes2, put(positiveLymphNodes,2.));
I would be curious why you're using put only in one place and not the other - use it in both or neither, I would suggest.

How do I transform this code into a list comprehension?

I have this code in Python2.7 and I wanna (if possible) transform this code into a list comprehension.
z=[]
if p==1:
z.append('a')
if m==2:
z.append('b')
print ''.join(z)
The problem is it gives me an error (syntax error) when I transformed the code like this:
z=['b' if m==2 'a' if p==1]
print ''.join(z)
Or
z=['a' if p==1 'b' if ==m]
print ''.join(z)
Please let me know if this question has a duplicate.
I would appreciate your advice.
This is a tricky one. I came up with a solution that uses enumerate and an inline if statement to tell the difference between the two if statements. Honestly, using a list comp for this will probably obfuscate the code and it'd be better to just stick with the simpler if statements you already have.
values = ['a', 'b'] # put the append arguments in here, you can also inline this but I put it apart to make the line shorter
z = [val for idx, val in enumerate(values) if (m==2 and p==1 if idx==1 else p==1)]

Stata: Efficient way to replace numerical values with string values

I have code that currently looks like this:
replace fname = "JACK" if id==103
replace lname = "MARTIN" if id==103
replace fname = "MICHAEL" if id==104
replace lname = "JOHNSON" if id==104
And it goes on for multiple pages like this, replacing an ID name with a first and last name string. I was wondering if there is a more efficient way to do this en masse, perhaps by using the recode command?
I will echo the other answers that suggest a merge is the best way to do this.
But if you absolutely must code the lines item-wise (again, messy) you can generate a long list ("pages") of replace commands by using MS Excel to "help" you write the code. Here is a picture of your Excel sheet with one example, showing the MS Excel formula:
columns:
A B C D
row: 1 last first id code
2 MARTIN JACK 103 ="replace fname=^"&B2&"^ if id=="&C2
You type that in, make sure it looks like Stata code when the formula calculates (aside from the carets), and copy the formula in column D down to the end of your list. Then copy the whole block of Stata code in column D generated by the formulas into your do-file, and do a find and replace (be careful here if you are using the caret elsewhere for mathematical uses!!) for all ^ to be replaced with ", which will end up generating proper Stata syntax.
(This is truly a brute force way of doing this, and is less dynamic in the case that there are subsequent changes to your generation list. All--apologies in advance for answering a question here advocating use of Excel :) )
You don't explain where the strings you want to add come from, but what is generally the best technique is explained at
http://www.stata.com/support/faqs/data-management/group-characteristics-for-subsets/index.html
Create an associative array of ids vs Fname,Lname
103 => JACK,MARTIN
104 => MICHAEL,JOHNSON
...
Replace
id => hash{id} ( fname & lname )
The efficiency of doing this will be taken care by the programming language used

convert List[Tuple2[A,B]] to Tuple2[Seq[A],Seq[B]]

Stuck here, trying to convert a List of case class tuples to a tuple of sequences and multi-assign the result.
val items = repo.foo.list // gives me a List[(A,B)]
I can pull off multi-assignment like so:
val(a,b) = (items.map(_._1).toSeq, items.map(_._2).toSeq)
but it would be nicer to do in 1 step, along the lines of:
val(a,b) = repo.foo.list.map{case(a,b) => (a,b)}
I am not sure if I understood the question correctly. Maybe unzip works for what you want?
Here is a link with some examples: http://daily-scala.blogspot.de/2010/03/unzip.html
For a more general case you can look at product-collections. A CollSeqN is both a Seq[TupleN[A1..An]] and a TupleN[Seq[A1..An]]
In your example you could extract the Seqs like so:
items._1
items._2
...