I am calculating a percent complete with variables of mixed data types.
int incompleteCritical = 12;
int total = 24;
float progress = 0;
NSLog(#"Incomplete Total: %d", incompleteCritical);
NSLog(#"Total Total: %d", total);
if (total > 0) {
progress = ((float)incompleteCritical/(float)total)*100;
NSLog(#"Progress: %d", progress);
}
The console output is as follows:
2011-01-11 10:02:59.993 [18570:207] Incomplete Total: 12
2011-01-11 10:02:59.993 [18570:207] Total Total: 24
2011-01-11 10:02:59.994 [18570:207] Progress: 0
Why is Progress not returning "50"?
You're using the wrong format string in your NSLog statement. %d is used for integers. You need to use %f when you log floating point numbers. (There are extra parameters to use to limit the number of decimal places, etc.)
Related
I need this service in which if the person stays for longer than 30 minutes, they have to pay an extra $10 every 15 minutes (and for the fraction of the 15 as well).
I designed it like this so far:
var checkInTime: Calendar
val totalTime: Long
get() = (Calendar.getInstance().timeInMillis - checkInTime.timeInMillis) / MIN_IN_MILISEC
fun getTime(totalTime:Long): Int{
var finalPrice = 0
var initialPrice = 20
if(totalTime<31){
finalFee = initialPrice
} else {
val extraPrice = 10
val extraTime = 15
finalFee = initialPrice
for(extraTime in totalTime){
finalFee += extraTime
}
return finalFee
}
I get the error "For loop must have an iterator()" when I try to loop through the totalTime when it's more than 30 minutes so that I can add $10 every 15 extra minutes. I need some help as to how to add to the finalFee every extra 15 minutes the person stays since my method is not working.
Thank you.
Let's take a look at your getTime function:
You're using a Long as totalTime. You can measure it in minutes to simplify your calculation (since all time values are measured in minutes). Since a Long type in Kotlin stores a integer up to 9,223,372,036,854,775,807 and no soul on Earth will use your service for that long (this represents 17 billion milleniums), you can just use an Int.
You're not declaring the finalFee variable, thus the code will raise an
"Unresolved reference" error. Since you're not using the finalPrice variable, I'm assuming you wanted to use this instead.
You're trying to iterate over a numeric value (in this case, totalTime, which is a Long). You can iterate over each element of a List, but how would you iterate over each element of an integer? I'm assuming you want to do a certain action totalTime number of times. In this case, you would use ranges.
You're also not using the variables extraPrice and extraTime.
There's code that's common to both if-else conditions (finalPrice = initialPrice), so you can extract that to outside the if-statement.
Refactoring your function:
fun getTime(totalTime: Int): Int {
var finalPrice = 20
if (totalTime >= 30) {
(0 until totalTime).forEach {
finalPrice += 15
}
}
return finalPrice
}
It's shorter, but still doesn't do what it's supposed to: let's suppose totalTime is equal to 45. The person got 30 minutes costing $20 and only have to pay $10 for every 15 minutes, therefore will only pay $30 total. Your function is considering that the person will have to pay $15 for every minute they stayed, because it uses a for-loop that goes from 0 to totalTime. For that, you need a for-loop that goes from 30 (the time limit) from the total time (the totalTime) every 15 minutes:
fun getTime(totalTime: Int): Int {
var finalPrice = 20
if (totalTime > 30) {
(30 until totalTime step 15).forEach {
finalPrice += 10
}
}
return finalPrice
}
Better yet, you don't even need a for-loop, you can just use maths:
fun getTime(totalTime: Int): Int {
var finalPrice = 20
if (totalTime > 30) {
finalPrice += ((totalTime - 30) / 15) * 10
// ^^^^^^^^^^^^^^^^ Get the exceeding time
// ^^^^^^^^^^^^^^^^^^^^^^^ How many 15 minutes are there?
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Put $10 for every 15 minutes
}
return finalPrice
}
The last part: your question said you need to consider the fraction of 15 as well. Therefore, you need to use a real value, not an integer. Let's change it to a Double:
fun getTime(totalTime: Int): Double {
var finalPrice = 20.0
if (totalTime > 30) {
finalPrice += ((totalTime - 30) / 15.0) * 10
}
return finalPrice
}
Let's test your function:
fun main() {
println(getTime(0)) // Outputs 20.0
println(getTime(10)) // Outputs 20.0
println(getTime(30)) // Outputs 20.0
println(getTime(45)) // Outputs 30.0
println(getTime(60)) // Outputs 40.0
println(getTime(70)) // Outputs 46.666...
}
Blank project. Code:
int i = 0;
while (i < 8) {
float amount = 100-arc4random_uniform(200);
NSLog(#"amount: %f", amount);
i++;
}
Log:
amount: 21.000000
amount: 90.000000
amount: 79.000000
amount: 4294967296.000000
amount: 39.000000
amount: 4294967296.000000
amount: 81.000000
amount: 4294967296.000000
4294967296.000000 is clearly outside the range of 100 - ran(200) (pseudocode)
If I don't declare amount as float and instead use int this doesn't happen.
What's going on here?
As #rob points out, arc4random_uniform returns a 32-bit unsigned integer type (uint32_t), that is, a number greater than or equal to zero, never negative. The compiler thus evaluates the expression 100-arc4random_uniform(200) expecting the result also to be an unsigned number.
If the result of arc4random_uniform(200) in your example code happens to be greater than 100, then 100-arc4random_uniform(200) will result in a negative number being assigned to a data type that cannot express negative numbers, so you'll end up with unexpected results.
You can indicate to the compiler that you want to be dealing with signed numbers by, as #rob suggests, casting the result of arc4random_uniform to a signed number (in this case a float):
float amount = 100 - (float)arc4random_uniform(200);
...or by indicating that the expression should return a signed number by explicitly making your other argument a signed number:
float amount = 100.0f - arc4random_uniform(200);
#include <stdio.h>
#include <cs50.h>
int GetPositiveInt();
int main (void)
{
int min; /*variable to hold minutes*/
printf ("How many minutes does it take you to use a shower?");
scanf ("%d", &min);
int numbtl = min * 12; /*computes number of bottles*/
if (min > 0)
{
printf ("Taking a shower you use %d bottles of water", numbtl);
}
else
{
printf ("Please enter the positive number: \n");
scanf ("%d", &min);}
return min;
}
}
I've written this program but I've got some bug in else place.
Here is the text which I get trying to execute this program.
~/workspace/pset1/ $ make water
clang -ggdb3 -O0 -std=c11 -Wall -Werror -Wshadow water.c -lcs50 -lm -o water
~/workspace/pset1/ $ ./water
How many minutes does it take you to use a shower?0
Please enter the positive number:
10
~/workspace/pset1/ $
Let me explin what I mean by this code and its execution. This code is used to compute how many bottles of water you use while taking a shower. 1 minute of shower equals 12 bottles.
If you enter the positive integer (for example, 10) the result will be like this:Taking a shower you use 120 bottles of water. BUT if you enter 0 or negative integer the program will ask you to enter the positive integer. And here is when the problem occurs. After entering the positive integer I get the result of 0 bottles.
Lets break down your program and see what it is doing; first
int GetPositiveInt();
Is a forward declaration for a function that is never used or defined, you can remove it entirely.
int main (void)
{
int min; /*variable to hold minutes*/
printf ("How many minutes does it take you to use a shower?");
scanf ("%d", &min);
Here we define the main function (the entry point to a c program) and declare a variable of type int called min. Then print out a line asking for user input and read in their response storing it in the min variable.
int numbtl = min * 12; /*computes number of bottles*/
Here you process min by multiplying it by 12 and storing the result in numbtl.
if (min > 0)
{
printf ("Taking a shower you use %d bottles of water", numbtl);
}
Here you check if min is valid, if it is you print the response. Here you can see the success path of your program is correct, the problem is what happens when min is not greater than 0. (Note there was a minor formatting error in this next bit that I corrected by what I assume you meant - note that this is why correct indenting and formatting is important).
else
{
printf ("Please enter the positive number: \n");
scanf ("%d", &min);
}
If min is not valid (ie less than or equal to 0) then you ask for another input and store it in min.
return min;
}
Lastly you return whatever is stored in min. Note you never actually do anything with this second value, except return it.
Side note: The return value on main is used as the exit status of your application. You can see the exit status of the last command in bash with echo $?.
$ ./water
How many minutes does it take you to use a shower?
2
Taking a shower you use 24 bottles of water
$ echo $?
2
This is probably not what you want. The exit status is normally 0 to indicate success and a positive number otherwise. This last return you will likely want return 0 to indicate your program has run successfully.
Now for the logic of your program, what it looks like you are trying to do is obtain some input from the user; validate it (obtaining new input if its invalid); then process it. So the first thing to do is move your processing to the end of your program
int main (void)
{
int min; /*variable to hold minutes*/
...
int numbtl = min * 12; /*computes number of bottles*/
printf ("Taking a shower you use %d bottles of water", numbtl);
return 0;
}
Now we just need to acquire and validate the user input; a typical algorithm to do this is:
prompt for user input
while (input is not valid) {
reprompt for user input
}
process user input
Converting this to c your applications ends up with;
int main (void)
{
int min; /*variable to hold minutes*/
printf ("How many minutes does it take you to use a shower? ");
scanf ("%d", &min);
while (min <= 0)
{
printf ("Please enter the positive number: ");
scanf ("%d", &min);
}
int numbtl = min * 12; /*computes number of bottles*/
printf ("Taking a shower you use %d bottles of water", numbtl);
return 0;
}
This will continue to ask the user for a positive number until they either enter one or hit crtl+c to kill the command. Once a valid number has been obtained it will processes it and print out the result.
#include <stdio.h>
#include <string.h>
int main (void)
{
long min;
char msg[255];
strcpy(msg,"How many minutes does it take you to use a shower?\n");
do {
printf ("%s", msg);
scanf ("%lu", &min);
strcpy(msg , "Please enter the positive number: \n");
}while( min <= 0 );
long numbtl = min * 12; /*computes number of bottles*/
printf ("Taking a shower you use %lu bottles of water", numbtl);
return 0;
}
You can also use a goto label. Here I used a goto label named start. If a number less than zero is entered then the program goes to beginning of the program. Hope, It helps.
#include<stdio.h>
int main (void)
{
int min; /*variable to hold minutes*/
start :
printf ("How many minutes does it take you to use a shower?\nEnter here : ");
scanf ("%d", &min);
if (min <= 0)
{
printf("Enter a number grater than zero\n\n");
goto start;
}
int numbtl = min * 12; /*computes number of bottles*/
printf ("Taking a shower you use %d bottles of water", numbtl);
return 0;
}
In Java,I need to ask user input for two integers. The program needs to divide by these two integers and produce a decimal to the sixth place.
I know that i will need to name two integers: numerator and denominator. Also, I need to name a double variable: result.
Thanks for the help!!
You haven't given any clues as to the language or platform you are using, but here is a basic example written in C running on a console.
#include <stdio.h>
int main()
{
int num, den;
double quo;
printf("Enter numerator: ");
scanf("%d", &num);
printf("Enter denominator: ");
scanf("%d", &den);
if (den == 0)
printf("Divide by zero\n");
else {
quo = (double)num / (double) den;
printf("Quotient = %.6f\n", quo);
}
return 0;
}
I'm currently using the below code to grab a random element from an array. How would I go about changing the code so that it returns an element weighted on the percentage that I want it to come up? For example, I want the element at index 0 to come up 27.4% of the time, but the element at index 7 to come up only 5.9% of the time.
NSArray *quoteArray = #[ #"quote1", #"quote2", #"quote3", #"quote4", #"quote5", #"quote6", #"quote7", #"quote8", ];
NSString *quoteString;
int r = arc4random() % [quoteArray count];
if(r<[rewardTypeArray count])
quoteString = [quoteArray objectAtIndex:r];
I would use an array of float (wrapped into NSNumber) objects.
Every object represents a percentage.In this case you would have an array of 8 objects:
Object 1: #27.5 ;
...
Object 7: #5.9 .
Then you get a random number from 1 to 100. If you want more precision you can also get a random number with the decimal part, and the precision doesn't influence the efficiency and neither the memory used.
Then when you get the number you iterate through all the array, keep track of the index and the percentage that you have. You use a float to sum all the percentages met and you stop only when the total percentage is greater on equal that the one that you have.
Example
NSArray* percentages= #[ #27.4 , ... , #5.9];
float randomNumber= arc4random_uniform(100) + (float)arc4random_uniform(101)/100;
NSUInteger n=0;
float totalPercentage= 0.0;
for(NSUInteger i=0; i<percentages.count; i++)
{
totalPercentage+= [ percentages[i] floatValue ];
if( totalPercentage >= randomNumber) // This case we don't care about
// the comparison precision
{
break;
}
n++;
}
// Now n is index that you want
The easiest way would be to generate a random number based on how fine-grained you want the percentage to be. To calculate to the tenth of a percent, you could generate between 0-1000, and 274 of the values you could randomly generate would be the first element. 59 values would correspond to element 7.
For example:
0-273 = index 1 27.4%
274-301 = index 2 2.7%
302-503 = index 3 20.1%
504-550 = index 4 4.6%
551-700 = index 5 14.9%
701-941 = index 6 24%
942-1000 = index 7 5.9%
The percentages don't add up properly, so I did my math wrong somewhere, but you get the point.
You can make another array with counter that would keep tracking how many times each one of your elements is being generated. If that counter is less than your target let that index come in your r, otherwise regenarate.