Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
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

7018 Articles
article-image-getting-started-etcd
Packt
15 Feb 2016
6 min read
Save for later

Getting Started with etcd

Packt
15 Feb 2016
6 min read
In this article we will cover etcd, CoreOS's central hub of all services that provides a reliable way of storing shared data across cluster machines and monitoring it. In this article, we will cover the following topics: Introducing etcd Reading and writing to etcd from the host machine Reading and writing from an application container Watching etcd changes A TTL (time to live) example use cases of etcd (For more resources related to this topic, see here.) Introducing etcd The etcd function is an open source distributed key value store on a computer network where information is stored on more than one node and data is replicated using the Raft consensus algorithm. The etcd function is used to store the CoreOS cluster service discovery and the shared configuration. The configuration is stored in the write-ahead log and includes the cluster member ID, cluster ID and cluster configuration, and everything else that is put there container applications running in the cluster. The etcd function runs on each cluster's central services role machine, and gracefully handles master election during network partitions and in the event of a loss of the current master. Reading and writing to etcd from the host machine You are going to learn how read and write to ectd from the host machine. We will use both the etcdctl and curl examples here. Logging in to host To login to CoreOS VM, follow these steps: Boot your CoreOS VM installed. In your terminal, type this: $ cdcoreos-vagrant $ vagrant up We need to login to the host via ssh: $ vagrant ssh Reading and writing to ectd Let's read and write to etcd using etcdctl. So, perform these steps: Set with etcdctl a message1 key with Book1 as the value: $ etcdctl set /message1 Book1Book1 (we got respond for our successful write to etcd Now, let's read the key value to double-check whether everything is fine there: $ etcdctl get /message1 Book1 Perfect! Next, let's try to do the same using curl via an HTTP-based API. The curl function is handy for accessing etcd from any place from where you have access to etcd cluster but don't want/need to use the etcdctl client: $ curl -L -X PUT http://127.0.0.1:2379/v2/keys/message2 -d value="Book2" {"action":"set","key":"/message2","prevValue":"Book1","value":"Book2","index":13371} Let's read it: $ curl -L http://127.0.0.1:2379/v2/keys/message2 {"action":"get","node":{"key":"/message2","value":"Book2","modifiedIndex":13371,"createdIndex":13371}} Using the HTTP-based etcd API means that etcd can be read from and written to by client applications without the need to interact with the command line. Now, if we want to delete the key value pair, we type the following command: $ etcdctl rm /message1 $ curl -L -X DELETE http://127.0.0.1:2379/v2/keys/message2 Also, we can add a key value pair to a directory, as directories are created automatically when a key is placed inside. We need only one command to put a key inside a directory: $ etcdctl set /foo-directory/foo-key somekey Let's now check the directory's content: $ etcdctl ls /foo-directory –recursive /foo-directory/foo-key Finally, we get the key value from the directory by typing: $ etcdctl get /foo-directory/foo-key somekey Reading and writing from the application container Usually, application containers (this is a general term for docker, rkt, and other types of containers) do not have etcdctl or even curl installed by default. Installing curl is much easier than installing etcdctl. For our example, we will use the AlpineLinux docker image, which is very small in size and will not take much time to pull from docker registry: Firstly, we need to check the docker0 interface IP, which we will use with curl: $ echo"$(ifconfig docker0 | awk'/<inet>/ { print $2}'):2379" 10.1.42.1:2379 Let's run the docker container with a bash shell: $ docker run -it alpine ash We should see something like this in Command Prompt:/ #. As curl is not installed by default on AlpineLinux, we need to install it: $ apk update&&apk add curl $ curl -L http://10.1.42.1:2379/v2/keys/ {"action":"get","node":{"key":"/","dir":true,"nodes":[{"key":"/coreos.com","dir":true,"modifiedIndex":3,"createdIndex":3}]}} Repeat steps 3 and 4 from the previous subtopic so that you understand that it does not matter where you are connecting to etcd from, curl still works in the same way. Press Ctrl +D to exit from the docker container. Watching changes in etcd This time, let's watch the key changes in etcd. Watching key changes is useful when we have, for example, one fleet unit with nginx writing its port to etcd, and another reverse proxy application watching for changes and updating its config: We need to create a directory in etcd first: $ etcdctlmkdir /foo-data Next, we watch for changes in this directory: $ etcdctl watch /foo-data--recursive Now open another CoreOS shell in a new terminal window: $ cdcoreos-vagrant $ vagrantssh We put a new key to /foo-data directory: $ etcdctl set /foo-data/Book is_cool In the first terminal, we should see a notification saying that the key was changed: is_cool A TTL (time to live) examples Sometimes, it is handy to put a time to live (TTL) for a key to expire in a certain amount of time. This is useful, for example,in the case of watching a key with a 60 second TTL, from a reverse proxy. So, if the nginx fleet service has not updated the key, it will expire in 60 seconds and will be removed from etcd. Then the reverse proxy checks for it and does not find it. Hence, it will remove the nginx service from config. Let's set TTL for 30 seconds in this example: Type this in a terminal: $ etcdctl set /foo "I'm Expiring in 30 sec" --ttl 30 I'm Expiring in 30 sec Verify that the key is still there: $ etcdctl get /foo I'm Expiring in 30 sec Check againafter 30 seconds : $ etcdctl get /foo If your requested key has already expired, you will be returned Error: 100: Error: 100: Key not found (/foo) [17053] This time the key got deleted by etcd because we put a TTL of 30 seconds for it. TTL is very handy to use to communicate between different services using etcd as the checking point. Use cases of etcd Application containers running on worker nodes with etcd in proxy mode can read and write to an etcd cluster. Very common etcd use cases are as follows: storing database connection settings, cache settings, and shared settings. For example, the Vulcand proxy server (http://vulcanproxy.com/) uses etcd to store web host connection details, and it becomes available for all cluster-connected worker machines. Another example could be to store a database password for MySQL and retrieve it when running an application container. Summary To learn more about CoreOS Essentials, the following books published by Packt Publishing (https://www.packtpub.com/) are recommended: Learning CoreOS (https://www.packtpub.com/networking-and-servers/learning-coreos) Resources for Article: Further resources on this subject: Mastering CentOS 7 Linux Server[article] Linux Shell Scripting[article] What is Kali Linux[article]
Read more
  • 0
  • 0
  • 8612

article-image-installing-neutron
Packt
04 Nov 2015
15 min read
Save for later

Installing Neutron

Packt
04 Nov 2015
15 min read
We will learn about OpenStack networking in this article by James Denton, who is the author of the book Learning OpenStack Networking (Neutron) - Second Edition. OpenStack Networking, also known as Neutron, provides a network infrastructure as-a-service platform to users of the cloud. In this article, I will guide you through the installation of Neutron networking services on top of the OpenStack environment. Components to be installed include: Neutron API server Modular Layer 2 (ML2) plugin By the end of this article, you will have a basic understanding of the function and operation of various Neutron plugins and agents, as well as a foundation on top of which a virtual switching infrastructure can be built. (For more resources related to this topic, see here.) Basic networking elements in Neutron Neutron constructs the virtual network using elements that are familiar to all system and network administrators, including networks, subnets, ports, routers, load balancers, and more. Using version 2.0 of the core Neutron API, users can build a network foundation composed of the following entities: Network: A network is an isolated layer 2 broadcast domain. Typically reserved for the tenants that created them, networks could be shared among tenants if configured accordingly. The network is the core entity of the Neutron API. Subnets and ports must always be associated with a network. Subnet: A subnet is an IPv4 or IPv6 address block from which IP addresses can be assigned to virtual machine instances. Each subnet must have a CIDR and must be associated with a network. Multiple subnets can be associated with a single network and can be noncontiguous. A DHCP allocation range can be set for a subnet that limits the addresses provided to instances. Port: A port in Neutron represents a virtual switch port on a logical virtual switch. Virtual machine interfaces are mapped to Neutron ports, and the ports define both the MAC address and the IP address to be assigned to the interfaces plugged into them. Neutron port definitions are stored in the Neutron database, which is then used by the respective plugin agent to build and connect the virtual switching infrastructure. Cloud operators and users alike can configure network topologies by creating and configuring networks and subnets, and then instruct services such as Nova to attach virtual devices to ports on these networks. Users can create multiple networks, subnets, and ports, but are limited to thresholds defined by per-tenant quotas set by the cloud administrator. Extending functionality with plugins Neutron introduces support for third-party plugins and drivers that extend network functionality and implementation of the Neutron API. Plugins and drivers can be created that use a variety of software- and hardware-based technologies to implement the network built by operators and users. There are two major plugin types within the Neutron architecture: Core plugin Service plugin A core plugin implements the core Neutron API and is responsible for adapting the logical network described by networks, ports, and subnets into something that can be implemented by the L2 agent and IP address management system running on the host. A service plugin provides additional network services such as routing, load balancing, firewalling, and more. The Neutron API provides a consistent experience to the user despite the chosen networking plugin. For more information on interacting with the Neutron API, visit http://developer.openstack.org/api-ref-networking-v2.html. Modular Layer 2 plugin Prior to the inclusion of the Modular Layer 2 (ML2) plugin in the Havana release of OpenStack, Neutron was limited to using a single core plugin at a time. The ML2 plugin replaces two monolithic plugins in its reference implementation: the LinuxBridge plugin and the Open vSwitch plugin. Their respective agents, however, continue to be utilized and can be configured to work with the ML2 plugin. Drivers The ML2 plugin introduced the concept of type drivers and mechanism drivers to separate the types of networks being implemented and the mechanisms for implementing networks of those types. Type drivers An ML2 type driver maintains type-specific network state, validates provider network attributes, and describes network segments using provider attributes. Provider attributes include network interface labels, segmentation IDs, and network types. Supported network types include local, flat, vlan, gre, and vxlan. Mechanism drivers An ML2 mechanism driver is responsible for taking information established by the type driver and ensuring that it is properly implemented. Multiple mechanism drivers can be configured to operate simultaneously, and can be described using three types of models: Agent-based: This includes LinuxBridge, Open vSwitch, and others Controller-based: This includes OpenDaylight, VMWare NSX, and others Top-of-Rack: This includes Cisco Nexus, Arista, Mellanox, and others The LinuxBridge and Open vSwitch ML2 mechanism drivers are used to configure their respective switching technologies within nodes that host instances and network services. The LinuxBridge driver supports local, flat, vlan, and vxlan network types, while the Open vSwitch driver supports all of those as well as the gre network type. The L2 population driver is used to limit the amount of broadcast traffic that is forwarded across the overlay network fabric. Under normal circumstances, unknown unicast, multicast, and broadcast traffic floods out all tunnels to other compute nodes. This behavior can have a negative impact on the overlay network fabric, especially as the number of hosts in the cloud scales out. As an authority on what instances and other network resources exist in the cloud, Neutron can prepopulate forwarding databases on all hosts to avoid a costly learning operation. When ARP proxy is used, Neutron prepopulates the ARP table on all hosts in a similar manner to avoid ARP traffic from being broadcast across the overlay fabric. ML2 architecture The following diagram demonstrates at a high level how the Neutron API service interacts with the various plugins and agents responsible for constructing the virtual and physical network: Figure 3.1 The preceding diagram demonstrates the interaction between the Neutron API, Neutron plugins and drivers, and services such as the L2 and L3 agents. For more information on the Neutron ML2 plugin architecture, refer to the OpenStack Neutron Modular Layer 2 Plugin Deep Dive video from the 2013 OpenStack Summit in Hong Kong available at https://www.youtube.com/watch?v=whmcQ-vHams. Third-party support Third-party vendors such as PLUMGrid and OpenContrail have implemented support for their respective SDN technologies by developing their own monolithic or ML2 plugins that implement the Neutron API and extended network services. Others, including Cisco, Arista, Brocade, Radware, F5, VMWare, and more, have created plugins that allow Neutron to interface with OpenFlow controllers, load balancers, switches, and other network hardware. For a look at some of the commands related to these plugins, refer to Appendix, Additional Neutron Commands. The configuration and use of these plugins is outside the scope of this article. For more information on the available plugins for Neutron, visit http://docs.openstack.org/admin-guide-cloud/content/section_plugin-arch.html. Network namespaces OpenStack was designed with multitenancy in mind and provides users with the ability to create and manage their own compute and network resources. Neutron supports each tenant having multiple private networks, routers, firewalls, load balancers, and other networking resources. It is able to isolate many of those objects through the use of network namespaces. A network namespace is defined as a logical copy of the network stack with its own routes, firewall rules, and network interface devices. When using the open source reference plugins and drivers, every network, router, and load balancer that is created by a user is represented by a network namespace. When network namespaces are enabled, Neutron is able to provide isolated DHCP and routing services to each network. These services allow users to create overlapping networks with other users in other projects and even other networks in the same project. The following naming convention for network namespaces should be observed: DHCP namespace: qdhcp-<network UUID> Router namespace: qrouter-<router UUID> Load Balancer namespace: qlbaas-<load balancer UUID> A qdhcp namespace contains a DHCP service that provides IP addresses to instances using the DHCP protocol. In a reference implementation, dnsmasq is the process that services DHCP requests. The qdhcp namespace has an interface plugged into the virtual switch and is able to communicate with instances and other devices in the same network or subnet. A qdhcp namespace is created for every network where the associated subnet(s) have DHCP enabled. A qrouter namespace represents a virtual router and is responsible for routing traffic to and from instances in the subnets it is connected to. Like the qdhcp namespace, the qrouter namespace is connected to one or more virtual switches depending on the configuration. A qlbaas namespace represents a virtual load balancer and may run a service such as HAProxy that load balances traffic to instances. The qlbaas namespace is connected to a virtual switch and can communicate with instances and other devices in the same network or subnet. The leading q in the name of the network namespaces stands for Quantum, the original name for the OpenStack Networking service. Network namespaces of the types mentioned earlier will only be seen on nodes running the Neutron DHCP, L3, and LBaaS agents, respectively. These services are typically configured only on controllers or dedicated network nodes. The ip netns list command can be used to list available namespaces, and commands can be executed within the namespace using the following syntax: ip netns exec NAMESPACE_NAME <command> Commands that can be executed in the namespace include ip, route, iptables, and more. The output of these commands corresponds to data specific to the namespace they are executed in. For more information on network namespaces, see the man page for ip netns at http://man7.org/linux/man-pages/man8/ip-netns.8.html. Installing and configuring Neutron services In this installation, the various services that make up OpenStack Networking will be installed on the controller node rather than a dedicated networking node. The compute nodes will run L2 agents that interface with the controller node and provide virtual switch connections to instances. Remember that the configuration settings recommended here and online at docs.openstack.org may not be appropriate for production systems. To install the Neutron API server, the DHCP and metadata agents, and the ML2 plugin on the controller, issue the following command: # apt-get install neutron-server neutron-dhcp-agent neutron-metadata-agent neutron-plugin-ml2 neutron-common python-neutronclient On the compute nodes, only the ML2 plugin is required: # apt-get install neutron-plugin-ml2 Creating the Neutron database Using the mysql client, create the Neutron database and associated user. When prompted for the root password, use openstack: # mysql –u root –p Enter the following SQL statements in the MariaDB [(none)] > prompt: CREATE DATABASE neutron; GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' IDENTIFIED BY 'neutron'; GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' IDENTIFIED BY 'neutron'; quit; Update the [database] section of the Neutron configuration file at /etc/neutron/neutron.conf on all nodes to use the proper MySQL database connection string based on the preceding values rather than the default value: [database] connection = mysql://neutron:neutron@controller01/neutron Configuring the Neutron user, role, and endpoint in Keystone Neutron requires that you create a user, role, and endpoint in Keystone in order to function properly. When executed from the controller node, the following commands will create a user called neutron in Keystone, associate the admin role with the neutron user, and add the neutron user to the service project: # openstack user create neutron --password neutron # openstack role add --project service --user neutron admin Create a service in Keystone that describes the OpenStack Networking service by executing the following command on the controller node: # openstack service create --name neutron --description "OpenStack Networking" network The service create command will result in the following output: Figure 3.2 To create the endpoint, use the following openstack endpoint create command: # openstack endpoint create --publicurl http://controller01:9696 --adminurl http://controller01:9696 --internalurl http://controller01:9696 --region RegionOne network The resulting endpoint is as follows: Figure 3.3 Enabling packet forwarding Before the nodes can properly forward or route traffic for virtual machine instances, there are three kernel parameters that must be configured on all nodes: net.ipv4.ip_forward net.ipv4.conf.all.rp_filter net.ipv4.conf.default.rp_filter The net.ipv4.ip_forward kernel parameter allows the nodes to forward traffic from the instances to the network. The default value is 0 and should be set to 1 to enable IP forwarding. Use the following command on all nodes to implement this change: # sysctl -w "net.ipv4.ip_forward=1" The net.ipv4.conf.default.rp_filter and net.ipv4.conf.all.rp_filter kernel parameters are related to reverse path filtering, a mechanism intended to prevent certain types of denial of service attacks. When enabled, the Linux kernel will examine every packet to ensure that the source address of the packet is routable back through the interface in which it came. Without this validation, a router can be used to forward malicious packets from a sender who has spoofed the source address to prevent the target machine from responding properly. In OpenStack, anti-spoofing rules are implemented by Neutron on each compute node within iptables. Therefore, the preferred configuration for these two rp_filter values is to disable them by setting them to 0. Use the following sysctl commands on all nodes to implement this change: # sysctl -w "net.ipv4.conf.default.rp_filter=0" # sysctl -w "net.ipv4.conf.all.rp_filter=0" Using sysctl –w makes the changes take effect immediately. However, the changes are not persistent across reboots. To make the changes persistent, edit the /etc/sysctl.conf file on all hosts and add the following lines: net.ipv4.ip_forward = 1 net.ipv4.conf.default.rp_filter = 0 net.ipv4.conf.all.rp_filter = 0 Load the changes into memory on all nodes with the following sysctl command: # sysctl -p Configuring Neutron to use Keystone The Neutron configuration file found at /etc/neutron/neutron.conf has dozens of settings that can be modified to meet the needs of the OpenStack cloud administrator. A handful of these settings must be changed from their defaults as part of this installation. To specify Keystone as the authentication method for Neutron, update the [DEFAULT] section of the Neutron configuration file on all hosts with the following setting: [DEFAULT] auth_strategy = keystone Neutron must also be configured with the appropriate Keystone authentication settings. The username and password for the neutron user in Keystone were set earlier in this article. Update the [keystone_authtoken] section of the Neutron configuration file on all hosts with the following settings: [keystone_authtoken] auth_uri = http://controller01:5000 auth_url = http://controller01:35357 auth_plugin = password project_domain_id = default user_domain_id = default project_name = service username = neutron password = neutron Configuring Neutron to use a messaging service Neutron communicates with various OpenStack services on the AMQP messaging bus. Update the [DEFAULT] and [oslo_messaging_rabbit] sections of the Neutron configuration file on all hosts to specify RabbitMQ as the messaging broker: [DEFAULT] rpc_backend = rabbit The RabbitMQ authentication settings should match what was previously configured for the other OpenStack services: [oslo_messaging_rabbit] rabbit_host = controller01 rabbit_userid = openstack rabbit_password = rabbit Configuring Nova to utilize Neutron networking Before Neutron can be utilized as the network manager for Nova Compute services, the appropriate configuration options must be set in the Nova configuration file located at /etc/nova/nova.conf on all hosts. Start by updating the following sections with information on the Neutron API class and URL: [DEFAULT] network_api_class = nova.network.neutronv2.api.API [neutron] url = http://controller01:9696 Then, update the [neutron] section with the proper Neutron credentials: [neutron] auth_strategy = keystone admin_tenant_name = service admin_username = neutron admin_password = neutron admin_auth_url = http://controller01:35357/v2.0 Nova uses the firewall_driver configuration option to determine how to implement firewalling. As the option is meant for use with the nova-network networking service, it should be set to nova.virt.firewall.NoopFirewallDriver to instruct Nova not to implement firewalling when Neutron is in use: [DEFAULT] firewall_driver = nova.virt.firewall.NoopFirewallDriver The security_group_api configuration option specifies which API Nova should use when working with security groups. For installations using Neutron instead of nova-network, this option should be set to neutron as follows: [DEFAULT] security_group_api = neutron Nova requires additional configuration once a mechanism driver has been determined. Configuring Neutron to notify Nova Neutron must be configured to notify Nova of network topology changes. Update the [DEFAULT] and [nova] sections of the Neutron configuration file on the controller node located at /etc/neutron/neutron.conf with the following settings: [DEFAULT] notify_nova_on_port_status_changes = True notify_nova_on_port_data_changes = True nova_url = http://controller01:8774/v2 [nova] auth_url = http://controller01:35357 auth_plugin = password project_domain_id = default user_domain_id = default region_name = RegionOne project_name = service username = nova password = nova Summary Neutron has seen major internal architectural improvements over the last few releases. These improvements have made developing and implementing network features easier for developers and operators, respectively. Neutron maintains the logical network architecture in its database, and network plugins and agents on each node are responsible for configuring virtual and physical network devices accordingly. With the introduction of the ML2 plugin, developers can spend less time implementing the core Neutron API functionality and more time developing value-added features. Now that OpenStack Networking services have been installed across all nodes in the environment, configuration of a layer 2 networking plugin is all that remains before instances can be created. Resources for Article: Further resources on this subject: Installing OpenStack Swift [article] Securing OpenStack Networking [article] The orchestration service for OpenStack [article]
Read more
  • 0
  • 0
  • 8611

article-image-using-different-jquery-event-listeners-responsive-interaction
Packt
16 Sep 2013
9 min read
Save for later

Using different jQuery event listeners for responsive interaction

Packt
16 Sep 2013
9 min read
(For more resources related to this topic, see here.) Getting Started First we want to create JavaScript that transforms a select form element into a button widget that changes the value of the form element when a button is pressed. So the first part of that task is to build a form with a select element. How to do it This part is simple; start by creating a new web page. Inside it, create a form with a select element. Give the select element some options. Wrap the form in a div element with the class select. See the following example. I have added a title just for placement. <h2>Super awesome form element</h2><div class="select"> <form> <select> <option value="1">1</option> <option value="Bar">Bar</option> <option value="3">3</option> </select> </form></div> Next, create a new CSS file called desktop.css and add a link to it in your header. After that, add a media query to the link for screen media and min-device-width:321px. The media query causes the browser to load the new CSS file only on devices with a screen larger than 320 pixels. Copy and paste the link to the CSS, but change the media query to screen and min-width:321px. This will help you test and demonstrate the mobile version of the widget on your desktop. <link rel="stylesheet" media="screen and (min-device-width:321px)" href="desktop.css" /><link rel="stylesheet" media="screen and (min-width:321px)" href="desktop.css" /> Next, create a script tag with a link to a new JavaScript file called uiFunctions.js and then, of course, create the new JavaScript file. Also, create another script element with a link to the recent jQuery library. <script src = "http://code.jquery.com/jquery-1.8.2.min.js"></script><script src = "uiFunctions.js"></script> Now open the new JavaScript file uiFunctions.js in your editor and add instructions to do something on a document load. $(document).ready(function(){ //Do something}); The first thing your JavaScript should do when it loads is determine what kind of device it is on—a mobile device or a desktop. There are a few logical tests you can utilize to determine whether the device is mobile. You can test navigator.userAgent; specifically, you can use the .test() method, which in essence tests a string to see whether an expression of characters is in it, checks the window width, and checks whether the screen width is smaller than 600 pixels. For this article, let's use all three of them. Ultimately, you might just want to test navigator.userAgent. Write this inside the $(document).ready() function. if( /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) || $(window).width()<600 ||window.screen.width<600) { //Do something for mobile} else { //Do something for the desktop} Inside, you will have to create a listener for the desktop device interaction event and the mouse click event, but that is later. First, let's write the JavaScript to create the UI widget for the select element. Create a function that iterates for each select option and appends a button with the same text as the option to the select div element. This belongs inside the $(document).ready() function, but outside and before the if condition. The order of these is important. $('select option').each(function(){ $('div.select').append('<button>'+$(this).html()+'</button>');}); Now, if you load the page on your desktop computer, you will see that it generates new buttons below the select element, one for each select option. You can click on them, but nothing happens. What we want them to do is change the value of the select form element. To do so, we need to add an event listener to the buttons inside the else condition. For the desktop version, you need to add a .click() event listener with a function. Inside the function, create two new variables, element and itemClicked. Make element equal the string button, and itemClicked, the jQuery object event target, or $(event.target). The next line is tricky; we're going to use the .addClass() method to add a selected class to the element variable :nth-child(n). Also, the n of the :nth-child(n) should be a call to a function named .eventAction(), to which we will add the integer 2. We will create the function next. $('button').click(function(){ var element = 'button'; var itemClicked = $(event.target); $(element+':nth-child(' + (eventAction(itemClicked,element) + 2) + ')').addClass('selected');}); Next, outside the $(document).ready() function, create the eventAction() function. It will receive the variables itemClicked and element. The reason we make this function is because it performs the same functions for both the desktop click event and the mobile tap or long tap events. function eventAction(itemClicked,element){ //Do something!}; Inside the eventAction() function, create a new variable called choiceAction. Make choiceAction equal to the index of the element object in itemClicked, or just take a look at the following code: var choiceAction = $(element).index(itemClicked); Next, use the .removeClass() method to remove the selected class from the element object. $(element).removeClass('selected'); There are only two more steps to complete the function. First, add the selected attribute to the select field option using the .eq() method and the choiceAction variable. Finally, remember that when the function was called in the click event, it was expecting something to replace the n in :nth-child(n); so end the function by returning the value of the choiceAction variable. $('select option').eq(choiceAction).attr('selected','selected');return choiceAction; That takes care of everything but the mobile event listeners. The button style will be added at the end of the article. See how it looks in the following screenshot: This will be simple. First, using jQuery's $.getScript() method, add a line to retrieve the jQuery library in the first if condition where we tested navigator.userAgent and the screen sizes to see whether the page was loaded into the viewport of a mobile device. The jQuery Mobile library will transform the HTML into a mobile, native-looking app. $.getScript("http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"); The next step is to copy the desktop's click event listener, paste it below the $.getScript line, and change some values. Replace the .click() listener with a jQuery Mobile event listener, .tap() or .taphold(), change the value of the element variable to the string .uti-btn, and append the daisy-chained .parent().prev() methods to the itemClicked variable value, $(event.target). Replace the line that calls the eventAction() function in the :nth-child(n) selector with a more simple call to eventAction(), with the variables itemClicked and element. $('button').click(function(){ var element = '.ui-btn'; var itemClicked = $(event.target).parent().prev(); eventAction(itemClicked,element);}); When you click on the buttons to update the select form element in the mobile device, you will need to instruct jQuery Mobile to refresh its select menu. jQuery Mobile has a method to refresh its select element. $('select').selectmenu("refresh",true); That is all you need for the JavaScript file. Now open the HTML file and add a few things to the header. First, add a style tag to make the select form element and .ui-select hidden with the CSS display:none;. Next, add links to the jQuery Mobile stylesheets and desktop.css with a media query for media screen and max-width: 600px; or max-device-width:320px;. <style> select,.ui-select{display:none;}</style><link rel="stylesheet" media="screen and (max-width:600px)" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css"><link rel="stylesheet" media="screen and (min-width:600px)" href="desktop.css" /> When launched on a mobile device, the widget will look like this: Then, open the desktop.css file and create some style for the widget buttons. For the button element, add an inline display, padding, margins, border radius, background gradient, box shadow, font color, text shadow, and a cursor style. button { display:inline; padding:8px 15px; margin:2px; border-top:1px solid #666; border-left:1px solid #666; border-bottom:1px solid #333; border-right:1px solid #333; border-radius:5px; background: #7db9e8; /* Old browsers */ background:-moz-linear-gradient(top, #7db9e8 0%,#207cca 49%,#2989d8 50%,#1e5799 100%); /* FF3.6+ */ background:-webkit-gradient(linear,left top,left bottom, color-stop(0%,#7db9e8), color-stop(49%,#207cca), color-stop(50%,#2989d8), color-stop(100%,#1e5799)); /* Chrome,Safari4+ */ background:-webkit-linear-gradient(top,#7db9e8 0%,#207cca 49%, #2989d8 50%,#1e5799 100%); /* Chrome10+,Safari5.1+ */ background:-o-linear-gradient(top,#7db9e8 0%,#207cca 49%,#2989d8 50%,#1e5799 100%); /* Opera 11.10+ */ background:-ms-linear-gradient(top,#7db9e8 0%,#207cca 49%,#2989d8 50%,#1e5799 100%); /* IE10+ */ background:linear-gradient(to bottom,#7db9e8 0%,#207cca 49%,#2989d8 50%,#1e5799 100%); /* W3C */ filter:progid:DXImageTransform.Microsoft.gradient ( startColorstr='#7db9e8', endColorstr='#1e5799',GradientType=0 ); /* IE6-9 */ color:white; text-shadow: -1px -1px 1px #333; box-shadow: 1px 1px 4px 2px #999; cursor:pointer;} Finally, add CSS for the .selected class that was added by the JavaScript. This CSS will change the button to look as if the button has been pressed in. .selected{ border-top:1px solid #333; border-left:1px solid #333; border-bottom:1px solid #666; border-right:1px solid #666; color:#ffff00; box-shadow:inset 2px 2px 2px 2px #333; background: #1e5799; /* Old browsers */ background:-moz-linear-gradient(top,#1e5799 0%,#2989d8 50%, #207cca 51%, #7db9e8 100%); /* FF3.6+ */ background:-webkit-gradient(linear,left top,left bottom, color-stop(0%,#1e5799),color-stop(50%,#2989d8), color-stop(51%,#207cca),color-stop(100%,#7db9e8)); /* Chrome,Safari4+ */ background:-webkit-linear-gradient(top, #1e5799 0%,#2989d8 50%, #207cca 51%,#7db9e8 100%); /* Chrome10+,Safari5.1+ */ background:-o-linear-gradient(top, #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%); /* Opera 11.10+ */ background:-ms-linear-gradient(top, #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%); /* IE10+ */ background: linear-gradient(to bottom, #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%); /* W3C */ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#1e5799', endColorstr='#7db9e8',GradientType=0 ); /* IE6-9 */} How it works This uses a combination of JavaScript and media queries to build a dynamic HTML form widget. The JavaScript tests the user agent and screen size to see if it is a mobile device and responsively delivers a different event listener for the different device types. In addition to that, the look of the widget will be different for different devices. Summary In this article we learned how to create an interactive widget that uses unobtrusive JavaScript, which uses different event listeners for desktop versus mobile devices. This article also helped you build your own web app that can transition between the desktop and mobile versions without needing you to rewrite your entire JavaScript code. Resources for Article : Further resources on this subject: Video conversion into the required HTML5 Video playback [Article] LESS CSS Preprocessor [Article] HTML5 Presentations - creating our initial presentation [Article]
Read more
  • 0
  • 0
  • 8609

article-image-irrlicht-creating-basic-template-application
Packt
21 Nov 2011
3 min read
Save for later

Irrlicht: Creating a Basic Template Application

Packt
21 Nov 2011
3 min read
(For more resources related to this topic, see here.) Creating a new empty project Let's get started by creating a new project from scratch. Follow the steps that are given for the IDE and operating system of your choice. Visual Studio Open Visual Studio and select File | New | Project from the menu. Expand the Visual C++ item and select Win32 Console Application. Click on OK to continue: In the project wizard click on Next to edit the Application Settings. Make sure Empty project is checked. Whether Windows application or Console application is selected will not matter. Click on Finish and your new project will be created: Let's add a main source file to the project. Right-click on Source Files and select Add New Item...|. Choose C++ File(.cpp) and call the file main.cpp: CodeBlocks Use the CodeBlocks project wizard to create a new project as described in the last chapter. Now double-click on main.cpp to open this file and delete its contents. Your main source file should now be blank. Linux and the command line Copy the make file of one of the examples from the Irrlicht examples folder to where you wish to create your new project. Open the make file with a text editor of your choice and change, in line 6, the target name to what you wish your project to be called. Additionally, change, in line 10, the variable IrrlichtHome to where you extracted your Irrlicht folder. Now create a new empty file called main.cpp. Xcode Open Xcode and select File | New Project. Select Command Line Tool from Application. Make sure the type of the application is set to C++ stdc++: When your new project is created, change Active Architecture to i386 if you are using an Intel Mac, or ppc if you are using a PowerPC Mac. Create a new target by right-clicking on Targets, select Application and click on Next. Target Name represents the name of the compiled executable and application bundle: The target info window will show up. Fill in the location of the include folder of your extracted Irrlicht package in the field Header Search Path and make sure the field GCC_ PREFIX_HEADER is empty: Right-click on the project file and add the following frameworks by selecting Add Existing Frameworks...|: Cocoa.framework Carbon.framework IOKit.framework OpenGL.framework Now, we have to add the static library named libIrrlicht.a that we compiled in Chapter 1, Installing Irrlicht. Right-click on the project file and click on Add | Existing Frameworks.... Now click on the button Add Other... and select the static library. Delete the original compile target and delete the contents of main.cpp. Time for action – creating the main entry point Now that our main file is completely empty, we need a main entry point. We don't need any command-line parameters, so just go ahead and add an empty main() method as follows: int main(){ return 0;} If you are using Visual Studio, you need to link against the Irrlicht library. You can link from code by adding the following line of code: #pragma comment(lib, "Irrlicht.lib") This line should be placed between your include statements and your main() function. If you are planning to use the same codebase for compiling on different platforms, you should use a compiler-specific define statement, so that this line will only be active when compiling the application with Visual Studio. #if defined(_MSC_VER) #pragma comment(lib, "Irrlicht.lib")#endif
Read more
  • 0
  • 0
  • 8600

article-image-new-ipad-features-ios-6
Packt
20 Feb 2013
2 min read
Save for later

New iPad Features in iOS 6

Packt
20 Feb 2013
2 min read
(For more resources related to this topic, see here.) New iPad features and native applications We're going to identify some of the applications that come built-in to the new iPad. The applications designed by Apple for the iPad are Safari, Mail, Photos, FaceTime, Maps, Siri, Newsstand, Messages, Calendar, Reminders, Contacts, App Store, iTunes, Music, Videos, Notes, Camera, Photo Booth, Clock, Game Center, and Settings. Let's get started by exploring these applications. Getting ready Locate the Mail, Photos, App Store, iTunes, Music, and Settings apps For details on each app, visit http://www.apple.com/ipad/built-in-apps/ How to do it... These apps form the base of the iPad and by themselves can satisfy most of our media and communication needs. We'll delve deeper into each of the following apps in the upcoming recipes. Mail Photos App Store iTunes and Music Settings How it works... The applications can work together to provide a unifying experience. From the Photos app, we are able to share photos via the Mail application. Purchasing music in iTunes will allow us playback in our Music app. Ubiquity is what makes this device and its apps so useful. Summary This article gave us a brief overview of the application that illustrate the new iPad's features. Resources for Article : Further resources on this subject: Build iPhone, Android and iPad Applications using jQTouch [Article] Getting Started on UDK with iOS [Article] Interface Designing for Games in iOS [Article]
Read more
  • 0
  • 0
  • 8593

article-image-objects-python
Packt
27 Jul 2010
15 min read
Save for later

Objects in Python

Packt
27 Jul 2010
15 min read
(For more resources on Python 3, see here.) Creating Python classes We don't have to write much Python code to realize that Python is a very "clean" language. When we want to do something, we just do it, without having to go through a lot of setup. The ubiquitous, "hello world" in Python, as you've likely seen, is only one line. Similarly, the simplest class in Python 3 looks like this: class MyFirstClass: pass There's our first object-oriented program! The class definition starts with the class keyword. This is followed by a name (of our choice) identifying the class, and is terminated with a colon. The class name must follow standard Python variable naming rules (must start with a letter or underscore, can only be comprised of letters, underscores, or numbers). In addition, the Python style guide (search the web for "PEP 8"), recommends that classes should be named using CamelCase notation (start with a capital letter, any subsequent words should also start with a capital).   The class definition line is followed by the class contents, indented. As with other Python constructs, indentation is used to delimit the classes, rather than braces or brackets as many other languages use. Use four spaces for indentation unless you have a compelling reason not to (such as fitting in with somebody else's code that uses tabs for indents). Any decent programming editor can be configured to insert four spaces whenever the Tab key is pressed. Since our first class doesn't actually do anything, we simply use the pass keyword on the second line to indicate that no further action needs to be taken. We might think there isn't much we can do with this most basic class, but it does allow us to instantiate objects of that class. We can load the class into the Python 3 interpreter so we can play with it interactively. To do this, save the class definition mentioned earlier into a file named first_class.py and then run the command python -i first_class.py. The -i argument tells Python to "run the code and then drop to the interactive interpreter". The following interpreter session demonstrates basic interaction with this class: >>> a = MyFirstClass() >>> b = MyFirstClass() >>> print(a) <__main__.MyFirstClass object at 0xb7b7faec> >>> print(b) <__main__.MyFirstClass object at 0xb7b7fbac> >>> This code instantiates two objects from the new class, named a and b. Creating an instance of a class is a simple matter of typing the class name followed by a pair of parentheses. It looks much like a normal function call, but Python knows we're "calling" a class and not a function, so it understands that its job is to create a new object. When printed, the two objects tell us what class they are and what memory address they live at. Memory addresses aren't used much in Python code, but here,it demonstrates that there are two distinctly different objects involved. Adding attributes Now, we have a basic class, but it's fairly useless. It doesn't contain any data, and it doesn't do anything. What do we have to do to assign an attribute to a given object? It turns out that we don't have to do anything special in the class definition. We can set arbitrary attributes on an instantiated object using the dot notation: class Point: pass p1 = Point() p2 = Point() p1.x = 5 p1.y = 4 p2.x = 3 p2.y = 6 print(p1.x, p1.y) print(p2.x, p2.y) If we run this code, the two print statements at the end tell us the new attribute values on the two objects: 5 4 3 6 This code creates an empty Point class with no data or behaviors. Then it creates two instances of that class and assigns each of those instances x and y coordinates to identify a point in two dimensions. All we need to do to assign a value to an attribute on an object is use the syntax <object>.<attribute>=<value>. This is sometimes referred to as dot notation. The value can be anything: a Python primitive, a built-in data type, another object. It can even be a function or another class! Making it do something Now, having objects with attributes is great, but object-oriented programming is really about the interaction between objects. We're interested in invoking actions that cause things to happen to those attributes. It is time to add behaviors to our classes. Let's model a couple of actions on our Point class. We can start with a method called reset that moves the point to the origin (the origin is the point where x and y are both zero). This is a good introductory action because it doesn't require any parameters: class Point: def reset(self): self.x = 0 self.y = 0 p = Point() p.reset() print(p.x, p.y) That print statement shows us the two zeros on the attributes: 0 0 A method in Python is identical to defining a function. It starts with the keyword def followed by a space and the name of the method. This is followed by a set of parentheses containing the parameter list (we'll discuss the self parameter in just a moment), and terminated with a colon. The next line is indented to contain the statements inside the method. These statements can be arbitrary Python code operating on the object itself and any parameters passed in as the method sees fit. The one difference between methods and normal functions is that all methods have one required argument. This argument is conventionally named self; I've never seen a programmer use any other name for this variable (convention is a very powerful thing). There's nothing stopping you, however, from calling it this or even Martha. The self argument to a method is simply a reference to the object that the method is being invoked on. We can access attributes and methods of that object as if it were any other object. This is exactly what we do inside the reset method when we set the x and y attributes of the self object. Notice that when we call the p.reset() method, we do not have to pass the self argument into it. Python automatically takes care of this for us. It knows we're calling a method on the p object, so it automatically passes that object to the method. However, the method really is just a function that happens to be on a class. Instead of calling the method on the object, we could invoke the function on the class, explicitly passing our object as the self argument: p = Point() Point.reset(p) print(p.x, p.y) The output is the same as the previous example because, internally, the exact same process has occurred. What happens if we forget to include the self argument in our class definition? Python will bail with an error message: >>> class Point: ... def reset(): ... pass ... >>> p = Point() >>> p.reset() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: reset() takes no arguments (1 given) The error message is not as clear as it could be ("You silly fool, you forgot the self argument" would be more informative). Just remember that when you see an error message that indicates missing arguments, the first thing to check is whether you forgot self in the method definition. So how do we pass multiple arguments to a method? Let's add a new method that allows us to move a point to an arbitrary position, not just the origin. We can also include one that accepts another Point object as input and returns the distance between them: import math class Point: def move(self, x, y): self.x = x self.y = y def reset(self): self.move(0, 0) def calculate_distance(self, other_point): return math.sqrt((self.x - other_point.x)**2 +(self.y - other_point.y) **2) # how to use it: point1 = Point() point2 = Point() point1.reset() point2.move(5,0) print(point2.calculate_distance(point1)) assert (point2.calculate_distance(point1) == point1.calculate_distance(point2)) point1.move(3,4) print(point1.calculate_distance(point2)) print(point1.calculate_distance(point1)) The print statements at the end give us the following output: 5.0 4.472135955 0.0 A lot has happened here. The class now has three methods. The move method accepts two arguments, x and y, and sets the values on the self object, much like the old reset method from the previous example. The old reset method now calls move, since a reset is just a move to a specific known location. The calculate_distance method uses the not-too-complex Pythagorean Theorem to calculate the distance between two points. I hope you understand the math (** means squared, and math.sqrt calculates a square root), but it's not a requirement for our current focus: learning how to write methods. The example code at the end shows how to call a method with arguments; simply include the arguments inside the parentheses, and use the same dot notation to access the method. I just picked some random positions to test the methods. The test code calls each method and prints the results on the console. The assert function is a simple test tool; the program will bail if the statement after assert is False (or zero, empty, or None). In this case, we use it to ensure that the distance is the same regardless of which point called the other point's calculate_distance method. Initializing the object If we don't explicitly set the x and y positions on our Point object, either using move or by accessing them directly, we have a broken point with no real position. What will happen when we try to access it? Well, let's just try it and see. "Try it and see" is an extremely useful tool for Python study. Open up your interactive interpreter and type away. The following interactive session shows what happens if we try to access a missing attribute. If you saved the previous example as a file or are using the examples distributed in this article, you can load it into the Python interpreter with the command python -i filename.py. >>> point = Point() >>> point.x = 5 >>> print(point.x) 5 >>> print(point.y) Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Point' object has no attribute 'y' Well, at least it threw a useful exception. You've probably seen them before (especially the ubiquitous SyntaxError, which means you typed something incorrectly!). At this point, simply be aware that it means something went wrong. The output is useful for debugging. In the interactive interpreter it tells us the error occurred at line 1, which is only partially true (in an interactive session, only one line is executed at a time). If we were running a script in a file, it would tell us the exact line number, making it easy to find the offending code. In addition, it tells us the error is an AttributeError, and gives a helpful message telling us what that error means. We can catch and recover from this error, but in this case, it feels like we should have specified some sort of default value. Perhaps every new object should be reset() by default or maybe it would be nice if we could force the user to tell us what those positions should be when they create the object. Most object-oriented programming languages have the concept of a constructor, a special method that creates and initializes the object when it is created. Python is a little different; it has a constructor and an initializer. Normally, the constructor function is rarely ever used unless you're doing something exotic. So we'll start our discussion with the initialization method. The Python initialization method is the same as any other method, except it has a special name: __init__. The leading and trailing double underscores mean, "this is a special method that the Python interpreter will treat as a special case". Never name a function of your own with leading and trailing double underscores. It may mean nothing to Python, but there's always the possibility that the designers of Python will add a function that has a special purpose with that name in the future, and when they do, your code will break. Let's start with an initialization function on our Point class that requires the user to supply x and y coordinates when the Point object is instantiated: class Point: def __init__(self, x, y): self.move(x, y) def move(self, x, y): self.x = x self.y = y def reset(self): self.move(0, 0) # Constructing a Point point = Point(3, 5) print(point.x, point.y) Now, our point can never go without a y coordinate! If we try to construct a point without including the proper initialization parameters, it will fail with a not enough arguments error similar to the one we received earlier when we forgot the self argument. What if we don't want to make those two arguments required? Well then we can use the same syntax Python functions use to provide default arguments. The keyword argument syntax appends an equals sign after each variable name. If the calling object does not provide that argument, then the default argument is used instead; the variables will still be available to the function, but they will have the values specified in the argument list. Here's an example: class Point: def __init__(self, x=0, y=0): self.move(x, y) Most of the time, we put our initialization statements in an __init__ function. But as mentioned earlier, Python has a constructor in addition to its initialization function. You may never need to use the other Python constructor, but it helps to know it exists, so we'll cover it briefly. The constructor function is called __new__ as opposed to __init__, and accepts exactly one argument, the class that is being constructed (it is called before the object is constructed, so there is no self argument). It also has to return the newly created object. This has interesting possibilities when it comes to the complicated art of meta-programming, but is not very useful in day-to-day programming. In practice, you will rarely, if ever, need to use __new__, and __init__ will be sufficient. Explaining yourself Python is an extremely easy-to-read programming language; some might say it is self-documenting. However, when doing object-oriented programming, it is important to write API documentation that clearly summarizes what each object and method does. Keeping documentation up-to-date is difficult; the best way to do it is to write it right into our code. Python supports this through the use of docstrings. Each class, function, or method header can have a standard Python string as the first line following the definition (the line that ends in a colon). This line should be indented the same as the following code. Docstrings are simply Python strings enclosed with apostrophe (') or quote (") characters. Often, docstrings are quite long and span multiple lines (the style guide suggests that line-length should not exceed 80 characters), which can be formatted as multi-line strings, enclosed in matching triple apostrophe (''') or triple quote (""") characters. A docstring should clearly and concisely summarize the purpose of the class or method it is describing. It should explain any parameters whose usage is not immediately obvious, and is also a good place to include short examples of how to use the API. Any caveats or problems an unsuspecting user of the API should be aware of should also be noted. To illustrate the use of docstrings, we will end this part with our completely documented Point class: import math class Point: 'Represents a point in two-dimensional geometric coordinates' def __init__(self, x=0, y=0): '''Initialize the position of a new point. The x and y coordinates can be specified. If they are not, the point defaults to the origin.''' self.move(x, y) def move(self, x, y): "Move the point to a new location in two-dimensional space." self.x = x self.y = y def reset(self): 'Reset the point back to the geometric origin: 0, 0' self.move(0, 0) def calculate_distance(self, other_point): """Calculate the distance from this point to a second point passed as a parameter. This function uses the Pythagorean Theorem to calculate the distance between the two points. The distance is returned as a float.""" return math.sqrt( (self.x - other_point.x)**2 + (self.y – other_point.y)**2) Try typing or loading (remember, it's python -i filename.py) this file into the interactive interpreter. Then enter help(Point)<enter> at the Python prompt. You should see nicely formatted documentation for the class, as shown in the following screenshot:
Read more
  • 0
  • 0
  • 8592
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 €18.99/month. Cancel anytime
article-image-adding-animations
Packt
19 Mar 2014
10 min read
Save for later

Adding Animations

Packt
19 Mar 2014
10 min read
(For more resources related to this topic, see here.) Exploring 3D hierarchies The ability to parent objects among one another is a versatile feature in Unity3D. So far, in this article, we have seen how hierarchies can be used as a means of associating objects with one another and organizing them into hierarchies. One example of this is the character Prefabs with their child hats we developed for the player Prefab and the racers. In this example, by dragging-and-dropping the hat object onto the player's body, we associated the hat with the object body by putting the child into the parent's coordinate system. After doing this, we saw that the rotations, translations, and scales of the body's transform component were propagated to the hat. In practice, this is how we attach objects to one another in 3D games, that is, by parenting them to different parents and thereby changing their coordinate systems or frames of reference. Another example of using hierarchies as a data structure was for collections. Examples of this are the splineData collections we developed for the NPCs. These objects had a single game object at the head and a collection of data as child objects. We could then perform operations on the head, which lets us process all of the child objects in the collection (in our case, installing the way points). A third use of hierarchies was for animation. Since rotations, translations, and scales that are applied to a parent transform are propagated to all of the children, we have a way of developing fine-tuned motion for a hierarchy of objects. It turns out that characters in games and animated objects alike use this hierarchy of transforms technique to implement their motion. Skinned meshes in Unity3D A skinned mesh is a set of polygons whose positions and rotations are computed based on the positions of the various transforms in a hierarchy. Instead of each GameObject in the hierarchy have its own mesh, a single set of polygons is shared across a number of transforms. This results in a single mesh that we call a skin because it envelops the transforms in a skin-like structure. It turns out that this type of mesh is great for in-game characters because it moves like skin. We will now use www.mixamo.com to download some free models and animations for our game. Acquiring and importing models Let's download a character model for the hero of our game. Open your favorite Internet browser and go to www.mixamo.com. Click on Characters and scroll through the list of skinned models. From the models that are listed free, choose the one that you want to use. At the time of writing this article, we chose Justin from the free models available, as shown in the following screenshot: Click on Justin and you will be presented with a preview window of the character on the next page. Click on Download to prepare the model for download. Note, you may have to sign up for an account on the website to continue. Once you have clicked on Download, the small downloads pop-up window at the bottom-right corner of the screen will contain your model. Open the tab and select the model. Make sure to set the download format to FBX for Unity (.fbx) and then click on Download again. FBX (Filmbox)—originally created by a company of the same name and now owned by AutoDesk—is an industry standard format for models and animations. Congratulations! You have downloaded the model we will use for the main player character. While this model will be downloaded and saved to the Downloads folder of your browser, go back to the character select page and choose two more models to use for other NPCs in the game. At the time of writing this article, we chose Alexis and Zombie from the selection of free models, as shown in the following screenshot: Go to Unity, create a folder in your Project tab named Chapter8, and inside this folder, create a folder named models. Right-click on this folder and select Open In Explorer. Once you have the folder opened, drag-and-drop the two character models from your Download folder into the models folder. This will trigger the process of importing a model into Unity, and you should then see your models in your Project view as shown in the following screenshot: Click on each model in the models folder, and note that the Preview tab shows a t-pose of the model as well as some import options. In the Inspector pane, under the Rig tab, ensure that Animation Type is set to Humanoid instead of Generic. The various rig options tell Unity how to animate the skinned mesh on the model. While Generic would work, choosing Humanoid will give us more options when animating under Mechanim. Let Unity create the avatar definition file for you and you can simply click on Apply to change the Rig settings, as shown in the following screenshot: We can now drag-and-drop your characters to the game from the Project tab into the Scene view of the level, as shown in the following screenshot: Congratulations! You have successfully downloaded, imported, and instantiated skinned mesh models. Now, let's learn how to animate them, and we will do this starting with the main player's character. Exploring the Mechanim animation system The Mechanim animation system allows the Unity3D user to integrate animations into complex state machines in an intuitive and visual way! It also has advanced features that allow the user to fine-tune the motion of their characters, right from the use of blend trees to mix, combine, and switch between animations as well as Inverse Kinematics (IK) to adjust the hands and feet of the character after animating. To develop an FSM for our main player, we need to consider the gameplay, moves, and features that the player represents in the game. Choosing appropriate animations In level one, our character needs to be able to walk around the world collecting flags and returning them to the flag monument. Let's go back to www.mixamo.com, click on Animations, and download the free Idle, Gangnam Style, and Zombie Running animations, as shown in the following screenshot: Building a simple character animation FSM Let's build an FSM that the main character will use. To start, let's develop the locomotion system. Import the downloaded animations to a new folder named anims, in Chapter8. If you downloaded the animations attached to a skin, don't worry. We can remove it from the model, when it is imported, and apply it to the animation FSM that you will build. Open the scene file from the first gameplay level TESTBED1. Drag-and-drop the Justin model from the Projects tab into the Scene view and rename it Justin. Click on Justin and add an Animator component. This is the component that drives a character with the Mechanim system. Once you have added this component, you will be able to animate the character with the Mechanim system. Create a new animator controller and call it JustinController. Drag-and-drop JustinController into the controller reference on the Animator component of the Justin instance. The animator controller is the file that will store the specific Mechanim FSM that the Animator component will use to drive the character. Think of it as a container for the FSM. Click on the Justin@t-pose model from the Project tab, and drag-and-drop the avatar definition file from Model to the Avatar reference on the Animator component on the Justin instance. Go to the Window drop-down menu and select Animator. You will see a new tab open up beside the Scene view. With your Justin model selected, you should see an empty Animator panel inside the tab, as shown in the following screenshot: Right now our Justin model has no animations in his FSM. Let's add the idle animation (named Idle_1) from the Adam model we downloaded. You can drag-and-drop it from the Project view to any location inside this panel. That's all there is to it! Now, we have a single anim FSM attached to our character. When you play the game now, it should show Justin playing the Idle animation. You may notice that the loop doesn't repeat or cycle repeatedly. To fix this, you need to duplicate the animation and then select the Loop Pose checkbox. Highlight the animation child object idle_1 and press the Ctrl + D shortcut to duplicate it. The duplicate will appear outside of the hierarchy. You can then rename it to a name of your choice. Let's choose Idle as shown in the following screenshot: Now, click on Idle, and in the Inspector window, make sure that Loop Pose is selected. Congratulations! Using this Idle animation now results in a character who idles in a loop. Let's take a look at adding the walk animation. Click on the Zombie Running animation, which is a child asset of the Zombie model, and duplicate it such that a new copy appears in the Project window. Rename this copy Run. Click on this animation and make sure to check the Loop Pose checkbox so that the animation runs in cycles. Drag-and-drop the Run animation into the Animator tab. You should now have two animations in your FSM, with the default animation still as Idle; if you run the game, Justin should still just be idle. To make him switch animations, we need to do the following: Add some transitions to the Run animation from the Idle animation and vice versa. Trigger the transitions from a script. You will want to switch from the Idle to the Run animation when the player's speed (as determined from the script) is greater than a small number (let's say 0.1 f). Since the variable for speed only lives in the script, we will need a way for the script to communicate with the animation, and we will do this with parameters. In your Animator tab, note that the FSM we are developing lives in the Base Layer screen. While it is possible to add multiple animation layers by clicking on the + sign under Base Layer, this would allow the programmer to design multiple concurrent animation FSMs that could be used to develop varying degrees/levels of complex animation. Add a new parameter by clicking on the + sign beside the Parameters panel. Select float from the list of datatypes. You should now see a new parameter. Name this speed as shown in the following screenshot: Right-click on the Idle Animation and select Make Transition. You will now see that a white arrow is visible, which extends from Idle, that tracks the position of your mouse pointer. If you now click on the Run animation, the transition from Idle to Run will lock into place. Left-click on the little white triangle of the transition and observe the inspector for the transition itself. Scroll down in the Inspector window to the very bottom and set the condition for the transition to speed greater than 0.1, as shown in the following screenshot: Make the transition from the Run animation cycle back to the Idle cycle by following the same procedure. Right-click on the Run animation to start the transition. Then, left-click on Idle. After this, left-click on the transition once it is locked into place. Then, when the transition is activated in Conditions, set its speed to less than 0.09. Congratulations! Our character will now transition from Idle to Run when the speed crosses the 0.1 threshold. The transition is a nice blend from the first animation to the second over a brief period of time, and this is indicated in the transition graph.
Read more
  • 0
  • 0
  • 8591

Packt
23 Sep 2010
4 min read
Save for later

iNotes and Sametime—Chatting from the Web

Packt
23 Sep 2010
4 min read
  IBM Lotus Sametime 8 Essentials: A User's Guide Mastering Online Enterprise Communication with this collaborative software Collaborate securely with your colleagues and teammates both inside and outside your organization by using Sametime features such as instant messaging and online meetings Make your instant messaging communication more interesting with the inclusion of graphics, images, and emoticons to convey more information in fewer words Communicate with other instant messaging services and users, such as AOL Instant Messaging, Yahoo Instant Messaging, and Google Talk and know how someone's online status can help you communicate faster and more efficiently Discover how the Sametime Meeting Center can maximize the productivity of teams in your organization with the use of online meetings, training session playback, seamless voice/video integration, and screen sharing See how Sametime works in common, every-day, real-world situations with tips, resources, and detailed screenshots Read more about this book (For more resources on Microsoft see here.) Using Sametime in iNotes Let’s talk a little bit about iNotes. iNotes is the Lotus Notes web client. It works with browsers like Microsoft Internet Explorer, Mozilla Firefox, and Apple Safari. To get started using iNotes, you will need to login using a user ID and password that your e-mail administrator has given you. Your company or organization may have a central website for you to use to login, like webmail.companyname.com, so that the login URL is easy to remember. Some possible uses for iNotes and Sametime include: Beza uses a netbook and doesn’t want to install either the Notes client or Sametime Connect client. Sametime in iNotes allows him to contact his friends and colleagues. Maja primarily works from a kiosk. She can use iNotes and Sametime to access her e-mail and her company’s directory. Tatiana is traveling without her laptop. She’d like to connect with her team members. She’s stopped at an internet café where she’s able to login to iNotes and Sametime. When you first login to iNotes you might see your inbox displayed. iNotes has several modes: Full Mode, Lite Mode, and Ultralite Mode. Each of these modes has specific features. We’re going to focus on Full Mode as that is the version that allows you to login to Sametime.   If you’re used to using Notes as your e-mail client, you’ll notice a very strong similarity to the Notes 8.x mail client, so you should already be pretty comfortable with the display on the screen. Enable instant messaging Because you are using Sametime in a web browser, there are far fewer preferences that are available to you. This is because in a web browser, you don’t have the ability to control a rich Sametime client as you do when you’re running within the Sametime Connect client. The web browser version of Sametime is meant to deliver a basic set of functionality that works regardless of what type of computer you’re using. The first thing you need to make sure of is that Sametime is enabled to run within iNotes. You do this by launching the iNotes preferences in the upper-right corner of your browser window: When you click on the Preferences option, you’ll see a list of iNotes preferences, one of which allows you to enable Instant Messaging. After you select the Enable Instant messaging option, click on Save and Close. This saves the preference in your iNotes profile. At this point your screen will refresh and you’ll notice a new twisty icon just below the toolbar above your name in the Inbox. In order to get Sametime started, click on the twisty icon and highlight the option to Log On To Instant Messaging. Once you’re logged in you’ll notice your awareness changes to Available. If you have never launched Sametime in iNotes before, the browser has to load a Java application called STLinksApp to allow Sametime to work properly. You’ll see the following warning box, and you click on Run to let the browser load the application and launch Sametime. Be sure to select Always trust content from this publisher and Run. The wording for these options may vary slightly with the browser you are using. It is very important that you select this application to run. Some of the functionality we describe later may not work if it has not been installed. Check with your systems staff regarding your default browser settings and whether or not you have the system authority to run these types of Java applets.
Read more
  • 0
  • 0
  • 8576

article-image-pop-image-widget-using-javascript-php-and-css
Packt
22 Oct 2009
7 min read
Save for later

Pop-up Image Widget using JavaScript, PHP and CSS

Packt
22 Oct 2009
7 min read
If you’re a regular blog reader then it’s likely that you’ve encountered the Recent Visitors widget form (http://mybloglog.com). This widget displays the profile like name, picture and sites authored by members of Mybloglog who have recently visited your blog. In the Mybloglog widget, when you move the mouse cursor to the member’s picture, you’ll see a popup displaying a brief description of that member. A glance at MyBlogLog widget The above image is of a MyBlogLog widget. As you can see in the right part of the widget, there is a list of the recent visitors to the blog from members of MyBlogLog. You may also have noticed that in the left part of the widget is a popup showing the details and an image of the visitor. This popup is displayed when the mouse is moved over the image on the widget. Now, let’s look at the code which we got from MyBlogLog to display the above widget. <script src="http://pub.mybloglog.com/comm3.php?mblID=2007121300465126&r= widget&is=small&o=l&ro=5&cs=black&ww=220&wc=multiple"></script> In the above script element, the language and type attributes are not specified. Although they are optional attributes in HTML - you must specify a value in the type attribute to make the above syntax valid in an XHTML web page. If you closely looked at the src attribute of the script element, you can see that the source page of the script is a .php file. You can use the JavaScript code with any file extension like .php , .asp, and so on , but whenever you use such a file in src attribute please note that the final output code of the file (after being parsed by server) should be a valid JavaScript code. Creating pop-up image widget This pop-up image widget is somewhat similar to MyBlogLog widget but it is a simplified version of that widget. This is a very simple widget with uses JavaScript, PHP and CSS. Here you’ll see four images in the widget and a pop-up image (corresponding to the chosen image) will be displayed when you move the mouse over it. After getting the core concept, you can extend the functionality to make this look fancier. Writing Code for Pop-up Image Widget As I’ve already discussed, this widget is going to contain PHP code, JavaScript and a little bit of CSS as well. For this, you need to write the code in a PHP file with the .php extension. First of all, declare the variables for storing the current mouse position and string variables for storing the string of the widget. var widget_posx=0;var widget_posy=0;var widget_html_css=''; The widget_posx variable is to hold the x co-ordinate values of the mouse position on the screen, whereas, the widget_posy variable will store the y co-ordinate. The widget_html_css variable stores the HTML and CSS elements which will be used later in the code. The (0,0) co-ordinate of the output devices like monitor is located at the top left position. So the mouse position 10,10 will be somewhere near the top left corner of monitor. After declaring the variables, let’s define an event handler to track the mouse position on the web page. document.onmousemove=captureMouse; As you can see above, we’ve called a function captureMouse() When the mouse is moved anywhere on the document (web page), the event handler which is the function captureMouse() is called on the onmousemove event. The Document object represents the entire HTML document and can be used to access and capture the events of all elements on a page. Each time a user moves the mouse one pixel, a mousemove event occurs. It engages system resources to process all mousemove events, hence, use this event carefully! Now, let’s look at the code of the captureMouse() function. function captureMouse(event){ if (!event){var event = window.event;}if (event.pageX || event.pageY) { widget_posx = event.pageX; widget_posy = event.pageY; } else if (event.clientX || event.clientY) { widget_posx = event.clientX; widget_posy = event.clientY; } } As you can see in the above function, the event variable is passed as a function parameter. This event variable is the JavaScript’s Event object. The Event object keeps track of various events that occur on the page, such as the user moving the mouse or clicking on the link, and allows you to react to them by writing code which is relevant to the event. if (!event){var event = window.event;} In the above code, the first line of the event handler ensures that if the browser doesn’t pass the event information to the above function, then we would obtain it from any explicit event registration of the window object. We can track different activity in the document by the event object with the help of its various defined properties. For example, if eventObj is the event object and we’ve to track whether the ctrl key is pressed (or not) - we can use the following code in JavaScript: eventObj.ctrlKey If we’ve assigned the x, y-position of mouse in the page using the pageX and pageY properties, we can also get the same mouse position of the mouse cursor using clientX and clientY property. Most browsers provide both pageX/pageY and clientX/clientY. Internet Explorer is the only current browser that provides clientX/clientY, but not pageX/pageY. To provide cross-browser support, we’ve used both pageX/pageY and clientX/clientY to get the mouse co-ordinates in the document, and assigned them to the widget_posx and widget_posy variables accordingly. Now, let’s look at widget_html_css variable, where we’re going to store the string which is going to be displayed in the widget. widget_html_css+='<style type="text/css">';widget_html_css+='.widgetImageCss';widget_html_css+='{ margin:2px;border:1px solid #CCCCCC;cursor:pointer}';widget_html_css+='</style>'; As you can see in the string of the above variable, we’ve added the style for the HTML element with the class name widgetImageCss within the style element. When applied, this class in the HTML adds a 2 pixel margins ‘brown color border’ to the element. Furthermore, the mouse cursor will be converted into pointer (a hand) which is defined with the cursor attribute in CSS. widget_html_css+='<div id="widget_popup"style="position:absolute;z-index:10; display:none">&nbsp;</div>'; Using the above code, we’re adding a division element with id widget_popup to the DOM. We’ve also added style to this element using inline styling. The position attribute of this element is set to absolute so that this element can move freely without disturbing the layout of the document. The z-index property is used for stacking the order of the element and in the above element it is set 10 so that this element will be displayed above all the other elements of the document. Finally, the display property is set to none for hiding the element at first. Afterwards, this element will be displayed with the pop-up image using JavaScript in the document. Elements can have negative stack orders i.e. you can set the z-index to -1 for an element. This will display it underneath the other elements on the page. Z-index only works on elements that have been positioned using CSS (such as position:absolute). Now, the PHP part of the codes comes in. We’ve used PHP to add the images to the widget_html_css string variables of JavaScript. We’ve used PHP in this part rather than using JavaScript for making this application flexible. JavaScript is a client side scripting language and can’t access the database or do any kind of server activity. Using PHP, you can extract and display the images from the database which might be the integral part of your desired widget.
Read more
  • 0
  • 0
  • 8547

article-image-understanding-big-picture
Packt
04 Sep 2013
7 min read
Save for later

Understanding the big picture

Packt
04 Sep 2013
7 min read
(For more resources related to this topic, see here.) So we've got this thing for authentication and authorization. Let's see who is responsible and what for. There is an AccessDecisionManager, which, as the name suggests, is responsible for deciding whether we can access something or not; if not, an AccessDeniedException or InsufficientAuthenticationException is thrown. AuthenticationManager is another crucial interface. It is responsible for confirming who we are. Both are just interfaces, so we can swap our own implementations if we like. In a web application, the job of talking with these two components and the user is handled by a web filter called DelegatingFilterProxy, which is decomposed into several small filters. Each one is responsible for a different thing, so we can turn them on, off, or put our own filters in between and mess with them anyway we like. These are quite important, and we will dig into them later. For the big picture, all we need to know is that these filters take care of all the talking, redirect the user to the login page (or an access-denied page), and save the current user details in an HTTPSession. Well, the last part, while true, is a bit misleading. User details are kept in a SecurityContext object, which we can get a hold of by calling SecurityContextHolder.getContext(), and which in the end is stored in HTTPSession by our filters. But we had promised a big picture, not the gory details, so here it is: Quite simple, right? If we have an authentication protocol without login and password, it works in a similar way. We just switch one of the filters, or the authentication manager, to a different implementation. If we don't have a web application, we just need to do the talking ourselves. But this is all for web resources (URLs). What is much more interesting and useful is securing calls to methods. It looks, for example, like this: @PreAuthorize(["isAuthenticated() and hasRole('ROLE_ADMIN')"])public void somethingOnlyAdminCanDo() {} Here, we decided that somethingOnlyAdminCanDo will be protected by our AccessDecisionManager and that the user must be authenticated (not anonymous) and has to have an admin role. Can a user be anonymous and have an admin role at the same time? In theory, yes, but it would not make any sense. Because it's much cheaper to check if he is authenticated and stop right there. We see a bit of optimization in here. We could drop the isAuthenticated() method and the behavior wouldn't change. We can put this kind of annotation on any Java method, but our configuration and mechanism to fire up the security will depend on the type of objects we are trying to protect. For objects declared as Spring beans (which is a short name for anything defined in our Inversion of Control (IoC) configuration, either via XML or annotations), we don't need to do much. Spring will just create proxies (dynamic classes) that take over calls to our secured methods and fire up AccessDecisionManager before passing the call to the object we really wanted to call. For objects outside of the IoC container (anything created with new or just code not defined in Spring context), we can use the power of Aspect Oriented Programming (AOP) to get the same effect. If you don't know what AOP is, don't worry. It's just a bit of magic at the classloader and bytecode level. For now, the only important thing is that it works basically in the same way. This is depicted as follows: We can do much more than this, as we'll see next, but these are the basics. So, how does the AccessDecisionManager decide whether we can access something or not? Imagine a council of very old Jedi masters sitting around a fire. They decide whether or not you are permitted to call a secured method or access a web resource. Each of these masters makes a decision or abstains. Each of them can consult additional information (not only who you are and what you want to do, but every aspect of the situation). In Spring Security, those smart people are called AccessDecisionVoters, and each of them has one vote. The council can be organized in many different ways. It has one voice, and so it may make the decision based on a majority of votes. It may be veto-based, where everything is allowed unless someone disagrees. Or it may need everyone to agree to grant access, otherwise access is denied. The council is the AccessDecisionManager, and we have three implementations previously mentioned out of the box. We can also decide who's in the council and who is not. This is probably the most important decision we can make, because this will decide the security model that we will use in our application. Let's talk about the most popular counselors (implementations of AccessDecisionVoter). Model based on roles (RoleVoter): This guy makes his decision based on the role of the user and the required role for the resource/method. So if we write @PreAuthorize("hasRole('ROLE_ADMIN')"), you better be a damn admin or you'll get a no-no from this guy. Model based on entity access control permissions (AclEntryVoter): This guy doesn't worry about roles. He is much more than that. Acl stands for Access Control List, which represents a list of permissions. Every user has a list of permissions, possibly for every domain object (usually an object in the database), that you want to secure. So, for example, if we have a bank application, the supervisor can give Frank access to a single specific customer (say, ACME—A Company that Makes Everything), which is represented as an entity in the database and as an object in our system. No other employee will be able to do anything to that customer unless the supervisor grants that person the same permission as Frank. This is probably the most scrutinous voter we would ever use. Our customer can have a very detailed configuration with him/her. On the other hand, this is also the most cumbersome, as we need to create a usable graphical interface to set permissions for every user and every domain object. While we have done this a few times, most of our customers wanted a simpler approach, and even those who started with a graphical user interface to configure everything asked for a simplified version based on business rules, at the end of the project. If your customer describes his security needs in terms of rules such as "Frank can edit every customer he has created but he cannot do anything other than view other customers", it means it's time for PreInvocationAuthorizationAdviceVoter. Business rules model (PreInvocationAuthorizationAdviceVoter): This is usually used when you want to implement static business rules in the application. This goes like "if I've written a blog post, I can change it later, but others can only comment" and "if a friend asked me to help him write the blog post, I can do that, because I'm his friend". Most of these things are also possible to implement with ACLs, but would be very cumbersome. This is our favorite voter. With it, it's very easy to write, test, and change the security restrictions, because instead of writing every possible relation in the database (as with ACL voter) or having only dumb roles, we write our security logic in plain old Java classes. Great stuff and most useful, once you see how it works. Did we mention that this is a council? Yes we did. The result of this is that we can mix any voters we want and choose any council organization we like. We can have all three voters previously mentioned and allow access if any of them says "yes". There are even more voters. And we can write new ones ourselves. Do you feel the power of the Jedi council already? Do you feel the power of the Jedi council already? Summary This section provides an overview of authentication and authorization, which are the principles of Spring security. Resources for Article : Further resources on this subject: Migration to Spring Security 3 [Article] Getting Started with Spring Security [Article] So, what is Spring for Android? [Article]
Read more
  • 0
  • 0
  • 8546
Packt
12 Jun 2013
8 min read
Save for later

A quick start – OpenCV fundamentals

Packt
12 Jun 2013
8 min read
(For more resources related to this topic, see here.) The OpenCV library has a modular structure, and the following diagram depicts the different modules available in it: A brief description of all the modules is as follows: Module Feature Core A compact module defining basic data structures, including the dense multidimensional array Mat and basic functions used by all other modules. Imgproc An image processing module that includes linear and non-linear image filtering, geometrical image transformations (resize, affine and perspective warping, generic table-based remapping), color space conversion, histograms, and so on. Video A video analysis module that includes motion estimation, background subtraction, and object tracking algorithms. Calib3d Basic multiple-view geometry algorithms, single and stereo camera calibration, object pose estimation, stereo correspondence algorithms, and elements of 3D reconstruction. Features2d Salient feature detectors, descriptors, and descriptor matchers. Objdetect Detection of objects and instances of the predefined classes; for example, faces, eyes, mugs, people, cars, and so on. Highgui An easy-to-use interface to video capturing, image and video codecs, as well as simple UI capabilities. Gpu GPU-accelerated algorithms from different OpenCV modules. Task 1 – image basics When trying to recreate the physical world around us in digital format via a camera, for example, the computer just sees the image in the form of a code that just contains the numbers 1 and 0. A digital image is nothing but a collection of pixels (picture elements) which are then stored in matrices in OpenCV for further manipulation. In the matrices, each element contains information about a particular pixel in the image. The pixel value decides how bright or what color that pixel should be. Based on this, we can classify images as: Greyscale Color/RGB Greyscale Here the pixel value can range from 0 to 255 and hence we can see the various shades of gray as shown in the following diagram. Here, 0 represents black and 255 represents white: A special case of grayscale is the binary image or black and white image. Here every pixel is either black or white, as shown in the following diagram: Color/RGB Red, Blue, and Green are the primary colors and upon mixing them in various different proportions, we can get new colors. A pixel in a color image has three separate channels— one each for Red, Blue, and Green. The value ranges from 0 to 255 for each channel, as shown in the following diagram: Task 2 – reading and displaying an image We are now going to write a very simple and basic program using the OpenCV library to read and display an image. This will help you understand the basics. Code A simple program to read and display an image is as follows: // opencv header files #include "opencv2/highgui/highgui.hpp" #include "opencv2/core/core.hpp" // namespaces declaration using namespace cv; using namespace std; // create a variable to store the image Mat image; int main( int argc, char** argv ) { // open the image and store it in the 'image' variable // Replace the path with where you have downloaded the image image=imread("<path to image">/lena.jpg"); // create a window to display the image namedWindow( "Display window", CV_WINDOW_AUTOSIZE ); // display the image in the window created imshow( "Display window", image ); // wait for a keystroke waitKey(0); return 0; } Code explanation Now let us understand how the code works. Short comments have also been included in the code itself to increase the readability. #include "opencv2/highgui/highgui.hpp" #include "opencv2/core/core.hpp" The preceding two header files will be a part of almost every program we write using the OpenCV library. As explained earlier, the highgui header is used for window creation, management, and so on, while the core header is used to access the Mat data structure in OpenCV. using namespace cv; using namespace std; The preceding two lines declare the required namespaces for this code so that we don't have to use the :: (scope resolution) operator every time for accessing the functions. Mat image; With the above command, we have just created a variable image of the datatype Mat that is frequently used in OpenCV to store images. image=imread("<path to image">/lena.jpg"); In the previous command, we opened the image lena.jpg and stored it in the image variable. Replace <path to image> in the preceding command with the location of that picture on your PC. namedWindow( "Display window", CV_WINDOW_AUTOSIZE ); We now need a window to display our image. So, we use the above function to do the same. This function takes two parameters, out of which the first one is the name of the window. In our case, we would like to name our window Display Window. The second parameter is optional, but it resizes the window based on the size of the image so that the image is not cropped. imshow( "Display window", image ); Finally, we are ready to display our image in the window we just created by using the preceding function. This function takes two parameters out of which the first one is the window name in which the image has to be displayed. In our case, obviously, that will be Display Window . The second parameter is the image variable containing the image that we want to display. In our case, it's the image variable. waitKey(0); Last but not least, it is advised that you use the preceding function in most of the codes that you write using the OpenCV library. If we don't write this code, the image will be displayed for a fraction of a second and the program will be immediately terminated. It happens so fast that you will not be able to see the image. What this function does essentially is that it waits for a keystroke from the user and hence it delays the termination of the program. The delay here is in milliseconds. Output The image can be displayed as follows: Task 3 – resizing and saving an image We are now going to write a very simple and basic program using the OpenCV library to resize and save an image. Code The following code helps you to resize a given image: // opencv header files #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/core/core.hpp" // namespaces declaration using namespace std; using namespace cv; int main(int argc, char** argv) { // create variables to store the images Mat org, resized,saved; // open the image and store it in the 'org' variable // Replace the path with where you have downloaded the image org=imread("<path to image>/lena.png"); //Create a window to display the image namedWindow("Original Image",CV_WINDOW_AUTOSIZE); //display the image imshow("Original Image",org); //resize the image resize(org,resized,Size(),0.5,0.5,INTER_LINEAR); namedWindow("Resized Image",CV_WINDOW_AUTOSIZE); imshow("Resized Image",resized); //save the image //Replace <path> with your desired location imwrite("<path>/saved.png",resized; namedWindow("Image saved",CV_WINDOW_AUTOSIZE); saved=imread("<path to image>/saved.png"); imshow("Image saved",saved); //wait for a keystroke waitKey(0); return 0; } Code explanation Only the new functions/concepts will be explained in this case. #include "opencv2/imgproc/imgproc.hpp" Imgproc is another useful header that gives us access to the various transformations, color conversions, filters, histograms, and so on. Mat org, resized; We have now created two variables, org and resized, to store the original and resized images respectively. resize(org,resized,Size(),0.5,0.5,INTER_LINEAR); We have used the preceding function to resize the image. The preceding function takes six parameters, out of which the first one is the variable containing the source image to be modified. The second one is the variable to store the resized image. The third parameter is the output image size. In this case we have not specified this, but we have instead used the Size() function, which will automatically calculate it based on the values of the fourth and fifth parameters. The fourth and fifth parameters are the scale factors along the horizontal and vertical axes respectively. The sixth parameter is for choosing the type of interpolation method. We have used the bilinear interpolation, which is the default method. imwrite("<path>/saved.png",final); Finally, using the preceding function, you can save an image to a particular location on our PC. The function takes two parameters, out of which the first one is the location where you want to store the image and the second is the variable in which the image is stored. This function is very useful when you want to perform multiple operations on an image and save the image on your PC for future reference. Replace <path> in the preceding function with your desired location. Output Resizing can be demonstrated through the following output: Summary This section showed you how to perform a few of the basic tasks in OpenCV as well as how to write your first OpenCV program. Resources for Article : Further resources on this subject: OpenCV: Segmenting Images [Article] Tracking Faces with Haar Cascades [Article] OpenCV: Image Processing using Morphological Filters [Article]
Read more
  • 0
  • 0
  • 8544

article-image-configuration-and-handy-tweaks-udk
Packt
01 Mar 2012
18 min read
Save for later

Configuration and Handy Tweaks for UDK

Packt
01 Mar 2012
18 min read
(For more resources on UDK, see here.) Groundwork for adjusting configuration defaults In this article we'll build up from simply changing some trivial configuration settings to orchestrating unique gaming experiences. To start out, we need to make clear how UDK configures content under the hood by introducing the layout and formatting for this kind of file. The experience in this recipe can be likened to savoring morsels of cake samples in a shop before committing to a purchase; while you're not actually changing major settings yet, the aim is to make some tasty observations so later the changes you make will come from informed decisions. Getting ready In your UDK installation, you have a folder called C:UDK~UDKGameConfig and it is worthwhile to browse the files here and get to know them. Treat them like the faces of colleagues in a new company. It may take a while, but you'll eventually know all their names! You may want to make an alternative install of UDK before starting this article, to protect any content you've been working on. In these examples we're going to assume you are using ConTEXT, or a notepad alternative that highlights UnrealScript syntax, like those listed at http://wiki.beyondunreal.com/Legacy:Text_Editor. The advantage with ConTEXT is that you have a history of recently opened files, and several concurrently open files can be arranged in tabs; also, you can view specific lines in the file in response to line error warnings from the UDK log, should they arise. In ConTEXT, to display line numbers go to the Options | Environment Options menu then click on the Editor tab in the options dialog, tick on Line Numbers and press Apply. How to do it... Open the file C:UDK~UDKGameConfigDefaultCharInfo.INI using ConTEXT. Alongside it, open C:UDK~UDKGameConfigUDKCharInfo.INI, which is a rather similar file. Values we set from an existing class are presented after a reference to the class in square brackets which surround the folder and class name, such as [UTGame.UTCharInfo]. Commented out lines or notes are distinguished using ; and the entire line isn't parsed. This differs from the // used to comment out lines in UnrealScript. In some configuration files you will see BasedOn=... followed by the path to another configuration file. This helps you track where the info is coming from. Values for variables are set in the configuration file as in the example: LOD1DisplayFactor=0.4. In ConTEXT , click on File | Open... and scroll down the list of files. Notice that it previews the contents of the highlighted .INI files before you open them. Choose DefaultWeapon.INI and edit line 3 (strictly speaking line 1 is empty). Press Ctrl + G (or View | Go to Line) and enter the line number 3. This line specifies CrosshairColor for the weapon. If you change the value A=255 to A=0 you will effectively have hidden the weapon target. Supposing you wanted to do so, you'd just have to save this file then reload UDK. No compiling is needed for adjusting configuration files, unlike classes, unless the configuration is defining custom scripts to be used in some way. Let's assume for now that you don't want to hide the weapon cursor, so close the file without saving by pressing Ctrl + W and choose No for the file save option. Open the file UDKEditor.INI and go to line 12: Bindings=(Key="S",SeqObjClassName="Engine.SeqAct_PlaySound") then look at line 28: Bindings=(Key="S",bControl=true,SeqObjClassName="Engine.SeqEvent_LevelLoaded"). What's important here is the added bControl=true for the S key. S will create a Play Sound node in Kismet. Ctrl + S will create a Level Loaded event. We really don't need to change anything but you can, for instance, change Ctrl + S to Ctrl + L in line 28, for adding a new Level Loaded event node in Kismet: Bindings=(Key="L",bControl=true,SeqObjClassName="Engine.SeqEvent_LevelLoaded") . Make sure that UDK is closed before you save the change or the file will not be effected at all. Reloading UDK after saving the change will see it take effect. Unless you have very long hands you will probably want to test this using the right Ctrl button on the right-hand side of the keyboard so your fingers can hold L and Ctrl and left mouse click all at once. You should get the Level Loaded event in Kismet from this key combination now. On that note, when you are specifying hotkeys for your game, bear in mind the idea of user friendly interface as you decide what keys to use. Often used keys should be easy to remember, fast to reach, and possibly semantically clustered together. How it works... What we looked at in this recipe were some formatting features that occur in every configuration file. In particular it is important to know that edits should be made while UDK is closed or they get scrubbed back out immediately. Also you will have noticed that the values we change reference UnrealScript classes from the C:UDK~DevelopmentSrc folder, and reading through their layout can help you learn how the default content in UDK is made to work during gameplay. There's more... Consider a version control software for editing UDK content There is a free version control system called Bazaar ( http://bazaar.canonical.com) that integrates with Windows folders. What version control software does is keep track of changes you have made to files, protecting them through a history based backup that lets you review and revert changes to a previous state if needed. You can init a folder, then browse it, add content and commit changes to changed files with comments that help you track what's going on. Where needed you can review the change history and revert files to any previously committed state. Alternatives to Bazaar are the commercial tool Alienbrain Essentials for Artists, or the free repository TortoiseSVN. The utility of version control in the case of UDK development is to prevent unrecoverable problems when doing a script compile when changes haven't been tracked and therefore can't be restored without re-installing from scratch, and to allow assets to be overwritten with a history. Enabling the remote control for game inspection This is a method for turning on an extra feature of UDK called the Remote Control that can be used to manipulate render nodes, inspect Actors, and evaluate performance. How to do it... In Windows, go to the Start menu or your desktop and find the shortcut for the UDK Editor and right-click on it to expose its properties. In the Target field edit it to read: C:UDK~BinariesUDKLift.exe editor -wxwindows -remotecontrol -log. The main point of this entry is so that we can launch a tool called RemoteControl. The usefulness of running the -log window increases over time. It is used for tracking what is happening while you run the editor and PIE. When trouble shooting problems in Kismet or with missing assets for example, it is a good first port of call for seeing where and when errors occur. In the following screenshot, the log shows the creation of a Trigger Touch event in the main Kismet sequence based on the actor Trigger_0 in the scene: Having edited the UDK launch properties to allow RemoteControl to launch, now load the Midday Lighting map template and PIE (F8). If you press Tab and type remotecontrol you should get a pop-up window like this: If you hit the Actors tab you get access to properties of certain actors, and you can change properties live while playing. For example, expand Actors | DominantDirectionalLight and double-click on DominantDirectionalLight_0 . Then in the light's property Movement | Rotation | Yaw or Pitch, try out different angle values. However, the changed values will revert to the editor state after PIE is closed. See also: http://udn.epicgames.com/Three/RemoteControl.html. An additional note: if you happen to minimize the RemoteControl window in some cases it may stay like that until you press Alt + Space . And to swap between the game and the Remote Control window press Alt + Tab . Pressing Show Flags lets you display various elements of the scene such as Collision, Bones, and Bounds. Go to the Stats tab and tick on Memory in the listing, then expand it and tick on the item within it called Lightmap Memory . This shows the cost of displaying lighting backed into lightmaps. Further down in the Stats tab list, tick on the item D3D9RHI and look at the DrawPrimitive calls. In the game, look straight up at the empty sky and note the value. Now look at the box on the ground. Notice the value increases. This is because the view has to draw the added objects (ground and box). In a large scene, especially on iOS, there is a functional limit to the number of drawcalls. How it works... The RemoteControl tool is external to the game window and is created using wxWindows. It is meant for use during PIE, for evaluation of performance. The Actors tab shows us a tree list of what is in the level, along with filters. You can access Actor Properties for an actor under the crosshairs using the icon [] or access them from a list. What you see in this screenshot is the result of turning the memory statistics on within a scene and the frame rate indicator (FPS = frames per second) through the Rendering tab in the Stats section, as well as the display of bones used in the scene. In Remote Control , you can set the Game Resolution (or game window size) under Rendering | View Settings. In the next recipe, we'll look at how to do this in UDK's configuration. Changing the Play in Editor view resolution This is a very short method for setting the view size for PIE sessions. How to do it... In C:UDK~UDKGameConfigDefaultEngineUDK.INI press Ctrl + F and search for [SystemSettings]. This should expose the lines: [SystemSettings] ; NOTE THAT ANY ITEMS IN THIS SECTION AFFECT ALL PLATFORMS! bEnableForegroundShadowsOnWorld=False bEnableForegroundSelfShadowing=False ResX=1024 ResY=768 Change the ResX and ResY values to suit yourself, using screen resolutions that make sense, such as 1920x1080. This will update UDKEngine.INI in the same folder so you will see the change reflected in these lines: PlayInEditorWidth=1920 PlayInEditorHeight=1080 Load a level and PIE to see the difference. Note that if you update UDKEngine.INI directly it will just revert to whatever is set in DefaultEngineUDK.INI. There is a lot of redundancy built into UDK's configuration that takes some time and practice to get used to. Removing the loading hints and similar articles Quickly getting rid of all the peripheral text and imagery that wraps around a given level, especially in console mode, is not easy. A few options exist for removing the more distracting elements such as splash screens and menus. You may want to do this if you wish to show your work without any artwork made by someone else getting in the way of your own. One method is called destructive editing, where your delete or blank out assets at the source, and this isn't as safe as it is quick. Instead you can provide your own menus, splash, and UI by extending on the classes that call up the default ones. How to do it... Removing the console mode videos during map loading Open C:UDK~UDKGameConfigDefaultEngine.INI. Press Ctrl + F and search for [FullScreenMovie] , which should expose the startup and loadmap references. Comment out the entries as follows: [FullScreenMovie] //+StartupMovies=UDKFrontEnd.UDK_loading //+LoadMapMovies=UDKFrontEnd.UDK_loading Load a level and play in console mode []. You won't get the movies that precede gameplay. If you take out all the pre-loading content there may occur the problem of getting a look at the level too early and "pre-caching" showing up. To learn how to instead swap out the .BIK files that constitute the loading movies between levels you can follow the video by Michael J Collins: http://www.youtube.com/watch?v=SX1VQK1w4NU. Removing the level loading hints To totally prevent .BIK movies during development, you can open C:UDK~EngineConfigBaseEngine.INI and search for NoMovies, then adjust the FALSE in the exposed lines: // Game Type name //class'Engine'.static.AddOverlay( LoadingScreenGameTypeNameFont, Desc, 0.1822, 0.435, 1.0, 1.0, false); // becomes class'Engine'.static.AddOverlay( LoadingScreenGameTypeNameFont, Desc, 0.1822, 0.435, 1.0, 0, false); // and Map name // class'Engine'.static.AddOverlay( LoadingScreenMapNameFont, MapName, 0.1822, 0.46, 2.0, 2.0, false); // becomes class'Engine'.static.AddOverlay( LoadingScreenMapNameFont, MapName, 0.1822, 0.46, 2.0, 0, false); What's happening here is that the last digit of four in an entry 1,1,1,1 is the Alpha value, controlling transparency, so 1,1,1,0 will be invisible. The first three numbers are RGB values, but they can be anything if the Alpha is 0. Removing the default exit menu Open C:UDK~UDKGameConfigDefaultInput.INI and press Ctrl + F to search for Escape. The first time will expose a removed key binding, so search from the cursor again to find in line 205: .Bindings=(Name="Escape",Command="GBA_ShowMenu" and comment it out with ; then add this line underneath instead: .Bindings=(Name="Escape",Command="quit" if UDK should close directly. If you want to provide a custom menu type: .Bindings=(Name="Escape",Command="open Menu" , where players pressing Esc will be sent to Menu.UDK (a scene of your own design) instead of the default menu. This won't do anything if you don't provision a Menu.UDK map first and cook it with your game levels. The map Menu.UDK would typically include some kind of clickable exit, resume, and reload buttons. If you want Esc to automatically restart the level you're playing, put in "open YOURMAPNAME" but bear in mind the only way to exit then will be Alt + F4. Possibly a strong way to approach the Escape option is to have a Pause command that permits a choice about leaving the game through a floating button: Resume or Exit. In addition you might have a similar floating button when the player dies: Replay or Exit, rather than the default Fire to Respawn. Editing DefaultEngineUDK to allow 4096x4096 texture compression This is a method for enabling UDK to use textures larger than its default limit. Conventional wisdom says that game textures should be highly optimized, but large resolution artwork is always enticing for many designers, and computers are getting better all the time. Performance issues aside, it's a good goal to push the graphic envelope and larger textures allow detail to hold up better on close inspection. Getting ready We've provided one really large texture that is 4096x4096 that you may find convenient, intended for use as a Skydome. If you are going to use a large texture it would most likely be on a very important model like a key character always close to the camera or else of a very large model which is always visible, such as a Skydome, or Skybox. A simple tutorial for making a Skybox is at http://www.worldofleveldesign.com/categories/UDK/UDK-how-add-skybox.php but this recipe assumes the use of a provided one. How to do it... With UDK closed, open C:UDK~UDKGameConfigDefaultEngineUDK.INI. Press Ctrl + F in ConTEXT and search for Skybox . You should be directed to line 127: TEXTUREGROUP_Skybox=(MinLODSize=512,MaxLODSize=2048,LODBias=0,MinMagFilter=aniso,MipFilter=point). Change the value for MaxLODSize=2048 to 4096. To really force it, you can also set the MinLODSize=4096 too. Doing this for a Skybox is okay, since there's normally only one used in a map, but you'd risk slowing the game down to do this with regular textures. Note, the TEXTUREGROUP_Skybox will allow a texture for a Skybox to be large, but not other things like character textures. For that, you can edit the relevant values in the other TEXTUREGROUP lines. Further down, in the SystemSettingsMobile section, the texture sizes are much smaller, which is due to the relatively limited processing power of mobile devices. Now save, and next we'll verify this in fact worked by adding a large sky to a scene in UDK. Look in the Content Browser and search the Packt folder for Packt_SkyDome , which is a typical mesh for a sky. You can see there is a completed version, and a copy called Packt_SkyDomeStart which has no material. Go to the Packt texture group. You will see there is already a provisioned 4096x4096 texture for Packt_SkyDome , but let's import a fresh one. Right-click in the Content Browser panel and choose Import , and browse to find Packt_SkydomeStart.PNG which is just a copy of the already existing texture. The reason to import it, is to verify you understand the compression setting. In the options you will see a panel that lets you specify the name info, which you should enter as Packt.Texture.SkyDomeTest or something unique. Further down you will see the compression settings. Choose LODGroup and from the expanding list choose TEXTUREGROUP_Skybox, as shown in the next screenshot, since this is what we have set to have 4096x4096 compression enabled in the configuration: The file may take some time to process, given its size. Once it is complete you can create a new Material Packt.Material.SkyDomeTest_mat. Open it and in the Material Editor hold T and click to add the highlighted SkyDomeTest texture to the Emissive channel. Skies are self lighting, so in the PreviewMaterial node's properties, set the Lighting Model to MLM_Unlit . The mesh Packt_SkyDomeStart is already UV mapped to match the texture, and if you double-click on it you can assign the new Material Packt.Material.SkyDomeTest_mat in the LODGroupInfo by expanding until you access the empty Material channel. Select the Material in the Content Browser then use the assign icon [] to assign it. Then you can save the package and place the mesh in the level. Be sure to access its properties (F4) and under the Lighting turn off Cast Shadow and set the Lighting Channels tick on Skybox and uncheck Static , as shown in the next screenshot: You could scale the mesh in the scene to suit, and perhaps drop it down below Z=0 a little. You could also use an Exponential Height Fog to hide the horizon. Since there is a specific sun shown in the sky image, you will need to place a Dominant Directional light in the scene and rotate it so its arrow (representing its direction) approximates the direction the sunlight would be coming from. It would be appropriate to tint the light warmly for a sunset. Setting the preview player size reference object In UDK versions greater than April 2011, pressing the key in the editor Perspective view will show a mesh that represents the player height. By default this is just a cube. The mesh to display can be set in the configuration file UDKEditorUserSettings.INI and we'll look at how to adjust this. This is to help designers maintain proper level metrics. You'll be able to gauge how tall and wide to make doors so there's sufficient space for the player to move through without getting stuck. Getting ready Back up C:UDK~UDKGameConfigUDKEditorUserSettings.INI then open it in ConTEXT with UDK closed. How to do it... Press Ctrl + F and search for [EditorPreviewMesh] . Under it, we will change the entry PreviewMeshNames=" EditorMeshes.TexPropCube ". Note the we need to replace this with a StaticMesh, and a good place to put this to ensure loading would be the EngineContent package EditorMeshes . First, open UDK and in the Content Browser search using the type field for TexPropCube . When this appears, right-click on the asset and choose Find Package . The packages list will show us EngineContentEditorMeshes and in here right-click and choose Import . You'll be prompted to browse in Windows, so from the provided content folder, find SkinTail.ASE which is a character model and import this into EditorMeshes. There's no need to set a group name for this. Importing this file as a StaticMesh enables it to be used as a preview model. By contrast, the SkeletalMesh Packt.Mesh.Packt_SkinTail won't work for what we are trying to do. If you set up a SkeletalMesh for the preview model the log will return cannot find staticmesh Yourmodelname whenever you press in the editor. It is optional, but you can double click the imported StaticMesh and assign a Material to it after expanding the LOD_Info property to show the Material channel. For the SkinTail content, choose Packt.Material.Packt_CharMat . Then save the EditorMeshes package including SkinTail and quit UDK. Use ConTEXT to edit the file UDKEditorUserSettings.INI so that the line we were looking at in Step 1 is changed to: PreviewMeshNames=" EditorMeshes.SkinTail " Eventually you'll opt to use your own StaticMesh. Save, close, and restart UDK. Open a map, and press in the editor to see if SkinTail will display. If it doesn't, run UDK using the -log option and check for error warnings when is pressed. Note that PreviewMeshNames=" EditorMeshes.TexPropCube " can also be adjusted in these configuration files: C:UDK~EngineConfigBaseEditorUserSettings.INI or C:UDK~UDKGameConfigDefaultEditorUserSettings.INI.
Read more
  • 0
  • 0
  • 8544

article-image-10-tips-make-great-visual-diagrams-omnigraffle-5
Packt
11 Nov 2010
10 min read
Save for later

10 Tips to make great visual diagrams with OmniGraffle 5

Packt
11 Nov 2010
10 min read
  OmniGraffle 5 Diagramming Essentials Create better diagrams with less effort using OmniGraffle Produce high-quality professional-looking diagrams that communicate information much better than words Makes diagramming fun and simple for Macintosh users Master the art of illustrating your ideas with OmniGraffle Learn to draw engaging charts and graphs to grasp your viewers' attention to your presentations A hands-on guide filled with visual step-by-step examples that cover both the basics and the advanced features of OmniGraffle         Diagramming is really communication. There is a substantial field of study out there, which only deals with the psychology of communication. It is outside the scope of this article to go into the theoretical background on the best way of visually presenting an idea (consider, as an example, some of the works of Edward Tufte). What you will learn in this section are a few handy tips that you may or may not follow. If you decide to follow these tips, your visual diagramming will not go wrong. However, do not follow these tips as "rules". Obey them if they make sense and disobey them when they get in your way. Most importantly, don't lose sight of, or forget what you want to communicate with your diagram. Tip 1: Do some planning before you start OmniGraffle may be the best diagramming tool on the Macintosh. Complex diagrams are still a lot of (hard) work to get right, even with the aid of a computer. OmniGraffle is still just a diagramming tool—it will not do your thinking processes for you. For small and simple diagrams where you have full knowledge of what you want to communicate, you can start working directly in OmniGraffle. However, for bigger and more complex diagrams, it may be easier to start your thought process using a white board, or some paper and a pencil. If you still insist on using a computer for organizing your thought processes, you should take a look at OmniOutliner from the same people that make OmniGraffle. The cool thing about using OmniOutliner is that you can import your outliner documents into OmniGraffle and then OmniGraffle will create a diagram for you. If outlining is too simple, and you are more used to mind mapping—there are some simple mind mapping stencils at Graffletopia. However, you may be better off using a specialty tool like MindManager from MindJet Corporation (http://www.mindjet.com/). A very good example of planning ahead is traffic signs. Designing traffic signs takes into account the driver's needs and requirements (that is, easy to understand pictograms going by in 120 km/h on the highway). These signs may seem simple to create – but a lot of work has been put into them to make them this simple. Even if you have not seen a given sign before, there is a good chance that you will understand it's meaning without further explanation. A good diagram should be like a well designed traffic sign. Tip 2: Colorize gently The old adage that "less is more" really applies to diagramming at large. Use light colors whenever possible when filling shapes. Try not to mix strong and light colors on the same diagram. If want to use text in colored shapes – take into account the contrast of the background color and the text. Light colors should have black text, and strong colors should have white text. Stick to either black or white text. Use as few colors as possible – never use yet-another-color just because you can. If you need ideas on which colors may match each other you should investigate the software tools found on the ColorJack website (http://www.colorjack.com/). The ColorSphere and the swatches are a good starting point. Another interesting website to get some ideas on good color combinations is the Kuler community. In this community users are both sharing their own color swatches, and can vote on the best-looking color swatches in the community. You find Kuler community at http://kuler.adobe.com/. If you need to use colored text on a colored background – and really care about the readability (contrast) of your message (which you should), then you should try the Colour Contrast Check tool from snook.ca —go to http://www.snook.ca/technical/colour_contrast/colour.html and experiment with foreground and background colors. Tip 3: Use few fonts The rule of thumb to use on any publication with regards to font use: Never use more than two fonts. Unless for the title of your diagram, avoid using serif fonts. Serif fonts have small details on the end of each stroke making up a letter. A very good example of a serif font is Times Roman. The text you are reading right now is set in a serif font. The various headings found throughout this book are without serifs. These fonts without serifs are also known as sans serif fonts. Good diagramming fonts are Helvetica, Futura, Optima, and Lucida Grande. All these fonts are sans serif fonts, and readily available from the Fonts stencil found in the Common stencil directory. This said, if your main document is not using any of these fonts—try to match your diagram fonts with your main document. Though one of the "rules of thumb" regarding fonts and types is not to use ALL CAPS, there may be times when it is appropriate for your diagram. The same also is true regarding starting a word with an upper case letter. It may look better to start a word using lower case. Tip 4: Consider your output media If your diagram is going to appear in a printed report, thin lines may be better than thicker lines. If your diagram is going to appear on a wall poster—thicker lines will probably be better than thinner lines as the reader is reading the poster from a distance. If your diagram is going to appear only on screen, thicker lines may be better than thinner lines, but try not to go beyond 2 points thickness. A thin line is a 1 point thick line—a thicker line is 2 points or more. Tip 5: Symmetry is better than asymmetry By nature, our brains tend to seek symmetry. Symmetry helps your diagram look balanced. Balance makes your diagram look more professional. There is a caveat regarding visual symmetry: Visual symmetry does not equal mathematical symmetry. A good example of mathematical symmetry is the income diagram shown below. The cylinders below the blue arrows are mathematically correct but if you study the diagram you might get a nagging feeling that there is something not quite right. However, you cannot really put your finger on what the problem is. This is probably due to the lack of visual symmetry. One solution is given below where the expenditures are alone shown in cylinders. The saving is shown as a piggy bank using a stencil called Cash Flow from Graffletopia. Any educated graphics designer (architect, photographer, illustrator, and so on) will tell you that you should favor visual symmetry rather than mathematical. If you are unsure about how to do this—just create diagrams that "feel and look right". If this fails, go down the mathematical symmetry route. Tip 6: Have one, and only one, focus point The focus point is the most important part of your diagram. Creating diagrams means that you will have several elements in your diagram. If you are not careful, your readers will not "get" your diagram without spending a lot of time studying the details. It is really important to have as few focus points as possible. If you can get away with only one focus point – this is excellent. If your number of focus points increases beyond five, your diagram runs the risk of becoming everything and the kitchen sink – as such, you should really go back to your planning stage! If your diagram is conveying more than one message, try to make more than one diagram. Even if your audience is versed in the subject it will often pay to either divide the diagram – or create separate ones. Tip 7: Apply the Golden Ratio to stand alone diagrams If your diagram is not part of an accompanying and explanatory text, you should apply the so-called Golden Ratio. Another name for the Golden Ratio, is the Rule of Thirds. In practise you divide your page into thirds, both horizontally and vertically. You will now have a grid of nine boxes. However, it's where the horizontal and vertical lines cross each other that you should concentrate. This is the part of your diagram where you should place the most important elements. Tip 8: Use titles, figure captions, and legends Stand-alone diagrams must always have a title telling the reader what the diagram is about. If your diagram is part of a book or a report, you may want to include figure captions – at least if you reference your diagram at more than one place in the text. Instead of addressing the diagrams as "In the second diagram from the bottom on page 34, we see that ..." – put a figure caption below the diagram, and you can now address the diagram in the text as "In fig. 12, we see that ...". If your diagram contains elements that may not be intuitive for the reader, then add a legend to your drawing. If the lines between elements have different colors—then you absolutely need a legend to explain the difference between the red and the green lines. It may be an excellent idea to place the legend inside a box a bit away from the diagram with a readable heading stating: Diagram legend. Tip 9: Be liberal with white space Use space around your elements. Do not cramp them together, as this will make your diagram look messy and dirty. It's better to use a whole extra page in landscape mode in a report for an important diagram, rather to compress the diagram to fit within the text. In the planning stage of your diagram, take white space into account – and you may end up with a different layout that is more fitting for your report than your original plan. A lot of times your diagram will end up in a report or on a web page. Most of these places adhere to portrait-based layouts. It may be a good thing trying to make your diagram fit a portrait-based layout – rather than sticking to using landscape out of habit. Tip 10: Be consistent Never use two different shapes for the same kind of element. Never use two different colors on shapes or lines to convey the same meaning. Never use different fonts, and font sizes, within the same types of shapes. Let's say you need to have a diagram involving animals in the general sense. If you can't find a drawing or a picture of a group of animals – use the same animal concisely. Also, use a shape/picture/drawing (animal) that people recognize.   Further resources on this subject: OmniGraffle 5: Making your Diagram Look Good OmniGraffle 5: Shape Selection, Re-Styling and Color Picker in Detail
Read more
  • 0
  • 0
  • 8540
article-image-building-consumer-review-website-using-wordpress-3
Packt
06 Aug 2010
15 min read
Save for later

Building a Consumer Review Website using WordPress 3

Packt
06 Aug 2010
15 min read
(For more resources on Wordpress, see here.) Building a consumer review website will allow you to supply consumers with the information that they seek and then, once they've decided to make a purchase, your site can direct them to a source for the product or service. This process can ultimately allow you to earn some nice commission checks because it's only logical that you would affiliate yourself with a number of the sites to which you will be directing consumers. The great thing about using the WP Review Site plugin to build your consumer review website is that you can provide people with an unbiased source of public opinions on any product or service that you can imagine. You will never have to resort to the hard sell in order to drive traffic to the companies that you've affiliated yourself with. Instead, consumers can research the reviews posted on your website and,ultimately, make a purchase feeling confident that they're making the right decision. In this article, you will learn about the following: Present reviews in the most convenient way possible for visitors browsing your site Specify the ratings criteria that site visitors will use when reviewing the products or services included on your website Display informational comparison tables on your site's index and category pages Provide visitors with the location of local businesses using Google Maps Perform the additional steps required when writing a post now that the WP Review Site plugin has been introduced into the process Perform either automatic and manual integration so that you can use a theme of your own rather than either of the ones provided with this plugin Once this project is complete, you will have succeeded in creating a site that's similar to the one shown in the following screenshot:   Introducing WP Review Site With the WP Review Site plugin you will be able to build a consumer review site where visitors can share their opinions about the products or services of your choosing. The plugin, which can be found at WP Review Site, can be used to build a dedicated review site or, if you would like consumer reviews to make up only a subsection of your website, then you can specify certain categories where they should appear. This plugin gives you complete control over where ratings appear and where they don't since you can choose to include or exclude them on any category, page, or post. The WP Review Site plugin seamlessly integrates with WordPress by, among other things, altering the normal appearance and functionality of the comments submission form. This plugin provides visitors with a way to write a review and assign stars to the ratings categories that you previously defined. They can also write a review and opt to provide no stars without harming the overall rating presented on your site, since no stars is interpreted as though no rating was given. WP Review Site plugin makes it easy for you to present your visitors with concise information. Using the features available with this plugin, you can build comparison tables based upon your posts and user reviews. In order to accomplish this, you will need to configure a few settings and then the plugin will take care of the rest. Typically, WordPress displays posts in chronological order, but that doesn't make much sense on a consumer review site where visitors want to view posts based upon other factors such as the number of positive reviews that a particular product or service has received. The developer behind WP Site Review took that into consideration and has included two alternative sorting methods for your site's posts. The developer has even included a Bayesian weighting feature so that reviews are ordered in the most logical way possible. Right about now, you're probably wondering what Bayesian weighting is and how it works. What it does is provide a way to mathematically calculate the rating of products and/or services based upon the credibility of the votes that have been cast. If an item receives only a few votes, then it can't be said with any certainty that that's how the general public feels. If an item receives several votes, then it can be safely assumed that many others hold the same opinion. So, with Bayesian weighting, a product that has received only one five star review won't outrank another that has received fifteen four star reviews. As the product that received one five star review garners more ratings, its reviews will grow in credibility and, if it continues to receive high ratings, it will eventually become credible enough to outrank the other reviews. If you're planning to create a website where visitors can come and review local businesses, then you might consider this plugins ability to automatically embed Google Maps quite handy. After configuring the settings on the plugin's Google Maps screen you will be able to type the address for a business into a custom field when writing a post and then the plugin will take care of the rest. The WP Review Site plugin also includes two sidebar widgets that can used with any widget-ready theme. These widgets will allow you to display a list of top rated items and a list of recent reviews. Lastly, the themes provided with this plugin include built-in support for the hReview microformat. This means that Google will easily be able to extract and highlight reviews from your website. That feature will prove to be very beneficial for driving search engine traffic to your site. Installing WP Review Site Once you've installed WordPress you can then concentrate on the installation of the WP Review Site plugin and its accompanying themes. First, extract the wpreviewsite.zip archive. Inside you will find a plugins folder and a themes folder. Within the plugins folder is another folder named review-site. Since none of these folders are zipped, you will need to upload them using either an FTP program or the file manager provided by your web host. So, upload the review-site folder to the wp-content/plugins directory on your server. If you plan to use one of the themes provided with this plugin, then you will next need to upload the contents of the themes folder to the wp-content/themes directory. Setting up and configuring WP Review Site With the installation process complete, you will now need to activate the WP Review Site plugin. Once that's finished, a Review Site menu will appear on the left side of your screen. This menu contains links to the settings screens for this plugin. Before you delve into the configuration process you must first activate the theme that you plan to use on your consumer review website. Using one of the provided themes is a bit easier. That's because using any other theme will mean that you must integrate the functionality of WP Review Site into it. Now that you know the benefits offered by the themes that are bundled with this plugin, click on Appearance | Themes. Once there, activate either Award Winning Hosts, Bonus Black, or a theme of your choice. General Settings Navigate to Review Site | General Settings to be taken to the first of the WP Review Site settings screens. On this screen, Sort Posts By is the first setting that you will encounter. Rather than displaying reviews in the normal chronological order used by WordPress you should, instead, select either the Average User Rating (Weighted) or the Number of Reviews/Comments option. Either of these settings will provide a much more user-friendly experience for your visitors. If you want to make it impossible for site visitors to submit a comment without also choosing a rating, tick the checkbox next to Require Ratings with All Comments. If you don't want to make this a requirement, then you can leave this setting as is. This setting will, of course, only apply to posts that you would like your visitors to rate. On normal posts, that don't include rating stars in the comment form area, it will still be possible for your visitors to submit a comment. When using one of the themes provided with the plugin, none of the other settings on this screen need to be configured. If you would like to integrate this plugin into a different theme, then, depending upon the method that you choose, you may need to revisit this screen later on. No matter how you're handling the theme issue, you can, for now, just click Save Settings before proceeding to the next screen. Rating Categories To access the next settings screen, click on Review Site | Rating Categories. Here you can add categories for people to rate when submitting reviews. These categories shouldn't be confused with the categories used in WordPress for organizational purposes. These WP Review Site categories are more like ratings criteria. By default, WP Review Site includes a category called Overall Rating, but you can click the remove link to delete it if you like. To add your first rating category, simply enter its title into the Add a Category textbox and then click Save Settings. The screen will then refresh and your newly created rating category will now appear under the Edit Rating Categories section of the screen. To add additional rating categories, simply repeat the process that you previously completed. Once you've finished adding rating categories, you will next need to turn your attention to the Bulk Apply Rating Categories section of the screen. In the Edit Rating Categories area you will see all of the rating categories that you just finished adding to your site. If you want to simplify matters, and apply these rating categories to all of the posts on your site, tick the checkbox next to each of the available rating categories. Then, from the Apply to Posts in Category drop-down menu, select All Categories. This is most likely the configuration that you will use if you're building a website entirely dedicated to providing consumer reviews. Once you've finished, click Save Settings. If you, instead, want your newly added rating categories to only appear on certain categories, then bypass the Edit Rating Categories area for now and first look to the Apply to Posts in Category settings area. Currently this will only show All Categories and Uncategorized. The lack of categories in this menu is being caused by two things. First, you haven't added any WordPress categories to your site yet. Secondly, categories won't be included in this menu until they contain at least one post. To solve part of this problem, open a new browser window and then, navigate to Posts | Categories. Then, add the categories that you would like to include on your website. Now, click on Posts | Edit to visit the Edit Posts screen. At the moment, the Hello world! post is the only one published on your site and you can use it to force your site's categories to appear in the Apply to Posts in Category drop-down menu. So, hover over the title of this post and then, from the now visible set of links, click Quick Edit. In the Categories section of the Quick Edit configuration area, tick the checkbox next to each of the categories found on your site. Then, click Update Post. After content has been added to each of your site's categories, you can delete the Hello world! post, since you will no longer need to use it to force the categories to appear in the Apply to Posts in Category drop-down menu. Now, return to the Rating Categories screen and then select the first category that you want to configure from the Apply to Posts in Category drop-down menu. With that selected, in the Edit Rating Categories area, tick the checkbox next to each rating category that you want to appear within that WordPress category. Then, click Save Settings. Repeat this process for each of the WordPress categories to which you would like rating categories to be added. Comparison Tables If you wish, you can add a comparison table to either the home page or the category pages on your site. To do this, you need to visit the Comparison Tables screen, so click on Review Site | Comparison Tables. If you want to display a comparison table on your home page, then tick the checkbox next to Display a Comparison Table on Home Page. If you would like to include all of your site's categories in the comparison table that will be displayed on the home page, then leave the Categories To Display On Home Page textbox as is. However, if you would prefer to include only certain categories, then enter their category IDs, separated by commas, into the textbox instead. You can learn the ID numbers that have been assigned to each of your site's categories by opening a new browser window and then navigating to Posts | Categories. Once there, hover over the title of each of the categories found on the right hand side of your screen. As you do, look at the URL that appears in your browser's status bar and make a note of the number that appears directly after tag_ID=. That's the number that you will need to enter in the Comparison Table screen. If you want to display a comparison table in one or more categories, then tick the checkbox next to Display a Comparison Table on Category Page(s). Now, return to the Comparison Table screen. If you want a comparison table to be displayed on each of your category pages, leave the Categories To Display Comparison Table On textbox at its default. Otherwise, enter a list of comma separated category IDs into the textbox for the categories where you want to display comparison tables. The Number of Posts in the Table setting is currently set to 5, but you can enter another value if you would like a different number of posts to be included in each comparison table. When writing posts, you might use custom fields to include additional information. If you would like that information to be displayed in your comparison tables you will need to enter the names of those fields, separated by commas, into the Custom Fields to Display textbox. Lastly, you can change the text that appears in the Text for the Visit Site link in the Table if you wish or you may leave it at its default. With these configurations complete, click Save Settings. In this screenshot, you can see what a populated comparison table will look like on your website: Google Maps If you plan on featuring reviews centered around local businesses, then you might want to consider adding Google Maps to your site. This will make it easy for visitors to see exactly where each business is located. You can access this settings screen by clicking on Review Site | Google Maps. To activate this feature, tick the checkbox next to Display a Google Map on Posts/Pages with mapaddress Custom Field. Next, you need to use the Map Position setting to specify where these Google Maps will appear in relation to the content. You can choose to use either the Top of Post or Bottom of Post position. The Your Google Maps API Key textbox is next. Here you will need to enter a Google Maps API key. If you don't have a Google Maps API key for this domain, then you will need to visit Google to generate one. To do this, right-click on the link provided on the Google Maps screen and then open that link in a new browser window. You will then be taken to the Google Maps API sign up screen, which can be found at Google Maps API sign up. If you've ever signed up to use any of Google's services, then you can use that username and password to log in. If you don't have an account with Google, create one now. Take a moment to read the information and terms presented on the Google Maps API sign up page. After you've finished reviewing this text, if it's acceptable to you, enter the URL for your website into the My web site URL textbox and then click Generate API Key. You will then be taken to a thank you screen where your API key will be displayed. Copy the API key and then return to the Google Maps screen on your website. Once there, paste your API key into the textbox for Your Google Maps API Key. The Map Width and Map Height settings are next. By default, these are configured to 400px and 300px. If you would prefer that the maps be displayed at a different size, then enter new values into each of these textboxes. The last setting is Map Zoom Level (1-5), which is currently set to 3. This setting should be fine, but you may change it if you wish. Finally, click Save Settings. When you publish a post that includes the mappadress custom field, this is what the Google Map will look like on your site.
Read more
  • 0
  • 0
  • 8538

article-image-search-using-beautiful-soup
Packt
20 Jan 2014
6 min read
Save for later

Search Using Beautiful Soup

Packt
20 Jan 2014
6 min read
(For more resources related to this topic, see here.) Searching with find_all() The find() method was used to find the first result within a particular search criteria that we applied on a BeautifulSoup object. As the name implies, find_all() will give us all the items matching the search criteria we defined. The different filters that we see in find() can be used in the find_all() method. In fact, these filters can be used in any searching methods, such as find_parents() and find_siblings(). Let us consider an example of using find_all(). Finding all tertiary consumers We saw how to find the first and second primary consumer. If we need to find all the tertiary consumers, we can't use find(). In this case, find_all() will become handy. all_tertiaryconsumers = soup.find_all(class_="tertiaryconsumerslist") The preceding code line finds all the tags with the = "tertiaryconsumerlist" class. If given a type check on this variable, we can see that it is nothing but a list of tag objects as follows: print(type(all_tertiaryconsumers)) #output <class 'list'> We can iterate through this list to display all tertiary consumer names by using the following code: for tertiaryconsumer in all_tertiaryconsumers: print(tertiaryconsumer.div.string) #output lion tiger Understanding parameters used with find_all() Like find(), the find_all() method also has a similar set of parameters with an extra parameter, limit, as shown in the following code line: find_all(name,attrs,recursive,text,limit,**kwargs) The limit parameter is used to specify a limit to the number of results that we get. For example, from the e-mail ID sample we saw, we can use find_all() to get all the e-mail IDs. Refer to the following code: email_ids = soup.find_all(text=emailid_regexp) print(email_ids) #output [u'abc@example.com',u'xyz@example.com',u'foo@example.com'] Here, if we pass limit, it will limit the result set to the limit we impose, as shown in the following example: email_ids_limited = soup.find_all(text=emailid_regexp,limit=2) print(email_ids_limited) #output [u'abc@example.com',u'xyz@example.com'] From the output, we can see that the result is limited to two. The find() method is find_all() with limit=1. We can pass True or False values to find the methods. If we pass True to find_all(), it will return all tags in the soup object. In the case of find(), it will be the first tag within the object. The print(soup.find_all(True)) line of code will print out all the tags associated with the soup object. In the case of searching for text, passing True will return all text within the document as follows: all_texts = soup.find_all(text=True) print(all_texts) #output [u'n', u'n', u'n', u'n', u'n', u'plants', u'n', u'100000', u'n', u'n', u'n', u'algae', u'n', u'100000', u'n', u'n', u'n', u'n', u'n', u'deer', u'n', u'1000', u'n', u'n', u'n', u'rabbit', u'n', u'2000', u'n', u'n', u'n', u'n', u'n', u'fox', u'n', u'100', u'n', u'n', u'n', u'bear', u'n', u'100', u'n', u'n', u'n', u'n', u'n', u'lion', u'n', u'80', u'n', u'n', u'n', u'tiger', u'n', u'50', u'n', u'n', u'n', u'n', u'n'] The preceding output prints every text content within the soup object including the new-line characters too. Also, in the case of text, we can pass a list of strings and find_all() will find every string defined in the list: all_texts_in_list = soup.find_all(text=["plants","algae"]) print(all_texts_in_list) #output [u'plants', u'algae'] This is same in the case of searching for the tags, attribute values of tag, custom attributes, and the CSS class. For finding all the div and li tags, we can use the following code line: div_li_tags = soup.find_all(["div","li"]) Similarly, for finding tags with the producerlist and primaryconsumerlist classes, we can use the following code lines: all_css_class = soup.find_all(class_=["producerlist","primaryconsumerlist"]) Both find() and find_all() search an object's descendants (that is, all children coming after it in the tree), their children, and so on. We can control this behavior by using the recursive parameter. If recursive = False, search happens only on an object's direct children. For example, in the following code, search happens only at direct children for div and li tags. Since the direct child of the soup object is html, the following code will give an empty list: div_li_tags = soup.find_all(["div","li"],recursive=False) print(div_li_tags) #output [] If find_all() can't find results, it will return an empty list, whereas find() returns None. Navigation using Beautiful Soup Navigation in Beautiful Soup is almost the same as the searching methods. In navigating, instead of methods, there are certain attributes that facilitate the navigation. So each Tag or NavigableString object will be a member of the resulting tree with the Beautiful Soup object placed at the top and other objects as the nodes of the tree. The following code snippet is an example for an HTML tree: html_markup = """<div class="ecopyramid"> <ul id="producers"> <li class="producerlist"> <div class="name">plants</div> <div class="number">100000</div> </li> <li class="producerlist"> <div class="name">algae</div> <div class="number">100000</div> </li> </ul> </div>""" For the previous code snippet, the following HTML tree is formed: In the previous figure, we can see that Beautiful Soup is the root of the tree, the Tag objects make up the different nodes of the tree, while NavigableString objects make up the leaves of the tree. Navigation in Beautiful Soup is intended to help us visit the nodes of this HTML/XML tree. From a particular node, it is possible to: Navigate down to the children Navigate up to the parent Navigate sideways to the siblings Navigate to the next and previous objects parsed We will be using the previous html_markup as an example to discuss the different navigations using Beautiful Soup. Summary In this article, we discussed in detail the different search methods in Beautiful Soup, namely, find(), find_all(), find_next(), and find_parents(); code examples for a scraper using search methods to get information from a website; and understanding the application of search methods in combination. We also discussed in detail the different navigation methods provided by Beautiful Soup, methods specific to navigating downwards and upwards, and sideways, to the previous and next elements of the HTML tree. Resources for Article: Further resources on this subject: Web Services Testing and soapUI [article] Web Scraping with Python [article] Plotting data using Matplotlib: Part 1 [article]
Read more
  • 0
  • 0
  • 8522
Modal Close icon
Modal Close icon