Billing
require "not_activerecord"
require "dependor/shorty"
#removed configuration options for clarity
create_table :school_billing_licenses, id: false do |t|
t.string :id
t.integer :school_id
t.integer :pupil_id
t.datetime :activated_at
t.string :native_language
t.string :learning_language
t.string :school_year_id
t.datetime :deactivated_at
end
create_table :school_billing_subscriptions, id: false do |t|
t.string :id
t.integer :school_id
t.string :native_language
t.string :learning_language
t.string :school_year_id
t.integer :bought_licenses
t.integer :used_licenses
t.decimal :price
end
create_table :school_billing_purchases, id: false do |t|
t.string :id
t.integer :school_id
t.string :native_language
t.string :learning_language
t.string :school_year_id
t.integer :bought_licenses
t.decimal :price
t.datetime :purchased_at
end
class Billing < ActiveRecord::Base
class Subscription < ActiveRecord::Base
include SchoolYearSerializer
extend NotActiveRecord
does_not_belong_to :school
def dictionary_name
s_("School|lang_" + learning_language)
end
def overused?
used_licenses > bought_licenses
end
def cancelable?
bought_licenses.nonzero?
end
end
class License < ActiveRecord::Base
include SchoolYearSerializer
extend NotActiveRecord
does_not_belong_to :school
does_not_belong_to :pupil
end
class Purchase < ActiveRecord::Base
include SchoolYearSerializer
extend NotActiveRecord
does_not_belong_to :school
end
class SubscriptionPriceCalculator
takes :school_year, :bought_licenses, :now
def price
raise ArgumentError if months_to_pay >= 13
raise ArgumentError if months_to_pay <= 0
price = price_per_license * bought_licenses * BigDecimal.new(months_to_pay) / BigDecimal.new(12)
price.round(2, BigDecimal::ROUND_HALF_UP)
end
private
def months_to_pay
if now < school_year.starts_at
12
else
(school_year.ends_at.year * 12 + school_year.ends_at.month) - (now.year * 12 + now.month) + 1
end
end
def price_per_license
BigDecimal.new("2.5")
end
end
self.table_name = "schools"
has_many :subscriptions, class_name: "::School::Billing::Subscription", foreign_key: "school_id", autosave: true
has_many :licenses, class_name: "::School::Billing::License", foreign_key: "school_id", autosave: true
has_many :purchases, class_name: "::School::Billing::Purchase", foreign_key: "school_id", autosave: true
def used_licenses(pupil_ids, native_language, learning_languages, school_year, at_time)
pupil_ids = Array.wrap(pupil_ids)
Array.wrap(learning_languages).each do |learning_language|
s = subscription_for(native_language, learning_language, school_year)
s.used_licenses += pupil_ids.size
pupil_ids.each do |pupil_id|
licenses.build do |l|
l.id = SecureRandom.uuid
l.pupil_id = pupil_id
l.activated_at = at_time
l.native_language = native_language
l.learning_language = learning_language
l.school_year = school_year
end
end
end
end
def terminated_licenses(pupil_ids, native_language, learning_languages, school_year, at_time)
pupil_ids = Array.wrap(pupil_ids)
Array.wrap(learning_languages).each do |learning_language|
s = subscription_for(native_language, learning_language, school_year)
s.used_licenses -= pupil_ids.size
pupil_ids.each do |pupil_id|
license = licenses.find do |l|
l.pupil_id == pupil_id &&
l.native_language == native_language &&
l.learning_language == learning_language &&
l.school_year == school_year &&
l.deactivated_at.nil?
end
license.deactivated_at = at_time
end
end
end
def subscriptions_for(native_language, learning_languages, school_years)
Array.wrap(learning_languages).map do |ll|
Array.wrap(school_years).map do |sy|
subscriptions.find do |s|
s.native_language == native_language &&
s.learning_language == ll &&
s.school_year == sy
end || subscriptions.build do |s|
s.id = SecureRandom.uuid
s.native_language = native_language
s.learning_language = ll
s.school_year = sy
s.used_licenses = 0
s.bought_licenses = 0
s.price = 0
end
end
end.flatten
end
def subscription_for(native_language, learning_language, school_year)
subscriptions_for(native_language, learning_language, school_year).first
end
PurchasingNotEnoughLicenses = Class.new(StandardError)
def buy_subscription(native_language, learning_language, school_year, bought_licenses, at)
s = subscription_for(native_language, learning_language, school_year)
raise PurchasingNotEnoughLicenses if s.bought_licenses + bought_licenses < 40
price = SubscriptionPriceCalculator.new(school_year, bought_licenses, at).price
purchase = purchases.build do |p|
p.id = SecureRandom.uuid
p.native_language = native_language
p.learning_language = learning_language
p.school_year = school_year
p.bought_licenses = bought_licenses
p.price = price
p.purchased_at = at
end
s.bought_licenses += purchase.bought_licenses
s.price += purchase.price
s
end
def cancel_subscription(native_language, learning_language, school_year, at)
s = subscription_for(native_language, learning_language, school_year)
purchases.build do |p|
p.id = SecureRandom.uuid
p.native_language = native_language
p.learning_language = learning_language
p.school_year = school_year
p.bought_licenses = -s.bought_licenses
p.price = s.price * BigDecimal.new(-1)
p.purchased_at = at
end
s = subscription_for(native_language, learning_language, school_year)
s.bought_licenses = 0
s.price = 0
s
end
# some domain methods removed
end


Required Files
- cases/helper
- models/developer
- models/project
- models/company
- models/customer
- models/order
- models/categorization
- models/category
- models/post
- models/author
- models/tag
- models/tagging
- models/parrot
- models/person
- models/pirate
- models/treasure
- models/price_estimate
- models/club
- models/member
- models/membership
- models/sponsor
- models/country
- models/treaty
- models/vertex
- models/publisher
- models/publisher/article
- models/publisher/magazine
- active_support/core_ext/string/conversions
Namespace
- MODULE ActiveRecord
- CLASS DeveloperForProjectWithAfterCreateHook
- CLASS DeveloperWithSymbolsForKeys
- CLASS HasAndBelongsToManyAssociationsTest
- CLASS ProjectWithAfterCreateHook
- CLASS ProjectWithSymbolsForKeys
- CLASS SubDeveloper


Past Tense
Present Tense
1)
brought
1)
catch
2)
slept
2)
float
3)
clapped
3)
imagine
4)
forgot
4)
drop
5)
gathered
5)
begin
6)
continued
6)
drink


|
MindScape
1.0
MindScape é um jogo plataforma com elementos de terror e suspense. Como o jogo se situa na mente da protagonista, há monstros surreais que são criados com base em seus medos.
|
#include <hitbox.hpp>
Public Member Functions | |
| Hitbox (std::string name, std::pair< int, int > go_coordinates, std::pair< int, int > displacement, std::pair< int, int > dimensions, SDL_Renderer *p_render, bool active=true, int priority=5) | |
| std::pair< int, int > | get_dimensions () |
| This method return the width and height of the hitbox. More... | |
| void | set_dimensions (std::pair< int, int >) |
| This method set the width and height of the hitbox. More... | |
| bool | collides_with (Hitbox *) |
| Defines the collides with others hitboxes. More... | |
| void | set_displacement (std::pair< int, int >, std::pair< int, int >) |
| Sets the new coordinate of the hitbox after its movement. More... | |
| std::pair< int, int > | get_coordinates () |
| This method gets the coordinates of the hitbox. More... | |
| void | update (std::pair< int, int >) |
| Update the coordinate of the hitbox after its movement. More... | |
| void | draw () |
| Shows the image that was loaded and initialized on the screen. More... | |
| void | initialize () |
| Load and show the hitbox on the screen. More... | |
| bool | wanna_draw_hitbox () |
| Help developers to debug the hitboxes. More... | |
| Public Member Functions inherited from engine::Component | |
| Component (std::string p_name, std::pair< int, int > p_displacement, bool p_active, int p_priority) | |
| virtual bool | load () |
| virtual void | free () |
| virtual void | draw (int, int) |
| bool | is_active () |
| This Routine verifys if the component is active or deactive. More... | |
| void | activate () |
| This Routine activate the current component. More... | |
| void | deactivate () |
| This Routine deactivate the current component. More... | |
| std::pair< int, int > | get_displacement () |
| This Routine get the current component displacement. More... | |
| void | set_displacement (std::pair< int, int >) |
| This Routine set the current component displacement. More... | |
| int | get_priority () |
| This Routine get the current component priority. More... | |
| void | set_priority (int) |
| This Routine set the current component priority. More... | |
| std::string | get_name () |
| This Routine get the current component name. More... | |
| void | set_name (std::string) |
| This Routine set the current component name. More... | |
A Hitbox class.
The class hitbox has atributtes and methods for all types of hitboxes. That need information about width, height, coordinates, displacement and others.
| bool Hitbox::collides_with | ( | Hitbox * | other_hitbox | ) |
Defines the collides with others hitboxes.
this method defines the collision with two hitbox, based in its coordinates and dimensions
| other_hitbox | A hitbox object to identify collision between them. |
< int. Coordinate of the hitbox in axis x
< int. Coordinate in axis x and width of the hitbox
< int. Coordinate of the hitbox in axis y
< int. Coordinate in axis y and height of the hitbox
< pair<int, int>. Dimensions of the hitbox. width and height
< pair<int, int>. Coordinates on the axis x and y
< int. Coordinate of the hitbox that will collide in axis x
< int. Coordinate in axis x and width of the hitbox
< int. Coordinate of the hitbox in axis y
< int. Coordinate in axis y and height of the hitbox
| void Hitbox::draw | ( | ) |
Shows the image that was loaded and initialized on the screen.
< SDL_Rect. This render_quad tells where the image will appear in the screen.
| std::pair< int, int > Hitbox::get_coordinates | ( | ) |
This method gets the coordinates of the hitbox.
| std::pair< int, int > Hitbox::get_dimensions | ( | ) |
This method return the width and height of the hitbox.
| void Hitbox::initialize | ( | ) |
Load and show the hitbox on the screen.
this method load an image and initialize as a hitbox.
< SDL_Surface. Structure that contains a collection of pixels and images of the surface.
< SDL_Texture. A group of pixels.
| void Hitbox::set_dimensions | ( | std::pair< int, int > | p_dimensions | ) |
This method set the width and height of the hitbox.
| p_dimensions | is it the pointer that sets the dimensions of hitbox. |
| void Hitbox::set_displacement | ( | std::pair< int, int > | go_coordinates, |
| std::pair< int, int > | p_displacement | ||
| ) |
Sets the new coordinate of the hitbox after its movement.
this method calculate the new coordinate of the hitbox based in the its coordinate plus its coordinate of the movement.
| go_coordinates | coordinate that the hitbox will go. |
| p_displacement | coordinate that the hitbox is. |
| void Hitbox::update | ( | std::pair< int, int > | go_coordinates | ) |
Update the coordinate of the hitbox after its movement.
this method updates the coordinate of the hitbox based in the its coordinate plus its coordinate of the movement.
| go_coordinates | coordinate that the hitbox will go. |
| bool Hitbox::wanna_draw_hitbox | ( | ) |
Help developers to debug the hitboxes.
Help developers to debug the hitboxes because it allows you to show all hitboxes.


module Open3
Open3 grants you access to stdin, stdout, stderr and a thread to wait for the child process when running another program. You can specify various attributes, redirections, current directory, etc., of the program in the same way as for Process.spawn.
-
#popen3 : pipes for stdin, stdout, stderr
-
#popen2 : pipes for stdin, stdout
-
#popen2e : pipes for stdin, merged stdout and stderr
-
#capture3 : give a string for stdin; get strings for stdout, stderr
-
#capture2 : give a string for stdin; get a string for stdout
-
#capture2e : give a string for stdin; get a string for merged stdout and stderr
-
#pipeline_rw : pipes for first stdin and last stdout of a pipeline
-
#pipeline_r : pipe for last stdout of a pipeline
-
#pipeline_w : pipe for first stdin of a pipeline
-
#pipeline_start : run a pipeline without waiting
-
#pipeline : run a pipeline and wait for its completion
Public Class Methods
#capture2 captures the standard output of a command.
stdout_str, status = Open3.capture2([env,] cmd... [, opts])
The arguments env, cmd and opts are passed to #popen3 except
opts[:stdin_data]
and opts[:binmode]
. See Process.spawn.
If opts[:stdin_data]
is specified, it is sent to the
command's standard input.
If opts[:binmode]
is true, internal pipes are set to binary
mode.
Example:
# factor is a command for integer factorization. o, s = Open3.capture2("factor", :stdin_data=>"42") p o #=> "42: 2 3 7\n" # generate x**2 graph in png using gnuplot. gnuplot_commands = <<"End" set terminal png plot x**2, "-" with lines 1 14 2 1 3 8 4 5 e End image, s = Open3.capture2("gnuplot", :stdin_data=>gnuplot_commands, :binmode=>true)
# File lib/open3.rb, line 304 def capture2(*cmd, stdin_data: nil, binmode: false, **opts) popen2(*cmd, opts) {|i, o, t| if binmode i.binmode o.binmode end out_reader = Thread.new { o.read } if stdin_data begin i.write stdin_data rescue Errno::EPIPE end end i.close [out_reader.value, t.value] } end
#capture2e captures the standard output and the standard error of a command.
stdout_and_stderr_str, status = Open3.capture2e([env,] cmd... [, opts])
The arguments env, cmd and opts are passed to #popen3 except
opts[:stdin_data]
and opts[:binmode]
. See Process.spawn.
If opts[:stdin_data]
is specified, it is sent to the
command's standard input.
If opts[:binmode]
is true, internal pipes are set to binary
mode.
Example:
# capture make log make_log, s = Open3.capture2e("make")
# File lib/open3.rb, line 339 def capture2e(*cmd, stdin_data: nil, binmode: false, **opts) popen2e(*cmd, opts) {|i, oe, t| if binmode i.binmode oe.binmode end outerr_reader = Thread.new { oe.read } if stdin_data begin i.write stdin_data rescue Errno::EPIPE end end i.close [outerr_reader.value, t.value] } end
#capture3 captures the standard output and the standard error of a command.
stdout_str, stderr_str, status = Open3.capture3([env,] cmd... [, opts])
The arguments env, cmd and opts are passed to #popen3 except
opts[:stdin_data]
and opts[:binmode]
. See Process.spawn.
If opts[:stdin_data]
is specified, it is sent to the
command's standard input.
If opts[:binmode]
is true, internal pipes are set to binary
mode.
 # However, if the image is really stored in a file, # system("convert", "-thumbnail", "80", "png:#{filename}", "png:-") is better # because of reduced memory consumption. # But if the image is stored in a DB or generated by the gnuplot Open3.capture2 example, # Open3.capture3 should be considered. # image = File.read("/usr/share/openclipart/png/animals/mammals/sheep-md-v0.1.png", :binmode=>true) thumbnail, err, s = Open3.capture3("convert -thumbnail 80 png:- png:-", :stdin_data=>image, :binmode=>true) if s.success? STDOUT.binmode; print thumbnail end
# File lib/open3.rb, line 256 def capture3(*cmd, stdin_data: '', binmode: false, **opts) popen3(*cmd, opts) {|i, o, e, t| if binmode i.binmode o.binmode e.binmode end out_reader = Thread.new { o.read } err_reader = Thread.new { e.read } begin i.write stdin_data rescue Errno::EPIPE end i.close [out_reader.value, err_reader.value, t.value] } end
#pipeline starts a list of commands as a pipeline. It waits for the completion of the commands. No pipes are created for stdin of the first command and stdout of the last command.
status_list = Open3.pipeline(cmd1, cmd2, ... [, opts])
Each cmd is a string or an array. If it is an array, the elements are passed to Process.spawn.
cmd: commandline command line string which is passed to a shell [env, commandline, opts] command line string which is passed to a shell [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell) [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell) Note that env and opts are optional, as Process.spawn.
Example:
fname = "/usr/share/man/man1/ruby.1.gz" p Open3.pipeline(["zcat", fname], "nroff -man", "less") #=> [#<Process::Status: pid 11817 exit 0>, # #<Process::Status: pid 11820 exit 0>, # #<Process::Status: pid 11828 exit 0>] fname = "/usr/share/man/man1/ls.1.gz" Open3.pipeline(["zcat", fname], "nroff -man", "colcrt") # convert PDF to PS and send to a printer by lpr pdf_file = "paper.pdf" printer = "printer-name" Open3.pipeline(["pdftops", pdf_file, "-"], ["lpr", "-P#{printer}"]) # count lines Open3.pipeline("sort", "uniq -c", :in=>"names.txt", :out=>"count") # cyclic pipeline r,w = IO.pipe w.print "ibase=14\n10\n" Open3.pipeline("bc", "tee /dev/tty", :in=>r, :out=>w) #=> 14 # 18 # 22 # 30 # 42 # 58 # 78 # 106 # 202
# File lib/open3.rb, line 601 def pipeline(*cmds, **opts) pipeline_run(cmds, opts, [], []) {|ts| ts.map(&:value) } end
#pipeline_r starts a list of commands as a pipeline with a pipe which connects to stdout of the last command.
Open3.pipeline_r(cmd1, cmd2, ... [, opts]) {|last_stdout, wait_threads| ... } last_stdout, wait_threads = Open3.pipeline_r(cmd1, cmd2, ... [, opts]) ... last_stdout.close
Each cmd is a string or an array. If it is an array, the elements are passed to Process.spawn.
cmd: commandline command line string which is passed to a shell [env, commandline, opts] command line string which is passed to a shell [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell) [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell) Note that env and opts are optional, as for Process.spawn.
Example:
Open3.pipeline_r("zcat /var/log/apache2/access.log.*.gz", [{"LANG"=>"C"}, "grep", "GET /favicon.ico"], "logresolve") {|o, ts| o.each_line {|line| ... } } Open3.pipeline_r("yes", "head -10") {|o, ts| p o.read #=> "y\ny\ny\ny\ny\ny\ny\ny\ny\ny\n" p ts[0].value #=> #<Process::Status: pid 24910 SIGPIPE (signal 13)> p ts[1].value #=> #<Process::Status: pid 24913 exit 0> }
# File lib/open3.rb, line 450 def pipeline_r(*cmds, **opts, &block) out_r, out_w = IO.pipe opts[:out] = out_w pipeline_run(cmds, opts, [out_w], [out_r], &block) end
#pipeline_rw starts a list of commands as a pipeline with pipes which connect to stdin of the first command and stdout of the last command.
Open3.pipeline_rw(cmd1, cmd2, ... [, opts]) {|first_stdin, last_stdout, wait_threads| ... } first_stdin, last_stdout, wait_threads = Open3.pipeline_rw(cmd1, cmd2, ... [, opts]) ... first_stdin.close last_stdout.close
Each cmd is a string or an array. If it is an array, the elements are passed to Process.spawn.
cmd: commandline command line string which is passed to a shell [env, commandline, opts] command line string which is passed to a shell [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell) [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell) Note that env and opts are optional, as for Process.spawn.
The options to pass to Process.spawn are constructed by
merging opts
, the last hash element of the array, and
specifications for the pipes between each of the commands.
Example:
Open3.pipeline_rw("tr -dc A-Za-z", "wc -c") {|i, o, ts| i.puts "All persons more than a mile high to leave the court." i.close p o.gets #=> "42\n" } Open3.pipeline_rw("sort", "cat -n") {|stdin, stdout, wait_thrs| stdin.puts "foo" stdin.puts "bar" stdin.puts "baz" stdin.close # send EOF to sort. p stdout.read #=> " 1\tbar\n 2\tbaz\n 3\tfoo\n" }
# File lib/open3.rb, line 400 def pipeline_rw(*cmds, **opts, &block) in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[:out] = out_w pipeline_run(cmds, opts, [in_r, out_w], [in_w, out_r], &block) end
#pipeline_start starts a list of commands as a pipeline. No pipes are created for stdin of the first command and stdout of the last command.
Open3.pipeline_start(cmd1, cmd2, ... [, opts]) {|wait_threads| ... } wait_threads = Open3.pipeline_start(cmd1, cmd2, ... [, opts]) ...
Each cmd is a string or an array. If it is an array, the elements are passed to Process.spawn.
cmd: commandline command line string which is passed to a shell [env, commandline, opts] command line string which is passed to a shell [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell) [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell) Note that env and opts are optional, as for Process.spawn.
Example:
# Run xeyes in 10 seconds. Open3.pipeline_start("xeyes") {|ts| sleep 10 t = ts[0] Process.kill("TERM", t.pid) p t.value #=> #<Process::Status: pid 911 SIGTERM (signal 15)> } # Convert pdf to ps and send it to a printer. # Collect error message of pdftops and lpr. pdf_file = "paper.pdf" printer = "printer-name" err_r, err_w = IO.pipe Open3.pipeline_start(["pdftops", pdf_file, "-"], ["lpr", "-P#{printer}"], :err=>err_w) {|ts| err_w.close p err_r.read # error messages of pdftops and lpr. }
# File lib/open3.rb, line 539 def pipeline_start(*cmds, **opts, &block) if block pipeline_run(cmds, opts, [], [], &block) else ts, = pipeline_run(cmds, opts, [], []) ts end end
#pipeline_w starts a list of commands as a pipeline with a pipe which connects to stdin of the first command.
Open3.pipeline_w(cmd1, cmd2, ... [, opts]) {|first_stdin, wait_threads| ... } first_stdin, wait_threads = Open3.pipeline_w(cmd1, cmd2, ... [, opts]) ... first_stdin.close
Each cmd is a string or an array. If it is an array, the elements are passed to Process.spawn.
cmd: commandline command line string which is passed to a shell [env, commandline, opts] command line string which is passed to a shell [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell) [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell) Note that env and opts are optional, as for Process.spawn.
Example:
Open3.pipeline_w("bzip2 -c", :out=>"/tmp/hello.bz2") {|i, ts| i.puts "hello" }
# File lib/open3.rb, line 486 def pipeline_w(*cmds, **opts, &block) in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true pipeline_run(cmds, opts, [in_r], [in_w], &block) end
#popen2 is similar to #popen3 except that it doesn't create a pipe for the standard error stream.
Block form:
Open3.popen2([env,] cmd... [, opts]) {|stdin, stdout, wait_thr| pid = wait_thr.pid # pid of the started process. ... exit_status = wait_thr.value # Process::Status object returned. }
Non-block form:
stdin, stdout, wait_thr = Open3.popen2([env,] cmd... [, opts]) ... stdin.close # stdin and stdout should be closed explicitly in this form. stdout.close
See Process.spawn for the optional hash arguments env and opts.
Example:
Open3.popen2("wc -c") {|i,o,t| i.print "answer to life the universe and everything" i.close p o.gets #=> "42\n" } Open3.popen2("bc -q") {|i,o,t| i.puts "obase=13" i.puts "6 * 9" p o.gets #=> "42\n" } Open3.popen2("dc") {|i,o,t| i.print "42P" i.close p o.read #=> "*" }
# File lib/open3.rb, line 138 def popen2(*cmd, **opts, &block) in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[:out] = out_w popen_run(cmd, opts, [in_r, out_w], [in_w, out_r], &block) end
#popen2e is similar to #popen3 except that it merges the standard output stream and the standard error stream.
Block form:
Open3.popen2e([env,] cmd... [, opts]) {|stdin, stdout_and_stderr, wait_thr| pid = wait_thr.pid # pid of the started process. ... exit_status = wait_thr.value # Process::Status object returned. }
Non-block form:
stdin, stdout_and_stderr, wait_thr = Open3.popen2e([env,] cmd... [, opts]) ... stdin.close # stdin and stdout_and_stderr should be closed explicitly in this form. stdout_and_stderr.close
See Process.spawn for the optional hash arguments env and opts.
Example:
# check gcc warnings source = "foo.c" Open3.popen2e("gcc", "-Wall", source) {|i,oe,t| oe.each {|line| if /warning/ =~ line ... end } }
# File lib/open3.rb, line 181 def popen2e(*cmd, **opts, &block) in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[[:out, :err]] = out_w popen_run(cmd, opts, [in_r, out_w], [in_w, out_r], &block) end
Open stdin, stdout, and stderr streams and start external executable. In addition, a thread to wait for the started process is created. The thread has a pid method and a thread variable :pid which is the pid of the started process.
Block form:
Open3.popen3([env,] cmd... [, opts]) {|stdin, stdout, stderr, wait_thr| pid = wait_thr.pid # pid of the started process. ... exit_status = wait_thr.value # Process::Status object returned. }
Non-block form:
stdin, stdout, stderr, wait_thr = Open3.popen3([env,] cmd... [, opts]) pid = wait_thr[:pid] # pid of the started process ... stdin.close # stdin, stdout and stderr should be closed explicitly in this form. stdout.close stderr.close exit_status = wait_thr.value # Process::Status object returned.
The parameters env, cmd, and opts are passed to Process.spawn. A commandline string and a list of argument strings can be accepted as follows:
Open3.popen3("echo abc") {|i, o, e, t| ... } Open3.popen3("echo", "abc") {|i, o, e, t| ... } Open3.popen3(["echo", "argv0"], "abc") {|i, o, e, t| ... }
If the last parameter, opts, is a Hash, it is recognized as an option for Process.spawn.
Open3.popen3("pwd", :chdir=>"/") {|i,o,e,t| p o.read.chomp #=> "/" }
wait_thr.value waits for the termination of the process. The block form also waits for the process when it returns.
Closing stdin, stdout and stderr does not wait for the process to complete.
You should be careful to avoid deadlocks. Since pipes are fixed length buffers, #popen3(“prog”) {|i, o, e, t| o.read } deadlocks if the program generates too much output on stderr. You should read stdout and stderr simultaneously (using threads or IO.select). However, if you don't need stderr output, you can use #popen2. If merged stdout and stderr output is not a problem, you can use #popen2e. If you really need stdout and stderr output as separate strings, you can consider #capture3.
# File lib/open3.rb, line 83 def popen3(*cmd, **opts, &block) in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[:out] = out_w err_r, err_w = IO.pipe opts[:err] = err_w popen_run(cmd, opts, [in_r, out_w, err_w], [in_w, out_r, err_r], &block) end
Private Instance Methods
#capture2 captures the standard output of a command.
stdout_str, status = Open3.capture2([env,] cmd... [, opts])
The arguments env, cmd and opts are passed to #popen3 except
opts[:stdin_data]
and opts[:binmode]
. See Process.spawn.
If opts[:stdin_data]
is specified, it is sent to the
command's standard input.
If opts[:binmode]
is true, internal pipes are set to binary
mode.
Example:
# factor is a command for integer factorization. o, s = Open3.capture2("factor", :stdin_data=>"42") p o #=> "42: 2 3 7\n" # generate x**2 graph in png using gnuplot. gnuplot_commands = <<"End" set terminal png plot x**2, "-" with lines 1 14 2 1 3 8 4 5 e End image, s = Open3.capture2("gnuplot", :stdin_data=>gnuplot_commands, :binmode=>true)
# File lib/open3.rb, line 304 def capture2(*cmd, stdin_data: nil, binmode: false, **opts) popen2(*cmd, opts) {|i, o, t| if binmode i.binmode o.binmode end out_reader = Thread.new { o.read } if stdin_data begin i.write stdin_data rescue Errno::EPIPE end end i.close [out_reader.value, t.value] } end
#capture2e captures the standard output and the standard error of a command.
stdout_and_stderr_str, status = Open3.capture2e([env,] cmd... [, opts])
The arguments env, cmd and opts are passed to #popen3 except
opts[:stdin_data]
and opts[:binmode]
. See Process.spawn.
If opts[:stdin_data]
is specified, it is sent to the
command's standard input.
If opts[:binmode]
is true, internal pipes are set to binary
mode.
Example:
# capture make log make_log, s = Open3.capture2e("make")
# File lib/open3.rb, line 339 def capture2e(*cmd, stdin_data: nil, binmode: false, **opts) popen2e(*cmd, opts) {|i, oe, t| if binmode i.binmode oe.binmode end outerr_reader = Thread.new { oe.read } if stdin_data begin i.write stdin_data rescue Errno::EPIPE end end i.close [outerr_reader.value, t.value] } end
#capture3 captures the standard output and the standard error of a command.
stdout_str, stderr_str, status = Open3.capture3([env,] cmd... [, opts])
The arguments env, cmd and opts are passed to #popen3 except
opts[:stdin_data]
and opts[:binmode]
. See Process.spawn.
If opts[:stdin_data]
is specified, it is sent to the
command's standard input.
If opts[:binmode]
is true, internal pipes are set to binary
mode.
 # However, if the image is really stored in a file, # system("convert", "-thumbnail", "80", "png:#{filename}", "png:-") is better # because of reduced memory consumption. # But if the image is stored in a DB or generated by the gnuplot Open3.capture2 example, # Open3.capture3 should be considered. # image = File.read("/usr/share/openclipart/png/animals/mammals/sheep-md-v0.1.png", :binmode=>true) thumbnail, err, s = Open3.capture3("convert -thumbnail 80 png:- png:-", :stdin_data=>image, :binmode=>true) if s.success? STDOUT.binmode; print thumbnail end
# File lib/open3.rb, line 256 def capture3(*cmd, stdin_data: '', binmode: false, **opts) popen3(*cmd, opts) {|i, o, e, t| if binmode i.binmode o.binmode e.binmode end out_reader = Thread.new { o.read } err_reader = Thread.new { e.read } begin i.write stdin_data rescue Errno::EPIPE end i.close [out_reader.value, err_reader.value, t.value] } end
#pipeline starts a list of commands as a pipeline. It waits for the completion of the commands. No pipes are created for stdin of the first command and stdout of the last command.
status_list = Open3.pipeline(cmd1, cmd2, ... [, opts])
Each cmd is a string or an array. If it is an array, the elements are passed to Process.spawn.
cmd: commandline command line string which is passed to a shell [env, commandline, opts] command line string which is passed to a shell [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell) [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell) Note that env and opts are optional, as Process.spawn.
Example:
fname = "/usr/share/man/man1/ruby.1.gz" p Open3.pipeline(["zcat", fname], "nroff -man", "less") #=> [#<Process::Status: pid 11817 exit 0>, # #<Process::Status: pid 11820 exit 0>, # #<Process::Status: pid 11828 exit 0>] fname = "/usr/share/man/man1/ls.1.gz" Open3.pipeline(["zcat", fname], "nroff -man", "colcrt") # convert PDF to PS and send to a printer by lpr pdf_file = "paper.pdf" printer = "printer-name" Open3.pipeline(["pdftops", pdf_file, "-"], ["lpr", "-P#{printer}"]) # count lines Open3.pipeline("sort", "uniq -c", :in=>"names.txt", :out=>"count") # cyclic pipeline r,w = IO.pipe w.print "ibase=14\n10\n" Open3.pipeline("bc", "tee /dev/tty", :in=>r, :out=>w) #=> 14 # 18 # 22 # 30 # 42 # 58 # 78 # 106 # 202
# File lib/open3.rb, line 601 def pipeline(*cmds, **opts) pipeline_run(cmds, opts, [], []) {|ts| ts.map(&:value) } end
#pipeline_r starts a list of commands as a pipeline with a pipe which connects to stdout of the last command.
Open3.pipeline_r(cmd1, cmd2, ... [, opts]) {|last_stdout, wait_threads| ... } last_stdout, wait_threads = Open3.pipeline_r(cmd1, cmd2, ... [, opts]) ... last_stdout.close
Each cmd is a string or an array. If it is an array, the elements are passed to Process.spawn.
cmd: commandline command line string which is passed to a shell [env, commandline, opts] command line string which is passed to a shell [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell) [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell) Note that env and opts are optional, as for Process.spawn.
Example:
Open3.pipeline_r("zcat /var/log/apache2/access.log.*.gz", [{"LANG"=>"C"}, "grep", "GET /favicon.ico"], "logresolve") {|o, ts| o.each_line {|line| ... } } Open3.pipeline_r("yes", "head -10") {|o, ts| p o.read #=> "y\ny\ny\ny\ny\ny\ny\ny\ny\ny\n" p ts[0].value #=> #<Process::Status: pid 24910 SIGPIPE (signal 13)> p ts[1].value #=> #<Process::Status: pid 24913 exit 0> }
# File lib/open3.rb, line 450 def pipeline_r(*cmds, **opts, &block) out_r, out_w = IO.pipe opts[:out] = out_w pipeline_run(cmds, opts, [out_w], [out_r], &block) end
#pipeline_rw starts a list of commands as a pipeline with pipes which connect to stdin of the first command and stdout of the last command.
Open3.pipeline_rw(cmd1, cmd2, ... [, opts]) {|first_stdin, last_stdout, wait_threads| ... } first_stdin, last_stdout, wait_threads = Open3.pipeline_rw(cmd1, cmd2, ... [, opts]) ... first_stdin.close last_stdout.close
Each cmd is a string or an array. If it is an array, the elements are passed to Process.spawn.
cmd: commandline command line string which is passed to a shell [env, commandline, opts] command line string which is passed to a shell [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell) [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell) Note that env and opts are optional, as for Process.spawn.
The options to pass to Process.spawn are constructed by
merging opts
, the last hash element of the array, and
specifications for the pipes between each of the commands.
Example:
Open3.pipeline_rw("tr -dc A-Za-z", "wc -c") {|i, o, ts| i.puts "All persons more than a mile high to leave the court." i.close p o.gets #=> "42\n" } Open3.pipeline_rw("sort", "cat -n") {|stdin, stdout, wait_thrs| stdin.puts "foo" stdin.puts "bar" stdin.puts "baz" stdin.close # send EOF to sort. p stdout.read #=> " 1\tbar\n 2\tbaz\n 3\tfoo\n" }
# File lib/open3.rb, line 400 def pipeline_rw(*cmds, **opts, &block) in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[:out] = out_w pipeline_run(cmds, opts, [in_r, out_w], [in_w, out_r], &block) end
#pipeline_start starts a list of commands as a pipeline. No pipes are created for stdin of the first command and stdout of the last command.
Open3.pipeline_start(cmd1, cmd2, ... [, opts]) {|wait_threads| ... } wait_threads = Open3.pipeline_start(cmd1, cmd2, ... [, opts]) ...
Each cmd is a string or an array. If it is an array, the elements are passed to Process.spawn.
cmd: commandline command line string which is passed to a shell [env, commandline, opts] command line string which is passed to a shell [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell) [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell) Note that env and opts are optional, as for Process.spawn.
Example:
# Run xeyes in 10 seconds. Open3.pipeline_start("xeyes") {|ts| sleep 10 t = ts[0] Process.kill("TERM", t.pid) p t.value #=> #<Process::Status: pid 911 SIGTERM (signal 15)> } # Convert pdf to ps and send it to a printer. # Collect error message of pdftops and lpr. pdf_file = "paper.pdf" printer = "printer-name" err_r, err_w = IO.pipe Open3.pipeline_start(["pdftops", pdf_file, "-"], ["lpr", "-P#{printer}"], :err=>err_w) {|ts| err_w.close p err_r.read # error messages of pdftops and lpr. }
# File lib/open3.rb, line 539 def pipeline_start(*cmds, **opts, &block) if block pipeline_run(cmds, opts, [], [], &block) else ts, = pipeline_run(cmds, opts, [], []) ts end end
#pipeline_w starts a list of commands as a pipeline with a pipe which connects to stdin of the first command.
Open3.pipeline_w(cmd1, cmd2, ... [, opts]) {|first_stdin, wait_threads| ... } first_stdin, wait_threads = Open3.pipeline_w(cmd1, cmd2, ... [, opts]) ... first_stdin.close
Each cmd is a string or an array. If it is an array, the elements are passed to Process.spawn.
cmd: commandline command line string which is passed to a shell [env, commandline, opts] command line string which is passed to a shell [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell) [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell) Note that env and opts are optional, as for Process.spawn.
Example:
Open3.pipeline_w("bzip2 -c", :out=>"/tmp/hello.bz2") {|i, ts| i.puts "hello" }
# File lib/open3.rb, line 486 def pipeline_w(*cmds, **opts, &block) in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true pipeline_run(cmds, opts, [in_r], [in_w], &block) end
#popen2 is similar to #popen3 except that it doesn't create a pipe for the standard error stream.
Block form:
Open3.popen2([env,] cmd... [, opts]) {|stdin, stdout, wait_thr| pid = wait_thr.pid # pid of the started process. ... exit_status = wait_thr.value # Process::Status object returned. }
Non-block form:
stdin, stdout, wait_thr = Open3.popen2([env,] cmd... [, opts]) ... stdin.close # stdin and stdout should be closed explicitly in this form. stdout.close
See Process.spawn for the optional hash arguments env and opts.
Example:
Open3.popen2("wc -c") {|i,o,t| i.print "answer to life the universe and everything" i.close p o.gets #=> "42\n" } Open3.popen2("bc -q") {|i,o,t| i.puts "obase=13" i.puts "6 * 9" p o.gets #=> "42\n" } Open3.popen2("dc") {|i,o,t| i.print "42P" i.close p o.read #=> "*" }
# File lib/open3.rb, line 138 def popen2(*cmd, **opts, &block) in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[:out] = out_w popen_run(cmd, opts, [in_r, out_w], [in_w, out_r], &block) end
#popen2e is similar to #popen3 except that it merges the standard output stream and the standard error stream.
Block form:
Open3.popen2e([env,] cmd... [, opts]) {|stdin, stdout_and_stderr, wait_thr| pid = wait_thr.pid # pid of the started process. ... exit_status = wait_thr.value # Process::Status object returned. }
Non-block form:
stdin, stdout_and_stderr, wait_thr = Open3.popen2e([env,] cmd... [, opts]) ... stdin.close # stdin and stdout_and_stderr should be closed explicitly in this form. stdout_and_stderr.close
See Process.spawn for the optional hash arguments env and opts.
Example:
# check gcc warnings source = "foo.c" Open3.popen2e("gcc", "-Wall", source) {|i,oe,t| oe.each {|line| if /warning/ =~ line ... end } }
# File lib/open3.rb, line 181 def popen2e(*cmd, **opts, &block) in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[[:out, :err]] = out_w popen_run(cmd, opts, [in_r, out_w], [in_w, out_r], &block) end
Open stdin, stdout, and stderr streams and start external executable. In addition, a thread to wait for the started process is created. The thread has a pid method and a thread variable :pid which is the pid of the started process.
Block form:
Open3.popen3([env,] cmd... [, opts]) {|stdin, stdout, stderr, wait_thr| pid = wait_thr.pid # pid of the started process. ... exit_status = wait_thr.value # Process::Status object returned. }
Non-block form:
stdin, stdout, stderr, wait_thr = Open3.popen3([env,] cmd... [, opts]) pid = wait_thr[:pid] # pid of the started process ... stdin.close # stdin, stdout and stderr should be closed explicitly in this form. stdout.close stderr.close exit_status = wait_thr.value # Process::Status object returned.
The parameters env, cmd, and opts are passed to Process.spawn. A commandline string and a list of argument strings can be accepted as follows:
Open3.popen3("echo abc") {|i, o, e, t| ... } Open3.popen3("echo", "abc") {|i, o, e, t| ... } Open3.popen3(["echo", "argv0"], "abc") {|i, o, e, t| ... }
If the last parameter, opts, is a Hash, it is recognized as an option for Process.spawn.
Open3.popen3("pwd", :chdir=>"/") {|i,o,e,t| p o.read.chomp #=> "/" }
wait_thr.value waits for the termination of the process. The block form also waits for the process when it returns.
Closing stdin, stdout and stderr does not wait for the process to complete.
You should be careful to avoid deadlocks. Since pipes are fixed length buffers, #popen3(“prog”) {|i, o, e, t| o.read } deadlocks if the program generates too much output on stderr. You should read stdout and stderr simultaneously (using threads or IO.select). However, if you don't need stderr output, you can use #popen2. If merged stdout and stderr output is not a problem, you can use #popen2e. If you really need stdout and stderr output as separate strings, you can consider #capture3.
# File lib/open3.rb, line 83 def popen3(*cmd, **opts, &block) in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[:out] = out_w err_r, err_w = IO.pipe opts[:err] = err_w popen_run(cmd, opts, [in_r, out_w, err_w], [in_w, out_r, err_r], &block) end


MapR-DB OJAI - Sample Application
Sample Application
Complete Application: UI consuming the REST API
REST API
Direct Access to the REST API (JAX-RS and Swagger)


Cars Token
Tokenized cars that live on the Ethereum blockchain.
Generate a random tokenized crypto car to your wallet!
Address
Get Token


{% load static %}
To provide a precise, efficient and stable container management platform
Concise, efficient, data visualization
Efficient, responsive, second-level deployment
Data visualization, dynamic updates
Multiple mirroring, load balancing, high availability
One container platform innovation.
To provide a more efficient and safe docker container management platform.
A Red Hat Certified Engineer,A Linux System Architect,Docker official developer.
Very good use, very stable, look forward to new version
BaoJin Xu, DevOps, TianTianCloud Company.
Easy to manage, quick deployment
GuoXin Yuan, Community members, GeekCloud.
33 Runyang South Road
YangZhou, Zip code 225127
<EMAIL_ADDRESS>+86<PHONE_NUMBER>1


?6
7
8
9
10
_
.XT
„
The
New
York
copyright
reserved
botanical
Garden
AT
S\)
D
aAUW
UNIV.
herbarium:
New
York
Botanical
Garden
IblkS'iO
<£W
Yo^
BOTANICAL
®ARDE^
PLANTS
OF
JAMAICA
Parish:
St.
Aim
Date:
Dec.
23»
1957
Bot.
Name:
Canavalia
altissima
Macf.
Vem.
NameOverlook
Bean.
Herbaceous
vine;
banner
dark
red
or
purple,
the
wings
and
keel
greenish-yellow;
leaves
somewhat
fleshy.
Climbing
in
thicket,
slope
near
the
sea,
west
of
Ocho
Rios.
ilt.
50-100
ft.
Prc
Collector:
T.
G.
YUNCKER
No.
17,788
TRUMAN
G.
YUNCKER
HERBARIUM
OF
DEPAUW
UNIVERSITY
(DPU)
PURCHASED
BY
NY
IN
1987
Legend -
Level of confidence that token is an accurately-transcribed word
extremely low
very low
low
undetermined
medium
high
very high


Into the web
It has taken me 10 years to embrace my love of web development and dedicate myself to the craft. Since studying computer science I have been working as a Systems Analyst, always closely aligned with extremely talented development teams.
After working with so many brilliant programmers who are passionate about their work, I have been drawn to programming. So after all this time I have returned to my studies and am steadily building this portfolio of my programming projects.
xox
One step at a time
My journey has been like a roller coaster ride. Filled with anxiety when approaching a new challenge, absolute rapture as the understanding of a technology crystallized and devastating lows when staggering through minefields of realised misconceptions.
I know that my experience gained so far has been positively reinforced with my programming abilities. I'm brimming with enthusiasm and cannot wait to keep learning and growing as a part of the programming community.
Portfolio
Blackjack
Online blackjack game between a dealer and single player. Game statistics are available but the ability to bet is still a work in progress.
Technologies: Foundation, HTML5, CSS3, JavaScript, JQuery, TDD with RSpec, Ruby on Rails, ActiveRecord and Postgres
ShareMyRide
Any traveller is able to register a road trip that they plan to take and a number of seats can be made available for other travellers to book. The origin, destination and date of trip is registered and can be searched.
Technologies: Foundation, HTML5, CSS3, JavaScript, GoogleMaps API, Ruby on Rails, CRUD with ActiveRecord and Postgres
CubbyLife
Connects apartment tenants with the building manager. This application allows building managers to register events that affect the tenants of a particular building. Tenants are able to schedule time for their participation in a registered event.
Technologies: Bootstrap, HTML5, CSS3, Ruby on Rails, CRUD with ActiveRecord and Postgres
MovieFinder
Search for a movie title and view the information related to revenue, year of release, actors, director and plot. All the successful searches are saved and the history can be cleared.
Technologies: HTML5, CSS3, Sinatra framework, Ruby, file management, HTTPrequest, JSON and OMDB API
MTA
Plan a journey route for the MTA train lines. The stations where the journey begins and end can be entered and the route will be displayed. Platforms where line changes need to be made will be included as well.
Technologies: HTML5, CSS3, JavaScript


My favorite things
These are a few of my favorite things
People
Here are some of my favorite people!
- My best friends:
- My Mother Kim
- My significant other Katelyn
Here are three of my favorite flavors of icecream, in order:
- Salted Caramel
- Vnilla
- Strawberry Shortcake
Thank you for taking the time to read about me!


Code Docs for each helper module¶
Modules¶
|
PyreParser - The highest level parser class - directly parses |
|
RuleBuilder - A class for constructing iptables rules, with auto generation of related rules |
|
PyreParser - The highest level parser class - directly parses |
privex.pyrewall¶
|
|
Define names for built-in types that aren’t directly accessible as a builtin. |


| I l@ve RuBoard |
18.3 String Module UtilitiesPython's string module includes a variety of text-processing utilities that go above and beyond string expression operators. For instance: The Python library manual includes an exhaustive list of available tools. Moreover, as of Python 2.0, Unicode (wide) strings are fully supported by Python string tools, and most of the string module's functions are also now available as string object methods. For instance, in Python 2.0, the following two expressions are equivalent: string.find(str, substr) # traditional str.find(substr) # new in 2.0 except that the second form does not require callers to import the string module first. As usual, you should consult the library manuals and Appendix A, for late-breaking news on the string tools front. In terms of this chapter's main focus, though, Python's built-in tools for splitting and joining strings around tokens turn out to be especially useful when it comes to parsing text:
As we saw earlier in this book, split chops a string into a list of substrings, and join puts them back together:[1]
>>> import string >>> string.split('A B C D') ['A', 'B', 'C', 'D'] >>> string.split('A+B+C+D', '+') ['A', 'B', 'C', 'D'] >>> string.join(['a', 'b', 'c'], '--') 'a--b--c' Despite their simplicity, they can handle surprisingly complex text-parsing tasks. Moreover, the string module is very fast because it has been migrated to C. For instance, to quickly replace all tabs in a file with four periods, pipe the file into a script that looks like this: from sys import * from string import * stdout.write( join( split(stdin.read( ), '\t'), '.'*4) ) The split call here divides input around tabs, and the join puts it back together with periods where tabs had been. The combination of the two calls is equivalent to using the global replacement call in the string module as follows: stdout.write( replace(stdin.read( ), '\t', '.'*4) ) 18.3.1 Summing Columns in a FileLet's look at a couple of practical applications of string splits and joins. In many domains, scanning files by columns is a fairly common task. For instance, suppose you have a file containing columns of numbers output by another system, and you need to sum each column's numbers. In Python, string splitting does the job (see Example 18-1). As an added bonus, it's easy to make the solution a reusable tool in Python. Example 18-1. PP2E\Lang\summer.py#!/usr/local/bin/python import string def summer(numCols, fileName): sums = [0] * numCols # make list of zeros for line in open(fileName, 'r').readlines( ): # scan file's lines cols = string.split(line) # split up columns for i in range(numCols): # around blanks/tabs sums[i] = sums[i] + eval(cols[i]) # add numbers to sums return sums if __name__ == '__main__': import sys print summer(eval(sys.argv[1]), sys.argv[2]) # '% summer.py cols file' As usual, you can both import this module and call its function, and run it as a shell tool from the command line. The summer calls split to make a list of strings representing the line's columns, and eval to convert column strings to numbers. Here's an input file that uses both blanks and tabs to separate columns: C:\...\PP2E\Lang>type table1.txt 1 5 10 2 1.0 2 10 20 4 2.0 3 15 30 8 3 4 20 40 16 4.0 C:\...\PP2E\Lang>python summer.py 5 table1.txt [10, 50, 100, 30, 10.0] Notice that because the summer script uses eval to convert file text to numbers, you could really store arbitrary Python expressions in the file. Here, for example, it's run on a file of Python code snippets: C:\...\PP2E\Lang>type table2.txt 2 1+1 1<<1 eval("2") 16 2*2*2*2 pow(2,4) 16.0 3 len('abc') [1,2,3][2] {'spam':3}['spam'] C:\...\PP2E\Lang>python summer.py 4 table2.txt [21, 21, 21, 21.0] We'll revisit eval later in this chapter when we explore expression evaluators.[2]
18.3.2 Parsing and Unparsing Rule StringsExample 18-2 demonstrates one way that splitting and joining strings can be used to parse sentences in a simple language. It is taken from a rule-based expert system shell (holmes) that is written in Python and included at http://examples.oreilly.com/python2 (see the top-level Ai examples directory). Rule strings in holmes take the form: "rule <id> if <test1>, <test2>... then <conclusion1>, <conclusion2>..." Tests and conclusions are conjunctions of terms ("," means "and"). Each term is a list of words or variables separated by spaces; variables start with ?. To use a rule, it is translated to an internal form -- a dictionary with nested lists. To display a rule, it is translated back to the string form. For instance, given a call: rules.internal_rule('rule x if a ?x, b then c, d ?x') the conversion in function internal_rule proceeds as follows: string = 'rule x if a ?x, b then c, d ?x' i = ['rule x', 'a ?x, b then c, d ?x'] t = ['a ?x, b', 'c, d ?x'] r = ['', 'x'] result = {'rule':'x', 'if':[['a','?x'], ['b']], 'then':[['c'], ['d','?x']]} It first splits around the if, then around the then, and finally around rule. The result is the three substrings that were separated by the keywords. Test and conclusion substrings are split around "," and spaces last. join is used to convert back (unparse) to the original string for display. Example 18-2 is the concrete implementation of this scheme. Example 18-2. PP2E\Lang\rules.pyfrom string import split, join, strip def internal_rule(string): i = split(string, ' if ') t = split(i[1], ' then ') r = split(i[0], 'rule ') return {'rule':strip(r[1]), 'if':internal(t[0]), 'then':internal(t[1])} def external_rule(rule): return ('rule ' + rule['rule'] + ' if ' + external(rule['if']) + ' then ' + external(rule['then']) + '.') def internal(conjunct): res = [] # 'a b, c d' for clause in split(conjunct, ','): # -> ['a b', ' c d'] res.append(split(clause)) # -> [['a','b'], ['c','d']] return res def external(conjunct): strs = [] for clause in conjunct: # [['a','b'], ['c','d']] strs.append(join(clause)) # -> ['a b', 'c d'] return join(strs, ', ') # -> 'a b, c d' As usual, we can test components of this module interactively: >>> import rules >>> rules.internal('a ?x, b') [['a', '?x'], ['b']] >>> rules.internal_rule('rule x if a ?x, b then c, d ?x') {'if': [['a', '?x'], ['b']], 'rule': 'x', 'then': [['c'], ['d', '?x']]} >>> r = rules.internal_rule('rule x if a ?x, b then c, d ?x') >>> rules.external_rule(r) 'rule x if a ?x, b then c, d ?x.' Parsing by splitting strings around tokens like this only takes you so far: there is no direct support for recursive nesting of components, and syntax errors are not handled very gracefully. But for simple language tasks like this, string splitting might be enough, at least for prototyping systems. You can always add a more robust rule parser later or reimplement rules as embedded Python code or classes .
<IP_ADDRESS> More on the holmes expert system shellSo how are these rules actually used? As mentioned, the rule parser we just met is part of the Python-coded holmes expert system shell. This book does not cover holmes in detail due to lack of space; see the PP2E\AI\ExpertSystem directory on the book CD (see http://examples.oreilly.com/python2) for its code and documentation. But by way of introduction, holmes is an inference engine that performs forward and backward chaining deduction on rules that you supply. For example, a rule: rule pylike if ?X likes coding, ?X likes spam then ?X likes Python can be used both to prove whether someone likes Python (backward, from "then" to "if"), and to deduce that someone likes Python from a set of known facts (forward, from "if" to "then"). Deductions may span multiple rules, and rules that name the same conclusion represent alternatives. Holmes also performs simple pattern-matching along the way to assign the variables that appear in rules (e.g., ?X), and is able to explain its work. To make this all more concrete, let's step through a simple holmes session.  Now, to kick off a backward-chaining proof of a goal, use the ?- command. A proof explanation is shown here; holmes can also tell you why it is asking a question. Holmes pattern variables can show up in both rules and queries; in rules, variables provide generalization; in a query, they provide an answer: holmes> ?- mel likes Python is this true: "mel likes coding" ? y is this true: "mel likes spam" ? y yes: (no variables) show proof ? yes "mel likes Python" by rule pylike "mel likes coding" by your answer "mel likes spam" by your answer more solutions? n holmes> ?- linda likes ?X is this true: "linda likes coding" ? y is this true: "linda likes spam" ? y yes: linda likes Python Forward-chaining from a set of facts to conclusions is started with a +- command. Here, the same rule is being applied but in a different way: holmes> +- chris likes spam, chris likes coding I deduced these facts... chris likes Python I started with these facts... chris likes spam chris likes coding time: 0.0 More interestingly, deductions chain through multiple rules when part of a rule's "if" is mentioned in another rule's "then": holmes> += rule 1 if thinks ?x then human ?x holmes> += rule 2 if human ?x then mortal ?x holmes> ?- mortal bob is this true: "thinks bob" ? y yes: (no variables) holmes> +- thinks bob I deduced these facts... human bob mortal bob I started with these facts... thinks bob time: 0.0 Finally, the @= command is used to load files of rules that implement more sophisticated knowledgebases; the rule parser is run on each rule in the file. Here is a file that encodes animal classification rules; other example files are available on the CD (see http://examples.oreilly.com/python2) if you'd like to experiment: holmes> @= ..¸bases\zoo.kb holmes> ?- it is a penguin is this true: "has feathers" ? why to prove "it is a penguin" by rule 17 this was part of your original query. is this true: "has feathers" ? y is this true: "able to fly" ? n is this true: "black color" ? y yes: (no variables) Type "stop" to end a session and "help" for a full commands list, and see the text files in the holmes directories for more details. Holmes is an old system written before Python 1.0 (and around 1993), but still works unchanged on all platforms under Python 1.5.2. |
| I l@ve RuBoard |


7-Minute+
Get in shape with this simple 7-Minute Workout app! Never forget to exercise with a daily timeline reminder, and receive a pin when you complete it.
Daily Timeline Reminder
Enabled
When


the link directory is to your left. For other artwork by AltoHearts please visit: AltoHearts Creations To see my portal, please visit: My Portal Link
No Thoughts.
Only code.


Issues
| # | Summary | Product | Status | Kind | When |
|---|---|---|---|---|---|
| 1882 |
Option to stop CommandT from following symlinks |
Command-T | closed | feature request | Created , updated |
| 1881 |
Take VIM "switchbuf" setting into account when switching between buffers. |
Command-T | closed | feature request | Created , updated |
| 1880 |
Does not show covers anymore |
Synergy | closed | support ticket | Created , updated |
| 1879 |
Turn SHA-1s in commit messages into hyperlinks in repo browser |
wincent.com | open | feature request | |
| 1878 |
Multiple caches, keyed off path-to-directory |
Command-T | closed | feature request | Created , updated |
| 1876 |
Crash while using commandT |
Command-T | closed | bug | Created , updated |
| 1875 |
command-t-1.2.1.vba fails to unpack under vim-7.3, ruby-1.9 |
Command-T | closed | feedback | Created , updated |
| 1874 |
Update to Rails 3.1.1.rc1 |
wincent.com | closed | feature request | Created , updated |
| 1873 |
Issue description changes shouldn't trigger annotations |
wincent.com | closed | bug | Created , updated |
| 1872 |
I get NoMethodError: undefined method `show_file_finder' for nil:NilClass |
Command-T | closed | bug |


3.48% Since last month
3.48% Since last week
1.10% Since yesterday
12% Since last month
{{ contract.description }}


[gecode-users] New gecode version desiderata: channeling between set variables
Luca Di Gaspero
l.digaspero at uniud.it
Tue Oct 25 12:56:22 CEST 2011
Hi all,
would it be possible to have channeling constraints between SetVarArrays in the new gecode version. Even though they are just implemented with decomposition they would be extremely useful in modeling (and in teaching).
The constraints I am thinking about are of the form:
i \in SetA_j \iff j \in SetB_i
which can be of course implemented through a few element() constraints, but it would be great to have a global channel(*this, Set_A, Set_B)!
Thanks in advance,
Luca
More information about the users
mailing list


SteamyCalc
Developed by Kiran Pashikanti<EMAIL_ADDRESS>Usage
Simply provide two conditions (quality, temperature, pressure, enthalpy, entropy) and remaining thermodynamic properties will be calculated. If there is any interest for other thermodynamic pairs (internal energy, etc.), those can probably be implemented upon request.
License
SteamyCalc is a full implementation of the IAPWS/IFC-97 Water and Steam tables written completely in JS and HTML.
Copyright 2021 Kiran Pashikanti
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
This code is driven by a JS translation of the excellent XSteam code written by Magnus Holgrem
JS and original VBA version available at https://github.com/kpatvt/xsteam2
Water and steam properties according to IAPWS IF-97
By Magnus Holmgren, www.x-eng.com
The steam tables are free and provided as is.
We take no responsibilities for any errors in the code or damage thereby.
You are free to use, modify and distribute the code as long as authorship is properly acknowledged.
Please notify me at<EMAIL_ADDRESS>if the code is used in commercial applications.


General Sources
{{macro.displaySourceList(general)}}
Business Sources
{{macro.displaySourceList(business)}}
Entertainment Sources
{{macro.displaySourceList(entertainment)}}
Health Sources
{{macro.displaySourceList(health)}}
Technology Sources
{{macro.displaySourceList(technology)}}
Sports Sources
{{macro.displaySourceList(sports)}}


var assert = require('assert');
var assert = require('assert');
The Connection class manages HTTP/2 connections. Each instance corresponds to one transport stream (TCP stream). It operates by sending and receiving frames and is implemented as a Flow subclass.
var Flow = require('./flow').Flow;
exports.Connection = Connection;
new Connection(log, firstStreamId, settings): create a new Connection
Event: 'error' (type): signals a connection level error made by the other end
Event: 'peerError' (type): signals the receipt of a GOAWAY frame that contains an error code other than NO_ERROR
Event: 'stream' (stream): signals that there's an incoming stream
createStream(): stream: initiate a new stream
set(settings): change the value of one or more settings according to the key-value pairs
of settings
ping([callback]): send a ping and call callback when the answer arrives
close([error]): close the stream with an error code
The main aspects of managing the connection are:
function Connection(log, firstStreamId, settings) {
Flow.call(this, 0);
this._log = log.child({ component: 'connection' });
this._initializeStreamManagement(firstStreamId);
this._initializeLifecycleManagement();
this._initializeFlowControl();
this._initializeSettingsManagement(settings);
this._initializeMultiplexing();
}
Connection.prototype = Object.create(Flow.prototype, { constructor: { value: Connection } });
| ^ | ^
v | v |
+--------------+ +--------------+
+---| stream1 |---| stream2 |---- .... ---+
| | +----------+ | | +----------+ | |
| | | stream1. | | | | stream2. | | |
| +-| upstream |-+ +-| upstream |-+ |
| +----------+ +----------+ |
| | ^ | ^ |
| v | v | |
| +-----+-------------+-----+-------- .... |
| ^ | | | |
| | v | | |
| +--------------+ | | |
| | stream0 | | | |
| | connection | | | |
| | management | multiplexing |
| +--------------+ flow control |
| | ^ |
| _read() | | _write() |
| v | |
| +------------+ +-----------+ |
| |output queue| |input queue| |
+----------------+------------+-+-----------+-----------------+
| ^
read() | | write()
v |
var Stream = require('./stream').Stream;
Initialization:
Connection.prototype._initializeStreamManagement = function _initializeStreamManagement(firstStreamId) {
_streamIds
is an id -> stream map of the streams that are allowed to receive frames._streamPriorities
is a priority -> [stream] map of stream that allowed to send frames. this._streamIds = [];
this._streamPriorities = [];
this._nextStreamId = firstStreamId;
this._lastIncomingStream = 0;
_writeControlFrame
when there's an incoming stream with 0 as stream ID this._streamIds[0] = { upstream: { write: this._writeControlFrame.bind(this) } };
_streamLimit
can
be set by the SETTINGS_MAX_CONCURRENT_STREAMS setting. this._streamSlotsFree = Infinity;
this._streamLimit = Infinity;
this.on('RECEIVING_SETTINGS_MAX_CONCURRENT_STREAMS', this._updateStreamLimit);
};
_writeControlFrame
is called when there's an incoming frame in the _control
stream. It
broadcasts the message by creating an event on it.
Connection.prototype._writeControlFrame = function _writeControlFrame(frame) {
if ((frame.type === 'SETTINGS') || (frame.type === 'PING') ||
(frame.type === 'GOAWAY') || (frame.type === 'WINDOW_UPDATE')) {
this._log.debug({ frame: frame }, 'Receiving connection level frame');
this.emit(frame.type, frame);
} else {
this._log.error({ frame: frame }, 'Invalid connection level frame');
this.emit('error', 'PROTOCOL_ERROR');
}
};
Methods to manage the stream slot pool:
Connection.prototype._updateStreamLimit = function _updateStreamLimit(newStreamLimit) {
var wakeup = (this._streamSlotsFree === 0) && (newStreamLimit > this._streamLimit);
this._streamSlotsFree += newStreamLimit - this._streamLimit;
this._streamLimit = newStreamLimit;
if (wakeup) {
this.emit('wakeup');
}
};
Connection.prototype._changeStreamCount = function _changeStreamCount(change) {
if (change) {
this._log.trace({ free: this._streamSlotsFree, change: change },
'Changing active stream count.');
var wakeup = (this._streamSlotsFree === 0) && (change < 0);
this._streamSlotsFree -= change;
if (wakeup) {
this.emit('wakeup');
}
}
};
Creating a new inbound or outbound stream with the given id
(which is undefined in case of
an outbound stream) consists of three steps:
Allocating an ID to a stream
Connection.prototype._allocateId = function _allocateId(stream, id) {
if (id === undefined) {
id = this._nextStreamId;
this._nextStreamId += 2;
}
else if ((id > this._lastIncomingStream) && ((id - this._nextStreamId) % 2 !== 0)) {
this._lastIncomingStream = id;
}
else {
this._log.error({ stream_id: id, lastIncomingStream: this._lastIncomingStream },
'Invalid incoming stream ID.');
this.emit('error', 'PROTOCOL_ERROR');
return undefined;
}
assert(!(id in this._streamIds));
this._streamIds
this._log.trace({ s: stream, stream_id: id }, 'Allocating ID for stream.');
this._streamIds[id] = stream;
stream.id = id;
this.emit('new_stream', stream, id);
stream.on('error', this.emit.bind(this, 'error'));
return id;
};
Allocating a priority to a stream, and managing priority changes
Connection.prototype._allocatePriority = function _allocatePriority(stream) {
this._log.trace({ s: stream }, 'Allocating priority for stream.');
this._insert(stream, stream._priority);
stream.on('priority', this._reprioritize.bind(this, stream));
stream.upstream.on('readable', this.emit.bind(this, 'wakeup'));
this.emit('wakeup');
};
Connection.prototype._insert = function _insert(stream, priority) {
if (priority in this._streamPriorities) {
this._streamPriorities[priority].push(stream);
} else {
this._streamPriorities[priority] = [stream];
}
};
Connection.prototype._reprioritize = function _reprioritize(stream, priority) {
var bucket = this._streamPriorities[stream._priority];
var index = bucket.indexOf(stream);
assert(index !== -1);
bucket.splice(index, 1);
if (bucket.length === 0) {
delete this._streamPriorities[stream._priority];
}
this._insert(stream, priority);
};
Creating an inbound stream with the given ID. It is called when there's an incoming frame to a previously nonexistent stream.
Connection.prototype._createIncomingStream = function _createIncomingStream(id) {
this._log.debug({ stream_id: id }, 'New incoming stream.');
var stream = new Stream(this._log);
this._allocateId(stream, id);
this._allocatePriority(stream);
this.emit('stream', stream, id);
return stream;
};
Creating an outbound stream
Connection.prototype.createStream = function createStream() {
this._log.trace('Creating new outbound stream.');
var stream = new Stream(this._log);
this._allocatePriority(stream);
return stream;
};
Connection.prototype._initializeMultiplexing = function _initializeMultiplexing() {
this.on('window_update', this.emit.bind(this, 'wakeup'));
this._sendScheduled = false;
this._firstFrameReceived = false;
};
The _send
method is a virtual method of the Flow class that has to be implemented
by child classes. It reads frames from streams and pushes them to the output buffer.
Connection.prototype._send = function _send(immediate) {
if (this._closed) {
return;
}
if (immediate) {
this._sendScheduled = false;
} else {
if (!this._sendScheduled) {
this._sendScheduled = true;
setImmediate(this._send.bind(this, true));
}
return;
}
this._log.trace('Starting forwarding frames from streams.');
bucket
s in priority order.priority_loop:
for (var priority in this._streamPriorities) {
var bucket = this._streamPriorities[priority];
var nextBucket = [];
streamCount
greater than streamLimit
, skip
this streamstreamCount
as appropriate while (bucket.length > 0) {
for (var index = 0; index < bucket.length; index++) {
var stream = bucket[index];
var frame = stream.upstream.read((this._window > 0) ? this._window : -1);
if (!frame) {
continue;
} else if (frame.count_change > this._streamSlotsFree) {
stream.upstream.unshift(frame);
continue;
}
nextBucket.push(stream);
if (frame.stream === undefined) {
frame.stream = stream.id || this._allocateId(stream);
}
if (frame.type === 'PUSH_PROMISE') {
this._allocatePriority(frame.promised_stream);
frame.promised_stream = this._allocateId(frame.promised_stream);
}
this._log.trace({ s: stream, frame: frame }, 'Forwarding outgoing frame');
var moreNeeded = this.push(frame);
this._changeStreamCount(frame.count_change);
assert(moreNeeded !== null); // The frame shouldn't be unforwarded
if (moreNeeded === false) {
break priority_loop;
}
}
bucket = nextBucket;
nextBucket = [];
}
}
if (moreNeeded === undefined) {
this.once('wakeup', this._send.bind(this));
}
this._log.trace({ moreNeeded: moreNeeded }, 'Stopping forwarding frames from streams.');
};
The _receive
method is another virtual method of the Flow class that has to be
implemented by child classes. It forwards the given frame to the appropriate stream:
Connection.prototype._receive = function _receive(frame, done) {
this._log.trace({ frame: frame }, 'Forwarding incoming frame');
_onFirstFrameReceived
method if (!this._firstFrameReceived) {
this._firstFrameReceived = true;
this._onFirstFrameReceived(frame);
}
var stream = this._streamIds[frame.stream];
this.streams
if (!stream) {
stream = this._createIncomingStream(frame.stream);
}
if (frame.type === 'PUSH_PROMISE') {
frame.promised_stream = this._createIncomingStream(frame.promised_stream);
}
frame.count_change = this._changeStreamCount.bind(this);
stream
's upstream
stream.upstream.write(frame);
done();
};
var defaultSettings = {
SETTINGS_FLOW_CONTROL_OPTIONS: true
};
Settings management initialization:
Connection.prototype._initializeSettingsManagement = function _initializeSettingsManagement(settings) {
this._log.debug({ settings: settings },
'Sending the first SETTINGS frame as part of the connection header.');
this.set(settings || defaultSettings);
_receiveSettings
method this.on('SETTINGS', this._receiveSettings);
};
Connection.prototype._onFirstFrameReceived = function _onFirstFrameReceived(frame) {
if ((frame.stream === 0) && (frame.type === 'SETTINGS')) {
this._log.debug({ settings: frame.settings },
'Receiving the first SETTINGS frame as part of the connection header.');
} else {
this._log.fatal({ frame: frame }, 'Invalid connection header: first frame is not SETTINGS.');
this.emit('error');
}
};
Handling of incoming SETTINGS frames.
Connection.prototype._receiveSettings = function _receiveSettings(frame) {
for (var name in frame.settings) {
this.emit('RECEIVING_' + name, frame.settings[name]);
}
};
Changing one or more settings value and sending out a SETTINGS frame
Connection.prototype.set = function set(settings) {
this.push({
type: 'SETTINGS',
flags: {},
stream: 0,
settings: settings
});
for (var name in settings) {
this.emit('SENDING_' + name, settings[name]);
}
};
The main responsibilities of lifecycle management code:
Connection.prototype._initializeLifecycleManagement = function _initializeLifecycleManagement() {
this._pings = {};
this.on('PING', this._receivePing);
this.on('GOAWAY', this._receiveGoaway);
this._closed = false;
};
Generating a string of length 16 with random hexadecimal digits
Connection.prototype._generatePingId = function _generatePingId() {
do {
var id = '';
for (var i = 0; i < 16; i++) {
id += Math.floor(Math.random()*16).toString(16);
}
} while(id in this._pings);
return id;
};
Sending a ping and calling callback
when the answer arrives
Connection.prototype.ping = function ping(callback) {
var id = this._generatePingId();
var data = new Buffer(id, 'hex');
this._pings[id] = callback;
this._log.debug({ data: data }, 'Sending PING.');
this.push({
type: 'PING',
flags: {
PONG: false
},
stream: 0,
data: data
});
};
Answering pings
Connection.prototype._receivePing = function _receivePing(frame) {
if (frame.flags.PONG) {
var id = frame.data.toString('hex');
if (id in this._pings) {
this._log.debug({ data: frame.data }, 'Receiving answer for a PING.');
var callback = this._pings[id];
if (callback) {
callback();
}
delete this._pings[id];
} else {
this._log.warn({ data: frame.data }, 'Unsolicited PING answer.');
}
} else {
this._log.debug({ data: frame.data }, 'Answering PING.');
this.push({
type: 'PING',
flags: {
PONG: true
},
stream: 0,
data: frame.data
});
}
};
Terminating the connection
Connection.prototype.close = function close(error) {
if (this._closed) {
this._log.warn('Trying to close an already closed connection');
return;
}
this._log.debug({ error: error }, 'Closing the connection');
this.push({
type: 'GOAWAY',
flags: {},
stream: 0,
last_stream: this._lastIncomingStream,
error: error || 'NO_ERROR'
});
this.push(null);
this._closed = true;
};
Connection.prototype._receiveGoaway = function _receiveGoaway(frame) {
this._log.debug({ error: frame.error }, 'Other end closed the connection');
this.push(null);
this._closed = true;
if (frame.error !== 'NO_ERROR') {
this.emit('peerError', frame.error);
}
};
Connection.prototype._initializeFlowControl = function _initializeFlowControl() {
Handling of initial window size of individual streams.
this._initialStreamWindowSize = INITIAL_STREAM_WINDOW_SIZE;
this.on('new_stream', function(stream) {
stream.upstream.setInitialWindow(this._initialStreamWindowSize);
if (this._remoteFlowControlDisabled) {
stream.upstream.disableRemoteFlowControl();
}
});
this.on('RECEIVING_SETTINGS_INITIAL_WINDOW_SIZE', this._setInitialStreamWindowSize);
this.on('RECEIVING_SETTINGS_FLOW_CONTROL_OPTIONS', this._setLocalFlowControl);
this.on('SENDING_SETTINGS_FLOW_CONTROL_OPTIONS', this._setRemoteFlowControl);
this._streamIds[0].upstream.setInitialWindow = function noop() {};
this._streamIds[0].upstream.disableRemoteFlowControl = function noop() {};
};
The initial connection flow control window is 65535 bytes.
var INITIAL_STREAM_WINDOW_SIZE = 65535;
A SETTINGS frame can alter the initial flow control window size for all current streams. When the
value of SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver MUST adjust the window size of all
stream by calling the setInitialStreamWindowSize
method. The window size has to be modified by
the difference between the new value and the old value.
Connection.prototype._setInitialStreamWindowSize = function _setInitialStreamWindowSize(size) {
if ((this._initialStreamWindowSize === Infinity) && (size !== Infinity)) {
this._log.error('Trying to manipulate initial flow control window size after flow control was turned off.');
this.emit('error', 'FLOW_CONTROL_ERROR');
} else {
this._log.debug({ size: size }, 'Changing stream initial window size.');
this._initialStreamWindowSize = size;
this._streamIds.forEach(function(stream) {
stream.upstream.setInitialWindow(size);
});
}
};
_setStreamFlowControl()
may be used to disable/enable flow control. In practice, it is just
for turning off flow control since it can not be turned on.
Connection.prototype._setLocalFlowControl = function _setLocalFlowControl(disable) {
if (disable) {
this._increaseWindow(Infinity);
this._setInitialStreamWindowSize(Infinity);
} else if (this._initialStreamWindowSize === Infinity) {
this._log.error('Trying to re-enable flow control after it was turned off.');
this.emit('error', 'FLOW_CONTROL_ERROR');
}
};
Connection.prototype._setRemoteFlowControl = function _setRemoteFlowControl(disable) {
if (disable) {
this.disableRemoteFlowControl();
this._streamIds.forEach(function(stream) {
stream.upstream.disableRemoteFlowControl();
});
} else if (this._remoteFlowControlDisabled) {
this._log.error('Trying to re-enable flow control after it was turned off.');
throw new Error('Trying to re-enable flow control after it was turned off.');
}
};