I am making a program that puts different participants in a library with a particular key. I came to the problem where I got a KeyNotFoundException.
Here you can see my code error which was at if (sessionPersonsSchedule[s].Count == s.MaxParticipants)
public bool personAddToLibrary(int personsIn)
{
if (personsIn == participants.Count)
{
return true;
}
else
{
for ( int j = 0; j < participants[personsIn].Preferences.Count; j++ )
{
Participant p = participants[personsIn];
Session s = sessions[p.Preferences[j] - 1];
SessionPersonsSchedule[s]
if (testSessions(s))
{
sessionPersonsSchedule[s].Add(p);
Console.Write(personsIn + ". " + p + "is added to session " + s);
personAddToLibrary(personsIn + 1);
if (personsIn == participants.Count)
{
return true;
}
}
else
{
sessionPersonsSchedule[s].Remove(p);
Console.Write(personsIn + ". " + p + "is deleted from session " + s);
}
}
}
return false;
}
public bool testSessions(Session s)
{
if (sessionPersonsSchedule[s].Count == s.MaxParticipants)
{
return false;
}
else
{
return true;
}
}
The KeyNotFoundException indicates that you are trying to index into the collection with a key that doesn't exist in the collection.
So, before you do sessionPersonsSchedule[s] in testSessions, you can make sure that s exists first by calling Dictionary.ContainsKey.
Related
I am trying to create a command that returns the number of guild members that are currently playing a specified game.
Example (! is my prefix): !playing League of Legends.
If there are 5 members playing League of Legends, output:
There are 5 users currently playing League of Legends.
I set up the following, from debugging I was able to pick up that v.Game.toString() returns the correct string but for some reason the if statement does not trigger. It also catches an exception that is thrown whenever members are not playing a game (I assumed it's null?), is there a workaround for that? Why does this not count how many members are playing a certain game?
[Command("playing")]
public async Task playingGame(params string[] s)
{
string gameName = "";
int count = 0;
for (int i = 0; i < s.Length; i++)
{
gameName += s[i] + " ";
}
await Context.Channel.SendMessageAsync("Looking for: " + gameName);
var u = Context.Guild.Users;
foreach (var v in u)
{
await Context.Channel.SendMessageAsync("v = " + v.ToString());
try
{
await Context.Channel.SendMessageAsync(v.Game.ToString());
if (v.Game.ToString().ToLower().Equals(gameName.ToLower()))
{
count++;
await Context.Channel.SendMessageAsync("Found match, count = " + count);
}
}
catch (Exception x)
{
await Context.Channel.SendMessageAsync("Exception throw caught");
}
}
if (count > 1) {
await Context.Channel.SendMessageAsync("There are " + count + " users currently playing " + gameName + ".");
}
else if (count == 1)
{
await Context.Channel.SendMessageAsync("There is " + count + " user currently playing " + gameName + ".");
}
else if (count == 0)
{
await Context.Channel.SendMessageAsync("No one is currently playing " + gameName + ".");
}
}
This is the exception:
System.ArgumentException: Argument cannot be blank
Parameter name: Content
at Discord.Preconditions.NotNullOrEmpty(String obj, String name, String msg)
at Discord.API.DiscordRestApiClient.<CreateMessageAsync>d__77.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
Pic of where if statement should trigger (username blocked for privacy reasons):
There is no need to have params string[] s for the game parameter. Just use the Remainder attribute.
I have also simplified this code alot :
[Command("playing")]
public async Task GetUsersPlaying([Remainder]string game)
{
await Context.Message.DeleteAsync();
var users = Context.Guild.Users.Where(x => x.Game.ToString() == game).Distinct().Select(x => x.Username);
var count = users.Count();
var SeparatedList = string.Join(", ", users);
string message;
if (count > 1)
message = $"There are {count} users playing {game}. [{SeparatedList}]";
else if (count == 1)
message = $"There is {count} user playing {game}. [{SeparatedList}]";
else
message = $"There is no one playing {game}.";
await Context.Channel.SendMessageAsync(message);
}
I've read many articles but I don't seem to get it. I have this code working now because I hardcode a 3 second delay so there is enough time for the web call to finish so when the score is displayed there is data. But what I really want is to have the web call finish and THEN display the score. Help ?
IEnumerator Start()
{
client = new MobileServiceClient(_appUrl, _appKey);
table = client.GetTable<Highscore>("Highscores");
yield return StartCoroutine(ReadItems());
DisplayScores();
}
void Update()
{
}
public void btn_GoBack()
{
Application.LoadLevel("StartScene");
}
private void OnReadItemsCompleted(IRestResponse<List<Highscore>> response)
{
if (response.StatusCode == HttpStatusCode.OK)
{
Debug.Log("OnReadItemsCompleted data: " + response.Content);
List<Highscore> items = response.Data;
Debug.Log("Read items count: " + items.Count);
Scores = items;
}
else
{
Debug.Log("Error Status:" + response.StatusCode + " Uri: " + response.ResponseUri);
}
}
private IEnumerator ReadItems()
{
table.Read<Highscore>(OnReadItemsCompleted);
yield return new WaitForSeconds(3);
}
private void DisplayScores()
{
txtHighScores.text = "";
int numberOfScores = Math.Min(Scores.Count, 5);
for (int i = 0; i < numberOfScores; i++)
{
string name = Scores[i].username.ToString();
string score = Scores[i].score.ToString();
txtHighScores.text += (i + 1).ToString() + ". " +
" - " + name + "\r\n" +
score.ToString().PadLeft(4, '0');
}
}
It is important to pass a parameter with Startcorutine method,
Otherwise it gives error.
So try my fix in your code.
IEnumerator Start()
{
client = new MobileServiceClient(_appUrl, _appKey);
table = client.GetTable<Highscore>("Highscores");
yield return StartCoroutine(ReadItems(2.0f)); //delay
DisplayScores();
}
IEnumerator ReadItems(float delay)
{
yield return new WaitForSeconds(delay);
table.Read<Highscore>(OnReadItemsCompleted);
}
Remove the method call for "DisplayScores()" from Start()
And insert DisplayScores() as the last line of method callback OnReadItemsCompleted
And then you should remove the line yield return new WaitForSeconds(3);
I have a thread that is supposed to run continuously in my program and parse incoming serial data from a collection of sensors.
//initialized as a global variable
System.Threading.Thread processThread = new System.Threading.Thread(ProcessSerialData);
//this gets called when you press the start button
processThread.Start();
private void ProcessSerialData()
{
while (true)
{
//do a whole bunch of parsing stuff
}
int howDidYouGetHere = 0;
}
How is it possible that my program is reaching the "int howDidYouGetHere = 0" line??
Full code can be found here:
/// <summary>
/// ProcessSerialData thread will be used to continue testing the connection to the controller,
/// process messages in the incoming message queue (actually a linked list),
/// and sends new messages for updated data.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ProcessSerialData()
{
while (true)
{
UpdateAhTextbox(test.ampHoursOut.ToString());
if (!relayBoard.OpenConn())
{
MessageBox.Show("Connection to controller has been lost.");
testInterrupted = "Lost connection. Time = " + test.duration;
UpdateStatusText(false);
ShutErDown();
}
/////////////////////////////////////////////////////
if (incomingData.Count > 0)
{
string dataLine = "";
try
{
dataLine = incomingData.First();
UpdateParsedDataTextbox(dataLine + "\r\n");
}
catch (System.InvalidOperationException emai)
{
break; //data hasn't come in yet, it will by the time this runs next.
}
incomingData.RemoveFirst();
if (dataLine.Contains("GET")) // some sensor values (analog/temp/digital) has come in
{
if (dataLine.Contains("GETANALOG")) // an analog value has come in
{
int index = dataLine.IndexOf("CH");
int pin = (int)Char.GetNumericValue(dataLine[index + 2]);
double value = 0;
int dataLineLength = dataLine.Length;
if (dataLineLength > 13) // value is appended to end of line
{
try
{
value = Convert.ToDouble(dataLine.Substring(13));
}
catch // can't convert to double
{
int index2 = dataLine.IndexOf("CH", 3);
if (index2 != -1) // there happen to be two sets of commands stuck together into one
{
string secondHalf = dataLine.Substring(index2);
incomingData.AddFirst(secondHalf);
}
}
}
else // value is on the next line
{
try
{
value = Convert.ToDouble(incomingData.First());
incomingData.RemoveFirst();
}
catch // can't convert to double
{
MessageBox.Show("Error occured: " + dataLine);
}
}
switch (pin)
{
case 1:
ReadVoltage(value);
break;
case 2:
ReadAmperage(value);
break;
}
}
else if (dataLine.Contains("GETTEMP")) // received reply with temperature data
{
int index = dataLine.IndexOf("CH");
int pin = (int)Char.GetNumericValue(dataLine[index + 2]); // using index of CH, retrieve which pin this message is coming from
double value = 0;
int dataLineLength = dataLine.Length;
if (dataLineLength > 11) // value is appended to end of line
{
try
{
value = Convert.ToDouble(dataLine.Substring(11));
}
catch // can't convert to double
{
int index2 = dataLine.IndexOf("CH", 3);
if (index2 != -1) // there happen to be two sets of commands stuck together into one
{
string secondHalf = dataLine.Substring(index2);
incomingData.AddFirst(secondHalf);
}
}
}
else // value is on the next line
{
value = Convert.ToDouble(incomingData.First());
incomingData.RemoveFirst();
}
ReadTemperature(pin, value);
}
else // must be CH3.GET
{
int index = dataLine.IndexOf("CH");
int pin = (int)Char.GetNumericValue(dataLine[index + 2]); // using index of CH, retrieve which pin this message is coming from
if (pin == 3) // only care if it's pin 3 (BMS), otherwise it's a mistake
{
double value = 0;
int dataLineLength = dataLine.Length;
if (dataLineLength > 7) // value is appended to end of line
{
try
{
value = Convert.ToDouble(dataLine.Substring(7));
}
catch // can't convert to double
{
int index2 = dataLine.IndexOf("CH", 3);
if (index2 != -1) // there happen to be two sets of commands stuck together into one
{
string secondHalf = dataLine.Substring(index2);
incomingData.AddFirst(secondHalf);
}
}
}
else // value is on the next line
{
value = Convert.ToDouble(incomingData.First());
incomingData.RemoveFirst();
}
ReadBMS(value);
}
}
}
else if (dataLine.Contains("REL")) // received reply about relay turning on or off.
{
if (dataLine.Contains("RELS")) // all relays turning on/off
{
if (dataLine.Contains("ON"))
{
for (int pin = 1; pin <= 4; pin++)
{
test.contactors[pin] = true;
}
}
else // "OFF"
{
for (int pin = 1; pin <= 4; pin++)
{
test.contactors[pin] = false;
}
}
}
else // single relay is turning on/off
{
int index = dataLine.IndexOf("REL");
int pin = (int)Char.GetNumericValue(dataLine[index + 3]);
if (dataLine.Contains("ON"))
{
test.contactors[pin] = true;
}
else if (dataLine.Contains("OFF"))
{
test.contactors[pin] = false;
}
else if (dataLine.Contains("GET"))
{
if (Convert.ToInt32(incomingData.First()) == 1)
test.contactors[pin] = true;
else
test.contactors[pin] = false;
incomingData.RemoveFirst();
}
}
}
}
/////////////////////////////////////////////////////
// we only want more data if we're done processing the current data, otherwise we're stuck with too much and processing is heavily delayed.
if (isTestRunning && incomingData.Count < 3)
{
//read & output v, a, bms state
sendToController("CH1.GETANALOG"); // get voltage
sendToController("CH2.GETANALOG"); // get amperage
sendToController("CH3.GET"); // get BMS state
//read & output temperature
sendToController("CH4.GETTEMP"); // get temperature
sendToController("CH5.GETTEMP");
string lines = "Ah Out: " + test.ampHoursOut + ", Voltage: " + test.voltage +
", Amperage: " + test.amperage + ", Cell Temperature: " + test.tempBattery +
", Load Temperature: " + test.tempLoad;
WriteToLog(lines);
}
}
int howDidYouGetHere = 0;
}
The break (ignoring those inside the nested switch) breaks out of the while loop.
Perhaps you have tried to update your UI using UpdateParsedDataTextbox This will cause InvalidOperationException(then breaks the while loop) because you tries to access the UI control from thread that doesn't own the control.
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 8 years ago.
So I have my memory class which looks like this:
namespace GeminiCore
{
public class Memory
{
public static int[] memory = new int[256];
public string nextInstruction;
public static int cacheSize = 8;
public CPU myCPU;
public struct frame
{
public bool dirtyBit;
public int isEmpty;
public int value;
public int tag;
public frame(int cacheSize)
{
dirtyBit = false;
isEmpty = 1;
value = 0;
tag = 0;
}
}
public int solveMemory(int value, int instr, frame[] myCache)
{
Console.WriteLine("I reached the solveMemory!!!");
int block = value % cacheSize;
if(instr == 127 || instr == 125 || instr == 124 || instr == 123
|| instr == 122 || instr == 121|| instr == 120)
{
Console.WriteLine("I reached the read section!!!");
if(myCache[block].isEmpty == 0) //Read hit
if(myCache[block].tag == value)
return myCache[block].value;
else
{
myCache[block].value = memory[value]; //Read Miss
myCache[block].tag = value;
myCache[block].isEmpty = 0;
Console.WriteLine("Read Miss --- The Cache is as follows: block = " + block + " the value at this block is: " + myCache[block].value + " the tag at this block is: " + myCache[block].tag);
return myCache[block].value;
}
}
else
{
Console.WriteLine("I reached the write section!!!");
if (myCache[block].isEmpty == 1) //Write Miss
{
Console.WriteLine("Write Miss --- The Cache is as follows: block = " + block + " the value at this block is: " + myCache[block].value + " the tag at this block is: " + myCache[block].tag);
memory[value] = myCPU.ACC;
}
else
{
if (myCache[block].dirtyBit == false)
{
if (myCache[block].tag != value)
{
myCache[block].value = myCPU.ACC; //Write Hit
myCache[block].dirtyBit = true;
myCache[block].tag = value;
Console.WriteLine("Write Hit --- The Cache is as follows: block = " + block + " the value at this block is: " + myCache[block].value + " the tag at this block is: " + myCache[block].tag);
}
}
else
{
memory[myCache[block].tag] = myCache[block].value;
myCache[block].value = myCPU.ACC;
myCache[block].tag = value;
myCache[block].dirtyBit = false;
Console.WriteLine("Write Hit --- The Cache is as follows: block = " + block + " the value at this block is: " + myCache[block].value + " the tag at this block is: " + myCache[block].tag);
}
}
}
return value;
}
}
}
and then I have my CPU class, and I will just post a small snippet of where the error is occurring:
public Memory myMemory;
public static Memory.frame[] myCache = new Memory.frame[Memory.cacheSize];
public void doInstruction()
{
var instr = (finalCodes[i] >> 9) & 127; //Parses op code to find instruction
var immed = (finalCodes[i] >> 8) & 1; //Parses op code to find immediate value
var value = (finalCodes[i] & 255); //Parse op code to find value
foreach (Memory.frame x in myCache)
{
Console.WriteLine("Dirtybit: " + x.dirtyBit + " isEmpty: " + x.isEmpty + " tag: " + x.tag + " value: " + x.value);
}
switch (instr)
{
case (127): //LDA instruction
if (immed == 1)
ACC = value;
else if (immed == 0)
//ACC = Memory.memory[value];
ACC = myMemory.solveMemory(value, instr, myCache);
break;
case (126): //STA instruction
if (immed == 0)
{
Console.WriteLine("The value is: " + value + " The instruction is: " + instr);
foreach (Memory.frame x in myCache)
{
Console.WriteLine("Dirtybit: " + x.dirtyBit + " isEmpty: " + x.isEmpty + " tag: " + x.tag + " value: " + x.value);
}
//Memory.memory[value] = ACC;
myMemory.solveMemory(value, instr, myCache);
}
So here is my problem, when I run my test which takes in assembly code and translates it to binary then runs through the code, when I get to the second command "sta" it should go to the line:
myMemory.solveMemory(value, instr, myCache);
It then gives me a Null Reference Exception when it reaches that point. As you can see I have some command line output to try and see where it is going. It prints out the contents of myCache right before that line. It does not reach any of the debug statements in the solveMemory function however, not even the first one that says:
Console.WriteLine("I reached the solveMemory!!!");
I'm not really sure what is causing this error and I've been looking at it for quite some time. Hopefully one of you will be able to find where exactly I am messing up. Thanks for the time.
public Memory myMemory;
should be:
public Memory myMemory = new Memory();
return found;
is giving:
Invalid token 'return' in class, struct, or interface member declaration
Code:
public bool IsTextPresent(ISelenium Selenium, string searchText)
{
int count = (int)Selenium.GetXpathCount("//*[#id='resultTable']/table");
string text;
bool found;
for (int i = 1; i <= count; i++)
{
StringBuilder container = new StringBuilder();
for (int j = 4; j <= 8; j += 2)
{
if (Selenium.IsElementPresent("xpath=/html/body/form/div[2]/table[" + (i) + "]/tr[" + (j) + "]/td[4]"))
{
text = Selenium.GetText("xpath=/html/body/form/div[2]/table[" + (i) + "]/tr[" + (j) + "]/td[4]");
container.Append(text + Environment.NewLine);
}
string fullText = container.ToString();
if (!fullText.Contains(searchText))
{
found = false;
}
else
{
found = true;
}
}
}
}
return found;
}
You have too many closing curly braces... Your indented if at end is confusing your number of closing }s:
string fullText = container.ToString();
if (!fullText.Contains(searchText))
{
found = false;
}
else
{
found = true;
}
} // <<<< The indention of the if probably threw you off here...
Your braces mismatch, so the return is outside the function definition.
This part contains one too many }, terminating the method:
string fullText = container.ToString();
if (!fullText.Contains(searchText))
{
found = false;
}
else
{
found = true;
}
} // remove this one
You have placed return found; after the methods closing brace. Align the code properly to see. Use Ctrl-K, Ctrl-D to format the code in Visual Studio.
Really? Count your open and closing braces.