Jump to content

Programing Practice

Windows7ge
8 hours ago, Nuluvius said:

you don't want to be doing more than one thing in a given method or class - they should only have a single concern

So if I'm testing an input against a condition in an if statement if the condition is true I should end the if statement as quickly as possible. If further lines need executing I should move them elsewhere and tell the if statement where to find them?

 

8 hours ago, Nuluvius said:

Yes, one would likely use int.TryParse

Is it OK for me to insert the syntax for this inside of a private void? This would make it so that it executes only when the button (for my circumstance it is a button) is pressed? Or does this have to be setup outside the private void and referenced (called? Is the action I think.) each time I want to test a value/input.

 

8 hours ago, Nuluvius said:

As I said, academia does a rather piss poor job of teaching how to do something the right way. Follow it if you will but you'll inevitably end up in a tangled mess and be very sad for your efforts. I took the information that you had described and turned into a very simple example of how one may encapsulate such behaviour in a set of abstractions (using a console application template).

I'm not trying to oppose your recommendations. I'm actually quite grateful you're putting forth the effort to help some stranger on the internet with no real expectation of compensation (that you've made me aware of anyways). I'm referencing what I learned from my class simply to express the magnitude of difference between what I learned vs what you've shown me. It's just to kind of show you how I don't have a complete grasp on the right way to do things. Attempting to switch languages at the exact same time doesn't make it any easier either :). I do have some understanding of the code you displayed. Some of it I can make educated guesses as to what role it plays. However what I could really use is a detailed breakdown of what each portion controls. If that's asking too much perhaps you could point me in the direction of an online lecture that explains it in more detail. Like I said in my original post I am a SLOW learner. I will give myself a little credit though. Once I successfully wrap my head around a skill that interests me, I usually get pretty good at doing it. Within the first week of class the professor was actually kind of mad at me because I wasn't understanding any of the material or things he was saying. By the end he was impressed by how much I progressed. There was even a point where he wanted us to use certain lines of code to check multiple inputs and determine what would happen to them accordingly. I told him his code was more complicated than it needed to be. He said we could write our own it just needed approval. I wrote up a simplified version that did the exact same thing, easier to read, used less lines, and wasn't particularly resource demanding. He approved it when I showed him but of course if you read it it would fall under the same misconduct as the rest of the things I've exampled so I won't bother.

 

9 hours ago, Nuluvius said:

Though I do appreciate that you are simply trying to get something to just work so that you can learn in this case.

I'm sorry. I'm not exactly the spitting image of "normal". Quite often I learn new things "The hard way.". Which is by doing them wrong first (But it just works as you pointed out). Getting yelled at by teachers, professors, & colleagues THEN getting or doing it right by example. I have a rather short attention span. I want to know things but often lack the patience to learn them. It's really annoying. Listening to a teacher for a couple of hours is really the worst possible way to teach me. I've learned the best way for me to learn is hands on and through trial and error. Is it the most efficient way to learn? No, but I haven't found a better way for me. As you've been giving me guidance I've been adding pieces to my C# code for a Volts, Watts, Amps converter. Using basic math any two values can create the third. I could add power factor or power efficiency down the line but for now I'd like to leave it like this.

 

9 hours ago, Nuluvius said:

Put simply, you wouldn't, not in my example at least. I'm not doing your homework for you ^_^ My purpose is to furnish you with the tools and appreciation that you need in order to accomplish that yourself and I expect for you to meet me at least halfway.

You got me to laugh a little, feel like I'm in high school again. Yes. I don't expect you to throw all of the answers at me. Nobody learns that way I struggle the way I do because I have to try harder than most others to learn something. As I said I learn the hard way. That is because in doing so SOME of it I do get right. The teacher then helps fill in what I didn't understand. For now what you showed me was just over my head. I'm on level 1 of C# and you showed me level 5 (I have no basis to say that's a real measurement of the difficulty. It is simply my expression of my level of understanding. What I feel like I'm looking at.) I know I can understand it all someday...just not today.

9 hours ago, Nuluvius said:

the 'input box' should be capable of providing this kind of filtering.

With some searching you believe Visual Studios should have some sort of properties option to control the input range? I know it has a character limit. Such as 8 would means no more than 8 characters can be entered.

Link to comment
Share on other sites

Link to post
Share on other sites

6 hours ago, Windows7ge said:

So if I'm testing an input against a condition in an if statement if the condition is true I should end the if statement as quickly as possible. If further lines need executing I should move them elsewhere and tell the if statement where to find them?

If you're checking against preconditions such as if some string is empty or whether it conforms to some expected structure then those would be classed as Guard Clauses and therefore should usually come first. Exiting/terminating is done to reduce nesting thus decreasing the Cyclomatic Complexity (I mentioned this earlier); nesting is bad, it makes things hard to read and understand.

 

Moreover you really don't want to the execution flow to be jumping around all over the place. If the input has passed these sort of checks then fine, go ahead with whatever real work needs to be carried out on it. It's like a you're building a filter of sorts and then dropping something into it and watching as it falls through - it may get diverted somewhere else or thrown away completely as it descends.

6 hours ago, Windows7ge said:

Is it OK for me to insert the syntax for this inside of a private void? This would make it so that it executes only when the button (for my circumstance it is a button) is pressed? Or does this have to be setup outside the private void and referenced (called? Is the action I think.) each time I want

Perhaps you should just do the simplest possible thing for now and not worry so much. Just get it working for you in whatever way feels easiest. That's a good core principle to follow in fact; do the simplest possible thing to achieve a result and then refactor it later.

6 hours ago, Windows7ge said:

I'm actually quite grateful you're putting forth the effort to help some stranger on the internet with no real expectation of compensation (that you've made me aware of anyways).

It's often what's not said that can be the most important part of a dialog ^_^

 

I'm teasing of course xD

6 hours ago, Windows7ge said:

For now what you showed me was just over my head. I'm on level 1 of C# and you showed me level 5 (I have no basis to say that's a real measurement of the difficulty. It is simply my expression of my level of understanding. What I feel like I'm looking at.) I know I can understand it all someday...just not today.

I can appreciate where you're at a bit better now and I'm sorry for leaping ahead.

6 hours ago, Windows7ge said:

I could really use is a detailed breakdown of what each portion controls.

I've added some comments:

// Just an example template application; this is a Console Application
class Program
{
  // You identified a thing: Range, so I pulled it out and made it a real thing; a class that can be instantiated
  class Range
  {
    // These are properties that are publically visible on the class
    public int Minimum { get; set; }

    public int Maximum { get; set; }
	
    // This is a public function that encapsulates the ‘is something in range’ logic - this implementation detail belongs to our Range
    public bool ContainsValue(int value)
    {
      return value >= Minimum && value <= Maximum;
    }
  }
  
  // This is just an example of how to instantiate our Ranges (this is initialization syntax); these could come from a file or be hard coded
  private static readonly List<Range> Ranges = new List<Range>
  {
    new Range { Minimum = 0, Maximum = 10 },
    new Range { Minimum = 60, Maximum = 70 }
  };

  // This is part of this particular application template: the Main is the entry point for a Console Application
  static void Main(string[] args)
  {
    // We are sending some different arguments to this procedure
    ProcessSomeNumber(100);
    ProcessSomeNumber(5);

    // This is simply going to make the console wait instead of closing automatically
    Console.ReadKey();
  }

  // This is an example procedure with a single parameter
  private static void ProcessSomeNumber(int someNumber)
  {
    // Our first Guard Clause which makes use of a function
    if (!IsInRange(someNumber))
    {
      return;
    }
	
    // This simply outputs a message to the console using string interpolation, we may imagine that it represents some meaningful work
    Console.WriteLine($"Do something with {someNumber}");
  }

  // A function that encapsulates the logic to check if a value is within any of our Ranges (in our list)
  private static bool IsInRange(int someNumber)
  {
    // We are using LINQ to iterate over those Range objects calling their 'ContainsValue' function
    return Ranges.Any(r => r.ContainsValue(someNumber));
  }
}

You can of course accomplish the whole thing procedurally... I don't usually get a great deal of free time during the week (or the weekends for that matter). But I'll do my best to try to further simplify if needed - maybe some of the others may like to take care of that though...

6 hours ago, Windows7ge said:

perhaps you could point me in the direction of an online lecture that explains it in more detail

I find that Pluralsight is quite good in terms of C# and also more general Software Engineering concepts; they do have a fantastic compendium of Design Patterns.

6 hours ago, Windows7ge said:

Like I said in my original post I am a SLOW learner. I will give myself a little credit though. Once I successfully wrap my head around a skill that interests me, I usually get pretty good at doing it.

6 hours ago, Windows7ge said:

m sorry. I'm not exactly the spitting image of "normal". Quite often I learn new things "The hard way.". Which is by doing them wrong first (But it just works as you pointed out). Getting yelled at by teachers, professors, & colleagues THEN getting or doing it right by example. I have a rather short attention span. I want to know things but often lack the patience to learn them. It's really annoying. Listening to a teacher for a couple of hours is really the worst possible way to teach me. I've learned the best way for me to learn is hands on and through trial and error. Is it the most efficient way to learn? No, but I haven't found a better way for me.

I wouldn't be inclined to worry too much, we all learn and react differently, there's really no normal. Don't let the reactions of others bother you, life is far too short to be pissed away for the sake of other people. I'm both dyslexic and dyscalculic and if I'd have listened to the people that I have met along the course of my journey then I certainly wouldn't be where I am today.

 

Here's an example: It's taken me several hours to type out this reply and quite a few edits beyond that until I was somewhat content with it... Another example: I'm absolutely inept when it comes to mathematics as I cannot retain or make any sense of numbers (logic is fine, no issues there). In other words I'm literally crippled in this area :$

 

I've been through all kinds of hell in my life in and around these issues but guess what, they all went away once I was out in the real world with my bit of paper. They are artifacts of a broken system and a draconian mentality.

6 hours ago, Windows7ge said:

He approved it when I showed him but of course if you read it it would fall under the same misconduct as the rest of the things I've exampled so I won't bother.

I won't bite ^_^

6 hours ago, Windows7ge said:

With some searching you believe Visual Studios should have some sort of properties option to control the input range? I know it has a character limit. Such as 8 would means no more than 8 characters can be entered.

I honestly don't know what technology set you are working with... If it's WinForms (which is deprecating) then there are specific methodologies which are different to the likes of WPF and various flavours of web based implementations. Visual Studio is just an IDE and it is more or less completely agnostic to what you are working in.

The single biggest problem in communication is the illusion that it has taken place.

Link to comment
Share on other sites

Link to post
Share on other sites

7 hours ago, Nuluvius said:

nesting is bad, it makes things hard to read and understand.

When I was learning VB I was finding the code very complicated to read when he had us nesting if statements for tasks such as number sorting. It most definitely increased the cyclomatic complexity.

7 hours ago, Nuluvius said:

do the simplest possible thing to achieve a result and then refactor it later.

So try to get the core of the program working for now and worry about the finer details (input error checking) later. Got it.

8 hours ago, Nuluvius said:

I can appreciate where you're at a bit better now and I'm sorry for leaping ahead.

It's OK. I did understand some of it. So I'm on my way there.

 

class Program // Comparing this to my code I assumed it meant the name of the application "class whateverILabledTheApplicationAs"
{
  
  class Range // I made an assumption that with the following code it was something I could refference from anywhere inside the form (Public) and that "class Range" (I assume Range can be called anything I want) is something outside any private void. Perhaps I could even put it inside a Module file to share it between forms? 
  {
    // Public as in everything in the application can see or use it. int as in Integer (That is a guess). Minimum & Maximum are variables that I COULD label as anything but for simplicity reasons are labeled as such. At this point I think they still need to be assigned a value? {get; set; } Not sure what they're doing. Probably have something to do with actually assigning the value.
    public int Minimum { get; set; }

    public int Maximum { get; set; }
	
    // OK so it's publically viewable, bool as in boolean so True/False, "ContainsValue()" Is that something I would insert into the private void button to send the execution to this page? And int (integer), value is a user assigned name to represent the input which is either a string, integer, or string converted to integer (In VB it would be written "CInt(value)" to convert a string to an integer but it could only be done when the value was being used to modify something)
    public bool ContainsValue(int value)
    {
      return value >= Minimum && value <= Maximum; //Tests the value against the min/max requirements. The bool true/false determines if it passes/fails
    }
  }
  
  // So in the event I only wanted to keep track of one set of min/max values...
  private static readonly List<Range> Ranges = new List<Range>
  {
    new Range { Minimum = 0, Maximum = 10 }, // I could just write the one line and set the value such as new Range { Minimum = 0, Maximum = 100 }
    new Range { Minimum = 60, Maximum = 70 } // If I wanted to use more than 1 Range, how would I tell the code which set to use? Range 0 - 60 or range 10 - 70 for different input fields?
  };

  // So this is an intermediary between our application and values we want to test?
  static void Main(string[] args)
  {
    // "ProcessSomeNumber()" sends the data into the procedure? Are the example numbers 100, 5 replacable with variables that represent the user input?
    ProcessSomeNumber(100);
    ProcessSomeNumber(5);

    // I take it that without this, data would go into the procedure but we wouldn't be able to get an answer back out?
    Console.ReadKey();
  }

  // Once the variable is assigned a value I would I insert the "ProcessSomeNumber(int someNumber)" into the private void button to test the number against the range? Also could this be put inside a module to keep the mainForm clean?
  private static void ProcessSomeNumber(int someNumber)
  {
    // What does the ! do? I saw this once before for a bool
    if (!IsInRange(someNumber))
    {
      return;
    }
	
    // So this just kind of lets us know that it worked. Otherwise we could replace this with the next If to test another condition or continue with the execution of the program?
    Console.WriteLine($"Do something with {someNumber}");
  }

  // I was wondering where "IsInRange" came from. I didn't see it at the beginning so I didn't know how the program would recognize it.
  private static bool IsInRange(int someNumber)
  {
    // This is how we are looking at the min max values to compare to our input number?
    return Ranges.Any(r => r.ContainsValue(someNumber));
  }
}

 

9 hours ago, Nuluvius said:

I don't usually get a great deal of free time during the week (or the weekends for that matter). But I'll do my best to try to further simplify if needed - maybe some of the others may like to take care of that though...

I do like to value more than one persons opinion on something at a time. It's easy for people to develop a bias towards one thing as oppose to other options so I find if multiple people can find common ground on the same topic then it is probably the best option for the application. If your free time is limited you don't have to spend it on me. I will most likely spend time browsing the web finding my own way to learn C# but someone to tell me when I'm using something that's bad practice is definitely something I would like from time to time at least. You and the 3~4 others on the thread have given me plenty of starting material to try and figure things out on my own. When I manage to write a small functioning application I may send you a message with the source code because your passion for doing things the right way is of great value to me. I also like things to be done the right way. Though I might say I go about it differently and what I excel at has nothing to do with programming.

 

9 hours ago, Nuluvius said:

It's taken me several hours to type out this reply

Jeeze...if I can help it I'll try to shorten my replies so it's no so much work.

9 hours ago, Nuluvius said:

I've been through all kinds of hell in my life in and around these issues but guess what, they all went away once I was out in the real world with my bit of paper. They are artifacts of a broken system and a draconian mentality.

I'm glad I'm not the only one with a steep learning curve and a dislike towards the way the world chooses to operate.

 

9 hours ago, Nuluvius said:

I won't bite ^_^

I'm going to hold you to that. I do not have a copy of the exact code he wanted us to use because I didn't understand it. However it used things such as, ByRef, ByVal, Returns, flags, we were suppose to put it in a module and call it when needed. All of that just to test multiple cells in a 1D array for a match. I didn't understand ByRef, ByVal (I still don't) or flags but I almost instantly came up with a simpler design that did the exact same thing with things that I did understand:

Private Sub
Dim varInput as String
Dim varName as String(10) 'I may have spelt this wrong, I haven't made an array in a while
Dim varIndex as Integer
Dim varMatch as Boolean
Dim varNoMatch as Boolean

Do
    If varInput = varName(varIndex) then
        varMatch = True
        
    Else
        varIndex += 1
        If varIndex = 10 then
            varNoMatch = True
        End If
    End If
Loop Until varMatch = True Or varNoMatch = True
    If varMatch = True Then
        [Output to form]
        
    ElseIf varNoMatch = True
        [Output to form]
        
    End If
    
    varIndex = 0
    
    End If
End Sub

This was much easier for me to understand and still allowed the program to react differently dependent on weather the final outcome was true or false. To be honest the professor knew my major was unrelated to programming. If it was he might have been more strict as to weather or not he would accept it.

 

10 hours ago, Nuluvius said:

I honestly don't know what technology set you are working with... If it's WinForms (which is deprecating) then there are specific methodologies which are different to the likes of WPF and various flavours of web based implementations. Visual Studio is just an IDE and it is more or less completely agnostic to what you are working in.

I'll see what I can find. I do like exploring legacy equipment and software. I have FreeDOS installed on a thumb drive and I use it from time to time. Though I've had times where it was the only thing that could fix a given situation. I needed to update a server motherboards BIOS. There was no Flash BIOS option in the BIOS. I needed DOS. There was a time I needed to flash the Firmware on a 8 port 6Gb/s RAID controller to a HBA so I could use FreeNAS software RAID. There wasn't a windows program I could locate to do it. I had to use DOS. I had a time where a 16GB thumb drive of mine managed to format itself in the FAT file system, not FAT32, not FAT16 but FAT and it only recognized something like 8 or 16MB of storage. Nothing I used could recover it, not even strait CMD but DOS came to the rescue and got it back. So I believe some legacy things are worth learning. Not all of them though.

Link to comment
Share on other sites

Link to post
Share on other sites

// Comparing this to my code I assumed it meant the name of the application "class whateverILabledTheApplicationAs"

Not really, it's just a class. It can be called whatever you like.

// I made an assumption that with the following code it was something I could refference from anywhere inside the form (Public) and that "class Range" (I assume Range can be called anything I want) is something outside any private void. Perhaps I could even put it inside a Module file to share it between forms?

More or less. I think that I'm beginning to suspect that you may have holes in your fundamental knowledge. I'll try to give you material as we work through your points. Relevant for this particular point would likely be Classes, Accessibility Levels and Access Modifiers.

// Public as in everything in the application can see or use it. int as in Integer (That is a guess). Minimum & Maximum are variables that I COULD label as anything but for simplicity reasons are labeled as such. At this point I think they still need to be assigned a value? {get; set; } Not sure what they're doing. Probably have something to do with actually assigning the value.

See Properties and Built-In Types.

// OK so it's publically viewable, bool as in boolean so True/False, "ContainsValue()" Is that something I would insert into the private void button to send the execution to this page? And int (integer), value is a user assigned name to represent the input which is either a string, integer, or string converted to integer (In VB it would be written "CInt(value)" to convert a string to an integer but it could only be done when the value was being used to modify something)

See Methods.

// I could just write the one line and set the value such as new Range { Minimum = 0, Maximum = 100 }

Correct.

// If I wanted to use more than 1 Range, how would I tell the code which set to use? Range 0 - 60 or range 10 - 70 for different input fields?

If you need to be selective about that then this is more of a design concern. One immediate solution could be to use a dictionary instead of a list.

// So this is an intermediary between our application and values we want to test?

Not sure what you mean by 'intermediary'. It is the main entry point for that particular type of application.

// "ProcessSomeNumber()" sends the data into the procedure? Are the example numbers 100, 5 replacable with variables that represent the user input?

Correct.

// I take it that without this, data would go into the procedure but we wouldn't be able to get an answer back out?

That is only there to keep the console window from closing immediately. Go ahead and remove it and note what happens when you run the application.

// Once the variable is assigned a value I would I insert the "ProcessSomeNumber(int someNumber)" into the private void button to test the number against the range? Also could this be put inside a module to keep the mainForm clean?

I think that you may be starting to get the idea.

// What does the ! do? I saw this once before for a bool

See Operators.

// So this just kind of lets us know that it worked. Otherwise we could replace this with the next If to test another condition or continue with the execution of the program?

Correct it's just a placeholder/example.

// This is how we are looking at the min max values to compare to our input number?

Essentially yes. As I said this is LINQ and more specifically Enumerable.Any. LINQ provides us access to the functional paradigm.

13 hours ago, Windows7ge said:

I didn't understand ByRef, ByVal (I still don't)

See Passing Arguments by Value and by Reference (Visual Basic)Passing Parameters (C# Programming Guide)Passing Value-Type Parameters (C# Programming Guide) and Passing Reference-Type Parameters (C# Programming Guide)

13 hours ago, Windows7ge said:

...or flags

Flags can be just another term for Booleans.

The single biggest problem in communication is the illusion that it has taken place.

Link to comment
Share on other sites

Link to post
Share on other sites

6 hours ago, Nuluvius said:

I think that I'm beginning to suspect that you may have holes in your fundamental knowledge.

Yes. Very very much. Near the beginning of this thread I mentioned in a post that my understanding of programming is like someone who knows how to build a computer but doesn't know what any of the components are called. I have the ability to take pieces of code and use them like puzzle pieces to fit an application, however when it comes to what they're called ie. (modifiers, parameters, arguments, constants, procedures, and many many more) then I have no idea. I entered the VB class not understanding all of these words or able to write any applications and I left still not understanding the words but I could write basic applications.

 

6 hours ago, Nuluvius said:

Not sure what you mean by 'intermediary'.

If my question is wrong then it's not important. I've seen instances in programming where one particular section of code could not directly communicate with another but it needed to. So an intermediary was made so they could talk. (A middle man, or proxy if you rather.

 

6 hours ago, Nuluvius said:

That is only there to keep the console window from closing immediately. Go ahead and remove it and note what happens when you run the application.

Unfortunately in my efforts to understand and test what you've shown me I've failed to incorporate it successfully so I cannot run the application to see what happens. I'll explain later.

 

6 hours ago, Nuluvius said:

Flags can be just another term for Booleans.

Oh. Makes sense. If C# doesn't use flags then I suppose it may not matter anymore.

 

I'm going to go through and use your links to try and increase my understanding. In the meantime using your help and my own research I came up with the following. Minus the Range portion of the code I was able to test that the program will test if the field is empty, test if it's a number or not, then it'll perform the math and output the result. So the program works. I'm just missing the range. I want to make sure I'm not using anything from the internet that would be considered bad practice.

class inputRange
        {
            public int minimum { get; set; }
            public int maximum { get; set; }

            public bool userInput(int value)
            {
                return value >= minimum && value <= maximum;
            }
        }

        private static readonly List<inputRange> inputRanges = new List<inputRange>
        {
            new inputRange { minimum = 0, maximum = 10000}
        };

        private void btnCalculate1_Click(object sender, EventArgs e)
        {
            string watts, amps;
            int number;

            watts = txtWatts1.Text;
            amps = txtAmps1.Text;

            if (string.IsNullOrEmpty(watts))
            {
                MessageBox.Show("The Watts field is empty.");
                txtWatts1.Focus();
            }

            else
            {
                bool result = Int32.TryParse(watts, out number);

                if (!result)
                {
                    MessageBox.Show("Input for Watts contained a non-numeric character.");
                    txtWatts1.Clear();
                    txtWatts1.Focus();

                }

                else
                {
                   
                    // Checking the Range needs to go here

                    int a = Convert.ToInt32(watts); // a = watts
                    int b = Convert.ToInt32(amps); // b = amps

                    lblOutputVolts.Text = (a / b).ToString(); // Solve the problem, convert to string, and output to form
                }
            }
        }

        private void btnClear1_Click(object sender, EventArgs e)
        {
            // Clear all fields
            txtWatts1.Clear();
            txtAmps1.Clear();
            lblOutputVolts.Text = string.Empty;
        }

 

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, Windows7ge said:

If my question is wrong then it's not important. I've seen instances in programming where one particular section of code could not directly communicate with another but it needed to. So an intermediary was made so they could talk. (A middle man, or proxy if you rather.

I understand and that was indeed not what was happening with that particular part.

1 hour ago, Windows7ge said:

Oh. Makes sense. If C# doesn't use flags then I suppose it may not matter anymore.

It's more so another name for a Boolean type; nothing specific to any particular language implementation - an overarching term if you will.

1 hour ago, Windows7ge said:

I want to make sure I'm not using anything from the internet that would be considered bad practice.

There are a number of improvements that I could suggest. Firstly, as a general point, you should have a look at Implicitly Typed Local Variables. You do not need to (and should not) be explicitly declaring the type of your local variables. It's not necessary and is considered bad practice in a purist sense. That said however, a certain amount of subjectivity does reside within the industry about this statement. In general one should always attempt to be consistent to the style of a given code base, despite how much that may hurt at times.

string watts, amps;
int number;

There's no real need to do this and it's therefore considered bad form.

if (string.IsNullOrEmpty(watts))
{
  MessageBox.Show("The Watts field is empty.");
  txtWatts1.Focus();
}

else
{
  bool result = Int32.TryParse(watts, out number);
  ...

There's no need for the first check. The parse will either succeed or it will not, irrespective of what's actually in the string.

bool result = Int32.TryParse(watts, out number);

if (!result)
{
  ...

Why are you using a separate variable for the result of this function call? You should evaluate it directly.

 

If you are able to put those points into practice then I'd imagine that you'd likely see a decent reduction in the amount of nesting that you have going on.

The single biggest problem in communication is the illusion that it has taken place.

Link to comment
Share on other sites

Link to post
Share on other sites

6 hours ago, Nuluvius said:

There's no real need to do this and it's therefore considered bad form.

Am I able to test the user inputs without putting them into memory and assigning them a name? I know instead of creating a space in memory (string, int), assigning a name (watts, amps, numbers), then assigning a value to them from the user input (watts = txtWatts1.Text) I think I could skip all of that and just directly compare the form object (txtWatts.Text) against the conditions (if (string.IsNullOrEmpty(txtWatts1.Text))) but I was told that isn't something I should do (VB class).

6 hours ago, Nuluvius said:

There's no need for the first check. The parse will either succeed or it will not, irrespective of what's actually in the string.

I actually understand what you mean perfectly :). However my reasoning is because I like to use specific error messages (messagebox.show("What the user did wrong")). I could get rid of the first condition but that would then merge the "Is it empty?" condition with the "Is it a number?" condition. I would then have to make the messagebox message universal. So the user wouldn't know what they did wrong. They would just know that they did something wrong. I like being detail oriented.

6 hours ago, Nuluvius said:

Why are you using a separate variable for the result of this function call? You should evaluate it directly.

The example listed down the page here: Int32.TryParse Method (String, Int32) displayed it done as such for an if statement which was my intended application. With the exception of the !. I put that in there because instead of the if statement reading true if the result is false it would read true if the result is true.

 

I'm still reading through your provided links. I'll have to take another shot at incorporating the range code you provided into my program using the notes you gave me answering some of my questions. I can also look into getting rid of the variables but I don't know if the program will be happy working directly with the forms input fields. (We were taught that that was something we shouldn't do. That we should assign the objects on the form a variable and use the variable in the code to represent the objects value. Ex: textbox1.text has an input of "3". Create a string variable: string variable;, assign the string variable to the textbox (variable = textbox1.text) then have the variable represent the textbox input so not to address the testbox directly in the execution such as adding the number to something) If I should do it some other way let me know.

Link to comment
Share on other sites

Link to post
Share on other sites

12 hours ago, Windows7ge said:

Am I able to test the user inputs without putting them into memory and assigning them a name?

You are if it makes sense to do so. 

12 hours ago, Windows7ge said:

They would just know that they did something wrong. I like being detail oriented.

As I said before, this is a concern that should really live at the View level. You need to design your View in such a way that the user can only enter a valid numerical input (if that's what you want). The code that then has to deal with this input can therefore be simplified a great deal. There are control that only permit numerical input and there are also validation methodologies.

12 hours ago, Windows7ge said:

I put that in there because instead of the if statement reading true if the result is false it would read true if the result is true.

You still don't need an extra variable. Simply just negate the function result. You may even be able to use an Inline Declaration.

12 hours ago, Windows7ge said:

I can also look into getting rid of the variables but I don't know if the program will be happy working directly with the forms input fields.

That wasn't the point I was trying to get across and indeed it would be wrong to try to work with whatever properties directly in this context.

 

I was meaning that you should combine the declaration and the assignment of your variables. In your code you had declared variables without any assignments thus they would have been initialized to their default values. There's no good reason, in this case, to do that.

The single biggest problem in communication is the illusion that it has taken place.

Link to comment
Share on other sites

Link to post
Share on other sites

14 hours ago, Nuluvius said:

You are if it makes sense to do so. 

To test if the field contains a number it makes sense. I'm not sure if I can also directly test the field when testing for the range.

14 hours ago, Nuluvius said:

You need to design your View in such a way that the user can only enter a valid numerical input (if that's what you want).

For this application that is what I want. While researching the Range to see if VS had a properties option for it I came across a person who said they set the field so only a number could be entered. I don't know if they were using VS but if they could do it at all I imagine it should be possible for me. That would strip the requirement for one of the If's and reduce the nesting by a fair margin.

14 hours ago, Nuluvius said:

You still don't need an extra variable. Simply just negate the function result.

(After looking at the InLine Declaration) OH! You mean I don't need a separate bool to test the input using TryParse() I can test the result directly inside the If statement. I can also have the resulting int output variable inside the same line which would get rid of the int variable at the top of the private void.

 

One problem. The latest version of C# I have is C# 6. That is a feature of C# 7. I'm not certain how to update the language package.

 

EDIT: Nevermind. I just uninstalled VS 2015 & installed VS 2017. It supports C# 7 and now "out int Variable" works or at least it's recognized. Haven't tried to compile the application with it yet.

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, Windows7ge said:

While researching the Range to see if VS had a properties option for it I came across a person who said they set the field so only a number could be entered. I don't know if they were using VS but if they could do it at all I imagine it should be possible for me. That would strip the requirement for one of the If's and reduce the nesting by a fair margin.

As I said before, Visual Studio is simply an IDE, it's mostly independent of what technology you're working in. I'm going to make an assumption that it's WinForms in which case you could use a MaskedTextBox or a NumericUpDown.

1 hour ago, Windows7ge said:

The latest version of C# I have is C# 6. That is a feature of C# 7. I'm not certain how to update the language package.

What version of Visual Studio are you using? See the compatibility matrix here and get the latest for free here.

The single biggest problem in communication is the illusion that it has taken place.

Link to comment
Share on other sites

Link to post
Share on other sites

4 hours ago, Nuluvius said:

I'm going to make an assumption that it's WinForms in which case you could use a MaskedTextBox or a NumericUpDown.

It is WinForms. I feel against using a numericUpDown object because I'm not looking for a user input between 1 & 10 which would be fine with up & down arrows but I'm looking for a user input anywhere between 0.001 & 9999.999. However I've never used a MaskedTextBox and sure enough it's an option in the toolbox. Pulling it out almost immediately I saw a mask properties option that gives me 9 default input filters including only allowing numerical inputs. Now it's only kind of visually displeasing because it uses a place holder to represent what the user can input. So if I set 0000.000 to represent what range the user can use. Running the application the user sees ____.___ without typing anything. Maybe there's an option to make it blank until the user inputs something but it does achieve the objective. I cannot input anything but numbers so I can get rid of some of the error checking.

 

I just discovered some good news and bad news. The masked input box also allows me to limit the number of input characters. Meaning it is impossible for the user to input anything higher than 9999.999. The bad news is it actually eliminates the necessity to check the Range as you've been teaching me the past couple of days...so...no input error checking required at least for this specific application. Still I should learn these things. This isn't an excuse not to.

4 hours ago, Nuluvius said:

What version of Visual Studio are you using? See the compatibility matrix here and get the latest for free here.

It was VS 2015. Only officially supports C# 6 and lower. I just downloaded and installed version 2017. Now I can use C# 7

Link to comment
Share on other sites

Link to post
Share on other sites

4 minutes ago, Windows7ge said:

The bad news is it actually eliminates the necessity to check the Range as you've been teaching me the past couple of days...so...no input error checking required at least for this specific application.

That's not really bad new if I understand you correctly; it's just further simplified your business logic has it not? As long as one is trying to do things properly and actually cares about what they are doing then there's really no such thing as wasted effort when writing software.

8 minutes ago, Windows7ge said:

Now I can use C# 7

That's great xD

The single biggest problem in communication is the illusion that it has taken place.

Link to comment
Share on other sites

Link to post
Share on other sites

4 hours ago, Nuluvius said:

That's not really bad new if I understand you correctly; it's just further simplified your business logic has it not? As long as one is trying to do things properly and actually cares about what they are doing then there's really no such thing as wasted effort when writing software.

The reason I say it's bad is because it could be viewed as an excuse to not have to learn something. As you presumed a while ago (and were correct) I have gaps in my fundamental knowledge. The last thing I need is an excuse to not have to learn something. On the good side of things it has simplified it. When coding in VB most of the code that made up my applications were just preventing user input errors. (That's generally how small my applications are.) Even though error checking has now taken care of itself there's still the matter of actually doing the math. Allow me to rewrite the code inside the private void and I'll get back to you with a functioning revised version...provided I don't hit a wall and can't find an answer on my own...

Link to comment
Share on other sites

Link to post
Share on other sites

@Nuluvius

I made a mistake. The masked textbox object although it does allow the use of decimal numbers it doesn't work well for my application. Also even if no numbers have been entered using TryParse in an If statement it thinks numbers are there and the application crashes when it tries to compute an empty string as a result.

 

I've now switched over to using numericUpDown. This lets me, control the range, use decimal numbers, make it so only numbers can be entered & doesn't let a field remain blank which makes it so the user cannot make an input error in any way...cool.

 

So now it's just a matter of verifying the math and clearing fields.

 

This is what I have now. My plan is to repeat this code two more times for the other two buttons except for object names and altering between division and multiplication because the other conversions use different math:

        private void btnCalculate1_Click(object sender, EventArgs e)
        {
            {
                decimal watts = Convert.ToDecimal(nudWatts1.Value); // watts = nudWatts1.Value
                decimal amps = Convert.ToDecimal(nudAmps1.Value); // amps = nudAmps1.Value

                lblOutputVolts.Text = (watts / amps).ToString(); // Solve the problem, convert to string, and output to form
            }
        }

        private void btnClear1_Click(object sender, EventArgs e)
        {
            // Clear all fields
            nudWatts1.Value = 0.001m;
            nudAmps1.Value = 0.001m;
            lblOutputVolts.Text = string.Empty;
        }

 

Link to comment
Share on other sites

Link to post
Share on other sites

6 hours ago, Windows7ge said:

So now it's just a matter of verifying the math and clearing fields.

That's great :D And your code looks so much more clean and concise now, quite aesthetically pleasing don't you think.

6 hours ago, Windows7ge said:

My plan is to repeat this code two more times for the other two buttons except for object names and altering between division and multiplication because the other conversions use different math

Instead of essentially copy pasting you should extract the logic out and put it into it's own method. That way you can simply call it from multiple places without violating the Don't Repeat Yourself (DRY) principal; you'll be staying dry xD

private void btnCalculate1_Click(object sender, EventArgs e)
{
  {
...
  }
}

What's going on with this nesting?

decimal watts = Convert.ToDecimal(nudWatts1.Value); // watts = nudWatts1.Value

Remember Implicitly Typed Local Variables - unless you've actually made the decision not to...

nudWatts1.Value = 0.001m;
nudAmps1.Value = 0.001m;

Remember that magic values are considered bad practice. Consider refactoring these out into constants. Consider the next line for example:

lblOutputVolts.Text = string.Empty;

Not only does it encapsulate the narrative of what is going on but it also consolidates the implementation of what an empty string really is... Now consider the unlikely scenario that what constituted an empty string actually changed... That it became some value or token instead. One would be left trying to find and replace all of the literals instead of making the change in just one single place.

lblOutputVolts.Text = "";

Not that great and is the same sort of thing as the decimal literal.

// Clear all fields

Overuse of comments is considered a bad code smell and is indicative of a bad design. Commenting the obvious, as is the case here, is just unnecessary; your code tells its own narrative well enough. In other words one can easily see that some kind of reset is occurring thus the comment is redundant. Remember always strive to keep things as simple as possible, always ask yourself the questions:

  1. What does it really mean?
  2. What am I really trying to do here?
  3. What is the simplest possible thing that I can do?

The single biggest problem in communication is the illusion that it has taken place.

Link to comment
Share on other sites

Link to post
Share on other sites

6 hours ago, Nuluvius said:

That's great :D And your code looks so much more clean and concise now, quite aesthetically pleasing don't you think.

Easier to read and potentially less work for the system.

 

6 hours ago, Nuluvius said:

Instead of essentially copy pasting you should extract the logic out and put it into it's own method. That way you can simply call it from multiple places without violating the Don't Repeat Yourself (DRY) principal; you'll be staying dry xD

Well, if I went this route I would have to assign variables to each inputbox, I would have to assign a variable to weather it's multiplication or division and then I'd have to tie it into the button.

 

Id have to turn the private void buttons into public voids, assign the needed values to the equation in its own public void, run it, then pull the answer back out. It would definitely be DRY but there would be a lot of strings and I think it would become more complicated. Perhaps there's a simpler way of doing it as oppose to my explanation? Or should I attempt this on my own and show you the results?

 

6 hours ago, Nuluvius said:

What's going on with this nesting?

That was a typo. During all the If statement testing, object property testing, trying different things, and etc...in the clean up process it seams I missed a pair of curly braces. Kind of like picking up garbage off the floor but you missed a piece.

 

7 hours ago, Nuluvius said:

Remember Implicitly Typed Local Variables - unless you've actually made the decision not to...

Did you have me read that once before? I might have not gotten to it yet. I'll read it now. (5 minutes later) Is it possible to not specify the variable type and still have the program function correctly? The lecture doesn't quite explain my use case. (or it does and I just don't understand the wording) Examples:

// How I inturpreted the lecture:
var watts = Convert.ToDecimal(nudWatts1.Value);
// or is it able to do the full conversion for me?
var watts = nudWatts.Value;
// Maybe I should test this and find out for myself?

 

7 hours ago, Nuluvius said:

Not only does it encapsulate the narrative of what is going on but it also consolidates the implementation of what an empty string really is... Now consider the unlikely scenario that what constituted an empty string actually changed... That it became some value or token instead. One would be left trying to find and replace all of the literals instead of making the change in just one single place.

 

Not that great and is the same sort of thing as the decimal literal.

I'm a little lost here. Are you saying String.Empty is bad? The only other method I know of to clear a field is to replace an input with an empty string. (textbox.Text = "") However you don't seem particularly fond of that either. 

 

7 hours ago, Nuluvius said:

Overuse of comments is considered a bad code

Sorry, another memento of VB class. In a nutshell "comments everywhere, can never have too many."

Link to comment
Share on other sites

Link to post
Share on other sites

3 minutes ago, Windows7ge said:

Well, if I went this route I would have to assign variables to each inputbox, I would have to assign a variable to weather it's multiplication or division and then I'd have to tie it into the button.

 

Id have to turn the private void buttons into public voids, assign the needed values to the equation in its own public void, run it, then pull the answer back out. It would definitely be DRY but there would be a lot of strings and I think it would become more complicated. Perhaps there's a simpler way of doing it as oppose to my explanation? Or should I attempt this on my own and show you the results?

I think that you may be missing the point just a little there. Your conversion is quite a concise peace of functionality, you have two inputs and one single output; an ideal candidate for encapsulation within a discrete function wouldn't you agree? Why don't you have a go and see what you can come up with and we can review.

8 minutes ago, Windows7ge said:

That was a typo. During all the If statement testing, object property testing, trying different things, and etc...in the clean up process it seams I missed a pair of curly braces. Kind of like picking up garbage off the floor but yo

It's a somewhat serendipitous opportunity for you to take note that the compiler has no issue with the extra nesting ;)

14 minutes ago, Windows7ge said:

Is it possible to not specify the variable type and still have the program function correctly?

Yes quite. The type is inferred, try hovering your mouse cursor over the 'var' and you'll see for yourself.

// How I inturpreted the lecture:
var watts = Convert.ToDecimal(nudWatts1.Value);

Indeed.

// or is it able to do the full conversion for me?
var watts = nudWatts.Value;

No, you'll get the type of 'nudWatts.Value'.

// Maybe I should test this and find out for myself?

This is often a good way to learn ;)

20 minutes ago, Windows7ge said:

I'm a little lost here. Are you saying String.Empty is bad? The only other method I know of to clear a field is to replace an input with an empty string. (textbox.Text = "") However you don't seem particularly fond of that either. 

I'm saying that 'String.Empty' is a good example of consolidating a magic literal; it's a constant and it does a great job of describing it's purpose and reason for existing quite nicely. I'm also pointing out that "" as an example would be very bad as it does nothing towards these ends. Moreover it increases complexity because one would have to change all occurrences of it if the concept of an empty string were to change at some point. Whereas with a constant it's only going to be a single place that has to change.

29 minutes ago, Windows7ge said:

Sorry, another memento of VB class. In a nutshell "comments everywhere, can never have too many."

Sounds about right... Thanks academia for deeply ingraining those bad practices into aspirants right from the start 9_9

The single biggest problem in communication is the illusion that it has taken place.

Link to comment
Share on other sites

Link to post
Share on other sites

24 minutes ago, Nuluvius said:

It's a somewhat serendipitous opportunity for you to take note that the compiler has no issue with the extra nesting ;)

The fact that you pointed it out, the more I think about it the more interesting I find that fact it didn't complain. Nevertheless I got rid of the extra curly braces.

 

35 minutes ago, Nuluvius said:

I'm saying that 'String.Empty' is a good example of consolidating a magic literal; it's a constant and it does a great job of describing it's purpose and reason for existing quite nicely. I'm also pointing out that "" as an example would be very bad as it does nothing towards these ends. Moreover it increases complexity because one would have to change all occurrences of it if the concept of an empty string were to change at some point. Whereas with a constant it's only going to be a single place that has to change.

You mentioned earlier that the use of magic values isn't considered good. I used it to reset the value property of the input boxes because without it it threw the error "Literal of type double cannot be implicitly converted to type 'decimal'; use an 'M' suffix to create a literal of this type". Alternatively I think it is possible to do the following:

// Instead of:
nudVolts2.Value = 0.001m;
nudAmps2.Value = 0.001m;

// Use the minimum property to reset the value
nudVolts2.Value = nudVolts2.Minimum;
nudAmps2.Value = nudAmps2.Minimum;

// I think I tried this once before and there were some minor issues. I can try it again if it's more appropriate.

 

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, Windows7ge said:

You mentioned earlier that the use of magic values isn't considered good. I used it to reset the value property of the input boxes because without it it threw the error "Literal of type double cannot be implicitly converted to type 'decimal'; use an 'M' suffix to create a literal of this type". Alternatively I think it is possible to do the following:


// Instead of:
nudVolts2.Value = 0.001m;
nudAmps2.Value = 0.001m;

// Use the minimum property to reset the value
nudVolts2.Value = nudVolts2.Minimum;
nudAmps2.Value = nudAmps2.Minimum;

// I think I tried this once before and there were some minor issues. I can try it again if it's more appropriate.

 

The problem there may be apparent to you if you look at the decimal type, specifically note its range. Now think about which constant you are using.

 

Why not try this:

const decimal SomeDecimal = 0.01m;

 

The single biggest problem in communication is the illusion that it has taken place.

Link to comment
Share on other sites

Link to post
Share on other sites

 

29 minutes ago, Nuluvius said:

The problem there may be apparent to you if you look at the decimal type, specifically note its range. Now think about which constant you are using.

I think I'm understanding this a little. The issue is I'm attempting to use a fraction that is outside of the range of the decimal type?

 

Also constants. I haven't really learned much about them but from what you've told me plus your example code I'm starting to think that a constant is used when you have a variable of which its value is set to never change. Or rather you never plan to have its value change so you make it constant...I think...

 

Your example code only measures down to the hundreds place but my application requires accuracy down to the thousands. Comparing your code to mine I don't see any reason I cannot add an additional 0 to reach my requirements (0.001m;)

 

To use your example code I'm thinking it would be written:

private void btnClear1_Click(object sender, EventArgs e)
        {
            const decimal defaltValue = 0.001m;
  
            nudWatts1.Value = defaltValue;
            nudAmps1.Value = defaltValue;
            lblOutputVolts.Text = string.Empty;
        }

If this is more or less correct I'm wondering if (const decimal defaltValue = 0.001m;) would be better of in the form_load void so that the constant gets loaded into RAM when the form loads rather than every single time the user presses the clear button which sounds undesirable.

Link to comment
Share on other sites

Link to post
Share on other sites

3 minutes ago, Windows7ge said:

The issue is I'm attempting to use a fraction that is outside of the range of the decimal type?

The decimal type can go negative by a significant amount. It's what is known as a signed type - you may have had undesirable results because 'MinValue' will essentially be the lowest value of a decimals range and not 0. You'd likely get a compiler/intellisense error however if you had attempted to assign a value outside of the range of the type.

 

Specifically though:

2 hours ago, Windows7ge said:

I used it to reset the value property of the input boxes because without it it threw the error "Literal of type double cannot be implicitly converted to type 'decimal'; use an 'M' suffix to create a literal of this type".

Perhaps have a look at C# Literal Suffixes. I think that you were trying to assign a double to a decimal type.

17 minutes ago, Windows7ge said:

I haven't really learned much about them but from what you've told me plus your example code I'm starting to think that a constant is used when you have a variable of which its value is set to never change. Or rather you never plan to have its value change so you make it constant...I think...

Yes indeed, that's a rather good way of putting it; 'a constant is used when you have a variable of which its value is set to never change. Or rather you never plan to have its value change'. Make sure that it's name means something and that it helps to tell the story of your code, so that you can avoid comments and give yourself and others an easier time later on!

21 minutes ago, Windows7ge said:

Your example code only measures down to the hundreds place but my application requires accuracy down to the thousands. Comparing your code to mine I don't see any reason I cannot add an additional 0 to reach my requirements (0.001m;)

Of course, whatever I do is only ever going to be a vague example, to aid you in getting the job done yourself. Moreover, remember that I told you that numbers mean very little to me - I'm effectively blind to them.

19 minutes ago, Windows7ge said:

If this is more or less correct I'm wondering if (const decimal defaltValue = 0.001m;) would be better of in the form_load void so that the constant gets loaded into RAM when the form loads rather than every single time the user presses the clear button which sounds undesirable.

You don't really have to worry so much about that since the compiler will do it's magic to make things like this more efficient. But honestly if it were me then if it made sense to do so I'd probably define it at the class level scope and make it private of course.

The single biggest problem in communication is the illusion that it has taken place.

Link to comment
Share on other sites

Link to post
Share on other sites

17 minutes ago, Nuluvius said:

Perhaps have a look at C# Literal Suffixes. I think that you were trying to assign a double to a decimal type.

The only thing that makes any sense to me is that somehow the program interprets the value property of the numericUpDown as a double so when I attempt to assign a decimal the system doesn't know how to convert it. If I'm understanding it correctly. Also yes that is what the error i was given was essentially saying I'm to assume using M to specify it is a decimal somehow allows the interpreter to recognize what it is I'm trying to do with it and assign it.

 

23 minutes ago, Nuluvius said:

Of course, whatever I do is only ever going to be a vague example, to aid you in getting the job done yourself. Moreover, remember that I told you that numbers mean very little to me - I'm effectively blind to them.

That's right you told me about that. Sorry. It's just that with programming I've learned if something isn't word for word or letter for letter with what you want to do it likely won't work when you apply your own touches to it.

 

On another note you've provided me with a lot of information today. I'm going to try and use all of it then I'll show you how it went.

Link to comment
Share on other sites

Link to post
Share on other sites

5 minutes ago, Windows7ge said:

The only thing that makes any sense to me is that somehow the program interprets the value property of the numericUpDown as a double

If you're ever in doubt then review the documentation: NumericUpDown.Value.

The single biggest problem in communication is the illusion that it has taken place.

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


×