Assistance with temperature comparisons assignment in C# - c#

I'm kinda new to C#, and I'm currently doing an assignment which is having me do three things:
1) Write a program named TemperaturesComparison that allows a user to input five daily Fahrenheit temperatures that must range from −30 to 130.
2) Display the temperatures in the order they were entered, and then display the average of the temperatures.
3) If a temperature is out of range, require the user to reenter it. If no temperature is lower than any previous one, display a message Getting warmer. If every temperature is lower than the previous one, display a message Getting cooler. If the temperatures are not entered in either ascending or descending order, display a message It’s a mixed bag.
The first two I've basically already got, but I'm not 100% sure how to address the third one in the most convenient way. Any advice on how to best handle this one would be greatly appreciated!
Here's a sample of the code I've written so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Console;
class TemperaturesComparison {
static void Main(string[] args) {
string userInput;
// Set Array Range
const int ARRAY_RANGE = 5;
const double AVG_RANGE = 5.0;
int[] dblArray = new int[ARRAY_RANGE];
int total = 0;
double average = 0;
WriteLine("This application calculates the average temperature of a provided dataset.\n");
for (int i = 0; i < ARRAY_RANGE; ++i) {
do {
Write("\nPlease provide temperature {0}: ", i + 1);
userInput = ReadLine();
} while (!int.TryParse(userInput, out dblArray[i]));
}
for (int i = 0; i < ARRAY_RANGE; ++i) {
total += dblArray[i];
}
foreach(var numListHolding in dblArray)
Write(numListHolding.ToString() + " ");
average = total / AVG_RANGE;
Write("\nAverage: {0}", average);
ReadKey();
}
}

You're making a few common beginner mistakes. First, arrays are better for collections that have a fixed size and never change, like the months of a year. If you want to have a changing number of entries, use something like a list:
var temperatures = new List<float>();
Second, integers are a poor type for real-world measurements like temperature. Prefer a floating-point type like float or double.
Next, variable names should tell you what the variables contain; names like userInput don't tell us that.
Next, your code doesn't “allow” a user to input five temperatures, it requires them to enter exactly five and will throw exceptions if they don't. Design your loops to work with any number of inputs:
while (true)
{
var nextTemperature = GetTemperatureFromSomewhere();
if (nextTemperature == null)
break;
if (nextTemperature is valid)
temperatures.Add(nextTemperature);
}
Look at the code above. If nextTemperature is not null but out of range you don't want to add it to temperatures.
When you have that working you want to store a maximumTemperature and compare it to each nextTemperature. If every nextTemperature exceeds maximumTemperature then your temperatures are getting warmer.

Related

inputting values into an array and printing the total value in the command prompt

I am trying to create an array that holds prices that the user inputs into the command prompt.
This is what I have so far
using System;
using static System.Console;
namespace Chapter6._2
{
class Program
{
static void Main()
{
int price;
int[] pricesList = new int[9];
Write("Enter price 1: ");
price = Read();
}
}
}
Also how would I create a loop to where it asks for the price of an item 10 times but goes something like this...
"Enter price 1: < user input price >"
"Enter price 2: < user input price >"
"Enter price 3: < user input price >"
and etc...Hopefully that makes sense.
Basically with these 2 questions I have asked, how would I create a loop where the program asks the user for prices 10 times, and stores the prices in an array and prints the total of all of the prices entered into the program at the end.
You need to use a for loop, cycling many times as your array length. Each iteration will ask the user for the Nth price, store it in the Nth position of the array and add the price to some "sum" variable. Also maybe you want to check System.Convert class.
This is as far I can go without doing your homework for you.
Please read this before asking more school related stuff:
How do I ask and answer homework questions?
Think of using a for loop. Your condition should be like i <= pricesList.Length
You can ask for user input as something like this: Console.WriteLine("Enter price {0}", i); or Console.WriteLine("Enter price {0}", i+1); if you want to start with 1 and not 0.
See array loops here C# arrays

System.FormatException error and having issues trying to fix it

Hello I am currently having issues with my project. im currently having issues with my console program where i am taking a users inputs (of which is decimals) and then using them in a if els statements, then finally doing the final math to work out ticket cost.
i have been researching into ways that i could fix this but for the past few hours i haven't been able to find a fix.
i have tried using strings, inter, var and boolen to store the price but when it comes to the final math to work out the cost, only inters do not give me a error.
i think a fix would be to change the way a user chooses the ticket they want but i cannot work out a way of allowing them to pick from the menu of tickets, while having the price values assigned to their input say:
Int family = 39.90
and then using this in some way to asinge the users input a value based on what i state.
Please could anyone suggest a way that i could maybe do this different or a solution to my current division / FormatException error ?
also any other tips on format ect would be much appreciated, all criticism is welcome im trying to learn.
Current console code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace The_Admission_Price_Calculator
{
class Program
{
static void Main(string[] args)
{
Action<string> cw = Console.WriteLine;
cw("Hello welcome to the WildLife park");
cw("We currently have 4 ticket options:");
cw("1: Famliy ticket(2 adults + 3 children) £39.90");
cw("2: Adult ticket £14.90");
cw("3: Child (under 16) £9.90");
cw("4: Senior (over 65) £7.00");
cw("Please input the price of the ticket you would like?");
cw("(EG if you want to child ticket please input 9.90, please also include the decimal place.");
cw("Input your the tickets price you would like to order now please.");
string Answer1;
int TicketCost1;
int TicketAmount1;
int TicketType1;
TicketType1 = Convert.ToInt32(Console.ReadLine());
if (TicketType1 == 39.90)
{
//int Famliy = 3990;
}
else if (TicketType1 == 9.90)
{
//int Child = 990;
}
else if (TicketType1 == 14.90)
{
//int Adult = 1490;
}
else if (TicketType1 == 7.00)
{
//int Senior = 700;
}
else
{
Console.WriteLine("you need to Input from the options, using the price of the ticket, with the decimal included.");
TicketType1 = Convert.ToInt32(Console.ReadLine());
}
cw("your choosen ticket is " + TicketType1 + ", how many tickets of this type would you like?");
TicketAmount1 = int.Parse(Console.ReadLine());
//Rember to Add /100 to the final sum, so that the output is in decimals.
TicketCost1 = TicketAmount1 * TicketType1;
cw("With the choosen amount of tickets of " +TicketAmount1+ " this will cost £" +TicketCost1+" ");
cw("Is this correct? (YES OR NO");
Answer1 = Console.ReadLine();
if (Answer1 == "YES")
{
cw("Tickets are printing now.");
}
if (Answer1 == "NO")
{
cw("Please reselect what tickets you would like");
//code here
}
else
{
cw("You have not entred a vaild asnswer please Input YES Or not in captials");
Answer1 = Console.ReadLine();
//core here
}
Console.ReadKey();
}
}
}
One thing i'd change is to have the user input the number of the option instead of the price when making a selection from the menu which should make things a little easier for you (then the selection is an int)
Like everyone is advising, switch from using int to decimal.
Which affects your conversion from string input too:
//TicketType1 = Convert.ToInt32(Console.ReadLine());
TicketType1 = Convert.ToDecimal(Console.ReadLine());
it also affects the way you do comparisons:
// if (TicketType1 == 39.90)
if (Decimal.Compare(TicketType1,39.90) == 0)
you cannot put decimals into an int. ints hold whole numbers. Traditionally you use double to store fractional things, but this is bad habit for currency. For currency use the decimal type http://csharpindepth.com/Articles/General/Decimal.aspx

Accepting only decimals and numbers in Console.ReadLine

I have just made a program to calculate the total cost of an item or items given the quantity and price. One of my concerns is in the Cost of Item field, it does not accept decimals at all. I would also like both fields to not accept letters. I have seen something about TryParse but I am unsure of how to use this and how it works. Any help is appreciated.
Here is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace QuantityPrice
{
class Program
{
static void Main(string[] args)
{
int Quantity;
int Cost;
Console.WriteLine("How much is the item you are buying? (In Canadian Dollars)");
Cost = int.Parse(Console.ReadLine());
Console.WriteLine("How many of the item are you buying? (In Canadian Dollars)");
Quantity = int.Parse(Console.ReadLine());
var TotalCost = Quantity * Cost * 1.13;
Console.WriteLine("Your total cost is:");
Console.WriteLine("$" + TotalCost);
Console.ReadLine();
System.Threading.Thread.Sleep(100000);
}
}
}
The problem is you are using int.Parse to extract the values from the user input. The int type is only for integers. If you want to handle decimals, use either float or double (for general mathematics where you want a floating decimal point) or decimal (for fixed point arithmetic such as currency).
As a general style comment, use "camel case" (starting with a lower case character) for variable names instead of "Pascal case" (starting with an upper case character).
You need to use decimals instead of int and to get the value, just ask for it as long as it is not a valid decimal like in this answer Need help with accepting decimals as input in C#
that you could use directly like this:
var cost = RequestDecimal("How much is the item you are buying? (In Canadian Dollars)");
Use an equivalent function to get an int for quantity

How do I sort a split array to read highest to lowest?

I need a little help sorting a split array into highest to lowest while keeping the names next to the scores. Im a little unsure how to do so because the array is split. Also, is there a way to let the user enter as many names and scores as they want without the program giving the user an error? So if they only want to enter 4 names and scores, all they have to do is press enter?
This is the code I have so far.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace proj09LEA
{
class Program
{
static void Main(string[] args)
{
// declare and array of integers
string[] name = new string[5];
int[] score = new int[5];
Console.WriteLine("\nSaturday Coder's Bowling Team");
Console.WriteLine("Enter in a name and score for each person on the team.");
Console.WriteLine("For example, Mary 143. Just hit Enter when you are done.\n");
// fill an array with user input
for (int i = 0; i < score.Length; i++)
{
Console.WriteLine("Enter in a name and score: ");
string line = Console.ReadLine();
name[i] = line.Substring(0, line.IndexOf(' '));
score[i] = int.Parse(line.Substring(line.IndexOf(' ') + 1));
}
Console.WriteLine("------------ Input Complete ------------\n");
Console.WriteLine("Here are the scores for this game, from highest to lowest:\n");
for (int i = 0; i < score.Length; i++)
{
if (score[i] >= 300)
{
Console.WriteLine("{0}'s score was {1}*.", name[i], score[i]);
}
else
{
Console.WriteLine("{0}'s score was {1}.", name[i], score[i]);
}
}
AverageScore(score);
Console.WriteLine("Press Enter to continue. . .");
Console.ReadLine();
}
static void AverageScore(int[] score)
{
int sum = score.Sum();
int average = sum / score.Length;
Console.WriteLine("The average score for this game was {0:d}.\n", average);
}
}
}
Let me first address the infinite-players question. Arrays, as you know, have a size, fixed at creation. There’s a data structure, List, though, that can have an unbounded (well, practically) number of elements. You might create one like this:
List<string> names = new List<string>();
Then if you want to add a new name, you can, for example, use
names.Add("Mary");
The rest of your code should work about the same; indexing works as normal, summing works as normal, etc.
Now what about sorting both of them together? Well, you don’t really have a list of names and a list of scores; what you really semantically have is a list of pairs of names and scores, or a list of players. You could first define a structure that represents a player:
struct Player {
public string Name { get; set; }
public int Score { get; set; }
public Player(string name, int score) {
Name = name;
Score = score;
}
}
Then you could just have a list of players:
List<Player> players = new List<Player>();
Instead of adding names and scores separately, we add them together:
string name = /* ... */;
int score = /* ... */;
players.Add(new Player(name, score));
Represented like this, your printing routine also becomes simpler. You can iterate through both at once:
foreach(Player player in players) {
Console.WriteLine("{0} scored {1}", player.Name, player.Score);
}
Lastly, summing is a little trickier, but not too hard. Basically, we extract all of the scores and sum those:
int sum = players.Select((player) => player.Score).Sum();
But for you, the real benefit is finally being able to sort it:
players.Sort((x, y) => y.Score - x.Score);
What you basically need is to take a look at HashMaps which are ADT's specifically for this purpose. Their structure is as follows:
-key1 : value1
-key2 : value2
.....
-keyn : valuen
your key here should be your score (but it can be anything). The value will be the name associated to the score.
Then , you can create a method sortKeys, depending on your implementation, which would take each key in the HashMap, move it at the end or at the beginning, while pointing to your name.
But please note that some HashMaps are randomly stored, so you will have to possibly make an array to write the sorted order of keys (and then lookup the key's value in the HashMap).
sort the array first using the Arrays.sort method then loop from
for(int i= x.length-1;i>=0;i--)
System.out.print(x[i]+"");
Should work this way
List would be a better option and these come in built sorting options that would make your task easier.

Printing an array in a method, from a different class?

I'm a fairly inexperienced programmer, and i'm currently working on a Console Application project. It's basically a little 'mathematics game'; the application generates two random numbers, that have either been added, subtracted, multiplied or divided against each other randomly. The answer is shown on screen and the user has to pick from the menu which is the right mathematical operator, once the correct answer is picked the application then displays on screen how long it took for the user in milliseconds to input the correct answer.
Now I want to save the times of the players in an array that can be called up later with all the scores. I need to include a method in this programme and I figured a method to save the times into an array would be suitable. I seem to have stumbled across a little problem though.
I'm not quite sure what's wrong:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Mathgame
{
class Program
{
}
class arrayclass
{
public static void saveInArray(int duration)
{
int[] TopTenScores = {000,1000,2000,3000,4000,5000,6000,7000,8000,9000};
if (duration < 1000)
{
duration = TopTenScores[000];
}
else if ((duration >= 1000) && (duration <= 1999))
{
duration = TopTenScores[1000];
}
else if ((duration >= 2000) && (duration <= 2999))
{
duration = TopTenScores[2000];
}
else if ((duration >= 3000) && (duration <= 3999))
{
duration = TopTenScores[3000];
}
else if ((duration >= 4000) && (duration <= 4999))
{
duration = TopTenScores[4000];
}
else if ((duration >= 5000) && (duration <= 5999))
{
duration = TopTenScores[5000];
}
else if ((duration >= 6000) && (duration <= 6999))
{
duration = TopTenScores[6000];
}
else if ((duration >= 7000) && (duration <= 7999))
{
duration = TopTenScores[7000];
}
else if ((duration >= 8000) && (duration <= 8999))
{
duration = TopTenScores[8000];
}
else if ((duration >= 9000) && (duration <= 9999))
{
duration = TopTenScores[9000];
}
Console.WriteLine(TopTenScores);
}
static void Main(string[] args)
{
int intInput, num1, num2, incorrect, array1;
float answer;
string input;
System.Random randNum = new System.Random();
Console.WriteLine("Welcome to the Maths game!");
Console.WriteLine("(Apologies for the glitchiness!)");
Console.WriteLine();
Console.WriteLine("Please choose from the following options:");
Console.WriteLine();
retry:
Console.WriteLine("1 - Test your Maths against the clock!");
Console.WriteLine("2 - Exit the application.");
Console.WriteLine("3 - Top scores");
Console.WriteLine();
input = Console.ReadLine();
intInput = int.Parse(input);
if (intInput == 1)
{
goto start;
}
else if (intInput == 2)
{
goto fin;
}
else if (intInput == 3)
{
array1 = array1.saveInArray;
goto retry;
}
Now, in the last 'else if' statement in the code, you can see my variable array1 trying to call the method, but no matter what I do I keep getting errors.
This is the only error I have at the moment, but I have a feeling soon as I resolve that error, another will come up. For now i'm just determined to get past this error:
'int' does not contain a definition for 'saveInArray' and no extension method 'saveInArray' accepting a first argument of type 'int' could be found (are you missing a using directive or an assembly reference?).
Any help would be kindly appreciated, apologies in advanced for my ugly written code! And thank you to any help that I receive!
Regards,
Omar.
Okay,
There's quite a bit in this code that needs fixing TBH.
I'll start with your error first:
You are declaring the variable array1 as an integer. In C# integers are primitive types. This means that they have no methods and no class members. So, when you call array1.saveInArray the compiler is basically saying "the type integer doesn't have any methods... I can't find an appropriate method to match your call".
Instead of calling array1.saveInArray I think what you meant to call was arrayclass.saveInArray(x).
Notice the x in that call above. I'm passing a variable called x which is of type int into the function saveInArray().
This brings us to the second error. If saveInArray was a property, then you could just go arrayclass.saveInArray. However, it is a function which requires an argument... namely an integer.
When you call arrayclass.saveInArray(someInteger) you are passing someInteger as an argument into a method. The method is then free to use this argument to do its calculations.
That should fix your most basic errors and hopefully you can compile.
Moving on to some other errors that will cause you problems at runtime:
In the method saveInArray you are declaring an integer array called TopTenScores.
You are declaring this fine... however later on when you are indexing into TopTenScores, you are using an index that is way out of range of TopTenScores.
Here is your declaration of TopTenScores:
int[] TopTenScores = {000,1000,2000,3000,4000,5000,6000,7000,8000,9000};
Notice that there are 10 numbers in this declaration. This means that the max index you can have is 9. Why? Because arrays start indexing at 0 in C#.
I think you might be thinking that this array is associative... however this is not the case. When you do TopTenScores[1000] you are saying "give me the value at index 1000". This value does not exists and you will get a runtime error.
Instead, you would want to call TopTenScores[1] if you wanted to access the value 1000.
Also, you are not overwriting the default value with the new top score, rather you are overwriting the new top score with the default value. I don't think this is intended. Instead, switch your calls from this: duration = TopTenScores[1000];
to this: TopTenScores[1] = duration;
Edit: Lastly, as the commenter pointed out, using goto is bad practice and greatly discouraged. You will understand why later on as you start to understand program flow and organization better. For now, it is best to try and avoid the habit of using goto. goto maps to a low level system construct, which we should avoid when using a higher level language like C#. Your code can get confusing and error prone quickly with using goto.
Anyways, feel free to ask more questions/comment etc if you have questions or you need to clarify something. Welcome to StackOverflow!
One of your problems is that you're missing the fundamental concept of what an array is. Think of an array as a row of numbered mailboxes. This line of code:
int[] TopTenScores = {000,1000,2000,3000,4000,5000,6000,7000,8000,9000};
is creating an array of 10 integers that look something like this in memory:
Index Value
----- -----
0 0
1 1000
2 2000
3 3000
4 4000
5 5000
6 6000
7 7000
8 8000
9 9000
It is unclear how this is a useful structure to represent your top scores, and I'm not sure what your saveInArray method is trying to do. In that method, here's how one of your lines of code is interpreted:
duration = TopTenScores[1000];
What that means is "take what's at index 1000 of TopTenScores and store it in duration." As you can see from the table above, there is no index 1000, and besides, that code has nothing to do with saving a top score.
Another problem you're having is that you don't seem to have your algorithm in place for accomplishing the task. For the top ten functionality, try breaking down what needs to be done into instructions on how you would do it manually if you were a score keeper. It would be something like this:
I keep track of the top scores by stacking index cards with the scores on them in order of highest to lowest. At first, I have no index cards.
I can do two things: record scores and tell someone the top ten scores.
When someone asks me to record a score, I:
Write the score down on an index card
Look through the stack of previous scores in order until I find a score lower than this new score.
If I find a score that was lower than this new one, I place the card on top of the lower score.
Otherwise, if this score is the lowest one of the bunch, including if this is the first score recorded, I'll place the score at the bottom of the stack.
When someone asks me to tell them the top 10 scores, I:
Go through the first 10 cards or all the cards if I have less than 10.
For each of those scores, write them down in order.
Give the list of scores to the one requesting them.
It may seem silly to do this, but most programs are really only sequences of simple steps, and as a programmer, you need to be able to determine those steps before translating them into a language that the compiler can understand. Once you formulate the problem in simple terms, you can start translating it into code for example:
// You can think of a role a person would do for a manual process as a class
// in a program.
public class ScoreKeeper
{
// Our high score list (stack of cards) is empty to begin with. Unlike
// arrays, lists allow us insert items rather than placing them in
// numbered slots.
private List<int> _scores = new List<int>();
// This is the method for when someone asks us to record a score. The
// "score" parameter is the new score which you can think of as being
// written on a card.
public void RecordScore(int score)
{
// Go through each of the existing scores. "i" is the index in the
// list.
for (int i = 0; i < _scores.Count; i++)
{
// See if the new score is less than the score at index #i
if (_scores[i] < score)
{
// It is lower than this new score. Insert the new score
// above that score.
_scores.Insert(i, score);
// We're done. Stop looping and exit RecordScore.
return;
}
}
// If we get here, we found no scores lower than this new one. Add
// this score to the bottom of the stack.
_scores.Add(score);
}
// This is the method for when someone asks us for the top 10 scores.
// Notice that we return an array of integers, which will represent
// our piece of paper we hand back to the one requesting the scores.
public int[] GetTop10Scores()
{
// We start with a blank piece of paper.
int[] result = new int[10];
// Go through the scores. The first 10 are the top 10 because
// RecordScore puts them in order. We also need to make sure
// we don't try to get more scores than we've recorded.
for (int i = 0; i < 10 && i < _scores.Count; i++)
{
// Write down the score on the paper
result[i] = _scores[i];
}
// Send back the list of scores to the requester
return result;
}
}
Now, inside of your main program, you can create a ScoreKeeper and ask it to do its score keeping:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Welcome to the Maths game!");
Console.WriteLine("(Apologies for the glitchiness!)");
Console.WriteLine();
Console.WriteLine("Please choose from the following options:");
Console.WriteLine();
// This object keeps track of scores
ScoreKeeper scoreKeeper = new ScoreKeeper();
bool keepRunning = true;
while (keepRunning)
{
Console.WriteLine("1 - Test your Maths against the clock!");
Console.WriteLine("2 - Exit the application.");
Console.WriteLine("3 - Top scores");
Console.WriteLine();
string input = Console.ReadLine();
int intInput = int.Parse(input);
if (intInput == 1)
{
// You should avoid gotos. Try writing a method instead
// Play the game and get the player's score.
int newScore = PlayGame();
// Have the score keeper record the new score.
scoreKeeper.RecordScore(newScore);
}
else if (intInput == 2)
{
keepRunning = false;
}
else if (intInput == 3)
{
// Get the top scores from the score keeper
int[] topScores = scoreKeeper.GetTop10Scores();
// Print each score
for (int i = 0; i < topScores.Length; i++)
{
Console.WriteLine("{0}: {1}", i + 1, topScores[i]);
}
}
}
}
private static int PlayGame()
{
// Put your game logic in here. Return the score.
}
}
Once you become more familiar with the fundamentals of programming, you'll find there are existing classes you can reuse, like SortedList, that can already take care of common tasks like maintaining an ordered list.

Categories

Resources