I'm new to code so the only way I know how to increment is += and ++
Sorry if it's wrong not near PC but will correct it later.
public string variable1
public int variable2
if(variable1.Contains ("24:59")
variable2 += 1
This should return 1 but instead returns 7
variable 1 is a clock script I found witch starts at 0:00 and restarts at 24:59
variable 2 is for the date when the clock hits 24:59 it should increment by 1, so it should be day 1, day 2, day 3
my problem appears to be that 24:59 is true long enough to increment the value up to 7 instead of 1
I want this If statement to stop once it run its function 1 time
public bool testBool = false;
public int testInt;
if (testBool == true)
{
testInt++;
}
My main issue is how to stop an if statement that stays true for longer than expected
As your question is tagged with Unity3D I assume this code is running inside an Update() method. What I think is happening is that your code is ran at least 7 times a second (hopefully way more) and for each time this check is true your counter increments once.
There are several ways to solve this. One would be to use the DateTime datatype so you don't need to do any of this in the first place.
The other would be to save the time you check in a _previousTime variable and then see what the difference is between the new time and the old time.
private string _lastTime;
private string time;
private string rollOverCounter = 0;
private const string rolloverTime = "23:59"
public void Update(){
const wasRollingOver = string.Equals("23:59", _lastTime);
const isRollingOver = string.Equals("23:59", time);
if(wasRollingOver && !isRollingOver){
rollOverCounter++;
}
_lastTime = time;
}
There are more performant and less error prone ways of going about this, but this solution quite readable and answers your question I think.
If you see a performance impact (because you'll be doing this every frame) or you bump into the limitations of represeting time with a string I suggest looking into ways to solve this problem with a more appropriate data type like datetime or an integer with some divisions.
Related
My if statement runs even if the condition is not true. Variable as already been change in the first loop but due to getkeydown event it keeps looping 4 times
Just to introduce i'm making this with C# in Unity and diferent from other process it runs by frames, so each frame it will run the code again.
So basically I'm verifying if the user as pass a situation, if not, the code will enter in the if statement and give a new value to the array index (situacao[8]) my problem is due to GetKeyDown it will run 4 times until the frame is updated (or so i read in another post).
It should be simple, since i change the value to 1 it should not enter in the if again.
if (Input.GetKeyDown(KeyCode.Space))
{
meuEstado = estado.Cela;
}
else if (Input.GetKeyDown(KeyCode.G))
{
print(situacao[8]);
texto.text = "He look for the Window.";
if (situacao[8] != 1)
{
texto.text += "\nand notice there is a bird there!";
situacao[8] = 1;
}
}
The print output is 0 - 1 - 1 - 1 but it should just give a 0. It's not showing any console errors.
PROBLEM DISCOVER:
I had 4 textboxes associated to the same script all of them were also variable assigned.
SOLUTION:
Just add a script to one object and associate the other objects there
You're printing before you check if the value is 1, so it will always print the current value of situacao[8], which is 0 the first time, then 1 for every time after that.
If you only want it to print when situacao[8] is not 1, consider moving it inside the if statement like so:
else if (Input.GetKeyDown(KeyCode.G))
{
texto.text = "He look for the Window.";
if (situacao[8] != 1)
{
print(situacao[8]);
texto.text += "\nand notice there is a bird there!";
situacao[8] = 1;
}
}
Including this script on exactly one gameobject instead of 4 will result in only "0" being printed for the first press, and for no further presses.
I apologize in advance that the title might be very confusing, but I wasn't sure how else to explain this due to my English issue.
I have a form application written in C# using VS2008, and it constantly reads data from an external device. The data read is either 0 (OFF) or 1 (ON). Most of the time, it stays 0, but when something occurs in the system, it becomes 1 and stays 1 for 5 seconds and goes back to 0.
What my program needs to do is to always watch the value change from 0 to 1, and count the number of the occurrences of catching the 1.
The problem is, sometimes the external device has a mistake and changes the value from 0 to 1 on accident for a second or less.
My program needs to ignore and not count the occurrence if the value change from 0 to 1 lasted for less than 1 second, and accept and count the occurrence if the value change from 0 to 1 lasted for 2 seconds out of the 5 seconds life.
I am thinking that basically I can just increment the count only if it stays 1 for more than 2 seconds, and do nothing otherwise.
I tried to use Thread.Sleep(2000), but it does not work, and I don't think this is the right way, but I haven't found a solution to achieve this.
private int data; //will contain the data read from the ext. device
private int occurrence = 0;
//Tick runs every 100 seconds
private void MyTick(object sender, EventArgs e)
{
//if data becomes 1
if(data == 1)
{
Thread.Sleep(2000); //wait 2 seconds??? does not work
//if the data stays 1 for 2 seconds, it is a valid value
if(?????)
{
occurrence++; //count up the occurrence
}
}
}
Can someone please give me some advice on what I can do to achieve this?
You can track the time point when the switch from 0 to 1 has been detected and then check the length of that time period.
Something like this:
private int occurrence;
private int data;
private int previousData;
private DateTime? switchToOne;
private void MyTick(object sender, EventArgs e)
{
if (data == 1 && previousData == 0) // switch detected
{
switchToOne = DateTime.Now; // notice the time point when this happened
}
// if the current value is still 1
// and a switch time has been noticed
// and the "1" state lasts for more than 2 seconds
if (data == 1 && switchToOne != null && (DateTime.Now - switchToOne.Value) >= TimeSpan.FromSeconds(2))
{
// then count that occurrence
occurrence++;
// and reset the noticed time in order to count this occurrence
// only one time
switchToOne = null;
}
previousData = data;
}
Note that DateTime is not very accurate.
If you need to perform very accurate time measurements, you will need to use Stopwatch. But since you're using a Timer (I'm inferring this from your event handler) which is not accurate anyway, I could suppose that the DateTime resolution will suit your needs.
I wonder how I can get the duration between 2300 and 0100, which should be 0200, but it returns 2200. Im working on an application with Xamarin.Forms and use two TimePickers which returns a TimeSpan.
private TimeSpan CalculateDuration()
{
var result = timePickerEnd.Time.Subtract(timePickerStart.Time);
return result.Duration();
}
As long as the startTime is smaller then the endTime, everything works fine. But if someone starts something at 2300 and ends at 0100 it returns 22. I wonder if anyone have some guidelines how i should attack this problem.
You have specific rules, you have to implement them:
var ts1 = timePickerStart.Time;
var ts2 = timePickerEnd.Time;
var difference= ts2.Subtract(ts1);
if(ts1 > ts2)
{
difference= difference.Add(TimeSpan.FromHours(24));
}
return difference;
Because the rule that you've failed to articulate (that I've guessed at above) is that "if the start time is greater than the end time, then they should be interpreted as occurring on successive days" - which is by no means a universal assumption that the system should make.
I am trying to build a help function in my guess the number game, whereby the user gets the first digit of the number he/she has to guess. So if the generated number is 550, he will get the 5.
I have tried a lot of things, maybe one of you has an idea what is wrong?
public partial class Class3
{
public Class3()
{
double test = Convert.ToDouble(globalVariableNumber.number);
while (test > 10)
{
double firstDigit = test / 10;
test = Math.Round(test);
globalVariableNumber.helpMe = Convert.ToString(firstDigit);
}
}
}
Under the helpButton clicked I have:
private void helpButton_Click(object sender, EventArgs e)
{
label3.Text = globalVariableNumber.helpMe;
label3.AutoSize = true;
That is my latest try, I putted all of this in a custom class. In the main I putted the code to show what is in the helpMe string.
If you need more code please tell me
Why not ToString the number and use Substring to get the first character?
var number = 550;
var result = number.ToString().Substring(0, 1);
If for some reason you dont want to use string manipulation you could do this mathematically like this
var number = 550;
var result = Math.Floor(number / Math.Pow(10, Math.Floor(Math.Log10(number))));
What's wrong - you have an infinite while loop there. Math.Round(test) will leave the value of test unchanged after the first iteration.
You may have intended to use firstDigit as the variable controlling the loop.
Anyway, as suggested by others, you can set helpMe to the first digit by converting to a string and using the first character.
As an aside, you should consider supplying the number as a parameter and returning the helpMe string from the method. Your current approach is a little brittle.
The problem with your code is that you are doing the division and storing that in a separate variable, then you round the original value. That means that the original value only changes in the first iteration of the loop (and is only rounded, not divided), and unless that happens to make the loop condition false (i.e. for values between 10 and 10.5), the loop will never end.
Changes:
Use an int intead of a double, that gets you away from a whole bunch of potential precision problems.
Use the >= operator rather than >. If you get the value 10 then you want the loop to go on for another iteration to get a single digit.
You would use Math.Floor instead of Math.Round as you don't want the first digit to be rounded up, i.e. getting the first digit for 460 as 5. However, if you are using an integer then the division truncates the result, so there is no need to do any rounding at all.
Divide the value and store it back into the same variable.
Use the value after the loop, there is no point in updating it while you still have multiple digits in the variable.
Code:
int test = (int)globalVariableNumber.number;
while (test >= 10) {
test = test / 10;
}
globalVariableNumber.helpMe = test.ToString();
By using Math.Round(), in your example, you're rounding 5.5 to 6 (it's the even integer per the documentation). Use Math.Floor instead, this will drop the decimal point but give you the number you're expecting for this test.
i.e.
double test = Convert.ToDouble(globalVariableNumber.number);
while (test > 10)
{
test = Math.Floor(test / 10);
globalVariableNumber.helpMe = Convert.ToString(firstDigit);
}
Like #Sam Greenhalgh mentions, though, returning the first character of the number as a string will be cleaner, quicker and easier.
globalVariableNumber.helpMe = test >= 10
? test.ToString().SubString(0, 1)
: "Hint not possible, number is less than ten"
This assumes that helpMe is a string.
Per our discussion in the comments, you'd be better off doing it like this:
private void helpButton_Click(object sender, EventArgs e)
{
label3.Text = GetHelpText();
label3.AutoSize = true;
}
// Always good practice to name a method that returns something Get...
// Also good practice to give it a descriptive name.
private string GetHelpText()
{
return test >= 10 // The ?: operator just means if the first part is true...
? test.ToString().SubString(0, 1) // use this, otherwise...
: "Hint not possible, number is less than ten" // use this.
}
i'm trying to do a average speed of bugs killed per min. This is my code now but its throwing an error saying string input format is wrong. Any advice? I'm using C# for WPF.
//Score is the number of bugs hit
score.Text = (_killings * 1).ToString();
//Change it to integer
int x = Int32.Parse(score.Text);
int y = Int32.Parse(TBCountdown.Text); - this is where the error is showing
//Get the average speed by dividing number of bugs hit during the time
int average = (x / y);
//Displaying the average score by converting int to string
averagescore.Text = average.ToString();
For more information, i'm using a dispatcher timer and this is my code for the timer.
TBCountdown.Text = string.Format("00:0{0}:0{1}", time / 60, time % 60);
There are a couple of things that are wrong with your code, I am presuming that you are incrementing a variable and using it to create an elapsed time of some sort. The first thing to state is that Ed S. is correct and you should not be using your UI to store your value, create a backing variable and work with that. As far as your issues: the first one that comes to mind that I mentioned in my comments is that you are trying to convert a string that looks like a TimeSpan to an integer, the second is that your Format String will not convert to a DateTime Object it comes up with a Format Exception Error. I was able to get your code to work by changing your Timer's Tick eventhandler to this.
DateTime temp = DateTime.Parse(string.Format("00:{0}:{1}", time / 60, time % 60));
TBCountdown.Text = temp.ToString("00:mm:ss");
and you can use something like this to get your Y value (you did not respond to me about what information you were wanting for value)
int y = (int)TimeSpan.Parse(TBCountdown.Text).TotalSeconds;
There is a lot of conjecture here about what you want, if this isn't correct please let us know.
This is how you format the textbox:
TBCountdown.Text = string.Format("00:0{0}:0{1}", time / 60, time % 60);
And then you try to parse that as an int. Well, it's not an int. Parse it back as a DateTime or, better yet, just use the variable you already have (time). In general it is a poor idea to rely on your UI for storing your data. The UI is for display.
int y = time;
TBCountdown.Text = string.Format("00:0{0}:0{1}", (time / 60).ToString(), (time % 60).ToString());
remember this is a string function