Thursday, July 26, 2012

Faith explained.

This the perfect explanation for my stance on religion.  Keep in mind, however, that my issues with fools that try to shove their religion down your throat is something far more complex!

Note that this image was submitted through Reddit.com (http://www.reddit.com/r/atheism/comments/kvpbc/evidence_vs_belief_a_tale_of_two_bunnies/) and no original author is listed for credit, even via Google image search).  Credit to whoever made it...I am not creative enough to do so ;-)



Wednesday, June 27, 2012

SharePoint 2010 - Workflow Woes

Solution
Disabled all workflow-related Features in the site collection.
Run the Products and Technologies Wizard.
Re-enable all workflow-related Features in the site collection.
Fixed...

Problem
Workflows are showing "Failed on Start" message.

Details:
  • SharePoint Server 2010 Enterprise.  
  • All Site Collections are within the same Web Application (HTTPS, Claims-enabled).
  • Only one Site Collection is affected, and all sub-sites within that collection are affected.
  • All workflows are "out of the box" (not created with SharePoint Designer 2010). 
  • The Workflow History List shows that on Friday, workflows were OK.  On Monday, they failed.
  • No updates/configuration changes were made that Friday - Monday period, and no power/network outages were reported.

Troubleshooting:
I have created 6 document libraries, one for each of the workflow types within this site collection.  Three of them fail, three of them completed successfully.  I am not certain as to the cause (yet), but I'm working on it.  Searching online has not provided any results yet.  In one case, a post said to turn on Content Approval in Site Collection Features if the Approval workflow was used to control content approval...which I did (after deleting the list and workflow and starting "from scratch").

The error says that it was cancelled by the System Account, which isn't supposed to be handling workflows and event receivers, according to TechNet.  I've no idea how to change this functionality, or even where to change it...all other workflows are fine in this site collection, except for these three!



My Docs (Disposition Workflow):  Completed
My Docs (Three-State Workflow):  Completed
My Docs (Signatures Workflow):  Failed on Start
My Docs (Feedback Workflow):  Failed on Start
My Docs (Approval Workflow):  Failed on Start
My Docs (Publishing Approval Workflow): Completed








The Document Library shows this:


The Workflow History List shows this:

Workflow History List Item Details:

Tuesday, June 12, 2012

Why I Hate Polls and Surveys

I wrote this for a class when I was attending the University of Maryland University College - Asia (whew...can it be any longer?!). The assignment was:

  1. Research the results of any poll or survey in which you disagree with the results.
  2. Describe why you disagree with the results.
  3. Offer a brief explanation of how the survey/poll could have been improved (results, survey base, etc).

"A recent Gallup poll in the United States indicated that around 40% of Americans do not believe that humans evolved from less advanced forms of life. That contrasts to 59% acceptance in Canada, and upwards of 80% in some European countries.", taken from here.

Without getting into the Science vs Religion debate, I can accept these statistics. However, I wanted to look at the survey base to find out how accurate it might be, and this is what I found:

"Results are based on telephone interviews with 1,018 national adults, aged 18 and older, conducted Feb. 6-7, 2009, as part of Gallup Poll Daily tracking. For results based on the total sample of national adults, one can say with 95% confidence that the maximum margin of sampling error is ±3 percentage points."

Really?  1,018 adults surveyed over three days can give a confidence rating of 95% that the margin of error is only "'±3 percentage points."?  If I could skew data to show only what I want to show, then I'll just start referring to Gallup for my references from now on!

Here is what I find wrong with this poll:
  1. They don't list what city the poll was taken in, which DOES matter.
We are talking about the opinion of 1,018 individuals being taken as a reflection of the whole of the United States of America. Because of this, the city that was polled is critical to the data represented.  What if the poll was taken in New York, New York? What if it was taken in Montgomery, Alabama? 

If the city lies in the "Bible Belt", the results are skewed in favor of the Biblical representation of the origin and growth of our species.

 If it is taken in a city with a "healthy" amount of non-religious citizens, it may be skewed in favor of the Darwinian representation.

And if the results are taken in cities where the religious community (of mixed religions, not just Christian religions) and the non-religious community are well-balanced, the results are closer to what they SHOULD be, in order to adequately reflect the opinion of an entire nation based on a miniscule percentage of citizens in a specific city.

But it doesn't state this. We don't know if they polled one city, or a number of cities. They don't give us that information, which is ridiculous! "1,018 national adults" surveyed over a period of three days cannot adequately reflect the opinion of the nation as a whole.  How is this small subset of people, each with their own religious or scientific bias, supposed to constitute "40% of Americans"?

According to the Wolfram Alpha Computational Search Engine, the United States population between ages 18-64 in 2009 was 189.3 million people (189,300,000). 1,018 adults out of 189.3 million adults = 0.000537770734284205 % of the 189.3 million adults. Round up a bit to the nearest millionth for an "easy" 0.000538 %.  That is the percentage of the US population that they surveyed. So I think it's safe to say that we can throw their results into the trash.

What should have been included in the survey was the pool of adults in the city that was polled.  1,018 adults out of how many in the city?  This would give a reference for comparison, a ratio, for comparing it to what the average national opinion might be.  Get the ratio of the people who were surveyed (say, 1018 out of 10,180, which is 1/10th), and use that for the basis of stating what the "National Average" is.  1/10th of the adult population in 2009 is 18,930,000.  Grab that percentage and it would result in a more reliable answer.

I may as well survey a married couple, and say that their opinions reflect that of the entire city. If one is religious and one is not, then "50% of the American populace in Okinawa does not believe in evolution". Or take it a step further, and survey ten families (10 men, 10 women). Assume that it comes out 80% in favor of creationism. Can I then go on to say that "80% of the American populace in all of Asia (China, Korea, Japan, Taiwan, etc) does not believe in evolution"? I could, but my statistical results may very well be wrong.

This is the "Age of the Internet". We do everything online: shopping, socializing, and even find entertainment via a staggering amount of venues. Why are polls limited to such a small number of people taken as the opinion for the nation as a whole? Why not put the survey online, and gather data in this way?

There is always a fear of invalid data (the same person taking the survey multiple times, or a person who enters information as a joke), but invalid data can be given in a face-to-face survey and telephone-surveys as well, so there will always be a certain amount of data which is invalid based on those situations. Surveys and polls which are used to define the opinion of a large mass of people are already hard to retrieve data for, and I understand this. But with a survey that included data from such a miniscule subset of the population, with the location of the survey being undisclosed, lends credence to my opinion that the survey itself is nothing more than a joke.

Thursday, May 17, 2012

8086 Assembly (TASM): "Toy" Program

I thought I'd post this here, just in case I end up losing it and needing it later on.  Or whatever...

This was the assignment given:


Write a program to emulate a child's toy which is played by dropping a marble in one of the three holes ( A, B, or C ) at the top of the toy and watching the changes.  As the marble moves past switches, the values of the switch are changed.   The path which the marble will take is dependent upon the current state of the switch.  Your game display should look something like the following: the letters should be displayed, the numbers representing the switch positions, and the value of each switch which is initially a 0:



                   A                           B                           C
                   1                           2                           3
                   0                           0                           0
                                4                           5
                                0                           0
                   6                           7                           8
                   0                           0                           0


          Treat the toy as a multi-switch device with each switch having two states and being independent of each other.   Each switch's input and output are defined as follows:

          INPUT :
                   hole A :  the marble goes to Switch 1
                   hole B :  the marble goes to Switch 2
                   hole C :  the marble goes to Switch 3
          OUTPUT:
                   When Switch 1 is 0, the marble goes to Switch 6
                   When Switch 1 is 1, the marble goes to Switch 4
                   When Switch 2 is 0, the marble goes to Switch 5
                   When Switch 2 is 1, the marble goes to Switch 4
                   When Switch 3 is 0, the marble goes to Switch 5
                   When Switch 3 is 1, the marble goes to Switch 8
                   When Switch 4 is 0, the marble goes to Switch 7
                   When Switch 4 is 1, the marble goes to Switch 6
                   When Switch 5 is 0, the marble goes to Switch 8
                   When Switch 5 is 1, the marble goes to Switch 7
                   When Switch 6 is 0, the marble exits the Toy
                   When Switch 6 is 1, the marble exits the Toy
                   When Switch 7 is 0, the marble exits the Toy
                   When Switch 7 is 1, the marble exits the Toy
                   When Switch 8 is 0, the marble exits the Toy
                   When Switch 8 is 1, the marble exits the Toy

          The Toy starts with a display of the board having all switches set to 0.

          Accept the input from the keyboard (provide an appropriate prompt)  of A, B, or C which is the selection of the hole into which to drop the marble.  Calculate the state changes of the switches, change them, and then re-display the board in its new state. Continue until the proper exit code is provided.  You must idiot proof your program to ignore improper values.  Use of procedures and Macros as appropriate is required.
And here's the garbage that I regurgitated into Notepad!

; Toy.asm
; 
;    What the array looks like when not crammed onto one line.
;    a[0,0] is the array element at position [0,0].  and so on.
;    Essentially, there are 3 rows, just like the assignment description:
;        1st Row has 3 columns.
;        2nd Row has 2 columns.
;        3rd Row has 3 Columns. 
;        +--------+--------+--------+
;        | a[0,0] | a[0,1] | a[0,2] |
;        | OFF 0  | OFF 1  | OFF 2  |
;        +--------+--------+--------+
;          | a[1,0] | a[1,1] | 
;           | OFF 3  | OFF 4  | 
;        +--------+--------+--------+
;        | a[2,0] | a[2,1] | a[2,2] |
;        | OFF 6  | OFF 7  | OFF 8  |
;        +--------+--------+--------+

.MODEL small

.STACK 100h

.DATA
  ; 1FH = ON
  ; 7FH = OFF
  PRMPT1  DB 10, 10, 13, '[q] Or [Q] To Quit'
     DB 10, 10, 13, '[A], [B], [C] To Drop Ball: $'

  HEADER  DB 10, 10, 13, '          ', 41H, '          ', 42H, '          ', 43H, '$'                 ; A  B  C     
  
  LINE1A  DB 10, 10, 13, '          $'
  LINE1B  DB '          $'
  LINE1C  DB '          $'

  LINE2A  DB 10, 10, 13, '               $'
  LINE2B  DB '          $'

  LINE3A  DB 10, 10, 13, '          $'
  LINE3B  DB '          $'
  LINE3C  DB '          $'
  
  SWITCHES DB 1FH, 1FH, 1FH
     DB 1FH, 1FH
     DB 1FH, 1FH, 1FH
  
.CODE

 START PROC
   MOV AX, @DATA   ; Startup code.
   MOV DS, AX

  DRAWGAME:
    CALL CLRSCRN   ; Clear the screen
  
    MOV DX, OFFSET HEADER  ; Display menu
    MOV AH, 09H
    INT 21H

    MOV DX, OFFSET LINE1A  ; Draw Row 1, Col A
    MOV AH, 09H
    INT 21H

      MOV DL, SWITCHES + 0 ; Display switch 1 value.
      MOV AH, 02h             
      INT 21H                     
    
    MOV DX, OFFSET LINE1B  ; Draw Row 1, Col B
    MOV AH, 09H
    INT 21H

      MOV DL, SWITCHES + 1 ; Display switch 2 value.
      MOV AH, 02h             
      INT 21H                   
    
    MOV DX, OFFSET LINE1C  ; Draw Row 1, Col C
    MOV AH, 09H
    INT 21H    
    
      MOV DL, SWITCHES + 2 ; Display switch 3 value.
      MOV AH, 02h         
      INT 21H                 
    
    MOV DX, OFFSET LINE2A  ; Draw Row 2, Col B
    MOV AH, 09H
    INT 21H

      MOV DL, SWITCHES + 3  ; Display switch 4 value.
      MOV AH, 02h             
      INT 21H                 
    
    MOV DX, OFFSET LINE2B  ; Draw Row 2, Col C
    MOV AH, 09H
    INT 21H

      MOV DL, SWITCHES + 4  ; Display switch 5 value.
      MOV AH, 02h             
      INT 21H                 
       
    MOV DX, OFFSET LINE3A  ; Draw Row 3, Col A
    MOV AH, 09H
    INT 21H

      MOV DL, SWITCHES + 5  ; Display switch 6 value.
      MOV AH, 02h             
      INT 21H                 
    
    MOV DX, OFFSET LINE3B  ; Draw Row 3, Col B
    MOV AH, 09H
    INT 21H

      MOV DL, SWITCHES + 6  ; Display switch 7 value.
      MOV AH, 02h             
      INT 21H                 
    
    MOV DX, OFFSET LINE3C  ; Draw Row 3, Col C
    MOV AH, 09H
    INT 21H 

      MOV DL, SWITCHES + 7  ; Display switch 8 value.
      MOV AH, 02h             
      INT 21H                     

    MOV DX, OFFSET PRMPT1  ; Display menu
    MOV AH, 09H
    INT 21H 
   
  GETINPUT:
   MOV AX, 0
   MOV AH, 08H    ; Get user input.
   INT 21H
   
   CMP_bA:
    CMP AL, 41H    ; Is input = "A"?
    JNE CMP_sA    ; If not, check for "a".
    JMP SWITCH1    ;  If it is, Jump to Switch #1.
    
   CMP_sA:      
    CMP AL, 61H    ; Is input = "a"?
    JNE CMP_bB    ; If not, check for "B".
    JMP SWITCH1    ; If it is, jump to Swtich #1.
    
   CMP_bB:
    CMP AL, 42H    ; Is input = "B"?
    JNE CMP_sB    ; If not, check for "b".
    JMP SWITCH2    ; If it is, jump to Switch #2.
    
   CMP_sB:
    CMP AL, 62H    ; Is input = "b"?
    JNE CMP_bC    ; If not, check for "C".
    JMP SWITCH2    ; If it is, jump to Switch #2.
    
   CMP_bC:
    CMP AL, 43H    ; Is input = "C"?
    JNE CMP_sC    ; If not, check for "c".
    JMP SWITCH3    ; If it is, jump to Swtich #3.
    
   CMP_sC:
    CMP AL, 63H    ; Is input = "c"?
    JNE CMP_bQ    ; If not, check for "Q".
    JMP SWITCH3    ; If it is, jump to Switch #3.
    
   CMP_bQ:
    CMP AL, 51H    ; Is input = "Q"?
    JNE CMP_sQ    ; If not, check for "q".
    JMP EXITPROG   ; If it is, jump to EXITPROG.
    
   CMP_sQ:
    CMP AL, 71H    ; Is input = "q"?
    JNE GETINPUT   ; If it is not, then user did not enter any of the above keys.
    JMP EXITPROG   ; If it is, jump to EXITPROG.
   
  SWITCH1:  
   CMP [SWITCHES + 0], 7FH   ; if character in switch 1 is 7FH
   JE SWITCH1A
   
   CMP [SWITCHES + 0], 1FH   ; if character in switch 1 is 1FH.
   JE SWITCH1B   
   
   SWITCH1B:
    MOV [SWITCHES + 0], 7FH     ; switch character to OFF
    JMP SWITCH4

   SWITCH1A:
    MOV [SWITCHES + 0], 1FH    ; switch character to ON
    JMP SWITCH6
    
  SWITCH2:
   CMP [SWITCHES + 1], 7FH   ; if character in switch 2 is 7FH
   JE SWITCH2A
   
   CMP [SWITCHES + 1], 1FH   ; if character in switch 2 is 1FH.
   JE SWITCH2B   
   
   SWITCH2B:
    MOV [SWITCHES + 1], 7FH  ; switch character to OFF
    JMP SWITCH2

   SWITCH2A:
    MOV [SWITCHES + 1], 1FH  ; switch character to ON
    JMP SWITCH5
 
  SWITCH3:
   CMP [SWITCHES + 2], 7FH   ; if character in switch 3 is 7FH
   JE SWITCH3A
   
   CMP [SWITCHES + 2], 1FH   ; if character in switch 3 is 1FH.
   JE SWITCH3B   
   
   SWITCH3B:
    MOV [SWITCHES + 2], 7FH  ; switch character to OFF
    JMP SWITCH8

   SWITCH3A:
    MOV [SWITCHES + 2], 1FH  ; switch character to ON
    JMP SWITCH5
   
  SWITCH4:
   ; Code for Switch #4 goes here.
   CMP [SWITCHES + 3], 7FH   ; if character in switch 4 is 7FH
   JE SWITCH4A
   
   CMP [SWITCHES + 3], 1FH   ; if character in switch 4 is 1FH.
   JE SWITCH4B   
   
   SWITCH4B:
    MOV [SWITCHES + 3], 7FH  ; switch character to OFF
    JMP SWITCH6

   SWITCH4A:
    MOV [SWITCHES + 3], 1FH  ; switch character to ON
    JMP SWITCH7
   
  SWITCH5:
   CMP [SWITCHES + 4], 7FH   ; if character in switch 5 is 7FH
   JE SWITCH5A
   
   CMP [SWITCHES + 4], 1FH   ; if character in switch 5 is 1FH.
   JE SWITCH5B   
   
   SWITCH5B:
    MOV [SWITCHES + 4], 7FH  ; switch character to OFF
    JMP SWITCH7

   SWITCH5A:
    MOV [SWITCHES + 4], 1FH  ; switch character to ON
    JMP SWITCH8
   
  SWITCH6:
   CMP [SWITCHES + 5], 7FH   ; if character in switch 6 is 7FH
   JE SWITCH6A
   
   CMP [SWITCHES + 5], 1FH   ; if character in switch 6 is 1FH.
   JE SWITCH6B   
   
   SWITCH6B:
    MOV [SWITCHES + 5], 7FH  ; switch character to OFF
    JMP DRAWGAME

   SWITCH6A:
    MOV [SWITCHES + 5], 1FH  ; switch character to ON
    JMP DRAWGAME
   
  SWITCH7:
   CMP [SWITCHES + 6], 7FH   ; if character in switch 7 is 7FH
   JE SWITCH7A
   
   CMP [SWITCHES + 6], 1FH   ; if character in switch 7 is 1FH.
   JE SWITCH7B   
   
   SWITCH7B:
    MOV [SWITCHES + 6], 7FH  ; switch character to OFF
    JMP DRAWGAME

   SWITCH7A:
    MOV [SWITCHES + 6], 1FH  ; switch character to ON
    JMP DRAWGAME
   
  SWITCH8:
   CMP [SWITCHES + 7], 7FH   ; if character in switch 8 is 7FH
   JE SWITCH8A
   
   CMP [SWITCHES + 7], 1FH   ; if character in switch 8 is 1FH.
   JE SWITCH8B   
   
   SWITCH8B:
    MOV [SWITCHES + 7], 7FH  ; switch character to OFF
    JMP DRAWGAME

   SWITCH8A:
    MOV [SWITCHES + 7], 1FH  ; switch character to ON
    JMP DRAWGAME
    
  EXITPROG:
   CALL CLRSCRN
   
   MOV AL, 0    ; exit to DOS.
   MOV AH, 04ch
   INT 21h
 START ENDP

 CLRSCRN PROC
   MOV AH, 0fh
   INT 10h
   
   MOV AL, 00h
   MOV AH, 0
   INT 10h 
   
   RET
 CLRSCRN ENDP 
END START   

PowerShell: Searching For Installed Patches/Updates

I had the need to search for the installation of specific patches on one of my servers recently. This isn't really a big deal...just type "appwiz.cpl" into the Run window and click "View Installed Updates" or take the dangerous journey through the control panel to find the same thing)...

However, even in Windows Server 2008, there is no option to sort this list by KB article (patch name). So what to do?

Hello, PowerShell! Nice to meet you again!



$KB = Read-Host "Enter KB Number (EX: KB2604094, with or without KB): "

 If ($KB.StartsWith("KB", "CurrentCultureIgnoreCase"))
  { $KB = $KB.Substring(2) }
 
 $Result = Get-HotFix | Where {$_.HotFixID -like "*$KB*"} | Select Description, HotFixID, InstalledBy, InstalledOn | Format-List
 
 If ($Result.Count -gt 0) { $Result }
 Else { Write-Host "KB Not Found!" }


Just enter any part of the HotFix ID that want. Here is the output. It's messy, but it gets the job done.


Sunday, May 6, 2012

Final Exam Finished

Well, I paid the price for watching a movie, chatting with the kids, playing a video game (Mass Effect 3, heh), and eating dinner....

all while taking my final exam for CIS 217.

So, I made a few mistakes, mostly not noticing when a question says "Show me which of these is incorrect", and I pick the "correct" answer, thus getting the question wrong. I do it all the time...and it's too late to stop doing it now, I guess!

Anyway, I wanted to let everyone know that there ARE errors in the Final Exam. I've sent Grace a list of the ones that I got wrong that I KNOW to be correct (which I verified with code shortly after submitting the exam). I would have sent the list to everyone, but I'm not going to get hammered for giving out exam answers ;-)

But if you got something wrong and got a bad grade, don't stress over it if you know the answer was right. She'll update it if you let her know.

Cheers!

Final Project Completed

I've finished the final project.  I can see why some of my classmates had trouble with it.  I don't know if passing data between Form objects is covered in the book or not...I stopped reading at around Chapter 3, other than to get the details for weekly assignments.

If anyone got stuck, here is the code for the project...so you can at least see how it is done (or rather, how I implemented it).

Here is the class in Form1 (frmMain in my project). Be sure to add a using statement for System.IO in order to get StreamReader/StreamWriter operational.
public partial class frmMain : Form
    {
        public string[] pbEntries = new string[5];
        public List People = new List();

        public frmMain()
        {
            InitializeComponent();
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            ReadTextFile();
            AddToListBox();
        }

        public void ReadTextFile()
        {

            int index = 0;                                                          // Index used in loops.
            StreamReader inputFile;                                                 // Declare StreamReader.
            inputFile = File.OpenText("myPhoneBook.txt");                           // Open file and get SR obj.

            while (index < pbEntries.Length && !inputFile.EndOfStream)
            {
                pbEntries[index] = inputFile.ReadLine();                            // Read contents of myPhoneBook.txt, store in pbEntries String array.
                index++;
            }
            
            for (int count = 0; count < pbEntries.Length; count++)
            {
                ConvertToObject(pbEntries[count]);                                  // Read each item in the String array 
            }
            inputFile.Close();                                                      // Close the file.
        }

        public string ConvertToObject(string dataLine)
        {
            string[] pInfo = dataLine.Split(',');                                   // Split entry for each person into sub-entries in the pInfo String array.
            PersonEntry Person = new PersonEntry(pInfo[0], pInfo[1], pInfo[2]);     // New instance of PersonEntry, pass name, email, and phone fields.
            People.Add(Person);                                                     // Add new Person object to People<> List.
            return null;
        }

        public void AddToListBox()
        {
            for (int count = 0; count != People.Count; count++)
            {
                lbPhoneBook.Items.Add(People[count].Name);                          // Durrr...obvious.
            }
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void lbPhoneBook_SelectedIndexChanged(object sender, EventArgs e)
        {
            frmSub Form = new frmSub(People[lbPhoneBook.SelectedIndex]);            // Overload new frmSub, passed PersonEntry object in People<>
            Form.ShowDialog();                                                      //  ...with SelectedIndex of lbPhoneBook.
        }   // No idea why it's throwing these  tags here...that's not part of my project code, it's something to do with the code coloring script.

And here is the code for the second form's code.
public frmSub(PersonEntry thisPerson)
        {
            InitializeComponent();
            lblName.Text = thisPerson.Name;
            lblEmail.Text = thisPerson.Email;
            lblPhone.Text = thisPerson.Phone;
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            this.Hide();
        }

And the required PersonEntry class for the project itself:

public class PersonEntry
    {
        // Fields
        private string _Name;
        private string _Email;
        private string _Phone;

        // Constructor
        public PersonEntry(string Name, string Email, string Phone)
        {
            _Name = Name;
            _Email = Email;
            _Phone = Phone;
        }

        // Name property
        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }

        // Email property
        public string Email
        {
            get { return _Email; }
            set { _Email = value; }
        }

        // Phone property
        public string Phone
        {
            get { return _Phone; }
            set { _Phone = value; }
        }
    }

Wednesday, May 2, 2012

8086 Assembly: ASCII/Decimal to Hex conversion

Well, I finally finished the assignment I was given in my 8086 Assembly class to convert from an ASCII character to it's Hex value, or from 5 decimal values to Hex.  If option #1 in the menu is chosen, you can enter more than 5 numbers and hit 'Enter', but it will error out.  It's only supposed to take 5.  Anyone learning Assembly on their own...here ya go:

; Conversion program
; Write a menu-driven program which accepts a 1, 2, or 3 as input.
;    1) Accept a decimal value (up to 5 digits), and print its hex value
;    2) Accept a character, and print its ascii value in hex. (convert to base 10)
;    3) Quit program.

    .MODEL SMALL

    .STACK 100h

    .DATA
        Menu    DB    10, 13, 'Enter a choice (1, 2, or 3):'
                DB    10, 13, '1) Convert 1 to 5 Decimal values to Hex'
                DB    10, 13, '2) Convert ASCII to Hex'
                DB    10, 13, '3) Quit Program', 10, 13, '$'        
        MenuErr    DB    10, 13, 'Choice must be a 1, 2, or 3!'
                DB    10, 13, 'Try again!', 10, 13, '$'
        AskDec    DB    10, 13, 'Enter a number with 1 to 5 digits: ', 10, 13, '$'        
        AskChar DB    10, 13, 'Enter any character: ', 10, 13, '$'

    .CODE

        START    PROC
                MOV AX, @DATA                ; Startup code
                MOV DS, AX

            dispMenu:
                MOV DX, OFFSET Menu            ; Display menu
                MOV AH, 09H
                INT 21H

                MOV AH, 01H                    ; Get keyboard input
                INT 21H

                CMP AL, '1'                    
                JL dispErr

                CMP AL, '3'                    
                JG dispErr

                CMP AL, '1'                    
                JE goDec
                
                
                CMP AL, '2'                    
                JE goChar
                
                
                CMP AL, '3'                    
                JE goQuit

            dispErr:
                MOV DX, OFFSET MenuErr        ; Display menu error.
                MOV AH, 09H
                INT 21H
                JMP dispMenu                

            goDec:    
                CALL DEC2HEX                ; Call DEC2HEX procedure.
                JMP dispMenu

            goChar:
                CALL CHAR2HEX                ; Call CHAR2HEX procedure.
                JMP dispMenu

            goQuit:                            

                MOV AL, 0                    ; Exit program.
                MOV AH, 4CH
                INT 21H    

        START ENDP

        DEC2HEX PROC                        ; *** Accept a decimal value (up to 5 digits) > print it's hex value.
       
                MOV DX, OFFSET AskDec
                MOV AH, 09H
                INT 21H
           
                MOV AX, 0                     ; Clear AX
                PUSH AX                        ; Save AX to stack (else overwritten when 0Dh is pressed)       

            Again:
                
                MOV AH, 01H                    ; Get keyboard input
                INT 21H
                                    
                CMP AL, 0Dh                    ; If Return is entered, start division.
                JE SDiv1
               
                CMP AL, '0'                    
                JL Again
               
                CMP AL, '9'                    
                JG Again
                            
                MOV AH, 0                    ; Change to a digit.
                SUB AL, 30h                    
                MOV CX, AX                    ; Save digit in CX
                   pop ax

                MOV BX, 10                    ; Division by 10.
                MUL BX                        
               
                ADD AX, CX                    ; Add CX (original number) to AX (number after multiplication).
                PUSH AX                        ; Save on stack.
                JMP Again                    ; Repeat.

            SDiv1:

                mov cx, 0
                MOV BX, 16             
                pop ax
               
            Div1:                            

                DIV BX                      ; Divide (Word-sized).
                PUSH DX                     ; Save remainder.
                   
                ADD CX, 1                   ; Add one to counter   
                MOV DX, 0                   ; Clear Remainder (DX)
                CMP AX, 0                   ; Compare Quotient (AX) to zero
                JNE Div1                      ; If AX not 0, go to "Div1:"
               
            getHex:                            ; Get hex number.
                MOV DX, 0                    ; Clear DX.
                POP DX                        ; Put top of stack into DX.
                ADD DL, 30h                    ; Conv to character.

                CMP DL, 39h                    ; If DL > 39h (character 9)...
                JG MoreHex

            HexRet:                            ; Display hex number
                MOV AH, 02h                    ; 02h to display DL

                INT 21H                        ; Send to DOS
               
                LOOP getHex                 ; LOOP subtracts 1 from CX. If non-zero, loop.   
                JMP Skip
            MoreHex:                        ; Add 7h if DL > 39h (10-15)
                ADD DL, 7h                    ; Add another 7h to DL to get into the A-F hex range.
                JMP HexRet                    ; Return to where it left off before adding 7h.
            Skip:                            ; Skip addition of 7h if it is not needed.
                RET
        DEC2HEX ENDP
            
        CHAR2HEX PROC                        ; Accept a character, print it's ascii value in hex.
                                    
                MOV DX, OFFSET AskChar        ; Display prompt
                MOV AH, 09H
                INT 21H

                MOV AH, 01H                    ; Get keyboard input w/ no echo (AL)
                INT 21H
            
                MOV CL, AL                    ; Copy user input (AL) to CL
                MOV AX, 0                    ; Clear AX (get rid of HO bits)
                MOV AL, CL                    ; Copy user input back into AL

                MOV BX, 16                    ; Set up the divisor (base 16)
                MOV CX, 0                    ; Initialize the counter
                MOV DX, 0                    ; Clear DX

            Divide:                         
                                            ; Dividend in DX/AX pair, Quotient in AX, Remainder in DX.
                DIV BX                      ; Divide (will be word sized).
                PUSH DX                        ; Save DX (the remainder) to stack.
            
                ADD CX, 1                   ; Add one to counter

                MOV DX, 0                    ; Clear Remainder (DX)
                CMP AX, 0                    ; Compare Quotient (AX) to zero
                JNE Divide                    ; If AX not 0, go to "Divide:"
                
            Divide2:
                MOV DX, 0                    ; Clear DX
                POP DX                        ; Put top of stack into DX
       
                ADD DL, 30h                    ; ADD 30h (2) to DL 

                CMP DL, 39h
                JG HexDigit
    
            HexRet2:
                MOV AH, 02h                    ; 02h to display AH (DL)
                INT 21H                        ; Send to DOS

                LOOP Divide2                ; If more to do, Divide2 again
                                            ; LOOP subtracts 1 from CX. If non-zero, loop.
                JMP SkipHex2
            HexDigit:
                ADD DL, 7h                    ; Convert [10-15] to [A-F]
                JMP HexRet2                    ; Return to where I jumped from to do the ADD
            SkipHex2:
                RET
        CHAR2HEX ENDP
    END START

Sunday, April 22, 2012

New PC.

Well, I've got the new PC built. Here are the specs, for anyone interested:
  • Case: NZXT Switch 810 (Black) 
    • 2x Superbright LED bars (red) 
    • 10x 140mm Enthusiast 3 Speed Fluid Dynamic Bearing Fans (2k RPM) 
    • NZXT Sentry Mix 6 Channel Fan Controller
  • Mobo: Gigabyte GA-Z77X-UD5H LGA 1155 Socket 
  • CPU: Intel Core i5-2550k (Overclocked to 4.3 Ghz from 3.6 Ghz) 
    • Corsair Hydro Series H100 CPU Liquid Cooler 
  • RAM: 16 GB (2x 8GB sticks) Corsair Vengeance DDR3 1600 
  • GPU: Asus Radeon HD 7850 
  • PSU: Corsair AX750 Modular Power Supply (Gold+ Cert'd) 
  • HDD
    • 1x 1TB Seagate Barracuda (Boot drive) 
    • 3x 1TB Seagate Barracuda (RAID 5 array, Intel Z77 Chipset)
I plan to upgrade the boot drive to an SSD eventually, but I'm waiting until the market on pric per gigabyte stabilizes. Right now, 1 GB can range from $1 to $5, depending on manufacturer. It's not a huge issue for me, though.

I mean, boot times have been my largest complaint about PC's since I started using them back in the early 1990s, and while it's gotten better, it still takes a while sometimes. From a hard startup, It's 15 seconds to get the login screen for Windows, which is a LOT better than the 60-90 seconds of the HP Pavilion that just died!

The top of the case has a "fan grill" (for lack of a better term in my brain at the moment) that you can open and close by pulling a lever at the back of the case. Leaving it open means that you have a bit more fan noise, but the case exhausts more heat than if it were closed. Likewise, when closed, the case is pretty silent.

The front two fans (hidden behind a touch-open panel at the front of the case) have an air filter to catch dust and whatnot, and the bottom of the case features a mesh bottom that lets air come in also (which has two mounts for 120mm or 140mm fans, which fit next to the PSU). That bottom mesh area has an air filter for the entire length of the case, 1 accessible from the front and 1 from the back. It's pretty awesome.

Pictures: 

I hate my new phone (Pancrap Breakout). Pictures are crud!

Sunday, April 15, 2012

My Computer Is Dead

[Posting from my phone, so I hope this goes through]

Well, it finally happened.

I was planning my build for a new computer, considering that this one has been acting up for the past 6 months.

The old HP Pavilion It finally died today at about 2PM. Thermal paste, canned air, anti-static wrist strap, and screwdriver ready, I dove in to perform life saving surgery, but unfortunately nothing that I did was the answer.

The motherboard, arguably the heart of the computer (the CPU being the brain, right?) was failing, and so its on-board fan controller wouldn't spin up the system or CPU fans. The Fates decided that it was too late, though. The Laws of Thermodynamics did their job. (I've saved the processor and video card, though!).

I'm throwing the extra cash at next-day shipping so that I can get the new machine built and ready to go before the end of the week (I hope! Hard to do with classes Monday-Thursday, on top of working full time).

I've managed to save the CPU, VGA, and HDD set...so perhaps I'll go buy a cheap case, paint it pink, and grab some cheap components to give my daughter her first computer. She's 6 years old - it's high time she got into fixing computers and learning how everything works!

I'll let it connect to the internet, but will filter that IP so that it can only visit the PBS kids page ;-)


...Who would have thought that the voice-input system on a droid could have typed all this up for me? Pretty awesome!

Monday, April 2, 2012

CIS 217: Enumerated Data Types &, Structures Assignment [Slot Machine Sim]

Another assignment for Chapter 8, the slot machine simulator was a quick and easy project to have some "fun" with. I may pass it off to my wife to see if she has a problem gambling ;-)

Again, my first step was to add an ImageList control ("imglSlots") to the form, set it's ImageSize property to 128 x 128, and add the images that I was going to use. My form looked just as it did in the book, so no change there.

My second step was to create the Enumerated data-type to hold all of the possible fruit choices:
    public enum Fruit { Apple, Banana, Cherries, 
                        Grapes, Lemon, Lime, 
                        Orange, Pear, Strawberry, 
                        Watermelon }

My third step was to create a Spin() method for each slot, called "Slot1_Spin()", which determines what the result is going to be out of the total possible results, and displays the resulting fruit image from the ImageList control. These were created for each slot, and thrown into the _Click event of the "Spin" button:
        public void Slot1_Spin()
        {
            int index = rand.Next(0, 10);         

            switch (index)
            {
                case 0:
                    Slot1Fruit = Fruit.Apple;
                    pbSlot1.Image = imglSlots.Images[index];
                    break;
                case 1:
                    Slot1Fruit = Fruit.Banana;
                    pbSlot1.Image = imglSlots.Images[index];
                    break;
            }
        }

My fourth step, although probably considered even more simple than creating the above methods, was to create the conditionals to deal with winning the game:
                if (Slot1Fruit == Slot2Fruit)
                {
                    Winnings = 2 * AmtEntered;
                    Total += Winnings;
                    MessageBox.Show("You have won 2x the amount entered (" + Winnings.ToString("c") + ")");
                    Win = true;
                }

My thoughts on this section of the chapter are pretty simple: enumerated data types are very important to learn, which I think the examples given in the book plainly show (creating the "days of the week"). Yes, there are other ways to do it, but enums make the process much simpler. The only irksome thing that I've ever had to deal with while using enums is what is also discussed in the book, being that you cannot directly compare some things to the enum itself, but I'm sure that caveat will be addressed later in the book for those who don't know how to get around it.

*Note: Yes, I skimped on the TextBox and getting the bet info from the user, however I wanted to spend time with my wife and children since I haven't seen them much this past week, and so I took shortcuts where I could without impacting the overall running of the program (unless you're blatantly trying to break it).

Here is the full code for the assignment:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SlotMachineSimulation
{
    public enum Fruit { Apple, Banana, Cherries, 
                        Grapes, Lemon, Lime, 
                        Orange, Pear, Strawberry, 
                        Watermelon }
    
    public partial class frmMain : Form
    {
        public Random rand = new Random();
        public Fruit Slot1Fruit, Slot2Fruit, Slot3Fruit;
        public double AmtEntered, Total, Winnings;

        public frmMain()
        {
            InitializeComponent();
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            MessageBox.Show("You won a total of: $" + Total.ToString());
            this.Close();
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            pbSlot1.Image = imglSlots.Images[0];
            pbSlot2.Image = imglSlots.Images[1];
            pbSlot3.Image = imglSlots.Images[2];
        }

        private void btnSpin_Click(object sender, EventArgs e)
        {
            if (txtAmtInserted.Text == "")
            {
                MessageBox.Show("Please place a bet!");
            }
            else
            {
                AmtEntered = double.Parse(txtAmtInserted.Text);
                bool Win = false;

                Slot1_Spin();
                Slot2_Spin();
                Slot3_Spin();

                if (Slot1Fruit == Slot2Fruit)
                {
                    Winnings = 2 * AmtEntered;
                    Total += Winnings;
                    MessageBox.Show("You have won 2x the amount entered (" + Winnings.ToString("c") + ")");
                    Win = true;
                }

                if (Slot2Fruit == Slot3Fruit)
                {
                    Winnings = 2 * AmtEntered;
                    Total += Winnings;
                    MessageBox.Show("You have won 2x the amount entered (" + Winnings.ToString("c") + ")");
                    Win = true;
                }
                if (Slot1Fruit == Slot2Fruit && Slot2Fruit == Slot3Fruit)
                {
                    Winnings = 3 * AmtEntered;
                    Total += Winnings;
                    MessageBox.Show("You have won 3x the amount entered (" + Winnings.ToString("c") + ")");
                    Win = true;
                }
            }
        }


        public void Slot1_Spin()
        {
            int index = rand.Next(0, 10);         

            switch (index)
            {
                case 0:
                    Slot1Fruit = Fruit.Apple;
                    pbSlot1.Image = imglSlots.Images[index];
                    break;
                case 1:
                    Slot1Fruit = Fruit.Banana;
                    pbSlot1.Image = imglSlots.Images[index];
                    break;
                case 2:
                    Slot1Fruit = Fruit.Cherries;
                    pbSlot1.Image = imglSlots.Images[index];
                    break;
                case 3:
                    Slot1Fruit = Fruit.Grapes;
                    pbSlot1.Image = imglSlots.Images[index];
                    break;
                case 4:
                    Slot1Fruit = Fruit.Lemon;
                    pbSlot1.Image = imglSlots.Images[index];
                    break;
                case 5:
                    Slot1Fruit = Fruit.Lime;
                    pbSlot1.Image = imglSlots.Images[index];
                    break;
                case 6:
                    Slot1Fruit = Fruit.Orange;
                    pbSlot1.Image = imglSlots.Images[index];
                    break;
                case 7:
                    Slot1Fruit = Fruit.Pear;
                    pbSlot1.Image = imglSlots.Images[index];
                    break;
                case 8:
                    Slot1Fruit = Fruit.Strawberry;
                    pbSlot1.Image = imglSlots.Images[index];
                    break;
                case 9:
                    Slot1Fruit = Fruit.Watermelon;
                    pbSlot1.Image = imglSlots.Images[index];
                    break;
            }
        }

        public void Slot2_Spin()
        {
            int index = rand.Next(0, 10);

            switch (index)
            {
                case 0:
                    Slot2Fruit = Fruit.Apple;
                    pbSlot2.Image = imglSlots.Images[index];
                    break;
                case 1:
                    Slot2Fruit = Fruit.Banana;
                    pbSlot2.Image = imglSlots.Images[index];
                    break;
                case 2:
                    Slot2Fruit = Fruit.Cherries;
                    pbSlot2.Image = imglSlots.Images[index];
                    break;
                case 3:
                    Slot2Fruit = Fruit.Grapes;
                    pbSlot2.Image = imglSlots.Images[index];
                    break;
                case 4:
                    Slot2Fruit = Fruit.Lemon;
                    pbSlot2.Image = imglSlots.Images[index];
                    break;
                case 5:
                    Slot2Fruit = Fruit.Lime;
                    pbSlot2.Image = imglSlots.Images[index];
                    break;
                case 6:
                    Slot2Fruit = Fruit.Orange;
                    pbSlot2.Image = imglSlots.Images[index];
                    break;
                case 7:
                    Slot2Fruit = Fruit.Pear;
                    pbSlot2.Image = imglSlots.Images[index];
                    break;
                case 8:
                    Slot2Fruit = Fruit.Strawberry;
                    pbSlot2.Image = imglSlots.Images[index];
                    break;
                case 9:
                    Slot2Fruit = Fruit.Watermelon;
                    pbSlot2.Image = imglSlots.Images[index];
                    break;
            }
        }

        public void Slot3_Spin()
        {
            int index = rand.Next(0, 10);

            switch (index)
            {
                case 0:
                    Slot3Fruit = Fruit.Apple;
                    pbSlot3.Image = imglSlots.Images[index];
                    break;
                case 1:
                    Slot3Fruit = Fruit.Banana;
                    pbSlot3.Image = imglSlots.Images[index];
                    break;
                case 2:
                    Slot3Fruit = Fruit.Cherries;
                    pbSlot3.Image = imglSlots.Images[index];
                    break;
                case 3:
                    Slot3Fruit = Fruit.Grapes;
                    pbSlot3.Image = imglSlots.Images[index];
                    break;
                case 4:
                    Slot3Fruit = Fruit.Lemon;
                    pbSlot3.Image = imglSlots.Images[index];
                    break;
                case 5:
                    Slot3Fruit = Fruit.Lime;
                    pbSlot3.Image = imglSlots.Images[index];
                    break;
                case 6:
                    Slot3Fruit = Fruit.Orange;
                    pbSlot3.Image = imglSlots.Images[index];
                    break;
                case 7:
                    Slot3Fruit = Fruit.Pear;
                    pbSlot3.Image = imglSlots.Images[index];
                    break;
                case 8:
                    Slot3Fruit = Fruit.Strawberry;
                    pbSlot3.Image = imglSlots.Images[index];
                    break;
                case 9:
                    Slot3Fruit = Fruit.Watermelon;
                    pbSlot3.Image = imglSlots.Images[index];
                    break;
            }
        }
    }
}

CIS 217: Structures Assignment [Vending Machine Sim]

As the name of the assignment implied, we were directed to create a vending machine simulator. In regards to the design of the form, I went with how the book displayed it.

My first step was to add an ImageList control ("imgListLogos") to the form, set it's ImageSize to 64 x 64, and add the picture collection for each soda's logo. I also added six PictureBox controls, set their BorderStyle to Fixed3D, and named each after the soda that they would represent (pbCola, pbRootBeer, etc).

My second step, creating the event handlers for each PictureBox, was easy since I wasn't going to overload them - double-clicking each control gives it to me.

My third step was to create the Structure to hold the various properties of each soda (it's name, cost, logo, and how many are remaining in the vending machine). As the book dictates, this was done outside of the class, but inside of the project namespace:

public struct Soda
    {
        public string Name;
        public double Cost;
        public int Remaining;
        public int Logo;
    }

I also created the array of the Soda structure for easier maintenance of the data:

public partial class frmMain : Form
    {
        const int arrSIZE = 5;
        public double totalSales = 0.00;
        public Soda[] Sodas = new Soda[arrSIZE];

My third step, after creating the struct Soda, was to create a few methods to create each drink and it's associated data: the cost, number remaining, and the logo for each drink.

The method for creating each Soda structure, with associated properties:
public void CreateDrinks()
        {
            Sodas[0].Name = "Cola";
            Sodas[0].Cost = 1.00;
            Sodas[0].Remaining = 20;
            Sodas[0].Logo = 0;
        }

The method to display the logo, and the cost for each soda:
public void DisplayDrinks()
        {
            pbCola.Image = imglistLogos.Images[0];
            lblColaCost.Text = Sodas[0].Cost.ToString("c");
        }

And two methods to update the remaining number of drinks after a purchase is made:
public void UpdateTotalSales()
        {
            lblTotalSales.Text = totalSales.ToString("c");
        }

        public void UpdateRemaining()
        {
            lblColaRemaining.Text = Sodas[0].Remaining.ToString();
        }

My fourth step was to finally add code to each event handler to deal with the purchasing of each soda. This checks first to see if there are any remaining sodas of that type left. If there are, it will subtract 1 from the current value of .Remaining, update the totalSales with the cost of the soda, and then call the UpdateTotalSales() and UpdateRemaining() methods (which will update the labels associated with each). I did this for each PictureBox, except for the last (the one related to sales and not a particular soda):

private void pbCola_Click(object sender, EventArgs e)
        {
            if (Sodas[0].Remaining > 0)
            {
                Sodas[0].Remaining = Sodas[0].Remaining - 1;
                totalSales = totalSales + Sodas[0].Cost;
                UpdateTotalSales();
                UpdateRemaining();
            }
            else
            {
                MessageBox.Show("I'm Sorry, But That Drink Is Out Of Stock");
            }
        }

Thoughts:
I've done class-based development before in Visual Basic, and I am glad that the author introduces Structures before Classes, as it is a natural progression. However, I do not like how he "left the student hanging" by saying "you can do a lot more, but we're just going to cover the extreme basics". It would have been nice to give a few advanced examples of Struct use, and then re-visit those same examples with Class use, to show the similarities and differences, but oh well. All in all, a good chapter and something that gets closer to the topic that I want to learn about. Finally getting out of the "basics"!

Here is the code for the entire project:

Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace DrinkVendingMachineSim
{
    public struct Soda
    {
        public string Name;
        public double Cost;
        public int Remaining;
        public int Logo;
    }

    public partial class frmMain : Form
    {
        const int arrSIZE = 5;
        public double totalSales = 0.00;
        public Soda[] Sodas = new Soda[arrSIZE];

        public frmMain()
        {
            InitializeComponent();
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            CreateDrinks();
            DisplayDrinks();
            UpdateRemaining();
        }

        public void UpdateTotalSales()
        {
            lblTotalSales.Text = totalSales.ToString("c");
        }

        public void UpdateRemaining()
        {
            lblColaRemaining.Text = Sodas[0].Remaining.ToString();
            lblRBRemaining.Text = Sodas[1].Remaining.ToString();
            lblLLRemaining.Text = Sodas[2].Remaining.ToString();
            lblGSRemaining.Text = Sodas[3].Remaining.ToString();
            lblCSRemaining.Text = Sodas[4].Remaining.ToString();
        }

        public void DisplayDrinks()
        {
            pbCola.Image = imglistLogos.Images[0];
            lblColaCost.Text = Sodas[0].Cost.ToString("c");

            pbRootBeer.Image = imglistLogos.Images[1];
            lblRBCost.Text = Sodas[1].Cost.ToString("c");

            pbLemonLime.Image = imglistLogos.Images[2];
            lbLLCost.Text = Sodas[2].Cost.ToString("c");

            pbGrapeSoda.Image = imglistLogos.Images[3];
            lbGSCost.Text = Sodas[3].Cost.ToString("c");

            pbCreamSoda.Image = imglistLogos.Images[4];
            lbCSCost.Text = Sodas[4].Cost.ToString("c");
        }

        public void CreateDrinks()
        {
            Sodas[0].Name = "Cola";
            Sodas[0].Cost = 1.00;
            Sodas[0].Remaining = 20;
            Sodas[0].Logo = 0;

            Sodas[1].Name = "Root Beer";
            Sodas[1].Cost = 1.00;
            Sodas[1].Remaining = 20;
            Sodas[1].Logo = 1;

            Sodas[2].Name = "Lemon Lime";
            Sodas[2].Cost = 1.00;
            Sodas[2].Remaining = 20;
            Sodas[2].Logo = 2;

            Sodas[3].Name = "Grape Soda";
            Sodas[3].Cost = 1.50;
            Sodas[3].Remaining = 20;
            Sodas[3].Logo = 3;

            Sodas[4].Name = "Cream Soda";
            Sodas[4].Cost = 1.50;
            Sodas[4].Remaining = 20;
            Sodas[4].Logo = 4;
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void pbCola_Click(object sender, EventArgs e)
        {
            if (Sodas[0].Remaining > 0)
            {
                Sodas[0].Remaining = Sodas[0].Remaining - 1;
                totalSales = totalSales + Sodas[0].Cost;
                UpdateTotalSales();
                UpdateRemaining();
            }
            else
            {
                MessageBox.Show("I'm Sorry, But That Drink Is Out Of Stock");
            }
        }

        private void pbRootBeer_Click(object sender, EventArgs e)
        {
            if (Sodas[1].Remaining > 0)
            {
                Sodas[1].Remaining = Sodas[1].Remaining - 1;
                totalSales = totalSales + Sodas[1].Cost;
                UpdateTotalSales();
                UpdateRemaining();
            }
            else
            {
                MessageBox.Show("I'm Sorry, But That Drink Is Out Of Stock");
            }
        }

        private void pbLemonLime_Click(object sender, EventArgs e)
        {
            if (Sodas[2].Remaining > 0)
            {
                Sodas[2].Remaining = Sodas[2].Remaining - 1;
                totalSales = totalSales + Sodas[2].Cost;
                UpdateTotalSales();
                UpdateRemaining();
            }
            else
            {
                MessageBox.Show("I'm Sorry, But That Drink Is Out Of Stock");
            }
        }

        private void pbGrapeSoda_Click(object sender, EventArgs e)
        {
            if (Sodas[3].Remaining > 0)
            {
                Sodas[3].Remaining = Sodas[3].Remaining - 1;
                totalSales = totalSales + Sodas[3].Cost;
                UpdateTotalSales();
                UpdateRemaining();
            }
            else
            {
                MessageBox.Show("I'm Sorry, But That Drink Is Out Of Stock");
            }
        }

        private void pbCreamSoda_Click(object sender, EventArgs e)
        {
            if (Sodas[4].Remaining > 0)
            {
                Sodas[4].Remaining = Sodas[4].Remaining - 1;
                totalSales = totalSales + Sodas[4].Cost;
                UpdateTotalSales();
                UpdateRemaining();
            }
            else
            {
                MessageBox.Show("I'm Sorry, But That Drink Is Out Of Stock");
            }
        }
    }
}

Tuesday, March 27, 2012

CIS 217: Array Assignment [Tic-Tac-Toe] Part 2

I decided to post the code for the project now that I've finished it...but forgot to upload the project to my DropBox account...so I'll type this up from memory until I can post the code tonight after my other classes.

// Creates a 3x3 array.
int boardArray[3, 3]

Which makes an array that looks like this, each dimension of the array corresponding to an "x" or "y" value (like a grid):
[1, 1] [1, 2] [1, 3]
[2, 1] [2, 2] [2, 3]
[3, 1] [3, 2] [3, 3]

And I randomly generated the 0 or 1 result (for X or O) and inserted it into the array at the current spot:
for (int x = 0; x < 9; x++)
{
for (int y = 0; y < 9; y++)
{
boardArray[x,y] = rand.Next();
}
}
So the loop will run like this:
x=1/y=1, x=1/y=2, x=1/y=2
x=2/y=1, x=2/y=2, x=2/y=3
x=3/y=1, x=3/y=2, x=3/y=1

perfectly corresponding to the array.

I goofed on the loop that displayed the results, though, so the board was either all X's or all O's, based on the value stored in boardArray[3, 3]. Oops!

Monday, March 26, 2012

CIS 217: Array Assignment [Name Search]

The name search assignment was cake.
  1. Create a StreamReader object.
  2. Read BoyNames.txt file into memory.
  3. Check to see if it matches the name being searched for by the user.
  4. Display the results.
  5. Do the same for GirlNames.txt.
_Load event of the main form, calls methods to load boy and girl names from text files.
private void frmMain_Load(object sender, EventArgs e)
        {
            LoadBoyNames();
            LoadGirlNames();
        }

LoadBoyNames() loads the names for boys from the file.  Loading the names for girls was the same, obviously...just change the name of the method and file, etc.
public void LoadBoyNames()
        {
            try
            {
                // Index used in loops.
                int index = 0;

                // Declare StreamReader.
                StreamReader inputFile;

                // Open file and get SR obj.
                inputFile = File.OpenText("BoyNames.txt");

                // Read contents of BoyNames.txt
                while (index < boyNames.Length && !inputFile.EndOfStream)
                {
                    boyNames[index] = inputFile.ReadLine();
                    index++;
                }

                // Close the file.
                inputFile.Close();
            }
            catch
            {
            }
        }

SearchNames() method...passes reference to array, determines if current array item is the same as what the user entered (passed by value).
private int SearchNames(string[] sArray, string value)
        {
            bool found = false;
            int index = 0;
            int position = -1;

            // Search the array.
            while (!found && index < sArray.Length)
            {
                if (sArray[index] == value)
                {
                    found = true;
                    position = index;
                }

                index++;
            }

            return position;
        }

And finally, the Search button. 
private void btnSearch_Click(object sender, EventArgs e)
        {
            lbResults.Items.Clear();

            if (SearchNames(boyNames, txtBoyName.Text) != -1)
            {
                // MessageBox.Show("Found boy name!");
                lbResults.Items.Add("Boy found:\t" + txtBoyName.Text);
            }
            if (SearchNames(girlNames, txtGirlName.Text) != -1)
            {
                // MessageBox.Show("Found girl name!");
                lbResults.Items.Add("Girl found:\t" + txtGirlName.Text);
            }
        }

Piece of cake ;-)

CIS 217: Array Assignment [Tic-Tac-Toe]

This assignment did not go as planned, to say the least.

The flow of the program was easy enough to figure out - I've done it in the past in other languages for other classes.
  1. Create a form with 9 Labels on it, a button to generate a new game, and an exit button.
  2. Create an 2D array to hold either 0s or 1s (0 = Os, 1 = Xs).  
  3. Loop through the array, then
    1. Generate a 0 or 1.
    2. Loop through the Label controls.
    3. Set the Text property of the current label to either "X" or "O", based on the generated number.
  4. Detect a winner:
    1. Search through the array for possible victories for Xs and Os:
      1. Top Row: Array locations [1,1], [1,2], and [1,3] are the same = Win.
      2. Middle Row: Array locations [2,1], [2,2], and [2,3] are the same = Win.
      3. Bottom Row: Array locations [3,1], [3,2], and [3,3] are the same = Win.
      4. Left Col: Array locations [1,1], [2,1], and [3,1] are the same = Win.
      5. Middle Col: Array locations [1,2], [2,2], and [3,2] are the same = Win.
      6. Right Col: Array locations [1,3], [2,3], and [3,3] are the same = Win.
      7. Left-Right Diag: Array locations [1,1], [2,2], and [3,3] are the same = Win.
      8. Right-Left Diag: Array locations [1,3], [2,2], and [3,1] are the same = Win.
  5. Let player click "New Game" button to generate the outcome again.

 Alas, I ran into a few snags:
  • Random numbers weren't generating, regardless of what I did.  Rebooting my PC and re-running the program fixed this.  Odd...
  • In an outcome set of 9 numbers, with 4 zeroes and 5 ones, the labels seemed to all display whatever the first number in the array was.
    • Yet, if I displayed each result (referencing the array), it showed the correct values.
    • I tested this in a ListBox as well...and sure enough, the random numbers were there.
I think my problem was that I used a control loop to display the outcomes, and might have been setting the Text property of each label to the current value of the current position in the array...so on one pass, all labels = 0.  The next, they = 1, then 0 again on the next pass, and so on...but never a mix of 1s and 0s. 

As an afterthought...I'm almost absolutely certain that this was the problem, as nothing else makes sense.

Monday, March 5, 2012

Tips: C#, Visual Studio 2010 - Get All Control Names, View TabIndex Order.

Here's a neat trick that I have used every-so-often ever since picking up Visual Basic 6 back in the 90's.  Sure, it can be done in other ways, but this way suites me well.  I can keep the notepad file off sitting to the file to refer to it if needed.

Create a Button control on your form, double-click it, and past this code into it:



using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\myControlNames.txt"))
            {
                foreach (Control myControls in this.Controls)
                {
                    //MessageBox.Show(myControls.Name + " = " + myControls.GetType());
                    file.WriteLine(myControls.Name + " = " + myControls.GetType());
                }
            }   

Run your program (F5) and then click the button.
You can then go to C:\myControlNames.txt file in the C drive, which will display this:

btnGetControlNames = System.Windows.Forms.Button
lblProcessed = System.Windows.Forms.Label
txtNumEvents = System.Windows.Forms.TextBox
lblTimeProcessed = System.Windows.Forms.Label
btnReadEvents = System.Windows.Forms.Button
btnExit = System.Windows.Forms.Button
btnCopy = System.Windows.Forms.Button
label5 = System.Windows.Forms.Label
label3 = System.Windows.Forms.Label
label2 = System.Windows.Forms.Label
label1 = System.Windows.Forms.Label
lblIndex = System.Windows.Forms.Label
lbMessage = System.Windows.Forms.ListBox
lbSource = System.Windows.Forms.ListBox
lbTimeGenerated = System.Windows.Forms.ListBox
lbEntryType = System.Windows.Forms.ListBox
lbIndex = System.Windows.Forms.ListBox
So when running that, it will give you a list of all controls in your form! Cool, eh?



Another tip is this:
If you want to see the TabIndex values for all controls on the form, you can go into Design view (so you are looking at your form), and go to the "View" menu and click on "TabOrder".  It will show all the TabIndex values for each control on your form (if it has them; things like PictureBoxes do not).  Use the "Escape" button to exit out of this mode (or use the "View" menu again).  Using the mouse to left-click on different objects can manipulate the TabIndexes.

Have fun!