How can I extend this command to take more arguments - arguments

I have this command (createPerson) that already takes 9 arguments. However, I need it to take more. I have read on the xargs package but I cannot figure out how to use it. Can you help me to apply the changes to the method or maybe propose a better solution. My minimum working code is like this:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{hyperref}
\usepackage{tabularx} % Til tabeller der tilpaser sig i bredden
\newcolumntype{R}{>{\raggedleft\arraybackslash}r}
\usepackage{xifthen} % Used to test if an argument is empty
\usepackage{datetime} % Used to format dates
\newdateformat{timeLineDate}{\THEDAY.~\shortmonthname~\THEYEAR}
\newdateformat{monthYearDate}{\monthname[\THEMONTH]~\THEYEAR}
%Arguments:
% 1) MANDATORY - Reference to the current full name
% 2) OPTIONAL - Full birth name
% 3) MANDATORY - Called name
% 4) MANDATORY - Birth date in the format of dd. mmm. yyyy
% 4) - Day
% 5) - Month
% 6) - Year
% 7) OPTIONAL - Death date in the format of dd. mmm. yyyy
% 7) - Day
% 8) - Month
% 9) - Year
\newcommand{\createPerson}[9]
{
\begin{tabularx}{\textwidth}{lXRc}%
Navn: & \nameref{#1} & \formatdate{#4}{#5}{#6} & $\star$\\%
\ifNoArgumentElse{#2}{Kaldenavn: & #3}{Fødenavn: & #2} & \ifNoArgumentElse{#7#8#9}{&}{%
\ifNoArgumentElse{#7}{%
\ifNoArgumentElse{#8}{#9}{\monthYearDate\formatdate{1}{#8}{#9}}%
}{\formatdate{#7}{#8}{#9}} & \cross%
}%
\ifNoArgumentElse{#2}{}{\\Kaldenavn: & #3 &&}%
\end{tabularx}%
}
%Arguments
% 1) The argument to test
% 2) If empty then do this
% 3) If not empty then do this
\newcommand{\ifNoArgumentElse}[3]{
\ifthenelse{\isempty{#1}}{#2}{#3}%
}
\newcommand{\cross}[1][1pt]{\ooalign{%
\rule[1ex]{1ex}{#1}\cr% Horizontal bar
\hss\rule{#1}{.7em}\hss\cr}% Vertical bar
}
\begin{document}
\subsection{Else Jensen}
\label{person1}
\createPerson
{person1}
{Else Nielsen}
{Else}
{11}
{9}
{1940}
{13}
{11}
{1999}
\subsection{Hans Wright}
\label{person2}
\createPerson
{person2}
{}
{Hans}
{11}
{9}
{1940}
{}
{11}
{1999}
\end{document}

Related

Use repeat of format for many variables on the same line

puts "%-30s%2s%3d%2s%3d%2s%3d%2s%3d%2s%3d" % [tn,ln,a,ln,b,ln,c,ln,d,ln,e]
This is Ruby, but many languages use this formatting. I have forgotten how to output several variables in the same format, without repeating the format in each case. Here, I want "%3d%2s" for 5 integers, each separated by a '|'
You could write the following.
def print_my_string(tn, ln, *ints)
fmt = "%-10s" + ("|#{"%2s" % ln}%3d" * ints.size) + "|"
puts fmt % [tn, *ints]
end
Then, for example,
print_my_string("hello", "ho", 2, 77, 453, 61, 999)
displays
hello |ho 2|ho 77|ho453|ho 61|ho999|
after having computed
fmt = "%-10s" + ("|#{"%2s" % ln}%3d" * ints.size) + "|"
#=> %-10s|ho%3d|ho%3d|ho%3d|ho%3d|ho%3d|"

Syntax to generate a Syntax in SPSS

I’m trying to construct a Syntax to generate a Syntax in SPSS, but I’m having some issues…
I have an excel file with metadata and I would like to use it in order to make a syntax to extract information from it (like this, if I have a huge database, I just need to keep the excel updated – add/delete variables, etc. - and then run a syntax to extract the needed information for a new syntax).
I also noticed the produced syntax has always around 15Mb, which is a lot (applied to more than 500 lines)!
I don’t use Python due to run syntax in different computers and/or configurations.
Any ideas? Can anyone please help me?
Thank you in advance.
Example:
(test.xlsx – sheet 1)
Var Code Label List Var_label (concatenate Var+Label)
V1 3 Sex 1 V1 “Sex”
V2 1 Work 2 V2 “Work”
V3 3 Country 3 V3 “Country”
V4 1 Married 2 V4 “Married”
V5 1 Kids 2 V5 “Kids”
V6 2 Satisf1 4 V6 “Satisf1”
V7 2 Satisf2 4 V7 “Satisf2”
(information from other file)
List = 1
1 “Male”
2 “Female”
List = 2
1 “Yes”
2 “No”
List = 3
1 “Europe”
2 “America”
3 “Asia”
4 “Africa”
5 “Oceania”
List = 4
1 “Very unsatisfied”
10 “Very satisfied”
I want to make a Syntax that generates a new syntax to apply “VARIABLE LABELS” and “VALUE LABELS”. So, I thought about something like this:
GET DATA
/TYPE=XLSX
/FILE="test.xlsx"
/SHEET=name 'sheet 1'
/CELLRANGE=FULL
/READNAMES=ON
/DATATYPEMIN PERCENTAGE=95.0.
EXECUTE.
STRING vlb (A15) labels (A150) value (A12) lab (A1500) point (A2) separate (A50) space (A2) list1 (A100) list2 (A100).
SELECT IF (Code=1).
COMPUTE vlb = "VARIABLE LABELS".
COMPUTE labels = CONCAT (RTRIM(Var_label)," ").
COMPUTE point = ".".
COMPUTE value = "VALUE LABELS".
COMPUTE lab = CONCAT (RTRIM(Var)," ").
COMPUTE list1 = '1 " Yes "'.
COMPUTE list2 = '2 "No".'.
COMPUTE space = " ".
COMPUTE separate="************************************************.".
WRITE OUTFILE = "list_01.sps" / vlb.
WRITE OUTFILE = "list_01.sps" /labels.
WRITE OUTFILE = "list_01.sps" /point.
WRITE OUTFILE = "list_01.sps" /value.
WRITE OUTFILE = "list_01.sps" /lab.
WRITE OUTFILE = "list_01.sps" /list1.
WRITE OUTFILE = "list_01.sps" /list2.
WRITE OUTFILE = "list_01.sps" /space.
WRITE OUTFILE = "list_01.sps" /separate.
WRITE OUTFILE = "list_01.sps" /space.
If there is only one variable with same list (ex: V1), it works ok. However, if there is more than one variable having the same list, it reproduces the codes as much times as number of variables (Ex: V2, V4 and V5).
What I have (Ex: V2, V4 and V5), after running code above:
VARIABLE LABELS
V2 "Work"
.
VALUE LABELS
V2
1 " Yes "
2 " No "
************************************************.
VARIABLE LABELS
V4 "Married"
.
VALUE LABELS
V4
1 " Yes "
2 " No "
************************************************.
VARIABLE LABELS
V5 "Kids"
.
VALUE LABELS
V5
1 " Yes "
2 " No "
************************************************.
What I would like to have:
VARIABLE LABELS
V2 "Work"
V4 "Married"
V5 "Kids"
.
VALUE LABELS
V2 V4 V5
1 " Yes "
2 " No "
I think there are probably ways to automate the whole process better, including the use of your second data source. But for the scope of this question I will suggest a way to get what you asked for specifically.
The key is to build the command with special conditions for first and last lines:
string cmd1 cmd2 (a200).
sort cases by code.
match files /file=* /first=first /last=last /by code. /* marking first and last lines.
do if first.
compute cmd1="VARIABLE LABELS".
compute cmd2="VALUE LABELS".
end if.
if not first cmd1=concat(rtrim(cmd1), " /"). /* "/" only appears from the second varname.
compute cmd1=concat(rtrim(cmd1), " ", Var_label).
compute cmd2=concat(rtrim(cmd2), " ", Var).
do if last.
compute cmd1=concat(rtrim(cmd1), " .").
compute cmd2=concat(rtrim(cmd2), " ", ' 1 " Yes " 2 "No". ').
end if.
exe.
The commands are now ready, but we don't want to get them mixed up so we'll stack them one under the other, and only then write them out:
add files /file=* /rename cmd1=cmd /file=* /rename cmd2=cmd.
exe.
WRITE OUTFILE = "var definitions.sps" / cmd .
exe.
EDIT:
Note that the code above assumes you've already run a select cases if code = ... and that there is a single code in all the remaining lines.
Note also I added an exe. command at the end - without running that the new syntax will appear empty.

How to Enable Scroll Bar of QBasic Output Window?

I'm trying to display a statement 1000 times in QBASIC (using for statement). I think the program works properly, but I cannot see the 1000 statements because I cannot scroll up and down in the output window of QBASIC. I can see only the last part of the 1000 statements.
FOR x = 1 TO 1000
PRINT "maydie";
PRINT
NEXT x
That will be very hard. For QBasic you have to know how PRINT works. Than with look you could write an TSR program that does what you want in some other language. Alternative is store everything in array and create you own display routine with scrolling. But with 1000 lines will run into memory restrictions
In short, unless you're using a modern take on QBasic, you can't.
What you can do is print the output to a text file:
OPEN "C:\somefile.txt" FOR OUTPUT AS #1
FOR x = 1 TO 1000
PRINT #1, "maydie":
PRINT
NEXT x
This will write "maydie" to C:\somefile.txt 1000 times. Then use some text editor to view the output. You could even use a program to count the lines of text, something like OPEN "C:|somefile.txt" FOR INPUT AS #1: WHILE NOT EOF(1): INPUT #1, junk$: i = i + 1: WEND: PRINT "There were " + STR$(i) + " lines."
Though the other answerers are correct in saying that it is not inbuilt and hence not possible, I agree that this is very desirable! Consequently, I have time and time again devised scripts based on the following:
DIM text(1 to 1000) AS STRING
'Define text below: Here I've just defined it as every line being
'"maydie" with the value of the line number, but it could be whatever.
FOR i = 1 TO 1000
text(i) = STR$(i) + "maydie"
NEXT i
CLS
position% = 0
FOR i = 1 to 25
LOCATE i, 1: PRINT text(i); SPACE$(80 - LEN(text(i)));
NEXT i
DO
x$=INKEY$
IF x$ <> "" THEN
SELECT CASE x$
CASE CHR$(0) + CHR$(72) 'Up arrow
position% = position% - 1
IF position% < 0 THEN position% = 0
CASE CHR$(0) + CHR$(80) 'Down arrow
position% = position% + 1
IF position% > 975 THEN position% = 975
CASE CHR$(0) + "I" 'Page Up
position% = position% - 24
IF position% < 0 THEN position% = 0
CASE CHR$(0) + "Q" 'Page Down
position% = position% + 24
IF position% > 975 THEN position% = 975
CASE CHR$(27) 'ENDS the Program on ESC key.
END
END SELECT
FOR i = 1 to 25
LOCATE i, 1: PRINT text(i + position%); SPACE$(80 - LEN(text(i + position%)));
NEXT i
END IF
LOOP
Tested and works! If you want to use it multiple times in your program for multiple different text blocks, you can just turn it into a function and pass it the variables you want.

VBScript to format the file and date <filename><date>.csv [duplicate]

This question already has an answer here:
Format current date and time in VBScript
(1 answer)
Closed 4 years ago.
Hi I need help to set the file name as .csv
currently we could set the file name as 2_10_2018user.csv with the below codes
Set CPY = CreateObject("Scripting.FileSystemObject")
CPY.CopyFile "\\users\user.csv", "\\home\group\" & Replace(FormatDateTime(Date(),2),"","-") & "users.csv",True
Set CPY = nothing
'MsgBox("Done")
You cannot use the ANGLE brackets in a file/folder name it is not permitted.
In fact, The following characters are NOT permitted:
/ \ < > ? * | : "
The bit which you state concerns you:
Replace(FormatDateTime(Date(),2),"","-") & "users.csv",True"
Can be broken down into the following individual commands:
FormatDateTime(Date(),2)
This is telling the system to format the system date (date today) as a SHORT DATE
The options for the second parameter are:
0 = vbGeneralDate (date and time)
1 = vbLongDate (long date)
2 = vbShortDate (short date)
3 = vbLongTime (long time)
4 = vbShortTime (short time)
So now we have the date format,
Next is the replace action :
Replace(FormatDateTime(Date(),2),"","-") & "users.csv",True"
where we replace the date delimiters in this case "" (null string) with a hyphen "-" (-)
So this part of the filename changes from 010119 to 01-01-19 (for example 1st Jan 2019)
and "users.csv" is attached to the end of it all
Finally the TRUE comment tells the system to OVERWRITE the file if it already exists!
If you want the filename before the date then simply swap the bits over:
CPY.CopyFile "\\users\user.csv", "\\home\shared\group\" & "users-" & Replace(FormatDateTime(Date(),2),"","-") & ".csv",True

Select menu in bash

For some reason, my menu renders like this:
1) RUNTHROUGH 6) option 4
2) QUIT 7) option leg
3) NEW SEARCH PATERN 8) option arm
4) CLEAR SEARCHES 9) option whatever
5) option 1 10) option blabla
,but I would like it to be aligned properly, like this:
1) RUNTHROUGH 6) option 4
2) QUIT 7) option leg
3) NEW SEARCH PATERN 8) option arm
4) CLEAR SEARCHES 9) option whatever
5) option 1 10) option blabla
How can I do that?
I am populating menu from two arrays:
One is constructed from label variables like this:
MENU_OPTIONS=( "$SCRIPT_RUNTHROUGH" "$PROGRAM_QUIT" "$PATTERN_NEW" "$PATTERN_CLEAR" )
where variable has value like this, with color escapes
SCRIPT_RUNTHROUGH=$'\e[1;31mRUNTHROUGH\e[0;33m'
PROGRAM_QUIT=$'\e[1;31mQUIT\e[0;33m'
PATTERN_NEW=$'\e[1;31mNEW SEARCH PATERN\e[0;33m'
PATTERN_CLEAR=$'\e[1;31mCLEAR SEARCHES\e[0;33m'
and another array entries is coming from file:
readarray -t entries < ./file
content of file is raw text data:
option 1
option 4
option leg
option arm
option whatever
option blabla
so select block goes like:
select opt in "${MENU_OPTIONS[#]}" "${entries[#]}";
do
case "$opt" in
...)
;;
Bash mostly count the char in each option, regardless they are "displayable" or not. So, the escape code used to highlight some of your items false the display.
Here is an example:
sh$ for i in {1..12}; do OPTIONS[$i]=$(printf "option-%02d" $i); done
sh$ select i in "${OPTIONS[#]}"; do echo $i ; done
1) option-01 4) option-04 7) option-07 10) option-10
2) option-02 5) option-05 8) option-08 11) option-11
3) option-03 6) option-06 9) option-09 12) option-12
This is as expected. But if I highlight the 4th item:
sh$ OPTIONS[4]=$'\e[1;31moption-04\e[0;33m'
sh$ select i in "${OPTIONS[#]}"; do echo $i ; done
1) option-01 4) option-04 7) option-07 10) option-10
2) option-02 5) option-05 8) option-08 11) option-11
3) option-03 6) option-06 9) option-09 12) option-12
WORKAROUND
Well ... it's more a hack than a workaround. Really.
I add some extra spaces at the end of every option in order to widen the columns. Instead, I add a few \b at the end of the highlighted option (6 gave good results on my tests). I can't be more precise, since I wasn't able to clearly determine the rule to follow. You probably have to be prepared for trial and error...(thing are even more complicated by the fact Bash uses a mix of tab and space to indent the various options)
Anyway, this display properly on my system:
sh$ for i in {1..12}; do OPTIONS[$i]=$(printf "option-%02d " $i); done
# ^^^^^^^^
sh$ OPTIONS[4]=$'\e[1;31moption-04\e[0;33m\b\b\b\b\b\b'
# ^^^^^^^^^^^^
sh$ select i in "${OPTIONS[#]}"; do echo $i ; done
1) option-01 5) option-05 9) option-09
2) option-02 6) option-06 10) option-10
3) option-03 7) option-07 11) option-11
4) option-04 8) option-08 12) option-12
EDIT: I was puzzled by the fact in my example, the menu was off by 8 char. Doesn't match with the number of bytes in the various escape codes.
But, given the code from GNU bash 4.2 :
(execute_cmd.c)
static int
displen (s)
const char *s;
{
#if defined (HANDLE_MULTIBYTE)
wchar_t *wcstr;
size_t wclen, slen;
wcstr = 0;
slen = mbstowcs (wcstr, s, 0);
if (slen == -1)
slen = 0;
wcstr = (wchar_t *)xmalloc (sizeof (wchar_t) * (slen + 1));
mbstowcs (wcstr, s, slen + 1);
wclen = wcswidth (wcstr, slen);
free (wcstr);
return ((int)wclen);
#else
return (STRLEN (s));
#endif
}
It appears that if Bash is compiled with multibyte support, it converts the raw string using mbstowcs in order to calculate its length using wcswidth. Given my system has UTF-8 LC_CTYPE, probably mbstowcs misconverted the escape code as some Unicode character...

Resources