Jump to content
New account registrations are disabed. This website is now an archive. Read more here.

Search the Community

Showing results for tags 'tutorial'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Main Center
    • Announcements & News
    • Feedback, Bug Report and Forum Help
    • Introductions and Farewells
    • Community Contests & Events
  • Game Development
    • General Game Development
    • Engine Discussion
    • Support
    • Requests
    • Project Recruitment
  • Community Projects
  • Creativity & Design
    • Programming & Web Development
    • Stories and Literature
    • Resource Showcase & Critique
    • The artsy side
  • Off Topic
    • The Cafe
    • Computers, Internet and Tech Talk
    • Video Games
    • Entertainment & Media
    • Role Playing, Interactive Story Telling & Forum Games
  • Archive
    • Forum Archive
  • RPG Maker VX
  • Gamers Corner

Blogs

  • Emily_Konichi's Blog
  • Wyzrd's Blog
  • Marks Bloggy
  • Punkid's blog
  • isaacsol's Blog
  • Cloudstrife's blog of items
  • Lammorra's Blog
  • The most magnificent blog EVER!
  • dietcherrycoke
  • Elric1816's Blog
  • COPY RIGHT...???
  • Chaos Impact - Production Blog
  • Encounters
  • Kiriashi's RMXP Activity
  • bugbite250's Blog
  • polraudio's Blog
  • The Silent Assassin Horror Blog
  • Elandryal's Blog
  • niemitoad's Blog
  • Awakening project Blog
  • XDoggStrafe's Blog
  • Code Geass: Painful Memories Daily Progress
  • Check out what I'm doing... you stalker
  • Aerow's Blog
  • Omar510's Blog
  • Agckuu Coceg Blog
  • My RMXP Projects Blog
  • Franklin's Adventures
  • RMXPUnlimited Dev Blog
  • HedgeKnight.net
  • Zanime Dev Blog
  • Tomo2000's Blog
  • The Programmer's Blog
  • A Bayonetta Inspired game
  • Elviar: Erufu Tairiku Blog
  • ShinyToyGuns' Development Blog
  • Zeriab's thoughts
  • Blogotry
  • Leerox4eva1's Blog
  • Tatsu's
  • O
  • Zark: The Time Storm Blog
  • DS (Devine Shadow) Development Blog
  • Silver Moon Blog
  • Rhijun568's Blog
  • Rhijun568's Blog
  • Mundane's Blog
  • Meh
  • Cutting Through Time Itself
  • This is not a Blog
  • RGangsta's Blog. :D
  • jporter917's Blog
  • Leon's Blog for the Minions
  • Inner Monologue
  • White Rabbit's cave with a view.
  • Darktom77's Blog
  • Salsa de salsa en Malaga
  • mwillems' Blog
  • aaa135139's Blog
  • withinsin's Blog
  • Final Fantasy XP VI
  • The progress of Crym
  • Free to Listen
  • Final Fantasy XP
  • Mega Man Transfer
  • Random Blog
  • Random Blog
  • RPG Maker Inventions
  • Xeyla's Blog
  • 808_legend's Blog
  • My First Non-Fan game
  • kellessdee's Blog
  • Chronicles of the Chronicles
  • YAY! Factors
  • Merlin The RPG Blog
  • newgamergirl2011's Blog
  • Calathandias Blog
  • Jon Bon's Blog
  • RMU Development Blog
  • Glaze Of The Slient
  • Illuminate the pathway, blind the corrosion and set sail for awakening!
  • Project GK
  • frida89's Blog
  • Octopus Shoes
  • Stuffs
  • Uninstaller
  • Music Mayehm
  • Development Blog 2.0
  • Nickz's Blog
  • RageMage's Blog
  • UrHappyPlz's Blog
  • Gmack's Blog
  • Night Horror
  • Tales of Druidia Blog
  • Arcatis Progress
  • Ex-Stigma
  • yiyi's Blog
  • yiyi's Blog
  • jianren925's Blog
  • gaogen's Blog
  • Prince Liam
  • Bon Ink Creations Independent Showcase
  • Video Game Series Where Are They Now?
  • buwawa's Blog
  • Bon Ink Creations Blog
  • Bon Ink Creations Forum Feed
  • White Rabbit's Thought Bubble
  • Pyramid_Head's Grotto of Wonders
  • DarthVollis's Project
  • Day of the Darkness
  • Ovan35's Blog
  • nightprince75's Blog
  • Arcatis Project
  • Code Runners Dev Blog
  • valerinwuba's Blog
  • shontellewilson's Blog
  • Bob Rambles
  • The Other World
  • Audio bible
  • Audiobible

Categories

  • RMXP Projects
  • RMVX Projects
  • Other Games
  • RGSS(RMXP) Scripts
  • Graphical Resource Packs
  • Audio Downloads
    • Audio Packs
    • BGM
    • BGS
    • ME
    • SE
  • Tools & Utilities
  • Misc. Downloads
  • Eventing Systems/Tutorials

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Steam Profile


Website URL


Skype


Facebook


Location


Interests


Other Skills


Project(s)


Referer


Google Plus Profile

Found 5 results

  1. Terrain Tags By: Polraudio Welcome to the Terrain Tag Tutorial. This tutorial is to teach you all the useful things you can do with the Terrain Tags. Few things I will be covering in this tutorial is healing tiles, damaging tiles. STEP 1: Tileset Editor First lets set some terrain tags in the tileset editor. For this demonstration we will be using the grass and the rocks. Open your database and go to tilesets and the Grassland tileset then click on Terrain Tag. Set the Rocks for 1 and the Grass for 2 like the example below. We are going to use rocks to damage the player and the grass to heal the player. Hit ok on the database to ensure the tags are set. The next step will be to make the event to track what terrain tag the player is currently on and heal or damage the player. STEP 2: The Event Make a new event without a graphic and set the Trigger to Parallel Process. Create a control variables event and name it something like Terrain Tag. Set the Operand to Character, Player's, Terrain Tag. So it should look like this. Now we want to setup how the rocks and grass interact with the player. Create a Conditional Branch right under the Variable you just made. Set it to Variable and the variable you just made. Set it to Equal to and Constant 1. So it should look like this. If you remember from the tileset we set the terrain tag of rocks to 1. When the player is on the rocks the terrain tag will be set to 1 and when the player is over the grass it will be set to 2. Now we will make the part where it hurts the player when they are on the rocks. Note: i will hurt the player as long as they are on the rocks. Even when not moving. Right in the conditional branch above else we will want to make it so it hurts the player. Go to page 3 and Change HP .... Here you can set it to harm or heal the player but in this case we want to hurt the whole party so click on Decrease then set the operand to constant and whatever number you want. i will be using 50 for this example. So it should look like this. Now you can play test and enjoy. But wait... Something's wrong my party dies almost instantly. Why is that? The problem is because we forgot to set a wait time after each time the players party gets hurt so they get hurt 40 times a second because rpg maker xp runs at 40 frames a second. To fix this we will need to add a wait after the party gets hurt. After the change hp command add a wait for 40 frames. Why 40 frames? Cause rpg maker xp runs at 40 frames a second so they will only be getting hurt every second instead of 40 times a second. Now as you noticed after play testing again everything's working right except you have no clue when your getting hurt. To fix that add a screen flash right above the wait command. On the 2nd page click Screen Flash .... Set the sliders for green and blue to 0 while keeping red at 255 and strength at 255. Set the time for 2 frames. Any lower than 2 frames and it will not show sometimes cause rpg maker xp is not a constant 40 frames per second and sometimes is 39 frames per second so it will be skipped sometimes unless you have it set to 2 frames. So it should look like this. Now that we got the screen flashing we also need to make a noise when the party gets hit. It doesn't matter where you place it as long as its before the wait command. Make a play se ... command and set it for whatever sound you want. After everything's done your event should look like this. Congratulations you now know how to make a hurting and a healing event using terrain tags without using tons of events to get the same effect. Now your saying to yourself "But... we didn't go over healing the player!" but we did go over healing the player. It may not seem like we did but we did. To make it heal is the same way as making it hurt except we use change the variable, set it to increase party HP, change the screen flash to blue and change the sound. I will show you how to add healing in the pic below. Download: http://www.gdunlimit...in-tags-521.zip Hope you enjoyed this little tutorial and as always. Thanks for reading :D. If you want to request an event tutorial for me to do with rpg maker(any version) just shoot me a private message. Note: This tutorial is a GDU exclusive and shouldn't be posted anywhere else!
  2. I'm not quite sure where to put this so if this is in the wrong place, please move it. Anyway, since I haven't been able to use RMXP I've been making some characters. As for facesets, I'm usually fine with using face maker but for main characters I like to edit the face sets using paint.net (which can be downloaded for free from here: http://www.getpaint.net/download.html ) to give them more personality and set them apart from the NPC's. The way I edit them doesn't take much skill either. So, I thought I'd give a tutorial on how I go about editing a character with paint.net. How to edit eyes: How to edit eyes onto a face set: Forward Facing Face: Face that's at an angle: Face Profile: I'll add a tutorial on editing hair and skin soon.
  3. Version RMXP

    75 downloads

    A condition tutorial i made for scotty.. There is no screenshot for a moment.. Sorry
  4. This is mainly a reposting of my blog entries. You can find my blog here: http://www.rmxpunlim...llessdees-blog/ kellessdee here, I have been teetering on verge of writing a full tutorial on ruby scripting for a while, and have had difficulty deciding how to tie this into learning RGSS as well. In the end, I decided that one should not skip out on thoroughly learning Ruby prior to jumping into RPG Maker scripting. Ruby has a lot to offer, and I feel a lot of people try to jump too far ahead, jumping right into RGSS. While I understand the feeling of wanting to learn something NOW, but if you really take the time to learn, you'll find there are a great number of resources available in Ruby's core library that can aid in RPG Maker development greatly. I have decided that I am going to do this tutorial as a series of mini-tutorials, releasing one per week. This tutorial will be categorized into "lessons." In each lesson, I will first go over the topic of that lesson (mixing in some examples and demonstrations - to try and balance theory and practical application) and I will try to finish off with a few practice problems (where possible/applicable). In the following lesson, I will touch on any practice problems I presented. These tutorials are going to be geared towards someone with no programming background, although if you do have some kind of programming background (even RPG Maker XP eventing knowledge helps!) it will help greatly. However, it is not necessary. The lesson plan will be outlined in the table of contents entry (next entry), and I will use that entry to post links to each lesson that has been released. Please note, that this plan is subject to change. I do not claim to be a ruby expert, however, I do feel that I know enough about it to attempt to teach it. If you need me to elaborate on something, leave a comment and I will try to answer your question to the best of my ability. Likewise, if you feel I am wrong about something, feel free to correct me in the comments as well. I am only human, so by posting any errors I make will help improve the quality of these lessons for everyone. As always, if you have any questions or concerns, feel free to leave a comment, send me a PM, or email: kellessdee@gmail.com Learning Ruby - Table of Contents Lesson 1: Installing Ruby http://www.rmxpunlim...by-environment/ Lesson 2: Objects, Objects, Objects aka Ruby Data Types http://www.rmxpunlim...bys-data-types/ Lesson 3: Arithmetic Operators http://www.rmxpunlim...etic-operators/ Lesson 4: Variables, User Input and Type Conversion http://www.rmxpunlim...ype-conversion/ Lesson 5: Intro to Boolean Logic http://www.rmxpunlimited.net/forums/blog/72/entry-271-lesson-5-intro-to-boolean-logic/ Lesson 6: Flow Control - Decision Making http://www.rmxpunlimited.net/forums/blog/72/entry-272-lesson-6-flow-control-decision-making/ Lesson 7: Flow Control - Looping http://www.rmxpunlimited.net/forums/blog/72/entry-281-lesson-7-flow-control-looping/ Lesson 8: Ruby Objects In-Depth Lesson 8a: Strings to be released Lesson 8b: Arrays and Hashes to be released Lesson 8c: Structs to be released Lesson 9: Methods Lesson 10: Classes Lesson 11: Modules Lesson 12: Error Handling - Raise, Rescue Lesson 13: Advanced Flow Control - Throw, Catch Lesson 1: Setting up a Ruby Environment In these lessons, I will be working with the official Ruby interpreter. However, if you'd rather work through RPG Maker, that is definitely possible and for that reason, I will tell you how to do both. Personally, I think everyone interested in really getting into Ruby (whether for use in RPG Maker or not) should get the official interpreter. This will allow you to quickly test code outside of an RPG Maker environment, as well as the interpreter comes with a interactive ruby shell, so you can test code in a live environment, without even having to write a script first. **I will use these notes for little "asides" that I have throughout the lessons. These will contain information that is not necessary in the learning process, and for the most part be more "techy" stuff. Ruby: The Ruby Way Windows Users Linux Users Ruby: The RPG Maker Way And voila! We have a working ruby environment. Ruby is, as you may know or have noticed, an interpreted language. In programming, there are two main types of languages - compiled and interpreted. What does this mean? Well, computers-as you may know-are inherently stupid. In actuality, they really only understand machine code (which is essentially numeric instructions). However, it would quite a headache to try and code in say, strictly binary or hexadecimal so, programming languages were invented. However, in order for the computer to understand these languages, the code must first be translated into machine code before the computer can understand it. Compiled languages mean the code is translated into machine code, then stored for later execution. Interpreted languages are compiled real-time (each line is translated or interpreted into machine code and executed on run-time). So, this means compiled languages (naturally) are much, much faster than interpreted languages. However, with an interpreted language, one has room for a much higher level of abstraction and allow for much more dynamic code (ex. changing an objects functionality during run-time). This also means faster development. As you can see, each have their ups and downs Wait, that hardly seemed like a lesson.... Oh, I forgot to mention, this week you get a few small lessons to begin your journey into ruby I will provide you with enough to get you thinking and prepared for next week. Lesson 2: Objects, Objects, Objects aka Ruby's Data Types You've probably heard people talk about "object-oriented" languages or programming (and you may even know what this means already). Well then, what is an object-oriented language? It simply refers to a programming language that is based around the object model and it's concepts. So, it's probably better to start at: What is an object? Well, this may seem cheesy, but: ob·ject/'äbj?kt/ Noun: A material thing that can be seen and touched. (google search) So how does this apply to computers? Now, you may have gone ahead and googled the answer for yourself (if you did, I applaud you for doing so. Never forget that google can be the best resource if ever get stuck.), but I'll try to explain nonetheless. So, obviously, in programming, objects are not a material thing. We need to look at what an object is, in a more abstract/conceptual manner. Let's focus on this: An object is anything that can be seen or touched. An Object can be seen. If something can be seen, it would be safe to say it could be described as well, no? Well, in order to describe something, one usually lists off certain/unique characteristics or properties. An Object can be touched. If an object can be touched, that means something can be done with that object. So, in programming, an object is simply a structure that has properties or attributes, and carries some kind of functionality-it can do things. The object model and it's applications will make more sense as we progress; but I felt that since technically everything in Ruby is an object, and that I would be throwing the word around a lot, it would only be fair to give you some idea on at least what an object is. So, when I say everything in ruby is an object, I mean everything in ruby is a data structure with attributes and methods (functions, it can do something). With that in mind, I'd like to go over some of ruby's core data types. Integers Integers are simply whole numbers: -1 0 1 2 3 999 Floats Floats are decimal point numbers: -0.5 0.1 5.985 Strings Strings are any kind and any number of characters: "hello, world!" "this is a string" "&^$123" Boolean You can think of a boolean as a switch, with only 2 possible values: on or off. These values are represented by the ruby keywords: true false Nil Nil is a special data type, it is actually a representation of no value, or nothing. This value (or lack there of) is represented by the ruby keyword: nil if you have a background in another programming language, you probably have encountered the data type "null." In ruby, nil is conceptually the same as null. I will touch on more as we progress, but this should be enough for now. I promise, in the next lesson we will actually write some code. Lesson 3: Arithmetic Operators Arithmetic Operations are going to be the first methods you learn about in these lessons. Just like the name implies, arithmetic operations are simple mathematical operations: adding, subtracting, multiplying, dividing, etc. These are method calls that can be invoked on various data types (mainly numeric types, like floats or integers) Ruby Arithmetic Operators + Addition - Subtraction / Division * Multiplication % Modulus ** Exponents Okay, time to put these to use! Open up a command prompt, and type irb IF YOU OPTED OUT OF INSTALLING RUBY, SIMPLY PUT MY EXAMPLES INTO THE SCRIPT EDITOR AND ADD p BEFORE EACH EXAMPLE AND TEST PLAY (if you added foreverZer0's console script, you can use puts instead of p) irb is that interactive Ruby shell I was talking about earlier If Ruby was installed correctly, you should get a new prompt that looks like this: irb(main):001:0> Let's try some out. irb(main):001:0> 1 + 1 => 2 1 + 1 = 2. Good, it seems to be working correctly. Now, you can use irb as a calculator! Let's play around with this a bit! The best way to learn (IMO) is to experiment on your own. So feel free to try different operations than me. irb(main):002:0> 10000+250 => 10250 irb(main):003:0> 10 * 100 => 1000 irb(main):004:0> 100 / 10 => 10 irb(main):005:0> 30 - 100 => -70 irb(main):006:0> 10.5 + 0.777 => 11.277 irb(main):007:0> 10 + 10 * 2 => 30 Now, wait a second... 10 + 10 = 20, 20 * 2 = 40... How come 30? You probably already guessed it...but, remember bedmas or order of precedence? That's right, bedmas applies to programming as well. Let me refresh your memory: 1. Brackets 2. Exponents 3. Division 4. Multiplication 5. Addition 6. Subtraction So, it would be interpreted as 10 * 2 = 20, 20 + 10 = 30. Now what if we want ruby to read it the other way? Well, brackets work here too: irb(main):008:0> (10 + 10) * 2 => 40 How about this? irb(main):009:0> 3 / 2 => 1 Wait, 3 divided by 2 is NOT 1. Here is a little quirk you need to know about programming: Integer numbers and Floating point numbers are 2 distinct numeric types. They can be used together (adding, dividing, etc), however, if you divide and integer by an integer, you will ALWAYS get an integer back. irb(main):010:0> 3 / 2.0 => 1.5 So what does this mean? Well, if operate between integers and floats, you should know that you will always get back a float. Operating with just integers will send back integers, and of course, floats if you are operating with just floats. irb(main):011:0> 1.5+1 => 2.5 irb(main):012:0> 1.02 * 5 => 5.1 What about modulus? You may know what modulus is, but just in case: Modulus is a form a division (therefore, it falls into the same area of precedence as multiplication and division). How it works, is modulus divides 2 numbers and returns the remainder. I included the division operation in these examples, to help give you a full understanding of how it works: irb(main):001:0> 3 / 2 => 1 irb(main):002:0> 3 % 2 => 1 2 goes into 3: 1 time, with 1 leftover irb(main):003:0> 1 / 1 => 1 irb(main):004:0> 1 % 1 => 0 1 goes into 1: 1 time, with 0 leftover irb(main):005:0> 1 / 5 => 0 irb(main):006:0> 1 % 5 => 1 5 goes into 1: 0 times, with 1 leftover What happens when you add strings together? Or multiply them with integers? irb(main):008:0> "hello" + ", world!" => "hello, world!" irb(main):009:0> "*" * 25 => "*************************" Lesson 4: Variables, User Input and Type Conversion So, upto this point, we have only been working with literal values. A literal value, is a static value; hardcoded by the programmer. For example: 1 2 10.5 "String" are all literals. But, what if you aren't sure what the final value should be? Or if the value is chosen by the user? Well, as you may know, we have variables to do that. Variables are the programmers direct access to a computer's memory (RAM). Any object can be stored in variables for later use, or for whatever reason storing an object in memory may be. Anyways, let's try it on for size: irb(main):001:0> variable = 10 => 10 irb(main):002:0> puts variable 10 => nil Yup, it's almost that simple. variable_name = value value can be anything from a literal value to a method that returns a value to even another variable. Now, that was the simple part. The not so simple part (but still quite simple) are variable naming rules. variables, by rule, MUST start with a lowercase letter or underscore, and can contain letters, numbers and underscores. Also, you should know that variables cannot share the same name as ANY ruby keyword or reserved word. Ruby keywords are as follows: alias and BEGIN begin break case class def defined? do else elsif END end ensure false for if in module next nil not or redo rescue retry return self super then true undef unless until when while yield there are some exceptions to these rules, however to avoid confusion, we will go over these exceptions later. (There are however, NO exceptions to using keywords as variable names) Another thing that you should know about variables, is that although you can name a variable anything you would like; it is much better practice to give variables distinct, meaningful names. This however, is called coding convention--it is not necessary to run a program correctly, however it makes the code MUCH easier to read, and so you don't forget what each variable is later down the road. Another coding convention, is the style we use to write out our variables. The two most popular types are camel casing and snake casing. A camel-cased variable name would begin with a lowercase letter, and any sequential words begin with a capital: thisIsACamelCasedVariableName = nil A snake-cased variable name (which you will find much more popular in the ruby community) Snake casing means each word is separated by an underscore `_`: this_is_a_snake_cased_variable_name = nil Whichever way you prefer is upto you. I personally find snake casing easier to read, and all my lessons will reflect that convention. Note that it is good practice to choose a neat and consistent style. Now, back to the actual coding. So, you should understand the basic concept of what an object is, but what does this mean for programming? Well, as I said, everything is an object in ruby. To use an object, we must first create an instance of an object type. Whenever you store something in a variable, you are essentially storing an instance of an object in memory to be called upon and used. So, let's look at this example: variable = 10 What we are doing here, is creating an instance of the Fixnum object (which is an integer type), which is initialized to have the value 10, and storing it into the variable called `variable.` This means, you can now call any method or function belonging to the Fixnum object. irb(main):001:0> variable = 10 => 10 irb(main):002:0> variable.to_s => "10" Whoa, what happened here? What I have done here, is called the `to_s` method from variable. To call methods/attributes from a variable (or any instance of an object) in ruby, we use what is called "dot notation" object_instance dot method/attribute name. The method then returns a value (as defined by the method, in this case a string). What I mean by the method "returning a value" is that whenever a line of code is executed it sends back a value to the program. In this case, we didn't do anything with that value, but if we wanted to, we could store that value in another variable: other_variable = variable.to_s and in case you were wondering, to_s is simply a method that returns a string representation of the object that to_s was called from (all objects have this method) (to_s means "to string") The concept of converting objects in Ruby is called coercing. In other languages, this term is known as "casting" or "parsing"(in terms of extracting data types from strings) There are many different methods for converting data types, one more I will teach you, is the to_i method. irb(main):001 > "5".to_i => 5 irb(main):002 > "5".to_i + 10 => 15 irb(main):003 > "hello".to_i => 0 The to_i method attempts to convert the object to an integer. In this case, an integer is extracted from a string. Alright, with that said let's make our first script! Open up a command prompt, and create a folder for our scripts: Windows: C:\> mkdir learnruby C:\> cd learnruby C:\> notepad hello.rb Linux: ~$ mkdir learnruby ~$ cd learnruby ~$ vi hello.rb Of course, you can use any text editor that you like, it just so happens that these two editors ship with windows/linux. Now, enter this code: # The obligatory Hello, world program puts("Hello, world!") Now, let's test it out. Save the code, head back to the prompt/terminal and enter: ruby hello.rb This invokes the ruby interpreter on `hello.rb` (The script we made) If everything went well we should see: ruby hello.rb Hello, world! As you should know, puts writes text to the screen (or standard output) # The obligatory Hello, world program This however, is a comment. Any line preceded by a pound sign `#` will be ignored by the interpreter. Comments are like little signs to either help you or other programmers understand what you are doing. For long comments, you can do a `block comment` =begin Anything between the begin and end is one large comment =end Alright, well that was fairly anti-climatic. Let's make this program a little more interesting. Let's make a greeting program, that will take the user's name, then display a personalized greeting. First, I will teach you how to get input from the user. gets gets is a function that, when called, gets a string from the standard input (from the user). # First we will need to get a name from the user # We should store that name in a variable, for later use name = gets gets always returns a string, so we can take that value and store it in a variable. Now, that we have the name, we need to display the greeting. There are a couple of ways we can do this. The first way: concatenating strings If you remember, earlier we tried adding strings together: "Hello," + " World!" This is called concatenation, and it works the same way with variables that hold a string: "Hello, " + name + "!" And of course, we can pass that to puts: # Display our personalized greeting puts("Hello, " + name + "!") Another way we can do this is: "Hello, #{name}!" This is called embedded expressions. This tells the interpreter to take the value of the expression within the `#{}` and call its to_s method and place it within the string. You can use any kind of expression, such as addition, subtraction and even call methods from within those tags. It is important however, to know that the `#{}` is only available in strings defined with the double-quotes `""`, strings defined with single-quotes `''` will interpret the #{name} literally and display #{name}. So, this will be our new hello.rb script: # Prompt the user for input puts("Please enter your name:") # Get user's name name = gets # Display personalized greeting puts("Hello, #{name}!") Alright, let's call the ruby interpreter on this script again: ruby hello.rb Please enter you name: kellessdee Hello, kellessdee ! Wait a minute, why is that explanation mark on a different line than the greeting? Well, allow me to explain. Like its counterpart puts, which prints a new-line after the string, gets also reads in the new line character. So how do we get rid of it? The simplest way, would be to invoke the "strip" method on the string: puts("Hello, #{name.strip}") Now lets try it: ruby hello.rb Please enter you name: kellessdee Hello, kellessdee! Ah, much better. We are almost finished with this lesson. This was probably a lot more to take in than the previous lessons, so let it soak in, play around with everything I have given you. Before I let you go however, I would like to mention a few other things: I was talking about a "new-line character" earlier, now you may not have gave it much thought, but I would like to point this out. With computers, to represent certain characters (such as backspaces, tabs, returns, etc) it uses a different kind of symbol. For example, the New-line escape character is: "\n" If you put this in a puts, irb(main):001 > puts "Hello,\nWorld!" Hello, World! => nil you can see that the interpreter puts the rest of the string on a new line. This can be useful when, say, building a long multi-line string, etc. Other escape characters include: \t tab \s space \b backspace \\ backslash \" double quote \' single quote (only used within single-quote strings) It is important to note, that like the `#{}` escape characters only work within `""` (except for the case of `\'`) strings. In `''` strings, they will be interpreted literally. I suggest you test this out, to see what I mean. Coding Challenge: 1. Write a script, that takes two numbers from the users, and performs some kind of mathematic operation on them. 2. Write a script, that takes the users first and last name, and creates an e-mail address for them, in the format: lastname.firstname@pretendwebsite.extension firstname should be the user's inputted first name lastname should be the user's inputted last name pretendwebsite.extension can be any website name you wish Last, but not least: If you wish to learn more about the avaible objects and methods ruby provides, visit: http://www.ruby-doc.org/core-1.9.3/ This is the english documentation for the ruby api. Here it describes all of ruby's built-in objects and describes all of their methods. Please note that "classes" are a term for objects that can be created. If you don't know what that means, do not worry for now, I will explain that later. For now, you should explore the String class and the Numeric class. It will give you all the actions that can be performed on those objects, and it will give you a feel for the ruby documentation. I promise, one day it will be your best friend. Finally, don't let me stop you from learning from other places on your own if you wish to do so. In fact, if you really want to learn ruby, I ENCOURAGE you to do so. Additional Content Lesson 5: Intro to Boolean Logic You may remember from Lesson 2 (Data types) the "Boolean" data type. If you don't, that's okay; we didn't do much with them. But after this lesson, I promise: you will be on your way to becoming a boolean master. Money back guarantee! (yes, I do know you aren't paying anything for this...MUAHAHAHA!!! err, ahem..) So, like I mentioned before, a boolean is either "true" or "false" in ruby. Really though, all a boolean is, is a representation of two possible values: true or false, on or off, 0 or 1, etc. For you RPG Maker users, you might notice a boolean is quite similar to a switch. In fact, they are the same thing. Fun Fact: In older, and more lower-level languages (ex. C) boolean types actually do not exist, and rather than being represented by an abstract "true" or "false," booleans were represented by integers: 0 or 1. Additionally, to show where this comes from, computers at the lowest level, really only understand binary (0s and 1s), a single Binary Digit (or bit) is either 1 (on) or 0(off). So, how are booleans useful? Well, as you will learn, booleans and boolean logic is very useful in determining a program's state and can be used in decision making. However, before we get into that, I would like you to know how boolean logic works. I apologize that this lesson will be a little more conceptual than the previous lesson, but it is necessary you understand boolean logic before we begin the next lesson. If you can master boolean logic, you will be ahead of the game. So, let's begin. Now, we know that a boolean represents two values: true and false. But where do these values come from? First, we must look at boolean expressions, expression that generate a boolean value. You can think of a boolean expression, almost like a question, or more specifically: a boolean question. A question could be: "How are you today?" "What is your name?" These questions, however, could have many answers. A boolean question, would ask something more specific: "Are you 18 years of age?" "Do you own a computer?" "Is your name Kellessdee?" These questions, although in real life we may answer these in different ways, ultimately are looking for one answer, either "yes" or "no." But how do we ask these kinds of questions in ruby? Well, in programming, rather than looking at the question as a whole, you have to look at what data is really being tested. "Is age equal to 18?" "Is number of computers greater than 0?" "Is name equal to 'Kellessdee'?" While computers are terrible at interpreting human language, computers are REALLY good at comparing data or values. To write these comparisons into a program, the language in question will provide us with various comparative operators. We can create boolean expressions with these operators, which will evaluate to boolean values. In ruby's case: > - Greater than >= - Greater than or equal to < - Less than <= - Less than or equal to == - Equal to != - Not equal to There are other ruby comparison operators, however those are usually special operators, and I will explain them in later lessons You can use these operators with nearly any object. Some of these may behave differently depending on the object, and for now I will only go over Numeric values and String values. So back on those previous questions; how might we represent them in ruby? irb(main):001 > age = 18 => 18 irb(main):002 > age == 18 => true irb(main):003 > number_of_computers = 0 => 0 irb(main):004 > number_of_computers > 0 => false irb(main):005 > name = 'kellessdee' => "kellessdee" irb(main):006 > name == 'Kellessdee' => false So, as you can see, we use a variable to store the value, and we can compare that value based on the question we are asking. You do not need to use a variable, and can compare literal values: irb(main):007 > "hello" == "hello" => true However, you should never do this. There is no sense in using the computer's resources to compare values that are already known to the programmer. We will use variables, to simulate a value that could be any value You might be wondering why the last expression evaluated to false. Well, as you may have known or guessed by now, when comparing strings, ruby compares each character and if all are equal, then the string is equal. Each character is actually represented by an integer (ASCII value), and thus, 'k' and 'K' are not the same. Luckily, ruby strings have a useful method we can use to get around this - string.upcase and string.downcase These methods convert each character in a string to it's upper-case or lower-case equivalent, and returns the new string. So, if you wanted to check the equality of two strings, but not depend on the case: irb(main):008 > name = "KeLlEsSdEe" => "KeLlEsSdEe" irb(main):009 > name.downcase == "kellessdee" => true or irb(main):010 > name = "KELLESSDEE" => "KELLESSDEE" irb(main):011 > other = "kellessdee" => "kellessdee" irb(main):012 > name.downcase == other.downcase => true irb(main):013 > name.upcase == other.upcase => true Another thing to remember about comparing strings, if you use the >, >=, <, <= to compare strings, ruby will compare the LENGTH (number of characters) of the two strings. irb(main):017 > "one" < "three" => true "one" is 3 characters, and "three" is 5 characters: 3 < 5 == true A few other tips to keep in mind: Be careful with > and >= or < and <= when two values are compared with >= or <=, if they are equal, the expression will return true. With < or >, if they are equal the expression will return false. So there we have it. We can now ask ruby simple questions, and receive boolean answers. Now, for the hard part. What if we want to ask ruby a more complex question? "Is your name kellessdee and are you over 18?" In reality, this is two questions. However, there is still only one answer. Yes or No. In my case, my name is kellessdee (well, username teehee) and I am 22, which means I am over 18. So, I would answer yes. Easy enough for us to simply process...but what about a computer? Well, think about it this way. There are actually two individual questions, with individual answers: name == kellessdee? Yes. age > 18? Yes. So really, the answer is Yes and yes. or true and true. So, we could make two separate comparisons, and go from there, or we could use ruby's (conveniently) built-in "logical" operators. They are: && - logical AND || - logical OR ! - logical NOT and - logical AND or - logical OR not - logical NOT So you have a couple options here to join simple boolean expressions, to form complex boolean expressions. Most RPG Maker scripts use the English versions "and" "or" and "not". Because of this, and that these versions are easier to read, I will teach you with the English versions. Due to the way ruby handles the order of precedence, "and" "or" and "not" actually do not behave the same way as "&&" "||" and "!". In order of precedence, ! > && > ||, like it should be...however, not = and = or. The English operators have the same precedence in ruby. To be safe, always use parentheses to group your expressions in the order you want them to be evaluated. I will follow this tactic in my lessons. If you are comfortable with &&, ||, !; I would advise to use this form, as they work how they should. AND and returns true if all expressions are true, otherwise returns false irb(main):018 > true and true => true irb(main):019 > true and false => false irb(main):020 > false and false => false OR or returns true if one expression is true, and false only if all expressions are false irb(main):021 > true or true => true irb(main):022 > true or false => true irb(main):023 > false or false => false NOT not is special, it is a unary operator (meaning it only operates on one value), and simply inverses the result of the expression or returns the opposite. irb(main):024 > not true => false irb(main):025 > not false => true So, lets try the complex question again: irb(main):026 > name = "Kellessdee" => "Kellessdee" irb(main):027 > age = 22 => 22 irb(main):028 > (age > 18) and (name.downcase == "kellessdee") => true And that, is the basics of boolean logic. Now, the problem with this, is it's one thing to explain and read about boolean logic, but it is harder to practice. It will be easier to understand once we apply it to decision-making, but for now, I would like to leave you with some practice questions (try to get the answer without putting these into IRB or a script). 1. true or (false and (true and false)) ANSWER 2. false and (true or false) ANSWER 3. false or (true and false) or (true and (false or (true and (false or false)))) ANSWER 4. (true or (false and true) or false) and (true or (false and false)) ANSWER 5. (true and (true or false)) and (true or (true and (true and (false or false))) or true ANSWER Quick Technical Info on and/or One thing every programmer should know about and, or; is that they are what we would refer to as "short-circuiting." If you may have noticed, with and, if any of the expressions are FALSE the entire expression will be false. With or on the other hand, if any expression is TRUE, the entire expression will be true. Therefore, the ruby interpreter will evaluate the expressions, from left to right - if it finds an OR expression and hits a true, it will stop evaluating that expression - it already knows the entire expression will be true. Same goes for AND...when it hits a false value, it will stop evaluating because it knows the entire expression will be false. With that in mind, with any complex AND expression - you should test the values MOST likely to be false first (false most of the time) and with any complex OR expression - you should test the values MOST likely to be true first (true most of time) Lesson 6: Flow Control - Decision Making In the previous lesson, I taught you about boolean logic. Hopefully, you have a good basis to the concept. This lesson will actually put that logic to good, practical use. This lesson is the first part in the series on Flow Control. Now, for the obligatory "What is flow control...?" At this point, all your programs have had a very basic flow, just execute each line, one by one. However, when you start making real applications/programs, you'll find that this one directional program flow is too simple for your application. This is where flow control comes in, we want to be able to control the flow of the program. The most basic form of flow control is decision making. In programming, decision making is possible through the use of `if` statements. An if statement is what we use to make our boolean expressions do something. "if this, then do that." So, in ruby... if # What we want to do end where is an expression. note that an if statement must be closed with the "end" keyword. The code we embed within the "if clause" or "if statement" is tabbed, or by ruby's conventions, 2 spaces from the left margin. This is not necessary for the code to run, but as a coding convention this makes your code much easier to read and understand. What happens when the Ruby interpreter reaches an if statement? The interpreter will first evaluate , if evaluates to true, the code inside the statement will be executed. If the is false, the code inside the statement will be ignored, and the interpreter will continue from the line with "end" What about this? if 1 puts "1 is true" end If you were to run this code, the output would be: 1 is true But why? 1 is not a boolean! Well, this is because of how ruby handles boolean expressions. When the interpreter gets to the "if ..." it assumes the expression to be a boolean expression, and with ruby, anything except nil and false is interpreted as true, and nil and false interpreted as false. So, when the interpreter gets to "if 1", it evaluates the expression, in this case 1 returns 1, and since the value is not nil and not false (1), the code within the if statement is executed. So, let's try an example. I want you to create a script this time, call it "age.rb" So let's do some decision handling. We are going to make a program that takes the user's age, and tells them if they can buy alcohol. In Canada, where I live, you need to be 19 or older. You can incorporate your local age limit for drinking into the program if you'd like. # Prompt the user to enter their age # we use print as that does not append a new line character print ("Enter your age: ") # Now we should get the users age # and convert to an integer: age = gets.to_i # Lets see if the user is old enough if (age >= 19) # They are of age! puts ("You are old enough to buy alcohol.") end So, why not try it out! ruby age.rb Upon running your script, you will notice, unless you enter 19 or greater, the script will just end. Only if you enter age greater than or equal to 19, you will get "You are old enough to buy alcohol." Well, we should let the user know if they aren't old enough to buy alcohol as well...and hey, why not let them know how many more years until they can? The next part of the "if" statement, is the "else" clause. if # Code if condition true else # Code if condition not true end The block of code in the "else" clause will only be executed if the original block or any other block within the if statement is NOT executed. In this case, if the is false, the first block will not be executed. Because of this, the second block under "else" will be executed instead. if (age >= 19) # They are of age! puts ("You are old enough to buy alcohol.") else # They are not of age! years_left = 19 - age # How many years until they can buy alcohol puts ("You are not old enough. Come back in #{years_left} years!") end If you add that to your age.rb script, you will notice if you enter an age less than 19, the program will print out "You are not old enough. Come back in X years!" So now, you can test a value, and can act based upon whether or not that test is true. But, what if we want to act depending on several possibilities? This is where "elsif" come into play. The "elsif" clause allows us to create multi-sided responses, based on multiple conditions. if # Code elsif # Code else # Code end The ruby interpreter will first enter the if statement at "if ," if that condition is true, it will execute the following block of code, then jump to the "end." If that condition is false, the interpreter will then move to the first "elsif ." If that condition is true, the interpreter will execute the block of code within the elsif clause, then jump to the "end." If false, the interpreter will continuously check any following "elsif" and if none are true, finally the "else" block will be executed instead. So, this means you could have any arbitrary number of elsifs: if # Code elsif # Code elsif # Code elsif # Code else # Code end With the if statement, you can have as many elsif clauses as you'd like, however you can only have ONE if clause, and ONE else clause. You should also know, that the else clause is optional, whereas the if clause is NOT optional Be careful, if you have programmed in other languages, you may notice that the "elsif" equivalent may be represented differently, ex. else if © or elif (python), in ruby it is "elsif" So, why might you need to test multiple conditions? Well, let's try this example: Let's pretend we want to make a guessing game. The Game will have a set number, and the user will try to guess which number is set. If they guess too low, the program will say: "Too low!" and if the number is too high, the program will say: "Too high!", and if the number is equal, the computer will say "Wow! You got it!" We will not be making this guessing game fully functional just yet, in a real guessing game, you'd want the number to be different each time, and probably want the program to run until the user quits. We will finish this game in later lessons So, how would we do this? # Set a number to guess number = 10 # Prompt the user to guess what number it is: print ("I am thinking of a number. What is it? ") # Get the guess guess = gets.to_i if guess < number puts ("Too low!") elsif guess > number puts ("Too high!") else puts ("Wow! You got it!") end Try putting this in a script called "guessinggame.rb" and running it. As you may have noticed, the if statement could have also been written like this: if guess < number elsif guess > number elsif guess == number end This would work exactly the same. However, I chose to catch that in an else clause, as we know that if guess is NOT less than number, and NOT greater than number, it HAS to be equal to number. So, it would be more efficient to group that code under an else clause. In order to determine whether to execute a block under an if/elsif, the interpreter has to execute and evaluate the condition. With else, that condition is not executed, saving us some CPU processing. Let's try another example. Let's make a program that gets the current month as a number, and prints out the English name of that month. # Get month: prints ("Please enter the current month as a number: ") month = gets.to_i if month == 1 puts ("January") elsif month == 2 puts ("February") elsif month == 3 puts ("March") elsif month == 4 puts ("April") elsif month == 5 puts ("May") elsif month == 6 puts ("June") elsif month == 7 puts ("July") elsif month == 8 puts ("August") elsif month == 9 puts ("September") elsif month == 10 puts ("October") elsif month == 11 puts ("November") elsif month == 12 puts ("December") end Whew, that was a lot of work. It works, but that seems like an awful a lot for a simple translation. As you can see, in some cases you may want to test for a specific value, and each value could represent something specific. Well, thankfully, ruby has a much more elegant way of doing this, with "switch" or "case" statements. case when value then #code when value then #code when value then #code else #code end So how does this work? The case statement takes then tests that variable against each value, testing if they are equal to each other. The first value that matches, it's corresponding code is executed. You can have an arbitrary number of when clauses, and else works exactly like in if. If no other values are equal to then else will be executed. Like in the if statements, else is optional here as well. The "then" part of "when value then" is optional, as long as you have the block of code on a new line. when value # Code must be here However, with the "then" portion, you can actually put the block on the same line: when value then # Code could be here Also, I would like to point out that the "else" portion SHOULD NEVER have a "then," if you want to put the else block on the same line, use a semi-colon ( (ruby interprets this as a line terminator) else; # Code could be here So, lets fix our nasty if statement: case month when 1 then puts ("January") when 2 then puts ("February") when 3 then puts ("March") when 4 then puts ("April") when 5 then puts ("May") when 6 then puts ("June") when 7 then puts ("July") when 8 then puts ("August") when 9 then puts ("September") when 10 then puts ("October") when 11 then puts ("November") when 12 then puts ("December") end Well, that looks much neater. It's still long, but neater and a little less typing. However, I feel that the output is too "hard coded." What if later, we decide we want to put the month into a variable, for later usage? We'd have to change each "puts" to "variable =." With modern IDEs, this would be a simple task, but still unnecessary. One major rule of the ruby community (or even any programming community) is "Don't Repeat Yourself", and I feel both "puts" or "variable =" that many times, is repeating yourself. Conveniently, we can get around this. Remember how everything in ruby is an object? And every expression returns an object? Well, case is no different. case will "return" (or send back what the block returns) whichever block of code passes the test. In this case, it sends back "puts ("month")". Well, as you may know, the line of code "string" will return a string object, with the value "string." So what about this: puts case month when 1 then "January" when 2 then "February" when 3 then "March" when 4 then "April" when 5 then "May" when 6 then "June" when 7 then "July" when 8 then "August" when 9 then "September" when 10 then "October" when 11 then "November" when 12 then "December" end Now, that, is much neater. Normally, we would want to put the block of code in a when ... clause on the next line, but in the case where we are simply returning a single string, I find it actually more readable like this. Then, if we wanted to change it to store the month in a variable: # Get month prints ("Please enter the current month as a number: ") month_no = gets.to_i month_word = case month when 1 then "January" when 2 then "February" when 3 then "March" when 4 then "April" when 5 then "May" when 6 then "June" when 7 then "July" when 8 then "August" when 9 then "September" when 10 then "October" when 11 then "November" when 12 then "December" end puts ("The month is #{month_word}.") Now we only had to change one line of code, rather than 12 lines of code. You'll probably find yourself using "if" statements MUCH more than case/switch statements; however for certain things, especially menus (where you have several choices, and the current choice is stored in a single variable) case statements are much easier to employ. The case/switch statement is mainly used to test a single variable against multiple different values, however it IS possible to use it like an if...elsif statement: case when variable == 5 when other_variable < 5 end However, this isn't often used, as if...elsif would be preferred in this case. The case/switch statement uses the === operator to test the variable against when value rather than the == operator. For the most part, === works EXACTLY like ==. The reason for this is so one can define their own object's "case" behavior. I will explain how one can take advantage of this in later lessons; so do not worry about it for now. I just wanted to give you a heads up, in case you might be learning with other tutorials as well. One last thing I would like to teach you, is the "conditional assignment operator." As you start writing your own programs, you may find yourself in a situation where you only wish to assign a variable a certain value, depending on one condition, otherwise, set it to something else. This is called conditional assignment. For example, what if we want the absolute (non-negative) value of a number? We could do something like this: if number < 0 absolute = -number else absolute = number end That works, and is neat; but it's a lot of extra typing. This is where the conditional assignment operator comes in. It's a little bit trickier than if statements, but can save a lot of typing. variable = ? : is any boolean expression is the value assigned to variable if is true is the value assigned to variable if is false The important things to watch for is, MUST be followed by a `?` and must be separated by spaces. The true / false values MUST be separated by `:` So, let's try our example: absolute = number < 0 ? -number : number So, if number is less than 0, give absolute the value of -number (which would be positive, since number is < 0) otherwise, just give absolute the value of number. Now, it looks a bit neater, and much less typing. You do not NEED to use conditional assignment. However, if you are comfortable with using it, I would suggest doing so, as it can save you a lot of typing in the long run. There are also other "forms" of conditional assignment, that are used less often. I will leave those out for now, and include them at another time. So, that's it for now. Before I go, I would like to leave you with a few practice coding challenges: The following challenges are borrowed from "Practical C Programming" by Steve Oulline. I feel these are vary practical and challenging uses of decision making, and couldn't think of anything better (and I wanted you to have a lot more practice at this point) (By the way, they are actually easier to solve in ruby than in C) 1. Write a program that takes a student's grade as a number/percentage, and prints out their letter grade. Grade Table Letter Grade Numeric Grade F 0-60 D 61-70 C 71-80 B 81-90 A 91-100 (HINT: Remember how the interpreter executes an if statement) 2. Modify the previous program, to also display a + or - after the letter. The +/- modifier is based on the last digit of the numeric grade: Grade Modifications Last Digit Modifier 1-3 - 4-7 [/td] + ex. 81 = B-, 94 = A, 68 = D+. Remember, and F is only an F, you cannot get an F- (HINT: Remember the modulus operator? `%` ? EVEN BIGGER HINT: 3. Given an amount of money (less than $1.00), compute the number of quarters, dimes, nickels, and pennies needed. 4. A leap year is any year divisible by 4, unless the year is divisible by 100, but not 400. Write a program to tell if a year is a leap year. 5. Write a program that, given the number of hours an employee worked and the hourly wage, computes the employee's weekly pay. Count any hours over 40 as overtime at time and a half. 6. EXTRA HOMEWORK CHALLENGE: If the previous challenges did not satisfy you, here's the REAL challenge. For this challenge, you will need to go out and learn about Ruby's "Range" data type. Do not worry, I will teach you about this data type in the future. http://www.ruby-doc.....9.3/Range.html Now, the challenge will be to redo the first 2 challenges, using the Range class. HINTS MORE ON IF STATEMENTS: The following is a few extra points about "if" statements. These are non-essentially to learning if statements, but you may find them QUITE useful (I know I do). I left them out of the main lesson because I didn't want to overload you with too much. I would advise that you first ensure you are comfortable with using if statements, before learning these. Lesson 7: Flow Control - Looping Ah, looping. Loops, in my opinion, are what separate a "script" from a "program." So, here comes the obligatory... What is a loop? Think of the word loop, in the terms of a song loop -- we say a song is looping when it repeats, once it reaches the end. A loop in programming, is generally a block of code that is repeated any arbitrary number of times. For example, at its very essence, all a video game is, is a huge loop continuously taking input and reacting based on the input and the game's current state, until the player quits the game. So how does it work? Well, in ruby, there are actually many ways to "loop" or iterate -- as it's commonly referred to as -- let's start with the while loop. while condition do # Loop block end The `do` portion of the while - loop syntax is optional -- while condition # Loop block end works as well. So, "while" the "condition" evaluates to true (anything except false or nil), execute block. The while loop will continuously repeat until condition is false or nil. Be Careful -- Endless loops. Endless loops refer to a loop that never ends. This happens because the condition never becomes false. If you get stuck in an endless loop, usually CTRL + C will break the loop. As a programmer, we need to have some kind of control over how long a program repeats its statements. One common method of loop control, is through use of a counter: i = 0 while i < 5 puts "Hello!" i += 1 end the output would be: Hello! Hello! Hello! Hello! Hello! How did this happen? The interpreter sets a variable, `i`, to 0. It then enters the loop: Is i less than 5? yes, display "Hello". i is now 1 Is i less than 5? yes, display "Hello". i is now 2 Is i less than 5? yes, display "Hello". i is now 3 Is i less than 5? yes, display "Hello". i is now 4 Is i less than 5? yes, display "Hello". i is now 5 Is i less than 5? no, i is equal to 5, stop looping. We can use a variable as a counter, and use an arbitrary maximum number of iterations and then by counting the number of iterations we can determine when to stop executing the block. Here's a better example: "In mathematics, the factorial of a non-negative integer n, denoted by n!, is the product of all positive integers less than or equal to n. For example, 5! = 5 x 4 x 3 x 2 x 1 = 120 " (http://en.wikipedia.org/wiki/Factorial) (Yea, I was lazy and they had a better explanation......) Er, let's translate this to our code! Let's say we want a program that takes a number from the user, and calculates that number's factorial. # Calculate the factorial print("Enter a number: ") number = gets.to_i # Get first number factorial = number print("#{number}!\n#{number}") while number > 1 # move to next number number -= 1 # get product of n..n-1 factorial *= number print(" * #{number} ") end puts("= #{factorial}") Test: Enter a number: 5 5! 5 * 4 * 3 * 2 * 1 = 120 Looks good! As you can see, counters can decrement as well. How you do it, will mostly depend on the situation (remember, you don't always have to increment/decrement by 1, either.) Of course, condition can be ANY expression, and is also used to loop based on a program's "current state." Let's go back to the guessing game we created. Wouldn't it be much better if we let the user keep guessing until they quit or guess the number? # Set a number to guess number = 10 # define the current "state" game_over = false while !game_over # Prompt the user to guess what number it is: print("I am thinking of a number. What is it? (Type q to quit) ") # Get the guess guess = gets.strip if guess.upcase == "Q" puts("Goodbye!") # Change current "state" game_over = true elsif guess.to_i < number puts("Too low!") elsif guess.to_i > number puts("Too high!") elsif guess.to_i == number puts("Wow! You got it!") # Won the game, change state game_over = true end end Now, our simple guessing game is actually a game! Well, mostly. We'd want to randomize the number to make it more of a game, but I will go over random number generation another time. For now, it does what we need. The game will now continuously prompt the user until the variable game_over is true. Notice that, we could have instead made a variable, say, game_playing, and set it to true. Then, while game_playing is true, prompt the user -- either way would work. Before we finish, I'd like to introduce to another form of looping, and some more loop control methods. The next loop you will learn about, is called the "for" loop. The for loop can be considered a special type of iterator, but for now, just think of it as a loop with very specific bounds. (I will go over more about for and iterators, in a later lesson) Let's go back to the factorial program we made. If you notice, a factorial always loops a very specific number of times. The number of times it loops may be dependant on the input, but it will always be a set value. This is where for loops come in. for i in 0..5 puts i end produces: 0 1 2 3 4 5 So how does this work? Well, the syntax is: for variable in set # Block end For loops, will iterate through each item in a "set" (for now, we will only discuss ranges), and store the current object in the set, in the variable 'i'. So what happened in the above loop? Well, in Ruby, a Range object (denoted by min..max or min...max), is actually a representation of a set of numbers from min to max. Be careful with ranges, 0..5 means 0 to 5 inclusive, while 0...5 means 0 to 5 exclusive:0..5 => 0, 1, 2, 3, 4, 5 0...5 => 0, 1, 2, 3, 4 Then, based on this analysis, i is first set to 0 (first item in the set), then we print i in the block. When we move to the next item/iteration, i is then set to 1, and we print it. The loop continues this pattern, until we reach the last item, then when there are no items left to be stored in i, we break out of the loop.Why is this useful? Well, let's put this to more practical use. Let's go back to the factorial program -- like I promised. # Calculate the factorial print("Enter a number: ") number = gets.to_i factorial = number for i in 1...number # factorial *= i end puts("#{number}! = #{factorial}")[/code]Note, that unfortunately, ranges don't work in reverse. For example, 5...1 is not 5,4,3,2. It will not work. There are ways to reverse ranges, but that would be treading into an area I want to save for another lesson. Ahem, any who, carrying on... (I apologize for a larger amount of "later..."s, I would like, for this lesson, to focus on the concept of loops, without worrying too much about extra technical details, at least not yet) Another good use of for loops, is for generating rows and columns of display. Say, we want to generate a pattern like this: *************** *************** We could simply hard code a couple puts, and it would work...but what if we want to be able to draw any size? # Get rows and columns print("Enter number of rows: ") rows = gets.to_i print("Enter number of columns: ") cols = gets.to_i # Display pattern for i in 0...rows for j in 0...cols print("*") end print("\n") end could produce: Enter number of rows: 2 Enter number of columns: 15 *************** *************** It may seem silly, but if you can grasp this concept of nested for loops, you will find it VERY useful later on. But what exactly happens? So, rows == 2 and cols == 15. We enter the first loop at i = 0, and the second loop at j = 0. Then j will become 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 (remember, 0...cols is 0 to cols exclusive) and on each iteration, the interpreter will print a `*` on a single line. When we break out of the nested loop, ruby prints a \n (newline character), then i becomes 1. We then reach the nested loop again, and it does the exact same thing, printing 15 `*`s on the next line (notice, 0-14 inclusive or 0-15 exclusive, is 15 different numbers). We break, print a new line, i runs out of numbers (0...rows exclusive => 0, 1) and therefore break from the outerloop, and stop looping altogether. This concept will become very useful, when looping through grid-based data structures. (A single for loop, if you noticed, is meant/really good at looping through list-based data structures). Finally, before I finish loops, I would like to teach you a couple useful control statements for loops -- break, and next. loop do # Prompt the user to guess what number it is: print("I am thinking of a number. What is it? (Type q to quit) ") # Get the guess guess = gets.strip if guess.upcase == "Q" puts("Goodbye!") break end guess = guess.to_i if guess < number puts("Too low!") next end if guess > number puts("Too high!") next end if guess == number puts("Wow! You got it!") break end end So, this is a slightly modified version of our guessing game. If you try it out, you might notice it works exactly the same! Let's analyze what I changed. Firstly, the loop is no longer a while loop... loop do # Code end This is just another form of loop that ruby has, that represents an infinite loop -- when the interpreter finds this, it will continuously loop the block of code. (This is useful for if you need to loop, but not based on a certain state/condition). Now, when a guess is made, if the guess is 'Q' or the right number, the loop will "break." break is a keyword in ruby, and is also a special function. It will "break out" of the current, immediate loop, and stop looping (Note, if you use break in a nested loop, it will only break out of the loop it is called from, not all loops). We also, use `next` if the number is incorrect. next is like break (a special function for controlling loops), but what it does, is tell the ruby interpreter to skip to the "next" iteration, meaning next will skip the rest of the block of code, and restart the loop. If used in a for loop, this also means i becomes the next item in the list. Well, that's all for today's lesson! I apologize for taking so long this time. Things are getting busy for me again, and I may take a little bit longer to finish each lesson. I will try my best, however, to keep the lessons coming once a week! Now, I will leave you with a few more challenges: 1. Make a simple "menu" script, that will continuously prompt the user to enter a numeric selection, and display a different message based on the input. If the user types "q" or "Q" the menu should stop. 2. Write a script that will generate this output: * ** *** **** ***** ****** ******* ******** ********* ********** or, if you're feeling really creative, try making it look like this: * *** ***** ******* ********* *********** (Kinda late for christmas isn't it????) 3. The formula for converting degrees celsius to degrees fahrenheit is: F = C * 9 / 5 + 32 Write a script that will display a Celsius -> Fahrenheit conversion table from -10 celsius to 40 celsius. i.e -10C = 14F -9C = 15.8F -8C = 17.6F -7C = 19.4F ...etc.
  5. Lesson 7: Flow Control - Looping Ah, looping. Loops, in my opinion, are what separate a "script" from a "program." So, here comes the obligatory... What is a loop? Think of the word loop, in the terms of a song loop -- we say a song is looping when it repeats, once it reaches the end. A loop in programming, is generally a block of code that is repeated any arbitrary number of times. For example, at its very essence, all a video game is, is a huge loop continuously taking input and reacting based on the input and the game's current state, until the player quits the game. So how does it work? Well, in ruby, there are actually many ways to "loop" or iterate -- as it's commonly referred to as -- let's start with the while loop. while condition do # Loop block end The `do` portion of the while - loop syntax is optional -- while condition # Loop block end works as well. So, "while" the "condition" evaluates to true (anything except false or nil), execute block. The while loop will continuously repeat until condition is false or nil. Be Careful -- Endless loops. Endless loops refer to a loop that never ends. This happens because the condition never becomes false. If you get stuck in an endless loop, usually CTRL + C will break the loop. As a programmer, we need to have some kind of control over how long a program repeats its statements. One common method of loop control, is through use of a counter: i = 0 while i < 5 puts "Hello!" i += 1 end the output would be: Hello! Hello! Hello! Hello! Hello! How did this happen? The interpreter sets a variable, `i`, to 0. It then enters the loop: Is i less than 5? yes, display "Hello". i is now 1 Is i less than 5? yes, display "Hello". i is now 2 Is i less than 5? yes, display "Hello". i is now 3 Is i less than 5? yes, display "Hello". i is now 4 Is i less than 5? yes, display "Hello". i is now 5 Is i less than 5? no, i is equal to 5, stop looping. We can use a variable as a counter, and use an arbitrary maximum number of iterations and then by counting the number of iterations we can determine when to stop executing the block. Here's a better example: "In mathematics, the factorial of a non-negative integer n, denoted by n!, is the product of all positive integers less than or equal to n. For example, 5! = 5 x 4 x 3 x 2 x 1 = 120 " (http://en.wikipedia.org/wiki/Factorial) (Yea, I was lazy and they had a better explanation......) Er, let's translate this to our code! Let's say we want a program that takes a number from the user, and calculates that number's factorial. # Calculate the factorial print("Enter a number: ") number = gets.to_i # Get first number factorial = number print("#{number}!\n#{number}") while number > 1 # move to next number number -= 1 # get product of n..n-1 factorial *= number print(" * #{number} ") end puts("= #{factorial}") Test: Enter a number: 5 5! 5 * 4 * 3 * 2 * 1 = 120 Looks good! As you can see, counters can decrement as well. How you do it, will mostly depend on the situation (remember, you don't always have to increment/decrement by 1, either.) Of course, condition can be ANY expression, and is also used to loop based on a program's "current state." Let's go back to the guessing game we created. Wouldn't it be much better if we let the user keep guessing until they quit or guess the number? # Set a number to guess number = 10 # define the current "state" game_over = false while !game_over # Prompt the user to guess what number it is: print("I am thinking of a number. What is it? (Type q to quit) ") # Get the guess guess = gets.strip if guess.upcase == "Q" puts("Goodbye!") # Change current "state" game_over = true elsif guess.to_i < number puts("Too low!") elsif guess.to_i > number puts("Too high!") elsif guess.to_i == number puts("Wow! You got it!") # Won the game, change state game_over = true end end Now, our simple guessing game is actually a game! Well, mostly. We'd want to randomize the number to make it more of a game, but I will go over random number generation another time. For now, it does what we need. The game will now continuously prompt the user until the variable game_over is true. Notice that, we could have instead made a variable, say, game_playing, and set it to true. Then, while game_playing is true, prompt the user -- either way would work. Before we finish, I'd like to introduce to another form of looping, and some more loop control methods. The next loop you will learn about, is called the "for" loop. The for loop can be considered a special type of iterator, but for now, just think of it as a loop with very specific bounds. (I will go over more about for and iterators, in a later lesson) Let's go back to the factorial program we made. If you notice, a factorial always loops a very specific number of times. The number of times it loops may be dependant on the input, but it will always be a set value. This is where for loops come in. for i in 0..5 puts i end produces: 0 1 2 3 4 5 So how does this work? Well, the syntax is: for variable in set # Block end For loops, will iterate through each item in a "set" (for now, we will only discuss ranges), and store the current object in the set, in the variable 'i'. So what happened in the above loop? Well, in Ruby, a Range object (denoted by min..max or min...max), is actually a representation of a set of numbers from min to max. Be careful with ranges, 0..5 means 0 to 5 inclusive, while 0...5 means 0 to 5 exclusive:0..5 => 0, 1, 2, 3, 4, 5 0...5 => 0, 1, 2, 3, 4 Then, based on this analysis, i is first set to 0 (first item in the set), then we print i in the block. When we move to the next item/iteration, i is then set to 1, and we print it. The loop continues this pattern, until we reach the last item, then when there are no items left to be stored in i, we break out of the loop.Why is this useful? Well, let's put this to more practical use. Let's go back to the factorial program -- like I promised. # Calculate the factorial print("Enter a number: ") number = gets.to_i factorial = number for i in 1...number # factorial *= i end puts("#{number}! = #{factorial}")[/code]Note, that unfortunately, ranges don't work in reverse. For example, 5...1 is not 5,4,3,2. It will not work. There are ways to reverse ranges, but that would be treading into an area I want to save for another lesson. Ahem, any who, carrying on... (I apologize for a larger amount of "later..."s, I would like, for this lesson, to focus on the concept of loops, without worrying too much about extra technical details, at least not yet) Another good use of for loops, is for generating rows and columns of display. Say, we want to generate a pattern like this: *************** *************** We could simply hard code a couple puts, and it would work...but what if we want to be able to draw any size? # Get rows and columns print("Enter number of rows: ") rows = gets.to_i print("Enter number of columns: ") cols = gets.to_i # Display pattern for i in 0...rows for j in 0...cols print("*") end print("\n") end could produce: Enter number of rows: 2 Enter number of columns: 15 *************** *************** It may seem silly, but if you can grasp this concept of nested for loops, you will find it VERY useful later on. But what exactly happens? So, rows == 2 and cols == 15. We enter the first loop at i = 0, and the second loop at j = 0. Then j will become 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 (remember, 0...cols is 0 to cols exclusive) and on each iteration, the interpreter will print a `*` on a single line. When we break out of the nested loop, ruby prints a \n (newline character), then i becomes 1. We then reach the nested loop again, and it does the exact same thing, printing 15 `*`s on the next line (notice, 0-14 inclusive or 0-15 exclusive, is 15 different numbers). We break, print a new line, i runs out of numbers (0...rows exclusive => 0, 1) and therefore break from the outerloop, and stop looping altogether. This concept will become very useful, when looping through grid-based data structures. (A single for loop, if you noticed, is meant/really good at looping through list-based data structures). Finally, before I finish loops, I would like to teach you a couple useful control statements for loops -- break, and next. loop do # Prompt the user to guess what number it is: print("I am thinking of a number. What is it? (Type q to quit) ") # Get the guess guess = gets.strip if guess.upcase == "Q" puts("Goodbye!") break end guess = guess.to_i if guess < number puts("Too low!") next end if guess > number puts("Too high!") next end if guess == number puts("Wow! You got it!") break end end So, this is a slightly modified version of our guessing game. If you try it out, you might notice it works exactly the same! Let's analyze what I changed. Firstly, the loop is no longer a while loop... loop do # Code end This is just another form of loop that ruby has, that represents an infinite loop -- when the interpreter finds this, it will continuously loop the block of code. (This is useful for if you need to loop, but not based on a certain state/condition). Now, when a guess is made, if the guess is 'Q' or the right number, the loop will "break." break is a keyword in ruby, and is also a special function. It will "break out" of the current, immediate loop, and stop looping (Note, if you use break in a nested loop, it will only break out of the loop it is called from, not all loops). We also, use `next` if the number is incorrect. next is like break (a special function for controlling loops), but what it does, is tell the ruby interpreter to skip to the "next" iteration, meaning next will skip the rest of the block of code, and restart the loop. If used in a for loop, this also means i becomes the next item in the list. Well, that's all for today's lesson! I apologize for taking so long this time. Things are getting busy for me again, and I may take a little bit longer to finish each lesson. I will try my best, however, to keep the lessons coming once a week! Now, I will leave you with a few more challenges: 1. Make a simple "menu" script, that will continuously prompt the user to enter a numeric selection, and display a different message based on the input. If the user types "q" or "Q" the menu should stop. 2. Write a script that will generate this output: * ** *** **** ***** ****** ******* ******** ********* ********** or, if you're feeling really creative, try making it look like this: * *** ***** ******* ********* *********** (Kinda late for Christmas isn't it????) 3. The formula for converting degrees celsius to degrees fahrenheit is: F = C * 9 / 5 + 32 Write a script that will display a Celsius -> Fahrenheit conversion table from -10 celsius to 40 celsius. i.e -10C = 14F -9C = 15.8F -8C = 17.6F -7C = 19.4F ...etc.
×
×
  • Create New...