Home AMX General Discussion

Proper Code Layout???

GSLogicGSLogic Original MemberPosts: 562
Here?s a subject that goes along with politics and religion? code layout.
As most of use probably think our way of code layout is the best.

I?ve done many system upgrades/fixes and seeing the way others layout code. Needless to say it drives me crazy!
Why do programmers layout code so differently.
AMX programmers 1:
IF(1 == 1)
{
  amxNumber 1
}

AMX programmers 2:
IF(1 == 1)
  {
  AMX_NUMBER 2
  }

AMX programmers 3:
if (1 == 1)
  {
AMX_NUMBER 3
  }

Java programmers:
if(1 == 1){
    Java
}

Save real estate programmers:
IF(1 == 1){bad childhood}

Please keep in mind I mention all this in a little way. I'd like to now if it all steams from the first code you ever wrote or did someone say "this is the correct way"?

I understand there are times to use different styles such as the "save real estate programmer", but I think the first example is the easiest to read and understand in the quickest time. I'm changing my code layout from using all caps to small, more in line with Java coding. That's something I should have done from the beginning.

What do you think?

Comments

  • Here's what works for me.
    GSLogic wrote:
    Here’s a subject that goes along with politics and religion… code layout...What do you think?

    I vote for 1. This method provides the most reability and ease to copy and paste.
    In addition, the hash marks in Studio line up nicely with the braces (curly brackets.)

    Although I have been using mostly upper case, lately I have been converting to a combination, again for better readability.

    Keywords should always be in upper case.
    AMX programmers 1:
    IF (1 == 1)
    {
      AMX_Number1
    }
    
    And everyone please start using lower case prefixes to indicate the data type.
    DEFINE_DEVICE
    dvSomeDevice = 05001:01:0
    vdvSomeVirtualDevice = 33001:01:0
    
    dvTP1 = 10001:01:0
    dvTP2 = 10002:01:0
    
    DEFINE_CONSTANT
    INTEGER nSomeNumber = 65535
    INTEGER n_SomeNumberArray[] =
    {
      1,
      32000,
      65535
    }
    LONG lSomeLongNumber = 60000000
    
    DEFINE_VARIABLE
    VOLATILE CHAR cSomeText[8] = 'Help' 
    VOLATILE CHAR c_SomeTextArray[2][8] = 
    {
      {'Hello'},
      {'Goodbye'} 
    }
    
    DEV dv_TP[] = // Some array of devices
    {
      dvTP1,
      dvTP2
    }
    
    I have added the underscore between the prefix and the data type to differentiate arrays from non-arrays.

    See AMX Tech Note 407 for more information on recommended NetLinx programming conventions.
    http://www.amx.com/techsupport/Netlinx/NetLinx%20Programming%20Conventions.pdf
    The data type prefix recommendations can be found on page 8.
  • viningvining X Member Posts: 4,356
    I'm definitely a #2 guy. I go back and forth on keyword CAPS, butmostly like lower. Vars are usually a combination. I use braces when they're not required just for clarity but that makes for longer code requiring more scrolling. When I'm brain dead and just can't think to save my life I usually go into cleaning mode and tidy things up.
     {
         PUSH:
    	  {
    	  local_var integer nBTN ;  //change to stack var
    	  local_var integer nVST_Day ; // day of the week or group of days 1-7 = days, 8 week end, 9 = weekdays, 10 = all same
    	  local_var integer nVST_LastBtn ; //last button pushed for "Question" button push.
    	  local_var integer nVST_SetMode ; //all days the same, week ends & week days or all individual 1-3
    	  local_var integer nVST_SetPeriod ; //morning, day, evening or night 1-4 
    	  local_var integer nVST_CurZone ; //which zone is active for scheduling
    	  local_var integer nVST_ChangesMade ; //a change was made
    	  
    	  nBTN = get_last(nVST_SchedBtnArry) ;
    	  nVST_CurZone = HVAC_CurrentZone ;
    	  nVST_Day = HVAC_CurrentDay ;
    	  if (nVST_DeBug)
    	       {
    	       SEND_STRING 0,"'ViewStat_Module ',itoa(button.input.device.number),
    							    ':',itoa(button.input.device.port),
    							    ':',itoa(button.input.device.system),
    							    '-CHANNEL ',itoa(nBTN),', PUSHED.',
    							    ' Line-<',ITOA(__LINE__),'>',crlf" ;
    	       }
    	  SELECT
    	       {
    	       ACTIVE (nBTN >= VST_EXIT && nBTN <= VST_RESTORE_PREV):
    		    {
    		    SWITCH (nBTN)
    			 {(* 41,42,43,44,45,46,47,48 *)
    			 CASE VST_EXIT:
    			      {
    			      if (nVST_ChangesMade)
    				   {
    				   nVST_LastBtn = fnVST_ChangesMade(BUTTON.INPUT.DEVICE,nBTN) ;
    				   }
    			      else
    				   {
    				   stack_var sinteger nVST_Var_to_XML ;
    				   stack_var sinteger nVST_Var_to_STR ;
    				   stack_var long nVST_EncodePOS ;
         
    				   nVST_EncodePOS = 1 ;
    				   fnVST_ExitScheduler(BUTTON.INPUT.DEVICE) ;
    				   nVST_Var_to_XML = VARIABLE_TO_XML(sVSTStat,cVST_Var_to_XML,nVST_EncodePOS,0 ) ;
    				   fnVST_FileWrite_ToFile(VST_XML_FILENAME,cVST_Var_to_XML) ;
    				   clear_buffer cVST_Var_to_XML ;
    				   }
    			      }
    			 CASE VST_ZONE:
    			      {
    			      if (nVST_ChangesMade)
    				   {
    				   nVST_LastBtn = fnVST_ChangesMade(BUTTON.INPUT.DEVICE,nBTN) ;
    				   }
    			      else
    				   {
    				   nVST_CurZone = fnVST_NextZone(nVST_CurZone) ;
    				   fnVST_CopyCurZtoAdmin(nVST_CurZone,TRUE) ;
    				   fnVST_UpdateTP_VT() ;
    				   fnVST_DeterminePopUp(BUTTON.INPUT.DEVICE) ;
    				   }
    			      }
    			 CASE VST_NEXT:
    			      {
    			      if (nVST_ChangesMade)
    				   {
    				   nVST_LastBtn = fnVST_ChangesMade(BUTTON.INPUT.DEVICE,nBTN) ;
    				   }
    			      else
    				   {
    				   nVST_CurZone = fnVST_NextZone(nVST_CurZone) ;
    				   fnVST_CopyCurZtoAdmin(nVST_CurZone,TRUE) ;
    				   fnVST_UpdateTP_VT() ;
    				   fnVST_DeterminePopUp(BUTTON.INPUT.DEVICE) ;
    				   }
    			      }
    			 CASE VST_PREV:
    			      {
    			      if (nVST_ChangesMade)
    				   {
    				   nVST_LastBtn = fnVST_ChangesMade(BUTTON.INPUT.DEVICE,nBTN) ;
    				   }
    			      else
    				   {
    				   nVST_CurZone = fnVST_PrevZone(nVST_CurZone) ;
    				   fnVST_CopyCurZtoAdmin(nVST_CurZone,TRUE) ;
    				   fnVST_UpdateTP_VT() ;
    				   fnVST_DeterminePopUp(BUTTON.INPUT.DEVICE) ;
    				   }
    			      }
    			 CASE VST_SAVE:
    
  • JohnMichnrJohnMichnr Junior Member Posts: 276
    I'm definately a #1 guy - That has always been more readable for me, but I have been know to show my poor uprearing by doing the save real estate method on occasion...
  • Danny CampbellDanny Campbell Senior Member Posts: 311
    # 1 for me. I usually have my variable names in all caps with the exception of the first character which is lower case and follows the AMX programming recommendations.
  • DHawthorneDHawthorne Junior Member Posts: 4,584
    I too prefer #1 for readability. I find it very helpful to align curly braces vertically to see what is a block and what is nested.

    I tend towards all caps for keywords, and mixed case for variables, using a pseudo prefix system to tell at a glance what type of variable it is. I say pseudo because I do not strictly adhere to standards on this, partly from habit, and partly because I find some of the standards ridiculous for my use. For example, I'll name a string sStringName instead of strStringName; I'll use nNumber for any kind of data type unless it's real important to know the exact type, etc.
  • Spire_JeffSpire_Jeff Formerly Caffeinated Programmer Posts: 1,917
    I use #1, I use the lowercase datatype, and I like Brian's idea of _ indicating an array.

    Finally, because I am feeling ambitious, I will ask a question of perspective:

    In Brian's example:
    DEFINE_VARIABLE
    VOLATILE CHAR cSomeText[8] = 'Help' 
    VOLATILE CHAR c_SomeTextArray[2][8] = 
    {
      {'Hello'},
      {'Goodbye'} 
    }
    

    The first defination could also be defined as:
    VOLATILE CHAR sSomeText[8] = 'Help' 
    
    or 
    VOLATILE CHAR c_SomeText[8] = 'Help' 
    

    and obviously the second definition could be:
    VOLATILE CHAR s_SomeTextArray[2][8] = 
    {
      {'Hello'},
      {'Goodbye'} 
    }
    

    So, I wonder, when does a char array become a string? Could it be said that the string exists only in our minds and hence everything is really just a char array? Or does one believe that because we think there is a string, the string must exist?

    /me wanders off in a caffeine stupor

    Jeff
  • Great discussion.

    Jeff,

    Consider this regarding your question.

    Use a lower case s representing a string as the prefix for defined constants.
    DEFINE_CONSTANT
    CHAR sSomeText[8] = 'Help'      // No underscore for single dimensional array
    CHAR s_SomeTextArray[2][8] =    // Use underscore for multi dimensional array
    {
      {'Hello'},
      {'Goodbye'} 
    }
    

    Use a lower case c representing a string as the prefix for defined variables.
    DEFINE_VARIABLE
    VOLATILE CHAR cSomeText[8] = 'Help'      // No underscore for single dimensional array
    VOLATILE CHAR c_SomeTextArray[2][8] =    // Use underscore for multi dimensional array
    {
      {'Hello'},
      {'Goodbye'} 
    }
    
  • yuriyuri Junior Member Posts: 861
    Spire_Jeff wrote:
    I use #1, I use the lowercase datatype, and I like Brian's idea of _ indicating an array.

    Finally, because I am feeling ambitious, I will ask a question of perspective:

    In Brian's example:
    DEFINE_VARIABLE
    VOLATILE CHAR cSomeText[8] = 'Help' 
    VOLATILE CHAR c_SomeTextArray[2][8] = 
    {
      {'Hello'},
      {'Goodbye'} 
    }
    

    The first defination could also be defined as:
    VOLATILE CHAR sSomeText[8] = 'Help' 
    
    or 
    VOLATILE CHAR c_SomeText[8] = 'Help' 
    

    and obviously the second definition could be:
    VOLATILE CHAR s_SomeTextArray[2][8] = 
    {
      {'Hello'},
      {'Goodbye'} 
    }
    

    So, I wonder, when does a char array become a string? Could it be said that the string exists only in our minds and hence everything is really just a char array? Or does one believe that because we think there is a string, the string must exist?

    /me wanders off in a caffeine stupor

    Jeff

    a string is always an array of characters :p so yes, it just lives in your head.

    ontopic:
    the problem with using tabs (i use them always) is that when someone uses another tab lineout, and you open his code, it's all messed up.
  • Tabs and indents settings
    yuri wrote:
    the problem with using tabs (i use them always) is that when someone uses another tab lineout, and you open his code, it's all messed up.

    We have been recommending in our training classes for the programmer to write a comment for these settings somewhere in the beginning of the file.
    // This file is best viewed with tabs and indent set to 3.
    
  • viningvining X Member Posts: 4,356
    Yuri wrote:
    ontopic:
    the problem with using tabs (i use them always) is that when someone uses another tab lineout, and you open his code, it's all messed up.
    I've done that to myself sevral times but will still always indent.

    Yuri, does that make you a 2 or am I still the only one? Although 1's also have to indent, they just do it wrong.
    B-Clements wrote:
    We have been recommending in our training classes for the programmer to write a comment for these settings somewhere in the beginning of the file.
    Code:
    
    // This file is best viewed with tabs and indent set to 3.
    

    I initially used 4 in NS2 which was probably the default but I've since changed to 8 which I like. I use a widesceen which I'm sure every one uses now and I find that spreading the code out gives it a better visual flow. This is why I always use braces when I don't have to like a single statement after an "if" or wait.

    Y
  • More on settings
    B_Clements wrote:
    We have been recommending in our training classes for the programmer to write a comment for these settings somewhere in the beginning of the file.
    // This file is best viewed with tabs and indent set to 3.
    
    Going back to the DOS editor where columns were limited to 80 characters I have pretty much tried to keep that format. This allows you to vertically tile two editing windows of the same source code file on a wide screen display. To me a value of 3 seems the correct offset for each nested section.

    I hope everyone else is taking advantage of the window tile feature.

    One of my pet peeves is viewing/editing a file where scrolling horizontally is necessary. It really bothers me when a line of code is hiding out of complete view.
  • viningvining X Member Posts: 4,356
    B-Clements wrote:
    One of my pet peeves is viewing/editing a file where scrolling horizontally is necessary. It really bothers me when a line of code is hiding out of complete view.

    I agree, but like wise my variable and structure names are way to desciptive making them too long as well.
  • sethollesetholle Junior Member Posts: 66
    Coding clarity

    I too like example number one. However I like the commentating also. That is a problem that I have of tons of code that I have had to redo. NO comments at all.
    And very very long variable names. A variable name should be specific but not 50 letters long.
    I like the underscore for variable, such as i_tvinfo, i_dvdinfo etc.
    Want I don't like is when code is all over the place, nothing lines up at all. Has anyone else found this is old code?
  • dchristodchristo Junior Member Posts: 177
    B_Clements wrote:
    It really bothers me when a line of code is hiding out of complete view.

    But that's where I hide all of the "fun" code...

    ;-)

    I'm a #1.

    --D
  • Commenting and Constants
    setholle wrote:
    I too like example number one. However I like the commenting also... I don't like is when code is all over the place, nothing lines up at all. Has anyone else found this is old code?
    When comments don't fit to the right of a line of code there is nothing wrong with putting it just above the line.

    Sloppy code is like a poorly wired equipment rack where cables look like spaghetti. You need just the right amount of organization so it can be easily serviced or revised and the right amount of comments so there is no need to reference the design drawings.

    Of course you can also over do it. Anyone seen a rack with too many cable ties? I have and is amost as bad the spaghetti mess. In code I relate that to too many constants.

    For example:
    DEFINE_CONSTANT
    
    INTEGER nOff = 0
    INTEGER nOn = 1
    
    So why do you need...
    DEFINE_CONSTANT
    
    INTEGER nDVDOff = 0
    INTEGER nDVDOn = 1
    INTEGER nVCROff = 0
    INTEGER nVCROn = 1
    INTEGER nProjOff = 0
    INTEGER nProjOn = 1
    
    Bottom line, avoid unnecessary constants
  • Chip MoodyChip Moody Junior Member Posts: 727
    Snotty comments aside, 1 is better than 2. :)

    3 is just wrong.

    I'll do the real estate thing if I only have one - >maybe< two - statements inside the braces

    Re: Java & real estate, I can't really *****, because I have nearly forever done this just to save a line:
    BUTTON_EVENT [TP,1]
    { PUSH:
      {
        // statements
      }
    }
    


    I find the "signify the variable type by using lower case characters in front of the name" to be distracting & annoying - at best. I got a couple of years under my belt of Axcess, when there were only two types of variables, and it wasn't hard to tell the difference. Now the only extension are structures and more numerical types, and well - if you can't tell a structure is being used by the fact that an element is being accessed... I also haven't run into any situations where an indicator of what numerical type a variable is would be required/helpful, so I just haven't bothered.

    I still make keywords upper-case.

    This is all IMHO - your mileage is more than likely to vary.

    - Chip
  • yuriyuri Junior Member Posts: 861
    vining wrote:

    Yuri, does that make you a 2 or am I still the only one? Although 1's also have to indent, they just do it wrong.

    i'm a 1 :)
    however i started out doing it the "java" way :)
  • jjamesjjames AMX Sustaining Engineer Posts: 2,901
    First and formost - I'm a #1 guy, although I started out as #2.

    Going back to Jeff's reply and pointing out the "typical" way of listing things in an array, note the placement of the commas.
    INTEGER n_SomeArray[]=
    {
       1,
       2,
       3,
       4,
       5
    }
    

    I've started to do this after seeing it once:
    INTEGER n_SomeArray[]=
    {
        1
       ,2
       ,3
       ,4
       ,5
    }
    

    To me it's easier to read, and also, if I want to remove the last number (5), I can delete the line immediately without having to think about getting a syntax error.

    Does anyone else do it this way and what are your thoughts?
  • GSLogicGSLogic Original Member Posts: 562
    A few other ideas:

    I add different header symbols for each different EVENT,
    BUTTON_EVENTS get //########
    DATA_EVENTS get //%%%%%%%
    It makes reading a little easier on the eyes to see the different EVENTs
    //#############################################################
    BUTTON_EVENT[dTP_MAIN,btMainMenu]		//MAIN MENU NAVIGATION
    {
      PUSH:
      {
          fnPNL_ROUTER(GET_LAST(dTP_MAIN), GET_LAST(btMainMenu));
      }
    }
    
    //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    DATA_EVENT[dTP_MAIN]
    {
    

    I also start all my button array names with prefix "bt".
    All variables are small letters with Caps for the new words (nVarNameName) ala:Javaish.
    All comment over a line of code get (* comment *) Next to a line of code get //comment
    I still use "n" for all numbers and cString for all Strings/Chars.
    I use caps for all keywords.

    That's my 3 cents!
  • GSLogicGSLogic Original Member Posts: 562
    Spire_Jeff wrote:
    So, I wonder, when does a char array become a string? Could it be said that the string exists only in our minds and hence everything is really just a char array? Or does one believe that because we think there is a string, the string must exist?
    Hi Jeff,

    In the AMX world (for the moment) a string/char are the same but when/if you ever code in Java, you'll have to know the difference because they will not act the same. You'll have to declare a String or a Char as the variable.
  • jstargeljstargel Junior Member Posts: 12
    Me to 2
    vining wrote:

    ... am I still the only one? Although 1's also have to indent, they just do it wrong.


    Say on Brother!
  • What the Heck, I'll chime in...

    I am a #1 with the following naming conventions.

    CONSTANTS
    INTEGER SOME_INTEGER = 1
    CHAR SOME_CHAR = 'a'

    VARIABLES
    INTEGER nTPButtons[] //Touch panel channel arrays always have 'Buttons' at the end
    INTEGER nIntegerArray[] // Somehow I just remember that this is an Array
    INTEGER nSomeInteger //Simple Integer
    CHAR cSomeCharacter //Simple Char
    CHAR sSormeChaString[] //Use 's' to denote string

    All KEYWORDS and CONSTANTS are capitalized.(Most of the time, some 'atoi's slip by)


    And of course, color coding to differentiate Variables, Constants, Numbers, ASCII Text, Keywords, etc..
    INTEGER nSomeArray[]=
    {
        1
       ,2
       ,3
       ,4
       ,5
    }
    

    Comma's before the number just looks silly to me...But, to Each his own!!
  • Daniel TehanDaniel Tehan Junior Member Posts: 42
    colors anyone?

    I am a #1, I guess that is what was taught in class and sometimes I spend an unjustafiable time "re-indenting" someone's code before I make changes just because I can't read it. I have a hard time reading anything if it isn't "just so", a personal weakness of mine I think.

    Does anyone else use the colors for different variable types to organize? I have my studio set to a black background (I guess a leftover preference from CAD) so I can use many more shades of orange and blue to reflect data types. This way even if the previous programmer of a system didn't follow the same naming conventions as I do I can still read it faster.

    I also use many multiple DEFINE_XXX sections with a comment line after it so I can use the code folding to organize groups of operations.

    Disclamer - None of these are my own ideas, but I figured I would pass on to anyone who hadn't seen them before.
  • JohnMichnrJohnMichnr Junior Member Posts: 276
    yes - I too use different colors for variables vs constants etc. I also use bolded or normal fonts. My constnts and devices are bolded, the variables are not. But i do use a white background, although I use black on CAD. I just can't make the leap to having the black background on teh programming side.
  • JeffJeff Junior Member Posts: 374
    I also use many multiple DEFINE_XXX sections with a comment line after it so I can use the code folding to organize groups of operations.

    So you're saying you can do things like "Define_Event" with a comment afterwards to specify a certain group of events, and then right after that do Define_Event again, wiht a different comment and have it nest separately?

    That makes an awful lot of sense, I guess I'd just never realized I could have multiple Define_XXX sections of the same thing before . . . .

    J
  • Daniel TehanDaniel Tehan Junior Member Posts: 42
    It would look something like this:

    - DEFINE_EVENT// DATA EVENTS

    + DATA_EVENT[dvLCD]
    + DATA_EVENT[dvEXTRON]
    + DATA_EVENT[dvCLEAR_ONE]
    + DATA_EVENT[dvDVD]
    + DATA_EVENT[dvCD_A]
    + DATA_EVENT[dvTP_1]

    + DEFINE_EVENT// CHANNEL EVENTS, TIMELINE EVENTS
    + DEFINE_EVENT// SOURCE SELECTS, PAGE FLIPS
    - DEFINE_EVENT// SOURCE CONTROL

    + BUTTON_EVENT[dvTP_1,nDVD_BUTTONS] ///// DVD CONTROL /////
    + BUTTON_EVENT[dvTP_1,56]
    + BUTTON_EVENT[dvTP_1,57]
    + BUTTON_EVENT[dvTP_1,nDSS_BUTTONS]
    + BUTTON_EVENT[dvTP_1,nCD_BUTTONS]


    and so forth.

    You can have multiple DEFINE_CONSTANT, DEFINE_VARIABLE, DEFINE_DEVICE, DEFINE_EVENT, I am sure others as well but those are the ones I use
  • viningvining X Member Posts: 4,356
    Jeff wrote:
    That makes an awful lot of sense, I guess I'd just never realized I could have multiple Define_XXX sections of the same thing before
    Basically the same as what your doing with "INCLUDE" files. Your main program pulls in the .axi's and adds those DEFINITIONS after the corresponding main definition and keeps adding until all INCLUDES are included.
  • JeffJeff Junior Member Posts: 374
    Alright, so I'm sitting in the Programmer I class as we speak. The Instructor just put up on the board a beautiful Powerpoint slide with the "AMX Recommended Code Format" on it.
    BUTTON_EVENT[PANEL,1]
    {
       PUSH:
       {
          IF (X=1)
          {
             Y=2
             Z=3
          }
       }
    }
    

    He also showed an example of real estate programming and basically said "this will work but its confusing, dont do it"

    Anyway, thats the official word of whats right, but his statement pretty much said "do whatever works as long as it isn't stupid"



    Jeff
Sign In or Register to comment.