Dynamic array of string skips the first index - arrays

I am doing a program in which the user inputs the wage, name and the number of working hours per month for a certain number of employees. This piece of code is supposed to recieve Nemp employees and then ask for Nemp names. The problem is, it always skips the first name, it displays 'Employee name:' twice and doesn't allow the user to insert the first one. I don't understand why this is happening, any help would be greatly appreciated!
program test;
uses crt;
var
i, Nemp : integer;
employee: array of string;
BEGIN
read(Nemp);
SetLength (employee, Nemp);
for i:=1 to Nemp do
Begin
writeln ('Employee name: ');
readln (employee[i]);
end;
END.

Dynamic arrays are zero based. You should loop from zero to Nemp-1. Or loop from zero to High(employee).
And as #Rudy and #trincot points out, to read the length of the employee array, use ReadLn(Nemp) to avoid unwanted input effects.
A tip:
Enable range and overflow check in the compiler when debugging. That would have detected the error at the high range.

Related

SAS- setting missings to a range of columns based on the value of another variable

I currently have a dataset that includes an ID for each person, and then variables called day1 through day1826 that are binary indicators of availability of a drug on each of those days. I need to censor individuals on certain days. For example, if a person needs to be censored on day500, then I need day500 to be set to missing, as well as every day variable after that (i.e. day500 through day1826). I have a variable called time_for_censor that indicates what day to start the missings.
How can I code this in SAS?
I've tried to code it in a loop like this:
array daydummy (1826) day1-day1826;
if time_for_censor ne . then do time_for_censor=1 to 1825;
daydummy(time_for_censor)=.;
daydummy(time_for_censor + 1) =.;
end;
Just loop from the censor date to the end of the array.
array daydummy (1826) day1-day1826;
if not missing(time_for_censor) then do index=time_for_censor to 1826;
daydummy(index)=.;
end;
drop index;
You might need to change the lower bound on the do loop to time_for_censor+1 depending on the whether the values are valid on the censoring date or not.

Combobox value to code

I'm a Pascal newbie and I already read some stuff about it, but it is still pretty hard for me. I want to create a simple password generator, and adjust the number of characters.
I found a function that actually generates the random password for me, which is this:
function RandomPassword(PLen: Integer): string;
var
str: string;
begin
Randomize;
//string with all possible chars
str := 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
Result := '';
repeat
Result := Result + str[Random(Length(str)) + 1];
until (Length(Result) = PLen)
end;
This is the code that prints the string to the Memo:
procedure TForm1.Button2Click(Sender: TObject);
begin
Memo1.Caption := RandomPassword(10);
end;
I also got a TComboBox, and I want to use the value from the combobox to chose the number of characters (6-32). The number of characters is in this case 10 but I want to use the value from the Combobox instead of a predetermined number. Who can help me? I'd appreciate it!
You can select the combobox value like this:
RandomPassword(StrToInt(ComboBox.Items[ComboBox.ItemIndex]))
ComboBox.ItemIndex returns the index of select combobox item
ComboBox.Items[] is used to select a item in the combobox.
StrToInt() is used cause the combobox value is a string and you have to change it to integer

creating array of text files with FPS

Is it possible that FPS program read user input and then creates a file with a name of that input and that read another input and so on and on..?
I have tried to create array of text file but got some problems.
First of all an error occurred that (some) access was denied and secondly, how to create a result file where variable is in the middle of the text file name (I've tried assign (Df,'rezult',i,'.txt'); i - here is changing variable, but in this way program does not work.
P.S. Sorry for my English language skills...
This is what I have tried:
program testing;
var
Df : text;
i:integer;
SomeUserInput:integer;
begin
for i:=1 to 10 do
begin
Assign(Df,'rez.txt'); Rewrite(Df);
Read(SomeUserInput);
WriteLn(Df,'some words + ',SomeUserInput);
Close(Df);
end;
Readln;
end.
(fixed the problem that first comment suggest, but now only last thing is written in my file, I wish to create 10 or more files)
If I understand correctly, you want to number the filename with your loop var.
This should work:
program testing;
Uses
SysUtils;
var
Df : text;
i:integer;
SomeUserInput:integer;
begin
for i:=1 to 10 do
begin
Assign(Df,'rez'+IntToStr(i)+'.txt');
Rewrite(Df);
ReadLn(SomeUserInput);
WriteLn(Df,'some words + ',SomeUserInput);
Close(Df);
end;
Readln;
end.

SAS: Dynamically Setting a Variable Name

In this block of SAS data step code I am setting a Table from an SQL query called TEST_Table. This table contains multiple columns including a larger section of columns titled PREFIX_1 to PREFIX_20. Each column starts with PREFIX_ and then an incrementing number from 1 to 20.
What I would like to do is iteratively cycle through each column and analyze the value of that column.
Below is an example of what I am trying to go for. As you can see I would like to create a variable that increases on each iteration and then I use that count value as a part of the variable name I am checking.
data TEST_Data;
set TEST_Table;
retain changing_number;
changing_number=1;
do while(changing_number<=20);
if PREFIX_changing_number='BAD_IDENTIFIER' then do;
PREFIX_changing_number='This is a bad part';
end;
end;
run;
How would be the best way to do this in SAS? I know I can do it by simply checking each value individually from 1 to 20.
if PREFIX_1 = 'BAD_IDENTIFIER' then do;
PREFIX_1 = 'This is a bad part';
end;
if PREFIX_2 = ...
But that would be really obnoxious as later I will be doing the same thing with a set of over 40 columns.
Ideas?
SOLUTION
data TEST_Data;
set TEST_Table;
array SC $ SC1-SC20;
do i=1 to dim(SC);
if SC{i}='xxx' then do;
SC{i}="bad part";
end;
end;
run;
Thank you for suggesting Arrays :)
You need to look up Array processing in SAS. Simply put, you can do something like this:
data TEST_Data;
set TEST_Table;
*retain changing_number; Remove this - even in your code it does nothing useful;
array prefixes prefix:; *one of a number of ways to do this;
changing_number=1;
do while(changing_number<=20);
if prefixes[changing_number]='BAD_IDENTIFIER' then do;
prefixes[changing_number]='This is a bad part';
end;
end;
run;
A slightly better loop is:
do changing_number = 1 to dim(prefixes);
... loop ...
end;
As that's all in one step, and it is flexible with the number of array elements (dim = number of elements in the array).

How do I write arrays in pascal?

Is this program correctly written with the array?
Program Malaria_Outbreak (input,output);
Var
BC:real;
LO:real;
count:integer;
Num:integer;
BloodTest:integer;
Registration:integer;
Clinic:string;
DoctorFee:integer;
Total:integer;
NMB_Payable:real;
Company:string;
Name:string;
Patient:Array[1..10] of string
Begin
clrscr;
BC:=(0.8);
LO:=(0.7);
Count:=(0);
Num:=(0);
BloodTest:=(Num * 700);
Registration:=(500);
Writeln('Please enter the name of the patient');
Readln(Name);
While (Name <> 'END')Do
Begin
For count:= 1 to 10 Do
Begin
Writeln('Please enter the clinic the patient attends');
Readln(Clinic);
If (Clinic = 'Type 1') Then
Begin
DoctorFee:=(800);
End;
If (Clinic = 'Type 2') Then
Begin
DoctorFee:=(1200);
End;
Writeln('The doctor fee for the patient is $',DoctorFee);
Writeln('Please enter the number of blood tests the patient has had');
Readln(Num);
BloodTest:=(Num * BloodTest);
Writeln('The blood test for the patient is $',BloodTest);
TMB:=(Registration + DoctorFee + BloodTest);
Writeln('The total medical bill for the patient is $',TMB);
Writeln('Please enter the insurance company the clinic is affiliated with');
Readln(Company);
If (Company = 'Blue Cross') Then
Begin
NMB_Payable:=(BC * TMB);
End;
If (Company = 'LOJ') Then
Begin
NMB_Payable:=(LO * TMB);
End;
Writeln('The net medical bill for the patient is $',NMB_Payable);
End;
Readln;
Readln;
End
Looks good, but you might want to include the ; after the datatype (string)
Patient : Array[1..10] of String;
There are some problems in the code.
Your code was not formatted. Especially the lack of indenting makes it hard to understand what's going on. (thanks to GolezTrol for fixing that)
You're missing a semi-colon (;) after Array[1..10] of string
Some end; statement is missing. Either While (Name <> 'END')Do begin or For count:= 1 to 10 Do begin should have a matching end; statement.
Variable Tmb is not declared.
Bloodtest will always be 0. It's initialized to 0, and the only time you write to Bloodtest is on this line: BloodTest := (Num * BloodTest);. That's probably not what you want to do.
DoctorFee is uninitialized unless the user types Type 1 or Type 2. NMB_Payable has a similar problem.
There's a variable Count that's initialized, but never used afterwards. Doesn't do any damage, but for readability I'd clean it up.
To answer your question: No, you're not using the array that's declared, and I don't think this program does what you want it to do.
If you explain what you're trying to accomplish, we can help you out with that.
I don't see where it's writing to the array at all, nor where it would make any use of the array in the first place. It's simply processing each item it gets, nothing is carried to be stored in an array in the first place.
It's also going to ask and bill each patient 10 times. I've heard of double-billing but this is crazy!
You should always run your code and see what actually happens. It's quite obvious you didn't.

Resources