Tuesday, August 2, 2016

16 Best CSS Code Generators for Developers

If you are a CSS developer then you definitely know the importance of CSS tools which can make your job lot easier and quick. There are number of CSS code generator out there which enable you to do number of things for you.

Once you know what code you need to generate, all you need to find appropriate tool for it. Therefore sparing you from such effort we have compiled a list of 16 Best CSS Code Generators for you which we feel are best and can serve multiple purpose for you.

These tools are absolutely free and packed with tons of features to help you with your projects. So, without further ado, let’s explore the list of following CSS Code Generators.

1. Atomizer Web


Atomizer is a tool for creating Atomic CSS. Generate an Atomic stylesheet dynamically from the Atomic classes you’re actually using in your project (no unused styles!), or predeclare styles in configuration – it’s up to you. Atomizer is not opinionated, brings no CSS of its own, and integrates nicely with your favorite task runner.

2. CSS Specificity Graph Generator


The CSS Specificity Graph Generator makes it simple to create specificity graphs for your stylesheets, for better insight into how well structured they are. It uses d3, css-parser, and specificity to create interactive visualizations.

3. CSSMatic


CSSmatic is a non-profit ultimate CSS tools for web designers. There are four useful tools at the moment. You can use the Gradient Generator which supports multiple colors and opacity stops to get amazing gradients. By using the gradient tool you can create gradients with smooth color changing effects and subtle transparencies.

4. FlexyBoxes


Flexy Boxes is a flexbox code generator and playground in one. Just set the options for your flexboxes, preview them, and then output the code.

5. CSS Sprite Generator


CSS Sprite Generator will help you put all your background pictures for a website page into a solitary picture. You can then utilize CSS situating to show the right picture at the correct spot. In the event that your page has many background pictures, the browser needs to make a lot of people more HTTP solicitations to bring every one of them from the server.

6. Penthouse


Penthouse is a critical path CSS generator for speeding up web page rendering. It looks at your full CSS in relation to the page and provides the CSS needed to render the above-the-fold content of your page, saving time and server resources.

7. Wait Animate


CSS doesn’t provide an easy way to pause an animation before it loops around again. Yes, there’s animation-delay but this simply denotes a delay at the very start of the animation, i.e on load. WAIT! Animate provides an easy way to calculate the keyframe percentages so that you can insert a delay between each animation iteration.

8. Color CSS Gradient Background Generator


This Color CSS Gradient Background Generator makes it easy to create complex backgrounds gradients using CSS. Forget about simple two color gradients, and instead create gradients with up to four different layers!

9. EnjoyCSS


EnjoyCSS is an advanced CSS3 generator that allows you to get rid of routine coding. It’s handy and easy-to-use UI allows you to adjust rich graphical styles quickly and without coding.

You’ll be able to play with all EnjoyCSS parameters just like in photoshop or illustarator (with sliders, colorpickers and etc) combining all possible CSS3 style capabilities for the same element. Moreover you can include pseudo states (:hover, :active, :focus, :after, :before) and style them as well. All required CSS code will be automatically generated by EnjoyCSS.

10. CSS Rationcinator


CSS Ratiocinator is a tool that will automatically refactor your CSS and generate a new stylesheet for your site. It works by examining your site’s live DOM in the browser and reverse engineering a new, more elegant definition that captures styles down to the last pixel.

11. CSS3 Keyframes Animation


The CSS3 Keyframes Animation Generator, as the name suggests, is an online tool that lets you create CSS3 keyframe animations.

12. Patternify


Patternify is a free CSS pattern generator with a complete visual editor. Everything is managed from your web browser, so all you need is an Internet connection.

13. Bulletproof Email Buttons Generator


Bulletproof Email Buttons Generator helps you design gorgeous buttons using progressively enhanced VML and CSS. You can change the background text, background image, background color, border width and color easily as well. You can also create rock-solid background images in emails too.

14. CSS Form Code Generator


CSS Form Code maker creates nice looking layouts for forms. It also helps you to crate colorful table less layout for forms. This ‘code maker’ generates CSS layout code to ‘spice up’ those forms as well.

15. Racket


Racket is a Yeoman generator for universal and isomorphic web apps. It lets you choose the technologies and tools you want most and then offers them in a maintainable structure.

16. How to Center in CSS


How to Center in CSS makes it super easy to generate the code you need to center your content according to parameters you set.
Written by: Gavin

For more information , please support and follow us.
 Suggest for you:

CSS: Foundation classes on CSS

Coding Made Easy: HTML & CSS For Beginners 

Bootstrap 4 Rapid web development framework HTML CSS JS


Monday, August 1, 2016

How to Use the JavaBean API Library

JavaBean is a paradigm of specified norms that define reusable software component design. Any Java class is a potential bean, provided they follow the specification laid by the specification guideline. The rules are simple and straightforward as we shall see down the line. Apart from these norms, there is a Java bean API library that helps in the process of transforming a POJO into a bean component and in realizing the introspection mechanism subsequently. The list of library APIs are contained in the java.beans package. Once a Java bean is created, it can be plugged in as an independent entity to an application that requires the service defined by the component. This article shall discuss some of the key aspects of transforming a POJO into a bean component and how the JavaBean API library helps in the process.

JavaBean and Library Classes

Can we not create every Java class as a bean? Yes, we can, but it will not make sense under all circumstances. Beans usually are appropriate for creating visual software components that are manipulated and customized to meet specific requirements. For example, think of a visual component such as a frame or button, whose shape and color can be customized according to our needs. (Recall how you can drag-drop and use components such as JButton, JList, and so forth, and change its properties in NetBeans). So, those Java classes are perfect to be re-christened as a JavaBean from POJO. Class libraries, on the other hand, are POJOs that provide functionalities for programmers. They do not have, rather they do not require, visual manipulation. For example, the JDBC API classes are library classes that do not require visual manipulation. But, you always can make a database access bean on top of the JDBC classes, and in that case it would better be created as a JavaBean component, so that it can be used/reused at any time. There are some specific advantages and disadvantages of a Java bean:

Advantages
  • Beans are persistable and can be stored and retrieved back from permanent storage.
  • A bean can be customized and manipulated by some auxiliary software.
  • We can control what properties, methods, and events are to be exposed to the application that wants to use it.
  • A bean can not only be registered to receive events send by another object, but also generate events.
Disadvantages
  • The benefits of immutable objects are absent in beans because they are by default mutable.
  • Because every Java bean must have a no-argument constructor (nullary constructor), this may lead to an object being instantiated in an invalid state.
  • Bean classes contain much boilerplate code because, as per specification, most or all private properties must be exposed through public getters and setters. This often leads to writing many unnecessary codes.
The Standard

Firstly, to create a JavaBean, the following basic rules are to be maintained in a Java class. These rules are actually conventions that must be adhered to because other libraries, when using this component, expect these rules are maintained.
  • All private properties deemed to be accessed programmatically must be accessible through a public getter and setter method. For example, if salary is a property of an Employee class, it must be exposed through the getSalary and setSalary methods.
  • It doesn't matter how many polymorphic constructor are supplied, but a bean class must have a public no-argument constructor.
  • A bean class must be serializable; or, in other words, must implement a java.io.Serializable or java.io.Externalizable interface. This provides the ability of persistence to a bean component.
A class that deviates from the rules will not be a bean because JavaBean is a standard. Once you follow the rules and design the class appropriately, the user who also knows the standard can appropriately fit the component into their application easily. This is the goal of JavaBean—to create reusable software components.

Important Features

There are three important features associated with JavaBeans:
  • Properties: Named attributes associated with a bean
  • Methods: POJO methods of which the bean can choose to expose a subset of its public types.
  • Events: Notify other components if something interesting occurs.
JavaBean API

The package java.beans contains a set of classes and interfaces that provide many functionalities related to creating components based on JavaBeans architecture. These classes are used by beans at runtime. For example, the PropertyChangeEvent class is used to fire property and vetoable change events.

JavaBeans component architecture also provides support for a long-term persistence model. This enables beans to be saved in XML format. The read scheme with persistence is pretty straightforward and does not require any special knowledge in the process. The write scheme is a bit tricky at times and requires special knowledge about the bean's type. If the bean's state is exposed using a nullary constructor, properties using public getters and setters, no special knowledge is required. Otherwise, the bean requires a custom object, called a persistence delegate, to handle the process of writing out beans of a particular type.

The classes that inherit java.awt.Component or its descendents, automatically own persistence delegates. Otherwise, we can use a DefaultPersistenceDelegate instance or create our own subclass of PersistenceDelegate to support the scheme.

The JavaBean APIs are meant to be used by the bean editor, which provides the environment to customize and manipulate the properties of a bean component.

Some interfaces and classes commonly used are as follows.
The JavaBean APIs are meant to be used by the bean editor, which provides the environment to customize and manipulate the properties of a bean component.
Some interfaces and classes commonly used are as follows.
InterfaceDescription
AppletInitializerMethods of this interface are particularly useful for initializing applet beans.
BeanInfoThis interface is used in the process of introspection about the events, methods, and properties of a Bean.
CustomizerThis interface helps in providing a GUI interface. This GUI interface may be used to manipulate and configure beans.
DesignModeMethods in this interface help in finding out if the bean is operating in the design mode.
ExceptionListenerMethods of this interface are called when an exception occurs.
PropertyChangeListenerA method of this interface is invoked when a bounded property change is triggered.
PropertyEditorA Java class that implements this interface is able to change and display property values.
VetoableChangeListener

Visibility
This is an event listener interface and contains a method for events to notify as soon as a constrained property is changed.

Methods in this interface helps the bean to execute in an environment where a GUI is unavailable.

ClassDescription
BeanDescriptorA BeanDescriptor provides global information about a "bean", including its Java class, its displayName, and so on.
BeansThis class provides some general purpose bean control methods.
PropertyChangeEventA "PropertyChange" event gets delivered whenever a bean changes a "bound" or "constrained" property.
SimpleBeanInfoThis is a support class to make it easier for people to provide BeanInfo classes.
VetoableChangeSuportThis is a utility class that can be used by beans that support constrained properties.
IntrospectorThe Introspector class provides a standard way for tools to learn about the properties, events, and methods supported by a target Java Bean.
EventHandlerThe EventHandler class provides support for dynamically generating event listeners whose methods execute a simple statement involving an incoming event object and a target object.
FeatureDescriptorThe FeatureDescriptor class is the common baseclass for PropertyDescriptor, EventSetDescriptor, MethodDescriptor, and the like.
StatementA Statement object represents a primitive statement in which a single method is applied to a target and a set of arguments—as in "a.setFoo(b)".
Refer to the java.beans package of the Java API Documentation for an extended list and more information.

  1.  package greetbean;

  2. import java.awt.Color;
  3. import java.awt.Font;
  4. import java.awt.event.MouseEvent;
  5. import java.awt.event.MouseListener;
  6. import java.awt.event.MouseMotionListener;
  7. import java.io.Serializable;
  8. import javax.swing.JLabel;

  9. public class GreetBean extends JLabel implements
  10.    Serializable {

  11.    private final String greet = "Hi there! ";
  12.    transient private Color color;
  13.    private final MouseHandler handler;

  14.    public GreetBean() {
  15.       handler = new MouseHandler();
  16.       registerMouseEvents();
  17.    }

  18.    private void registerMouseEvents() {
  19.       addMouseListener(handler);
  20.       addMouseMotionListener(handler);
  21.    }

  22.    public String getGreet() {
  23.       return this.getText();
  24.    }

  25.    public void setGreet(String greet) {
  26.       this.setText(greet);
  27.    }

  28.    public Color getColor() {
  29.       return color;
  30.    }

  31.    public void setColor(Color color) {
  32.       this.color = color;
  33.    }

  34.    private void changeColor() {
  35.       int red = (int) (255 * Math.random());
  36.       int green = (int) (255 * Math.random());
  37.       int blue = (int) (255 * Math.random());
  38.       setColor(new Color(red, green, blue));
  39.       setFont(new Font("Serif", 1, 14));
  40.       setForeground(getColor());

  41.    }

  42.    private class MouseHandler implements MouseListener,
  43.       MouseMotionListener {

  44.       @Override
  45.       public void mouseClicked(MouseEvent e) {
  46.          setText(String.format(greet + " Mouse clicked at [%d,%d]",
  47.             e.getX(), e.getY()));
  48.          changeColor();
  49.       }

  50.       @Override
  51.       public void mousePressed(MouseEvent e) {
  52.          setText(String.format(greet + " Mouse pressed at [%d,%d]",
  53.             e.getX(), e.getY()));
  54.          changeColor();
  55.       }

  56.       @Override
  57.       public void mouseReleased(MouseEvent e) {
  58.          setText(String.format(greet + " Mouse released at [%d,%d]",
  59.             e.getX(), e.getY()));
  60.          changeColor();
  61.       }

  62.       @Override
  63.       public void mouseEntered(MouseEvent e) {
  64.          setText(String.format(greet + " Mouse entered at [%d,%d]",
  65.             e.getX(), e.getY()));
  66.          changeColor();
  67.       }

  68.       @Override
  69.       public void mouseExited(MouseEvent e) {
  70.          setText(String.format(greet + " Mouse exited at [%d,%d]",
  71.             e.getX(), e.getY()));
  72.          changeColor();
  73.       }

  74.       @Override
  75.       public void mouseDragged(MouseEvent e) {
  76.          setText(String.format(greet + " Mouse dragged at [%d,%d]",
  77.             e.getX(), e.getY()));
  78.          changeColor();
  79.       }

  80.       @Override
  81.       public void mouseMoved(MouseEvent e) {
  82.          setText(String.format(greet + " Mouse moved at [%d,%d]",
  83.             e.getX(), e.getY()));
  84.          changeColor();
  85.       }

  86.    }
  87. }

  1. package greetbean;

  2. import java.awt.Image;
  3. import java.beans.BeanDescriptor;
  4. import java.beans.BeanInfo;
  5. import java.beans.EventSetDescriptor;
  6. import java.beans.IntrospectionException;
  7. import java.beans.Introspector;
  8. import java.beans.PropertyDescriptor;
  9. import java.beans.SimpleBeanInfo;

  10. public class GreetBeanInfo extends SimpleBeanInfo {

  11.    private final static Class BEAN = GreetBean.class;

  12.    @Override
  13.    public PropertyDescriptor[] getPropertyDescriptors() {
  14.       try {
  15.          PropertyDescriptor greet = new
  16.             PropertyDescriptor("greet", BEAN);
  17.          PropertyDescriptor color = new
  18.             PropertyDescriptor("color", BEAN);

  19.          PropertyDescriptor[] pd = {greet, color};
  20.          return pd;

  21.       } catch (IntrospectionException ex) {
  22.          throw new Error(ex.toString());
  23.       }
  24.    }

  25.    @Override
  26.    public BeanDescriptor getBeanDescriptor() {
  27.       BeanDescriptor bd = new BeanDescriptor(BEAN);
  28.       bd.setShortDescription("Customizable greetings bean");
  29.       bd.setDisplayName("Greetings");
  30.       return bd;
  31.    }

  32.    @Override
  33.    public Image getIcon(int it) {
  34.       if (it == BeanInfo.ICON_COLOR_16x16) {
  35.          System.out.println("Getting image...");
  36.          return loadImage("../images/icons16x16/icon.png");
  37.       }
  38.       return null;
  39.    }

  40.    @Override
  41.    public EventSetDescriptor[] getEventSetDescriptors() {
  42.       try {
  43.          return Introspector.getBeanInfo(BEAN).getEventSetDescriptors();
  44.       } catch (IntrospectionException e) {
  45.          return null;
  46.       }
  47.    }
  48. }


  1. package greetbean;

  2. import java.beans.BeanDescriptor;
  3. import java.beans.BeanInfo;
  4. import java.beans.EventSetDescriptor;
  5. import java.beans.IntrospectionException;
  6. import java.beans.Introspector;
  7. import java.beans.PropertyDescriptor;

  8. public class GreetBeanIntrospect {

  9.    public static void main(String[] args) {
  10.       try {
  11.          BeanInfo info = Introspector.getBeanInfo(GreetBean.class);
  12.          System.out.println("-------------PROPERTIES-----------------");
  13.          for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
  14.             System.out.println(pd.getName());
  15.          }

  16.          System.out.println("-----------BEAN DESCRIPTOR-------------");
  17.          BeanDescriptor bd = info.getBeanDescriptor();
  18.          System.out.println(bd.getDisplayName());
  19.          System.out.println(bd.getShortDescription());

  20.          System.out.println("--------------EVENTS----------------");
  21.          for (EventSetDescriptor ed : info.getEventSetDescriptors()) {
  22.             System.out.println(ed.getName());
  23.          }

  24.       } catch (IntrospectionException ex) {

  25.       }

  26.    }

  27. }



Once the jar file of the bean is created after compilation, run to see if the bean information such as properties, descriptors events, and so forth with the help of introspection mechanism (as described in GreetBeanIntrospect.java) is present.

However, you might want use the bean (after the jar is created) in an another application. It may be done in the following way:

Include a JFrame form.
Open the recently included JFrame in the design mode.
Click Tools→Palette→Swing/AWT Components. A Palette Managerwindow will appear.
https://school.codequs.com/p/SJFK6ODO
Figure 1: The Palette Manager window
Select "Add from JAR..." or "Add from Project" appropriately and include GreetBean as shown above. Make sure to add the component in the palette category of beans in one of the subsequent windows that will appear. Lastly, close Palette Manager window.
Observe that GreetBeanappears in the list of beans in the palette list of NetBeans IDE.

https://school.codequs.com/p/SJFK6ODO
Figure 2: GreetBeans appears in the list of beans
Simple, drag and drop the bean in the JFrame, as shown in Figure 2.
That's it. Now, run the JFrame file and observe the color and text change as you move and click the mouse over the bean at runtime.

https://school.codequs.com/p/SJFK6ODO
Figure 3: Observing the color and text changing
Conclusion

Java beans are actually re-christened POJOs that are designed according to the component architecture defined by JavaBean specification. Software components leverage clean and reusable code and should be used under appropriate circumstances and not indiscriminately. This article provided a glimpse of the usage of JavaBean APIs and how they are actually implemented. Consult the Java API Documentation for details and information of the APIs and their usages.
Source: developer 

If you found this post interesting, follow and support us.
Suggest for you:

Friday, July 29, 2016

The Pros and Cons of Ruby Refinements

In Ruby 2.0.0, refinements were introduced as a new feature. Monkey patching has been used for a long time for modifying code behavior, but it creates side effects in code elsewhere that ends up affected by the modified code.
The purpose of Ruby refinements is to provide a solution by scoping changed behavior to the very specific area of code you choose. This is a huge blessing for the language, but the current implementation of refinements has its flaws. Still, everyone should be using refinements to create a more sane code base and not create surprise side effects in your code base. In this post, I’ll go into detail on how refinements can be used, as well as discuss many of the issues you’ll face with its as-yet-incomplete design.

How to Use Refinements

First, you need to define the behavior you wish to change by defining a module and declaring which class(es) you will be refining.

  1. module ListStrings
  2. refine String do
  3. def +(other)
  4. "#{self}, #{other}"
  5. end
  6. end
  7. end

To use the behavior, simply use using ListStrings in one of several areas.
  1. using ListStrings
  2. '4' + '5'
  3. # => "4, 5"

You can use the refinement at the top level of your code, and all code written below that in the current file will be affected. You may also use it within eval statements

  1. eval "using ListStrings; '4' + '5'"
  2. # => "4, 5"
As of Ruby 2.3, these won’t work in IRB but will still work in your Ruby files.
The use of using is lexically scoped. When used at the top level of your code, its affects are scoped only to the current file from that point on to the end and not in any other code you require from other files.
As of Ruby 2.3, you may use refinements within classes..

  1. module Foo
  2. refine Fixnum do
  3. def to_s
  4. :foo
  5. end
  6. end
  7. end
  8. class NumAsString
  9. def num(input)
  10. input.to_s
  11. end
  12. end
  13. class NumAsFoo
  14. using Foo
  15. def num(input)
  16. input.to_s
  17. end
  18. end
  19. NumAsString.new.num(4)
  20. # => "4"
  21. NumAsFoo.new.num(4)
  22. # => :foo

This creates a very safe and sane way to scope changed behavior for existing code.

Current Issues with Ruby Refinements

As with most relatively young features, refinements still has some flaws. Let’s unpack where the trouble is.

Refinements can only be used once within a scope

If you’re benchmarking alternative ways and using multiple refinements on the same method name, then consecutive runs will fail to reuse used refinements. While this may not be a likely scenario, it’s good to keep this limitation in mind.

Dynamic dispatch won’t work with refinements yet

Dynamic dispatch happens when you use the proc form of mapping method calls, like [1,2,3].map(&:to_s). Here’s an example of how it won’t work with refinements:

  1. module Moo
  2. refine Fixnum do
  3. def to_s
  4. "moo"
  5. end
  6. end
  7. end
  8. class A
  9. using Moo
  10. def a
  11. [1,2,3].map {|x| x.to_s }
  12. end
  13. def b
  14. [1,2,3].map(&:to_s)
  15. end
  16. end
  17. A.new.a
  18. # => ["moo", "moo", "moo"]
  19. A.new.b
  20. # => ["1", "2", "3"]

If you had redefined the to_s method as a monkey patch, then both method calls would have returned lists of “moo”.

You cannot use methods for introspection

The Ruby documentation says, “When using indirect method access such as Kernel#sendKernel#send, or Kernel#respond_to?, refinements are not honored for the caller context during method lookup. This behavior may be changed in the future.”

  1. module Baz
  2. refine String do
  3. def baz
  4. :baz
  5. end
  6. end
  7. end
  8. class Venue
  9. using Baz
  10. def respond?
  11. "".respond_to? :baz
  12. end
  13. def call
  14. "".baz
  15. end
  16. end
  17. Venue.new.respond?
  18. # => false
  19. Venue.new.call
  20. # => :baz

This makes determining whether code has been changed more difficult if you’re not looking at the source code yourself. It might be worthwhile to add something like an instance variable to your refinement if you need to dynamically determine what refinements are in play.

  1. module Bar
  2. def refinements
  3. require 'set'
  4. @refinements = (@refinements || Set.new) << Bar
  5. end
  6. refine String do
  7. def bar
  8. :bar
  9. end
  10. end
  11. end
  12. class A
  13. include Bar and using Bar
  14. def a
  15. "".bar
  16. end
  17. end
  18. A.new.refinements
  19. # => #<Set: {Bar}>
  20. A.new.a
  21. # => :bar

You can decide for yourself how important introspection is for you; it would be quite handy when debugging. You may also choose to give more details for your introspection method than the example given here.

You can’t use using from within a method or module

This requires you to very explicitly declare usingwithin the lexical scope where you’ve choosen to modify the codes behavior. This is good for the sanity of all future developers who’ll look at the code and see that there is modified behavior.

You’re unable to experiment with refinements at the top level

As I mentioned earlier, the behavior in IRB changed at 2.3, limiting the ways you can experiment with refinements. To experiment with it in IRB with Ruby 2.3 and later, you may do so with anonymous classes.

  1. module Fiz
  2. refine Fixnum do
  3. def +(other)
  4. "#{self}#{other}"
  5. end
  6. end
  7. end
  8. class << Class.new
  9. using Fiz
  10. 1 + 2
  11. end
  12. # => "12"

Summary

Refinements are still in their infancy in Ruby, and improvements are very likely to be made to them. However, current development on refinements seems to be on hold, as Ruby development focuses on optimizing Ruby 3 to be three times faster than Ruby 2. As a result, refinement issues raised on the bug tracker aren’t receiving much attention.

Regardless of all the issues that exist with refinements, they are still a must for developers. With them, you can help ensure a code base that clearly shows alternative behavior while ensuring safe cohesion with larger code bases. You can worry less about name collision, side effects, and hard-to-track bugs when you contain your changes with refinements.

Refinements become most important any time you’re making modifications to existing methods on core classes in Ruby or any other widely used code base. I have tried monkey patching in the past to write a gem in the past that would have a String object behave like an Array, but when I included it in a Rails project, it all came crashing down. Many applications may use methods respond_to? to type check and perform different actions based on type. So of course making strings respond as arrays will break things globally. Now with refinements, you don’t have to worry about this — the changes are specifically only effective within the file, eval string, or class you used the refinement in.
Don’t rely on the lack of introspection in refinements as a feature. This will likely change in the future. If you use a refinement to have a method respond to a specific method call, and you type-check against that knowing it won’t show up, you’d have created a “bug waiting to happen.”
I for one really look forward to future development in Ruby around refinements to get past the current issues and move on to a more mature code use for all our benefit. And the biggest thing that will help refinements move further along in the development process is for more people to use it. The more people who use it, the more attention it will get, which will lead to more focus in developing it within the language.
Source: codeship
For more information please support and follow us .
Suggest for you:

The Complete Ruby on Rails Developer Course

Learn Ruby on Rails from Scratch

Python, Ruby, Shell - Scripting for Beginner