Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
Here is my code thus far; my main problem is in the main method.
namespace Lab
{
class dailyMenu
{
public static int r;
public string day;
public int date;
public string entree;
public double price;
public int calories;
public static int assignDate = 1;
public string Day
{
get { return day; }
set { day = value; }
}
public int Date
{
get { return date; }
set { date = value; }
}
public string Entree
{
get { return entree; }
set { entree = value; }
}
public double Price
{
get { return price; }
set { price = value; }
}
public int Calories
{
get { return calories; }
set { calories = value; }
}
private static string[] DayArray = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" , "Saturday" , "Sunday" };
private static string[] EntreeArray = { "Pizza", "Spaghetti", "Cheeseburger", "Salad", "Soup", "Sandwich", "Pork", "Roast Chicken", "Kebab", "Steak", "Tacos", "Risotto" };
private static double[] PriceArray = { 2.50, 4.00, 1.50, 1.50, 1.50, 3.00, 3.50, 3.00, 2.50, 4.00, 3.00, 2.00 };
private static int[] CalorieArray = { 300, 600, 650, 270, 190, 680, 250, 300, 180, 250, 350, 600 };
public static void DayofMonth(int date)
{
date = assignDate;
assignDate++;
if (date == 5 || date == 12 || date == 19 || date == 26)
{
assignDate += 2;
}//end if
}// end DateofMonth
public static void DayofWeek (int day)
{
day = (day % 7) - 1;
}// end DayofWeek
public void randomItem()
{
Random rnd = new Random();
r = rnd.Next(0, 12);
this.entree = EntreeArray[r];
this.calories = CalorieArray[r];
this.price= PriceArray[r];
}// end randomItem
public dailyMenu()
{
randomItem();
}
static void Main(string[] args)
{
// Populates the 2D array
dailyMenu [,] day = new dailyMenu [4, 5];
for (int row = 0; row < 4; row ++)
{
for (int column = 0; column < 5; column++)
{
day[row, column] = new dailyMenu();
for (int i; r < Length.day; i++)
{
Console.WriteLine(r);
}
}//end forloop column
}// end forloop row
}//end Main
}//end dailyMenu
}//end namespace
I am trying to print out a new instance of DailyMenu with the three arrays using a for loop in Main, however the error message I'm getting is "The name Length does not exist in the current context."
Any help, please? Thanks.
You need to use day.Length not Length.day. day is your variable -- an array -- and it has a Length property.
One of the biggest problem I see with your code has to do with correctly naming your variables. Your class has a String property named 'day', you also declare a dailyMenu variable named 'day' in your main function and you also have an int parameter named 'day' in the DayOfWeek function. Talk about not helping with confusion. Name your things properly and you will have less problems.
Related
This question already has answers here:
Use a variable from another method in C#
(2 answers)
Closed 1 year ago.
Im sorting sellers in a data table. If a seller reach a curtain amount it will stand "Amount of sellers in lvl 4 is "X" ".
If I print the values for my if-statments it works. I get 1 salesman in each label for all my levels.
Now the problem is that if another salesman has the same amount the label wont update and it will still stand that 1 seller has reached that amount.
foreach (DataRow Drow in information.Rows)
{
int num = dataGridView1.Rows.Add();
dataGridView1.Rows[num].Cells[0].Value = Drow["Namn"].ToString();
dataGridView1.Rows[num].Cells[1].Value = Drow["Personnummer"].ToString();
dataGridView1.Rows[num].Cells[2].Value = Drow["Distrikt"].ToString();
dataGridView1.Rows[num].Cells[3].Value = Drow["Antal artiklar"];
WhatLevel(salesman);
}
public void WhatLevel(Salesman sales)
{
int levelOne = 0;
int levelTwo = 0;
int levelThree = 0;
int levelFour = 0;
if (sales.AmountSold < 50)
{
levelOne++;
label8.Text = levelOne.ToString();
}
if (sales.AmountSold >= 50 && sales.AmountSold < 99)
{
levelTwo++;
label12.Text = levelTwo.ToString();
}
if (sales.AmountSold >= 100 && sales.AmountSold < 199)
{
levelThree++;
label13.Text = levelThree.ToString();
}
if (sales.AmountSold >= 199)
{
levelFour++;
label14.Text = levelFour.ToString();
}
}
You have defined 4 local variables within the WhatLevel method. The scope of these 4 variables is limited to that method. Also, when the method is called, they are always initialized to zero before being incremented.
You'll have to do one of the following:
Make the 4 level* variables be fields instead. That will preserve the value across calls to WhatLevel.
If the WhatLevel method is only being called from within the foreach loop, move its content directly into the loop and avoid a separate method altogether, then place the declaration of the variables before the foreach loop.
I agree with Julius solution but i want to add some remarks.
You don't need to update label.Text in every iteration. You can do it at the end of the loop.
Based on single responsibility rule, i think it's better to add a property or a method to get level from salesman class.
finally use a collection to store number of level, imagine you have 10 or 20 levels.
I suggest this solution
Add a new property to the salesman class
public class Salesman
{
public int AmountSold { get; set; }
// Can be a method if you don't want to have property with a lot of code
public int Level
{
get
{
if (AmountSold < 50)
{
return 1;
}
if (AmountSold >= 50 && AmountSold < 99)
{
return 2;
}
if (AmountSold >= 100 && AmountSold < 199)
{
return 3;
}
// AmountSold >= 199
return 4;
}
}
}
Change implementation
Dictionary<int, int> levelNumbers = new Dictionary<int, int>
{
{ 1 , 0 },
{ 2 , 0 },
{ 3 , 0 },
{ 4 , 0 }
};
foreach (DataRow Drow in information.Rows)
{
int num = dataGridView1.Rows.Add();
dataGridView1.Rows[num].Cells[0].Value = Drow["Namn"].ToString();
dataGridView1.Rows[num].Cells[1].Value = Drow["Personnummer"].ToString();
dataGridView1.Rows[num].Cells[2].Value = Drow["Distrikt"].ToString();
dataGridView1.Rows[num].Cells[3].Value = Drow["Antal artiklar"];
levelNumbers[salesman.Level]++;
}
label8.Text = levelNumbers[1].ToString();
label12.Text = levelNumbers[2].ToString();
label13.Text = levelNumbers[3].ToString();
label14.Text = levelNumbers[4].ToString();
If you want more flexibility and maybe lisibility you can use enum
public enum AmountSoldLevel
{
One,
Two,
Three,
Four
}
In the class return AmountSoldLevel instead of int
public AmountSoldLevel Level
{
get
{
if (AmountSold < 50)
{
return AmountSoldLevel.One;
}
// ...
}
}
and init dictionary using
Dictionary<AmountSoldLevel, int> levelNumbers = new Dictionary<AmountSoldLevel, int>();
foreach (AmountSoldLevel amountSoldLevel in Enum.GetValues(typeof(AmountSoldLevel)))
{
levelNumbers.Add(amountSoldLevel, 0);
}
// ...
label8.Text = levelNumbers[AmountSoldLevel.One].ToString();
label12.Text = levelNumbers[AmountSoldLevel.Two].ToString();
Sample test with app
so i have this question :
"1. The word 'virile' means what?\na. Like a rabbit\nb. Like a man\nc. Like a wolf\nd. Like a horse\n"
As you can see its one string separated with \n for each choice . (a , b , c , d )
so i wrote a code to check where is the answer whether its on a , b , c or d
ans = "Like a man";
if (data.Content.StartsWith("a") && data.Content.Contains(ans))
{
Reply("a");
}
else if (data.Content.StartsWith("b") && data.Content.Contains(ans))
{
Reply("b");
}
else if (data.Content.StartsWith("c") && data.Content.Contains(ans))
{
Reply("c");
}
else if (data.Content.StartsWith("d") && data.Content.Contains(ans))
{
Reply("d");
}
It give me 'a' as it's the answer. I know why , its because im using Startwith , which it's wrong because the (data.content) starts with the question its self since its one string .
my question is :
how i can make the program look for any match in the question for my answer then write whatever it was a , b , c or d
Maybe this LINQ solution will be helpful:
string input = "1. The word 'virile' means what?\na. Like a rabbit\nb. Like a man\nc. Like a wolf\nd. Like a horse\n";
string[] inputSplit = input.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
string ans = "Like a man";
string result = new string(inputSplit.Where(x => x.Contains(ans))
.Select(x => x[0]).ToArray());
Reply(result);
result= b
Check if this helps you.
private string question = "1. The word 'virile' means what?\na. Like a rabbit\nb. Like a man\nc. Like a wolf\nd. Like a horse\n"; // your question
string ans = "Like a man"; // your answer
string[] allAnswers = question.Split('\n');
for (int i = 1; i < 5; i++) { // index 0 contains the question
if (answers[i].Contains(ans)) {
Reply(answers[i][0].ToString()); // toString since [0] returns the first char, in your case will be the answer.
}
}
public char GetQuestionRef(string question, string answer)
{
string[] answers = question.Split('\n');
char question;
for(int i = 1; i < answers.Length; i++)
{
if(answers[i].Contains(answer))
{
question = answers[i].Substring(0, 1);
}
}
return question;
}
Another way to do this is to create a class that holds the properties of a "quiz item", such as the Question, a list of Possible Answers, and the Correct Answer Index. We can also give this class the ability to ask the question, display the answers, get a response from the user and then return true or false if the response is correct.
For example:
public class QuizItem
{
public string Question { get; set; }
public List<string> PossibleAnswers { get; set; }
public bool DisplayCorrectAnswerImmediately { get; set; }
public int CorrectAnswerIndex { get; set; }
public bool AskQuestionAndGetResponse()
{
Console.WriteLine(Question + Environment.NewLine);
for (int i = 0; i < PossibleAnswers.Count; i++)
{
Console.WriteLine($" {i + 1}. {PossibleAnswers[i]}");
}
int response = GetIntFromUser($"\nEnter answer (1 - {PossibleAnswers.Count}): ",
1, PossibleAnswers.Count);
if (DisplayCorrectAnswerImmediately)
{
if (response == CorrectAnswerIndex + 1)
{
Console.WriteLine("\nThat's correct, good job!");
}
else
{
Console.WriteLine("\nSorry, the correct answer is: {0}",
$"{CorrectAnswerIndex + 1}. {PossibleAnswers[CorrectAnswerIndex]}");
}
}
return response == CorrectAnswerIndex + 1;
}
// This helper method gets an integer from the user within the specified bounds
private int GetIntFromUser(string prompt, int min, int max)
{
int response;
do
{
Console.Write(prompt);
} while (!int.TryParse(Console.ReadLine(), out response) ||
response < min || response > max);
return response;
}
}
Now that we have a class that represents a QuizItem, we can create another class to represent the Quiz itself. This class would have a list of quiz items, would be able to present each item to the user, save the responses, and display the results of the quiz.
For example:
public class Quiz
{
public Quiz(User user)
{
if (user == null) throw new ArgumentNullException(nameof(user));
User = user;
QuizItems = new List<QuizItem>();
}
public List<QuizItem> QuizItems { get; set; }
public User User { get; set; }
public DateTime StartTime { get; private set; }
public DateTime EndTime { get; private set; }
public void BeginTest()
{
Console.Clear();
if (QuizItems == null)
{
Console.WriteLine("There are no quiz items available at this time.");
return;
}
Console.WriteLine($"Welcome, {User.Name}! Your quiz will begin when you press a key.");
Console.WriteLine($"There are {QuizItems.Count} multiple choice questions. Good luck!\n");
Console.Write("Press any key to begin (or 'Q' to quit)...");
if (Console.ReadKey().Key == ConsoleKey.Q) return;
Console.SetCursorPosition(0, Console.CursorTop);
Console.Write(new string(' ', Console.WindowWidth));
Console.SetCursorPosition(0, Console.CursorTop - 1);
var itemNumber = 1;
StartTime = DateTime.Now;
foreach (var item in QuizItems)
{
Console.WriteLine($"Question #{itemNumber}");
Console.WriteLine("-------------");
itemNumber++;
var result = item.AskQuestionAndGetResponse();
User.QuestionsAnswered++;
if (result) User.CorrectAnswers++;
}
EndTime = DateTime.Now;
var quizTime = EndTime - StartTime;
Console.WriteLine("\nThat was the last question. You completed the quiz in {0}",
$"{quizTime.Minutes} minues, {quizTime.Seconds} seconds.");
Console.WriteLine("\nYou answered {0} out of {1} questions correctly, for a grade of '{2}'",
User.CorrectAnswers, User.QuestionsAnswered, User.LetterGrade);
}
}
This class makes use of a User class, which is used to store the user name and their results:
public class User
{
public User(string name)
{
Name = name;
}
public string Name { get; set; }
public int QuestionsAnswered { get; set; }
public int CorrectAnswers { get; set; }
public string LetterGrade => GetLetterGrade();
private string GetLetterGrade()
{
if (QuestionsAnswered == 0) return "N/A";
var percent = CorrectAnswers / QuestionsAnswered * 100;
if (percent < 60) return "F";
if (percent < 63) return "D-";
if (percent < 67) return "D";
if (percent < 70) return "D+";
if (percent < 73) return "C-";
if (percent < 77) return "C";
if (percent < 80) return "C+";
if (percent < 83) return "B-";
if (percent < 87) return "B";
if (percent < 90) return "B+";
if (percent < 90) return "A-";
if (percent < 97) return "A";
return "A+";
}
}
This seems like a lot of work, but if you're going to ask a lot of questions, it will save time in the end by reducing duplicated code and encapsulating functionality in separate classes and methods. Adding new features will be easier, too.
To use these classes, we can simply instantiate a new Quiz class, pass it a User, populate the QuizItems, and then call BeginTest:
private static void Main()
{
Console.Write("Please enter your name: ");
var userName = Console.ReadLine();
var quiz = new Quiz(new User(userName));
PopulateQuizItems(quiz);
quiz.BeginTest();
GetKeyFromUser("\nDone!! Press any key to exit...");
}
I put the code to populate the quiz items in a separate method, in order to reduce the clutter in the Main method. Right now it just has your single question:
private static void PopulateQuizItems(Quiz quiz)
{
if (quiz == null) return;
quiz.QuizItems.Add(new QuizItem
{
Question = "What does the word 'virile' mean?",
PossibleAnswers = new List<string>
{
"Like a rabbit",
"Like a man",
"Like a wolf",
"Like a horse"
},
CorrectAnswerIndex = 1,
DisplayCorrectAnswerImmediately = true
});
}
Then it looks something like this:
public class dailyMenu
{
private string day="";
private int date = 0;
private static int nextDate=1;
private string entree ="";
private double price;
private double calories;
private static string [] daysOfWeek= {"Monday","Tuesday","Wednesday",
"Thursday", "Friday", "Saturday", "Sunday"};
private static string[] entrees = {"Beef Tenderloin Fresco",
"Madagascar Filet Mignon", "Filet Mignon", " Lobster Ravioli",
"Asian Infused Braised Beef", "New Age Chicken Cordon Bleu",
"Short Ribs", " Beef Wellington","Fajitas", "Bacon Cheeseburger",
"Beef Burgandy", "Spagehetti"};
private static double [] entreePrices= { 5.99,7.99,6.99,4.50,9.99,10.29,
5.67,8.99, 3.99,4.78,10,79,6.98};
private static int[] entreeMealCaloricVal= { 999,1288,770,699,450,999,1500,873, 911,
1011, 777,500};
public dailyMenu()
{
assignDate();
GetDay();
RandPopulate();
}
void assignDate()
{
date = nextDate;
nextDate++;
if (GetDay()== "Friday")
{
nextDate += 2;
}
}
void RandPopulate()
{
Random random = new Random();
int randomNumber = random.Next(0,13);
entree = entrees [randomNumber];
price = entreePrices [randomNumber];
calories = entreeMealCaloricVal [randomNumber];
}
}
The IDE is telling me that line 56, 41, and 14 could be the problem so I'm guessing it has something to do with my random number generator.
Can someone give me a hand?
looks like entrees and entreeMealCaloricVal contain 12 items. That means they'll be indexed from 0 to 11.
Using random.Next(0,13) will generate a number from 0 to 12. When you try to access those arrays at index 12, your exception gets thrown.
I have been noodling around in C# and I am doing well so far but I am trying to find out how to Search an index in a multi dimensional array. I have an array which is for products made in each day. This displays the products made each day for each week by asking the user for input (using an InputBox) E.g. Week 1 Monday = 10 Bears, Wednesday = 20 Bears. Week 2 Tuesday = 30, Friday = 11, etc. I know about the IndexOf but this is for finding the index of a given value. I want to search the index and find and display the value.
The code is below:
class Day
{
private string monday;
private string tuesday;
private string wednesday;
private string thursday;
private string friday;
public string Monday
{
get { return monday; }
set { monday = value; }
}
public string Tuesday
{
get { return tuesday; }
set { tuesday = value; }
}
public string Wednesday
{
get { return wednesday; }
set { wednesday = value; }
}
public string Thursday
{
get { return thursday; }
set { thursday = value; }
}
public string Friday
{
get { return friday; }
set { friday = value; }
}
}
private void btnSelect_Click(object sender, EventArgs e)
{
Day[] week = new Day[4];
//Week[0] = new Day(); Ask users for input box value
E.g.Monday = Microsoft.VisualBasic.Interaction.InputBox("Enter the amount of products made on Monday for week 1", "Product Amount"),etc
//Prints the amounts
txtOutput.Text += "The product allocation is as follows:" + "\r\n" + "\r\n";
txtOutput.Text += " Mon Tue Wed Thu Fri \r\n";
int weeknum = 0;
//Iterates through and shows the values for each day of the week.
foreach (Day days in week)
{
weeknum++;
if (days != null)
{
txtOutput.Text += "Week " + weeknum + " " + days.Monday + " " + days.Tuesday + " " + days.Wednesday + " " + days.Thursday + " " + days.Friday + "\r\n";
}
}
}
"I want to search the index and find and display the value."
Sorry I might not be answering your question, but this sounds like a perfect use-case for Dictionary.
IDictionary<string, int> database = new Dictionary<string, int>
{
{"Week1 Monday", 10},
{"Week1 Wednesday", 20}
};
var userinput = "Week1 Monday";
int numberOfBears;
database.TryGetValue(userinput, out numberOfBears);
//numberOfBears = 10
For more information, you can refer to http://www.dotnetperls.com/dictionary
You'll need to loop through the array using the Array.GetLowerBound and Array.GetUpperBound methods. The Array.IndexOf and Array.FindIndex methods don't support multidimensional arrays.
For example:
string[,,] data = new string[3,3,3];
data.SetValue("foo", 0, 1, 2 );
for (int i = data.GetLowerBound(0); i <= data.GetUpperBound(0); i++)
for (int j = data.GetLowerBound(1); j <= data.GetUpperBound(1); j++)
for (int k = data.GetLowerBound(2); k <= data.GetUpperBound(2); k++)
Console.WriteLine("{0},{1},{2}: {3}", i, j, k, data[i,j,k]);
You might also find the Array.GetLength method and Array.Rank property useful. I recommend setting up a small multidimensional array and using all these methods and properties to get an idea of how they work.
There are no built-in functions for multidimensional array like Array.Find().
You basically have two choices: create your own helper methods and implement a generic search pattern there, or generate a list of domain objects correlating to the contents of the multidimensional array. I personally have tended to choose the latter option.
If you choose to write a helper method, it could look something (very roughly) like this:
// you could easily modify this code to handle 3D arrays, etc.
public static class ArrayHelper
{
public static object FindInDimensions(this object[,] target,
object searchTerm)
{
object result = null;
var rowLowerLimit = target.GetLowerBound(0);
var rowUpperLimit = target.GetUpperBound(0);
var colLowerLimit = target.GetLowerBound(1);
var colUpperLimit = target.GetUpperBound(1);
for (int row = rowLowerLimit; row < rowUpperLimit; row++)
{
for (int col = colLowerLimit; col < colUpperLimit; col++)
{
// you could do the search here...
}
}
return result;
}
}
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
lets say I have 5 outcomes
Console.WriteLine("1");
Console.WriteLine("2");
Console.WriteLine("3");
Console.WriteLine("4");
Console.WriteLine("5");
I want to randomly do one of the above actions using weights so lets say their weights start at 100.
it randomly prints 1 and lowers its weight by 5, making its weight 95.
so after this has done the weights in ascending order are (95, 100, 100, 100, 100) so all the 100 weights have a 5% chance of randomly being chosen over 95 but 95 still has a chance of being randomly picked but not as much as the others.
sample output:(console output)
1 (weight = 95)
3 (weight = 95)
1 (weight = 90)
5 (weight = 95)
1 (weight = 85)
2 (weight = 95)
No idea why you would be messing around with nested case statements.
Every time you need to generate a new random number, add up your weights.
Then use Random.Next(sumOfWeights).
Then compare your returned random number to the first weight, the sum of the first two weights, the sum of the first three weights, etc., until it is less than.
That's your selection. Then reduce that weight by 5.
Here is a simple code, If I understood well, what you need, you can use this, as a starting point:
class Program
{
static void Main(string[] args)
{
List<ActionWithChance> list = new List<ActionWithChance>()
{
new ActionWithChance("1", 100),
new ActionWithChance("2", 100),
new ActionWithChance("3", 100),
new ActionWithChance("4", 100),
new ActionWithChance("5", 100)
};
for (int i = 0; i < 10; i++)
{
RandomHandler.CreateIntervals(list);
RandomHandler.GetRandom(list);
}
}
}
static class RandomHandler
{
public static void CreateIntervals(List<ActionWithChance> list)
{
int currentBorderMin = 1;
int currentBorderMax = 0;
foreach (var actionWithChance in list)
{
actionWithChance.TempMin = currentBorderMin;
actionWithChance.TempMax = currentBorderMax
+ actionWithChance.Chance;
currentBorderMax = actionWithChance.TempMax;
currentBorderMin = currentBorderMax;
}
}
public static void GetRandom(List<ActionWithChance> list)
{
Thread.Sleep(20);
int allChance = list.Sum(i => i.Chance);
Random rand = new Random();
int nextValue = rand.Next(1, allChance + 1);
ActionWithChance selectedAction =
list.FirstOrDefault(i => i.TempMin <= nextValue && i.TempMax >= nextValue);
selectedAction.Chance = selectedAction.Chance > 5
? selectedAction.Chance - 5 : 100;
selectedAction.DoSomething();
}
}
class ActionWithChance
{
public string Name { get; set; }
public int Chance { get; set; }
public int TempMin { get; set; }
public int TempMax { get; set; }
public void DoSomething()
{
Console.WriteLine(Name);
}
public ActionWithChance(string name, int chance)
{
Name = name;
Chance = chance;
}
}
Another Approach:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace RandomWeights
{
public class WeightedItem
{
public string Text { get; set; }
public int Weight { get; set; }
public WeightedItem(string text, int weight)
{
Text = text;
Weight = weight;
}
}
public class WeightedOutput
{
public static readonly int _decreaseIncrement = 5;
List<WeightedItem> items = new System.Collections.Generic.List<WeightedItem>();
public WeightedOutput()
{
//initialize the five items with weight = 100
for (int i = 1; i <= 5; i++)
items.Add(new WeightedItem(i.ToString(), 100));
for (int x = 0; x < 50; x++)
WriteSelected();
Console.ReadLine();
}
public void WriteSelected()
{
WeightedItem selectedItem = GetItem();
if (selectedItem != null)
Console.WriteLine(selectedItem.Text + ": " + selectedItem.Weight);
else
Console.WriteLine("All items have 0 probability of getting selected");
}
public WeightedItem GetItem()
{
int totalWeight = items.Sum(x=>x.Weight);
Random rnd = new Random((int)DateTime.Now.Ticks);
int random = rnd.Next(0, totalWeight);
WeightedItem selected = null;
foreach (var item in items)
{
if (random < item.Weight && item.Weight > 0)
{
//need a new item and not a reference to get the right weights
selected = new WeightedItem(item.Text, item.Weight);
//decrease item's weight
item.Weight -= _decreaseIncrement;
break;
}
random -= item.Weight;
}
return selected;
}
}
}