I am new to programming in C# and i'm currently doing an exercise that looks like this:
Read the user's first and last name and save this in variables
Welcome the user
Ask the user about their age this year and save this in a variable with the appropriate data type
Calculate previous days the person has lived based on the specified age (age multiplied by 365) and present this.
So my code is working fine, but i would really appreciate if someone could explain the convert thing. I've been making alot of google searches and reading, but i can't seem to understand how it works.
int age = Convert.ToInt32(Console.ReadLine());
Can someone break this down for me for my code?
Thanks!
Console.Title = "Programming in C # - Exercise 1";
// Here the system asks the user to enter their full name.
Console.WriteLine("System: Enter your full name: ");
// Here I declare a variable and assign it a value.
string name = Console.ReadLine();
// Here the system welcomes the user.
Console.WriteLine("System: Welcome " + name + "!");
// Here the system asks how old the user is.
Console.WriteLine("System: How old are you?");
// This is the part i would like to have explained for me.
int age = Convert.ToInt32(Console.ReadLine());
// Here I declare a variable and calculate age in days.
int ageInDays = age * 365;
// Here the system answers.
Console.WriteLine("System: " + age + "?!" + " That means you are " + ageInDays + " days old!");
// Waiting to close the program.
Console.ReadLine();
Although you have a understanding now I'd like to point out that developers/coders should always expect the unexpected e.g. a user enters the wrong type such as for age a value that can not be converted to a integer or the case of name, they simply press enter without entering a name.
So for checking in this case for name being entered use string.IsNullOrWhiteSpace. For integer type, consider using int.TryParse.
In regards to concatenating string values or string values say with integers consider looking at string interpolation, this can be coder preference as some will like to string someString + anotherString or if using strings only there is String.Concat and StringBuilder Class.
Below is a slightly modified version of your code. Since you are just starting out, tuck this away for later or consider learning from this now than later.
using System;
namespace Exercise1
{
class Program
{
static void Main(string[] args)
{
Console.Title = "Programming in C # - Exercise 1";
Console.WriteLine("System: Enter your full name: ");
string fullName = Console.ReadLine();
/*
* Never assume a value for name has been entered
* https://learn.microsoft.com/en-us/dotnet/api/system.string.isnullorwhitespace?view=net-5.0
*/
if (!string.IsNullOrWhiteSpace(fullName))
{
/*
* Note original code concatenated name variable with text, you can also use string interpolation
* https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated
*/
Console.WriteLine($"System: Welcome {fullName}!");
}
else
{
Console.WriteLine("System: Welcome no name given!");
}
Console.WriteLine("System: How old are you?");
string ageInput = Console.ReadLine();
/*
* int.TryParse, better than Convert.ToInt32 which is recommended in the remark section
* for documentation for Convert.ToInt32.
*
* https://learn.microsoft.com/en-us/dotnet/api/system.int32.tryparse?view=net-5.0
*
*/
if (int.TryParse(ageInput, out var age))
{
int ageInDays = age * 365;
/*
* Note original code concatenated name variable with text, you can also use string interpolation
* https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated
*/
Console.WriteLine($"System: {age}?! That means you are {ageInDays} days old!");
}
else
{
Console.WriteLine("No age provided or the value was not a valid integer");
}
Console.WriteLine("Press any key to close this program");
Console.ReadLine();
}
}
}
You read a line from the console and then convert it to a 32bit integer, which is then stored in the variable age.
However this is dangerous, as you do not check if any non numerical characters are given by the user. What does your application do if the user inputs "Foo"? In your application this does not seem like a big problem, but be aware to check for the input first and then continue if the input is valid.
Console.ReadLine reads input from the console in the form of a string data type. This is a data type which, in very very basic terms, represents text. Under the hood, each character is represented by a code. You may have heard some of these encoding terms before, such as ASCII or UTF. For example, A in ASCII is represented by the number 65. This is also true for numbers. The ASCII code 48 represents the number 0.
We sometimes need to convert the string representation of a number to its actual numerical value. Often for performing mathematical operations and such. To do that, we need to get that "0 which is represented as 48 in ASCII" to a literal 0. This is done by Convert.ToInt32 as you're doing. It reads the string, and says "Oh i'm the text representation of a 0, therefore I will output the number 0".
So in a very brief summary, its taking text representation of a number and changes the data to a literal numerical value.
Console.Realine() in C# gives you a output of string..
So in order to convert to numerical... Convert Function will be useful..
Related
I'm wondering if someone can help me with decimals? Im going to make a program there can wright price and how much you paid, and then get a change back, but i need to add decimals. The decimals have to round up or down, so if it is 0,11 it goes to 0, if it is o,20 it goes to 0,25. So it will round up to either 0,25, 0,50, 0,75 and later on 1. The change have too also show in which cash you get back, so like 100 bucks, 500 bucks, 50 bucks if you know what i mean. I dont know how to do. This is how long i come:
using System;
namespace inlämninguno
{
class Program
{
// Starting point of my "Change" program
static void Main(string[] args)
{
Console.WriteLine(Subtract()); // adding a subract variable in the beginning of the code
Console.Read();
}
// Using the double datatype to for the decimals
public static double Subtract()
{
Console.WriteLine("Price?"); // how much it costs
string number1Input = Console.ReadLine();
Console.WriteLine("Paid?"); // how much the customer pays
string number2Input = Console.ReadLine();
double prince = Convert.ToDouble(number1Input);
double paid = Convert.ToDouble(number2Input);
// This is for the subtracting part
double num1 = double.Parse(number1Input);
double num2 = double.Parse(number2Input);
double result = num2 - num1; // this is so the console subtracts the values, have to put num2 first so the output isn't negative
Console.Write("Your change is " + result + ":"); // Output "Your change is ..."
return result; // A method that gives the right output of the code
}
}
}
Can someone please help me? Im stuck :D
I tried to convert to double and lots of stuff, but I don't know how to do now.
So I'm a complete newb to unity and c# and I'm trying to make my first mobile incremental game. I know how to format a variable from (e.g.) 1000 >>> 1k however I have several variables that can go up to decillion+ so I imagine having to check every variable's value seperately up to decillion+ will be quite inefficient. Being a newb I'm not sure how to go about it, maybe a for loop or something?
EDIT: I'm checking if x is greater than a certain value. For example if it's greater than 1,000, display 1k. If it's greater than 1,000,000, display 1m...etc etc
This is my current code for checking if x is greater than 1000 however I don't think copy pasting this against other values would be very efficient;
if (totalCash > 1000)
{
totalCashk = totalCash / 1000;
totalCashTxt.text = "$" + totalCashk.ToString("F1") + "k";
}
So, I agree that copying code is not efficient. That's why people invented functions!
How about simply wrapping your formatting into function, eg. named prettyCurrency?
So you can simply write:
totalCashTxt.text = prettyCurrency(totalCashk);
Also, instead of writing ton of ifs you can handle this case with logarithm with base of 10 to determine number of digits. Example in pure C# below:
using System.IO;
using System;
class Program
{
// Very simple example, gonna throw exception for numbers bigger than 10^12
static readonly string[] suffixes = {"", "k", "M", "G"};
static string prettyCurrency(long cash, string prefix="$")
{
int k;
if(cash == 0)
k = 0; // log10 of 0 is not valid
else
k = (int)(Math.Log10(cash) / 3); // get number of digits and divide by 3
var dividor = Math.Pow(10,k*3); // actual number we print
var text = prefix + (cash/dividor).ToString("F1") + suffixes[k];
return text;
}
static void Main()
{
Console.WriteLine(prettyCurrency(0));
Console.WriteLine(prettyCurrency(333));
Console.WriteLine(prettyCurrency(3145));
Console.WriteLine(prettyCurrency(314512455));
Console.WriteLine(prettyCurrency(31451242545));
}
}
OUTPUT:
$0.0
$333.0
$3.1k
$314.5M
$31.5G
Also, you might think about introducing a new type, which implements this function as its ToString() overload.
EDIT:
I forgot about 0 in input, now it is fixed. And indeed, as #Draco18s said in his comment nor int nor long will handle really big numbers, so you can either use external library like BigInteger or switch to double which will lose his precision when numbers becomes bigger and bigger. (e.g. 1000000000000000.0 + 1 might be equal to 1000000000000000.0). If you choose the latter you should change my function to handle numbers in range (0.0,1.0), for which log10 is negative.
Newb/hobbiest here trying to increase my understanding of arrays and to that end i'm trying to build a little meal calculator which will store user data in an array which would hold three strings and one double (The Users First Name, The Users Last Name, the Name of the Resturant, and a DOUBLE which is the cost of the meal). I know there are far easier ways to do this then the way I'm trying to do this, but my purpose is to increase my understand of how arrays work now that i'm starting to understand loops and methods (I get lost/am scared of arrays so i'm forcing myself to work with arrays all weekend long starting tonight - long weekend and i hope it will a worthwhile weekend of learning :D )
I am currently working on a method to populate the array which would work as follows:
Call GetUserData(question asked);
GetUserData asks the user for a specific type of data (string unless last position [3] then it's a double which I'll do math on later)
GetUserData Loop calls arrQuestions[] to ask user question
GetUserData reads user answer into corresponding position in arrUserData[]
arrUserData[] is populated (at this point with four strings, i'll have to convert the four string to a double when i do math which should be feasible i hope)
So in a nutshell, i'm trying to build a method that asks a series of questions from one array and stores the answers in another array that i can then use to do all sorts of wacky things with as i try to get a better understanding of arrays and how to use them and what they are good for and what they aren't good for.
And I promise all of you I've already tried to Google an answer to this, I've read up on arrays at several places including http://msdn.microsoft.com/en-us/library/ttw7t8t6.aspx and stackOverflow, but the answers I've thus found aren't written in a way someone of my skill level understands/my understanding isn't such that I can divine the answer from what i have been able to read thus far.
The following code all sits within the 'program' class
public void Play()
{
GetString("+ + + Meal Calculator Exercise + + +");
String command = "";
String[] arrQuestions = new String[3];//questions asked
arrQuestions [0] = "First Name: ";//string back
arrQuestions [1] = "Last Name: ";//string back
arrQuestions [2] = "Restaurant Name: ";//string back
arrQuestions [3] = "Cost of Meal: ";//I want a double back for this question
String[] arrUserData = new String[3];/user answers stored
arrUserData[0] = " ";//string
arrUserData[1] = " ";//string
arrUserData[2] = " ";//string
arrUserData[3] = " ";//figure out how to convert to double
do {
GetString("+ + + Meal Calculator Exercise + + +");
GetUserData(arrQuestions[i]);//run loop, ask questions populate arrUserData array
GetString("Again? ");
command = Console.ReadLine().ToLower().Trim();
Console.Clear();
}
while (command == "y" || command == "yes");
GetString("+ + + Thank you + + + Have a wonderful time + + + Goodbye! + + +");
}
public String GetString(String strTxt) {
Console.WriteLine(strTxt);return Console.ReadLine();}
public Array GetUserData(String strTxt)
{
for (int i = 0; i < arrUserData.Length; i++)
Console.WriteLine(arrQuestion[i]);
return Console.ReadLine(arrUserData[i]);
}
static void Main(string[] args){
Program myProgram = new Program();
myProgram.Play();}
In looking at your code I'll try to recommend something that I think uses some of the existing knowledge you've shown.
I won't delve right in to code but I'll try to explain it:
I could count how many questions are in the array, (array.length) and store that. Then I would do a while loop that checks if the number of questions answered is equal to the array length. In this loop you could use console readline to put the questions one by one in to the array and increment your counter variable, then use the variable that you are incrementing to insert the answer in to the user data array.
Does that make sense? Let me know if you want any clarification or if this isn't what you were looking for.
So a little more research, head scratching and help from the kind folks here lead me to this:
class Program
{
String[] arrUserData = new String[4];// Must specify 4 in brackets for array length, not the same as an index
// it will fill up as items are added to it starting from position 0 automatically
// should also be at class level for multiple method access
public void Play()
{
String command; // doesn't need to have an empty string value, only be declared
String[] arrQuestions = new String[4];//questions asked
arrQuestions[0] = "First Name: ";
arrQuestions[1] = "Last Name: ";
arrQuestions[2] = "Restaurant Name: ";
arrQuestions[3] = "Cost of Meal: ";
do {
GetString("+ + + Meal Calculator Exercise + + +"); // I removed the one in the top of the method, or else it does it twice
// pass in array of questions to satisfy necessary array argument in GetUserData();
GetUserData(arrQuestions);//run loop, ask questions populate arrUserData array
command = GetString("Again? "); // your GetString method returns whatever the console reads,
// so it can be assigned to your command variable at the same time, or else the user has to put in y or yes twice
Console.Clear();
}
while (command == "y" || command == "yes");
GetString("+ + + Thank you + + + Have a wonderful time + + + Goodbye! + + +");
}
public String GetString(String strTxt)
{
Console.WriteLine(strTxt); return Console.ReadLine().ToLower().Trim();
}
// changed it to a void to it just simply assigns the values to the class level array
public void GetUserData(string[] thisArray)
{
for (int i = 0; i < thisArray.Length; i++)//use the passed in array to determine loop length
{// missing curly braces
Console.WriteLine(thisArray[i]); // write question with corresponding index to console
arrUserData[i] = Console.ReadLine(); // use Console.ReadLine to get input and assign it to corresponding index in userData
if (i == 3) // check for the last index to convert to double
{// here's the basic way, can cause a lot of errors if user input is not a double
Convert.ToDouble(arrUserData[3]);
// here's the way trapping all possible errors, and giving a nice message for each
// remove the other Convert.ToDouble method and uncomment this to try giving some false values to see how it works
/*
try
{
Convert.ToDouble(arrUserData[3]);
}
catch (FormatException)
{
Console.WriteLine("Unable to convert " + arrUserData[3] + " to a Double.");
}
catch (OverflowException)
{
Console.WriteLine(arrUserData[3] + " is outside the range of a Double.");
}
* */
}
}
SeeUserData(thisArray); // to display the user data, demonstrates nesting methods that can
// operate off of one single variable pass in your Play method
// you could also move it to your play method and change it to SeeUserData(arrQuestions); and it would work the same
}
public void SeeUserData(string[] sameArrayAgain)
{
Console.WriteLine("Here's the data for " + arrUserData[0]);
for (int i = 0; i < sameArrayAgain.Length; i++)
{
Console.WriteLine("Your " + sameArrayAgain[i] + " " + arrUserData[i]);
}
}
static void Main(string[] args) { Program myProgram = new Program(); myProgram.Play(); }
}
okay so, I have been asked to write a console application for a theater ticket system. A user will type in the number of seats required, and the area of the theater chosen (using the code number 1-4 to represent the seating area chosen) The program should work out and display the cost of the tickets, based on the pricing plan shown below
Area Code price
Stalls 1 £24
Grand circle 2 £30
Upper circle 3 £27
Gallery 4 £20
I've so far came up with the following, But it's got an error to do with string + Int conversions under the IF Statements section, this is probably very easy to fix, but I'm new to programming so i'm unsure how to resolve it:
//Declare variables and constants
int iSeatNum;
int iArea;
int iCost;
int iTotalCost;
//Ask the user how many seats they require
Console.WriteLine("How many seats would you like to purchase?");
iSeatNum = Convert.ToInt32(Console.ReadLine());
//Ask the user what area they would like to be in
Console.WriteLine("Where would you like to sit? Please enter 1 for Stalls, 2 for Grand Circle, 3 for Upper Circle or 4 for Gallery");
iArea = Convert.ToInt32(Console.ReadLine());
**if (iArea = "1")**
{
iCost = 24;
}
//Clarify information & work out
Console.WriteLine("You are buying " + iSeatNum + " Seats at " + iArea);
iTotalCost = iSeatNum * iCost;
Console.WriteLine("Your total ticket cost is " + iTotalCost);
//Prevent from closing
Console.WriteLine("Press any key to close");
Console.ReadKey();
if (iArea = "1")
iArea is an integer, "1" is a string. So you cannot compare those two. You should compare with the integer 1 instead. Also note that a single equals symbol (=) is an asignment, and not a comparison. You will want to use two there: ==
if (iArea == 1)
now it displays a further error, when I put iTotalCost = iSeatNum * iCost; it comes up the error of "Use of unassigned local variable iCost" Any idea how I fix this?
The problem is that you declare the variable iCost at the beginning, but never safely assign any value to it before using it. You do assign a value when iArea equals to 1, but for all other cases, the variable remains uninitialized. Of course the compiler doesn’t know that you will end up typing in 1 when the program runs for testing, and that’s not a safe thing anyway. So it requires you to initialize your variable with anything instead.
So at the beginning, you can just say int iCost = 0; to fix this.
Well "1" is a string, not int.
if (iArea == 1)
Because you have already converted you string (the Console.ReadLine() return a string) into number using:
iArea = Convert.ToInt32(Console.ReadLine());
you can compare it as number using:
if (iArea == 1)
note the == instead of =, the single is used for assignment, the double for comparison.
if (iArea = "1")
This doesn't make sense. First of all you're using the assignment equals operator. You're attempting to assign iArea the value of "1". Instead, you need the logical equality operator == which will return true or false depending on whether the first operand is equal to the second operand.
Second, you have already converted the string value read from the console to a strongly typed integer. So you need to write your if statement as follows:
if (iArea == 1)
String strArea =Console.ReadLine();
if (strArea.Equals("1"))
{
iCost = 24;
}
or
int iArea = Convert.ToInt32(Console.ReadLine());
if (iArea == 1))
{
iCost = 24;
}
I have done a homework assignment, here is the problem statement:
Your program should work as follows:
Ask the user to give you a file name. Get the file name and save it.
Open the file.
From the file read a temperature and a wind speed. Both values should be stored in variables declared as double. The file is a text file. Each line of the file contains a temperature and a wind speed value.
Calculate the wind chill factor using a programmer written method, and display the result in the form:
For t = temperature from file
and v = wind speed from file
Wind chill index = calculated result degrees Fahrenheit.
Show all numbers with two digits after the decimal point. (Remember-no magic numbers!)
Repeat these steps until an end of file is encountered.
I have completed the assignment, my code is below, I was just wondering if there was any way to make it more efficient, or if there are some different and creative ways to accomplish this problem, I already turned this in and got 50/50, but I'm just curious as to how some of you advanced and skilled programmers would approach this problem.
using System;
using System.IO;
class Program
{
// declare constants to use in wind chill factor equation - no magic numbers
const double FIRST_EQUATION_NUMBER = 35.74;
const double SECOND_EQUATION_NUMBER = 0.6215;
const double THIRD_EQUATION_NUMBER = 35.75;
const double FOURTH_EQUATION_NUMBER = 0.4275;
const double EQUATION_EXPONENT = 0.16;
const int DEGREE_SYMBOL_NUMBER = 176;
static void Main()
{
// declare and initialize some variables
string filePath = "";
string line = "";
double temperature = 0.0;
double windSpeed = 0.0;
double windChillFactor = 0.0;
char degreeSymbol = (char)DEGREE_SYMBOL_NUMBER;
// ask user for a file path
Console.Write("Please enter a valid file path: ");
filePath = Console.ReadLine();
// create a new instance of the StreamReader class
StreamReader windChillDoc = new StreamReader(#filePath);
// start the read loop
do
{
// read in a line and save it as a string variable
line = windChillDoc.ReadLine();
// is resulting string empty? If not, continue execution
if (line != null)
{
string[] values = line.Split();
temperature = double.Parse(values[0]);
windSpeed = double.Parse(values[1]);
windChillFactor = WindChillCalc(temperature, windSpeed);
Console.WriteLine("\nFor a temperature {0:f2} F{1}", temperature, degreeSymbol);
Console.WriteLine("and a wind velocity {0:f2}mph", windSpeed);
Console.WriteLine("The wind chill factor = {0:f2}{1}\n", windChillFactor, degreeSymbol);
}
} while (line != null);
windChillDoc.Close();
Console.WriteLine("\nReached the end of the file, press enter to exit this program");
Console.ReadLine();
}//End Main()
/// <summary>
/// The WindChillCalc Method
/// Evaluates a wind chill factor at a given temperature and windspeed
/// </summary>
/// <param name="temperature">A given temperature</param>
/// <param name="ws">A given windspeed</param>
/// <returns>The calculated wind chill factor, as a double</returns>
static double WindChillCalc(double temperature, double ws)
{
double wci = 0.0;
wci = FIRST_EQUATION_NUMBER + (SECOND_EQUATION_NUMBER * temperature) - (THIRD_EQUATION_NUMBER * (Math.Pow(ws, EQUATION_EXPONENT))) + (FOURTH_EQUATION_NUMBER * temperature * (Math.Pow(ws, EQUATION_EXPONENT)));
return wci;
}
}//End class Program
Feel free to tell me what you think of it.
Your way looks good, but:
It would look nicer if you used PascalCase for the constants, as that's what coding conventions for c# use.
you should wrap the StreamReader in a using statement, so it gets properly disposed once you're done.
You should probably also wrap it in a try block (and a catch to properly handle the exception) to make sure that you don't get a FileNotFound exception.
It's probably a better idea to structure your while loop the following way:
while((line = windChillDoc.ReadLine()) != null)
{
...
}
[Darn formatting won't work right!]
Other than that though, i wouldn't know as i'm not familiar with weather calculations :)
You're not going to get much zippier than that for file IO in C#. Depending on the size of the data set it may be worth using a buffered reader, but for sufficiently small files, it's just not worth it. I'd leave it as-is.
Most of your comments are extraneous. The code should tell you how...the comments should tell you why.
Minor nitpick, but "WindChillCalc" should be "CalcWindChill" if you are are using English method names (the verb goes first).
string filePath = "";
...
filePath = Console.ReadLine();
Don't initialize with values that are never used; and keep declaration and initialization close together:
string filePath = Console.ReadLine();
using has been mentioned - but don't use # unnecessarily:
new StreamReader(#filePath);
should be just:
new StreamReader(filePath);
Personally, I'd use LINQ for the line-reader, but that is just me ;-p
Why the do/while? In your do you check for null. In your while you check for null. Why not just make it a while statement?
string line;
while((line = windChillDoc.ReadLine()) != null)
{
//Logic
}
EDIT: Fixed the compilation error. Funny thing was I had that originally. This Rich Text Box needs a compiler! :P
Although not really relating to performance (the main question)
IMO:
const double FIRST_EQUATION_NUMBER = 35.74;
const double SECOND_EQUATION_NUMBER = 0.6215;
const double THIRD_EQUATION_NUMBER = 35.75;
const double FOURTH_EQUATION_NUMBER = 0.4275;
const double EQUATION_EXPONENT = 0.16;
isn't much better than a magic number. Looking at that I have no idea what FIRST_EQUATION_NUMBER is used for other than in an equation somewhere, and I can't tell that they are in the same equation or you have four equations which use different numbers? They could also be put into the actual method as thats the only place they are used.
I would change degreeSymbol to a const rather than working it from a const int
later.
const char DEGREE_SYMBOL = (char)176;
If you're getting marked on style etc. then there's a couple extremely minor things
Initializing doubles to 0.0 is redundant.
string.Empty is preferred instead of ""
Your windchill method can be changed to simply (though, during compilation, I think that wci will be optimized out - so it's functionally the same):
(changed formatting for SO readability)
static double WindChillCalc(double temperature, double ws)
{
return FIRST_EQUATION_NUMBER +
(SECOND_EQUATION_NUMBER * temperature) -
(THIRD_EQUATION_NUMBER * (Math.Pow(ws, EQUATION_EXPONENT))) +
(FOURTH_EQUATION_NUMBER * temperature * (Math.Pow(ws, EQUATION_EXPONENT)));
}
In little academic programs like this, unless you do something really dumb, performance will not be an issue. A simple way to tell if performance is an issue is to ask the question: "Does it make me wait?"
If there were an enormous amount of input, I would ask who's providing the input and who's reading the output. That would tell me if I could do the I/O in binary rather than text, because as it is, by far the bulk of the processing will be in the conversion of text into numbers on input, and numbers to text on output, especially floating point.