Fundamentals of Tuples

Introduction

A tuple is a series of values considered as an entity. A tuple is not a data type like an integer or a string, but it is used as if it were. This means that you can declare a variable as a tuple but it is not strictly used as the types of regular variables we have used so far.

A tuple is a combination of values where each value is recognized for itself. A value can be one of the primitive types we have already seen (int, bool, double, or string). A value can also be a class type.

Practical LearningPractical Learning: Introducing Tuples

  1. Start Microsoft Visual Studio. In the Visual Studio 2019 dialog box, click Create a New Project and click Next (if Microsoft Visual Studio was already running, on the main menu, click File -> New -> Project...)
  2. In the list of projects templates, click Windows Forms App (.NET Framework)
  3. Click Next
  4. Change the project Name to DepartmentStore3
  5. Click Create
  6. Design the form as follows:

    Introducing Tuples

    Control (Name) Text Other Properties
    GroupBox   Item Preview:  
    Label   Item Number:  
    TextBox txtItemNumber    
    CheckBox chkSubjectToDiscount Item Preview: CheckAlign: MiddleRight
    Label   Item Name:  
    TextBox txtItemName  
    Label   Unit Price:
    TextBox txtUnitPrice 0.00 TextAlign: Right
    Label   Days in Store:  
    TextBox txtDaysInStore 0 TextAlign: Right
    Label   Days:  
    Button btnCalculate Evaluate Sale Record  
    GroupBox   Sale Preview  
    Label   Item Number:  
    TextBox txtRecordItemNumber TextAlign: Right
    Label   Discount Rate:  
    TextBox txtDiscountRate   TextAlign: Right
    Label   %  
    Label   Item Name:  
    TextBox txtRecordItemName  
    Label   Discount Amount:  
    TextBox txtDiscountAmount   TextAlign: Right
    Label   Marked Price:  
    TextBox txtMarkedPrice   TextAlign: Right
  7. Double-click the Evaluate Sale Record button
  8. Right-click the Code Editor and click Remove and Sort Usings

Creating a Tuple

You create a tuple as if you are declaring a variable as we have done so far. As a reminder, the formula to declare a variable is:

data-type variable-name;

This time, in place of the data type, use some parentheses. For what inside the parentheses, you have various options. To start, in the parentheses of the tuple, you can write two or more data types. Those data types are separated by commas. Here are examples:

// A tuple made of integral numbers only
(int, int)
// A tuple made of strings only
(string, string, string)
// A tuple made of various types of values
(int, string, double)

A value in a tuple can be called an item, a member, or an element (those are the names we will use in our lessons; all those names will mean the same thing).

In some cases, you can use an algebraic name to identify or define a tuple:

Naming a Tuple

After specifying the type of the tuple, like every variable, you must name it. This is done after the closing parenthesis. The name of a tuple follows the names of variables. After the name of the variable, add a semicolon. Here are examples:

(int, int) coordinates;
(string, string, string) employeeName;
(int, string, double) definition;

Initializing a Tuple: Binding Values to Elements of a Tuple

As is the case for other variables, before using a variable, you must initialize it. This is done by assigning a variable to each member of the tuple. You have various options.

As one way to initialize a tuple, assign the desired values to it. As a reminder, the formula to declare and initialize a variable is:

data-type variable-name = value;

Based on this formula, to initialize a tuple, add the assignment operator after the name of the tuple. Add some parentheses. In the parentheses, specify the value of each member exactly in the order the data types appear in the declaration. Here is an example:

(string, string, string) students = ("Aaron", "Jennifer", "Yerimah");

As an alternative, you can first declare a variable on one line, and then initialize it on another line. Here is an example:

(string, string, string) students;

students = ("Aaron", "Jennifer", "Yerimah")

Introduction to Using a Tuple

Introduction

The primary way you can use a tuple is to present its values to the user. To do this from the Console.Write() or the Console.WriteLine() methods, enter the name of the tuple in the parentheses. Here is an example:

using static System.Console;

namespace Exercises
{
    public class Exercise
    {
        public static void Main()
        {
            (string, string) employee = ("Robert", "Ewell");

            Write("Employee: ");
            WriteLine(employee);
            WriteLine("=================================");
        }
    }
}

This would produce:

Employee: (Robert, Ewell)
=================================
Press any key to continue . . .

To display a tuple in a Windows control, apply the ToString() method to the variable. Here is an example:

using System;
using System.Windows.Forms;

namespace Exercise
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            (string, int, int) coordinates = ("A", 4, 6);

            txtCoordinates.Text = coordinates.ToString();
        }
    }
}

Accessing an Element of a Tuple

The elements of a tuple each has a name. By default, the first element is named Item1, the second element is named Item2, and so on. These names are specified automatically by the compiler when you create a tuple. To access an element of a tuple, type the variable name of a tuple, a period, and the name of the element. If you are using Microsoft Visual Studio to develop your application, when you type the tuple variable and a period, the intellisense will display the names of the elements of the tuple. Here is an example:

Accessing an Element of a Tuple

By accessing each element like that, you can initialize a tuple by assigning a value to each element. Here is an example:

public class Exercise
{
    public static void Main()
    {
        (int, string, string, double) contractor;

        contractor.Item1 = 947_069;
        contractor.Item2 = "Gerard";
        contractor.Item3 = "Soundjok";
        contractor.Item4 = 68426;
    }
}

In the same way, you can access an element to present its value to the user. Here are examples:

using System;

namespace Exercise1
{
    class Program
    {
        static void Main()
        {
            (int, string, string, double) contractor;

            contractor.Item1 = 947_069;
            contractor.Item2 = "Gerard";
            contractor.Item3 = "Soundjok";
            contractor.Item4 = 68426;

            Console.WriteLine("Employee Record");
            Console.WriteLine("------------------------");
            Console.Write("Employee #:    ");
            Console.WriteLine(contractor.Item1);
            Console.Write("First Name:    ");
            Console.WriteLine(contractor.Item2);
            Console.Write("Last Name:     ");
            Console.WriteLine(contractor.Item3);
            Console.Write("Yearly Salary: ");
            Console.WriteLine(contractor.Item4);
            Console.WriteLine("========================");
        }
    }
}

This would produce:

Employee Record
------------------------
Employee #:    947069
First Name:    Gerard
Last Name:     Soundjok
Yearly Salary: 68426
========================
Press any key to continue . . .

Naming the Members of a Tuple

As seen already, when creating a tuple, you can simply specify the data types of the members of the tuple. As an option, you can name 0, some, or all members of the tuple. To name a member, after the data type of a member, add a space and a name. Again, you are free to choose what member(s) to name. Here are examples:

(double, string) x;
(int horizontal, int) coordinates;
(string first_name, string, string last_name) employeeName;
(int employeeNumber, string employment_Status, double yearlysalary) definition;

You can then initialize the tuple. Once again, to access an element of a tuple, type the name of the tuple variable, a period, and the element you want. Again, if you are using Microsoft Visual Studio, the intellisense will display the names of the elements of the tuple. Here are two examples where some elements were named and some were not:

Accessing an Element of a Tuple

Accessing an Element of a Tuple

When accessing the items of a tuple, if you had named an element, you can use either its default name (Item1, Item2, etc) or the name you had specified.

Practical LearningPractical Learning: Creating a Tuple

  1. To create a tuple, change the implement of the Click event as follows:
    using System;
    using System.Windows.Forms;
    
    namespace DepartmentStore3
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void btnEvaluate_Click(object sender, EventArgs e)
            {
                (int number, string name, double price, bool discounted, int days) storeItem;
            }
        }
    }
  2. To use the tuple, change the document as follows:
    using System;
    using System.Windows.Forms;
    
    namespace DepartmentStore3
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            double EvaluateDiscountRate(int days)
            {
                double discountRate = 0.00;
    
                if (days > 70)
                    discountRate = 70;
                else if (days > 50)
                    discountRate = 50;
                else if (days > 30)
                    discountRate = 35;
                else if (days > 15)
                    discountRate = 15;
    
                return discountRate;
            }
            
            double EvaluateDiscountAmount(double cost, bool reduced, double rate)
            {
                double discountAmount = 0.00;
    
                if(reduced == true)
                {
                    discountAmount = cost * rate / 100.00;
                }
    
                return discountAmount;
            }
    
            private void btnEvaluate_Click(object sender, EventArgs e)
            {
                (int number, string name, double price, bool discounted, int days) storeItem;
    
                storeItem.name = txtItemName.Text;
                storeItem.days = int.Parse(txtDaysInStore.Text);
                storeItem.number = int.Parse(txtItemNumber.Text);
                storeItem.price = double.Parse(txtUnitPrice.Text);
                storeItem.discounted = chkSubjectToDiscount.Checked;
    
                int a = storeItem.days;
                bool b = storeItem.discounted;
                double c = storeItem.price;
    
                double discountRate = EvaluateDiscountRate(a);
                double discountedAmount = EvaluateDiscountAmount(c, b, discountRate);
                double markedPrice = c - discountedAmount;
    
                if (chkSubjectToDiscount.Checked == false)
                    txtDiscountRate.Text = "0.00";
                else
                    txtDiscountRate.Text = discountRate.ToString("F");
    
                txtDiscountAmount.Text = discountedAmount.ToString("F");
                txtMarkedPrice.Text = markedPrice.ToString("F");
    
                txtRecordItemNumber.Text = storeItem.number.ToString();
                txtRecordItemName.Text = storeItem.name;
            }
        }
    }
  3. To execute, on the main menu, click Debug -> Start Without Debugging:

    Using a Tuple

  4. In the text boxes above the Evaluate button, enter some values as follows:
    Item Number:   258408
    Item Name:     Pinstripe Pencil Skirt
    Unit Price:    94.95
    Days in Store: 36

    Conditionally Returning a Value

  5. Click the Evaluate Sale Record button:

    Conditionally Returning a Value

  6. Click the Subject to Discount check box
  7. Click the Evaluate Sale Record button:

    Conditionally Returning a Value

  8. Close the form and return to your programming environment

Other Techniques of Initializing a Tuple

A Value from a Variable

We already know that, when you create a tuple, sooner or later, you must specify the value of each member. The value of a member can come from a variable. Here is an example:

using System;

namespace Exercise1
{
    class Program
    {
        static void Main()
        {
            int emplNbr = 138_475;

            (int emplNumber, string firstName, string lastName) employee = (emplNbr, "Gwendolyn", "Valance");

            Console.WriteLine("Employee Record");
            Console.WriteLine("---------------------------------------");
            Console.WriteLine($"Employee #: {employee.emplNumber}");
            Console.WriteLine($"Full Name:  {employee.Item2} {employee.lastName}");
            Console.WriteLine("=======================================");
        }
    }
}

This would produce:

Employee Record
---------------------------------------
Employee #: 138475
Full Name:  Gwendolyn Valance
=======================================
Press any key to continue . . .

A Value from an Expression

The value of a member of a tuple can come from an expression. Here is an example:

using System;

namespace Exercise1
{
    class Program
    {
        static void Main()
        {
            int emplNbr = 138_475;
            double weeklySalary = 22.27;
            string fName = "Christoffer";
            string lName = "Prize";

            (int emplNumber, string fullName, double salary) employee = (emplNbr, fName + " " + lName, weeklySalary * 40);

            Console.WriteLine("Employee Record");
            Console.WriteLine("---------------------------------------");
            Console.WriteLine($"Employee #:    {employee.emplNumber}");
            Console.WriteLine($"Full Name:     {employee.fullName}");
            Console.WriteLine($"Weekly Salary: {employee.salary}");
            Console.WriteLine("=======================================");
        }
    }
}

This would produce:

Employee Record
---------------------------------------
Employee #:    138475
Full Name:     Christoffer Prize
Weekly Salary: 890.8
=======================================
Press any key to continue . . .

The value of the variable can come from an expression, a property of a class, a function, etc. Here is an example:

using System;

namespace Exercise1
{
    class Program
    {
        static double EvaluateSalary(double hourly)
        {
            return hourly * 40;
        }

        static void Main()
        {
            int emplNbr = 138_475;
            double weeklySalary = 22.27;
            string fName = "Christoffer";
            string lName = "Prize";
            double sal = EvaluateSalary(weeklySalary);

            (int emplNumber, string fullName, double salary) employee = (emplNbr, fName + " " + lName, sal);

            Console.WriteLine("Employee Record");
            Console.WriteLine("---------------------------------------");
            Console.WriteLine($"Employee #:    {employee.emplNumber}");
            Console.WriteLine($"Full Name:     {employee.fullName}");
            Console.WriteLine($"Weekly Salary: {employee.salary}");
            Console.WriteLine("=======================================");
        }
    }
}

A Value from a Function

The value of a member of a tuple can come from a function or method. Here is an example:

using System;

namespace Exercise1
{
    class Program
    {
        static double EvaluateSalary(double hourly)
        {
            return hourly * 40 * 4 * 12;
        }

        static void Main()
        {
            int emplNbr = 726_254;
            double weeklySalary = 24.08;
            string fName = "Claudine";
            string lName = "McNeal";

            (int emplNumber, string fullName, double salary) employee = (emplNbr, fName + " " + lName, EvaluateSalary(weeklySalary));

            Console.WriteLine("Employee Record");
            Console.WriteLine("---------------------------------------");
            Console.WriteLine($"Employee #:    {employee.emplNumber}");
            Console.WriteLine($"Full Name:     {employee.fullName}");
            Console.WriteLine($"Weekly Salary: {employee.salary}");
            Console.WriteLine("=======================================");
        }
    }
}

This would produce:

Employee Record
---------------------------------------
Employee #:    726254
Full Name:     Claudine McNeal
Weekly Salary: 46233.6
=======================================
Press any key to continue . . .

A var Tuple

You can declare a tuple variable using the var keyword. Remember that if you declare a variable with that keyword, you must immediately initialize it. Therefore, the formula to declare a var tuple is:

var variable-name = ( item_1, item_2, item_x);

In the parentheses, you can specify the desired value for each member of the tuple. Here is an example:

class Exercise
{
    static void Main()
    {
        var staff = (392507, "Gertrude", "Ngovayang", 96275);
    }
}

You can then access the elements of the tuple. Once again in this case, by default, the first element is named Item1, the second is name Item2, and so on. Here are examples:

using System;

namespace Exercise1
{
    class Program
    {
        static void Main()
        {
            var staff = (392507, "Gertrude", "Ngovayang", 96275);

            Console.WriteLine("Employee Record");
            Console.WriteLine("------------------------");
            Console.Write("Employee #:    ");
            Console.WriteLine(staff.Item1);
            Console.Write("First Name:    ");
            Console.WriteLine(staff.Item2);
            Console.Write("Last Name:     ");
            Console.WriteLine(staff.Item3);
            Console.Write("Yearly Salary: ");
            Console.WriteLine(staff.Item4);
            Console.WriteLine("========================");
        }
    }
}

This would produce:

Employee Record
------------------------
Employee #:    392507
First Name:    Gertrude
Last Name:     Ngovayang
Yearly Salary: 96275
========================
Press any key to continue . . .

We saw that, when creating a tuple, you can specify the name of an element. If you are creating a var tuple, to specify the name of an element, in the parentheses, type that name, a colon, and the value of the element. Here are examples:

class Exercise
{
    static void Main()
    {
        var staff = (392507, firstName: "Gertrude", "Ngovayang", salary: 96275);
    }
}

This time too, you can access an element either by its ordinal name or the name you had given it, if any. Here are examples:

using System;

namespace Exercise1
{
    class Program
    {
        static void Main()
        {
            var staff = (emplNumber: 392507, "Gertrude", lastName: "Ngovayang", 96275, fullTime: true);

            Console.WriteLine("Employee Record");
            Console.WriteLine("------------------------------");
            Console.Write("Employee #:         ");
            Console.WriteLine(staff.Item1);
            Console.Write("First Name:         ");
            Console.WriteLine(staff.Item2);
            Console.Write("Last Name:          ");
            Console.WriteLine(staff.lastName);
            Console.Write("Yearly Salary:      ");
            Console.WriteLine(staff.Item4);
            Console.Write("Employed Full-Time: ");
            Console.WriteLine(staff.Item5);
            Console.WriteLine("=============================");
        }
    }
}

This would produce:

Employee Record
------------------------------
Employee #:         392507
First Name:         Gertrude
Last Name:          Ngovayang
Yearly Salary:      96275
Employed Full-Time: True
=============================
Press any key to continue . . .

Tuples and Functions

Introduction

We have seen that a tuple is a series of values. Each value is a sub-variable by itself. Such a value can be considered individually. For example, you can involve an element of a tuple in an operation that doesn't necessarily involve the other members of the same tuple. In the same way, you can pass a member of a tuple to a function.

Practical LearningPractical Learning: Introducing Tuples and Functions

  1. Change the event as follows:
    using System;
    using System.Windows.Forms;
    
    namespace DepartmentStore3
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            double EvaluateDiscountRate(int days)
            {
                double discountRate = 0.00;
    
                if (days > 70)
                    discountRate = 70;
                else if (days > 50)
                    discountRate = 50;
                else if (days > 30)
                    discountRate = 35;
                else if (days > 15)
                    discountRate = 15;
    
                return discountRate;
            }
            
            double EvaluateDiscountAmount(double cost, bool reduced, double rate)
            {
                double discountAmount = 0.00;
    
                if(reduced == true)
                {
                    discountAmount = cost * rate / 100.00;
                }
    
                return discountAmount;
            }
    
            private void btnEvaluate_Click(object sender, EventArgs e)
            {
                (int number, string name, double price, bool discounted, int days) storeItem;
    
                storeItem.name = txtItemName.Text;
                storeItem.days = int.Parse(txtDaysInStore.Text);
                storeItem.number = int.Parse(txtItemNumber.Text);
                storeItem.price = double.Parse(txtUnitPrice.Text);
                storeItem.discounted = chkSubjectToDiscount.Checked;
    
                double discountRate = EvaluateDiscountRate(storeItem.days);
                double discountedAmount = EvaluateDiscountAmount(storeItem.price, storeItem.discounted, discountRate);
                double markedPrice = storeItem.price - discountedAmount;
    
                if (chkSubjectToDiscount.Checked == false)
                    txtDiscountRate.Text = "0.00";
                else
                    txtDiscountRate.Text = discountRate.ToString("F");
    
                txtDiscountAmount.Text = discountedAmount.ToString("F");
                txtMarkedPrice.Text = markedPrice.ToString("F");
    
                txtRecordItemName.Text = storeItem.name;
                txtRecordItemNumber.Text = storeItem.number.ToString();
            }
        }
    }
  2. To execute, press Ctrl + F5
  3. Close the form and return to Microsoft Visual Studio

Passing a Tuple as Parameter

If you have a group of values that you want a function to process, instead of passing those values individually, you can package those values in ne tuple. In other words, you can create a function that takes a tuple as argument.

To make a function process a tuple, when creating the function, in its parentheses, type the parentheses for a tuple, followed by a name for the parameter. In the parentheses of the tuple, enter the data type of each member of the tuple and separate them with commas Here is an example:

void Calculate((int, double, string) parameter)
{
}

In the body of the function, to access the tuple, use the name of the parameter. To access a member of the tuple, in the body of the function, type the name of the parameter, a period, and the name of the desired member. As seen with using tuples on a function, if you provided only the data types of the members of the tuple parameter, access the members with their incrementing names: Item1, Item2, etc. As an alternative, you can provide a name for one or more members of the tuple parameters.

Practical LearningPractical Learning: Passing Tuples as Parameters

  1. Change the document as follows:
    using System;
    using System.Windows.Forms;
    
    namespace DepartmentStore3
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            double EvaluateDiscountRate(int days)
            {
                double discountRate = 0.00;
    
                if (days > 70)
                    discountRate = 70;
                else if (days > 50)
                    discountRate = 50;
                else if (days > 30)
                    discountRate = 35;
                else if (days > 15)
                    discountRate = 15;
    
                return discountRate;
            }
            
            double EvaluateDiscountAmount((double, bool, int) obj)
            {
                double discountAmount = 0.00;
    
                double fraction = EvaluateDiscountRate(obj.Item3);
    
                if(obj.Item2 == true)
                {
                    discountAmount = obj.Item1 * fraction / 100.00;
                }
    
                return discountAmount;
            }
    
            void PresentItem((int, string) obj)
            {
                txtRecordItemName.Text   = obj.Item2;
                txtRecordItemNumber.Text = obj.Item1.ToString();
            }
    
            void Summerize((bool hasLasted, double rate, double discount, double salePrice) obj)
            {
                if (obj.hasLasted == false)
                    txtDiscountRate.Text = "0.00";
                else
                    txtDiscountRate.Text = obj.rate.ToString("F");
    
                txtDiscountAmount.Text = obj.discount.ToString("F");
                txtMarkedPrice.Text    = obj.salePrice.ToString("F");
            }
    
            private void btnEvaluate_Click(object sender, EventArgs e)
            {
                (int number, string name) identification;
                (double price, bool discounted, int days) itemInfo;
                (bool discounted, double rate, double discount, double amount) sale;
    
                identification.name = txtItemName.Text;
                identification.number = int.Parse(txtItemNumber.Text);
    
                itemInfo.days = int.Parse(txtDaysInStore.Text);
                itemInfo.price = double.Parse(txtUnitPrice.Text);
                itemInfo.discounted = chkSubjectToDiscount.Checked;
    
                double discountRate = EvaluateDiscountRate(itemInfo.days);
                double discountedAmount = EvaluateDiscountAmount(itemInfo);
                double markedPrice = itemInfo.price - discountedAmount;
    
                sale.rate = discountRate;
                sale.amount = markedPrice;
                sale.discount = discountedAmount;
                sale.discounted = chkSubjectToDiscount.Checked;
    
                Summerize(sale);
                PresentItem(identification);
            }
        }
    }
  2. To execute, press Ctrl + F5
  3. Close the form and return to Microsoft Visual Studio

Passing Many Tuples to a Method

We saw that you can pass a tuple to a method. In the same way, you can pass a combination of a tuple and parameters of regular types to a method. Here is an example:

void Examine(int id, (string title, string description) issue, bool resolved)
{

}

In the same way, you can create a function or method that takes more than one tuple as parameters.

Practical LearningPractical Learning: Passing Many Tuples to a Function

  1. On the main menu, click File -> New -> Project...
  2. In the list of projects templates, click Windows Forms App (.NET Framework)
  3. Click Next
  4. Change the project Name to LinearGeometry1
  5. Click Create
  6. In the Solution Explorer, right-click Form1.cs -> Rename
  7. Type LinearGeometry to get LinearGeometry.cs
  8. Press Enter twice
  9. Design the form as follows:

    Passing Many Tuples to a Function

    Control (Name) Text
    Label   Equation of a line that goes through
    Label   A(
    TextBox txtPointStartX 0
    Label   ,
    TextBox txtPointStartY 0
    Label   ) and B(
    TextBox txtPointEndX 0
    Label   ,
    TextBox txtPointEndY 0
    Label   )
    Button btnFind Find
    Label   Equation
    TextBox txtEquation  
  10. On the form, double-click the Find button
  11. Right-click inside the Code Editor and click Remove and Sort Usings
  12. Change the document as follows:
    using System;
    using System.Windows.Forms;
    
    namespace LinearGeometry1
    {
        public partial class LinearGeometry : Form
        {
            int gcd(int a, int b)
            {
                if (b == 0)
                    return a;
                else
                    return gcd(b, a % b);
            }
        
            string CreateEquation((int a1, int b1) first, (int a2, int b2) last)
            {
                int a = first.b1 - last.b2;
                int b = last.a2 - first.a1;
                int c = (last.a2 * first.b1) - (first.a1 * last.b2); // (a2 * b1) - (a1 * b1) - (a1 * b1) + (a1 * b2)
    
                string u, v, w;
                string absu, absv /*, absw */;
                
                if (a / (gcd(a, (gcd(b, c)))) == 1)
                {
                    u    = "";
                    absu = "";
                }
                else
                {
                    u    = Math.Abs(a / (gcd(a, (gcd(b, c))))).ToString();
                    absu = Math.Abs(a / (gcd(a, (gcd(b, c))))).ToString();
                }
                
                if(b / (gcd(a, (gcd(b, c)))) == 1)
                {
                    v    = "";
                    absv = "";
                }
                else
                {
                    v    = (b / (gcd(a, (gcd(b, c))))).ToString();
                    absv = Math.Abs(b / (gcd(a, (gcd(b, c))))).ToString();
                }
                
                if(c / (gcd(a, (gcd(b, c)))) == 1)
                {
                    w    = "";
                    // absw = "";// 
                }
                else
                {
                    w    = Math.Abs(c / (gcd(a, (gcd(b, c))))).ToString();
                    //absw = Math.Abs(c / (gcd(a, (gcd(b, c))))).ToString();
                }
    
                if ((Math.Sign(a / (gcd(a, (gcd(b, c))))) == -1) && (Math.Sign(b / (gcd(a, (gcd(b, c)))))) == 1)
                {
                    if (a / (gcd(a, (gcd(b, c)))) == -1)
                        return "x - " + absv + "y = " + ((-1 * c) / (gcd(a, (gcd(b, c))))).ToString();
                    else
                        return absu + "x - " + absv + "y = " + ((-1 * c) / (gcd(a, (gcd(b, c))))).ToString();
                }
                else
                    return u + "x + " + v + "y = " + w;
            }
    
            public LinearGeometry()
            {
                InitializeComponent();
            }
    
            private void btnFind_Click(object sender, EventArgs e)
            {
                int a1 = int.Parse(txtPointStartX.Text);
                int b1 = int.Parse(txtPointStartY.Text);
                int a2 = int.Parse(txtPointEndX.Text);
                int b2 = int.Parse(txtPointEndY.Text);
    
                (int, int) startingPoint = (a1, b1);
                (int, int) endingPoint   = (a2, b2);
    
                string equation = CreateEquation(startingPoint, endingPoint);
    
                txtEquation.Text = equation;
            }
        }
    }
    
    // let equation = createEquation (2, 3) (1, -4); // 7x - y = 11
    // let equation = createEquation (-1, 5) (2, -4); // 3x + y = 2
    // let equation = createEquation (1, 6) (3, 2); // 2x + y = 8
    // let equation = createEquation (1, 3) (0, 1); // 2x - y = -1
    // let equation = createEquation (4, 5) (3, 2); // 3x - y = 7
    // let equation = createEquation (0, 4) (6, 0); // 2x + 3y = 12
    // let equation = createEquation (-2, 3) (3, 8); // x - y = -5
    // let equation = createEquation (-3, 3) (3, -1); // 4x + 6y =  6 => Reduced: 2x + 3y = 3
    // let equation = createEquation (1, 6) (3, 2);   // 4x + 2y = 16 => Reduced: 2x + y = 8
    // let equation = createEquation (3, 2) (7, -4);    // 6x + 4y = 26 => Reduced: 3x + 2y = 13
  13. To execute, on the main menu, click Debug -> Start Without Debugging:

    Passing Many Tuples

  14. In the top 4 text boxes, enter the following values:
    A(5, 2) and B(3, 6)

    Passing Many Tuples

  15. Click the Find button

    Modeling a Window

  16. Close the form and return to Microsoft Visual Studio
  17. On the main menu, click File -> New -> Project...
  18. In the list of projects templates, click Windows Forms App (.NET Framework)
  19. Click Next
  20. Change the project Name to PayrollPreparation08
  21. Click Create
  22. In the Solution Explorer, right-click Form1.cs -> Rename
  23. Type PayrollEvaluation to get PayrollEvaluation.cs
  24. Press Enter twice
  25. Design the form as follows:

    Returning a Tuple

    Control (Name) Text TextAlign
    Label   Hourly Salary:  
    TextBox txtHourlySalary 0.00 Right
    Label   Time Worked _____________
    Label   Monday
    Label   Tuesday
    Label   Wednesday
    Label   Thursday  
    Label   Friday  
    TextBox txtMondayTimeWorked 0.00 Right
    TextBox txtTuesdayTimeWorked 0.00 Right
    TextBox txtWednesdayTimeWorked 0.00 Right
    TextBox txtThursdayTimeWorked 0.00 Right
    TextBox txtFridayTimeWorked 0.00 Right
    Button btnEvaluate Evaluate  
    Label   Payroll Summary __________
    Label   Monday
    Label   Tuesday
    Label   Wednesday
    Label   Thursday  
    Label   Friday  
    Label   Total  
    Label   Regular Time:
    TextBox txtMondayRegularTime Right
    TextBox txtTuesdayRegularTime Right
    TextBox txtWednesdayRegularTime Right
    TextBox txtThursdayRegularTime Right
    TextBox txtFridayRegularTime Right
    Label   Overtime:
    TextBox txtMondayOvertime Right
    TextBox txtTuesdayOvertime Right
    TextBox txtWednesdayOvertime Right
    TextBox txtThursdayOvertime Right
    TextBox txtFridayOvertime Right
    Label   Regular Time Pay:
    TextBox txtMondayRegularPay Right
    TextBox txtTuesdayRegularPay Right
    TextBox txtWednesdayRegularPay Right
    TextBox txtThursdayRegularPay Right
    TextBox txtFridayRegularPay Right
    Label   Overtime Pay:
    TextBox txtMondayOvertimePay Right
    TextBox txtTuesdayOvertimePay Right
    TextBox txtWednesdayOvertimePay Right
    TextBox txtThursdayOvertimePay Right
    TextBox txtFridayOvertimePay Right
    Label   ________________________
    Label   Total Pay:
    TextBox txtMondayTotalPay Right
    TextBox txtTuesdayTotalPay Right
    TextBox txtWednesdayTotalPay Right
    TextBox txtThursdayTotalPay Right
    TextBox txtFridayTotalPay Right
    Label   ________________________
    Label   Time
    Label   Pay
    Label   Regular:
    TextBox txtSummaryRegularTime Right
    TextBox txtSummaryRegularPay Right
    Label   Overtime:
    TextBox txtSummaryOvertime Right
    TextBox txtSummaryOvertimePay Right
    Label   ________________________
    Label   Net Pay:
    TextBox txtNetPay Right
  26. On the form, double-click the Evaluate button
  27. Right-click inside the Code Editor and click Remove and Sort Usings

Returning a Tuple

Instead of a regular single value, a function can be made to return a tuple, which is a combination of values. This is one of the most important features of tuples.

When creating a function, to indicate that it must produce a tuple, on the left side of the name of the function, type a tuple. Here is an example:

(string, int, string, double) Summarize()
{

}

On the last line, type the return keyword, followed by a tuple that uses a combination of values of the exact same type declared for the function. Here is an example

(string, int, string, double) Summarize()
{
    return ("John", 10, "Doe", 1.00);
}

Otherwise, in the body of the function, you can perform any operation you want. For example, you can declare variables of any type and use them any way you want. In fact, you can return a tuple that uses such local variables. Here is an example:

(string, int, string, double) Summarize()
{
    double salary = 52_846;
    int    code   = 293_704;
    string first  = "John", last = "Doe";

    return (first, code, last, salary);
}

The return tuple can also use one or more expressions. Here is an example:

(int, string, double) Summarize()
{
    double hourSalary = 22.86;
    int    code       = 293_704;
    string first      = "John", last = "Doe";

    /* Yearly Salary = Hourly Salary *  8 (= Daily Salary)
                                     *  5 (= Weekly Salary)
                                     *  4 (= Monthly Salary)
                                     * 12 (= Yearly Salary)   */

    return (code, first + " " + last, hourSalary * 8 * 5 * 4 * 12);
}

Practical LearningPractical Learning: Returning a Tuple

  1. Change the document as follows:
    using System;
    using System.Windows.Forms;
    
    namespace PayrollPreparation08
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            (double, double, double, double) EvaluatePay((double rate, double work) param)
            {
                double regTime, over, regPay, overPay;
    
                if (param.work <= 8.00)
                {
                    over    = 0.00;
                    overPay = 0.00;
                    regTime = param.work;
                    regPay  = param.work * param.rate;
                }
                else
                {
                    regTime = 8.00;
                    regPay  = param.rate * 8.00;
                    over    = param.work - 8.00;
                    overPay = over * param.rate * 1.50;
                }
    
                return (regTime, over, regPay, overPay);
            }
    
            double Add((double a, double b, double c, double d) all)
            {
                return all.c + all.d;
            }
    
            private void btnEvaluate_Click(object sender, EventArgs e)
            {
                double hourly = double.Parse(txtHourlySalary.Text);
                
                (double sal, double time) mon = (hourly, double.Parse(txtMondayTimeWorked.Text));
                (double sal, double time) tue = (hourly, double.Parse(txtTuesdayTimeWorked.Text));
                (double sal, double time) wed = (hourly, double.Parse(txtWednesdayTimeWorked.Text));
                (double sal, double time) thu = (hourly, double.Parse(txtThursdayTimeWorked.Text));
                (double sal, double time) fri = (hourly, double.Parse(txtFridayTimeWorked.Text));
    
                (double regularTime, double overtime, double regularPay, double overtimePay) monday    = EvaluatePay(mon);
                (double regularTime, double overtime, double regularPay, double overtimePay) tuesday   = EvaluatePay(tue);
                (double regularTime, double overtime, double regularPay, double overtimePay) wednesday = EvaluatePay(wed);
                (double regularTime, double overtime, double regularPay, double overtimePay) thursday  = EvaluatePay(thu);
                (double regularTime, double overtime, double regularPay, double overtimePay) friday    = EvaluatePay(fri);
    
                txtMondayRegularTime.Text    = monday.regularTime.ToString("F");
                txtMondayOvertime.Text       = monday.overtime.ToString("F");
                txtMondayRegularPay.Text     = monday.regularPay.ToString("F");
                txtMondayOvertimePay.Text    = monday.overtimePay.ToString("F");
                txtMondayTotalPay.Text       = Add(monday).ToString("F");
    
                txtTuesdayRegularTime.Text   = tuesday.regularTime.ToString("F");
                txtTuesdayOvertime.Text      = tuesday.overtime.ToString("F");
                txtTuesdayRegularPay.Text    = tuesday.regularPay.ToString("F");
                txtTuesdayOvertimePay.Text   = tuesday.overtimePay.ToString("F");
                txtTuesdayTotalPay.Text      = Add(tuesday).ToString("F");
    
                txtWednesdayRegularTime.Text = wednesday.regularTime.ToString("F");
                txtWednesdayOvertime.Text    = wednesday.overtime.ToString("F");
                txtWednesdayRegularPay.Text  = wednesday.regularPay.ToString("F");
                txtWednesdayOvertimePay.Text = wednesday.overtimePay.ToString("F");
                txtWednesdayTotalPay.Text    = Add(wednesday).ToString("F");
    
                txtThursdayRegularTime.Text  = thursday.regularTime.ToString("F");
                txtThursdayOvertime.Text     = thursday.overtime.ToString("F");
                txtThursdayRegularPay.Text   = thursday.regularPay.ToString("F");
                txtThursdayOvertimePay.Text  = thursday.overtimePay.ToString("F");
                txtThursdayTotalPay.Text     = Add(thursday).ToString("F");
    
                txtFridayRegularTime.Text    = friday.regularTime.ToString("F");
    
                txtFridayOvertime.Text       = friday.overtime.ToString("F");
                txtFridayRegularPay.Text     = friday.regularPay.ToString("F");
                txtFridayOvertimePay.Text    = friday.overtimePay.ToString("F");
                txtFridayTotalPay.Text       = Add(friday).ToString("F");
    
                txtTotalRegularTime.Text     = (monday.regularTime + tuesday.regularTime + wednesday.regularTime + thursday.regularTime + friday.regularTime).ToString("F");
                txtTotalOvertime.Text        = (monday.overtime    + tuesday.overtime    + wednesday.overtime    + thursday.overtime    + friday.overtime).ToString("F");
                txtTotalRegularTimePay.Text  = (monday.regularPay  + tuesday.regularPay  + wednesday.regularPay  + thursday.regularPay  + friday.regularPay).ToString("F");
                txtTotalOvertimePay.Text     = (monday.overtimePay + tuesday.overtimePay + wednesday.overtimePay + thursday.overtimePay + friday.overtimePay).ToString("F");
    
                txtSummaryRegularTime.Text   = (monday.regularTime + tuesday.regularTime + wednesday.regularTime + thursday.regularTime + friday.regularTime).ToString("F");
                txtSummaryOvertime.Text      = (monday.overtime    + tuesday.overtime    + wednesday.overtime    + thursday.overtime    + friday.overtime).ToString("F");
                txtSummaryRegularPay.Text    = (monday.regularPay  + tuesday.regularPay  + wednesday.regularPay  + thursday.regularPay  + friday.regularPay).ToString("F");
                txtSummaryOvertimePay.Text   = (monday.overtimePay + tuesday.overtimePay + wednesday.overtimePay + thursday.overtimePay + friday.overtimePay).ToString("F");
    
                txtNetPay.Text               = (monday.regularPay    + monday.overtimePay    + 
                                                tuesday.regularPay   + tuesday.overtimePay   + 
                                                wednesday.regularPay + wednesday.overtimePay +
                                                thursday.regularPay  + thursday.overtimePay  + 
                                                friday.regularPay    + friday.overtimePay).ToString("F");
            }
        }
    }
  2. To execute, on the main menu, click Debug -> Start Without Debugging:

    Returning a Tuple

  3. In the top text boxes, enter the following values:
    Hourly Salary: 24.73
    Monday:         8.00
    Tuesday:        6.00
    Wednesday:     10.50
    Thursday:       7.50
    Friday:         9.00

    Returning a Tuple

  4. Click the Evaluate button:

    Returning a Tuple

  5. Close the form and return to Microsoft Visual Studio

Function/Method Overloading

In our introduction to function/method overloading, we saw that a function or method can get overloaded if you create more than one version in the same context. We also saw that the versions of the function must differ by their syntax or signature. Remember that the signature of a function doesn't include its return type. Based on this, you cannot overload a function based on the fact that one version returns a tuple and another does not.

To overload a function or method that involves tuples, you will rely on the parameters. You can create a function or method that has different versions. Two or more versions of a function or method can take one tuple parameter each; each tuple-parameter can have the same number of elements but the elements can be different. Consider the following example:

namespace Exercises
{
	public class Exercise
	{
	    /* The following two versions of an overloaded function/method take one tuple 
    	 * as parameter, but each tuple-parameter has different types of parameters. */
	    void Calculate((string, string) a)
    	{
	    }

	    void Calculate((string, double) a)
    	{
	    }

	    /* The following additional three versions of an overloaded function/method take 
    	 * one tuple as parameter, but each tuple-parameter has different number of parameters. */
	    void Calculate((int, bool) a)
    	{
	    }

	    void Calculate((string, int, double) a)
    	{
	    }

	    void Calculate((string, int, bool, double) a)
    	{
	    }
    
    	public static void Main()
	    {
    	}    
    }
}

On the other hand, you can overload a function or method by passing a mixture of primitive types and tuples.

Combining Tuples in Declaring Tuple Variables

We have already seen how to create a tuple. Here is an example:

public class Exercise
{
    public static void Main()
    {
        (string, int, string, double) pay_scale) contractor;
    }
}

In reality, every element of a tuple is an entity of its own. This means that you can create a tuple where an element of a tuple would be. Here are examples of tuples included in a tuple:

public enum Status { Something, Other, Nothing }

public class Exercise
{
    public static void Main()
    {
        ((string, string), int, (int, int, int), bool, (Status, double)) contractor;
    }
}

If the creation of a tuple is very long, you can create the element on different lines, like this:

public enum Status { Something, Other, Nothing }

public class Exercise
{
    public static void Main()
    {
        ((string, string),
         int, 
         (int, int, int),
         bool,
         (Status, double)
        ) contractor1;
    }
}

Or like this:

public enum Status { Something, Other, Nothing }

public class Exercise
{
    public static void Main()
    {
        (
            (string, string),
            int,
            (int, int, int),
            bool,
            (Status, double)
        ) contractor1;
    }
}

In fact, the following notation works as well:

public enum Status { Something, Other, Nothing }

public class Exercise
{
    public static void Main()
    {
        (
            (
            	string,
                string
            ),
            int,
            (
            	int,
                int,
                int
            ),
            bool,
            (
            	Status,
                double
            )
        ) contractor1;
    }
}

Once again, you are not required to name the elements of the tuples, but you must admit that the above tuple can be difficult to read. First, you must identify the primary element and how many they are. If you don't name them, the incremental default names given to them are Item1, Item2, etc.

To access an element that is from an internal tuple, first access its parent position.. This can be done as follows:

Tuples and Properties

Then use a period to access the internal element. This can be done as follows:

Tuples and Properties

As you can see, to make your tuple easy to read, it may be a good idea to name it elements. If you want, you can name just the primary elements. Here is an example:

((string, string) full_name, double height, (int, int, int) date_hired, bool recommended, (EmploymentStatus, double) pay_scale) contractor;

On the other hand, you can name only the internal elements. Here are examples:

((string fname, string lname), double, (int month, int day, int year), bool, (EmploymentStatus status, double rate)) contractor;

Otherwise, you can, and should, name all elements, primary and internal. Here are examples:

public enum EmploymentStatus { PartTime, FullTime, Seasonal }

public class Exercise
{
    public static void Main()
    {
        (
            (string fname, string lname) full_name,
            (int month, int day, int year) date_hired,
            (EmploymentStatus status, double rate) pay_scale
        ) contractor;
    }
}

You can then conveniently access the tuples and their elements using their explicit names.

Make:      AMD
Model:     RYZEN 5
Socket:    AM4
Processor: 6-Core, 12-Thread.
==============================
Press any key to continue . . .

Previous Copyright © 2001-2021, C# Key Next