Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7019 Articles
article-image-managing-citrix-policies
Packt
20 Jun 2011
7 min read
Save for later

Managing Citrix policies

Packt
20 Jun 2011
7 min read
Understanding Citrix policies In the Active Directory, a Group Policy contains two categories (also called nodes): Computer Configuration and User Configuration settings. The Computer Configuration node contains policy settings applied to computers, XenApp servers, when we use GPO to manage servers The User Configuration node contains settings applied to users accessing the machine, the XenApp server in our case, regardless of where they log on Citrix policies also have same categories: computer and user. Computer policy settings in Citrix applied to XenApp servers. When the server is rebooted, these policies are applied to the server. User policy settings are used for the duration of the session and are applied to user sessions. Policy settings changes can also take effect when XenApp re-evaluates policies every 90 minutes. Citrix policies are the preferred way to manage session settings or user access and the most effective method of controlling connection, security, and bandwidth settings on XenApp farms. We can create and assign Citrix policies to users, groups, machines, or connection types and each policy can contain one or several settings. Using policies allows us to turn on/off settings like: ICA session settings, like Auto Client Reconnect, Keep Alive, Session Reliability, or Multimedia configuration Licensing configuration, like license server hostname or port Mapping of local drivers, printer, and ports Server settings, like Connections Settings, Reboot Behavior, Memory/CPU Management Shadowing options and permissions Working with Citrix policies A policy is basically a collection of settings or rules. Citrix policies include the user, server, and environment settings that will affect XenApp sessions when the policy is enforced. Policy settings can be enabled, disabled, or not configured. For some policy settings, we can enter a value or we can choose a value from a list when we add the setting to a policy. We can set some policies to one of the following conditions to enable or permit a policy setting: Enabled or Allowed and we can use Disabled or Prohibited to turn off or disallow a policy setting. Also, we can limit configuration of the setting by selecting Use default value. Selecting this option disables configuration of the setting and allows only the setting's default value to be used when the policy is enforced. If we create more than one policy in our environment, we need to prioritize the policies. The best way to track applied settings is to run a Resulting Set of Policies Logging report from the Group Policy Management Console or the Citrix Policy Modeling Wizard. These reports will show all Citrix settings configured via a policy, and which Group Policy Object, including the farm GPO, has actually won the merging calculation. We are going to talk about this in detail later. Usually, Citrix policies will override the same or similar settings applied to the farm, specific XenApp servers, or on the client machine, except for the highest encryption setting and the most restrictive shadowing setting, which always overrides other rules or settings. Best practices for creating Citrix policies The following is a list of recommendations when configuring policy settings: Reduce the amount of policies: Avoid creating multiple policies for different groups of users. Create one policy and apply filters to it. Disable unused policies: Unused policies waste processing resources. If we are using Active Directory Group Policies, we can disable the unused part of the policy (Computer or User part). Assign policies to groups: If we assign policies to groups rather than a user, management is easy and can reduce processing time. Remote Desktop Session Host Configuration settings are similar to Citrix policy settings in a few ways. We need to avoid using Remote Desktop Session Host Configuration to reduce overlapping of settings. We can use Remote Desktop Session Host Configuration (formerly known as Terminal Services Configuration on Windows Server 2003) to configure settings for new connections, modify the settings of existing connections, and delete connections. We can configure settings on a per connection basis or for the server as a whole. Guidelines for working with policies The process for configuring policies is as follows: Create and give a name to the policy: We need to create and provide a name for the new policy. Configure policy settings: We need to choose if we are going to create a User Configuration or Computer Configuration policy and then set the policies. Apply the policy to connections using filters: Using filters we can choose to apply the policy to a specific group of users or computers. Prioritize the policy: In the final (and optional) step, we will assign priority so that policies will override or take precedence over other policies. Working with management consoles In previous versions of Citrix XenApp, Citrix Presentation Server and Citrix MetaFrame policies were stored on the IMA and we managed Citrix policies from the Citrix Management Console. Starting with XenApp 6, policies are stored on the Active Directory and we can manage Citrix policies through the Group Policy Management Console or Local Group Policy Editor in Windows or the Delivery Services Console in XenApp servers. Choosing the right console depends on our network environment and permissions. Using the Group Policy Management Console The Group Policy Management Console (shown in the following screenshot) allows us to view or create Active Directory policies. It also enables us to view the resulting policies applied to users or computers, which is very useful for troubleshooting (more about this is discussed later). If our network environment is based on the Active Directory and we have the appropriate permissions to manage Group Policies (GPO), using the Group Policy Management Console to create policies for our farm is the preferred option. The main reason to use the Group Policy Management Console over the Citrix Delivery Service Console is because Active Directory GPOs take precedence over the farm GPO (also known as IMA GPO). Using the Delivery Services Console The Citrix Delivery Services Console (shown in the following screenshot), formerly known as the Citrix Access Management Console, is a tool that integrates into the Microsoft Management Console (MMC) and enables us to execute management tasks, including creating and viewing Citrix Policies. If we don't have permissions to manage the Active Directory of our company or if our environment doesn't use the Active Directory, we need to use the Citrix Delivery Services Console to create policies for our farm. Policies are stored in a farm GPO in the Citrix data store. In the Citrix Delivery Services Console, we can view the policies configuration by clicking on the Policies node, then select either the Computer or User tabs in the middle pane. When we click on one of these two tabs, three more tabs will be displayed, as shown in the following screenshot. Summary: Shows the settings and filters configured for the selected policy Settings: Shows available and configured settings by category for the selected policy Filters: Shows the available and configured filters applied to the selected policy Using the Local Group Policy Editor If we don't want to use the Citrix Delivery Services Console, we don't have permissions to modify or create a GPO in the Active Directory, or we don't have an Active Directory domain (a NetWare network or workgroup, for example), we have another option. We can create a local GPO using the Local Group Policy Editor (shown in the following screenshot). If we type GPEDIT.MSC, from Start | Run, the Local Group Policy Editor will open. We can modify the local policy of a single server, so it is useful to create or edit a policy in one or maybe a couple of servers, for example, silos or test servers, but it is not useful for medium to large farms. The Local Group Policy will affect everyone who logs onto this machine—including users accessing via Citrix and administrators. We can access policies and their settings in the Local Group Policy Editor, by clicking the Citrix Policies node under User Configuration or the Computer Configuration in the tree pane, located on the left. Active Directory Group policies take precedence over farm GPO; and farm GPO takes precedence over Local Group policies.
Read more
  • 0
  • 0
  • 12943

article-image-exploratory-data-analysis-eda-spark-sql
Amarabha Banerjee
21 Dec 2017
7 min read
Save for later

How to perform Exploratory Data Analysis (EDA) with Spark SQL

Amarabha Banerjee
21 Dec 2017
7 min read
[box type="note" align="" class="" width=""]Below given post is a book excerpt taken from Learning Spark SQL written by Aurobindo Sarkar. This book will help you design, implement, and deliver successful streaming applications, machine learning pipelines and graph applications using Spark SQL API.[/box] Our article aims to give you an understanding of how exploratory data analysis is performed with Spark SQL. What is Exploratory Data Analysis (EDA) Exploratory Data Analysis (EDA), or Initial Data Analysis (IDA), is an approach to data analysis that attempts to maximize insight into data. This includes assessing the quality and structure of the data, calculating summary or descriptive statistics, and plotting appropriate graphs. It can uncover underlying structures and suggest how the data should be modeled. Furthermore, EDA helps us detect outliers, errors, and anomalies in our data, and deciding what to do about such data is often more important than other, more sophisticated analysis. EDA enables us to test our underlying assumptions, discover clusters and other patterns in our data, and identify the possible relationships between various variables. A careful EDA process is vital to understanding the data and is sometimes sufficient to reveal such poor data quality that using a more sophisticated model-based analysis is not justified. Typically, the graphical techniques used in EDA are simple, consisting of plotting the raw data and simple statistics. The focus is on the structures and models revealed by the data or best fit the data. EDA techniques include scatter plots, box plots, histograms, probability plots, and so on. In most EDA techniques, we use all of the data, without making any underlying assumptions. The analyst builds intuition, or gets a "feel", for the Dataset as a result of such exploration. More specifically, the graphical techniques allow us to efficiently select and validate appropriate models, test our assumptions, identify relationships, select estimators, detect outliers, and so on. EDA involves a lot of trial and error, and several iterations. The best way is to start simple and then build in complexity as you go along. There is a major trade-off in modeling between the simple and the more accurate ones. Simple models may be much easier to interpret and understand. These models can get you to 90% accuracy very quickly, versus a more complex model that might take weeks or months to get you an additional 2% improvement. For example, you should plot simple histograms and scatter plots to quickly start developing an intuition for your data. Using Spark SQL for basic data analysis Interactively, processing and visualizing large data is challenging as the queries can take a long time to execute and the visual interface cannot accommodate as many pixels as data points. Spark supports in-memory computations and a high degree of parallelism to achieve interactivity with large distributed data. In addition, Spark is capable of handling petabytes of data and provides a set of versatile programming interfaces and libraries. These include SQL, Scala, Python, Java and R APIs, and libraries for distributed statistics and machine learning. For data that fits into a single computer, there are many good tools available, such as R, MATLAB, and others. However, if the data does not fit into a single machine, or if it is very complicated to get the data to that machine, or if a single computer cannot easily process the data, then this section will offer some good tools and techniques for data exploration. In this section, we will go through some basic data exploration exercises to understand a sample Dataset. We will use a Dataset that contains data related to direct marketing campaigns (phone calls) of a Portuguese banking institution. The marketing campaigns were based on phone calls to customers. We'll use the bank-additional-full.csv file that contains 41,188 records and 20 input fields, ordered by date (from May 2008 to November 2010). The Dataset has been contributed by S. Moro, P. Cortez, and P. Rita, and can be downloaded from https://archive.ics.uci.edu/ml/datasets/Bank+Marketing. As a first step, let's define a schema and read in the CSV file to create a DataFrame. You can use :paste command to paste initial set of statements in your Spark shell session (use Ctrl+D to exit the paste mode), as shown: 2. After the DataFrame has been created, we first verify the number of records: We can also define a case class called Call for our input records, and then create a strongly-typed Dataset, as follows: Identifying missing data Missing data can occur in Datasets due to reasons ranging from negligence to a refusal on the part of respondents to provide a specific data point. However, in all cases, missing data is a common occurrence in real-world Datasets. Missing data can create problems in data analysis and sometimes lead to wrong decisions or conclusions. Hence, it is very important to identify missing data and devise effective strategies to deal with it. In this section, we analyze the numbers of records with missing data fields in our sample Dataset. In order to simulate missing data, we will edit our sample Dataset by replacing fields containing "unknown" values with empty strings. First, we created a DataFrame/Dataset from our edited file, as shown: In the next section, we will compute some basic statistics for our sample Dataset to improve our understanding of the data. Computing basic statistics Computing basic statistics is essential for a good preliminary understanding of our data. First, for convenience, we create a case class and a Dataset containing a subset of fields from our original DataFrame. In the following example, we choose some of the numeric fields and the outcome field, that is, the "term deposit subscribed" field: Next, we use describe() compute the count, mean, stdev, min, and max values for the numeric columns in our Dataset. The describe() command gives a way to do a quick sense-check on your data. For example, the counts of rows of each of the columns selected matches the total number records in the DataFrame (no null or invalid rows),whether the average and range of values for the age column matching your expectations, and so on. Based on the values of the means and standard deviations, you can get select certain data elements for deeper analysis. For example, assuming normal distribution, the mean and standard deviation values for age suggest most values of age are in the range 30 to 50 years, for other columns the standard deviation values may be indicative of a skew in the data (as the standard deviation is greater than the mean). Identifying data outliers An outlier or an anomaly is an observation of the data that deviates significantly from other observations in the Dataset. These erroneous outliers can be due to errors in the data collection or variability in measurement. They can impact the results significantly so it is imperative to identify them during the EDA process. However, these techniques define outliers as points, which do not lie in clusters. The user has to model the data points using statistical distributions, and the outliers are identified depending on how they appear in relation to the underlying model. The main problem with these approaches is that during EDA, the user typically does not have enough knowledge about the underlying data distribution. EDA, using a modeling and visualizing approach, is a good way of achieving a deeper intuition of our data. Spark MLlib supports a large (and growing) set of distributed machine learning algorithms to make this task simpler. For example, we can apply clustering algorithms and visualize the results to detect outliers in a combination columns. In the following example, we use the last contact duration, in seconds (duration), number of contacts performed during this campaign, for this client (campaign), number of days that have passed by after the client was last contacted from a previous campaign (pdays) and the previous: number of contacts performed before this campaign and for this client (prev) values to compute two clusters in our data by applying the k-means clustering algorithm: If you liked this article, please be sure to check out Learning Spark SQL which will help you learn more useful techniques on data extraction and data analysis.    
Read more
  • 0
  • 0
  • 12937

article-image-installation-cacti
Packt
11 Apr 2011
8 min read
Save for later

Installation of Cacti

Packt
11 Apr 2011
8 min read
Preparing the system—basic prerequisites In order to install and run Cacti, we need to make sure that all system prerequisites are met. Here we'll give an overview of the different components needed. Web server As most of Cacti is built as a web interface, a web server is needed. This can be Apache's httpd or Microsoft's Internet Information Server (IIS) if installing on Windows, but in fact, any PHP-capable web server can be used to run the web interface. For optimal support, the use of Apache or IIS is suggested. PHP Cacti is built with the PHP programming language and therefore needs PHP to be installed on the system. Most Linux distributions already have a base PHP environment installed, but some might need additional packages for Cacti to function properly. In particular, the LDAP, SNMP, and MySQL extensions should be installed. MySQL database Cacti uses the freely available MySQL database engine as its database server and it is available on most operating systems. One should note that the database server does not need to be installed on the same host as Cacti. For best performance, MySQL version 5 should be used. NET-SNMP package The NET-SNMP package provides the SNMP binaries used by Cacti and supports SNMPv1, SNMPv2c, and SNMPv3. The NET-SNMP package also provides the SNMP daemon for Linux. Installing Cacti on a CentOS 5 system You're now going to install Cacti from source on a CentOS 5 system. You should use at least Centos 5.5 as it is 100% binary compatible with RedHat Enterprise Linux 5, but in fact you can follow most of the installation processes on other Linux distributions, such as Ubuntu or SuSe Linux, as well. By installing from source you'll get some insight into the inner workings of Cacti, and it will also provide you with a system which most Cacti and plugin developers are used to. There are differences between a source installation and a Yum/APT installation, but they will be described later on. Let's get started. Preparing the system Assume that the CentOS system has been installed with only the "Server Package" selected and there is no graphical user interface installed. This is the default installation for a CentOS system with no manual package selection. Time for action – installing the missing packages The default CentOS installation is missing several important packages. So, we are now going to install these. Install the RPMForge repository. For a 32bit CentOS installation this can be achieved by executing the following command (all on one line): rpm -Uhv http://apt.sw.be/redhat/el5/en/i386/rpmforge/RPMS/rpmforge-release-0.3.6-1.el5.rf.i386.rpm The RPMForge repository includes an RRDtool version for CentOS. Issue the following command to install all required packages: yum install mysql-server php-mysql net-snmp-utils rrdtool php-snmp What just happened? You just gave the system a location to find the remaining packages needed for the Cacti installation and then installed them; therefore, you are now ready to start the next installation phase. Downloading and extracting Cacti Go to http://www.cacti.net and download the latest version of Cacti. In the top-left corner, under Latest Files, right-click on the tar.gz file and save the link address to the clipboard. You are going to need this link later. For simplicity we're assuming that your server has an Internet connection. Time for action – downloading Cacti It's now time to download the latest version of Cacti to your server. You will need your system username and password to login to your CentOS installation. If you have installed your CentOS system with the default settings, you should already have an SSH server running. If you're already logged on to the machine, you can ignore the first step. From a Windows machine, logon to your system using an SSH client such as Putty. If this is the first time you have connected to the server, Putty will display a security alert and ask you to accept the RSA key. By doing so, Putty will display the logon prompt where you can logon to the system. Maximize the window, so that long text lines do not break at the end of the line. This will make things easier. You'll need to become the root user in order to be able to setup Cacti properly. Should that not be an option, performing these steps with sudo should achieve the same results. Navigate to /var/www/html. This is the document root for Apache. To download Cacti you can use the wget command. Enter the following command to download Cacti. After entering the wget command, right-clicking into the window client using Putty will paste the URL you copied earlier after the command: wget http://www.cacti.net/downloads/cacti-0.8.7g.tar.gz You should see the following output on your screen: You now have the tar.gz file on your system, so let's move on and extract it. To do this, enter the following command: tar-xzvf cacti-0.8.7g.tar.gz This will extract the files and directories contained in the archive to the current directory. Finally you are going to create a symbolic link to this new Cacti directory. This will allow you to easily switch between different Cacti versions later, for example, when upgrading Cacti. To create a symbolic link, enter the following command: ln -s cacti-0.8.7g cacti This will create a link named cacti which points to the cacti-0.8.7g directory: What just happened? You downloaded the latest Cacti version to the root directory of the web server and created a symbolic link to the extracted directory. With the Cacti files in place, you are now ready for the next phase of the installation process. Creating the database The database isn't automatically created during the installation of Cacti. Therefore, you need to create it here. At the same time, a database user for Cacti should be created to allow it to access the database. It's also a good idea to secure the MySQL database server by using one of the included CentOS tools. Execute the following command to logon to the MySQL CLI: mysql -u root mysql The default MySQL root account does not have a password set, so you can set one as follows: SET PASSWORD FOR root@localhost = PASSWORD('MyN3wpassw0rd'); You can now also remove the example database, as it is not needed: DROP DATABASE test; Together with the example database, some example users may have been created. You can remove these with the following command: DELETE FROM user WHERE NOT (host = "localhost" AND user = "mydbadmin"); On a CentOS distribution you can use the following command to guide you through the above steps: /usr/bin/mysql_secure_installation Now that MySQL is secured, let's create the Cacti database. Enter the following command: mysqladmin -u root -p create cacti This will ask for the MySQL root password which you provided in Setup Step 1. When finished, you will have an empty database called cacti. As the database is still empty, you need to create the tables and fill it with the initial data that comes with Cacti. The following command will do just that: mysql -p cacti < /var/www/html/cacti/cacti.sql Again it will ask for the MySQL root password. Once the command finishes you'll have a working Cacti database. Unfortunately, Cacti is still unable to access it, therefore you are now going to create a database user for Cacti. Enter the following command: mysql -u root -p mysql You'll see the following on the screen: Type the next few lines in the MySQL prompt to create the user. Make sure to choose a strong password: GRANT ALL ON cacti.* TO cactiuser@localhost IDENTIFIED BY 'MyV3ryStr0ngPassword'; flush privileges; exit What just happened? You used some tools to secure the MySQL server and created a database. You also filled the Cacti database with the initial data and created a MySQL user for Cacti. However, Cacti still needs to know how to access the database, so let's move on to the next step. In case you are not using CentOS to install Cacti, you can use some MySQL internal functions to secure your installation. Configuring Cacti You need to tell Cacti where to find the database and which credentials it should use to access it. This is done by editing the config.php file in the include directory. Time for action – configuring Cacti The database and some other special configuration tasks are done by editing the information in the config.php file. Navigate to the cacti directory: cd /var/www/html/cacti/include Edit config.php with vi: vi config.php Change the $database_username and $database_password fields to the previously created username and password. Change the line $config['url_path'] = '/' to $config['url_path'] = '/cacti/' What just happened? You changed the database configuration for Cacti to the username and password that you created earlier. These settings will tell Cacti where to find the database and what credentials it needs to use to connect to it. You also changed the default URL path to fit your installation. As you install Cacti to /var/www/html/cacti, a sub-directory of the document root, you need to change this setting to /cacti/, otherwise Cacti will not work correctly.
Read more
  • 0
  • 0
  • 12933

article-image-app-development-using-react-native-vs-androidios
Manuel Nakamurakare
03 Mar 2016
6 min read
Save for later

App Development Using React Native vs. Android/iOS

Manuel Nakamurakare
03 Mar 2016
6 min read
Until two years ago, I had exclusively done Android native development. I had never developed iOS apps, but that changed last year, when my company decided that I had to learn iOS development. I was super excited at first, but all that excitement started to fade away as I started developing our iOS app and I quickly saw how my productivity was declining. I realized I had to basically re-learn everything I learnt in Android: the framework, the tools, the IDE, etc. I am a person who likes going to meetups, so suddenly I started going to both Android and iOS meetups. I needed to keep up-to-date with the latest features in both platforms. It was very time-consuming and at the same time somewhat frustrating since I was feeling my learning pace was not fast enough. Then, React Native for iOS came out. We didn’t start using it until mid 2015. We started playing around with it and we really liked it. What is React Native? React Native is a technology created by Facebook. It allows developers to use JavaScript in order to create mobile apps in both Android and iOS that look, feel, and are native. A good way to explain how it works is to think of it as a wrapper of native code. There are many components that have been created that are basically wrapping the native iOS or Android functionality. React Native has been gaining a lot of traction since it was released because it has basically changed the game in many ways. Two Ecosystems One reason why mobile development is so difficult and time consuming is the fact that two entirely different ecosystems need to be learned. If you want to develop an iOS app, then you need to learn Swift or Objective-C and Cocoa Touch. If you want to develop Android apps, you need to learn Java and the Android SDK. I have written code in the three languages, Swift, Objective C, and Java. I don’t really want to get into the argument of comparing which of these is better. However, what I can say is that they are different and learning each of them takes a considerable amount of time. A similar thing happens with the frameworks: Cocoa Touch and the Android SDK. Of course, with each of these frameworks, there is also a big bag of other tools such as testing tools, libraries, packages, etc. And we are not even considering that developers need to stay up-to-date with the latest features each ecosystem offers. On the other hand, if you choose to develop on React Native, you will, most of the time, only need to learn one set of tools. It is true that there are many things that you will need to get familiar with: JavaScript, Node, React Native, etc. However, it is only one set of tools to learn. Reusability Reusability is a big thing in software development. Whenever you are able to reuse code that is a good thing. React Native is not meant to be a write once, run everywhere platform. Whenever you want to build an app for them, you have to build a UI that looks and feels native. For this reason, some of the UI code needs to be written according to the platform's best practices and standards. However, there will always be some common UI code that can be shared together with all the logic. Being able to share code has many advantages: better use of human resources, less code to maintain, less chance of bugs, features in both platforms are more likely to be on parity, etc. Learn Once, Write Everywhere As I mentioned before, React Native is not meant to be a write once, run everywhere platform. As the Facebook team that created React Native says, the goal is to be a learn once, write everywhere platform. And this totally makes sense. Since all of the code for Android and iOS is written using the same set of tools, it is very easy to imagine having a team of developers building the app for both platforms. This is not something that will usually happen when doing native Android and iOS development because there are very few developers that do both. I can even go farther and say that a team that is developing a web app using React.js will not have a very hard time learning React Native development and start developing mobile apps. Declarative API When you build applications using React Native, your UI is more predictable and easier to understand since it has a declarative API as opposed to an imperative one. The difference between these approaches is that when you have an application that has different states, you usually need to keep track of all the changes in the UI and modify them. This can become a complex and very unpredictable task as your application grows. This is called imperative programming. If you use React Native, which has declarative APIs, you just need to worry about what the current UI state looks like without having to keep track of the older ones. Hot Reloading The usual developer routine when coding is to test changes every time some code has been written. For this to happen, the application needs to be compiled and then installed in either a simulator or a real device. In case of React Native, you don’t, most of the time, need to recompile the app every time you make a change. You just need to refresh the app in the simulator, emulator, or device and that’s it. There is even a feature called Live Reload that will refresh the app automatically every time it detects a change in the code. Isn’t that cool? Open Source React Native is still a very new technology; it was made open source less than a year ago. It is not perfect yet. It still has some bugs, but, overall, I think it is ready to be used in production for most mobile apps. There are still some features that are available in the native frameworks that have not been exposed to React Native but that is not really a big deal. I can tell from experience that it is somewhat easy to do in case you are familiar with native development. Also, since React Native is open source, there is a big community of developers helping to implement more features, fix bugs, and help people. Most of the time, if you are trying to build something that is common in mobile apps, it is very likely that it has already been built. As you can see, I am really bullish on React Native. I miss native Android and iOS development, but I really feel excited to be using React Native these days. I really think React Native is a game-changer in mobile development and I cannot wait until it becomes the to-go platform for mobile development!
Read more
  • 0
  • 0
  • 12911

article-image-part2-chatops-slack-and-aws-cli
Yohei Yoshimuta
18 Oct 2015
5 min read
Save for later

Part2. ChatOps with Slack and AWS CLI

Yohei Yoshimuta
18 Oct 2015
5 min read
In part 1 of this series, we installed the AWS-CLI tool, created an AWS EC2 instance, listed one, terminated one, and downloaded an AWS S3 content via AWS CLI instead of UI. Now that we know AWS CLI is very useful and that it supports an extensive API, let's use it more for daily development and operation works through Slack, which is a very popular chat tool. ChatOps, which is used in the title, means doing operations via a chat tool. So, before explaining the full process, I assume you are using Slack. Let's see how we can control EC2 instances using Slack. Integrate Slack with Hubot At first, you need to setup Hubot project with Slack Adapter on your machine. I assume that your machine is MacOSX, but the way to setup is not so different. # Install redis $ brew install redis # Install node $ brew install node # Install npm packages npm install -g hubot coffee-script yo generator-hubot # Make your project directory mkdir -p /path/to/hubot cd /path/to/hubot # Generate your project basement yohubot ? Owner: yoheimuta<yoheimuta@gmail.com> ? Bot name: hubot ? Description: A simple helpful robot for your Company ? Bot adapter: (campfire) slack ? Bot adapter: slack Then, you have to register an integration with Hubot on a Slack configuration page. This page issues an API Token that is necessary to work the integration. # Run the hubot $ HUBOT_SLACK_TOKEN=YOUR-API-TOKEN ./bin/hubot --adapter slack If all works as expected, Slack should respond PONG when you type hubot-name ping in Slack UI. Install hubot-aws module Ok, you are ready to introduce hubot-aws which makes Slack to be your team's AWS CLI environment. # Install and add hubot-aws to your package.json file: $ npm install --save hubot-aws # Addhubot-aws to your external-scripts.json: $ vi external-scripts.json # Set an AWS credential if your machine has no ~./aws/credentials $ export HUBOT_AWS_ACCESS_KEY_ID="ACCESS_KEY" $ export HUBOT_AWS_SECRET_ACCESS_KEY="SECRET_ACCESS_KEY" # Set an AWS region no matter whether your machine has ~/.aws/config or not $ export HUBOT_AWS_REGION="us-west-2" # Set a DEBUG flag until you use in production $ export HUBOT_AWS_DEBUG="1" Run an EC2 instance We are going to run an EC2 instance, which is provisioned mongodb, nodejs and Let's Chat — Self-hosted chat for small teams app. In order to run it, we first need to create config files. $ mkdiraws_config $ cdaws_config/ # Prepare option parameters $ viapp.cson $ catapp.cson MinCount: 1 MaxCount: 1 ImageId: "ami-936d9d93" KeyName: "my-key" InstanceType: "t2.micro" Placement: AvailabilityZone: "us-west-2" NetworkInterfaces: [ { Groups: [ "sg-***" ] SubnetId : "subnet-***" DeviceIndex : 0 AssociatePublicIpAddress : true } ] # Prepare a provisioning shell script $ viinitfile $ catinitfile #!/bin/bash # Install mongodb sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10 sudo echo "deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen" | sudo tee -a /etc/apt/sources.list.d/10gen.list # Install puppet sudowget -P /tmp https://apt.puppetlabs.com/puppetlabs-release-precise.deb sudodpkg -i /tmp/puppetlabs-release-precise.deb sudo apt-get -y update sudo apt-get -y install puppet 2>&1 | tee /tmp/initfile.log # Install a puppet module sudo puppet module install jay-letschat 2>&1 | tee /tmp/initfile1.log # Create a puppet manifest sudosh -c "cat >> /etc/puppet/manifests/letschat.pp<<'EOF'; class { 'letschat::db': user => 'lcadmin', pass => 'unsafepassword', bind_ip => '0.0.0.0', database_name => 'letschat', database_port => '27017', } -> class { 'letschat::app': dbuser => 'lcadmin', dbpass => 'unsafepassword', dbname => 'letschat', dbhost => 'localhost', dbport => '27017', deploy_dir => '/etc/letschat', http_enabled => true, lc_bind_address => '0.0.0.0', http_port => '5000', ssl_enabled => false, cookie => 'secret', authproviders => 'local', registration => true, } EOF" # Apply a puppet manifest sudo puppet apply /etc/puppet/manifests/letschat.pp 2>&1 | tee /tmp/initfile2.log $ export HUBOT_AWS_EC2_RUN_CONFIG="aws_config/app.cson" $ export HUBOT_AWS_EC2_RUN_USERDATA_PATH="aws_config/initfile" $ HUBOT_SLACK_TOKEN=YOUR-API-TOKEN ./bin/hubot --adapter slack Let's type hubot ec2 run --dry-run to validate the config and then hubot ec2 run to start running an EC2 instance. Enter public-ipaddr:5000 into a browser to enjoy Let's Chat app after initialization of the instance (maybe it takes about 5 minutes). You will find public-ipaddr from AWS UI or hubot ec2 ls --instance_id=*** (this command is described below). List running EC2 instances You now have created an EC2 instance. The detail of running EC2 instances is displayed whenever your colleague and you type hubot ec2 ls. It's cool. Terminate an EC2 instance Well, it's time to terminate an EC2 instance to save money. Type hubot ec2 terminate --instance_id=***. That's all. Conclusion ChatOps is very useful, especially for your team's routine ops work. For our team's example, we ran a temporal app instance to test a development feature before deploying it in production, terminating a problematic EC2 instance logging errors, and creating settings about Auto Scaling that is relatively difficult to automate completely yet like using Terraform for our team. Hubot-AWS works for dev&ops engineers who want to use AWS CLI while sharing ops with their colleagues but have no time to completely automate. About the author YoheiYoshimuta is a software engineer with a proven record of delivering high quality software in both game and advertising industries. He has extensive experience in building products from scratch in small and large team. His primary focuses are Perl, Go and AWS technologies. You can reach him at @yoheimutaonGitHubandTwitter.
Read more
  • 0
  • 1
  • 12891

article-image-functional-testing-jmeter
Packt
22 Oct 2009
5 min read
Save for later

Functional Testing with JMeter

Packt
22 Oct 2009
5 min read
JMeter is a 100% pure Java desktop application. JMeter is found to be very useful and convenient in support of functional testing. Although JMeter is known more as a performance testing tool, functional testing elements can be integrated within the Test Plan, which was originally designed to support load testing. Many other load-testing tools provide little or none of this feature, restricting themselves to performance-testing purposes. Besides integrating functional-testing elements along with load-testing elements in the Test Plan, you can also create a Test Plan that runs these exclusively. In other words, aside from creating a Load Test Plan, JMeter also allows you to create a Functional Test Plan. This flexibility is certainly resource-efficient for the testing project. In this article by Emily H. Halili, we will give you a walkthrough on how to create a Test Plan as we incorporate and/or configure JMeter elements to support functional testing. Preparing for Functional Testing JMeter does not have a built-in browser, unlike many functional-test tools. It tests on the protocol layer, not the client layer (i.e. JavaScripts, applets, and many more.) and it does not render the page for viewing. Although, by default that embedded resources can be downloaded, rendering these in the Listener | View Results Tree may not yield a 100% browser-like rendering. In fact, it may not be able to render large HTML files at all. This makes it difficult to test the GUI of an application under testing. However, to compensate for these shortcomings, JMeter allows the tester to create assertions based on the tags and text of the page as the HTML file is received by the client. With some knowledge of HTML tags, you can test and verify any elements as you would expect them in the browser. It is unnecessary to select a specific workload time to perform a functional test. In fact, the application you want to test may even reside locally, with your own machine acting as the "localhost" server for your web application. For this article, we will limit ourselves to selected functional aspects of the page that we seek to verify or assert. Using JMeter Components We will create a Test Plan in order to demonstrate how we can configure the Test Plan to include functional testing capabilities. The modified Test Plan will include these scenarios: 1. Create Account —New Visitor creating an Account 2. Login User —User logging in to an Account Following these scenarios, we will simulate various entries and form submission as a request to a page is made, while checking the correct page response to these user entries. We will add assertions to the samples following these scenarios to verify the 'correctness' of a requested page. In this manner, we can see if the pages responded correctly to invalid data. For example, we would like to check that the page responded with the correct warning message when a user enters an invalid password, or whether a request returns the correct page. First of all, we will create a series of test cases following the various user actions in each scenario. The test cases may be designed as follows: CREATE ACCOUNT Test Steps Data Expected 1 Go to Home page. www.packtpub.com Home page loads and renders with no page error 2 Click Your Account link (top right). User action 1. Your Account page loads and renders with no page error.2. Logout link is not found. 3 No Password: - Enter email address in Email text field.- Click the Create Account and Continue button. email=EMAIL 1. Your Account page resets with Warning message-Please enter password.2. Logout link not found. 4 Short Password: - Enter email address in Email text field.- Enter password in Password text field.- Enter password in Confirm Password text field. - Click Create Account and Continue button. email=EMAILpassword=SHORT_PWD confirm password=SHORT_PWD 1. Your Account page resets with Warning message-Your password must be 8 characters or longer.2. Logout link is not found. 5 Unconfirmed Password: - Enter email address in Email text field.- Enter password in Password text field.- Enter password in Confirm Password text field. - Click Create Account and Continue button. email=EMAILpassword=VALID_PWDconfirm password=INVALID_PWD 1. Your Account page resets with Warning messagePassword does not match.2. Logout link is not found. 6 Register Valid User: - Enter email address in Email text field.- Enter password in Password text field.- Enter password in Confirm Password text field. - Click Create Account and Continue button. email=EMAILpassword=VALID_PWDconfirm password=VALID_PWD 1. Logout link is found.2. Page redirects to User Account page.3. Message found: You are registered as: e:<EMAIL>. 7 Click Logout link. User action 1. Logout link is NOT found.     LOGIN USER Test Steps Data Expected 1 Click Home page. User action 1. WELCOME tab is active. 2 Log in Wrong Password: - Enter email in Email text field- Enter password at Password text field.- Click Login button. email=EMAILpassword=INVALID_PWD 1. Logout link is NOT found.2. Page refreshes.3. Warning message-Sorry your password was incorrect appears. 3 Log in Non-Exist Account:- Enter email in Email text field.- Enter password in Password text field.- Click Login button. email=INVALID_EMAILpassword=INVALID_PWD 1. Logout link is NOT found.2. Page refreshes.3. Warning message-Sorry, this does not match any existing accounts. Please check your details and try again or open a new account below appears. 4 Log in Valid Account:- Enter email in Email text field.- Enter password in Password text field.- Click Login-button. email=EMAILpassword=VALID_PWD 1. Logout link is found.2. Page reloads.3. Login successful message-You are logged in as: appears. 5 Click Logout link. User action 1. Logout link is NOT found.    
Read more
  • 0
  • 3
  • 12881
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at ₹800/month. Cancel anytime
article-image-sewable-leds-clothing
Packt
14 Aug 2017
16 min read
Save for later

Sewable LEDs in Clothing

Packt
14 Aug 2017
16 min read
In this article by Jonathan Witts, author of the book Wearable Projects with Raspberry Pi Zero, we will use sewable LEDs and conductive thread to transform an item of clothing into a sparkling LED piece of wearable tech, controlled with our Pi Zero hidden in the clothing. We will incorporate a Pi Zero and battery into a hidden pocket in the garment and connect our sewable LEDs to the Pi's GPIO pins so that we can write Python code to control the order and timings of the LEDs. (For more resources related to this topic, see here.) To deactivate the software running automatically, connect to your Pi Zero over SSH and issue the following command: sudo systemctl disable scrollBadge.service Once that command completes, you can shutdown your Pi Zero by pressing your off-switch for three seconds. Now let's look at what we are going to cover in this article. What We Will Cover  In this article we will cover the following topics: What we will need to complete the project in this article How we will modify our item of clothing Writing a Python program to control the electronics in our modified garment Making our program run automatically Let's jump straight in and look at what parts we will need to complete the project in this article. Bill of parts  We will make use of the following things in the project in this article: A Pi Zero W An official Pi Zero Case A portable battery pack Item of clothing to modify e.g. a top or t-shirt 10 sewable LEDs Conductive Thread Some fabric the same color as the clothing Thread the same color as the clothing A sewing needle Pins 6 metal poppers Some black and yellow colored cable Solder and soldering iron Modifying our item of clothing  So let's take a look at what we need to do to modify our item of clothing ready to accommodate our Pi Zero, battery pack and sewable LEDs. We will start by looking at creating our hidden pocket for the Pi Zero and the batteries, followed by how we will sew our LEDs into the top and design our sewable circuit. We will then solve the problem of connecting our conductive thread back to the GPIO holes on our Pi Zero. Our hidden pocket  You will need a piece of fabric that is large enough to house your Pi Zero case and battery pack alongside each other, with enough spare to hem the pocket all the way round. If you have access to a sewing machine then this section of the project will be much quicker, otherwise you will need to do the stitching by hand. The piece of fabric I am using is 18 x 22 cm allowing for a 1 cm hem all around. Fold and pin the 1 cm hem and then either stitch by hand or run it through a sewing machine to secure your hem. When you have finished, remove the pins. You need to then turn your garment inside out and decide where you are going to position your hidden pocket. As I am using a t-shirt for my garment I am going to position my pocket just inside at the bottom side of the garment, wrapping around the front and back so that it sits across the wearer's hip. Pin your pocket in place and then stitch it along the bottom and left and right sides, leaving the top open. Make sure that you stitch this nice and firmly as it has to hold the weight of your battery pack. The picture below shows you my pocket after being stitched in place. When you have finished this you can remove the pins and turn your garment the correct way round again. Adding our sewable LEDs  We are now going to plan our circuit for our sewable LEDs and add them to the garment. I am going to run a line of 10 LEDs around the bottom of my top. These will be wired up in pairs so that we can control a pair of LEDs at any one time with our Pi Zero. You can position your LEDs however you want, but it is important that the circuits of conductive thread do not cross one another. Turn your garment inside out again and mark with a washable pen where you want your LEDs to be sewn. As the fabric for my garment is quite light I am going to just stitch them inside and let the LED shine through the material. However if your material is heavier then you will have to put a small cut where each LED will be and then button-hole the cut so the LED can push through. Start with the LED furthest from your hidden pocket. Once you have your LED in position take a length of your conductive thread and over-sew the negative hole of your LED to your garment, trying to keep your stitches as small and as neat as possible, to minimize how much they can be seen from the front of the garment. You now need to stitch small running stitches from the first LED to the second, ensure that you use the same piece of conductive thread and do not cut it! When you get to the position of your LED, again over-sew the negative hole of your LED ensuring that it is face down so that the LED shows through the fabric. As I am stitching my LEDs quite close to the hem of my t-shirt, I have made use of the hem to run the conductive thread in when connecting the negative holes of the LEDs, as shown in the following image: Continue on connecting each negative point of your LEDs to each other with a single length of conductive thread. Your final LED will be the one closest to your hidden pocket, continue with a running stitch until you are on your hidden pocket. Now take the male half of one of your metal poppers and over-sew this in place through one of the holes. You can now cut the length of conductive thread as we have completed our common ground circuit for all the LEDs. Now stitch the three remaining holes with standard thread, as shown in this picture. When cutting the conductive thread be sure to leave a very short end. If two pieces of thread were to touch when we were powering the LEDs we could cause a short circuit. We now need to sew our positive connections to our garment. Start with a new length of conductive thread and attach the LED second closest to your hidden pocket. Again over-sew it it to the fabric trying to ensure that your stitches are as small as possible so they are not very visible from the front of the garment. Now you have secured the first LED, sew a small running stitch to the positive connection on the LED closest to the hidden pocket. After securing this LED stitch a running stitch so that it stops alongside the popper you previously secured to your pocket, and this time attach a female half of a metal popper in the same way as before, as shown in this picture: Secure your remaining 8 LEDs in the same fashion, working in pairs, away from the pocket. so that you are left with 1 male metal popper and 5 female metal poppers in a line on your hidden pocket. Ensure that the 6 different conductive threads do not cross at any point, the six poppers do not touch and that you have the positive and negative connections the right way round! The picture below shows you the completed circuit stitched into the t-shirt, terminating at the poppers on the pocket. Connecting our Pi Zero Now we have our electrical circuit we need to find a way to attach our Pi Zero to each pair of LEDs and the common ground we have sewn into our garment. We are going to make use of the poppers we stitched onto our hidden pocket for this. You have probably noticed that the only piece of conductive thread which we attached the male popper to was the common ground thread for our LEDs. This is so that when we construct our method of attaching the Pi Zero GPIO pins to the conductive thread it will be impossible to connect the positive and negative threads the wrong way round! Another reason for using the poppers to attach our Pi Zero to the conductive thread is because the LEDs and thread I am using are both rated as OK for hand washing; your Pi Zero is not!  Take your remaining female popper and solder a length of black cable to it, about two and a half times the height of your hidden pocket should do the job. You can feed the cable through one of the holes in the popper as shown in the picture to ensure you get a good connection. For the five remaining male poppers solder the same length of yellow cable to each popper. The picture below shows two of my soldered poppers. Now connect all of your poppers to the other parts on your garment and carefully bend all the cables so that they all run in the same direction, up towards the top of your hidden pocket. Trim all the cable to the same length and then mark the top and bottom of each yellow cable with a permanent marker so that you know which cable is attached to which pair of LEDs. I am marking the bottom yellow cable as number 1 and the top as number 5. We can now cut a length of heat shrink and and cover the loose lengths of cable, leaving about 4 cm free to strip, tin and solder onto your Pi. You can now heat the heat shrink with a hair dryer to shrink it around your cables. We are now going to stitch together a small piece of fabric to attach the poppers to. We want to end up with a piece of fabric which is large enough to sew all six poppers to and to stitch the uncovered cables down to. This will be used to detach the Pi Zero from our garment when we need to wash it, or just remove our Pi Zero for another project. To strengthen up the fabric I am doubling it over and hemming a long and short side of the fabric to make a pocket. This can then be turned inside out and the remaining short side stitched over. You now need to position these poppers onto your piece of fabric so that they are aligned with the poppers you have sewn into your garment. Once you are happy with their placement, stitch them to the piece of fabric using standard thread, ensuring that they are really firmly attached. If you like you can also put a few stitches over each cable to ensure they stay in place too. Using a fine permanent marker number both ends of the 5 yellow cables 1 through 5 so that you can identify each cable. Now push all 6 cables through about 12 cm of shrink wrap and apply some heat from a hair dryer until it shrinks around your cables.You can strip and tin the ends of the six cables ready to solder them to your Pi Zero. Insert the black cable in the ground hole below GPIO 11 on your Pi Zero and then insert the 5 yellow cables, sequentially 1 through 5, into the GPIO holes 11, 09, 10, 7 and 8 as shown in this diagram, again from the rear of the Pi Zero. When you are happy all the cables are in the correct place, solder them to your Pi Zero and clip off any extra length from the front of the Pi zero with wire snips. You should now be able to connect your Pi Zero to your LEDs by pressing all 6 poppers together. To ensure that the wearer's body does not cause a short circuit with the conductive thread on the inside of the garment, you may want to take another piece of fabric and stitch it over all of the conductive thread lines. I would recommend that you do this after you have tested all your LEDs with the program in the next section. We have now carried out all the modifications needed to our garment, so let's move onto writing our Python program to control our LEDs. Writing Our Python Program  To start with we will write a simple, short piece of Python just to check that all ten of our LEDs are working and we know which GPIO pin controls which pair of LEDs. Power on your Pi Zero and connect to it via SSH. Testing Our LEDs  To check that our LEDs are all correctly wired up and that we can control them using Python, we will write this short program to test them. First move into our project directory by typing: cd WearableTech Now make a new directory for this article by typing: mkdir Chapter3 Now move into our new directory: cd Chapter3 Next we create our test program, by typing: nano testLED.py Then we enter the following code into Nano: #!/usr/bin/python3 from gpiozero import LED from time import sleep pair1 = LED(11) pair2 = LED(9) pair3 = LED(10) pair4 = LED(7) pair5 = LED(8) for i in range(4):     pair1.on()     sleep(2)     pair1.off()     pair2.on()     sleep(2)     pair2.off()     pair3.on()     sleep(2)     pair3.off()     pair4.on()     sleep(2)     pair4.off()     pair5.on()     sleep(2)     pair5.off() Press Ctrl + o followed by Enter to save the file, and then Ctrl + x to exit Nano. We can then run our file by typing: python3 ./testLED.py All being well we should see each pair of LEDs light up for two seconds in turn and then the next pair, and the whole loop should repeat 4 times.  Our final LED program  We will now write our Python program which will control our LEDs in our t-shirt. This will be the program which we configure to run automatically when we power up our Pi Zero. So let's begin...  Create a new file by typing: nano tShirtLED.py Now type the following Python program into Nano: #!/usr/bin/python3 from gpiozero import LEDBoard from time import sleep from random import randint leds = LEDBoard(11, 9, 10, 7, 8) while True: for i in range(5): wait = randint(5,10)/10 leds.on() sleep(wait) leds.off() sleep(wait) for i in range(5): wait = randint(5,10)/10 leds.value = (1, 0, 1, 0, 1) sleep(wait) leds.value = (0, 1, 0, 1, 0) sleep(wait) for i in range(5): wait = randint(1,5)/10 leds.value = (1, 0, 0, 0, 0) sleep(wait) leds.value = (1, 1, 0, 0, 0) sleep(wait) leds.value = (1, 1, 1, 0, 0) sleep(wait) leds.value = (1, 1, 1, 1, 0) sleep(wait) leds.value = (1, 1, 1, 1, 1) sleep(wait) leds.value = (1, 1, 1, 1, 0) sleep(wait) leds.value = (1, 1, 1, 0, 0) sleep(wait) leds.value = (1, 1, 0, 0, 0) sleep(wait) leds.value = (1, 0, 0, 0, 0) sleep(wait) Now save your file by pressing Ctrl + o followed by Enter, then exit Nano by pressing Ctrl + x. Test that your program is working correctly by typing: python3 ./tShirtLED.py If there are any errors displayed, go back and check your program in Nano. Once your program has gone through the three different display patterns, press Ctrl + c to stop the program from running. We have introduced a number of new things in this program, firstly we imported a new GPIOZero library item called LEDBoard. LEDBoard lets us define a list of GPIO pins which have LEDs attached to them and perform actions on our list of LEDs rather than having to operate them all one at a time. It also lets us pass a value to the LEDBoard object which indicates whether to turn the individual members of the board on or off. We also imported randint from the random library. Randint allows us to get a random integer in our program and we can also pass it a start and stop value from which the random integer should be taken. We then define three different loop patterns and set each of them inside a for loop which repeats 5 times. Making our program start automatically  We now need to make our tShirtLED.py program run automatically when we switch our Pi Zero on: First we must make the Python program we just wrote executable, type: chmod +x ./tShirtLED.py Now we will create our service definition file, type: sudo nano /lib/systemd/system/tShirtLED.service Now type the definition into it: [Unit] Description=tShirt LED Service After=multi-user.target [Service] Type=idle ExecStart=/home/pi/WearableTech/Chapter3/tShirtLED.py [Install] WantedBy=multi-user.target Save and exit Nano by typing Ctrl + o followed by Enter and then Ctrl + x. Now change the file permissions, reload the systemd daemon and activate our service by typing: sudo chmod 644 /lib/systemd/system/tShirtLED.service sudo systemctl daemon-reload sudo systemctl enable tShirtLED.service Now we need to test whether this is working, so reboot your Pi by typing sudo reboot and then when your Pi Zero restarts you should see that your LED pattern starts to display automatically. Once you are happy that it is all working correctly press and hold your power-off button for three seconds to shut your Pi Zero down. You can now turn your garment the right way round and install the Pi Zero and battery pack into your hidden pocket. As soon as you plug your battery pack into your Pi Zero your LEDs will start to display their patterns and you can safely turn it all off using your power-off button. Summary In this article we looked at making use of stitchable electronics and how we could combine them with our Pi Zero. We made our first stitchable circuit and found a way that we could connect our Pi Zero to this circuit and control the electronic devices using the GPIO Zero Python library. Resources for Article: Further resources on this subject: Sending Notifications using Raspberry Pi Zero [article] Raspberry Pi LED Blueprints [article] Raspberry Pi and 1-Wire [article]
Read more
  • 0
  • 0
  • 12877

article-image-react-dashboard-and-visualizing-data
Xavier Bruhiere
26 Nov 2015
8 min read
Save for later

React Dashboard and Visualizing Data

Xavier Bruhiere
26 Nov 2015
8 min read
I spent the last six months working on data analytics and machine learning to feed my curiosity and prepare for my new job. It is a challenging mission and I chose to give up for a while on my current web projects to stay focused. Back then, I was coding a dashboard for an automated trading system, powered by an exciting new framework from Facebook : React. In my opinion, Web Components was the way to go and React seemed gentler with my brain than, say, Polymer. One just needed to carefully design components boundaries, properties and states and bam, you got a reusable piece of web to plug anywhere. Beautiful. This is quite a naive way to put it of course but, for an MVP, it actually kind of worked. Fast forward to last week, I was needing a new dashboard to monitor various metrics from my shiny new infrastructure. Specialized requirements kept me away from a full-fledged solution like InfluxDB and Grafana combo, so I naturally starred at my old code. Well, it turned out I did not reuse a single line of code. Since the last time I spent in web development, new tools, frameworks and methodologies had taken over the world : es6 (and transpilers), isomorphic applications, one-way data flow, hot reloading, module bundler, ... Even starter kits are remarkably complex (at least for me) and I got overwhelmed. But those new toys are also truly empowering and I persevered. In this post, we will learn to leverage them, build the simplest dashboard possible and pave the way toward modern, real-time metrics monitoring. Tooling & Motivations I think the points of so much tooling are productivity and complexity management. New single page applications usually involve a significant number of moving parts : front and backend development, data management, scaling, appealing UX, ... Isomorphic webapps with nodejs and es6 try to harmonize this workflow sharing one readable language across the stack. Node already sells the "javascript everywhere" argument but here, it goes even further, with code that can be executed both on the server and in the browser, indifferently. Team work and reusability are improved, as well as SEO (Search Engine optimization) when rendering HTML on server-side. Yet, applications' codebase can turn into a massive mess and that's where Web Components come handy. Providing clear contracts between modules, a developer is able to focus on subpart of the UI with an explicit definition of its parameters and states. This level of abstraction makes the application much more easy to navigate, maintain and reuse. Working with React gives a sense of clarity with components as Javascript objects. Lifecycle and behavior are explicitly detailed by pre-defined hooks, while properties and states are distinct attributes. We still need to glue all of those components and their dependencies together. That's where npm, Webpack and Gulp join the party. Npm is the de facto package manager for nodejs, and more and more for frontend development. What's more, it can run for you scripts and spare you from using a task runner like Gulp. Webpack, meanwhile, bundles pretty much anything thanks to its loaders. Feed it an entrypoint which require your js, jsx, css, whatever ... and it will transform and package them for the browser. Given the steep learning curve of modern full-stack development, I hope you can see the mean of those tools. Last pieces I would like to introduce for our little project are metrics-graphics and react-sparklines (that I won't actually describe but worth noting for our purpose). Both are neat frameworks to visualize data and play nicely with React, as we are going to see now. Graph Component When building components-based interfaces, first things to define are what subpart of the UI those components are. Since we start a spartiate implementation, we are only going to define a Graph. // Graph.jsx // new es6 import syntax import React from 'react'; // graph renderer import MG from 'metrics-graphics'; export default class Graph extends React.Component { // called after the `render` method below componentDidMount () { // use d3 to load data from metrics-graphics samples d3.json('node_modules/metrics-graphics/examples/data/confidence_band.json', function(data) { data = MG.convert.date(data, 'date'); MG.data_graphic({ title: {this.props.title}, data: data, format: 'percentage', width: 600, height: 200, right: 40, target: '#confidence', show_secondary_x_label: false, show_confidence_band: ['l', 'u'], x_extended_ticks: true }); }); } render () { // render the element targeted by the graph return <div id="confidence"></div>; } } This code, a trendy combination of es6 and jsx, defines in the DOM a standalone graph from the json data in confidence_band.json I stole on Mozilla official examples. Now let's actually mount and render the DOM in the main entrypoint of the application (I mentioned above with Webpack). // main.jsx // tell webpack to bundle style along with the javascript import 'metrics-graphics/dist/metricsgraphics.css'; import 'metrics-graphics/examples/css/metricsgraphics-demo.css'; import 'metrics-graphics/examples/css/highlightjs-default.css'; import React from 'react'; import Graph from './components/Graph'; function main() { // it is recommended to not directly render on body var app = document.createElement('div'); document.body.appendChild(app); // key/value pairs are available under `this.props` hash within the component React.render(<Graph title={Keep calm and build a dashboard}/>, app); } main(); Now that we defined in plain javascript the web page, it's time for our tools to take over and actually build it. Build workflow This is mostly a matter of configuration. First, create the following structure. $ tree . ├── app │ ├── components │ │ ├── Graph.jsx │ ├── main.jsx ├── build └── package.json Where package.json is defined like below. { "name": "react-dashboard", "scripts": { "build": "TARGET=build webpack", "dev": "TARGET=dev webpack-dev-server --host 0.0.0.0 --devtool eval-source --progress --colors --hot --inline --history-api-fallback" }, "devDependencies": { "babel-core": "^5.6.18", "babel-loader": "^5.3.2", "css-loader": "^0.15.1", "html-webpack-plugin": "^1.5.2", "node-libs-browser": "^0.5.2", "react-hot-loader": "^1.2.7", "style-loader": "^0.12.3", "webpack": "^1.10.1", "webpack-dev-server": "^1.10.1", "webpack-merge": "^0.1.2" }, "dependencies": { "metrics-graphics": "^2.6.0", "react": "^0.13.3" } } A quick npm install will download every package we need for development and production. Two scripts are even defined to build a static version of the site, or serve a dynamic one that will be updated on file changes detection. This formidable feature becomes essential once tasted. But we have yet to configure Webpack to enjoy it. var path = require('path'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var webpack = require('webpack'); var merge = require('webpack-merge'); // discern development server from static build var TARGET = process.env.TARGET; // webpack prefers abolute path var ROOT_PATH = path.resolve(__dirname); // common environments configuration var common = { // input main.js we wrote earlier entry: [path.resolve(ROOT_PATH, 'app/main')], // import requirements with following extensions resolve: { extensions: ['', '.js', '.jsx'] }, // define the single bundle file output by the build output: { path: path.resolve(ROOT_PATH, 'build'), filename: 'bundle.js' }, module: { // also support css loading from main.js loaders: [ { test: /.css$/, loaders: ['style', 'css'] } ] }, plugins: [ // automatically generate a standard index.html to attach on the React app new HtmlWebpackPlugin({ title: 'React Dashboard' }) ] }; // production specific configuration if(TARGET === 'build') { module.exports = merge(common, { module: { // compile es6 jsx to standard es5 loaders: [ { test: /.jsx?$/, loader: 'babel?stage=1', include: path.resolve(ROOT_PATH, 'app') } ] }, // optimize output size plugins: [ new webpack.DefinePlugin({ 'process.env': { // This has effect on the react lib size 'NODE_ENV': JSON.stringify('production') } }), new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }) ] }); } // development specific configuration if(TARGET === 'dev') { module.exports = merge(common, { module: { // also transpile javascript, but also use react-hot-loader, to automagically update web page on changes loaders: [ { test: /.jsx?$/, loaders: ['react-hot', 'babel?stage=1'], include: path.resolve(ROOT_PATH, 'app'), }, ], }, }); } Webpack configuration can be hard to swallow at first but, given the huge amount of transformations to operate, this style scales very well. Plus, once setup, the development environment becomes remarkably productive. To convince yourself, run webpack-dev-server and reach localhost:8080/assets/bundle.js in your browser. Tweak the title argument in main.jsx, save the file and watch the browser update itself. We are ready to build new components and extend our modular dashboard. Conclusion We condensed in a few paragraphs a lot of what makes the current web ecosystem effervescent. I strongly encourage the reader to deepen its knowledge on those matters and consider this post as it is : an introduction. Web components, like micro-services, are fun, powerful and bleeding edges. But also complex, fast-moving and unstable. The tooling, especially, is impressive. Spend a hard time to master them and craft something cool ! About the Author Xavier Bruhiere is a Lead Developer at AppTurbo in Paris, where he develops innovative prototypes to support company growth. He is addicted to learning, hacking on intriguing hot techs (both soft and hard), and practicing high intensity sports.
Read more
  • 0
  • 0
  • 12873

article-image-qgis-feature-selection-tools
Packt
05 Dec 2014
10 min read
Save for later

QGIS Feature Selection Tools

Packt
05 Dec 2014
10 min read
Make sure to subscribe our BIPro Newsletter so you never miss a key update in the data world. Join over 35K+ BI lovers and get tips from those who’ve cracked tough data challenges! In this article by Anita Graser, the author of Learning QGIS Third Edition, we will cover the following topics:Selecting features with the mouseSelecting features using expressionsSelecting features using Spatial queries(For more resources related to this topic, see here.)Selecting features with the mouseThe first group of tools in the Attributes toolbar allows us to select features on the map using the mouse. The following screenshot shows the Select Feature(s) tool. We can select a single feature by clicking on it or select multiple features by drawing a rectangle. The other tools can be used to select features by drawing different shapes: polygons, freehand areas, or circles around the features. All features that intersect with the drawn shape are selected. Holding down the Ctrl key will add the new selection to an existing one. Similarly, holding down Ctrl + Shift will remove the new selection from the existing selection.Selecting features by expressionThe second type of select tool is called Select by Expression, and it is also available in the Attribute toolbar. It selects features based on expressions that can contain references and functions using feature attributes and/or geometry. The list of available functions is pretty long, but we can use the search box to filter the list by name to find the function we are looking for faster. On the right-hand side of the window, we will find Selected Function Help, which explains the functionality and how to use the function in an expression. The Function List option also shows the layer attribute fields, and by clicking on Load all unique values or Load 10 sample values, we can easily access their content. As with the mouse tools, we can choose between creating a new selection or adding to or deleting from an existing selection. Additionally, we can choose to only select features from within an existing selection. Let's have a look at some example expressions that you can build on and use in your own work:Using the lakes.shp file in our sample data, we can, for example, select big lakes with an area bigger than 1,000 square miles using a simple attribute query, "AREA_MI" > 1000.0, or using geometry functions such as $area > (1000.0 * 27878400). Note that the lakes.shp CRS uses feet, and we, therefore, have to multiply by 27,878,400 to convert from square feet to square miles. The dialog will look like the one shown in the following screenshot.We can also work with string functions, for example, to find lakes with long names, such as length("NAMES") > 12, or lakes with names that contain the s or S character, such as lower("NAMES") LIKE '%s%', which first converts the names to lowercase and then looks for any appearance of s.Selecting features using spatial queriesThe third type of tool is called Spatial Query and allows us to select features in one layer based on their location, relative to the features in a second layer. These tools can be accessed by going to Vector | Research Tools | Select by location and then going to Vector | Spatial Query | Spatial Query. Enable it in Plugin Manager if you cannot find it in the Vector menu. In general, we want to use the Spatial Query plugin, as it supports a variety of spatial operations such as crosses, equals, intersects, is disjoint, overlaps, touches, and contains, depending on the layer's geometry type.Let's test the Spatial Query plugin using railroads.shp and pipelines.shp from the sample data. For example, we might want to find all the railroad features that cross a pipeline; we will, therefore, select the railroads layer, the Crosses operation, and the pipelines layer. After clicking on Apply, the plugin presents us with the query results. There is a list of IDs of the result features on the right-hand side of the window, as you can see in the following screenshot. Below this list, we can select the Zoom to item checkbox, and QGIS will zoom to the feature that belongs to the selected ID. Additionally, the plugin offers buttons to directly save all the resulting features to a new layer.SummaryThis article introduced you to three solutions to select features in QGIS: selecting features with mouse, using spatial queries, and using expressions.Resources for Article:Further resources on this subject:Editing attributes [article]Server Logs [article]Improving proximity filtering with KNN [article] 
Read more
  • 0
  • 0
  • 12869

article-image-detecting-anomalies-using-llm-sentence-embeddings
Alan Bernardo Palacio
21 Aug 2023
18 min read
Save for later

Detecting Anomalies Using LLM Sentence Embeddings

Alan Bernardo Palacio
21 Aug 2023
18 min read
IntroductionText classification tasks such as natural language inference (NLI) are a central part of modern natural language processing (NLP). In this article, we present an application of unsupervised machine learning techniques to detect anomalies in the MultiNLI dataset.Our aim is to use unsupervised Large Language Models (LLM) to create embeddings and discover patterns and relationships within the data. We'll preprocess the data, generate sentence pair embeddings, and use the Out-Of-Distribution (OOD) module from the cleanlab Python package to get outlier scores.Importing Libraries and Setting SeedsThe following block of code is essentially the initial setup phase of our data processing and analysis script. Here, we import all the necessary libraries and packages that will be used throughout the code. First, we need to install some of the necessary libraries:!pip install cleanlab datasets hdbscan nltk matplotlib numpy torch transformers umap-learnIt is highly recommended to use Google Colab with GPUs or TPUs to be able to create the embeddings in a proper amount of time.Now we can start with the importing of the sentences:import cleanlab import datasets import hdbscan import nltk import matplotlib.pyplot as plt import numpy as np import re import torch from cleanlab.outlier import OutOfDistribution from datasets import load_dataset, concatenate_datasets from IPython.display import display from sklearn.metrics import precision_recall_curve from torch.utils.data import DataLoader from tqdm.auto import tqdm from transformers import AutoTokenizer, AutoModel from umap import UMAP nltk.download('stopwords') datasets.logging.set_verbosity_error() torch.backends.cudnn.deterministic = True torch.backends.cudnn.benchmark = False torch.cuda.manual_seed_all(SEED)Here's what each imported library/package does:cleanlab: A package used for finding label errors in datasets and learning with noisy labels.datasets: Provides easy-to-use, high-level APIs for downloading and preparing datasets for modeling.hdbscan: A clustering algorithm that combines the benefits of hierarchical clustering and density-based spatial clustering of applications with noise (DBSCAN).nltk: Short for Natural Language Toolkit, a leading platform for building Python programs to work with human language data.torch: PyTorch is an open-source machine learning library based on the Torch library, used for applications such as natural language processing.This part of the code also downloads the NLTK (Natural Language Toolkit) stopwords. Stopwords are words like 'a', 'an', and 'the', which are not typically useful for modeling and are often removed during pre-processing. The datasets.logging.set_verbosity_error() sets the logging level to error. This means that only the messages with the level error or above will be displayed.The code also sets some additional properties for CUDA operations (if a CUDA-compatible GPU is available), which can help ensure consistency across different executions of the code.Dataset Preprocessing and LoadingThe following block of code represents the next major phase: preprocessing and loading the datasets. This is where we clean and prepare our data so that it can be fed into our LLM models:def preprocess_datasets(    *datasets,    sample_sizes = [5000, 450, 450],    columns_to_remove = ['premise_binary_parse', 'premise_parse', 'hypothesis_binary_parse', 'hypothesis_parse', 'promptID', 'pairID', 'label'], ):    # Remove -1 labels (no gold label)    f = lambda ex: ex["label"] != -1    datasets = [dataset.filter(f) for dataset in datasets]    # Sample a subset of the data    assert len(sample_sizes) == len(datasets), "Number of datasets and sample sizes must match"    datasets = [        dataset.shuffle(seed=SEED).select([idx for idx in range(sample_size)])        for dataset, sample_size in zip(datasets, sample_sizes)    ]    # Remove columns    datasets = [data.remove_columns(columns_to_remove) for data in datasets]    return datasetsThis is a function definition for preprocess_datasets, which takes any number of datasets (with their sample sizes and columns to be removed specified as lists). The function does three main things:Filtering: Removes examples where the label is -1. A label of -1 means that there is no gold label for that example.Sampling: Shuffles the datasets and selects a specific number of examples based on the provided sample_sizes.Removing columns: Drops specific columns from the dataset as per the columns_to_remove list.train_data = load_dataset("multi_nli", split="train") val_matched_data = load_dataset("multi_nli", split="validation_matched") val_mismatched_data = load_dataset("multi_nli", split="validation_mismatched") train_data, val_matched_data, val_mismatched_data = preprocess_datasets(    train_data, val_matched_data, val_mismatched_data )The above lines load the train and validation datasets from multi_nli (a multi-genre natural language inference corpus) and then preprocess them using the function we just defined.Finally, we print the genres available in each dataset and display the first few records using the Pandas data frame. This is useful to confirm that our datasets have been loaded and preprocessed correctly:print("Training data") print(f"Genres: {np.unique(train_data['genre'])}") display(train_data.to_pandas().head()) print("Validation matched data") print(f"Genres: {np.unique(val_matched_data['genre'])}") display(val_matched_data.to_pandas().head()) print("Validation mismatched data") print(f"Genres: {np.unique(val_mismatched_data['genre'])}") display(val_mismatched_data.to_pandas().head())With the help of this block, we have our datasets loaded and preprocessed, ready to be transformed into vector embeddings.Sentence Embedding and TransformationNow, we proceed to the next crucial step, transforming our textual data into numerical vectors. This is where text or sentence embeddings come into play.In simple terms, sentence embeddings are the numerical representations of sentences. Just as words can be represented by dense vectors (a process known as word embeddings), entire sentences can also be encoded into vectors. This transformation process facilitates mathematical operations on text, making it possible for machine learning algorithms to perform tasks like text classification, sentence similarity, sentiment analysis, and more.To produce high-quality sentence embeddings, the context of each word in the sentence and the semantics should be considered. Transformer-based models, like BERT, DistilBERT, or RoBERTa, are very effective in creating these contextual sentence embeddings.Now, let's explain the next block of code:#Mean Pooling - Take attention mask into account for correct averaging def mean_pooling(model_output, attention_mask):    token_embeddings = model_output[0]    input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()    return torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(input_mask_expanded.sum(1), min=1e-9)This function mean_pooling is used to calculate the mean of all token embeddings that belong to a single sentence. The function receives the model_output (containing the token embeddings) and an attention_mask (indicating where actual tokens are and where padding tokens are in the sentence). The mask is used to correctly compute the average over the length of each sentence, ignoring the padding tokens.The function embed_sentence_pairs processes the sentence pairs, creates their embeddings, and stores them. It uses a data loader (which loads data in batches), a tokenizer (to convert sentences into model-understandable format), and a pre-trained language model (to create the embeddings).The function is a vital part of the sentence embedding process. This function uses a language model to convert pairs of sentences into high-dimensional vectors that represent their combined semantics. Here's an annotated walkthrough:def embed_sentence_pairs(dataloader, tokenizer, model, disable_tqdm=False):    # Empty lists are created to store the embeddings of premises and hypotheses    premise_embeddings  = []    hypothesis_embeddings = []    feature_embeddings = []    # The device (CPU or GPU) to be used for computations is determined    device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")    # The model is moved to the chosen device and set to evaluation mode    model.to(device)    model.eval()    # A loop is set up to iterate over the data in the dataloader    loop = tqdm(dataloader, desc=f"Embedding sentences...", disable=disable_tqdm)    for data in loop:        # The premise and hypothesis sentences are extracted from the data       premise, hypothesis = data['premise'], data['hypothesis']        # The premise and hypothesis sentences are encoded into a format that the model can understand        encoded_premise, encoded_hypothesis = (            tokenizer(sentences, padding=True, truncation=True, return_tensors='pt')            for sentences in (premise, hypothesis)        )        # The model computes token embeddings for the encoded sentences        with torch.no_grad():            encoded_premise = encoded_premise.to(device)            encoded_hypothesis = encoded_hypothesis.to(device)            model_premise_output = model(**encoded_premise)            model_hypothesis_output = model(**encoded_hypothesis)        # Mean pooling is performed on the token embeddings to create sentence embeddings        pooled_premise = mean_pooling(model_premise_output, encoded_premise['attention_mask']).cpu().numpy()        pooled_hypothesis = mean_pooling(model_hypothesis_output, encoded_hypothesis['attention_mask']).cpu().numpy()        # The sentence embeddings are added to the corresponding lists        premise_embeddings.extend(pooled_premise)        hypothesis_embeddings.extend(pooled_hypothesis)    # The embeddings of the premises and hypotheses are concatenated along with their absolute difference    feature_embeddings = np.concatenate(        [            np.array(premise_embeddings),            np.array(hypothesis_embeddings),            np.abs(np.array(premise_embeddings) - np.array(hypothesis_embeddings))        ],        axis=1    )    return feature_embeddingsThis function does all the heavy lifting of turning raw textual data into dense vectors that machine learning algorithms can use. It takes in a dataloader, which feeds batches of sentence pairs into the function, a tokenizer to prepare the input for the language model, and the model itself to create the embeddings.The embedding process involves first tokenizing each sentence pair and then feeding the tokenized sentences into the language model. This yields a sequence of token embeddings for each sentence. To reduce these sequences to a single vector per sentence, we apply a mean pooling operation, which takes the mean of all token vectors in a sentence, weighted by their attention masks.Finally, the function concatenates the embeddings of the premise and hypothesis of each pair, along with the absolute difference between these two embeddings. This results in a single vector that represents both the individual meanings of the sentences and the semantic relationship between them. The absolute difference between the premise and hypothesis embeddings helps to capture the semantic contrast in the sentence pair.These concatenated embeddings, returned by the function, serve as the final input features for further machine-learning tasks.The function begins by setting the device to GPU if it's available. It sets the model to evaluation mode using model.eval(). Then, it loops over the data loader, retrieving batches of sentence pairs.For each sentence pair, it tokenizes the premise and hypothesis using the provided tokenizer. The tokenized sentences are then passed to the model to generate the model outputs. Using these outputs, mean pooling is performed to generate sentence-level embeddings.Finally, the premise and hypothesis embeddings are concatenated along with their absolute difference, resulting in our final sentence pair embeddings. These combined embeddings capture the information from both sentences and the relational information between them, which are stored in feature_embeddings.These feature embeddings are critical and are used as input features for the downstream tasks. Their high-dimensional nature contains valuable semantic information which can help in various NLP tasks such as text classification, information extraction, and more.Sentence Embedding and TokenizingThis block of code takes care of model loading, data preparation, and finally, the embedding process for each sentence pair in our datasets. Here's an annotated walkthrough:# Pretrained SentenceTransformers handle this task better than regular Transformers model_name = 'sentence-transformers/all-MiniLM-L6-v2' # Uncomment the following line to try a regular Transformers model trained on MultiNLI # model_name = 'sileod/roberta-base-mnli' # Instantiate the tokenizer and model from the pretrained transformers on the Hugging Face Hub tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModel.from_pretrained(model_name) batch_size = 128 # Prepare the PyTorch DataLoaders for each of the train, validation matched, and validation mismatched datasets trainloader = DataLoader(train_data, batch_size=batch_size, shuffle=False) valmatchedloader = DataLoader(val_matched_data, batch_size=batch_size, shuffle=False) valmismatchedloader = DataLoader(val_mismatched_data, batch_size=batch_size, shuffle=False) # Use the embed_sentence_pairs function to create embeddings for each dataset train_embeddings = embed_sentence_pairs(trainloader, tokenizer, model, disable_tqdm=True) val_matched_embeddings = embed_sentence_pairs(valmatchedloader, tokenizer, model, disable_tqdm=True) val_mismatched_embeddings = embed_sentence_pairs(valmismatchedloader, tokenizer, model, disable_tqdm=True)This block begins by setting the model_name variable to the identifier of a pretrained SentenceTransformers model available on the Hugging Face Model Hub. SentenceTransformers are transformer-based models specifically trained for generating sentence embeddings, so they are generally more suitable for this task than regular transformer models. The MiniLM model was chosen for its relatively small size and fast inference times, but provides performance comparable to much larger models. If you wish to experiment with a different model, you can simply change the identifier.Next, the tokenizer and model corresponding to the model_name are loaded using the from_pretrained method, which fetches the necessary components from the Hugging Face Model Hub and initializes them for use.The DataLoader utility from the PyTorch library is then used to wrap our Hugging Face datasets. The DataLoader handles the batching of the data and provides an iterable over the dataset, which will be used by our embed_sentence_pairs function. The batch size is set to 128, which means that the model processes 128 sentence pairs at a time.Finally, the embed_sentence_pairs function is called for each of our data loaders (train, validation matched, and validation mismatched), returning the corresponding embeddings for each sentence pair in these datasets. These embeddings will be used as input features for our downstream tasks.Outlier Detection in DatasetsIn the realm of machine learning, outliers often pose a significant challenge. These unusual or extreme values can cause the model to make erroneous decisions based on data points that don't represent the general trend or norm in the data. Therefore, an essential step in data preprocessing for machine learning is identifying and handling these outliers effectively.In our project, we make use of the OutOfDistribution object from the cleanlab Python package to conduct outlier detection. The OutOfDistribution method computes an outlier score for each data point based on how well it fits within the overall distribution of the data. The higher the outlier score, the more anomalous the data point is considered to be.Let's take a detailed look at how this is achieved in the code:ood = OutOfDistribution() train_outlier_scores = ood.fit_score(features=train_embeddings)In the first step, we instantiate the OutOfDistribution object. Then, we fit this object to our training data embeddings and calculate outlier scores for each data point in the training data:top_train_outlier_idxs = (train_outlier_scores).argsort()[:15] top_train_outlier_subset = train_data.select(top_train_outlier_idxs) top_train_outlier_subset.to_pandas().head()Next, we select the top 15 training data points with the highest outlier scores. These data points are then displayed for manual inspection, helping us understand the nature of these outliers.We then apply a similar process to our validation data:test_feature_embeddings = np.concatenate([val_matched_embeddings, val_mismatched_embeddings], axis=0) test_outlier_scores = ood.score(features=test_feature_embeddings) test_data = concatenate_datasets([val_matched_data, val_mismatched_data])First, we concatenate the matched and mismatched validation embeddings. Then, we calculate the outlier scores for each data point in this combined validation dataset using the previously fitted OutOfDistribution object:top_outlier_idxs = (test_outlier_scores).argsort()[:20] top_outlier_subset = test_data.select(top_outlier_idxs) top_outlier_subset.to_pandas()Lastly, we identify the top 20 validation data points with the highest outlier scores. Similar to our approach with the training data, these potential outliers are selected and visualized for inspection.By conducting this outlier analysis, we gain valuable insights into our data. These insights can inform our decisions on data preprocessing steps, such as outlier removal or modification, to potentially enhance the performance of our machine learning model.Evaluating Outlier Scores and Setting a ThresholdOnce we have determined the outlier scores for each data point, the next step is to set a threshold for what we will consider an "outlier." While there are various statistical methods to determine this threshold, one simple and commonly used approach is to use percentiles.In this project, we choose to set the threshold at the 2.5th percentile of the outlier scores in the training data. This choice implies that we consider the bottom 2.5% of our data (in terms of their fit to the overall distribution) as outliers. Let's look at how this is implemented in the code:threshold = np.percentile(test_outlier_scores, 2.5)The code above calculates the 2.5th percentile of the outlier scores in the training data and sets this value as our threshold for outliers.Next, we visualize the distribution of outlier scores for both the training and test data:fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 5)) plt_range = [min(train_outlier_scores.min(),test_outlier_scores.min()), \\\\             max(train_outlier_scores.max(),test_outlier_scores.max())] axes[0].hist(train_outlier_scores, range=plt_range, bins=50) axes[0].set(title='train_outlier_scores distribution', ylabel='Frequency') axes[0].axvline(x=threshold, color='red', linewidth=2) axes[1].hist(test_outlier_scores, range=plt_range, bins=50) axes[1].set(title='test_outlier_scores distribution', ylabel='Frequency') axes[1].axvline(x=threshold, color='red', linewidth=2)In the histogram, the red vertical line represents the threshold value. By observing the distributions and where the threshold falls, we get a visual representation of what proportion of our data is considered "outlying.":Finally, we select the outliers from our test data based on this threshold:sorted_ids = test_outlier_scores.argsort() outlier_scores = test_outlier_scores[sorted_ids] outlier_ids = sorted_ids[outlier_scores < threshold] selected_outlier_subset = test_data.select(outlier_ids) selected_outlier_subset.to_pandas().tail(15)This piece of code arranges the outlier scores in ascending order, determines which data points fall below the threshold (hence are considered outliers), and selects these data points from our test data. The bottom 15 rows of this selected outlier subset are then displayed:By setting and applying this threshold, we can objectively identify and handle outliers in our data. This process helps improve the quality and reliability of our LLM models.ConclusionThis article focuses on detecting anomalies in multi-genre NLI datasets using advanced tools and techniques, from preprocessing with transformers to outlier detection. The MultiNLI dataset was streamlined using Hugging Face's datasets library, enhancing manageability. Exploring sentence embeddings, transformers library generated robust representations by averaging token embeddings with mean_pooling. Outliers were identified using cleanlab library and visualized via plots and tables, revealing data distribution and characteristics.A threshold was set based on the 2.5th percentile of outlier scores, aiding anomaly identification in the test dataset. The study showcases the potential of Large Language Models in NLP, offering efficient solutions to complex tasks. This exploration enriches dataset understanding and highlights LLM's impressive capabilities, underlining its impact on previously daunting challenges. The methods and libraries employed demonstrate the current LLM technology's prowess, providing potent solutions. By continuously advancing these approaches, NLP boundaries are pushed, paving the way for diverse research and applications in the future.Author Bio:Alan Bernardo Palacio is a data scientist and an engineer with vast experience in different engineering fields. His focus has been the development and application of state-of-the-art data products and algorithms in several industries. He has worked for companies such as Ernst and Young, Globant, and now holds a data engineer position at Ebiquity Media helping the company to create a scalable data pipeline. Alan graduated with a Mechanical Engineering degree from the National University of Tucuman in 2015, participated as the founder in startups, and later on earned a Master's degree from the faculty of Mathematics in the Autonomous University of Barcelona in 2017. Originally from Argentina, he now works and resides in the Netherlands.LinkedIn
Read more
  • 0
  • 0
  • 12868
article-image-flash-10-multiplayer-game-introduction-lobby-and-room-management
Packt
14 Jul 2010
7 min read
Save for later

Flash 10 Multiplayer Game: Introduction to Lobby and Room Management

Packt
14 Jul 2010
7 min read
(For more resources on Flash and Games, see here.) A lobby, in a multiplayer game, is where people hang around before they go into a specific room to play. When the player comes out of the room, the players are dropped into the lobby again. The main function of a lobby is to help players quickly find a game room that is suited for them and join. When the player is said to be in a lobby, the player will be able to browse rooms within the lobby that can be entered. The player may be able to see several attributes and the status of each game room. For example, the player will be able to see how many players are in the room already, giving a hint that the game in the room is about to begin. If it is a four-player game and three are already in, there is a greater chance that the game will start soon. Depending on the game, the room may also show a lot of other information such as avatar names of all the players already in the room and who the host is. In a car race game, the player may be able to see what kind of map is chosen to play, what level of difficulty the room is set to, etc. Most lobbies also offer a quick join functionality where the system chooses a room for the player and enters them into it. The act of joining a room means the player leaves the lobby, which in turn means that the player is now unaware or not interested in any updates that happen in the lobby. The player now only receives events that occur within the game room, such as, another player has entered or departed or the host has left and a new host was chosen by the server. When a player is in the lobby, the player constantly receives updates that happen within the lobby. For example, events such as new room creation, deletion, and room-related updates. The room-related updates include the players joining or leaving the room and the room status changing from waiting to playing. A sophisticated lobby design lets a player delay switching to the room screen until the game starts. This is done so as to not have a player feel all alone once they create a room and get inside it. In this design, the player can still view activities in the lobby, and there's an opportunity for players to change their mind and jump to another table (game room) instantaneously. The lobby screen may also provide a chatting interface. The players will be able to view all the players in the lobby and even make friends. Note that the lobby for a popular game may include thousands of players. The server may be bogged down by sending updates to all the players in the lobby. As an advanced optimization, various pagination schemes may be adopted where the player only receives updates from only a certain set of rooms that is currently being viewed on the screen. In some cases, lobbies are organized into various categories to lessen the player traffic and thus the load on the server. Some of the ways you may want to break down the lobbies are based on player levels, game genres, and geographic location, etc. The lobbies are most often statically designed, meaning a player may not create a lobby on the fly. The server's responsibility is to keep track of all the players in the lobby and dispatch them with all events related to lobby and room activity. The rooms that are managed within a lobby may be created dynamically or sometimes statically. In a statically created room, the players simply occupy them, play the game, and then leave. Also in this design, the game shows with a bunch of empty rooms, say, one hundred of them. If all rooms are currently in play state, then the player needs to wait to join a room that is in a wait state and is open to accepting a new player into the room. Modeling game room The game room required for the game is also modeled via the schema file (Download here-chap3). Subclassing should be done when you want to define additional properties on a game room that you want to store within the game room. The properties that you might want to add would be specific to your game. However, some of the commonly required properties are already defined in the GameRoom class. You will only need to define one such subclass for a game. The following are the properties defined on the GameRoom Class: Property Notes Room name Name of the game room typically set during game room creation Host name The server keeps track of this value and is set to the current host of the room. The room host is typically the creator. If the host leaves the room while others are still in it, an arbitrary player in the room is set as host. Host ID Is maintained by the server similar to host name. Password Should be set by the developer upon creating a new game room. Player count The server keeps track of this value as and when the players enter or leave the room. Max player count Should be set by the developer upon creating a new game room. The server will automatically reject the player joining the room if the player count is equal to the max player count Room status The possible values for this property are GameConstants.ROOM_STATE_WAITING or GameConstants.ROOM_STATE_PLAYING The server keeps track of these value-based player actions such as PulseClient.startGame API. Room type The possible values for this property are value combinations of GameConstants.ROOM_TURN_BASED and GameConstants.ROOM_DISALLOW_POST_START The developer should set this value upon creating a new room. The server controls the callback API behavior based on this property. Action A server-reserved property; the developer should not use this for any purpose. The developer may inherit from the game room and specify an arbitrary number of properties. Note that the total number of bytes should not exceed 1K bytes. Game room management A room is where a group of players play a particular game. A player that joins the room first or enters first is called game or room host. The host has some special powers. For example, the host can set the difficulty level of the game, set the race track to play, limit the number of people that can join the game, and even set a password on the room. If there is more than one player in the room and the host decides to leave the room, then usually the system automatically chooses another player in the room as a host and this event is notified to all players in room. Once the player is said to be in the room, the player starts receiving events for any player entering or leaving the room, or any room-property changes such as the host setting a different map to play, etc. The players can also chat with each other when they are in a game room. Seating order Seating order is not required for all kinds of games, for example, a racing game may not place as much importance on the starting position of the player's cars, although the system may assign one automatically. This is also true in the case of two-player games such as chess. But players in a card game of four players around a table may wish to be seated at a specific position, for example, across from a friend who would be a partner during the game play. In these cases, a player entering a room also requests to sit at a certain position. In this kind of a lobby or room design, the GUI shows which seats are currently occupied and which seats are not. The server may reject the player request if another player is already seated at the requested seat. This happens when the server has already granted the position to another player just an instant before the player requested and the UI was probably not updated. In this case, the server will choose another vacant seat if one is available or else the server will reject the player entrance into the room.
Read more
  • 0
  • 0
  • 12867

article-image-running-your-applications-aws
Cheryl Adams
17 Aug 2016
4 min read
Save for later

Running Your Applications with AWS

Cheryl Adams
17 Aug 2016
4 min read
If you’ve ever been told not to run with scissors, you should not have the same concern when running with AWS. It is neither dangerous nor unsafe when you know what you are doing and where to look when you don’t. Amazon’s current service offering, AWS (Amazon Web Services), is a collection of services, applications and tools that can be used to deploy your infrastructure and application environment to the cloud.  Amazon gives you the option to start their service offerings with a ‘free tier’ and then move toward a pay as you go model.  We will highlight a few of the features when you open your account with AWS. One of the first things you will notice is that Amazon offers a bulk of information regarding cloud computing right up front. Whether you are a novice, amateur or an expert in cloud computing, Amazon offers documented information before you create your account.  This type of information is essential if you are exploring this tool for a project or doing some self-study on your own. If you are a pre-existing Amazon customer, you can use your same account to get started with AWS. If you want to keep your personal account separate from your development or business, it would be best to create a separate account. Amazon Web Services Landing Page The Free Tier is one of the most attractive features of AWS. As a new account you are entitled to twelve months within the Free Tier. In addition to this span of time, there are services that can continue after the free tier is over. This gives the user ample time to explore the offerings within this free-tier period. The caution is not to exceed the free service limitations as it will incur charges. Setting up the free-tier still requires a credit card. Fee-based services will be offered throughout the free tier, so it is important not to select a fee-based charge unless you are ready to start paying for it. Actual paid use will vary based on what you have selected.   AWS Service and Offerings (shown on an open account)     AWS overview of services available on the landing page Amazon’s service list is very robust. If you are already considering AWS, hopefully this means you are aware of what you need or at least what you would like to use. If not, this would be a good time to press pause and look at some resource-based materials. Before the clock starts ticking on your free-tier, I would recommend a slow walk through the introductory information on this site to ensure that you are selecting the right mix of services before creating your account. Amazon’s technical resources has a 10-minute tutorial that gives you a complete overview of the services. Topics like ‘AWS Training and Introduction’ and ‘Get Started with AWS’ include a list of 10-minute videos as well as a short list of ‘how to’ instructions for some of the more commonly used features. If you are a techie by trade or hobby, this may be something you want to dive into immediately.In a company, generally there is a predefined need or issue that the organization may feel can be resolved by the cloud.  If it is a team initiative, it would be good to review the resources mentioned in this article so that everyone is on the same page as to what this solution can do.It’s recommended before you start any trial, subscription or new service that you have a set goal or expectation of why you are doing it. Simply stated, a cloud solution is not the perfect solution for everyone.  There is so much information here on the AWS site. It’s also great if you are comparing between competing cloud service vendors in the same space. You will be able to do a complete assessment of most services within the free-tier. You can map use case scenarios to determine if AWS is the right fit for your project. AWS First Project is a great place to get started if you are new to AWS. If you are wondering how to get started, these technical resources will set you in the right direction. By reviewing this information during your setup or before you start, you will be able to make good use out of your first few months and your introduction to AWS. About the author Cheryl Adams is a senior cloud data and infrastructure architect in the healthcare data realm. She is also the co-author of Professional Hadoop by Wrox.
Read more
  • 0
  • 0
  • 12861

article-image-docker-container-management-with-saltstack
Nicole Thomas
25 Sep 2014
8 min read
Save for later

Docker Container Management at Scale with SaltStack

Nicole Thomas
25 Sep 2014
8 min read
Every once in a while a technology comes along that changes the way work is done in a data center. It happened with virtualization and we are seeing it with various cloud computing technologies and concepts. But most recently, the rise in popularity of container technology has given us reason to rethink interdependencies within software stacks and how we run applications in our infrastructures. Despite all of the enthusiasm around the potential of containers, they are still just another thing in the data center that needs to be centrally controlled and managed...often at massive scale. This article will provide an introduction to how SaltStack can be used to manage all of this, including container technology, at web scale. SaltStack Systems Management Software The SaltStack systems management software is built for remote execution, orchestration, and configuration management and is known for being fast, scalable, and flexible. Salt is easy to set up and can easily communicate asynchronously with tens of thousands of servers in a matter of seconds. Salt was originally built as a remote execution engine relying on a secure, bi-directional communication system utilizing a Salt Master daemon used to control Salt Minion daemons, where the minions receive commands from the remote master. Salt’s configuration management capabilities are called the state system, or Salt States, and are built on SLS formulas. SLS files are data structures based on dictionaries, lists, strings, and numbers that are used to enforce the state that a system should be in, also known as configuration management. SLS files are easy to write, simple to implement, and are typically written in YAML. State file execution occurs on the Salt Minion. Therefore, once any states files that the infrastructure requires have been written, it is possible to enforce state on tens of thousands of hosts simultaneously. Additionally, each minion returns its status to the Salt Master. Docker containers Docker is an agile runtime and packaging platform specializing in enabling applications to be quickly built, shipped, and run in any environment. Docker containers allow developers to easily compartmentalize their applications so that all of the program’s needs are installed and configured in a single container. This container can then be dropped into clouds, data centers, laptops, virtual machines (VMs), or infrastructures where the app can execute, unaltered, without any cross-environment issues. Building Docker containers is fast, simple, and inexpensive. Developers can create a container, change it, break it, fix it, throw it away, or save it much like a VM. However, Docker containers are much more nimble, as the containers only possess the application and its dependencies. VMs, along with the application and its dependencies, also install a guest operating system, which requires much more overhead than may be necessary. While being able to slice deployments into confined components is a good idea for application portability and resource allocation, it also means there are many more pieces that need to be managed. As the number of containers scales, without proper management, inefficiencies abound. This scenario, known as container sprawl, is where SaltStack can help and the combination of SaltStack and Docker quickly proves its value. SaltStack + Docker When we combine SaltStack’s powerful configuration management armory with Docker’s portable and compact containerization tools, we get the best of both worlds. SaltStack has added support for users to manage Docker containers on any infrastructure. The following demonstration illustrates how SaltStack can be used to manage Docker containers using Salt States. We are going to use a Salt Master to control a minimum of two Salt Minions. On one minion we will install HAProxy. On the other minion, we will install Docker and then spin up two containers on that minion. Each container hosts a PHP app with Apache that displays information about each container’s IP address and exposed port. The HAProxy minion will automatically update to pull the IP address and port number from each of the Docker containers housed on the Docker minion. You can certainly set up more minions for this experiment, where additional minions would be additional Docker container minions, to see an implementation of containers at scale, but it is not necessary to see what is possible. First, we have a few installation steps to take care of. SaltStack’s installation documentation provides a thorough overview of how to get Salt up and running, depending on your operating system. Follow the instructions on Salt’s Installation Guide to install and configure your Salt Master and two Salt Minions. Go through the process of accepting the minion keys on the Salt Master and, to make sure the minions are connected, run: salt ‘*’ test.ping Note: Much of the Docker functionality used in this demonstration is brand new. You must install the latest supported version of Salt, which is 2014.1.6. For reference, I have my master and minions all running on Ubuntu 14.04. My Docker minion is named “docker1” and my HAProxy minion is named “haproxy”. Now that you have a Salt Master and two Salt Minions configured and communicating with each other, it’s time to get to work. Dave Boucha, a Senior Engineer at SaltStack, has already set up the necessary configuration files for both our haproxy and docker1 minions and we will be using those to get started. First, clone the Docker files in Dave’s GitHub repository, dock-apache, and copy the dock_apache and docker> directories into the /srv/salt directory on your Salt Master (you may need to create the /srv/salt directory): cp -r path/to/download/dock_apache /srv/salt cp -r path/to/download/docker /srv/salt The init.sls file inside the docker directory is a Salt State that installs Docker and all of its dependencies on your minion. The docker.pgp file is a public key that is used during the Docker installation. To fire off all of these events, run the following command: salt ‘docker1’ state.sls docker Once Docker has successfully installed on your minion, we need to set up our two Docker containers. The init.sls file in the dock_apache directory is a Salt State that specifies the image to pull from Docker’s public container repository, installs the two containers, and assigns the ports that each container should expose: 8000 for the first container and 8080 for the second container. Now, let’s run the state: salt ‘docker1’ state.sls dock_apache Let’s check and see if it worked. Get the IP address of the minion by running: salt ‘docker1’ network.ip_addrs Copy and paste the IP address into a browser and add one of the ports to the end. Try them both (IP:8000 and IP:8080) to see each container up and running! At this point, you should have two Docker containers installed on your “docker1” minion (or any other docker minions you may have created). Now we need to set up the “haproxy” minion. Download the files from Dave’s GitHub repository, haproxy-docker, and place them all in your Salt Master’s /srv/salt/haproxy directory: cp -r path/to/download/haproxy /srv/salt First, we need to retrieve the data about our Docker containers from the Docker minion(s), such as the container IP address and port numbers, by running the haproxy.config salt ‘haproxy’ state.sls haproxy.config By running haproxy.config, we are setting up a new configuration with the Docker minion data. The configuration file also runs the haproxy state (init.sls. The init.sls file contains a haproxy state that ensures that HAProxy is installed on the minion, sets up the configuration for HAProxy, and then runs HAProxy. You should now be able to look at the HAProxy statistics by entering the haproxy minion’s IP address in your browser with /haproxy?stats on the end of the URL. When the authentication pop-up appears, the username and password are both saltstack. While this is a simple example of running HAProxy to balance the load of only two Docker containers, it demonstrates how Salt can be used to manage tens of thousands of containers as your infrastructure scales. To see this same demonstration with a haproxy minion in action with 99 Docker minions, each with two Docker containers installed, check out SaltStack’s Salt Air 20 tutorial by Dave Boucha on YouTube. About the author Nicole Thomas is a QA Engineer at SaltStack, Inc. Before coming to SaltStack, she wore many hats from web and Android developer to contributing editor to working in Environmental Education. Nicole recently graduated Summa Cum Laude from Westminster College with a degree in Computer Science. Nicole also has a degree in Environmental Studies from the University of Utah.
Read more
  • 0
  • 0
  • 12855
article-image-using-reactjs-without-jsx
Richard Feldman
30 Jun 2014
6 min read
Save for later

Using React.js without JSX

Richard Feldman
30 Jun 2014
6 min read
React.js was clearly designed with JSX in mind, however, there are plenty of good reasons to use React without it. Using React as a standalone library lets you evaluate the technology without having to spend time learning a new syntax. Some teams—including my own—prefer to have their entire frontend code base in one compile-to-JavaScript language, such as CoffeeScript or TypeScript. Others might find that adding another JavaScript library to their dependencies is no big deal, but adding a compilation step to the build chain is a deal-breaker. There are two primary drawbacks to eschewing JSX. One is that it makes using React significantly more verbose. The other is that the React docs use JSX everywhere; examples demonstrating vanilla JavaScript are few and far between. Fortunately, both drawbacks are easy to work around. Translating documentation The first code sample you see in the React Documentation includes this JSX snippet: /** @jsx React.DOM */ React.renderComponent( <h1>Hello, world!</h1>, document.getElementById('example') ); Suppose we want to see the vanilla JS equivalent. Although the code samples on the React homepage include a helpful Compiled JS tab, the samples in the docs—not to mention React examples you find elsewhere on the Web—will not. Fortunately, React’s Live JSX Compiler can help. To translate the above JSX into vanilla JS, simply copy and paste it into the left side of the Live JSX Compiler. The output on the right should look like this: /** @jsx React.DOM */ React.renderComponent( React.DOM.h1(null, "Hello, world!"), document.getElementById('example') ); Pretty similar, right? We can discard the comment, as it only represents a necessary directive in JSX. When writing React in vanilla JS, it’s just another comment that will be disregarded as usual. Take a look at the call to React.renderComponent. Here we have a plain old two-argument function, which takes a React DOM element (in this case, the one returned by React.DOM.h1) as its first argument, and a regular DOM element (in this case, the one returned by document.getElementById('example')) as its second. jQuery users should note that the second argument will not accept jQuery objects, so you will have to extract the underlying DOM element with $("#example")[0] or something similar. The React.DOM object has a method for every supported tag. In this case we’re using h1, but we could just as easily have used h2, div, span, input, a, p, or any other supported tag. The first argument to these methods is optional; it can either be null (as in this case), or an object specifying the element’s attributes. This argument is how you specify things like class, ID, and so on. The second argument is either a string, in which case it specifies the object’s text content, or a list of child React DOM elements. Let’s put this together with a more advanced example, starting with the vanilla JS: React.DOM.form({className:"commentForm"}, React.DOM.input({type:"text", placeholder:"Your name"}), React.DOM.input({type:"text", placeholder:"Say something..."}), React.DOM.input({type:"submit", value:"Post"}) ) For the most part, the attributes translate as you would expect: type, value, and placeholder do exactly what they would do if used in HTML. The one exception is className, which you use in place of the usual class. The above is equivalent to the following JSX: /** @jsx React.DOM */ <form className="commentForm"> <input type="text" placeholder="Your name" /> <input type="text" placeholder="Say something..." /> <input type="submit" value="Post" /> </form> This JSX is a snippet found elsewhere in the React docs, and again you can view its vanilla JS equivalent by pasting it into the Live JSX Compiler. Note that you can include pure JSX here without any surrounding JavaScript code (unlike the JSX playground), but you do need the /** @jsx React.DOM */ comment at the top of the JSX side. Without the comment, the compiler will simply output the JSX you put in. Simple DSLs to make things concise Although these two implementations are functionally identical, clearly the JSX version is more concise. How can we make the vanilla JS version less verbose? A very quick improvement is to alias the React.DOM object: var R = React.DOM; R.form({className:"commentForm"}, R.input({type:"text", placeholder:"Your name"}), R.input({type:"text", placeholder:"Say something..."}), R.input({type:"submit", value:"Post"})) You can take it even further with a tiny bit of DSL: var R = React.DOM; var form = R.form; var input = R.input; form({className:"commentForm"}, input({type:"text", placeholder:"Your name"}), input({type:"text", placeholder:"Say something..."}), input({type:"submit", value:"Post"}) ) This is more verbose in terms of lines of code, but if you have a large DOM to set up, the extra up-front declarations can make the rest of the file much nicer to read. In CoffeeScript, a DSL like this can tidy things up even further: {form, input} = React.DOM form {className:"commentForm"}, [ input type: "text", placeholder:"Your name" input type:"text", placeholder:"Say something..." input type:"submit", value:"Post" ] Note that in this example, the form’s children are passed as an array rather than as a list of extra arguments (which, in CoffeeScript, allows you to omit commas after each line). React DOM element constructors support either approach. (Also note that CoffeeScript coders who don’t mind mixing languages can use the coffee-react compiler or set up a custom build chain that allows for inline JSX in CoffeeScript sources instead.) Takeaways No matter your particular use case, there are plenty of ways to effectively use React without JSX. Thanks to the Live JSX Compiler ’s ability to quickly translate documentation code samples, and the ease with which you can set up a simple DSL to reduce verbosity, there really is very little overhead to using React as a JavaScript library like any other. About the author Richard Feldman is a functional programmer who specializes in pushing the limits of browser-based UIs. He’s built a framework that performantly renders hundreds of thousands of shapes in the HTML5 canvas, a writing web app that functions like a desktop app in the absence of an Internet connection, and much more in between
Read more
  • 0
  • 0
  • 12853

article-image-photoshop-foundation-difference-between-vector-and-bitmap-graphics
Packt
23 Oct 2009
4 min read
Save for later

Photoshop Foundation - The Difference between Vector and Bitmap Graphics

Packt
23 Oct 2009
4 min read
Introduction Welcome to the first in a new series of articles on Photoshop - the Photoshop Foundations series. The aim of this series is to give both beginners and more experienced users all the information they need to use Photoshop as efficiently as possible. Photoshop is a huge application, and there is usually more than one way to look at a given subject, or perform a certain action. This series aims to both, guide you through the more confusing aspects of Photoshop and show you the very best ways to use this application. In this first article we are going to look at the difference between vector and bitmap graphics, which is one of the most important principles to understand when working with graphics on a computer, inside or outside of Photoshop. Although Photoshop primarily is a bitmap image editor, it is capable of handling vector graphics to a certain extent. This can be a little confusing for people new to creating graphics on a computer, but by the end of this article you should have a clear idea of the difference between these two types of graphics. Bitmap Graphics Bitmap graphics are made up of colored pixels. Pixels are very small rectangles (usually square, although in some video applications they are wider than they are tall) of varying colors that once put together give you an image. You can see from the example below that zooming in on a bitmap image reveals the pixels that make up the image when viewed at 100%.   Bitmap graphics are usually (but not always) photographic in nature, capable of subtle graduated tones - often in the range of millions of colors per image. The problem with bitmap graphics is that they don't enlarge well as Photoshop needs to guess what color the extra pixels should be - this can result is loss of definition and a dramatic lowering in quality, depending on how much you enlarge the image. Common file formats for bitmap image data include GIF, JPEG and PNG for Internet usage and TIFF for print usage. As you can see from the example below, physically enlarging an image will degrade quality. Pixels are also used to display the image on your computer screen. Common pixel dimensions of computer displays are 1024 wide by 768 high and 1600 wide by 1200 high. The size of a bitmap graphic when viewed on your computer screen is defined by the number of pixels that make up the image - so an image that is 50 pixels wide will look very small on your screen at 100% viewing percentage, whereas an image that is 4000 pixels wide will be larger than your screen at 100% viewing percentage. The printable dimensions of an image are defined by the DPI (dots per inch) - this information is invisibly embedded in the image file. Digital cameras often embed information such as this, that may include the conditions the image was taken in, and even the camera model used. This information is not actually visible in the image, and requires software such as Photoshop to read it. You should not confuse the output DPI of your printer with this figure, which may range from 600-2400DPI - this refers to the density of the dots of ink laid down on the page by the printer. You don't have to prepare your images to 2400 DPI to get the best results - in fact doing so will significantly slow down printing as your file could potentially be huge! Often an image DPI in the range of 175-250 will give very good results on home printers. Images prepared for high quality commercial print are usually prepared at 300 DPI for up to A3 in size; whereas very large images (for instance on billboards) can be as low as 50 DPI, as they are not made to be viewed as closely as a magazine or small poster. There is no need to go above 300 DPI when creating images as you will yield virtually no improvement in output quality, only increasing the size of your file when saved. It is easy to understand the relationship between pixel dimensions and DPI - put simply, the DPI is how many pixels will be printed in an inch - so you could actually think of DPI as PPI (pixels per inch). Indeed, many experts believe this to be the true definition of DPI, and that Photoshop should refer to it as such. However, the term DPI is used throughout the professional print industry, so this is why it is referred to as DPI in Photoshop, not PPI.
Read more
  • 0
  • 0
  • 12849
Modal Close icon
Modal Close icon