end 023
This commit is contained in:
parent
e2b311c8eb
commit
b1f1525f81
832
023_alphanumeric_data_format/023_csharp.md
Normal file
832
023_alphanumeric_data_format/023_csharp.md
Normal file
@ -0,0 +1,832 @@
|
||||
# Format alphanumeric data for presentation in C#
|
||||
|
||||
## Introduction
|
||||
|
||||
Suppose you work for a sales and marketing department that sends thousands of
|
||||
personalized letters to the company's existing clients who are institutional
|
||||
investors. Your team's job is to promote new financial products to the customer.
|
||||
Each letter you send merges personalized information about the customer. The
|
||||
letter compares the returns of their current portfolios with projected returns
|
||||
using the newest products. How do you merge and format the data correctly?
|
||||
|
||||
From a high-level perspective, software developers are concerned with:
|
||||
|
||||
- **data input**, including data typed in by a user from a keyboard, using
|
||||
their mouse, a device, or by another software system via a network request.
|
||||
- **data processing**, including decision logic, manipulating data, and
|
||||
performing calculations.
|
||||
- **data output**, including presentation to an end user via a command-line
|
||||
message, a window, a web page, or saving the processed data into a file, and
|
||||
sending it to a network service.
|
||||
|
||||
To solve business problems in C#, you need to work with different types of data,
|
||||
such as strings and numbers. You also need to perform various operations on the
|
||||
data, such as calculations, comparisons, or conversions. In this module, you
|
||||
output string and numeric data in C# using various formatting options. You also
|
||||
create a receipt mockup and a personalized marketing message using data merging
|
||||
techniques.
|
||||
|
||||
### Learning objectives
|
||||
|
||||
In this module, you will:
|
||||
|
||||
- Merge string templates with variables using composite formatting.
|
||||
- Use various format specifiers to properly display percentages, currency, and
|
||||
numbers.
|
||||
- Use padding methods to properly align string values.
|
||||
|
||||
---
|
||||
|
||||
## Exercise - Investigate string formatting basics
|
||||
|
||||
In this unit, you learn methods to format strings for efficient display,
|
||||
especially for cases using multiple variables.
|
||||
|
||||
### What is Composite Formatting?
|
||||
|
||||
*Composite formatting* uses numbered placeholders within a string. At run time,
|
||||
everything inside the braces is resolved to a value that is also passed in
|
||||
based on their position.
|
||||
|
||||
This example of composite formatting uses a built-in method `Format()` on the
|
||||
`string` data type keyword. Update your code in the editor as follows:
|
||||
|
||||
```cs
|
||||
string first = "Hello";
|
||||
string second = "World";
|
||||
string result = string.Format("{0} {1}!", first, second);
|
||||
Console.WriteLine(result);
|
||||
```
|
||||
|
||||
If you run this code, you observe the following output.
|
||||
|
||||
```txt
|
||||
Hello World!
|
||||
```
|
||||
|
||||
There are a few important things to notice about this code.
|
||||
|
||||
- Data types and variables of a given data type have built-in "helper methods"
|
||||
to make certain tasks easy.
|
||||
- The literal string `"{0} {1}!"` forms a template, parts of which are replaced
|
||||
at run time.
|
||||
- The token `{0}` is replaced by the first argument after the string template,
|
||||
in other words, the value of the variable `first`.
|
||||
- The token `{1}` is replaced by the second argument after the string template,
|
||||
in other words, the value of the variable `second`.
|
||||
|
||||
> Note
|
||||
> You may think it's odd to start with the number 0. Actually this is very
|
||||
common in software development. Whenever there's a sequence of items that can
|
||||
be identified using a number, the numbering will usually start at 0.
|
||||
|
||||
Update your code as follows:
|
||||
|
||||
```cs
|
||||
string first = "Hello";
|
||||
string second = "World";
|
||||
Console.WriteLine("{1} {0}!", first, second);
|
||||
Console.WriteLine("{0} {0} {0}!", first, second);
|
||||
```
|
||||
|
||||
Save your code file, and then run your code. You should see the following
|
||||
output:
|
||||
|
||||
```txt
|
||||
World Hello!
|
||||
Hello Hello Hello!
|
||||
```
|
||||
|
||||
A few observations about these examples:
|
||||
|
||||
- For the first `Console.WriteLine()` statement, observe that the tokens can be
|
||||
arranged in any order. The sample code has `{1}` before `{0}`.
|
||||
- For the second `Console.WriteLine()` statement, observe that the tokens can be
|
||||
reused with three instances of `{0}`. Also, the second variable argument,
|
||||
`second`, isn't used. Yet, the code still runs without error.
|
||||
|
||||
#### What is string interpolation?
|
||||
|
||||
*String interpolation* is a technique that simplifies composite formatting.
|
||||
|
||||
Instead of using a numbered token and including the literal value or variable
|
||||
name in a list of arguments to `String.Format()` or `Console.WriteLine()`, you
|
||||
can just use the variable name inside of the curly braces.
|
||||
|
||||
In order for a string to be interpolated, you must prefix it with the `$`
|
||||
directive. Now, create the same examples from earlier using string interpolation
|
||||
instead of composite formatting. Update your code as follows:
|
||||
|
||||
```cs
|
||||
string first = "Hello";
|
||||
string second = "World";
|
||||
Console.WriteLine($"{first} {second}!");
|
||||
Console.WriteLine($"{second} {first}!");
|
||||
Console.WriteLine($"{first} {first} {first}!");
|
||||
```
|
||||
|
||||
Save your code file, and then run your code. You should see the following
|
||||
output:
|
||||
|
||||
```txt
|
||||
Hello World!
|
||||
World Hello!
|
||||
Hello Hello Hello!
|
||||
```
|
||||
|
||||
> Note
|
||||
> If you look at code examples in books and online, you're likely to see both
|
||||
*composite formatting* and *string interpolation* used, but generally you should
|
||||
choose *string interpolation*.
|
||||
|
||||
#### Formatting currency
|
||||
|
||||
Composite formatting and string interpolation can be used to format values for
|
||||
display given a specific language and culture. In the following example, the
|
||||
`:C` currency format specifier is used to present the `price` and `discount`
|
||||
variables as currency. Update your code as follows:
|
||||
|
||||
```cs
|
||||
decimal price = 123.45m;
|
||||
int discount = 50;
|
||||
Console.WriteLine($"Price: {price:C} (Save {discount:C})");
|
||||
```
|
||||
|
||||
If you executed this code on a computer that has its Windows display language
|
||||
set to "English (United States)", you observe the following output.
|
||||
|
||||
```txt
|
||||
Price: $123.45 (Save $50.00)
|
||||
```
|
||||
|
||||
Notice how adding the `:C` to the tokens inside of the curly braces formats the
|
||||
number as currency regardless of whether you use `int` or `decimal`.
|
||||
|
||||
> Note
|
||||
> What happens if your country/region and language isn't known? If you run the
|
||||
previous code in the "in-browser" .NET Editor, such as at
|
||||
[TrydotNet](https://dotnet.microsoft.com/en-us/platform/try-dotnet) you'll see
|
||||
the following output: `Price: ¤123.45 (Save ¤50.00)`. The symbol `¤` is used
|
||||
instead of the symbol for your country/region's money. This is a generic symbol
|
||||
used to denote "currency" regardless of the *type* of currency. You see this
|
||||
symbol in the .NET Editor because it ignores your current location.
|
||||
|
||||
### How the user's country/region and language affect string formatting
|
||||
|
||||
What if you execute the previous code on a computer in France that has its
|
||||
Windows Display Language set to French? In that case you would see the
|
||||
following output.
|
||||
|
||||
```txt
|
||||
Price: 123,45 € (Save 50,00 €)
|
||||
```
|
||||
|
||||
The reason for the previous "€" output is that the string currency formatting
|
||||
feature is dependent on the local computer setting for culture. In this context,
|
||||
the term "culture" refers to the country/region and language of the end user.
|
||||
The culture code is a five character string that computers use to identify the
|
||||
location and language of the end user. The culture code ensures certain
|
||||
information like dates and currency can be presented properly.
|
||||
|
||||
For example:
|
||||
|
||||
- the culture code of an English speaker in the USA is `en-US`.
|
||||
- the culture code of a French speaker in France is `fr-FR`.
|
||||
- the culture code of a French speaker in Canada is `fr-CA`.
|
||||
|
||||
The culture affects the writing system, the calendar that's used, the sort
|
||||
order of strings, and formatting for dates and numbers (like formatting
|
||||
currency).
|
||||
|
||||
Unfortunately, making sure your code works correctly on all computers
|
||||
regardless of the country/region or the end user's language is challenging.
|
||||
This process is known as *localization* (or *globalization*). Localization
|
||||
depends on many factors not discussed in this module, but simply, the string
|
||||
formatting syntax might use a different format depending on the user's culture.
|
||||
|
||||
#### Formatting numbers
|
||||
|
||||
When working with numeric data, you might want to format the number for
|
||||
readability by including commas to delineate thousands, millions, billions, and
|
||||
so on.
|
||||
|
||||
The `N` numeric format specifier makes numbers more readable. Update your code
|
||||
as follows:
|
||||
|
||||
```txt
|
||||
decimal measurement = 123456.78912m;
|
||||
Console.WriteLine($"Measurement: {measurement:N} units");
|
||||
```
|
||||
|
||||
If you're viewing this from the `en-US` culture, you observe the following
|
||||
output.
|
||||
|
||||
```txt
|
||||
Measurement: 123,456.79 units
|
||||
```
|
||||
|
||||
By default, the `N` numeric format specifier displays only two digits after the
|
||||
decimal point.
|
||||
|
||||
If you want to display more precision, you can do that by adding a number after
|
||||
the specifier. The following code will display four digits after the decimal
|
||||
point using the `N4` specifier. Update your code as follows:
|
||||
|
||||
```cs
|
||||
decimal measurement = 123456.78912m;
|
||||
Console.WriteLine($"Measurement: {measurement:N4} units");
|
||||
```
|
||||
|
||||
If you're viewing this from the `en-US` culture, you observe the following
|
||||
output.
|
||||
|
||||
```txt
|
||||
Measurement: 123,456.7891 units
|
||||
```
|
||||
|
||||
#### Formatting percentages
|
||||
|
||||
Use the `P` format specifier to format percentages and rounds to 2 decimal
|
||||
places. Add a number afterwards to control the number of values displayed after
|
||||
the decimal point. Update your code as follows:
|
||||
|
||||
```cs
|
||||
decimal tax = .36785m;
|
||||
Console.WriteLine($"Tax rate: {tax:P2}");
|
||||
```
|
||||
|
||||
If you're viewing this from the `en-US` culture, you observe the following
|
||||
output.
|
||||
|
||||
```txt
|
||||
Tax rate: 36.79%
|
||||
```
|
||||
|
||||
#### Combining formatting approaches
|
||||
|
||||
String variables can store strings created using formatting techniques. In the
|
||||
following example, decimals and decimal math results are formatted and stored
|
||||
in the `yourDiscount` string using composite formatting.
|
||||
|
||||
Update your code as follows.
|
||||
|
||||
```cs
|
||||
decimal price = 67.55m;
|
||||
decimal salePrice = 59.99m;
|
||||
|
||||
string yourDiscount = String.Format("You saved {0:C2} off the regular {1:C2} price. ", (price - salePrice), price);
|
||||
|
||||
Console.WriteLine(yourDiscount);
|
||||
```
|
||||
|
||||
If you're viewing this from the `en-US` culture, you observe the following
|
||||
output.
|
||||
|
||||
```txt
|
||||
You saved $7.56 off the regular $67.55 price.
|
||||
```
|
||||
|
||||
You can combine multiple formatted strings. Build on the previous code
|
||||
concatenating the calculated percentage using the string interpolation instead
|
||||
of string concatenation by inserting
|
||||
`yourDiscount += $"A discount of {(price - salePrice)/price:P2}!";` into the
|
||||
code on the line before `Console.WriteLine()`.
|
||||
|
||||
> Note
|
||||
> You don't need to use `String.Format()` with this string interpolation
|
||||
approach.
|
||||
|
||||
Update your code as follows.
|
||||
|
||||
```cs
|
||||
decimal price = 67.55m;
|
||||
decimal salePrice = 59.99m;
|
||||
|
||||
string yourDiscount = String.Format("You saved {0:C2} off the regular {1:C2} price. ", (price - salePrice), price);
|
||||
|
||||
yourDiscount += $"A discount of {((price - salePrice)/price):P2}!"; //inserted
|
||||
Console.WriteLine(yourDiscount);
|
||||
```
|
||||
|
||||
If you're viewing this unit from the `en-US` culture, you observe the following
|
||||
output.
|
||||
|
||||
```txt
|
||||
You saved $7.56 off the regular $67.55 price. A discount of 11.19%!
|
||||
```
|
||||
|
||||
### Recap
|
||||
|
||||
Here are most important takeaways from this unit about string formatting:
|
||||
|
||||
- You can use composite formatting or string interpolation to format strings.
|
||||
- With **composite formatting**, you use a string template containing one or
|
||||
more replacement tokens in the form `{0}`. You also supply a list of arguments
|
||||
that are matched with the replacement tokens based on their order. Composite
|
||||
formatting works when using `string.Format()` or `Console.WriteLine()`.
|
||||
- With **string interpolation**, you use a string template containing the
|
||||
variable names you want replaced surrounded by curly braces. Use the `$`
|
||||
directive before the string template to indicate you want the string to be
|
||||
interpolated.
|
||||
- Format currency using a `:C` specifier.
|
||||
- Format numbers using a `:N` specifier. Control the precision (number of values
|
||||
after the decimal point) using a number after the `:N` like `{myNumber:N3}`.
|
||||
- Format percentages using the `:P` format specifier.
|
||||
- Formatting currency and numbers depend on the end user's culture, a five
|
||||
character code that includes the user's country/region and language (per the
|
||||
settings on their computer).
|
||||
|
||||
---
|
||||
|
||||
## Exercise
|
||||
|
||||
### Explore string interpolation
|
||||
|
||||
You need to create the code to print a receipt for the customer purchasing
|
||||
shares of an investment product. The shares are purchased automatically at the
|
||||
end of the year based on a series of payroll deductions, so the number of
|
||||
shares purchased usually contains a decimal amount. To print the receipt, you
|
||||
would likely need to combine data of different types, including fractional
|
||||
values, currency, and percentages in precise ways.
|
||||
|
||||
### Display the invoice number using string interpolation
|
||||
|
||||
Update your code in the editor as follows:
|
||||
|
||||
```cs
|
||||
int invoiceNumber = 1201;
|
||||
decimal productShares = 25.4568m;
|
||||
decimal subtotal = 2750.00m;
|
||||
decimal taxPercentage = .15825m;
|
||||
decimal total = 3185.19m;
|
||||
|
||||
Console.WriteLine($"Invoice Number: {invoiceNumber}");
|
||||
```
|
||||
|
||||
The Program.cs file must be saved before building or running the code.
|
||||
|
||||
At the Terminal command prompt, to run your code, type `dotnet run` and then
|
||||
press Enter.
|
||||
|
||||
You should see the following output:
|
||||
|
||||
```txt
|
||||
Invoice Number: 1201
|
||||
```
|
||||
|
||||
> Note
|
||||
> You may see several warnings such as `warning CS0219: The variable
|
||||
'productShares' is assigned but its value is never used` for all the variables
|
||||
that were defined but not yet used in the code.
|
||||
|
||||
### Display the product shares with one thousandth of a share (0.001) precision
|
||||
|
||||
Since you bill the customers using fractions of shares even though the precision
|
||||
is one ten thousandth (0.0001), you'll only display three digits after the
|
||||
decimal point.
|
||||
|
||||
Add the following code below the code you typed previously:
|
||||
|
||||
```cs
|
||||
Console.WriteLine($" Shares: {productShares:N3} Product");
|
||||
```
|
||||
|
||||
Save your code file, and then run your code.
|
||||
|
||||
When you run the code, you should see the following output:
|
||||
|
||||
```txt
|
||||
Invoice Number: 1201
|
||||
Shares: 25.457 Product
|
||||
```
|
||||
|
||||
### Display the subtotal that you charge the customer formatted as currency
|
||||
|
||||
Add the following code below the code you typed in steps 1 and 2:
|
||||
|
||||
```cs
|
||||
Console.WriteLine($" Sub Total: {subtotal:C}");
|
||||
```
|
||||
|
||||
When you run the code, you should see the following output:
|
||||
|
||||
```txt
|
||||
Invoice Number: 1201
|
||||
Shares: 25.457 Product
|
||||
Sub Total: $2,750.00
|
||||
```
|
||||
|
||||
> Note
|
||||
> The sample shows the "$" but you may see a different regional currency symbol.
|
||||
|
||||
### Display the tax charged on the sale formatted as a percentage
|
||||
|
||||
Add the following code below the code you typed in steps 1 through 3:
|
||||
|
||||
```cs
|
||||
Console.WriteLine($" Tax: {taxPercentage:P2}");
|
||||
```
|
||||
|
||||
When you run the code, you should see the following output:
|
||||
|
||||
```txt
|
||||
Invoice Number: 1201
|
||||
Shares: 25.457 Product
|
||||
Sub Total: $2,750.00
|
||||
Tax: 15.83%
|
||||
```
|
||||
|
||||
### Finalize the receipt with the total amount due formatted as currency
|
||||
|
||||
Add the following code below the code you typed in steps 1 through 4:
|
||||
|
||||
```cs
|
||||
Console.WriteLine($" Total Billed: {total:C}");
|
||||
```
|
||||
|
||||
The entire code for the exercise should match as follows:
|
||||
|
||||
```cs
|
||||
int invoiceNumber = 1201;
|
||||
decimal productShares = 25.4568m;
|
||||
decimal subtotal = 2750.00m;
|
||||
decimal taxPercentage = .15825m;
|
||||
decimal total = 3185.19m;
|
||||
|
||||
Console.WriteLine($"Invoice Number: {invoiceNumber}");
|
||||
Console.WriteLine($" Shares: {productShares:N3} Product");
|
||||
Console.WriteLine($" Sub Total: {subtotal:C}");
|
||||
Console.WriteLine($" Tax: {taxPercentage:P2}");
|
||||
Console.WriteLine($" Total Billed: {total:C}");
|
||||
```
|
||||
|
||||
When you run the code, you should see the following output:
|
||||
|
||||
```txt
|
||||
Invoice Number: 1201
|
||||
Shares: 25.457 Product
|
||||
Sub Total: $2,750.00
|
||||
Tax: 15.83%
|
||||
Total Billed: $3,185.19
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Exercise
|
||||
|
||||
### Discover padding and alignment
|
||||
|
||||
The `string.Format()` method is used to perform composite formatting such as in
|
||||
the example:
|
||||
|
||||
```cs
|
||||
string first = "Hello";
|
||||
string second = "World";
|
||||
string result = string.Format("{0} {1}!", first, second);
|
||||
Console.WriteLine(result);
|
||||
```
|
||||
|
||||
It may have seemed a bit strange that a keyword that represents a data type has
|
||||
methods you can call in the same way that you call methods on the `Console`
|
||||
class. The fact is that there are many similar methods on the `string` data type
|
||||
and any literal string or variable of type string.
|
||||
|
||||
Here's a brief list of categories of these built-in methods so you can get an
|
||||
idea of what's possible.
|
||||
|
||||
- Methods that add blank spaces for formatting purposes (`PadLeft()`,
|
||||
`PadRight()`)
|
||||
- Methods that compare two strings or facilitate comparison (`Trim()`,
|
||||
`TrimStart()`, `TrimEnd()`, `GetHashcode()`, the `Length` property)
|
||||
- Methods that help you determine what's inside of a string, or even retrieve
|
||||
just a part of the string (`Contains()`, `StartsWith()`, `EndsWith()`,
|
||||
`Substring()`)
|
||||
- Methods that change the content of the string by replacing, inserting, or
|
||||
removing parts (`Replace()`, `Insert()`, `Remove()`)
|
||||
- Methods that turn a string into an array of strings or characters (`Split()`,
|
||||
`ToCharArray()`)
|
||||
|
||||
### Formatting strings by adding whitespace before or after
|
||||
|
||||
The `PadLeft()` method adds blank spaces to the left-hand side of the string so
|
||||
that the total number of characters equals the argument you send it. In this
|
||||
case, you want the total length of the string to be 12 characters.
|
||||
|
||||
Update your code in the editor as follows:
|
||||
|
||||
```cs
|
||||
string input = "Pad this";
|
||||
Console.WriteLine(input.PadLeft(12));
|
||||
```
|
||||
|
||||
At the Terminal command prompt, to run your code, type `dotnet run` and then
|
||||
press Enter.
|
||||
|
||||
When you run the code, you observe four characters prefixed to the left of the
|
||||
string bring the length to 12 characters long.
|
||||
|
||||
```txt
|
||||
Pad this
|
||||
```
|
||||
|
||||
To add space or characters to the right side of your string, use the
|
||||
`PadRight()` method instead. 1. Update your code in the editor as follows:
|
||||
|
||||
```cs
|
||||
Console.WriteLine(input.PadRight(12));
|
||||
```
|
||||
|
||||
Save your code file, and then run your code. You won't observe any characters
|
||||
added to the end of the string, but they're there.
|
||||
|
||||
#### What is an overloaded method?
|
||||
|
||||
In C#, an overloaded method is another version of a method with different or
|
||||
extra arguments that modify the functionality of the method slightly, as is the
|
||||
case with the overloaded version of the `PadLeft()` method.
|
||||
|
||||
You can also call a second overloaded version of the method and pass in
|
||||
whatever character you want to use instead of a space. In this case, you fill
|
||||
the extra space with the dash character.
|
||||
|
||||
Update your code in the editor as follows:
|
||||
|
||||
```cs
|
||||
Console.WriteLine(input.PadLeft(12, '-'));
|
||||
Console.WriteLine(input.PadRight(12, '-'));
|
||||
```
|
||||
|
||||
Save your code file, and then run your code. You should see four dashes
|
||||
prefixing the left of the string that is 12 characters long.
|
||||
|
||||
```txt
|
||||
----Pad this
|
||||
Pad this----
|
||||
```
|
||||
|
||||
Now, apply this newfound knowledge to another real world scenario.
|
||||
|
||||
### Working with padded strings
|
||||
|
||||
Suppose you work for a payment processing company that still supports legacy
|
||||
mainframe systems. Often, those systems require data to be input in specific
|
||||
columns. For example, store the Payment ID in columns 1 through 6, the payee's
|
||||
name in columns 7 through 30, and the Payment Amount in columns 31 through 40.
|
||||
Also, importantly, the Payment Amount is right-aligned.
|
||||
|
||||
You're asked to build an application that will convert data in the relational
|
||||
database management system to the legacy file format. To ensure that the
|
||||
integration works correctly, the first step is to confirm the file format by
|
||||
giving the legacy system maintainers a sample of the output. Later, you build
|
||||
on this work to send hundreds or thousands of payments to be processed via an
|
||||
ASCII text file.
|
||||
|
||||
#### Add the Payment ID to the output
|
||||
|
||||
To get started, print the Payment ID in the first six columns. You pick some
|
||||
random payment data that should be adequate for the purposes.
|
||||
|
||||
Update your code in the editor as follows:
|
||||
|
||||
```cs
|
||||
string paymentId = "769C";
|
||||
var formattedLine = paymentId.PadRight(6);
|
||||
Console.WriteLine(formattedLine);
|
||||
```
|
||||
|
||||
Reuse the `formattedLine` variable to build the output string.
|
||||
|
||||
Save your code file, and then run your code. You should see the following
|
||||
output:
|
||||
|
||||
```txt
|
||||
769C
|
||||
```
|
||||
|
||||
There are two blank spaces to the right that not visible. You'll confirm that
|
||||
they exist in the next step.
|
||||
|
||||
#### Add the payee name to the output
|
||||
|
||||
Next, you add a fictitious Payee Name, padding it appropriately.
|
||||
|
||||
Update your code as follows:
|
||||
|
||||
```cs
|
||||
string paymentId = "769C";
|
||||
string payeeName = "Mr. Stephen Ortega";
|
||||
|
||||
var formattedLine = paymentId.PadRight(6);
|
||||
formattedLine += payeeName.PadRight(24);
|
||||
|
||||
Console.WriteLine(formattedLine);
|
||||
```
|
||||
|
||||
The `+=` operator performs a string concatenation, taking the previous value of
|
||||
the variable `formattedLine` and adding the new value to it. It's a shortened
|
||||
equivalent the following code example:
|
||||
|
||||
```cs
|
||||
formattedLine = formattedLine + payeeName.PadRight(24);
|
||||
```
|
||||
|
||||
Save your code file, and then run your code. You should see the following
|
||||
output:
|
||||
|
||||
```txt
|
||||
769C Mr. Stephen Ortega
|
||||
```
|
||||
|
||||
Again, there are quite a few blank spaces after the Payee's Name. Also, there
|
||||
are two blank spaces after the Payment ID from Step 1.
|
||||
|
||||
#### Add the payment amount to the output
|
||||
|
||||
Next, add a fictitious Payment Amount and make sure to use `PadLeft()` to right
|
||||
-align the output.
|
||||
|
||||
Update your code as follows:
|
||||
|
||||
```cs
|
||||
string paymentId = "769C";
|
||||
string payeeName = "Mr. Stephen Ortega";
|
||||
string paymentAmount = "$5,000.00";
|
||||
|
||||
var formattedLine = paymentId.PadRight(6);
|
||||
formattedLine += payeeName.PadRight(24);
|
||||
formattedLine += paymentAmount.PadLeft(10);
|
||||
|
||||
Console.WriteLine(formattedLine);
|
||||
```
|
||||
|
||||
Save your code file, and then run your code. You should see the following
|
||||
output:
|
||||
|
||||
```txt
|
||||
769C Mr. Stephen Ortega $5,000.00
|
||||
```
|
||||
|
||||
This output is pretty close to what you understood the legacy system
|
||||
maintainers were looking for.
|
||||
|
||||
#### Add a line of numbers above the output to more easily confirm the result
|
||||
|
||||
Since it's difficult to count the exact columns where each data element appears,
|
||||
you add a line directly above the output that helps you count the columns.
|
||||
|
||||
```cs
|
||||
Console.WriteLine("1234567890123456789012345678901234567890");
|
||||
```
|
||||
|
||||
Update your code in the Visual Studio Code Editor as follows:
|
||||
|
||||
```txt
|
||||
string paymentId = "769C";
|
||||
string payeeName = "Mr. Stephen Ortega";
|
||||
string paymentAmount = "$5,000.00";
|
||||
|
||||
var formattedLine = paymentId.PadRight(6);
|
||||
formattedLine += payeeName.PadRight(24);
|
||||
formattedLine += paymentAmount.PadLeft(10);
|
||||
|
||||
Console.WriteLine("1234567890123456789012345678901234567890");
|
||||
Console.WriteLine(formattedLine);
|
||||
```
|
||||
|
||||
Save your code file, and then run your code. You should see the following
|
||||
output, that you can send off to the maintainers of the legacy system to
|
||||
confirm the new integration works correctly:
|
||||
|
||||
```txt
|
||||
1234567890123456789012345678901234567890
|
||||
769C Mr. Stephen Ortega $5,000.00
|
||||
```
|
||||
|
||||
Success!
|
||||
|
||||
### Recap
|
||||
|
||||
There's a few important takeaways from this unit.
|
||||
|
||||
- The `string` data type, literal strings, and variables of type string each
|
||||
implement many helper methods to format, modify, and perform other operations
|
||||
on strings.
|
||||
- The `PadLeft()` and `PadRight()` methods add white space (or optionally,
|
||||
another character) to the total length of a string.
|
||||
- Use `PadLeft()` to right-align a string.
|
||||
- Some methods are overloaded, meaning they have multiple versions of the
|
||||
method with different arguments that affect their functionality.
|
||||
- The `+=` operator concatenates a new string on the right to the existing
|
||||
string on the left.
|
||||
|
||||
---
|
||||
|
||||
## Exercise
|
||||
|
||||
### Complete a challenge to apply string interpolation to a form letter
|
||||
|
||||
For the sales and marketing company's newest investment products, you send
|
||||
thousands of personalized letters to the company's existing clients. Your job
|
||||
is to write C# code to merge personalized information about the customer. The
|
||||
letter contains information like their existing portfolio and compares their
|
||||
current returns to projected returns if they were to invest in using the new
|
||||
products.
|
||||
|
||||
The writers have decided on the following example marketing message. Here's the
|
||||
desired output (using fictitious customer account data).
|
||||
|
||||
```txt
|
||||
Dear Ms. Barros,
|
||||
As a customer of our Magic Yield offering we are excited to tell you about a new financial product that would dramatically increase your return.
|
||||
|
||||
Currently, you own 2,975,000.00 shares at a return of 12.75%.
|
||||
|
||||
Our new product, Glorious Future offers a return of 13.13%. Given your current volume, your potential profit would be ¤63,000,000.00.
|
||||
|
||||
Here's a quick comparison:
|
||||
|
||||
Magic Yield 12.75% $55,000,000.00
|
||||
Glorious Future 13.13% $63,000,000.00
|
||||
```
|
||||
|
||||
Use your new found knowledge of string formatting to build an application that
|
||||
can merge and format the appropriate content given the previous example output.
|
||||
Pay particular attention to the white space and make sure you accurately
|
||||
represent this exact format using C#.
|
||||
|
||||
Add the following code to get the data for the challenge:
|
||||
|
||||
```cs
|
||||
string customerName = "Ms. Barros";
|
||||
|
||||
string currentProduct = "Magic Yield";
|
||||
int currentShares = 2975000;
|
||||
decimal currentReturn = 0.1275m;
|
||||
decimal currentProfit = 55000000.0m;
|
||||
|
||||
string newProduct = "Glorious Future";
|
||||
decimal newReturn = 0.13125m;
|
||||
decimal newProfit = 63000000.0m;
|
||||
|
||||
// Your logic here
|
||||
|
||||
Console.WriteLine("Here's a quick comparison:\n");
|
||||
|
||||
string comparisonMessage = "";
|
||||
|
||||
// Your logic here
|
||||
|
||||
Console.WriteLine(comparisonMessage);
|
||||
```
|
||||
|
||||
Use the code editor to generate the message while using the given variables and
|
||||
code.
|
||||
|
||||
Ensure your code outputs the following message:
|
||||
|
||||
```txt
|
||||
Dear Ms. Barros,
|
||||
As a customer of our Magic Yield offering we are excited to tell you about a new financial product that would dramatically increase your return.
|
||||
|
||||
Currently, you own 2,975,000.00 shares at a return of 12.75%.
|
||||
|
||||
Our new product, Glorious Future offers a return of 13.13%. Given your current volume, your potential profit would be $63,000,000.00.
|
||||
|
||||
Here's a quick comparison:
|
||||
|
||||
Magic Yield 12.75% $55,000,000.00
|
||||
Glorious Future 13.13% $63,000,000.00
|
||||
```
|
||||
|
||||
Good luck!
|
||||
|
||||
Whether you get stuck and need to peek at the solution or you finish
|
||||
successfully, continue on to view a solution to this challenge.
|
||||
|
||||
---
|
||||
|
||||
### Summary
|
||||
|
||||
Your company needed to create a personalized marketing message to promote a new
|
||||
financial product to your customers. Using C#, you were able to write code that
|
||||
combined string and numeric data about your current customers.
|
||||
|
||||
You exercised different techniques for merging a string template with variables
|
||||
using composite formatting and string interpolation. The various specifiers
|
||||
allow you to properly format large numbers, currency, and percentages. The
|
||||
built-in methods on variables of type string allowed you to add padding to left
|
||||
and right align data.
|
||||
|
||||
Imagine how much extra work is required if you didn't have a wealth of string
|
||||
and number formatting tools and techniques available to you in C#. You would
|
||||
likely attempt to use string concatenation everywhere, possibly making it
|
||||
difficult to maintain or update.
|
||||
|
||||
Techniques and tools for formatting strings and numeric data has a wide array
|
||||
of applications. For example, you can use these techniques to present data for
|
||||
display on screen and format data to transfer between disparate systems.
|
||||
|
||||
#### Resources
|
||||
|
||||
[String.Format Method](https://learn.microsoft.com/en-us/dotnet/api/system.string.format?view=net-7.0&preserve-view=true)
|
||||
[Standard Numeric Format Strings](https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings)
|
58
023_alphanumeric_data_format/alpha_num_format/Program.cs
Normal file
58
023_alphanumeric_data_format/alpha_num_format/Program.cs
Normal file
@ -0,0 +1,58 @@
|
||||
string first = "Hello";
|
||||
string second = "World";
|
||||
string result = string.Format("{0} {1}!", first, second);
|
||||
Console.WriteLine(result);
|
||||
|
||||
Console.WriteLine("\n--------------------------\n");
|
||||
|
||||
Console.WriteLine("{1} {0}!", first, second);
|
||||
Console.WriteLine("{0} {0} {0}!", first, second);
|
||||
|
||||
Console.WriteLine("\n--------------------------\n");
|
||||
|
||||
Console.WriteLine($"{first} {second}!");
|
||||
Console.WriteLine($"{second} {first}!");
|
||||
Console.WriteLine($"{first} {first} {first}!");
|
||||
|
||||
Console.WriteLine("\n--------------------------\n");
|
||||
|
||||
decimal price = 123.45m;
|
||||
int discount = 50;
|
||||
Console.WriteLine($"Price: {price:C} (Save {discount:C})");
|
||||
|
||||
Console.WriteLine("\n--------------------------\n");
|
||||
|
||||
decimal measurement = 123456.78912m;
|
||||
Console.WriteLine($"Measurement: {measurement:N4} units");
|
||||
|
||||
Console.WriteLine("\n--------------------------\n");
|
||||
|
||||
decimal tax = .36785m;
|
||||
Console.WriteLine($"Tax rate: {tax:P2}");
|
||||
|
||||
Console.WriteLine("\n--------------------------\n");
|
||||
|
||||
decimal price_2 = 67.55m;
|
||||
decimal saleprice_2 = 59.99m;
|
||||
|
||||
string yourDiscount = String.Format(
|
||||
"You saved {0:C2} off the regular {1:C2} price_2. ",
|
||||
(price_2 - saleprice_2),
|
||||
price_2
|
||||
);
|
||||
|
||||
Console.WriteLine(yourDiscount);
|
||||
|
||||
Console.WriteLine("\n--------------------------\n");
|
||||
|
||||
decimal price_3 = 67.55m;
|
||||
decimal saleprice_3 = 59.99m;
|
||||
|
||||
string yourDiscount_2 = String.Format(
|
||||
"You saved {0:C2} off the regular {1:C2} price_3. ",
|
||||
(price_3 - saleprice_3),
|
||||
price_3
|
||||
);
|
||||
|
||||
yourDiscount += $"A discount of {((price_3 - saleprice_3)/price_3):P2}!"; //inserted
|
||||
Console.WriteLine(yourDiscount_2);
|
@ -0,0 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
32
023_alphanumeric_data_format/form_letter/Program.cs
Normal file
32
023_alphanumeric_data_format/form_letter/Program.cs
Normal file
@ -0,0 +1,32 @@
|
||||
string customerName = "Ms. Barros";
|
||||
|
||||
string currentProduct = "Magic Yield";
|
||||
int currentShares = 2975000;
|
||||
decimal currentReturn = 0.1275m;
|
||||
decimal currentProfit = 55000000.0m;
|
||||
|
||||
string newProduct = "Glorious Future";
|
||||
decimal newReturn = 0.13125m;
|
||||
decimal newProfit = 63000000.0m;
|
||||
|
||||
var formatted_letter = string.Format("Dear {0},\n", customerName);
|
||||
formatted_letter += $"As a customer of our {currentProduct} offering we" +
|
||||
"are excited to tell you about a new financial " +
|
||||
"product that would dramatically increase your " +
|
||||
"return.\n\n";
|
||||
formatted_letter += $"Currently, you own {currentShares:N2} shares at a return ";
|
||||
formatted_letter += $"of {currentReturn:P2}.\n\n";
|
||||
formatted_letter += $"Our new product, {newProduct} offers a return of ";
|
||||
formatted_letter += $"{newReturn:P2}. Given your current volume, your ";
|
||||
formatted_letter += $"potential profit would be {newProfit:C2}.\n";
|
||||
Console.WriteLine(formatted_letter);
|
||||
Console.WriteLine("Here's a quick comparison:\n");
|
||||
|
||||
string comparisonMessage = currentProduct.PadRight(20);
|
||||
comparisonMessage += $"{currentReturn:P2}".PadRight(9);
|
||||
comparisonMessage += $"{currentProfit:C2}\n";
|
||||
comparisonMessage += $"{newProduct}".PadRight(20);
|
||||
comparisonMessage += $"{newReturn:P2}".PadRight(9);
|
||||
comparisonMessage += $"{newProfit:C2}";
|
||||
|
||||
Console.WriteLine(comparisonMessage);
|
10
023_alphanumeric_data_format/form_letter/form_letter.csproj
Normal file
10
023_alphanumeric_data_format/form_letter/form_letter.csproj
Normal file
@ -0,0 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
59
023_alphanumeric_data_format/padding_alignment/Program.cs
Normal file
59
023_alphanumeric_data_format/padding_alignment/Program.cs
Normal file
@ -0,0 +1,59 @@
|
||||
string first = "Hello";
|
||||
string second = "World";
|
||||
string result = string.Format("{0} {1}!", first, second);
|
||||
Console.WriteLine(result);
|
||||
|
||||
Console.WriteLine("\n---------------------\n");
|
||||
|
||||
string input = "Pad this";
|
||||
Console.WriteLine(input.PadLeft(12));
|
||||
|
||||
Console.WriteLine("\n---------------------\n");
|
||||
|
||||
Console.WriteLine(input.PadRight(12));
|
||||
|
||||
Console.WriteLine("\n---------------------\n");
|
||||
|
||||
Console.WriteLine(input.PadLeft(12, '-'));
|
||||
Console.WriteLine(input.PadRight(12, '-'));
|
||||
|
||||
Console.WriteLine("\n---------------------\n");
|
||||
|
||||
string paymentId = "769C";
|
||||
var formattedLine = paymentId.PadRight(6);
|
||||
Console.WriteLine(formattedLine);
|
||||
|
||||
Console.WriteLine("\n---------------------\n");
|
||||
|
||||
paymentId = "769C";
|
||||
string payeeName = "Mr. Stephen Ortega";
|
||||
|
||||
formattedLine = paymentId.PadRight(6);
|
||||
formattedLine += payeeName.PadRight(24);
|
||||
|
||||
Console.WriteLine(formattedLine);
|
||||
|
||||
Console.WriteLine("\n---------------------\n");
|
||||
|
||||
paymentId = "769C";
|
||||
payeeName = "Mr. Stephen Ortega";
|
||||
string paymentAmount = "$5,000.00";
|
||||
|
||||
formattedLine = paymentId.PadRight(6);
|
||||
formattedLine += payeeName.PadRight(24);
|
||||
formattedLine += paymentAmount.PadLeft(10);
|
||||
|
||||
Console.WriteLine(formattedLine);
|
||||
|
||||
Console.WriteLine("\n---------------------\n");
|
||||
|
||||
paymentId = "769C";
|
||||
payeeName = "Mr. Stephen Ortega";
|
||||
paymentAmount = "$5,000.00";
|
||||
|
||||
formattedLine = paymentId.PadRight(6);
|
||||
formattedLine += payeeName.PadRight(24);
|
||||
formattedLine += paymentAmount.PadLeft(10);
|
||||
|
||||
Console.WriteLine("1234567890123456789012345678901234567890");
|
||||
Console.WriteLine(formattedLine);
|
@ -0,0 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
11
023_alphanumeric_data_format/string_interpolation/Program.cs
Normal file
11
023_alphanumeric_data_format/string_interpolation/Program.cs
Normal file
@ -0,0 +1,11 @@
|
||||
int invoiceNumber = 1201;
|
||||
decimal productShares = 25.4568m;
|
||||
decimal subtotal = 2750.00m;
|
||||
decimal taxPercentage = .15825m;
|
||||
decimal total = 3185.19m;
|
||||
|
||||
Console.WriteLine($"Invoice Number: {invoiceNumber}");
|
||||
Console.WriteLine($" Shares: {productShares:N3} Product");
|
||||
Console.WriteLine($" Sub Total: {subtotal:C}");
|
||||
Console.WriteLine($" Tax: {taxPercentage:P2}");
|
||||
Console.WriteLine($" Total Billed: {total:C}");
|
@ -0,0 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
@ -27,3 +27,4 @@ Following
|
||||
20. [Choose the correct data type](./020_data_types/020_csharp.md)
|
||||
21. [Convert data types](./021_Casting_and_conversion_techniques/021_csharp.md)
|
||||
22. [Array Operations](./022_array_operations/022_csharp.md)
|
||||
23. [Format alphanumeric data](/023_alphanumeric_data_format/023_csharp.md)
|
||||
|
Loading…
Reference in New Issue
Block a user