Back

Activity 1.9: Type Conversion

divider

Activity 1.9

Type Conversion

Key Concepts

Text Into Numbers

Reading Inside Out

Making It Readable

When It Cannot

We Left This Broken

int jerseyNumber = Console.ReadLine();
Terminal window
1-8-registration.cs(2,20): error CS0029: Cannot implicitly convert type 'string' to 'int'
The build failed. Fix the build errors and run again.

You collected the number. You could not use it.

One Word Fixes It

int jerseyNumber = int.Parse(Console.ReadLine());
Terminal window
Jersey number: 24 [Enter]
Next season you could be 25.

int.Parse takes text and hands back a number.

The text is not changed. A second thing is made from it.

Read It Inside Out

int.Parse(Console.ReadLine())

Console.ReadLine runs first and hands back text.

int.Parse takes that text and hands back a number.

The variable catches the number.

Innermost first, then outward.

Decimals Have Their Own

double average = double.Parse(Console.ReadLine());
Terminal window
Average points per game: 18.4 [Enter]
Scoring 18.4 a game

int.Parse for whole numbers. double.Parse for anything with a decimal point.

Now Do Some Arithmetic With It

double average = 18.4;
double threeGames = average * 3;
Console.WriteLine($"Three games: {threeGames}");
Terminal window
Three games: 55.199999999999996

Three games at 18.4 points is 55.2. Nobody wants to read that.

Now Do Some Arithmetic With It

Terminal window
Three games: 55.199999999999996

It is not a bug and your code is not wrong.

Computers store decimals approximately, and the error only becomes visible when you show it to somebody.

Two Characters Fix It

Console.WriteLine($"Three games: {threeGames:F2}");
Terminal window
Three games: 55.20

:F2 inside the braces. Fixed to two decimal places.

It Pads, Too

Console.WriteLine($"Scoring: {average} a game");
Console.WriteLine($"Scoring: {average:F2} a game");
Terminal window
Scoring: 18.4 a game
Scoring: 18.40 a game

18.4 becomes 18.40. Two decimal places means two, even when the second one is a zero.

That is what makes a column of money line up.

The Number Did Not Change

Console.WriteLine($"Rounded: {threeGames:F2}");
Console.WriteLine($"Raw: {threeGames}");
Terminal window
Rounded: 55.20
Raw: 55.199999999999996

:F2 changes how it is printed. It does not touch what is stored.

Do the arithmetic on the real number. Format only where you display it.

What If They Do Not Type a Number?

int players = int.Parse(Console.ReadLine());

Nothing stops them. The program has already started.

What If They Do Not Type a Number?

Terminal window
How many players signed up? seven [Enter]
Unhandled exception. System.FormatException: The input string 'seven' was not in a correct format.
at System.Number.ThrowFormatException[TChar](ReadOnlySpan`1 value)
at System.Int32.Parse(String s)
at Program.<Main>$(String[] args) in 1-9-planner.cs:line 2

The program stops where it stood.

Read the Last Line First

1-9-planner.cs:line 2

It names your file and the exact line that failed.

The lines above it are C#'s own machinery. Ignore them.

Two Kinds of Mistake

Last session
Refused before the program ran. It could never happen to a user.
This session
Built fine. Ran fine. Stopped when somebody typed the wrong thing.

The second kind is the dangerous one.

Why That Is Worse

A mistake the compiler catches is found by you, once.

A mistake it cannot catch is found by whoever uses your program.

Handling it needs a decision, and decisions arrive at session 12.

Today's Objectives

  • Converting input with int.Parse and double.Parse
  • Reading a call inside another call
  • Explaining why input has to be converted at all
  • Formatting a number for display with :F2
  • Recognizing a run-time error and finding the line that caused it

Key Terms

Conversion
Making a value of one type from a value of another.
Format specifier
An instruction after a colon inside braces, changing how a value is printed but not what it is.
Compile-time error
Found by reading the code, before it runs.
Run-time error
Found only while the program is running, and only sometimes.
Exception
A run-time error that stops the program and names its cause.

'F' → Fullscreen

divider

Build

Open your 1-8-registration program for Task 1. Everything after that goes in a new program named 1-9-planner.


Task 1: Finish Last Session

  • Uncomment the two lines you left broken at the end of Activity 1.8.
  • Add int.Parse around the Console.ReadLine call and run it.
  • Compare it with the guess you wrote down. Being wrong costs nothing; not having guessed costs the session.
Type Conversion
Console.Write("Jersey number: ");
int jerseyNumber = int.Parse(Console.ReadLine());
Console.WriteLine($"Next season you could be {jerseyNumber + 1}.");
Output
Jersey number: 24 [Enter]
Next season you could be 25.

Task 2: The Tournament Planner

  • Start 1-9-planner empty. Ask for the number of players and the team size, then work out the teams.
  • This is Activity 1.6's tournament with the numbers taken out. Run it with 47 and 6 first and check you still get 7 and 5.
  • Then run it again with numbers of your own choosing.
Type Conversion
Console.Write("How many players signed up? ");
int players = int.Parse(Console.ReadLine());
Console.Write("How many to a team? ");
int perTeam = int.Parse(Console.ReadLine());
int fullTeams = players / perTeam;
int leftOver = players % perTeam;
Console.WriteLine();
Console.WriteLine("=== TOURNAMENT PLAN ===");
Console.WriteLine($"Players: {players}");
Console.WriteLine($"Full teams: {fullTeams}");
Console.WriteLine($"Left over: {leftOver}");
Output
How many players signed up? 47 [Enter]
How many to a team? 6 [Enter]
=== TOURNAMENT PLAN ===
Players: 47
Full teams: 7
Left over: 5

Task 3: Two More Questions, and Making Them Readable

  • Ask for an entry fee per team and compute the total cost.
  • Ask for an average points-per-game, which is not a whole number. Use double.Parse for that one.
  • Work out what a team would score across three games, and print that too.
  • Run it with no :F2 anywhere first. Type 18.4 for the average. Write down exactly what the three-game number looks like — all of it.
  • Then add :F2 to the average and the projection, and run it again. Write down what each one says now.
  • Note: the green lines marked with a + sign are new. Do not type the + sign.
Type Conversion
Console.Write("How many players signed up? ");
int players = int.Parse(Console.ReadLine());
Console.Write("How many to a team? ");
int perTeam = int.Parse(Console.ReadLine());
Console.Write("Entry fee per team? ");
int teamFee = int.Parse(Console.ReadLine());
Console.Write("Average points per game? ");
double average = double.Parse(Console.ReadLine());
int fullTeams = players / perTeam;
int leftOver = players % perTeam;
double threeGames = average * 3;
Console.WriteLine();
Console.WriteLine("=== TOURNAMENT PLAN ===");
Console.WriteLine($"Players: {players}");
Console.WriteLine($"Full teams: {fullTeams}");
Console.WriteLine($"Left over: {leftOver}");
Console.WriteLine($"Entry cost: {fullTeams * teamFee}");
Console.WriteLine($"Scoring: {average:F2} a game");
Console.WriteLine($"Three games: {threeGames:F2}");

Task 4: Break It on Purpose

Five runs of your finished planner. Write down exactly what happens each time, copied from the screen.

  1. For the number of players, type seven instead of 7.
  2. For the number of players, press Enter without typing anything.
  3. For the number of players, type 3.5.
  4. For the number of players, type 47 with a space before and after it.
  5. For the average points, type 3.5.

Three of these stop the program and two do not. For each one that stops, write down the line number it names.


Challenge (Optional): Where Would You Put the Check?

  • You cannot fix Task 4 yet. Deciding what to do about bad input needs an if, and that is session 12.
  • Write a comment saying where in your program a check would have to go, and what it would have to ask.
  • Describing it in plain English is the exercise. No code.
divider

Checkpoint

Your finished planner should run like this.

Example Output
How many players signed up? 47 [Enter]
How many to a team? 6 [Enter]
Entry fee per team? 25 [Enter]
Average points per game? 18.4 [Enter]
=== TOURNAMENT PLAN ===
Players: 47
Full teams: 7
Left over: 5
Entry cost: 175
Scoring: 18.40 a game
Three games: 55.20
  • Every number in the summary came from an answer, not from your code.
  • 47 and 6 still produce 7 and 5.
  • The average uses double.Parse, and the rest use int.Parse.
  • Both decimal lines print with exactly two decimal places, and you have the unformatted three-game number written down.
  • All five Task 4 results are written down, with line numbers where the program stopped.
divider

Reflection

Answer the following questions before submitting your work.

  1. Describe what happens in int.Parse(Console.ReadLine()), in the order it happens. Name what each part hands to the next.
  2. Activity 1.8's mistake was refused before the program ran. This session's only appears when somebody types the wrong thing. Which is more dangerous, and why?
  3. Typing 3.5 for the number of players stopped the program, even though 3.5 is obviously a number. Explain why int.Parse refused it.
divider

Submit

Submit five things to the dropbox:

  1. Your 1-9-planner program file.
  2. A copy of one full run with 47 players and teams of 6.
  3. The three-game number as it printed before you added :F2, and as it printed after.
  4. Your five Task 4 results, with the line numbers.
  5. Your three reflection answers.

Activity Complete