Components and State
- Using State
- Multiple Components
- Reusable Components
- Param Validation
- Default Param Values
- Params of type Proc
- Other Params
- Mixins and Inheritance
Using State
A Simple Example
class LikeButton < Hyperloop::Component render(DIV) do P do "You #{state.liked ? 'like' : 'haven\'t liked'} this. Click to toggle." end.on(:click) do mutate.liked !state.liked end end end
Components are Just State Machines
React thinks of UIs as simple state machines. By thinking of a UI as being in various states and rendering those states, it's easy to keep your UI consistent.
In React, you simply update a component's state, and then the new UI will be rendered on this new state. React takes care of updating the DOM for you in the most efficient way.
How State Works
To change a state variable you use mutate.state_variable
and pass the new value. For example mutate.liked(!state.like)
gets the current value of like, toggles it, and then updates it. This in turn causes the component to be rerendered. For more details on how this works, and the full syntax of the update method see the component API reference
What Components Should Have State?
Most of your components should simply take some params and render based on their value. However, sometimes you need to respond to user input, a server request or the passage of time. For this you use state.
Try to keep as many of your components as possible stateless. By doing this you'll isolate the state to its most logical place and minimize redundancy, making it easier to reason about your application.
A common pattern is to create several stateless components that just render data, and have a stateful component above them in the hierarchy that passes its state to its children via params
. The stateful component encapsulates all of the interaction logic, while the stateless components take care of rendering data in a declarative way.
What Should Go in State?
State should contain data that a component's event handlers, timers, or http requests may change and trigger a UI update.
When building a stateful component, think about the minimal possible representation of its state, and only store those properties in state
. Add to your class methods to compute higher level values from your state variables. Avoid adding redundant or computed values as state variables as
these values must then be kept in sync whenever state changes.
What Shouldn't Go in State?
state
should only contain the minimal amount of data needed to represent your UI's state. As such, it should not contain:
- Computed data: Don't worry about precomputing values based on state — it's easier to ensure that your UI is consistent if you do all computation during rendering. For example, if you have an array of list items in state and you want to render the count as a string, simply render
"#{state.list_items.length} list items'
in yourrender
method rather than storing the count as another state. - Data that does not effect rendering: For example handles on timers, that need to be cleaned up when a component unmounts should go in plain old instance variables.
Multiple Components
So far, we've looked at how to write a single component to display data and handle user input. Next let's examine one of React's finest features: composability.
Motivation: Separation of Concerns
By building modular components that reuse other components with well-defined interfaces, you get much of the same benefits that you get by using functions or classes. Specifically you can separate the different concerns of your app however you please simply by building new components. By building a custom component library for your application, you are expressing your UI in a way that best fits your domain.
Composition Example
Let's create a simple Avatar component which shows a profile picture and username using the Facebook Graph API.
class Avatar < Hyperloop::Component
param :user_name
render(DIV) do
ProfilePic user_name: params.user_name
ProfileLink user_name: params.user_name
end
end
class ProfilePic < Hyperloop::Component
param :user_name
render do
IMG src: "https://graph.facebook.com/#{params.user_name}/picture"
end
end
class ProfileLink < Hyperloop::Component
param :user_name
render do
A href: "https://www.facebook.com/#{params.user_name}" do
params.user_name
end
end
end
Ownership
In the above example, instances of Avatar
own instances of ProfilePic
and ProfileLink
. In React, an owner is the component that sets the params
of other components. More formally, if a component X
is created in component Y
's render
method, it is said that X
is owned by Y
. As discussed earlier, a component cannot mutate its params
— they are always consistent with what its owner sets them to. This fundamental invariant leads to UIs that are guaranteed to be consistent.
It's important to draw a distinction between the owner-ownee relationship and the parent-child relationship. The owner-ownee relationship is specific to React, while the parent-child relationship is simply the one you know and love from the DOM. In the example above, Avatar
owns the div
, ProfilePic
and ProfileLink
instances, and div
is the parent (but not owner) of the ProfilePic
and ProfileLink
instances.
Children
When you create a React component instance, you can include additional React components or JavaScript expressions between the opening and closing tags like this:
Parent { Child() }
Parent
can iterate over its children by accessing its children
method.
Child Reconciliation
Reconciliation is the process by which React updates the DOM with each new render pass. In general, children are reconciled according to the order in which they are rendered. For example, suppose we have the following render method displaying a list of items. On each pass the items will be completely rerendered:
render do
params.items.each do |item|
para do
item[:text]
end
end
end
What if the first time items was [{text: "foo"}, {text: "bar"}]
, and the second time items was [{text: "bar"}]
?
Intuitively, the paragraph
foo

was removed. Instead, React will reconcile the DOM by changing the text content of the first child and destroying the last child. React reconciles according to the order of the children.
Stateful Children
For most components, this is not a big deal. However, for stateful components that maintain data in state
across render passes, this can be very problematic.
In most cases, this can be sidestepped by hiding elements based on some property change:
render do
state.items.each do |item|
PARA(style: {display: item[:some_property] == "some state" ? :block : :none}) do
item[:text]
end
end
end
Dynamic Children
The situation gets more complicated when the children are shuffled around (as in search results) or if new components are added onto the front of the list (as in streams). In these cases where the identity and state of each child must be maintained across render passes, you can uniquely identify each child by assigning it a key
:
param :results, type: [Hash] # each result is a hash of the form {id: ..., text: ....}
render do
OL do
params.results.each do |result|
LI(key: result[:id]) { result[:text] }
end
end
end
When React reconciles the keyed children, it will ensure that any child with key
will be reordered (instead of clobbered) or destroyed (instead of reused).
The key
should always be supplied directly to the components in the array, not to the container HTML child of each component in the array:
# WRONG!
class ListItemWrapper < Hyperloop::Component
param :data
render do
LI(key: params.data[:id]) { params.data[:text] }
end
end
class MyComponent < Hyperloop::Component
param :results
render do
UL do
params.result.each do |result|
ListItemWrapper data: result
end
end
end
end
# CORRECT
class ListItemWrapper < Hyperloop::Component
param :data
render do
LI { params.data[:text] }
end
end
class MyComponent < Hyperloop::Component
param :results
render do
UL do
params.result.each do |result|
ListItemWrapper key: result[:id], data: result
end
end
end
end
Data Flow
In React, data flows from owner to owned component through the params as discussed above. This is effectively one-way data binding: owners bind their owned component's param to some value the owner has computed based on its params
or state
. Since this process happens recursively, data changes are automatically reflected everywhere they are used.
Stores
Managing state between components is best done using Stores as many Components can access one store. This saves passing data btween Components. Please see the Store documentation for details.
Reusable Components
When designing interfaces, break down the common design elements (buttons, form fields, layout components, etc.) into reusable components with well-defined interfaces. That way, the next time you need to build some UI, you can write much less code. This means faster development time, fewer bugs, and fewer bytes down the wire.
Param Validation
As your app grows it's helpful to ensure that your components are used correctly. We do this by allowing you to specify the expected ruby class of your parameters. When an invalid value is provided for a param, a warning will be shown in the JavaScript console. Note that for performance reasons type checking is only done in development mode. Here is an example showing typical type specifications:
class ManyParams < Hyperloop::Component
param :an_array, type: [] # or type: Array
param :a_string, type: String
param :array_of_strings, type: [String]
param :a_hash, type: Hash
param :some_class, type: SomeClass # works with any class
param :a_string_or_nil, type: String, allow_nil: true
end
Note that if the param can be nil, add allow_nil: true
to the specification.
Default Param Values
React lets you define default values for your params
:
class ManyParams < Hyperloop::Component
param :an_optional_param, default: "hello", type: String, allow_nil: true
If no value is provided for :an_optional_param
it will be given the value "hello"
Params of type Proc
A Ruby Proc
can be passed to a component like any other object. The param
macro treats params declared as type Proc
specially, and will automatically call the proc when the param name is used on the params method.
param :all_done, type: Proc
...
# typically in an event handler
params.all_done(data) # instead of params.all_done.call(data)
Proc params can be optional, using the default: nil
and allow_nil: true
options. Invoking a nil proc param will do nothing. This is handy for allowing optional callbacks.
Other Params
A common type of React component is one that extends a basic HTML element in a simple way. Often you'll want to copy any HTML attributes passed to your component to the underlying HTML element.
To do this use the collect_other_params_as
macro which will gather all the params you did not declare into a hash. Then you can pass this hash on to the child component
class CheckLink < Hyperloop::Component
collect_other_params_as :attributes
render do
# we just pass along any incoming attributes
a(attributes) { '√ '.span; children.each &:render }
end
end
# CheckLink(href: "/checked.html")
Note: collect_other_params_as
builds a hash, so you can merge other data in or even delete elements out as needed.
Mixins and Inheritance
Ruby has a rich set of mechanisms enabling code reuse, and Hyperloop is intended to be a team player in your Ruby application. Components can be subclassed, and they can include (or mixin) other modules. You can also create a component by including Hyperloop::Component::Mixin
which allows a class to inherit from some other non-react class, and then mixin the React DSL.
# make a SuperFoo react component class
class Foo < SuperFoo
include Hyperloop::Component::Mixin
end
One common use case is a component wanting to update itself on a time interval. It's easy to use the kernel method every
, but it's important to cancel your interval when you don't need it anymore to save memory. React provides lifecycle methods that let you know when a component is about to be created or destroyed. Let's create a simple mixin that uses these methods to provide a React friendly every
function that will automatically get cleaned up when your component is destroyed.
module ReactInterval def self.included(base) base.before_mount do @intervals = [] end base.before_unmount do @intervals.each(&:stop) end end def every(seconds, &block) Kernel.every(seconds, &block).tap { |i| @intervals << i } end end class TickTock < Hyperloop::Component include ReactInterval before_mount do state.seconds! 0 end after_mount do every(1) { mutate.seconds state.seconds+1} end render(DIV) do "Hyperloop has been running for #{state.seconds} seconds".para end end
Notice that TickTock effectively has two before_mount callbacks, one that is called to initialize the @intervals
array and another to initialize state.seconds


Capturing Links
Clicking one of the links contained in a Polymer Element (or in regular DOM, doesn't matter) actually sends a PATCH
- Albert Einstein (index.html)
-
Nikola Tesla (subpage.html)
Capturing input
Welcome {{model.user.fullName}}!
This demo shows usage with Polymer's TemplateBinding outside and inside of Polymer Element
Clicking one of the links contained in a Polymer Element (or in regular DOM, doesn't matter) actually sends a PATCH


| < Day Day Up > |
7.5 Administration and MaintenanceConfiguring replication isn't something you do every day (unless you're writing a book about MySQL, of course.) Once replication is set up and running, you're likely just to let it run. But there are a few administrative tasks you'll likely need to deal with at some point. You should, of course, consider automating them as much as possible. 7.5.1 MonitoringReplication increases the complexity of monitoring MySQL's health. Are all the slaves replicating? Have the slaves encountered errors? How far behind is the slowest slave? As you may have come to expect, MySQL provides all the data necessary to answer those questions (and many questions you probably haven't even considered), but extracting and understanding the data is something it won't do for you. In Section 7.5.4, later in this chapter, we'll try to provide some details to help you make sense of all the data MySQL provides, which should help you understand the tools that are helpful in processing that data. <IP_ADDRESS> Master statusUsing the SHOW MASTER STATUS command, the master will tell you about its replication status: mysql> SHOW MASTER STATUS \G *************************** 1. row *************************** File: binary-log.004 Position: 635904327 Binlog_do_db: Binlog_ignore_db: 1 row in set (0.00 sec) The output includes the current binary log filename and the position (or offset) into the binary log where the next query will be written. The other two fields correspond to the binlog-do-db and binlog-ignore-db filtering options in the server's my.cnf file. If you are filtering binary log records on the master, one or both of these will list the database names affected by your filters. You can also ask the master which binary logs still exist on disk: mysql> SHOW MASTER LOGS; +----------------+ | Log_name | +----------------+ | binary-log.001 | | binary-log.002 | | binary-log.003 | | binary-log.004 | +----------------+ 4 rows in set (0.02 sec) But the output is quite limited. It would be helpful to know the sizes and ages of the files as well. MySQL is doing little more than reading and displaying the contents of the log-bin.index file. To get more information, you need to log on to the server and examine the files by hand. <IP_ADDRESS> Slave statusThere is significantly more information available on the slave side of replication, mostly because the slaves have more information to keep track of. To start, the SHOW SLAVE STATUS command provides a good summary of the information from both the master.info and relay-log.info files: mysql> SHOW SLAVE STATUS \G *************************** 1. row *************************** Master_Host: master.example.com Master_User: repl Master_Port: 3306 Connect_retry: 15 Master_Log_File: binary-log.004 Read_Master_Log_Pos: 635904807 Relay_Log_File: relay-log.004 Relay_Log_Pos: 846096118 Relay_Master_Log_File: binary-log.004 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_do_db: Replicate_ignore_db: Last_errno: 0 Last_error: Skip_counter: 0 Exec_master_log_pos: 635904807 Relay_log_space: 846096122 1 row in set (0.00 sec) In addition, there is some other metadata in the output. The Last_errno and Last_error fields provide information about the most recent replication-related error, if any. The Relay_log_space tells you how much space the relay log is consuming. The two most important fields are Slave_IO_Running and Slave_SQL_Running. They tell you if the IO and slave threads are running. <IP_ADDRESS> Replication heartbeatWatching the values produced by SHOW MASTER STATUS and SHOW SLAVE STATUS can give you a rough idea of how up to date a slave is. The trouble with relying on that information is that you're only looking at bytes. You can determine how many more bytes of log data the slave needs to execute before it is current. However, that doesn't tell you how many queries need to be executed. There's no good way to figure that out, short of running the binary log through mysqlbinlog and counting queries. It is possible to determine how out of date the slave is with some degree of accuracy by implementing a simple heartbeat system. The heartbeat principle is easy. At a fixed interval, say 20 seconds, a process on the master inserts a record with the latest timestamp into a table. On the slave, a corresponding process reads the most recent record every 20 seconds. Assuming that the system clocks on both machines are in sync, you can tell how far behind the slave is to within 20 seconds of accuracy. See the write_heartbeat and read_heartbeat scripts in Section 7.5.4 for a sample implementation. 7.5.2 Log RotationBinary log files accumulate on the server until they are explicitly removed. The SHOW MASTER LOGS command tells you how many logs there are at any given time. To remove one or more logs, use the PURGE MASTER LOGS TO ... command. It removes all the logs up to but not including the given log name. Here's an example: mysql> SHOW MASTER LOGS; +----------------+ | Log_name | +----------------+ | binary-log.001 | | binary-log.002 | | binary-log.003 | | binary-log.004 | +----------------+ 4 rows in set (0.02 sec) mysql> PURGE MASTER LOGS TO 'binary-log.004'; The command tells MySQL to remove binary-log.001, binary-log.002, and binary-log.003. Be careful not to remove logs too quickly. If a slave is offline for a significant period of time, there's a chance that it still needs one or more of the logs you removed. If you're in doubt, run SHOW SLAVE STATUS on each slave to verify which log it is using. To automate this process, see the purge_binary_logs script in Section 7.5.4. 7.5.3 Changing MastersSooner or later you'll need to point your slaves at a new master. Maybe the old one is being replaced with a newer, faster computer; perhaps there was a failure, and you are promoting a slave to master. In MySQL 3.23 and 4.0, you need to inform the slaves about their new master. A future version of MySQL is supposed to include a fail-safe replication feature that automates the process. A planned changing of masters is a straightforward process. (In the event of a master failure, it may not be so easy.) You simply need to issue the CHANGE MASTER TO ... command on each slave. In doing so, you inform the slave of the new master's parameters—the same ones specified in the my.cnf file. The slave will begin replicating from its new master, and MySQL will also update the master.info with the new information. <IP_ADDRESS> Using the right valuesAs usual, the devil is in the details. How do you decide which values to use? What if you get them wrong? First, let's consider the easy case. If you are in control of the situation, the process is easy. Follow these steps:
The RESET MASTER command tells the master to flush all its binary logs and start fresh. By starting with a clean slate on the new master, there's no guesswork involved in determining the right log position. Since it's a brand new log, we know the position is 4, because each binary log has a 4-byte header that consumes positions 0-3. The complete CHANGE MASTER TO ... command looks like this: mysql> CHANGE MASTER TO -> MASTER_HOST='newmaster.example.com', -> MASTER_USER='repl', -> MASTER_PASSWORD='MySecret!', -> MASTER_PORT=3306, -> MASTER_LOG_FILE='log-bin.001', -> MASTER_LOG_POS=4; If, on the other hand, the master crashes and you can't bring it back online in a reasonable amount of time, things aren't so clear-cut. If you have only one slave, of course, there's no decision to make. You use the slave. But if you have multiple slaves, you need to determine which one is the most up to date. By examining the output of SHOW SLAVE STATUS on each slave, you can easily determine which one is closest to matching the master at the time it crashed. Once you know the log name and position, you can construct a CHANGE MASTER TO ... command to run on the remaining slaves. In doing so, however, you'll likely cause some the slaves to be slightly out of sync with their new master. To illustrate why, assume that each query is assigned an increasing unique ID number. The original master had just executed query 500 when it crashed. The "most up-to-date" slave, the new master, had executed query 496. That means that your best slave is missing four queries, and there's no way to recover them unless your application logs every query it writes, which is unlikely. Now, let's assume that there are two more slaves, slave2 and slave3; slave2 executed query 490, and slave3 executed query 493. You have a choice. You can either point both slaves at the new master's current position (query 496) or you can try to figure the corresponding offsets for each slave in the new master's binary log. That will take more time, but it means you lose less data. To find the matching log position for each slave, you need to have the binary log enabled on each slave. Use the mysqlbinlog command (described in Section 7.5.4) to locate the last query executed. Then locate exactly the same query in the new master's binary log. Once you find the query, you'll have the offset you need. The output of mysqlbinlog always includes the offset in a comment right before the query. For example: $ mysqlbinlog log-bin.001 ... # at 683 #021103 18:36:33 server id 1 log_pos 683 Query thread_id=288 exec_time=0 error_code=0 SET TIMESTAMP=1036377393; insert into test1 values (8); The # at 683 line lists the position of the insert into test1 values (8) query in the log. 7.5.4 ToolsIn this section, we'll look at some tools that can make dealing with replication a bit easier. A couple of the tools come straight out of the MySQL distribution, while others are home-grown and often ripe for improvement. The home-grown tools can serve as a starting point for solving your specific needs; such tools are available (and kept up to date) at http://highperformancemysql.com. <IP_ADDRESS> mysqlbinlog: Viewing data in logsThe mysqlbinlog utility has been mentioned several times in this chapter. It is used to decode the binary formats used by the binary log and relay log. Given a log file, it outputs the SQL queries contained in the log. Furthermore, it precedes each query with several pieces of metadata as comments. $ mysql log-bin.001 ... # at 683 #021103 18:36:33 server id 1 log_pos 683 Query thread_id=288 exec_time=0 error_code=0 SET TIMESTAMP=1036377393; insert into test1 values (8); The first line contains the offset (or position) of the query in the log. The second line begins with a date and timestamp followed by the server ID of the server that first executed the query. The log position is repeated on this line and followed by the event type. Finally, there's the ID of the thread that executed the query, followed by the time the query took to execute (in seconds) and the error code generated by the query. You can use mysqlbinlog to pull the logs from a remote server by specifying a hostname, username, and password. Using the -o command-line option, you can specify the offset from which you'd like to start reading. For example: $ mysqlbinlog -h slave3.example.com -u root -p -o 35532 log-bin.032 <IP_ADDRESS> check_repl: Ensuring that replication takes placeAs discussed earlier, it's important to check that your slaves are replicating properly when you expect them to. The following script connects to the local MySQL server and makes sure that replication is running by examining the output of SHOW SLAVE STATUS and checking for the both the 3.23.xx and 4.x values: #!/usr/bin/perl -w ## On a slave server, check to see that the slave hasn't stopped. use strict; use DBIx::DWIW; my $conn = DBIx::DWIW->Connect( DB => "mysql", User => "root", Pass => "password", Host => "localhost", ) or exit; my $info = $conn->Hash("SHOW SLAVE STATUS"); if (exists $info->{Slave_SQL_Running} and $info->{Slave_SQL_Running} eq 'No') { warn "slave SQL thread has stopped\n"; } elsif (exists $info->{Slave_IO_Running} and $info->{Slave_IO_Running} eq 'No') { warn "slave IO thread has stopped\n"; } elsif (exists $info->{Slave_Running} and $info->{Slave_Running} eq 'No') { warn "slave has stopped\n"; } This script makes no effort to repair a problem; it simply reports when something is wrong. Without knowing why the failure occurred, it's probably not wise to blindly restart replication. To skip the problem query and restart replication, see the next section. <IP_ADDRESS> fix_repl: Skipping a bad query to continue replicationIn the event that replication has stopped on a slave, you should tell the slave to skip the problem query and continue, unless the problem warrants further investigation. No restart of MySQL is necessary. In MySQL 3.23.xx, execute: SET SQL_SLAVE_SKIP_COUNTER=1 SLAVE START In Versions 4.0.0-4.0.2, execute: SET SQL_SLAVE_SKIP_COUNTER=1 SLAVE START SQL_THREAD In Version 4.0.3 and beyond, execute: SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1 SLAVE START SQL_THREAD Yuck. If you're using a mixture of 3.23.xx and 4.0.x servers, it may be difficult to remember the exact syntax for each version. It's much easier to have a copy of the following fix_repl script on hand to do the hard work for you: #!/usr/local/bin/perl -w # # fix mysql replication if it encounters a problem $|=1; # unbuffer stdout use strict; use DBIx::DWIW; my $host = shift || 'localhost'; my $conn = DBIx::DWIW->Connect( DB => "mysql", User => "root", Pass => "pa55word", Host => $host, ) or die "Couldn't connect to database!"; print "checking $host ... "; my $info = $conn->Hash("SHOW SLAVE STATUS"); my $version = $conn->Scalar("SHOW VARIABLES LIKE 'Version'"); my $fix_cmd; my $start_cmd; # 3.23 if ($version =~ /^3\.23/ and $info->{Slave_Running} eq 'No') { $fix_cmd = "SET SQL_SLAVE_SKIP_COUNTER = 1"; $start_cmd = "SLAVE START"; } # 4.0.0 - 4.0.2 elsif ($version =~ /^4\.0\.[012]/ and $info->{Slave_SQL_Running} eq 'No') { $fix_cmd = "SET SQL_SLAVE_SKIP_COUNTER = 1"; $start_cmd = "SLAVE START SQL_THREAD"; } # 4.0.3 - 4.0.xx, 4.1.xx. Don't know what 5.0 will be like. elsif ($version =~ /^4\.[01]\./ and $info->{Slave_SQL_Running} eq 'No') { $fix_cmd = "SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1"; $start_cmd = "SLAVE START SQL_THREAD"; } # things are okay or unknown version? else { print "GOOD\n"; exit; } print "FIXING ... "; $conn->Execute($fix_cmd); $conn->Execute($start_cmd); print "DONE\n"; exit; Be careful with this technique. Blindly skipping queries on a slave may cause it to become out of sync with the master. If the query is failing due to a duplicate key error, it's probably safe, but you should investigate how that happened in the first place. <IP_ADDRESS> purge_binary_logs: Reclaiming space used by binary logsTo make log rotation easier, you can use something like the following purge_binary_logs Perl script. It connects to the specified server and checks to see how many binary logs are sitting around. If there are more than the specified threshold, it removes any extras. #!/usr/bin/perl -w ## On a slave server, purge the replication logs if there are too many ## sitting around sucking up disk space. use strict; use DBIx::DWIW; my $MIN_LOGS = 4; ## keep main log plus three old binary logs around my $conn = DBIx::DWIW->Connect( DB => "mysql", User => "root", Pass => "password", Host => 'localhost', ); die "Couldn't connect to database!" if not $conn; ## see if there are enough to bother, exit if not my @logs = $conn->FlatArray("SHOW MASTER LOGS"); exit if (@logs < $MIN_LOGS); ## if so, figure out what the last one we want to keep is, then purge ## the rest my $last_log = $logs[-$MIN_LOGS]; print "last log is $last_log\n" unless $ENV{CRON}; $conn->Execute("PURGE MASTER LOGS TO '$last_log'"); exit; Depending on your needs, there's a lot of room for improvement in this script. It would be nice if the script took command-line arguments so you wouldn't need to hardcode the hostname, password, and so on. It would also be nice if the script could check the sizes of the log files. If a master is restarted very frequently, using the number of log files as a metric probably isn't as useful as checking the volume of log data. However, the script can't be run remotely if it checked log file sizes, because it needs to examine the files directly. A valuable but difficult addition would be for the script to remove logs only if it can tell that all slaves had already read them. That requires knowing all the slaves and contacting each one to verify its progress in the replication process. <IP_ADDRESS> mysqldiff: Replication sanity checksAs with anything new, you may not trust replication right away. To help convince yourself that it is really doing what it should do, it's good to perform spot checks on the data, making sure that the slaves have exactly the data they should have. This checking can be done to varying degrees of paranoia:
The first check is quite easy to implement with a bit of Perl code: #!/usr/bin/perl -w use strict; use DBIx::DWIW; $|=1; # unbuffer stdout my $db_user = 'root'; my $db_pass = 'password'; my $db_name = 'test'; my $master = 'master.example.com'; my @slaves = qw( slave1.example.com slave2.example.com slave3.example.com ); my %master_count; for my $server ($master) { print "Checking master... "; my $conn = DBIx::DWIW->Connect(User => $db_user, Host => $server, Pass => $db_pass, DB => $db_name) or die "$!"; for my $table ($conn->FlatArray("SHOW TABLES")) { my $count = $conn->Scalar("SELECT COUNT(*) FROM '$table'"); $master_count{$table} = $count; } print "OK\n"; } for my $server (@slaves) { print "Checking $server... "; my $conn = DBIx::DWIW->Connect(User => $db_user, Host => $server, Pass => $db_pass, DB => $db_name) or die "$!"; for my $table ($conn->FlatArray("SHOW TABLES")) { my $count = $conn->Scalar("SELECT COUNT(*) FROM '$table'"); if ($count != $master_count{$table}) { print "MISMATCH (got $count on $table, expecting $master_count{$table}\n"; } } print "OK\n"; } exit; The script connects to the master and gets the number of rows in each table of the given database. Then it connects to each slave and checks to see that the counts match. If they don't, it issues a MISMATCH warning. This framework can easily be extended to handle multiple databases, perform more specific checks, and even attempt to take corrective action. It is even ready to handle multiple masters. <IP_ADDRESS> write_heartbeat: Generating a periodic health check heartbeatThe following script can implement a heartbeat monitoring system as described earlier. To use it, create a database named MySQL_Admin and a table named Heartbeat with the following structure: CREATE TABLE Heartbeat ( unix_time INTEGER NOT NULL, db_time TIMESTAMP NOT NULL, INDEX time_idx(unix_time) ) The unix_time field holds the timestamp that is explicitly inserted into the table. The db_time field is set automatically by MySQL. By keeping track of both times and inserting new records instead of simply running an UPDATE on a single record, you maintain historical data in the event someone wants to graph or analyze it. Let's look the script to add records: #!/usr/bin/perl -w use strict; use DBIx::DWIW; my $conn = DBIx::DWIW->Connect( DB => "MySQL_Admin", User => "root", Pass => "password", Host => 'localhost', ) or die; my $unix_time = time( ); my $sql = "INSERT INTO Heartbeat (unix_time, db_time) VALUES ($unix_time, NULL)"; $conn->Execute($sql); exit; Running the script at a fixed interval generates a heartbeat that can be used by the read_heartbeat script to monitor replication latency. <IP_ADDRESS> read_heartbeat: Measuring replication log using heartbeatThe companion to write_heartbeat reads the most recent timestamp from the database and computes how far behind the slave might be. Remember that we can't know this time exactly unless the heartbeat records are generated every second, which is probably overkill for most installations. #!/usr/bin/perl -w use strict; use DBIx::DWIW; my $conn = DBIx::DWIW->Connect( DB => "MySQL_Admin", User => "root", Pass => "password", Host => 'localhost', ) or die; my $sql = "SELECT unix_time, db_time FROM Heartbeat ORDER BY unix_time DESC LIMIT 1"; my $info = $conn->Hash($sql); my $time = $info->{unix_time}; my $delay = time( ) - $time; print "slave is $delay seconds behind\n"; exit; This script can also be extended to do far more than report on latency. If the latency is too great, it can send email or page a DBA. |
| < Day Day Up > |


Before v0.1
Completed:
- YAML config
- Success messages, build time
- Watch & rebuild
init
command
- Smarter scanning - look for index files in depth
- Top menu config
- Multiple sources - sub-projects or sub-directories
- Nice default theme with smart navigation
serve
command


Racing's Howard Abrahams in hospital after collapsing at the track
KINGSTON, Jamaica – One of the voices of local racing for over 40 years, Howard Abrahams is now in hospital after collapsing at the race track today (November 16).
The reason (s) why Abrahams was rushed from the race track to the hospital are still unknown despite checks by this medium.
OBSERVER ONLINE will keep readers up to date.


Publications
Safe Learning under Uncertain Objectives and Constraints
Jan 3, 2020
Deletion-Robust Submodular Maximization at Scale.
Jan 3, 2017
Near-Optimal Active Learning of Halfspaces via Query Synthesis in the Noisy Setting
Jan 3, 2016
Adaptive Content Search Through Comparisons
Jan 3, 2011
Continuous Submodular Maximization: Beyond DR-Submodularity
Nov 3, 2020
Minimax Regret of Switching-Constrained Online Convex Optimization: No Phase Transition
Nov 3, 2020
Online MAP Inference of Determinantal Point Processes
Nov 3, 2020
Submodular Maximization Through Barrier Functions
Nov 3, 2020
More data can expand the generalization gap between adversarially robust and standard models
Oct 3, 2020
Streaming Submodular Maximization under a k-Set System Constraint.
Oct 3, 2020
Black Box Submodular Maximization: Discrete and Continuous Settings
Sep 3, 2020
One Sample Stochastic Frank-Wolfe
Sep 3, 2020
Quantized frank-wolfe: Faster optimization, lower communication, and projection free
Sep 3, 2020
Gradient Methods for Submodular Maximization
Nov 3, 2017
Interactive Submodular Bandit.
Nov 3, 2017
Streaming Weak Submodularity: Interpreting Neural Networks on the Fly.
Nov 3, 2017
Differentially Private Submodular Maximization: Data Summarization in Disguise.
Oct 3, 2017
Greed Is Good: Near-Optimal Submodular Maximization via Greedy Optimization.
Oct 3, 2017
Probabilistic Submodular Maximization in Sub-Linear Time.
Oct 3, 2017
Near-Optimal Active Learning of Halfspaces via Query Synthesis in the Noisy Setting.
Aug 3, 2017
Greed Is Good: Near-Optimal Submodular Maximization via Greedy Optimization.
Jul 3, 2017
A Submodular Approach to Create Individualized Parcellations of the Human Brain
Jun 3, 2017
Estimating the Size of a Large Network and its Communities from a Random Sample
Nov 3, 2016
Fast Constrained Submodular Maximization: Personalized Data Summarization.
Oct 3, 2016
Seeing the Unseen Network: Inferring Hidden Social Ties from Respondent-Driven Sampling.
Aug 3, 2016
Submodular Variational Inference for Network Reconstruction
Jul 3, 2016
Learning network structures from firing patterns.
Jun 3, 2016
Distributed Submodular Cover: Succinctly Summarizing Massive Data.
Nov 3, 2015
Lazier Than Lazy Greedy.
Aug 3, 2015
Submodular Surrogates for Value of Information
Aug 3, 2015
Tradeoffs for Space, Time, Data and Risk in Unsupervised Learning.
Aug 3, 2015
Fast Mixing for Discrete Point Processes
Jul 3, 2015
Sequential Information Maximization: When is Greedy Near-optimal?
Jun 3, 2015
Normalization Phenomena in Asynchronous Networks.
May 3, 2015
Asynchronous decoding of LDPC codes over BEC.
Apr 3, 2015
Non-Monotone Adaptive Submodular Maximization.
Feb 3, 2015
Comparison-Based Learning with Rank Nets
Oct 3, 2012
Multi-level error-resilient neural networks
May 3, 2012
Sequential group testing with graph constraints
Apr 3, 2012
Hot or not: Interactive content search using comparisons
Mar 3, 2012
Calibration in circular ultrasound tomography devices.
Jul 3, 2011
Compression with graphical constraints: An interactive browser
Feb 3, 2011
Individualized functional networks reconfigure with cognitive state
Dec 3, 2020
Stochastic Conditional Gradient Methods: From Convex Minimization to Submodular Maximization
Dec 3, 2020
Stochastic Conditional Gradient++
Dec 3, 2020
Submodularity in Action: From Machine Learning to Signal Processing Applications
Dec 3, 2020
There is no single functional atlas even for a single individual: Functional parcel definitions change with task
Dec 3, 2020
Distributed Submodular Maximization
Dec 3, 2016
Fast Distributed Submodular Cover: Public-Private Data Summarization.
Nov 3, 2016
Fast Constrained Submodular Maximization: Personalized Data Summarization.
Oct 3, 2016
From Small-World Networks to Comparison-Based Search.
Dec 3, 2015
Graph-Constrained Group Testing
Dec 3, 2012
Low-Rank Matrix Approximation Using Point-Wise Operators
Dec 3, 2012
Jan 1, 0001


Fed's Williams: Fed has to make sure it is not overreacting to individual data points
by Eren SengezerThe Federal Reserve has to make sure that it is not overreacting to individual data points over the coming months, New York Federal Reserve President John Williams told reporters at a capital markets conference in Washington on Tuesday.
"The fact reserve levels are higher than the Fed was expecting does not change the calculus on monetary policy," Williams added. "If inflation were to move in the wrong direction on a sustained basis, that could cause the Fed to become more accommodative. The most important tools for financial stability are existing ones."
The US Dollar Index ignored these comments and was last moving sideways near 97.80, where it was virtually unchanged on a daily basis.


Fourier-Analysis, Data Input from a Picture
The coordinates of the quarter fold
can
be found from a picture by clicking on them.
Click on 'Import image' to open a *.BMP, *.GIF, *.TIF, *.JPG, *.WMF, or
*.EMF-file. The graphic may be loaded either from the clipboard (paste)
or from a file.
Before you can click on the quarter fold, it must be in an upright
position. You have to rotate
the image image, until both inflection points of the half fold are in a
horizontal line, then you have to eliminate
vergency.
To find the coordinates of the quarter fold click on the inflection
point. Click on the hinge. Now click on the 1/3- and 2/3-coordinates (X1
and X2).


Contens of the first tab. This is completely meaningless text, just to show how the content should look like


Module: ActiveRecord::AttributeMethods::Dirty::ClassMethods
| Relationships & Source Files | |
| Defined in: | activerecord/lib/active_record/attribute_methods/dirty.rb |
Instance Attribute Summary
Instance Attribute Details
#partial_writes (rw)
[ GitHub ]# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 31
def partial_writes ActiveSupport::Deprecation.warn(<<-MSG.squish) ActiveRecord::Base.partial_writes is deprecated and will be removed in Rails 7.1. Use `partial_updates` and `partial_inserts` instead. MSG partial_updates && partial_inserts end
#partial_writes=(value) (rw)
[ GitHub ]# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 47
def partial_writes=(value) ActiveSupport::Deprecation.warn(<<-MSG.squish) `ActiveRecord::Base.partial_writes=` is deprecated and will be removed in Rails 7.1. Use `partial_updates=` and `partial_inserts=` instead. MSG self.partial_updates = self.partial_inserts = value end
#partial_writes? ⇒ Boolean
(rw)
[ GitHub ]
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 39
def partial_writes? ActiveSupport::Deprecation.warn(<<-MSG.squish) `ActiveRecord::Base.partial_writes?` is deprecated and will be removed in Rails 7.1. Use `partial_updates?` and `partial_inserts?` instead. MSG partial_updates? && partial_inserts? end


This is a wonderful place where you can test your knowledge on the fundamentals of JavaScript. I wish you luck but just remember time is of the essence and please make sure to pick correctly or something awful might happen.
Last Player:
Last Score:


Association for Computing Machinery
Advancing Computing as a Science & Profession
We see a world where computing helps solve tomorrow’s problems – where we use our knowledge and skills to advance the profession and make a positive impact.
ETHICS IN COMPUTING
ACM Updates Code of EthicsACM has updated its Code of Ethics and Professional Conduct. The revised Code of Ethics addresses the significant advances in computing technology since the 1992 version, as well as the growing pervasiveness of computing in all aspects of society. ACM’s Code of Ethics is considered the standard for the computing profession, and has been adopted by computing professionals, organizations and technology companies around the world. The Code is a collection of principles and guidelines designed to help computing professionals make ethically responsible decisions in professional practice.
Read the news release.PEOPLE OF ACM INTERVIEW
Meet Jim HendlerJames A. “Jim” Hendler is the Director of the Institute for Data Exploration and Applications and the Tetherless World Professor of Computer, Web and Cognitive Sciences at Rensselaer Polytechnic Institute. He also serves as the Director of the joint Rensselaer-IBM HEALS project. He is an ACM Fellow and Chair of ACM’s US Technology Policy Committee. “I look forward to helping to make ACM a trusted, 'must-consult' organization for policy makers.”
The SIGKDD Conference on Knowledge Discovery and Data Mining brings together researchers and practitioners from data science, data mining, knowledge discovery, large-scale data analytics, and Big Data. The event includes 27 workshops, 37 tutorials, and keynotes by ACM fellow Jeannette Wing (Columbia University), David Hand (Imperial College), Alvin E. Roth (Stanford University), and Yee Whye Teh (University of Oxford/Deepmind).
The flagship annual conference of the ACM Special Interest Group on Data Communication focuses on the applications, technologies, architectures, and protocols in the computer communication field. Workshops will cover IoT, Big Data analytics, mobile edge communications, and more. Jennifer Rexford (Princeton University), 2016 Athena Lecturer and 2004 Hopper Award recipient, will keynote.
ACM NEWSMAKERS
ACM Names Vicki L. Hanson CEO/Executive DirectorACM has named Vicki L. Hanson to the position of executive director and CEO effective July 1, 2018. As ACM’s most senior staff member, Hanson will work with ACM’s volunteer community to provide strategic vision and to develop sustainable business models to ensure ACM’s continued worldwide membership, publications and revenue growth.
ACM President-elect Cherri Pancake said, “Having served ACM for many years in various volunteer capacities, Vicki’s unique insights into the organization and how it serves the profession should serve us well to ensure a sustainable future for ACM."
ACM ELECTIONS
2018 ACM General ElectionACM's newly-elected officers:
For the term 1 July 2018 — 30 June 2020
PresidentCherri M. Pancake
Vice PresidentElizabeth Churchill
Secretary/TreasurerYannis loannidis
For the term 1 July 2018 — 30 June 2022
Members at LargeClaudia Bauzer Medeiros brings
Theo Schlossnagle
ACM ELECTIONS
ACM India Council ElectionNewly-Elected Officers for the term 1 July 2018 - 30 June 2020:
President: Abhiram Ranade, IIT Bombay
Vice President: Venkatesh Raman, ITMSc Chennai
Secretary/Treasurer: Maria Choudhary, Oracle
Members-at Large for the term 1 July 2018 - 30 June 2022:
Supratik Chakraborty, IIT Bombay
Meenakshi D'Souza, IIIT Bangalore
Manish Gupta, VideoKen, Bangalore
Jayant Haritsa, IIS Bangalore
Pankaj Jalote, IIIT Delhi
Venkatesh Kamat, Goa University
Hemangee K. Kapoor, IIT Guwahati
Sudeshna Sarkar, IIT Kharagpur
Vasudeva Varma, IIIT Hyderabad
Proceedings of the ACM (PACM) is a journal series that launched in 2017. The series was created in recognition of the fact that conference-centric publishing disadvantages the CS community with respect to other scientific disciplines when competing with researchers from other disciplines for top science awards and career progression, and the fact that top ACM conferences have demonstrated high quality and high impact on the field. See PACMs on Programming Languages, Interactive, Mobile, Wearable and Ubiquitous Technologies, Measurement and Analysis of Computing Systems, and HCI.
PEOPLE OF ACM INTERVIEW
Meet Nuria OliverNuria Oliver is the first Director of Data Science Research at Vodafone, a global telecommunications conglomerate. An ACM Fellow, she is serving as a General Co-Chair of Mobile HCI 2018. "As telecommunications providers, we need to rely on sophisticated machine learning algorithms … to be able to personalize services; understand, anticipate and respond to customer needs; optimize our networks; create new data-driven services; and help make better decisions that have positive social impact. I am particularly passionate about this last topic."
The 2018 Global Survey of Mathematical, Computing, and Natural Scientists needs people in mathematical, computing and natural sciences, including students, to share their career and educational experiences. The data being collected will include focused information about women in these fields. The survey is being conducted by The Gender Gap in Science project, funded by the International Council for Science, a collaboration of several organizations including ACM.
CACM REPORTS
CACM August 2018 - Multiparty Privacy in Social MediaOnline social networks are not only huge in scale, they are predicted to keep growing in the coming years both in the number of users and in the amount of data users upload and share. There have been many efforts devoted to study privacy in social media and how to protect users' personal information since the very early days of social media. However, most of these efforts have focused on privacy from an individual point of view. Privacy is not just about what you say or disclose about yourself. It is also about what others say or disclose about you. In this video, Jose M. Such discusses "Multiparty Privacy in Social Media,” a Review Article in the August 2018 issue of Communications of the ACM.
ACM Queue’s “Research for Practice” is your number one resource for keeping up with emerging developments in the world of theory and applying them to the challenges you face on a daily basis. In this installment, Dan Crankshaw and Joey Gonzalez provide an overview of machine learning server systems. What happens when we wish to actually deploy a machine learning model to production, and how do we serve predictions with high accuracy and high computational efficiency? Dan and Joey’s curated research selection presents cutting-edge techniques spanning database-level integration, video processing, and prediction middleware. Given the explosion of interest in machine learning and its increasing impact on seemingly every application vertical, it's possible that systems such as these will become as commonplace as relational databases are today.
GET INVOLVED
Become an Ambassador for ACMEncourage your colleagues to join ACM, share the benefits of ACM and receive free gifts for participating. Your support of ACM is critical to our continuing efforts to advance computing as a science and a profession.
PREMIER RESOURCE
Bringing You the World’s Computing LiteratureThe most comprehensive collection of full-text articles and bibliographic records covering computing and information technology includes the complete collection of ACM's publications.
CAREER RESOURCE
Lifelong LearningACM offers lifelong learning resources including online books from Safari, online courses from Skillsoft, webinars on the hottest topics in computing and IT, and more.
The Association for Computing Machinery, a global scientific and educational organization representing the computing community, expresses concern over US President Donald J. Trump’s Executive Order imposing suspension of visas to nationals of six countries.
The open exchange of ideas and the freedom of thought and expression are central to the aims and goals of ACM. ACM supports the statute of International Council for Science in that the free and responsible practice of science is fundamental to scientific advancement and human and environmental well-being. Such practice, in all its aspects, requires freedom of movement, association, expression and communication for scientists. All individuals are entitled to participate in any ACM activity.


Buildings
Floor edit
Rooms
Paths
Edit
×
Getting started
Welcome to InnoMaps plugin!
Choose data you want to add or edit on navigation bar.


'Sarileru Neekevvaru': Teaser date unlocked - Telugu News - IndiaGlitz.com
The teaser for 'Sarileru Neekevvaru' is awaited like only a few teasers. The date is finally out. The much-awaited teaser will be unveiled on November 22. The exact time will be revealed later this week.
The makers have revealed the date in a first-of-its-kind manner in Tollywood. As the user hits on a tab on Twitter, the date gets unlocked, complete with a hashtag that comes ready-made automatically.
Directed by Anil Ravipudi, this Mahesh Babu comedy entertainer is a Sankranthi 2020 release. Vijayashanthi and Rashmika Mandanna are playing key roles.
Trending News
Wife kills hubby over a heated argument
Swami Nithyananda’s institute has kidnapped our daughters: Parents
NTR's fans troll 'Sye Raa' Surender Reddy
Mahesh Babu's director gets trolled badly
Update your WhatsApp to avoid hacking
Chiranjeevi has hidden a secret from his wife!
More News
'RRR': Ultimate good news for fans of NTR, Charan, Rajamouli
'Arjun Suravaram' Trailer: Finding a way out of a scam
Mega hero's 'Solo Bratuke So Better' locks its release date
Samantha gives a frustrated reply on pregnancy
I heard about George Reddy as Intermediate student: Chiranjeevi
Chiranjeevi has hidden a secret from his wife!

RGV announces 'Dadas Of Hyderabad'
Sumanth's film is titled 'Kapatadhaari'
George Reddy was anti-social: ABVP leader
'Raja Vaaru Rani Gaaru' Trailer: A village-based love story
Raj Madiraju's 'Sira' unveiled
Rajinikanth wraps up dubbing for 'Darbar'
Breaking! Srikanth Addala to direct Venky's next
Allu Arjun's 'whopping' demand makes news
Politicians were stunned by her ageless beauty: Chiranjeevi
Headlines
Wife kills hubby over a heated argument
Hyd: Man kills himself as wife refused to make tea
Swami Nithyananda’s institute has kidnapped our daughters: Parents
Update your WhatsApp to avoid hacking
Telugu realtor Lingamaneni Ramesh denies insolvency reports
BJP, other parties should learn from NCP, BJD: Modi
Tap water quality in Hyderabad is India's second best
Boy rapes cousin by tying up her hands & legs
Modi for 'One Nation, One Ration Card', & 'One Nation, One Pay Day'
#IWantMyMasjidBack trends on Twitter


Cartesian Products of Growth Groups#
See (Asymptotic) Growth Groups for a description.
AUTHORS:
Benjamin Hackl (2015)
Daniel Krenn (2015)
Clemens Heuberger (2016)
ACKNOWLEDGEMENT:
Benjamin Hackl, Clemens Heuberger and Daniel Krenn are supported by the Austrian Science Fund (FWF): P 24644-N26.
Benjamin Hackl is supported by the Google Summer of Code 2015.
Classes and Methods#
- class sage.rings.asymptotic.growth_group_cartesian.CartesianProductFactory#
Bases:
UniqueFactory
Create various types of Cartesian products depending on its input.
INPUT:
growth_groups
– a tuple (or other iterable) of growth groups.order
– (default:None
) if specified, then this order is taken for comparing two Cartesian product elements. Iforder
isNone
this is determined automatically.
Note
The Cartesian product of growth groups is again a growth group. In particular, the resulting structure is partially ordered.
The order on the product is determined as follows:
Cartesian factors with respect to the same variable are ordered lexicographically. This causes
GrowthGroup('x^ZZ * log(x)^ZZ')
andGrowthGroup('log(x)^ZZ * x^ZZ')
to produce two different growth groups.Factors over different variables are equipped with the product order (i.e. the comparison is component-wise).
Also, note that the sets of variables of the Cartesian factors have to be either equal or disjoint.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: A = GrowthGroup('x^ZZ'); A Growth Group x^ZZ sage: B = GrowthGroup('log(x)^ZZ'); B Growth Group log(x)^ZZ sage: C = cartesian_product([A, B]); C # indirect doctest Growth Group x^ZZ * log(x)^ZZ sage: C._le_ == C.le_lex True sage: D = GrowthGroup('y^ZZ'); D Growth Group y^ZZ sage: E = cartesian_product([A, D]); E # indirect doctest Growth Group x^ZZ * y^ZZ sage: E._le_ == E.le_product True sage: F = cartesian_product([C, D]); F # indirect doctest Growth Group x^ZZ * log(x)^ZZ * y^ZZ sage: F._le_ == F.le_product True sage: cartesian_product([A, E]); G # indirect doctest Traceback (most recent call last): ... ValueError: The growth groups (Growth Group x^ZZ, Growth Group x^ZZ * y^ZZ) need to have pairwise disjoint or equal variables. sage: cartesian_product([A, B, D]) # indirect doctest Growth Group x^ZZ * log(x)^ZZ * y^ZZ
- create_key_and_extra_args(growth_groups, category, **kwds)#
Given the arguments and keywords, create a key that uniquely determines this object.
- create_object(version, args, **kwds)#
Create an object from the given arguments.
- class sage.rings.asymptotic.growth_group_cartesian.GenericProduct(sets, category, **kwds)#
Bases:
CartesianProductPoset
,GenericGrowthGroup
A Cartesian product of growth groups.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: P = GrowthGroup('x^QQ') sage: L = GrowthGroup('log(x)^ZZ') sage: C = cartesian_product([P, L], order='lex'); C # indirect doctest Growth Group x^QQ * log(x)^ZZ sage: C.an_element() x^(1/2)*log(x)
sage: Px = GrowthGroup('x^QQ') sage: Lx = GrowthGroup('log(x)^ZZ') sage: Cx = cartesian_product([Px, Lx], order='lex') # indirect doctest sage: Py = GrowthGroup('y^QQ') sage: C = cartesian_product([Cx, Py], order='product'); C # indirect doctest Growth Group x^QQ * log(x)^ZZ * y^QQ sage: C.an_element() x^(1/2)*log(x)*y^(1/2)
See also
- CartesianProduct = <sage.rings.asymptotic.growth_group_cartesian.CartesianProductFactory object>#
- class Element#
Bases:
Element
- exp()#
The exponential of this element.
INPUT:
Nothing.
OUTPUT:
A growth element.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('x^ZZ * log(x)^ZZ * log(log(x))^ZZ') sage: x = G('x') sage: exp(log(x)) x sage: exp(log(log(x))) log(x)
sage: exp(x) Traceback (most recent call last): ... ArithmeticError: Cannot construct e^x in Growth Group x^ZZ * log(x)^ZZ * log(log(x))^ZZ > *previous* TypeError: unsupported operand parent(s) for *: 'Growth Group x^ZZ * log(x)^ZZ * log(log(x))^ZZ' and 'Growth Group (e^x)^ZZ'
- factors()#
Return the atomic factors of this growth element. An atomic factor cannot be split further and is not the identity (\(1\)).
INPUT:
Nothing.
OUTPUT:
A tuple of growth elements.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('x^ZZ * log(x)^ZZ * y^ZZ') sage: x, y = G.gens_monomial() sage: x.factors() (x,) sage: f = (x * y).factors(); f (x, y) sage: tuple(factor.parent() for factor in f) (Growth Group x^ZZ, Growth Group y^ZZ) sage: f = (x * log(x)).factors(); f (x, log(x)) sage: tuple(factor.parent() for factor in f) (Growth Group x^ZZ, Growth Group log(x)^ZZ)
sage: G = GrowthGroup('x^ZZ * log(x)^ZZ * log(log(x))^ZZ * y^QQ') sage: x, y = G.gens_monomial() sage: f = (x * log(x) * y).factors(); f (x, log(x), y) sage: tuple(factor.parent() for factor in f) (Growth Group x^ZZ, Growth Group log(x)^ZZ, Growth Group y^QQ)
sage: G.one().factors() ()
- is_lt_one()#
Return whether this element is less than \(1\).
INPUT:
Nothing.
OUTPUT:
A boolean.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('x^ZZ'); x = G(x) sage: (x^42).is_lt_one() # indirect doctest False sage: (x^(-42)).is_lt_one() # indirect doctest True
- log(base=None)#
Return the logarithm of this element.
INPUT:
base
– the base of the logarithm. IfNone
(default value) is used, the natural logarithm is taken.
OUTPUT:
A growth element.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('x^ZZ * log(x)^ZZ') sage: x, = G.gens_monomial() sage: log(x) # indirect doctest log(x) sage: log(x^5) # indirect doctest Traceback (most recent call last): ... ArithmeticError: When calculating log(x^5) a factor 5 != 1 appeared, which is not contained in Growth Group x^ZZ * log(x)^ZZ.
sage: G = GrowthGroup('(QQ_+)^x * x^ZZ') sage: x, = G.gens_monomial() sage: el = x.rpow(2); el 2^x sage: log(el) # indirect doctest Traceback (most recent call last): ... ArithmeticError: When calculating log(2^x) a factor log(2) != 1 appeared, which is not contained in Growth Group QQ^x * x^ZZ. sage: log(el, base=2) # indirect doctest x
sage: from sage.rings.asymptotic.growth_group import GenericGrowthGroup sage: x = GenericGrowthGroup(ZZ).an_element() sage: log(x) # indirect doctest Traceback (most recent call last): ... NotImplementedError: Cannot determine logarithmized factorization of GenericGrowthElement(1) in abstract base class.
sage: x = GrowthGroup('x^ZZ').an_element() sage: log(x) # indirect doctest Traceback (most recent call last): ... ArithmeticError: Cannot build log(x) since log(x) is not in Growth Group x^ZZ.
- log_factor(base=None, locals=None)#
Return the logarithm of the factorization of this element.
INPUT:
base
– the base of the logarithm. IfNone
(default value) is used, the natural logarithm is taken.locals
– a dictionary which may contain the following keys and values:'log'
– value: a function. If not used, then the usuallog
is taken.
OUTPUT:
A tuple of pairs, where the first entry is a growth element and the second a multiplicative coefficient.
ALGORITHM:
This function factors the given element and calculates the logarithm of each of these factors.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('(QQ_+)^x * x^ZZ * log(x)^ZZ * y^ZZ * log(y)^ZZ') sage: x, y = G.gens_monomial() sage: (x * y).log_factor() # indirect doctest ((log(x), 1), (log(y), 1)) sage: (x^123).log_factor() # indirect doctest ((log(x), 123),) sage: (G('2^x') * x^2).log_factor(base=2) # indirect doctest ((x, 1), (log(x), 2/log(2)))
sage: G(1).log_factor() ()
sage: log(x).log_factor() # indirect doctest Traceback (most recent call last): ... ArithmeticError: Cannot build log(log(x)) since log(log(x)) is not in Growth Group QQ^x * x^ZZ * log(x)^ZZ * y^ZZ * log(y)^ZZ.
- rpow(base)#
Calculate the power of
base
to this element.INPUT:
base
– an element.
OUTPUT:
A growth element.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('(QQ_+)^x * x^ZZ') sage: x = G('x') sage: x.rpow(2) # indirect doctest 2^x sage: x.rpow(1/2) # indirect doctest (1/2)^x
sage: x.rpow(0) # indirect doctest Traceback (most recent call last): ... ValueError: 0 is not an allowed base for calculating the power to x. sage: (x^2).rpow(2) # indirect doctest Traceback (most recent call last): ... ArithmeticError: Cannot construct 2^(x^2) in Growth Group QQ^x * x^ZZ > *previous* TypeError: unsupported operand parent(s) for *: 'Growth Group QQ^x * x^ZZ' and 'Growth Group ZZ^(x^2)'
sage: G = GrowthGroup('QQ^(x*log(x)) * x^ZZ * log(x)^ZZ') sage: x = G('x') sage: (x * log(x)).rpow(2) # indirect doctest 2^(x*log(x))
sage: n = GrowthGroup('(QQ_+)^n * n^QQ')('n') sage: n.rpow(2) 2^n sage: _.parent() Growth Group QQ^n * n^QQ
sage: n = GrowthGroup('QQ^n * n^QQ')('n') sage: n.rpow(-2) 2^n*(-1)^n
- variable_names()#
Return the names of the variables of this growth element.
OUTPUT:
A tuple of strings.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('QQ^m * m^QQ * log(n)^ZZ') sage: G('2^m * m^4 * log(n)').variable_names() ('m', 'n') sage: G('2^m * m^4').variable_names() ('m',) sage: G('log(n)').variable_names() ('n',) sage: G('m^3').variable_names() ('m',) sage: G('m^0').variable_names() ()
- cartesian_injection(factor, element)#
Inject the given element into this Cartesian product at the given factor.
INPUT:
factor
– a growth group (a factor of this Cartesian product).element
– an element offactor
.
OUTPUT:
An element of this Cartesian product.
- gens_monomial()#
Return a tuple containing monomial generators of this growth group.
INPUT:
Nothing.
OUTPUT:
A tuple containing elements of this growth group.
Note
This method calls the
gens_monomial()
method on the individual factors of this Cartesian product and concatenates the respective outputs.EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('x^ZZ * log(x)^ZZ * y^QQ * log(z)^ZZ') sage: G.gens_monomial() (x, y)
- some_elements()#
Return some elements of this Cartesian product of growth groups.
See
TestSuite
for a typical use case.OUTPUT:
An iterator.
EXAMPLES:
sage: from itertools import islice sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('(QQ_+)^y * x^QQ * log(x)^ZZ') sage: tuple(islice(G.some_elements(), 10r)) (x^(1/2)*(1/2)^y, x^(-1/2)*log(x)*2^y, x^2*log(x)^(-1), x^(-2)*log(x)^2*42^y, log(x)^(-2)*(2/3)^y, x*log(x)^3*(3/2)^y, x^(-1)*log(x)^(-3)*(4/5)^y, x^42*log(x)^4*(5/4)^y, x^(2/3)*log(x)^(-4)*(6/7)^y, x^(-2/3)*log(x)^5*(7/6)^y)
- variable_names()#
Return the names of the variables.
OUTPUT:
A tuple of strings.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: GrowthGroup('x^ZZ * log(x)^ZZ * y^QQ * log(z)^ZZ').variable_names() ('x', 'y', 'z')
- class sage.rings.asymptotic.growth_group_cartesian.MultivariateProduct(sets, category, **kwargs)#
Bases:
GenericProduct
A Cartesian product of growth groups with pairwise disjoint (or equal) variable sets.
Note
A multivariate product of growth groups is ordered by means of the product order, i.e. component-wise. This is motivated by the assumption that different variables are considered to be independent (e.g.
x^ZZ * y^ZZ
).See also
- CartesianProduct = <sage.rings.asymptotic.growth_group_cartesian.CartesianProductFactory object>#
- class sage.rings.asymptotic.growth_group_cartesian.UnivariateProduct(sets, category, **kwargs)#
Bases:
GenericProduct
A Cartesian product of growth groups with the same variables.
Note
A univariate product of growth groups is ordered lexicographically. This is motivated by the assumption that univariate growth groups can be ordered in a chain with respect to the growth they model (e.g.
x^ZZ * log(x)^ZZ
: polynomial growth dominates logarithmic growth).See also
- CartesianProduct = <sage.rings.asymptotic.growth_group_cartesian.CartesianProductFactory object>#


--- layout: post title: Speaking at Enterprise Search Summit in NY, May 2014 date: 2014-02-07 16:25:12.000000000 -06:00 type: post published: true status: publish categories: - Web Development tags: - Apache - Drupal - Search - Solr meta: _edit_last: '51126004' _publicize_pending: '1' _oembed_33f213d8450536a1deaaacd5e3a9a62d: '{{unknown}}' author: Nathan Ahlstrom ---
I will be presenting at the Enterprise Search Summit!
Just found out that they accepted my proposal; I will be talking about Drupal and Apache SOLR and how they play into a wider enterprise search strategy. I am very interested in the nuts and bolts, as you can see if you've read this blog, so my talk will get into some technical details.
Details:
Enterprise Search Summit, May 13-14 2014 in New York City.
http://www.enterprisesearchsummit.com/NY2014/
I have only been to NYC passing through on connecting flights before...anything that is a must see while I am there?


Setting up a new Typescript 1.9 and React project
Introduction
This post is a brain dump of the steps required to set up a Typescript and React project with some explanatory notes – I intend to write about working with Typescript and React in a real world project in more detail soon. Some knowledge of React and of the basics of Typescript is assumed.
These instructions will guide you through setting up a new project with Typescript, React, Webpack and Babel – neither Webpack nor Babel are required to work with Typescript, as Typescript can transpile ES6 to ES5 and do some degree of bundling itself; but using them enables Hot Module Reloading, and also allows you to run other Babel and Webpack plugins on the compiled output if desired.
The resulting project template is available on Github at https://github.com/tomduncalf/typescript-react-template.
Editor setup
Atom
Atom users will need to install the atom-typescript
plugin, which is excellent, but currently doesn’t support some of the features in Typescript 1.9, and seems to be lacking an active project leader.
Sublime
Sublime users will need the official Microsoft Typescript
package (https://github.com/Microsoft/TypeScript-Sublime-Plugin), which is also very good.
Visual Studio Code
Visual Studio Code users don’t need to install anything – it’s already set up for Typescript.
Recommendation
All of these editor/plugin combinations work well, and will automatically detect Typescript projects and offer the appropriate autocompletion and error highlighting.
Visual Studio Code has the best Typescript integration (as you might expect from Microsoft!) and is noticeably faster than Atom. In the past, I was put off using VS Code due to the lack of tabs, but as these are now available in the latest Insiders build by enabling a flag, it’s now my recommended editor.
The Atom and Sublime plugins offer broadly similar functionality, and I have always used Atom in the past, but I can’t fully recommend it at the minute due to the uncertain status of the atom-typescript
plugin and its lack of support for Typescript 1.9 features (although this is fair enough, as it is still a beta). The Sublime plugin is an official Microsoft product, so shouldn’t suffer from the same issues, and is a great choice if you are already a Sublime user.
Note: If you are using Visual Studio Code, see step 1 for additional setup required to make it use the typescript@next
compiler.
Linting
If you want to lint your code, you’ll want to install a tslint
plugin for your editor and setup tslint
– see the project page at https://github.com/palantir/tslint/ for more information.
Basic project setup
Install Typescript globally - this is optional, but it’s handy to have the Typescript compiler
tsc
available globally at the command line. We will usetypescript@next
(version 1.9.x) even though it is still in beta, as it supports installing type declarations fromnpm
rather than having to use thetypings
tool, which is the future of working with type declaration files and makes life much easier.npm install -g typescript@next
Note for VS Code users
If you are using VS Code, you need to tell it to use the Typescript compiler that you installed with
npm
, otherwise you’ll get syntax errors as the internal VS Code Typescript compiler is v1.8 and so doesn’t support type declarations installed fromnpm
.To do so, you’ll need to know where
npm
has installed your global packages to – you can check this with:npm list -g | head -n1
Then open up your user settings in VS Code (
Cmd
+,
on a Mac) and add a line to your user settings, pointing thetypescript.tsdk
option to thenode_modules/typescript/lib
directory in this location – for example, if the global packages are installed to/Users/td/.nvm/versions/node/v5.5.0/lib/
, then add the following and restart Code:{ "typescript.tsdk": "/Users/td/.nvm/versions/node/v5.5.0/lib/node_modules/typescript/lib" }
Create a new project:
mkdir my-project && cd my-project git init npm init -y
Initialise the project for Typescript - install Typescript as a dev dependency and create a skeleton
tsconfig.json
:npm i -D typescript@next tsc --init
Setting up tsconfig.json
tsconfig.json
controls the behaviour of the Typescript compiler (tsc
). There are a few settings which are useful for React and Babel projects which differ from the defaults. Opentsconfig.json
and change it to the following:{ "compilerOptions": { "module": "es6", "target": "es6", "moduleResolution": "node", "baseUrl": "src", "allowSyntheticDefaultImports": true, "noImplicitAny": false, "sourceMap": true, "outDir": "ts-build", "jsx": "preserve" }, "exclude": [ "node_modules" ] }
An explanation of what this all means:
"module": "es6"
tellstsc
to output code which uses the ES6 module spec (i.e.import
statements). It’s also possible to set this to e.g.commonjs
, in which casetsc
will convert your code to that module spec, but as we will be putting our compiled JS code through Webpack, we can keep it as ES6 and let Webpack handle the module bundling."target": "es6"
tellstsc
to output ES6 rather than ES5 Javascript code. We want this as we will be running the compiled JS through Babel, and keeping ES6 code intact after compilation can be useful for some Babel plugins (e.g.transform-react-stateless-component-name
, which automatically names stateless components, will only pick up on arrow functions).This also allows us to use
async
/await
, which is understood by Typescript but not currently able to be transpiled – instead, we can use Babel to handle the transpilation ofasync
code. If we weren’t using Babel, this setting could be omitted or set toes5
, to maketsc
do the transpilation of ES6 to ES5 itself."moduleResolution": "node"
tellstsc
to use the Node module resolution strategy. This allows Typescript to load type declarations supplied alongsidenpm
packages (e.g. MobX includes its own type declarations in the mainmobx
package), and with thebaseUrl
option, allows us to use absolute-style imports for local modules."baseUrl": "src"
tellstsc
to look insrc
for any modules we import that aren’t found innode_modules
. This allows us to write absolute-style imports for local modules, e.g.import Whatever from 'components/Whatever'
rather thanimport Whatever from '../components/Whatever'
, which is great for one’s sanity.Note that this settings does not work with the current version of
atom-typescript
(see https://github.com/TypeStrong/atom-typescript/pull/849) – remove this line from yourtsconfig.json
if you want to use Atom. You can get an approximation of the absolute-style import by using"moduleResolution": "classic"
(which will walk up the directory tree until a match is found, so not the same behaviour, but similar end result in many cases), but this breaks the ability to automatically import type declarations supplied withnpm
packages."allowSyntheticDefaultImports": true
allows us to use ES6import
syntax fornpm
modules which don’t have a default export."noImplicitAny": false
tellstsc
not to warn us if any variables are inferred as having a type ofany
. It’s actually probably good practice to set this totrue
, but it does mean you’ll potentially have to be more liberal with type annotations."sourceMap": true
tellstsc
to output a source map, which enables easier debugging from the browser as it can tell you where in the original.ts
source file an error occurred, rather than just in the compiled.js
."outDir": "ts-build"
tellstsc
to output the compiled.js
files to a directory calledts-build
(which can be.gitignore
d). The default is to output them alongside the original.ts
source files, but this gets messy. It should be noted that most of the time, we won’t be outputting the compiled.js
to disk, as the Webpack loader will do the compilation in memory, but it is sometimes useful to be able to invoketsc
manually and inspect the compiled output."jsx": "preserve"
tellstsc
to leave JSX code as it is, meaning that something else (in this case, Babel) is responsible for compiling it down toReact.createElement
function calls. It is possible to set this to"react"
instead, which will causetsc
to outputReact.createElement
calls directly, but it can be useful to have the raw JSX available to Babel, e.g. for plugins to process.We
exclude
node_modules
as we don’t wanttsc
to try and compile anything it finds in there – it’s alternatively possible to explicitlyinclude
files for compilation (or use the non-standardfilesGlob
option, which allows you to specify wildcard patterns, supported by the Atom plugin and https://github.com/TypeStrong/tsconfig)
Adding React to the project
Install React to
node_modules
:npm i -S react
To demonstrate what we are about to do,
mkdir src
and create a fileindex.tsx
in there containing a basic (stateless) React component:import * as React from 'react'; export default () =>
Hello world
;
If your editor is set up correctly, you should already see that it has highlighted an issue with the
import * as React from 'react';
line, but to demonstrate further, runtsc
from your project root and you should get the following output:src/index.tsx(1,24): error TS2307: Cannot find module 'react'.
The issue here is that the Typescript type declarations for React aren’t installed, and so Typescript says it can’t find the module, as type declarations are required for any modules that are
import
ed (the error message doesn’t make this especially clear!).Something interesting to note, however, is that
tsc
has created ats-build
directory and writtenindex.jsx
there, with sensible contents – in general, the Typescript compiler will try and emit code even if there are errors, as long as they aren’t fatal (although this can be disabled intsconfig.json
with thenoEmitOnError
option).Before installing type declarations for React, we first need to check if they exist – the majority of type declaration files are created by the community rather than the library authors, but most popular libraries are covered.
The type declaration system has been through several iterations of tooling (first
tsd
, thentypings
) but is now moving to be purelynpm
based. The original definitions live in the massive DefinitelyTyped Github repo, and are automatically synced tonpm
.It seems that the only way to check if a package has type declarations in
npm
is to search at http://microsoft.github.io/TypeSearch/ – type inreact
, and indeed it does have a definition, hosted onnpm
at<EMAIL_ADDRESS>iterations of the typing system had the ability to search from the command line, which is preferable in most cases, so hopefully someone will fill this gap for
npm
-based type declarations – for now, you could installtypings
(https://github.com/typings/typings) and use that to search DefinitelyTyped, or just use Google/GitHub/npm search.Now we know the React type declarations exist at
@types/react
, we can install them withnpm
:npm i -D @types/react
And now both
tsc
and your editor should be happy with the React import. At this point, you should also be able to get a sense for the autocompletion Typescript enables, by typingReact.
somewhere in yourindex.tsx
file and seeing the autocomplete dropdown with the correct options.We also need the
react-dom
package, which can be installed in the same way:npm i -S react-dom npm i -D @types/react-dom
To my mind, it makes sense for type declarations to be in
devDependencies
(sonpm -D
rather thannpm -S
). Also note that the structure of the type declaration package name is always@types/<npm_package_name>
, so you could take advantage of this naming scheme and try installing types for a given package based on its name rather than using the search in most cases.One other thing worth noting is that the current version of the React typings is
0.14
whereas we are using React0.15
– this is one downside of type declarations being maintained by the community, but in most cases it doesn’t present too much of a problem (as long as the API hasn’t changed much). It is of course possible to put in a PR to DefinitelyTyped to fix the type defs if they are out of sync (or to augment them with local type declaration “overrides”, or in extreme cases, to import the module without any typings – more on that later).
Setting up Webpack and Babel
As mentioned above, we’re using Babel to transpile to ES6 output from Typescript so we can take advantage of the Babel plugin ecosystem, and Webpack as our module bundler; so we need to setup Webpack to invoke the Typescript loader and then pass the output to Babel. I won’t go into too much detail on the Webpack setup as it’s a huge topic in itself!
Install Webpack itself, and the handy notifier plugin which will notify you of the build status with your system notifier (especially useful with Typescript as the code will be compiled every time you save a file, so this surfaces compile errors much quicker than watching the terminal):
npm i -D webpack webpack-notifier
Install the Webpack Typescript loader, so Webpack can handle compiling Typescript as part of the bundling process:
npm i -D ts-loader
Install Babel itself, the Babel Webpack loader, and a few presets so it can understand the ES6 and JSX code that the Typescript compiler will output (I’m not sure if
stage-0
is strictly necessary,stage-3
might be enough forasync
/await
support):npm i -D babel-core babel-loader babel-preset-es2015 babel-preset-react babel-preset-stage-0
Create a
.babelrc
file in the project root to tell Babel to use the presets we just installed:{ "presets": ["es2015", "react", "stage-0"] }
Create a Webpack config in
config/webpack.config.js
to tell Webpack how to build and bundle the project. I’ve added comments explaining what is going on inline:var webpack = require('webpack'); var path = require('path'); var WebpackNotifierPlugin = require('webpack-notifier'); module.exports = { devtool: 'eval', // This will be our app's entry point (webpack will look for it in the 'src' directory due to the modulesDirectory setting below). Feel free to change as desired. entry: [ 'index.tsx' ], // Output the bundled JS to dist/app.js output: { filename: 'app.js', path: path.resolve('dist') }, resolve: { // Look for modules in .ts(x) files first, then .js(x) extensions: ['', '.ts', '.tsx', '.js', '.jsx'], // Add 'src' to our modulesDirectories, as all our app code will live in there, so Webpack should look in there for modules modulesDirectories: ['src', 'node_modules'], }, module: { loaders: [ // .ts(x) files should first pass through the Typescript loader, and then through babel { test: /\.tsx?$/, loaders: ['babel', 'ts-loader'] } ] }, plugins: [ // Set up the notifier plugin - you can remove this (or set alwaysNotify false) if desired new WebpackNotifierPlugin({ alwaysNotify: true }), ] };
Add a script to invoke Webpack when you run
npm run build
to yourpackage.json
:"scripts": { "build": "webpack --config config/webpack.config.js" },
You should now be able to build the project with Webpack:
npm run build
and see that it has created an output file at
dist/app.js
(you probably want togitignore
thedist
directory).
Adding hot module reloading
Nearly there! All that remains is to add hot module reloading to the project. In reality, this is completely optional, but I find it invaluable for working on a React project, so would consider it part of any project’s setup. It’s also not really Typescript-specific, but there aren’t many good guides out there for setting up the latest version of HMR, and setting it up gives us a chance to see a couple more tips on working with Typescript.
Create an
index.html
file which will load the bundled JS and give React somewhere to mount the application to. Create the file in the project root with the following contents:<!DOCTYPE html>   <meta charset="UTF-8"> <title>My Typescript App</title>

Next, install the
react-hot-loader
npm
package. We are using the latest 3.0.0 beta version, as it supports stateless functional components.npm i -D<EMAIL_ADDRESS>Add the
react-hot-loader
plugin to.babelrc
, so it now contains:{ "presets": ["es2015", "react", "stage-0"], "plugins": ["react-hot-loader/babel"] }
Install the
webpack-dev-server
npm
package, to allow us to setup a dev server to work with the hot module reloading:npm i -D webpack-dev-server
Create the dev server in a new file in your project root,
server.js
, with the following contents (based on https://github.com/gaearon/react-hot-boilerplate/blob/next/server.js):var webpack = require('webpack'); var WebpackDevServer = require('webpack-dev-server'); var config = require('./config/webpack.config'); new WebpackDevServer(webpack(config), { publicPath: config.output.publicPath, hot: true, historyApiFallback: true }).listen(3000, 'localhost', function (err, result) { if (err) { return console.log(err); } console.log('Listening at http://localhost:3000/'); });
Modify
config/webpack.config.js
to enable Webpack support for hot module reloading, so it now contains the following (explanatory comments inline):var webpack = require('webpack'); var path = require('path'); var WebpackNotifierPlugin = require('webpack-notifier'); module.exports = { devtool: 'eval', entry: [ // Add the react hot loader entry point - in reality, you only want this in your dev Webpack config 'react-hot-loader/patch', 'webpack-dev-server/client?http://localhost:3000', 'webpack/hot/only-dev-server', 'index.tsx' ], output: { filename: 'app.js', publicPath: '/dist', path: path.resolve('dist') }, resolve: { extensions: ['', '.ts', '.tsx', '.js', '.jsx'], modulesDirectories: ['src', 'node_modules'], }, module: { loaders: [ { test: /\.tsx?$/, loaders: ['babel', 'ts-loader'] } ] }, plugins: [ // Add the Webpack HMR plugin so it will notify the browser when the app code changes new webpack.HotModuleReplacementPlugin(), new WebpackNotifierPlugin({ alwaysNotify: true }), ] };
Add a script to start the dev server with
npm start
to yourpackage.json
:"scripts": { "build": "webpack --config config/webpack.config.js", "start": "node server.js" },
Finally, we need to create a skeleton app set up in a suitable way for hot module reloading.
Our entry point needs to be set up so that it can handle requests to hot reload the app. Open up
src/index.tsx
and change it to the following (explanatory comments inline):// Import React and React DOM import * as React from 'react'; import { render } from 'react-dom'; // Import the Hot Module Reloading App Container – more on why we use 'require' below const { AppContainer } = require('react-hot-loader'); // Import our App container (which we will create in the next step) import App from 'containers/App'; // Tell Typescript that there is a global variable called module - see below declare var module: { hot: any }; // Get the root element from the HTML const rootEl = document.getElementById('app'); // And render our App into it, inside the HMR App ontainer which handles the hot reloading render( <AppContainer> <App /> </AppContainer>, rootEl ); // Handle hot reloading requests from Webpack if (module.hot) { module.hot.accept('./containers/App', () => { // If we receive a HMR request for our App container, then reload it using require (we can't do this dynamically with import) const NextApp = require('./containers/App').default; // And render it into the root element again render( <AppContainer> <NextApp /> </AppContainer>, rootEl ); }) }
Effectively, this renders our app inside a special container (the
react-hot-loader
AppContainer
), and then waits for Webpack to notify it of any changes to any of the app’s files (which will trigger HMR requests, which end up bubbling up to the top level parent module,containers/App
). When a change is detected, the wholeApp
container is reloaded and the existing instance of it in the DOM is replaced with the new, modified one.The trick here is that the
react-hot-loader
AppContainer
takes care of persisting the state of components (whether local state or in Redux or similar) when it is reloaded, so in most cases, we don’t lose where we were in the app.A quick note on a couple of things:
Importing modules without type declarations
const { AppContainer } = require('react-hot-loader');
Here, we are using
require
rather thanimport
. This is a useful trick to know, as it allows you to import annpm
module without requiring any type declarations.In this case, there are currently no type declarations for
react-hot-loader
, but if we userequire
, it is treated as being ofany
type. This can be handy for working with modules that don’t have type declarations, particularly if you are just trying out modules to see if they are suitable and don’t want worry about typing them.If you use
const Whatever = require('whatever');
rather thanimport Whatever from 'whatever';
, Typescript won’t complain aboutCannot find module
— although it also won’t offer you any type safety when working with this module!See the next step for an important note on this – by default, Typescript doesn’t know what
require
means (as it’s not a built-in Javascript construct).Declaring global variables
declare var module: { hot: any };
declare
is how we can tell Typescript about global variables that it doesn’t already know about. Here, we are telling it that a global variable calledmodule
will exist, and it’s type will be an object, which has a key calledhot
, who’s value is of typeany
(which means it will not be type-checked – a bit of a cop out, and generallyany
types should be avoided, but this is okay for our purposes here).If you run
tsc
at this point, you’ll get an error:src/index.tsx(5,26): error TS2304: Cannot find name 'require'.
This is because Typescript doesn’t know what
require
means. There are a few ways round this, for example installing thenode
orrequirejs
type declarations, but the one recommended at https://github.com/TypeStrong/ts-loader#loading-other-resources-and-code-splitting which plays nicely with CSS modules is to create your own declaration forrequire
— this also gives me the opportunity to demonstrate how we can create our own local type declarations for libraries!It’s up to you where you would like to keep your local type declarations, but I would suggest a top-level directory named
type-declarations
. If you are using the defaultexclude
pattern fortsconfig.json
, any*.ts
files in your entire project except those innode_modules
will automatically be included in the compilation, so we don’t need to explicitly tell Typescript where we have put the declarations.A type declaration file has the extension
.d.ts
, and can declare types either globally or inside a named module scope (which is how most third party library definitions are written, so the types only come into scope when the module is imported). Details of how type declarations work is beyond the scope of this guide, but for now create a file namedrequire.d.ts
in a directory calledtype-declarations
in the project root with the following contents:declare var require: { (path: string): any; <T>(path: string): T; (paths: string[], callback: (...modules: any[]) => void): void; ensure: (paths: string[], callback: (require: <T>(path: string) => T) => void) => void; };
Run
tsc
again, and the warning should be gone (with just one aboutcontainers/App
being missing remaining) – we’ve told Typescript that callingrequire
with a single string argument will return a variable of typeany
.This technique of creating local type declarations can also be useful if a libraries’ declarations are out of date or inaccurate – you can add exported variables or additional properties to existing interfaces like so (although really it’s best to submit these changes back to DefinitelyTyped if time allows):
declare module "redux-form" { export var change: any export interface ReduxFormConfig { alwaysAsyncValidate?: boolean } }
The final step: we need to create our actual
App
container component. We’ll just create a placeholder for now, but in reality this would be the root component of your app (e.g. where your<Router>
lives).Create a new directory,
src/containers
, and create a new file in there,App.tsx
, with the following contents:import * as React from 'react' export default () =>
Hello world

Now you should be able to start your dev server:
npm start
and go to http://<IP_ADDRESS>:3000 to see the “Hello World” message! Update the
App.tsx
file to say something else, and you should see the app hot reload.
Next steps
That’s basically it in terms of project setup. As mentioned at the start, the complete template is available at https://github.com/tomduncalf/typescript-react-template – I think it’s helpful to go through each step and understand why it is required the first time, but in future, you can use the template you’ve created as a starting point for new projects.
In terms of next steps, it’s really just a case of building your app as usual, but taking advantage of Typescript’s type checking and editor integration. The only real pain point is likely to be working with type declarations for third party libraries, but using npm
for the typings has made this easier, and there is always the option to import the library using require
and bypassing the need for type declarations initially.
I intend to write more about working with Typescript and React soon, but hopefully this is a useful start – any questions, comments or feedback is very welcome either via the comments, or via Twitter or email.


With Review Hotmouse, use mouse shortcuts to review easily and quickly.
For example, Scroll down to show answer, scroll up to answer 'again'.
How to use
By default, the hotmouses are configured as below.
You can customize the hotkey and their actions in the add-on config.
The shortcuts will only work while reviewing cards.
right click: undo
scroll down (front): show answer
scroll up (back): again
scroll down (back): good
middle button + scroll up (back): hard
middle button + scroll down (back): easy
left click + right click (left click first): disable hotkey
How It Works & Customizing Hotkeys
A hotkey is comprised of mouse press and mouse wheel events.
When you press a mouse button, the add-on searches for a hotkey where all the buttons you pressed beforehand are
written as 'press [button name]' and the last button you pressed as 'click [button name]'.
The same thing happens when you scroll: it searches for a hotkey where all the buttons that are being pressed
are written as 'press [button name]' and the scroll direction as 'wheel [direction]'.
If such hotkey exists, its corresponding action is executed.
Notes
If you have many long cards that require scrolling, having scroll hotkeys will not let you scroll your card
unless you turn off the add-on. (Left click + Right click by default)
You will not be able to access the context menu while reviewing unless you turn off the add-on.
Additional Links
Ankiweb - Github - Report an issue - License
This addon was created by Bluegreenmagick, and is licensed under the MIT License.


There's a map behind this card showing points of interest for the wedding! You can hide this card by clicking the icon on the top right. (Click to get the card back after hiding it.)
You're invited to join us for a pre-wedding party!
Meet us in the Gatehouse Sitting Area (near the lobby) at Residence Inn Capital View for dinner and drinks.
All wedding day events will take place at locations along Crystal Drive in Crystal City, VA. There is ample public parking in underground garages all along Crystal Drive.
Join us at Crystal City Water Park for acoustic guitar music before the ceremony.
Wedding ceremony at Crystal City Water Park!
Reception at the Crystal City Jaleo. We'll be gathering in the blue event room in the back of the restaurant.
Reception continues (for people who haven't had enough to drink yet) at Jaleo's bar. We'll migrate from the event room and take it over.
Our first day of married life! Thanks for being a part of our day, and we wish you safe travels home!


A week or two back, [Lisa Dabbs](http://www.twitter.com/teachwithsoul), known for starting and moderating [#ntchat](http://www.twitter.com/hashtag/ntchat) wrote a post (a second post, actually) on [why new teachers should use Periscope with their students](http://www.lisadabbs.com/2016/new-teachers-are-you-using-periscope-ntchat).
There are some concerns with the Periscope terms of service and privacy policy that come up when the teacher is broadcasting students across the app. I posted a comment on Lisa’s blog, but after some tweets and awaiting moderation, it isn’t live, so I’m posting it here because the discussion is valuable. I hope Lisa and others are willing to comment on some of the points below.
Hi Lisa,
I want to push back on the idea that new teachers should jump into using Periscope. Yes, it’s important to share and get feedback and it can be a great way to do that. But jumping right in and sharing _student_ images and _student_ information without at least mentioning the Terms of Use and Privacy Statements is, in my opinion, dangerous.
From the Periscope Privacy Statement (my emphasis added):
We use and store information about your location to provide features of our Services, such as broadcasting with your location, and to improve and customize the Services. We may infer your location based on information from your device. If you have turned on location services for Periscope, we may share your precise location.
There is no limitation on how long they store that information. If a new teacher is broadcasting and a student with limitations from their parents is included in that broadcast, that can lead to serious issues. Broadcasting specific location data is never a wise idea, especially when minors are involved.
From the TOS:
You agree that this license includes the right for Twitter, Inc. to provide, promote, and improve Periscope and to make Content submitted to or through Periscope available to other companies, organizations or individuals who partner with Twitter, Inc. for the syndication, broadcast, distribution or publication of such Content on other media and services, subject to our terms and conditions for such Content use.
Often, this licensing is so Periscope can rebroadcast your content, much like other services ask for the same permission to share materials you create on a wide basis and not case by case. But, this can also include use in advertisements, promotional materials, etc. Again, broadcasting the images of students and having a company with their own profit in mind with no control over how or why those images are stored perpetually can lead to liability problems at some point.
You are responsible for your use of Periscope, for any Content you provide, and for any consequences thereof, including the use of your Content by other users and our third party partners.
In other words, “If someone misuses your content, it’s your fault for posting it.”
The teacher is responsible _in loco parentis_. We are representatives of the school district. _Any_ liability the teacher takes on using _any_ application can come back to the district. This is an express agreement that is glossed over in most cases. Periscope, because of its public nature, brings a unique challenge.
All I’m saying is that [twice now](http://www.lisadabbs.com/2015/new-teachers-lets-get-started-using-periscope-ntchat) you have implored new teachers to jump into a service with no mention of repercussions that could come from tacit use. You have a great amount of influence and a lot of people look to you for guidance. Please consider taking explicit steps with these recommendations to outline Privacy and Terms of Use considerations for apps and programs. Especially for new teachers. They have enough to worry about already.
As always, comments are open.
Written on July 20th, 2016 by Brian Bennett Categorized in: Technology
Leave a comment


Class: Rack::Utils::Context
| Relationships & Source Files | |
| Inherits: | Object |
| Defined in: | lib/rack/utils.rb |
Overview
Context
allows the use of a compatible middleware at different points in a request handling stack. A compatible middleware must define #context which should take the arguments env and app. The first of which would be the request environment. The second of which would be the rack application that the request would be forwarded to.
Class Method Summary
- .call(env) mod_func
- .context(env, app = @app) mod_func
- .initialize(app_f, app_r) mod_func
- .recontext(app) mod_func
- .new(app_f, app_r) constructor private
Constructor Details
.new(app_f, app_r) (private)
[ GitHub ]# File 'lib/rack/utils.rb', line 450
def initialize(app_f, app_r) raise 'running context does not respond to #context' unless app_f.respond_to? :context @for, @app = app_f, app_r end
Class Method Details
.call(env) (mod_func)
[ GitHub ]# File 'lib/rack/utils.rb', line 455
def call(env) @for.context(env, @app) end
.context(env, app = @app) (mod_func)
[ GitHub ].initialize(app_f, app_r) (mod_func)
[ GitHub ]# File 'lib/rack/utils.rb', line 450
def initialize(app_f, app_r) raise 'running context does not respond to #context' unless app_f.respond_to? :context @for, @app = app_f, app_r end
.recontext(app) (mod_func)
[ GitHub ]# File 'lib/rack/utils.rb', line 459
def recontext(app) self.class.new(@for, app) end


{% blocktrans %}
Someone of you has heard something about an outdoor game like ‘Capture the Flag’ and someone hasn't yet.
In couple of words, I want bring closer this topic. It will be based on the idea that two opposing teams
(e.g. red and blue) compete each other. Main objective is to capture other team's flag and bring it back
to own base. I think it's a good idea that we can bring it to another level and introduce it to virtual world,
while players would still move in the real world. All players will be exploring the whole city (it doesn't
matter what kind of city it is) with mobile phones in their hands trying to locate other team's base
and steal the flag.
In BLStream we work together on this project as a guild team. It’s an open guild, not only for Python freaks
(as we are ;-), but it is an across platform community with one
common purpose - ‘Capture the Flag’ as an urban game for mobile phones. It’s an open source project and all
source code you can find on GitHub and everyone can join us (including people from outside the company).
So if you want to join and start your adventure with Python, mobile phones and urban games
please contact with Michał Krawczak.
{% endblocktrans %}


Button Wars
Log In
Button Wars
Compete with other users to pick the best button.
Blue Button
Clicks:
0
Orange Button
Clicks:
0


To use correctly the example you have to generate a new token and replace it. For example, you can use this script.