Announcement

Collapse
No announcement yet.

"I''m a n00b and I need help!"

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • "I''m a n00b and I need help!"

    For anyone who may feel the need to post a thread like this allow me to offer some preemptive advice. Starting out in any programming language can be a bit overwhelming and sometimes the next step can be quite elusive.

    I know when I first starting coding, conventions were unknown to me and, after developing them over the years, I can see their importance. Without conventions for naming variables, commenting and structuring code, proper organization of your code is nearly impossible. So, I thought I'd offer this little post in an effort to eliminate some of the beginning confusion that can occur with AMS coding. Keep in mind that we're all n00bs in some way or another and for those of you just starting out in AMS...I hope this helps.

    All the experienced coders feel free to chime in. I'll add more stuff when I think of it.


    Lesson #1: Variables Names
    Below I provide a list of variable type indicators. This is my way of doing it, take this example and use what you like and come up with your own stuff too and please, share it so other people can learn from your genius ideas.

    Now, keep in mind, that you should be able to look at your code a year from now and decipher it fairly easy. Your variable names should be chosen to reflect their use. Also, they should be concise; long and cumbersome variable names can create clutter and be confusing. If you need to specify several words, try abbreviating meaningfully or using a logical delimiter between the words. Capital letters are very good logic delimiters between words.

    Strings
    sMyString = a lower case "s" before my variable name indicates that this a non-specific string

    pFilePath = this is also a string but the "p" indicates that this is a path to a file or folder.

    Boolean
    bIsVisible = this is a boolean (true or false).

    Numbers
    nMyVeryLongNumberVariableName = the "n" tells me this is a number. "i" is also commonly used and stands for "integer". These are, for all intents and purposes, interchangeable in AMS.
    Note:In programming languages where variables are declared, these two indicators should not be used interchangeably as they stand for different number types (such as double or float).

    Tables
    tLetters = "t" stands for table...and the cow says "mooo".

    Functions
    MyFunction() = I don't typically use a letter in front of function names since a function is always followed by parentheses "()" that may or may not contain arguments.

    Userdata and Threads.
    These are not typically used by the beginner programmer so we'll come back to these later when we explain them in more detail.

    Window and File Handles
    hWnd = Although these are numbers, I use "h" to show that they are handles to files or windows. A few, well-chosen, variable type sub classes can make life a whole lot easier.

    Locals vs Globals.
    A common mistake for newcomers is to, simply, start typing variable names and assigning values without any regard for variable scope. According to the lua documentation, local tables are processed about 30% faster than global tables. That's huge! If a variable does not need to be global, make it local. Now, by default in AMS, all variables are global unless declared otherwise. Use the word local before your variable names to make them local.

    Tip! Repeat loops can be a little tricky when using local variables so experiment and figure out what works. Read the AMS documentation for more info on variable scope.

    _sProgramName = To indicate a global variable, I use an underscore "_".
    local nTotal = Declaring a local variable is as easy as typing the word "local" before it.


    Lesson #2: Object Naming
    Haphazardly naming objects can be confusing and result in the complete and utter destruction of the universe...or some catastrophe closely related. In each object's name field I place a prefix (three letters and always the same for a given object type) and the name of the object. Also, I use all lower case for my objects. This makes enumerating object types easy and also makes a quick glance at your code valuable and informative.

    Prefixes Examples
    CheckBox = "chk save file"
    Paragraph = "par details"
    Input = "inp password"

    I think you get the idea. Whatever three letters upon which you decide, stick to them! Changing prefixes mid-program will defeat the purpose of this method (unless you change them all). I would recommend deciding upon your prefixes (within a reasonable amount of time) and never changing them so you'll be able to look back on previous code and get the gist of its structure and function quickly.


    Lesson #3: Commenting, White-space and Indenting and Posting Code

    Comments
    Now, everyone has a different opinion of this part of coding. I'll give you mine and you can get others' from them. When writing plugins, I rarely comment my code. The code in my plugins is structured and the functions named in such a manner that all of it is, basically, self-explanatory.

    When writing programs, I comment frequently and concisely. My comments are not lengthy but they are descriptive. Also, I comment only in places where comments are needed.

    For example,
    PHP Code:
    local tLetters = {"a","b","c","d","e","f","g","h","i","j"};

    if 
    tLetters then
        
        
    for nIndexsLetter in pairs(tLetters) do
        
    Dialog.Message(nIndex"This is a the letter"..sLetter);
        
    end
        
    end 
    For me, the above code would not require a comment as it's pretty clear what's going on here. As the code becomes more complex, the comments should become more frequent.

    White-space and Indenting
    Consider this code,
    PHP Code:
    local tLetters = {"a","b","c","d","e","f","g","h","i","j"};
    if 
    tLetters then
        
    for nIndexsLetter in pairs(tLetters) do
        
    Dialog.Message(nIndex"This is the letter "..sLetter);
        
    end
    end 
    Having one's code all smashed together, especially when you've got a thousand lines of it, makes logic section distinction quite difficult. Leave a little space.

    Take at look at this,
    PHP Code:
    local tLetters = {"a","b","c","d","e","f","g","h","i","j"};

    if 
    tLetters then
    for nIndexsLetter in pairs(tLetters) do
    if 
    sLetter == "a" then
    Dialog
    .Message(nIndex"This is the letter "..sLetter);
    end
    end
    end 
    Even with some white-space, distinguishing the logic statement bounds is very difficult since I have not indented my code. The first time you write five embedded logic statements, try writing them with and without indentation and you'll see the difference.

    Posting Code
    There are many examples on this forum of people posting their code like this,

    local tLetters = {"a","b","c","d","e","f","g","h","i","j"};
    if tLetters then
    for nIndex, sLetter in pairs(tLetters) do
    if sLetter == "a" then
    Dialog.Message(nIndex, "This is the letter "..sLetter);
    end
    end
    end

    I usually pass right by these posts (unless I stop to say, "Please post your code using the CODE or PHP tags"). I have no intention of spending my time sorting out someone's mess. Many others here feel the same way as is clear from their posts regarding this issue. Most folks around here have no problem helping newcomers (or old timers for that matter) as long as it's clear that some effort went into their process and there is no mess to clean up before hand. So, do yourself a favor when asking for help with code and post it using indentation, white-space and a CODE or PHP tag.

    Like this...
    PHP Code:
    local tLetters = {"a","b","c","d","e","f","g","h","i","j"};

    if 
    tLetters then
        
        
    for nIndexsLetter in pairs(tLetters) do

            if 
    sLetter == "a" then
            Dialog
    .Message(nIndex"This is the letter "..sLetter);
            
    end
            
        end
        
    end 

    Lesson #4: RTFM!
    This should probably be lesson one....
    RTFM stands for Read the [email protected]*&^%$ Manual. Yes, read read read. When a newcomer asks a question like, "How do I get the text from an input object?" the response is generally unanimous, "RTFM!". Like, I said, we are all here to help each other and don't mind giving help except when it is quite clear that someone just wants us to do the work for them. IR has done an amazing job with the help file, it is a valuable resource for learning AMS and where I spent the first year and a half of my n00bhood.
    Last edited by Centauri Soldier; 07-22-2010, 03:09 AM.
    https://github.com/CentauriSoldier

  • #2
    Thanks Centauri,

    All us n00bs (he he he) appreciate when the upper echelon descend from the mountain top to grace us with their wisdom and knowledge.

    Oh geez, I better get my paper and pencil so I can save this information for later....

    Cheers,
    Dean

    Comment


    • #3
      Wow, really nice CS!
      Although, I have some suggestions (in addition to what you said) for:

      Lesson #1: Variables Names
      1) I'm also used to name variables as you do, and it's really a good method to remember even after years what is the variable there for. But when you have to distinguish between variables you set directly in the source (like: sExample = "This is an example string"), and variables that have values returned from functions, there's another trick you can use; you can put a RET_ (meaning return) after indicating the variable type.
      for example:
      sMyVariable = MyFunctionWithReturn();
      will become:
      sRET_MyVariable = MyFunctionWithReturn();

      This can help when you have global variables and you have it's value set the first time with a function and after you manage it otherwise.

      2) Global variables:
      Not many people build softwares that can load an external LUA file, but those who do know that external LUA files might (always) need some variables from the main application. Then, to distinguish from Global Project variables and Global Project and External LUA variables it could be a good thing putting them all in UPPERCASE, reminding so that this variable can be modified by external LUA files.

      Lesson #2: Object Naming
      Objects in AMS have really simple names indicating the object type; some of them have DoubleWord names (like the RadioButton, CheckBox..ect). When you name objects consider the object name and:
      if the object is named with more than one word:
      take the first letter of each word and put it in UPPERCASE followed by an underscore '_' before the object name you want to give it.
      for example:
      CheckBox
      RadioButton
      will become
      CB_Name
      RB_Name

      if the object name could be confused with another one because the letters are the same (like for ComboBox and CheckBox) then after the first letter put a lowercase letter token from the midlle of the word.
      for example
      CheckBox
      ComboBox
      will become
      CeB_Name
      CmB_Name

      if the object is named with only one word:
      take the first three letters and put them in UPPERCASE followed by an underscore '_' before the object name you want to give it.
      for example
      Button
      Paragraph
      Video
      Hotspot
      will become:
      BUT_Name
      PAR_Name
      VID_Name
      HOT_Name
      *where Name, is the name you want to give to the object

      This kind of object naming can help a lot in three cases:
      #when looking in the Project explorer list: you don't have to look at object's icon to understand if it's a paragraph, an input or else, and when the project has lots of objects it's useful, trust me
      #when listing objects at runtime: at runtime you have no idea what type are the objects (not really true as long as you're the author of the software), but if you name the objects like I said here, you know even at runtime that INP_ObjectName refers to an input object, or RT_ObjectName refers to a RichText object
      #almost always
      ---------------------------

      So, what do you think about this ?

      EDIT
      I was a nÓÒb once too...
      Last edited by T3STY; 07-22-2010, 09:24 AM.

      Comment


      • #4
        nice post CS, very helpful indeed :yes
        Embrace change in your life, you never know, it could all work out for the best

        Comment


        • #5
          Thanks, guys. Very nice "Coding 101" tips for everyone. We can all fall into bad coding habits from time to time.
          My tendency is to "Over comment" my code. So often I'll return to something I wrote months or even years ago and scratch my head...that said, my offering to the post would be:
          --comment, comment, comment;

          Comment


          • #6
            its better than my -- never comment

            im a bugger for commenting code, i always think, "i'll do this section and go back and comment it all up"....but i never do!
            Embrace change in your life, you never know, it could all work out for the best

            Comment


            • #7
              I always think: the variables names will say it all.. and I comment only when.. when?! XD
              No, really I comment once per event, with general sayings.. 2/3 lines max... I should do better than that

              Comment


              • #8
                If I commented my code and worried about how may variables are named, my family would starve. Only people who work for large corporations have that luxury.
                Dermot

                I am so out of here :yes

                Comment


                • #9
                  Also, what is way more important than variable naming especially for new users is variable scoping. So many people create all variables as global when they should be local. This has a huge impact on your apps.

                  Another thing I see people doing is this
                  Code:
                  result = Dialog.Message("Result", "message")
                  not only is the variable global, it is completely unnecessary and is not even used.
                  Dermot

                  I am so out of here :yes

                  Comment


                  • #10
                    ..and may break the value contained in another event with a variable called with the same name; that is one of the things new users find hard to figure out... it happened to me...

                    Comment


                    • #11
                      Nice to see people giving their two cents. Keep the tips coming guys...maybe we can make this a redirect thread for the simpler questions with AMS.
                      https://github.com/CentauriSoldier

                      Comment


                      • #12
                        I have booked this post as this post will help me explain to some people just starting out in AMS your a star for sure

                        Comment


                        • #13
                          Lesson #5: turn anything into generic functions
                          One of the things new users are not used to do is build generic functions for doing things they use in more projects. But why turn anything into generic functions?
                          Because when you have a generic function you can take this function and copy-paste it into another project, and it still does its work like it did in the first project. A little example:
                          Code:
                          --[[
                          NOTE: the next code is the one IR provided in AMS for a fast error test.
                          In the script editor:  Right-click > Quick scripts > test for error
                          ]]--
                          
                          -- Test for error
                          error = Application.GetLastError();
                          if (error ~= 0) then
                          	Dialog.Message("Error", _tblErrorMessages[error], MB_OK, MB_ICONEXCLAMATION);
                          end
                          This was a simple test for error code that it's used a lot when creating an application. But think how stupid would be to repeat those lines of code every time you need... not really sensed as long as the code is the same you've used maybe a few lines before... so turn it into a function!
                          Code:
                          --[[
                          NOTE: this function won't return anything;
                          ]]--
                          
                          function GetLastError()
                          
                          	-- Test for error
                          	error = Application.GetLastError();
                          	if (error ~= 0) then
                          		Dialog.Message("Error", _tblErrorMessages[error], MB_OK, MB_ICONEXCLAMATION);
                          	end
                          
                          end
                          So now, when you have to check for errors, instead of writing all those lines of code you just call the function GetLastError(); and here you are. Also, if you want to display a personal message with the error code providing additional information, or if you want to check only for a specific error code, you can modify this function to do so, and you have to modify it only ONCE, not as many times as you would do without a function.

                          Comment


                          • #14
                            This should be stickied.

                            Comment


                            • #15
                              Lesson #6: it's all under control!
                              When building applications you may write code that for its syntax is correct. But when you execute the application you get wrong results. For example:
                              Code:
                              nMyAge = 18;
                              Dialog.Message("My age", "My age is: ".."nMyAge");
                              This code should show a message with the value in the variable nMyAge but instead it's printing the nMyAge string. Why ? Because it didn't call the variable nMyAge!
                              The right code should be:
                              Code:
                              nMyAge = 18;
                              Dialog.Message("My age", "My age is: "..nMyAge);
                              Note that there are no quotes for nMyAge

                              So the thing you can do to find this is kind of errors - but not limited to - is to use the Debug window that AMS provides.
                              The debug has 2 modes: Trace and manual;
                              The Trace mode prints itself any line of code that's being executed in a moment and also prints the error message (if any) or the success message. It can be activated using Debug.SetTraceMode(true); // if you set false instead of true you can disable the trace mode

                              The manual mode let the user print, when called the Debug.Print(); function, the things s/he need.

                              Personally I suggest the trace mode and the best way to use it is to put this code on the On Startup event (Menubar > Project > Actions.. )
                              Code:
                              Debug.ShowWindow(true);
                              Debug.SetTraceMode(true);
                              With this code, right when the application is ran, the debug will start checking for all lines of code in any event of your application (when it's being executed)
                              NOTE 1: If you put this code on another event (like OnShow) the actions on the OnPreload or OnStartup events will not be logged;
                              NOTE 2: You cannot be so nÓÒb to put this code on the OnClose or OnShutdown event.. it's usless there as the window opens and closes after less than a second (because the application exits)...

                              But if you want to manually print things in the debug window, Use the Debug.ShowWindow(true); function on the OnStartup event but don't set the trace mode to active (just don't call the Debug.SetTraceMode(true) function -- it's disabled by default). So, call whenever you want the function Debug.Print("string with text to print"); and you'll have your desires.
                              NOTE 1: you can call the Debug.Print() function even if you're using the Trace mode
                              NOTE 2: if an error occurs this mode won't display any error message; you'll have to use the Application.GetLastError() function and print the result with Debug.Print();
                              NOTE 3: if the debug window is not opened you can still call the Debug.Print() function; the text will still be added to the debug window and showed up when showing the debug window again.

                              EDIT
                              I gave my little help here and I hope this will help new (and not) users to create good applications
                              Last edited by T3STY; 07-28-2010, 08:50 AM.

                              Comment

                              Working...
                              X