Reputation: 35
First, my apologies if this is posted twice. I think the site may have burped.
I have an apparently impossible requirement for a clinical trials pharma application in my C# course. Please, someone tell me if I'm interpreting this part of the assignment incorrectly (copied verbatim from handout):
"MONTHS NUMBER OF TREATMENTS (use a Switch command)
1 -19 10 -30
20 - 39 31 -60
40 - 59 61 - 100
60 - 79 101 - 130
80 - 99 131 - 180
For Example:
If the randomly chosen # of months is from 20 through 39 - the number of treatments will be a random number from 31 through 60. If the # of months is 82 - the number of treatments is from 131 through 180."
The number of months the patient is available for the trial is input directly into a text box; my code supplies the random ACTUAL months the patient is participating in the clinical trial. I already know that ranges CANNOT be used in switch commands. Since this instructor also teaches Visual Basic, which apparently does support ranges in a switch command, she may have gotten the two confused (which, sadly, happens with alarming frequency). At any rate, everything I have read said this is flatly impossible with a switch case.
I have no idea how to accomplish this without an if/else tree instead of a switch. Can anyone give me any ideas? PLEASE, no regex or LINQ. We are not covering either one.
Here's all of my code. What is here works; file read/write isn't implemented yet, but I already understand that part.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace NallyKProgram3ClinicalTrials
{
public partial class NallyKClinicalTrialsForm : Form
{
public NallyKClinicalTrialsForm()
{ InitializeComponent(); }
private StreamWriter outputFile;
private StreamReader inputFile;
int numberOfMonthsInTrialRangeInteger;
int numberAssignedToPatientInteger;
int numberOfMonthsInTrialInteger;
int numberOfTreatmentPlanInteger;
int numberOfTreatmentsInteger;
// const string CASE_STRING; this attempt didn't work
Random rndNumber = new Random();
Boolean duplicateNameBoolean;
private void NallyKClinicalTrialsForm_Load(object sender, EventArgs e)
{
reportLabel.ResetText();
removePatientButton.Enabled = false;
writeFileButton.Enabled = false;
}
private void addPatientButton_Click(object sender, EventArgs e)
{
if (patientNameTextBox.Text.Trim() != string.Empty)
{
checkForDuplicateNames();
generatePatientNumber(rndNumber);
if (duplicateNameBoolean == false)
{
if (numberOfMonthsTextBox.Text.Trim() != string.Empty)
{
if (int.TryParse(numberOfMonthsTextBox.Text.Trim(), out numberOfMonthsInTrialRangeInteger))
{
if (numberOfMonthsInTrialRangeInteger < 1 || numberOfMonthsInTrialRangeInteger > 99)
{
errorProvider1.SetError(numberOfMonthsTextBox, "The number of months available for participation in this trial must not be less than 1 or greater than 99.");
numberOfMonthsTextBox.Focus();
numberOfMonthsTextBox.SelectAll();
}
else
{
generateNumberOfMonthsInTrial(rndNumber);
generateTreatmentPlan(rndNumber);
// determineCaseString(); NOPE!
// determineNumberOfTreatments(rndNumber); TO DO
addToListBox();
addToNamesListBox();
readFileButton.Enabled = false;
removePatientButton.Enabled = true;
writeFileButton.Enabled = true;
}
}
else
{
errorProvider1.SetError(numberOfMonthsTextBox, "Please enter a number.");
numberOfMonthsTextBox.Focus();
numberOfMonthsTextBox.SelectAll();
}
}
else
{
numberOfMonthsTextBox.Text = " ";
errorProvider1.SetError(numberOfMonthsTextBox, "You must enter a number of months.");
numberOfMonthsTextBox.Focus();
numberOfMonthsTextBox.SelectAll();
}
}
else
{
errorProvider1.SetError(namesListBox, patientNameTextBox.Text + " is a duplicate name. Please enter a different name.");
patientNameTextBox.Focus();
patientNameTextBox.SelectAll();
}
}
else
{
patientNameTextBox.Text = " ";
errorProvider1.SetError(patientNameTextBox, "You must enter a patient name.");
patientNameTextBox.Focus();
patientNameTextBox.SelectAll();
}
}
private void checkForDuplicateNames()
{
int indexInteger = 0;
duplicateNameBoolean = false;
while (indexInteger < namesListBox.Items.Count)
{
if (patientNameTextBox.Text.ToLower().Trim() ==
namesListBox.Items[indexInteger].ToString().ToLower())
{
duplicateNameBoolean = true;
indexInteger = namesListBox.Items.Count;
}
indexInteger++;
}
}
private Random generatePatientNumber(Random rndNumber)
{
numberAssignedToPatientInteger = rndNumber.Next(1000, 9999);
return rndNumber;
}
private Random generateNumberOfMonthsInTrial(Random rndNumber)
{
numberOfMonthsInTrialInteger = rndNumber.Next(1, numberOfMonthsInTrialRangeInteger);
return rndNumber;
}
private Random generateTreatmentPlan(Random rndNumber)
{
numberOfTreatmentPlanInteger = rndNumber.Next(1, 5);
return rndNumber;
}
//private void determineCaseString() NOPE, NOPE, NOPE
//{
// if ((numberOfTreatmentPlanInteger >= 1) && (numberOfTreatmentPlanInteger < 20)) CASE_STRING = "a"; // clever, but error!
// if ((numberOfTreatmentPlanInteger >= 20) && (numberOfTreatmentPlanInteger < 40)) CASE_STRING = "b";
// if ((numberOfTreatmentPlanInteger >= 41) && (numberOfTreatmentPlanInteger < 60)) CASE_STRING = "c";
// if ((numberOfTreatmentPlanInteger >= 60) && (numberOfTreatmentPlanInteger < 80)) CASE_STRING = "d";
// if ((numberOfTreatmentPlanInteger >= 80) && (numberOfTreatmentPlanInteger < 100)) CASE_STRING = "e";
//}
//private Random determineNumberOfTreatments(Random rndNumber)
//{
// numberOfTreatmentsInteger = rndNumber.Next(10, CASE_STRING);
//}
private void addToListBox()
{
patientInformationListBox.Items.Insert(0, numberAssignedToPatientInteger.ToString() + "," + numberOfTreatmentPlanInteger + "," + numberOfMonthsInTrialInteger + "," + Environment.NewLine); // number of treatments goes after the final comma
}
private void addToNamesListBox()
{
namesListBox.Items.Insert(0, patientNameTextBox.Text.Trim());
}
private void exitButton_Click(object sender, EventArgs e)
{
this.Close();
}
private void removePatientButton_Click(object sender, EventArgs e)
{
if (patientInformationListBox.SelectedIndex > -1)
patientInformationListBox.Items.RemoveAt(patientInformationListBox.SelectedIndex);
else MessageBox.Show("You must select an entry you wish to remove from the list.", "SELECT AN ITEM TO REMOVE", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void patientNameTextBox_TextChanged(object sender, EventArgs e)
{
errorProvider1.SetError(patientNameTextBox, "");
errorProvider1.SetError(patientInformationListBox, "");
}
private void numberOfMonthsTextBox_TextChanged(object sender, EventArgs e)
{
errorProvider1.SetError(numberOfMonthsTextBox, "");
}
}
}
Upvotes: 0
Views: 157
Reputation: 391456
You're right in that C# does not allow you to use ranges in the switch-statement. In fact, C# only allows you to write a case X:
where X
is a single constant literal value.
However, C# does allow you to fall through from one case to another, and thus allows you to list all the cases for which you can write one single body of code to execute.
As such, you can write the code like this:
switch (months)
{
case 1:
case 2:
case 3:
...
case 19:
treatments = r.Next(10, 31);
break;
case 20:
case 21:
case 22:
...
case 39:
treatments = r.Next(30, 61);
break;
case 40:
...
Now, is that the best you can do?
No. You can notice a pattern in the ranges here. Each range goes from X to X+19, where X is a number divisible by 20, so you can use the fact that integer division will truncate downwards:
int monthsSection = months / 20; // 0-19 --> 0, 20-39 --> 1, etc.
switch (monthsSection)
{
case 0: // 0-19
treatments = r.Next(10, 31);
break;
case 1: // 20-39
treatments = r.Next(30, 61);
break;
case 2: // 40-59
...
Yes, this will include 0 as well. If that is a problem then I would simply add a specific if-statement in front to filter it out.
Upvotes: 4
Reputation: 7341
If you have to use a switch, you could divide your months by 20, and then do a switch on that. Something like this:
int monthValue = numberOfTreatmentPlanInteger / 20;
switch (monthValue)
{
case 0:
// between 10 and 30 treatments
break;
case 1:
// between 31 and 60 treatments
break;
case 2:
// between 61 and 100 treatments
break;
// and so on
}
Upvotes: 1