class BasicSocket
BasicSocket is the super class for all the Socket classes.
Public Class Methods
Gets the global ::do_not_reverse_lookup flag.
BasicSocket.do_not_reverse_lookup #=> false
static VALUE bsock_do_not_rev_lookup(void) { return rsock_do_not_reverse_lookup?Qtrue:Qfalse; }
Sets the global ::do_not_reverse_lookup flag.
The flag is used for initial value of ::do_not_reverse_lookup for each socket.
s1 = TCPSocket.new("localhost", 80) p s1.do_not_reverse_lookup #=> true BasicSocket.do_not_reverse_lookup = false s2 = TCPSocket.new("localhost", 80) p s2.do_not_reverse_lookup #=> false p s1.do_not_reverse_lookup #=> true
static VALUE bsock_do_not_rev_lookup_set(VALUE self, VALUE val) { rsock_do_not_reverse_lookup = RTEST(val); return val; }
Returns a socket object which contains the file descriptor, fd.
# If invoked by inetd, STDIN/STDOUT/STDERR is a socket. STDIN_SOCK = Socket.for_fd(STDIN.fileno) p STDIN_SOCK.remote_address
static VALUE bsock_s_for_fd(VALUE klass, VALUE fd) { rb_io_t *fptr; VALUE sock = rsock_init_sock(rb_obj_alloc(klass), NUM2INT(fd)); GetOpenFile(sock, fptr); return sock; }
Public Instance Methods
Disallows further read using shutdown system call.
s1, s2 = UNIXSocket.pair s1.close_read s2.puts #=> Broken pipe (Errno::EPIPE)
static VALUE bsock_close_read(VALUE sock) { rb_io_t *fptr; GetOpenFile(sock, fptr); shutdown(fptr->fd, 0); if (!(fptr->mode & FMODE_WRITABLE)) { return rb_io_close(sock); } fptr->mode &= ~FMODE_READABLE; return Qnil; }
Disallows further write using shutdown system call.
UNIXSocket.pair {|s1, s2| s1.print "ping" s1.close_write p s2.read #=> "ping" s2.print "pong" s2.close p s1.read #=> "pong" }
static VALUE bsock_close_write(VALUE sock) { rb_io_t *fptr; GetOpenFile(sock, fptr); if (!(fptr->mode & FMODE_READABLE)) { return rb_io_close(sock); } shutdown(fptr->fd, 1); fptr->mode &= ~FMODE_WRITABLE; return Qnil; }
Returns an address of the socket suitable for connect in the local machine.
This method returns self.local_address, except following condition.
-
IPv4 unspecified address (<IP_ADDRESS>) is replaced by IPv4 loopback address (<IP_ADDRESS>).
-
IPv6 unspecified address (::) is replaced by IPv6 loopback address (::1).
If the local address is not suitable for connect, SocketError is raised. IPv4 and IPv6 address which port is 0 is not suitable for connect. Unix domain socket which has no path is not suitable for connect.
Addrinfo.tcp("<IP_ADDRESS>", 0).listen {|serv| p serv.connect_address #=> #<Addrinfo: <IP_ADDRESS>:53660 TCP> serv.connect_address.connect {|c| s, _ = serv.accept p [c, s] #=> [#<Socket:fd 4>, #<Socket:fd 6>] } }
# File ext/socket/lib/socket.rb, line 250 def connect_address addr = local_address afamily = addr.afamily if afamily == Socket::AF_INET raise SocketError, "unbound IPv4 socket" if addr.ip_port == 0 if addr.ip_address == "<IP_ADDRESS>" addr = Addrinfo.new(["AF_INET", addr.ip_port, nil, "<IP_ADDRESS>"], addr.pfamily, addr.socktype, addr.protocol) end elsif defined?(Socket::AF_INET6) && afamily == Socket::AF_INET6 raise SocketError, "unbound IPv6 socket" if addr.ip_port == 0 if addr.ip_address == "::" addr = Addrinfo.new(["AF_INET6", addr.ip_port, nil, "::1"], addr.pfamily, addr.socktype, addr.protocol) elsif addr.ip_address == "<IP_ADDRESS>" # MacOS X 10.4 returns "a.b.c.d" for IPv4-mapped IPv6 address. addr = Addrinfo.new(["AF_INET6", addr.ip_port, nil, "::1"], addr.pfamily, addr.socktype, addr.protocol) elsif addr.ip_address == "::ffff:<IP_ADDRESS>" # MacOS X 10.6 returns "::ffff:a.b.c.d" for IPv4-mapped IPv6 address. addr = Addrinfo.new(["AF_INET6", addr.ip_port, nil, "::1"], addr.pfamily, addr.socktype, addr.protocol) end elsif defined?(Socket::AF_UNIX) && afamily == Socket::AF_UNIX raise SocketError, "unbound Unix socket" if addr.unix_path == "" end addr end
Gets the ::do_not_reverse_lookup flag of basicsocket.
require 'socket' BasicSocket.do_not_reverse_lookup = false TCPSocket.open("www.ruby-lang.org", 80) {|sock| p sock.do_not_reverse_lookup #=> false } BasicSocket.do_not_reverse_lookup = true TCPSocket.open("www.ruby-lang.org", 80) {|sock| p sock.do_not_reverse_lookup #=> true }
static VALUE bsock_do_not_reverse_lookup(VALUE sock) { rb_io_t *fptr; GetOpenFile(sock, fptr); return (fptr->mode & FMODE_NOREVLOOKUP) ? Qtrue : Qfalse; }
Sets the ::do_not_reverse_lookup flag of basicsocket.
TCPSocket.open("www.ruby-lang.org", 80) {|sock| p sock.do_not_reverse_lookup #=> true p sock.peeraddr #=> ["AF_INET", 80, "<IP_ADDRESS>", "<IP_ADDRESS>"] sock.do_not_reverse_lookup = false p sock.peeraddr #=> ["AF_INET", 80, "carbon.ruby-lang.org", "<IP_ADDRESS>"] }
static VALUE bsock_do_not_reverse_lookup_set(VALUE sock, VALUE state) { rb_io_t *fptr; GetOpenFile(sock, fptr); if (RTEST(state)) { fptr->mode |= FMODE_NOREVLOOKUP; } else { fptr->mode &= ~FMODE_NOREVLOOKUP; } return sock; }
Returns the user and group on the peer of the UNIX socket. The result is a two element array which contains the effective uid and the effective gid.
Socket.unix_server_loop("/tmp/sock") {|s| begin euid, egid = s.getpeereid # Check the connected client is myself or not. next if euid != Process.uid # do something about my resource. ensure s.close end }
static VALUE bsock_getpeereid(VALUE self) { #if defined(HAVE_GETPEEREID) rb_io_t *fptr; uid_t euid; gid_t egid; GetOpenFile(self, fptr); if (getpeereid(fptr->fd, &euid, &egid) == -1) rb_sys_fail("getpeereid(3)"); return rb_assoc_new(UIDT2NUM(euid), GIDT2NUM(egid)); #elif defined(SO_PEERCRED) /* GNU/Linux */ rb_io_t *fptr; struct ucred cred; socklen_t len = sizeof(cred); GetOpenFile(self, fptr); if (getsockopt(fptr->fd, SOL_SOCKET, SO_PEERCRED, &cred, &len) == -1) rb_sys_fail("getsockopt(SO_PEERCRED)"); return rb_assoc_new(UIDT2NUM(cred.uid), GIDT2NUM(cred.gid)); #elif defined(HAVE_GETPEERUCRED) /* Solaris */ rb_io_t *fptr; ucred_t *uc = NULL; VALUE ret; GetOpenFile(self, fptr); if (getpeerucred(fptr->fd, &uc) == -1) rb_sys_fail("getpeerucred(3C)"); ret = rb_assoc_new(UIDT2NUM(ucred_geteuid(uc)), GIDT2NUM(ucred_getegid(uc))); ucred_free(uc); return ret; #endif }
Returns the remote address of the socket as a sockaddr string.
TCPServer.open("<IP_ADDRESS>", 1440) {|serv| c = TCPSocket.new("<IP_ADDRESS>", 1440) s = serv.accept p s.getpeername #=> "\x02\x00\x82u\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00" }
If Addrinfo object is preferred over the binary string, use #remote_address.
static VALUE bsock_getpeername(VALUE sock) { union_sockaddr buf; socklen_t len = (socklen_t)sizeof buf; socklen_t len0 = len; rb_io_t *fptr; GetOpenFile(sock, fptr); if (getpeername(fptr->fd, &buf.addr, &len) < 0) rb_sys_fail("getpeername(2)"); if (len0 < len) len = len0; return rb_str_new((char*)&buf, len); }
Returns the local address of the socket as a sockaddr string.
TCPServer.open("<IP_ADDRESS>", 15120) {|serv| p serv.getsockname #=> "\x02\x00;\x10\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00" }
If Addrinfo object is preferred over the binary string, use #local_address.
static VALUE bsock_getsockname(VALUE sock) { union_sockaddr buf; socklen_t len = (socklen_t)sizeof buf; socklen_t len0 = len; rb_io_t *fptr; GetOpenFile(sock, fptr); if (getsockname(fptr->fd, &buf.addr, &len) < 0) rb_sys_fail("getsockname(2)"); if (len0 < len) len = len0; return rb_str_new((char*)&buf, len); }
Gets a socket option. These are protocol and system specific, see your local system documentation for details. The option is returned as a Socket::Option object.
Parameters¶ ↑
-
level
is an integer, usually one of the SOL_ constants such as Socket::SOL_SOCKET, or a protocol level. A string or symbol of the name, possibly without prefix, is also accepted. -
optname
is an integer, usually one of the SO_ constants, such as Socket::SO_REUSEADDR. A string or symbol of the name, possibly without prefix, is also accepted.
Examples¶ ↑
Some socket options are integers with boolean values, in this case getsockopt could be called like this:
reuseaddr = sock.getsockopt(:SOCKET, :REUSEADDR).bool optval = sock.getsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR) optval = optval.unpack "i" reuseaddr = optval[0] == 0 ? false : true
Some socket options are integers with numeric values, in this case getsockopt could be called like this:
ipttl = sock.getsockopt(:IP, :TTL).int optval = sock.getsockopt(Socket::IPPROTO_IP, Socket::IP_TTL) ipttl = optval.unpack("i")[0]
Option values may be structs. Decoding them can be complex as it involves examining your system headers to determine the correct definition. An example is a +struct linger+, which may be defined in your system headers as:
struct linger { int l_onoff; int l_linger; };
In this case getsockopt could be called like this:
# Socket::Option knows linger structure. onoff, linger = sock.getsockopt(:SOCKET, :LINGER).linger optval = sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER) onoff, linger = optval.unpack "ii" onoff = onoff == 0 ? false : true
static VALUE bsock_getsockopt(VALUE sock, VALUE lev, VALUE optname) { int level, option; socklen_t len; char *buf; rb_io_t *fptr; int family; GetOpenFile(sock, fptr); family = rsock_getfamily(fptr); level = rsock_level_arg(family, lev); option = rsock_optname_arg(family, level, optname); len = 256; buf = ALLOCA_N(char,len); rb_io_check_closed(fptr); if (getsockopt(fptr->fd, level, option, buf, &len) < 0) rsock_sys_fail_path("getsockopt(2)", fptr->pathv); return rsock_sockopt_new(family, level, option, rb_str_new(buf, len)); }
Returns an Addrinfo object for local address obtained by getsockname.
Note that addrinfo.protocol is filled by 0.
TCPSocket.open("www.ruby-lang.org", 80) {|s| p s.local_address #=> #<Addrinfo: <IP_ADDRESS>:36873 TCP> } TCPServer.open("<IP_ADDRESS>", 1512) {|serv| p serv.local_address #=> #<Addrinfo: <IP_ADDRESS>:1512 TCP> }
static VALUE bsock_local_address(VALUE sock) { union_sockaddr buf; socklen_t len = (socklen_t)sizeof buf; socklen_t len0 = len; rb_io_t *fptr; GetOpenFile(sock, fptr); if (getsockname(fptr->fd, &buf.addr, &len) < 0) rb_sys_fail("getsockname(2)"); if (len0 < len) len = len0; return rsock_fd_socket_addrinfo(fptr->fd, &buf.addr, len); }
Receives a message.
maxlen is the maximum number of bytes to receive.
flags should be a bitwise OR of Socket::MSG_* constants.
outbuf will contain only the received data after the method call even if it is not empty at the beginning.
UNIXSocket.pair {|s1, s2| s1.puts "Hello World" p s2.recv(4) #=> "Hell" p s2.recv(4, Socket::MSG_PEEK) #=> "o Wo" p s2.recv(4) #=> "o Wo" p s2.recv(10) #=> "rld\n" }
static VALUE bsock_recv(int argc, VALUE *argv, VALUE sock) { return rsock_s_recvfrom(sock, argc, argv, RECV_RECV); }
Receives up to maxlen bytes from socket
using
recvfrom(2) after O_NONBLOCK is set for the underlying file descriptor.
flags is zero or more of the MSG_
options. The
result, mesg, is the data received.
When recvfrom(2) returns 0, #recv_nonblock returns an empty string as data. The meaning depends on the socket: EOF on TCP, empty packet on UDP, etc.
Parameters¶ ↑
-
maxlen
- the number of bytes to receive from the socket -
flags
- zero or more of theMSG_
options -
options
- keyword hash, supporting `exception: false`
Example¶ ↑
serv = TCPServer.new("<IP_ADDRESS>", 0) af, port, host, addr = serv.addr c = TCPSocket.new(addr, port) s = serv.accept c.send "aaa", 0 begin # emulate blocking recv. p s.recv_nonblock(10) #=> "aaa" rescue IO::WaitReadable IO.select([s]) retry end
Refer to Socket#recvfrom for the exceptions that may be thrown if the call to recv_nonblock fails.
#recv_nonblock may raise any error corresponding to recvfrom(2) failure, including Errno::EWOULDBLOCK.
If the exception is Errno::EWOULDBLOCK or Errno::EAGAIN, it is extended by IO::WaitReadable. So IO::WaitReadable can be used to rescue the exceptions for retrying recv_nonblock.
By specifying a keyword argument exception to false
,
you can indicate that #recv_nonblock should
not raise an IO::WaitReadable exception,
but return the symbol :wait_readable
instead.
See¶ ↑
# File ext/socket/lib/socket.rb, line 369 def recv_nonblock(len, flag = 0, str = nil, exception: true) __recv_nonblock(len, flag, str, exception) end
recvmsg receives a message using recvmsg(2) system call in blocking manner.
maxmesglen is the maximum length of mesg to receive.
flags is bitwise OR of MSG_* constants such as Socket::MSG_PEEK.
maxcontrollen is the maximum length of controls (ancillary data) to receive.
opts is option hash. Currently :scm_rights=>bool is the only option.
:scm_rights option specifies that application expects SCM_RIGHTS control message. If the value is nil or false, application don't expects SCM_RIGHTS control message. In this case, recvmsg closes the passed file descriptors immediately. This is the default behavior.
If :scm_rights value is neither nil nor false, application expects SCM_RIGHTS control message. In this case, recvmsg creates IO objects for each file descriptors for Socket::AncillaryData#unix_rights method.
The return value is 4-elements array.
mesg is a string of the received message.
sender_addrinfo is a sender socket address for connection-less socket. It is an Addrinfo object. For connection-oriented socket such as TCP, sender_addrinfo is platform dependent.
rflags is a flags on the received message which is bitwise OR of MSG_* constants such as Socket::MSG_TRUNC. It will be nil if the system uses 4.3BSD style old recvmsg system call.
controls is ancillary data which is an array of Socket::AncillaryData objects such as:
#<Socket::AncillaryData: AF_UNIX SOCKET RIGHTS 7>
maxmesglen and maxcontrollen can be nil. In that case, the buffer will be grown until the message is not truncated. Internally, MSG_PEEK is used. Buffer full and MSG_CTRUNC are checked for truncation.
recvmsg can be used to implement recv_io as follows:
mesg, sender_sockaddr, rflags, *controls = sock.recvmsg(:scm_rights=>true) controls.each {|ancdata| if ancdata.cmsg_is?(:SOCKET, :RIGHTS) return ancdata.unix_rights[0] end }
# File ext/socket/lib/socket.rb, line 424 def recvmsg(dlen = nil, flags = 0, clen = nil, scm_rights: false) __recvmsg(dlen, flags, clen, scm_rights) end
recvmsg receives a message using recvmsg(2) system call in non-blocking manner.
It is similar to #recvmsg but non-blocking flag is set before the system call and it doesn't retry the system call.
By specifying a keyword argument exception to false
,
you can indicate that #recvmsg_nonblock
should not raise an IO::WaitReadable
exception, but return the symbol :wait_readable
instead.
# File ext/socket/lib/socket.rb, line 440 def recvmsg_nonblock(dlen = nil, flags = 0, clen = nil, scm_rights: false, exception: true) __recvmsg_nonblock(dlen, flags, clen, scm_rights, exception) end
Returns an Addrinfo object for remote address obtained by getpeername.
Note that addrinfo.protocol is filled by 0.
TCPSocket.open("www.ruby-lang.org", 80) {|s| p s.remote_address #=> #<Addrinfo: <IP_ADDRESS>:80 TCP> } TCPServer.open("<IP_ADDRESS>", 1728) {|serv| c = TCPSocket.new("<IP_ADDRESS>", 1728) s = serv.accept p s.remote_address #=> #<Addrinfo: <IP_ADDRESS>:36504 TCP> }
static VALUE bsock_remote_address(VALUE sock) { union_sockaddr buf; socklen_t len = (socklen_t)sizeof buf; socklen_t len0 = len; rb_io_t *fptr; GetOpenFile(sock, fptr); if (getpeername(fptr->fd, &buf.addr, &len) < 0) rb_sys_fail("getpeername(2)"); if (len0 < len) len = len0; return rsock_fd_socket_addrinfo(fptr->fd, &buf.addr, len); }
send mesg via basicsocket.
mesg should be a string.
flags should be a bitwise OR of Socket::MSG_* constants.
dest_sockaddr should be a packed sockaddr string or an addrinfo.
TCPSocket.open("localhost", 80) {|s| s.send "GET / HTTP/1.0\r\n\r\n", 0 p s.read }
VALUE rsock_bsock_send(int argc, VALUE *argv, VALUE sock) { struct rsock_send_arg arg; VALUE flags, to; rb_io_t *fptr; int n; rb_blocking_function_t *func; rb_scan_args(argc, argv, "21", &arg.mesg, &flags, &to); StringValue(arg.mesg); if (!NIL_P(to)) { SockAddrStringValue(to); to = rb_str_new4(to); arg.to = (struct sockaddr *)RSTRING_PTR(to); arg.tolen = RSTRING_SOCKLEN(to); func = rsock_sendto_blocking; } else { func = rsock_send_blocking; } GetOpenFile(sock, fptr); arg.fd = fptr->fd; arg.flags = NUM2INT(flags); while (rsock_maybe_fd_writable(arg.fd), (n = (int)BLOCKING_REGION_FD(func, &arg)) < 0) { if (rb_io_wait_writable(arg.fd)) { continue; } rb_sys_fail("send(2)"); } return INT2FIX(n); }
sendmsg sends a message using sendmsg(2) system call in blocking manner.
mesg is a string to send.
flags is bitwise OR of MSG_* constants such as Socket::MSG_OOB.
dest_sockaddr is a destination socket address for connection-less socket. It should be a sockaddr such as a result of Socket.sockaddr_in. An Addrinfo object can be used too.
controls is a list of ancillary data. The element of controls should be Socket::AncillaryData or 3-elements array. The 3-element array should contains cmsg_level, cmsg_type and data.
The return value, numbytes_sent is an integer which is the number of bytes sent.
sendmsg can be used to implement send_io as follows:
# use Socket::AncillaryData. ancdata = Socket::AncillaryData.int(:UNIX, :SOCKET, :RIGHTS, io.fileno) sock.sendmsg("a", 0, nil, ancdata) # use 3-element array. ancdata = [:SOCKET, :RIGHTS, [io.fileno].pack("i!")] sock.sendmsg("\0", 0, nil, ancdata)
# File ext/socket/lib/socket.rb, line 302 def sendmsg(mesg, flags = 0, dest_sockaddr = nil, *controls) __sendmsg(mesg, flags, dest_sockaddr, controls) end
#sendmsg_nonblock sends a message using sendmsg(2) system call in non-blocking manner.
It is similar to #sendmsg but the non-blocking flag is set before the system call and it doesn't retry the system call.
By specifying a keyword argument exception to false
,
you can indicate that #sendmsg_nonblock
should not raise an IO::WaitWritable
exception, but return the symbol :wait_writable
instead.
# File ext/socket/lib/socket.rb, line 318 def sendmsg_nonblock(mesg, flags = 0, dest_sockaddr = nil, *controls, exception: true) __sendmsg_nonblock(mesg, flags, dest_sockaddr, controls, exception) end
Sets a socket option. These are protocol and system specific, see your local system documentation for details.
Parameters¶ ↑
-
level
is an integer, usually one of the SOL_ constants such as Socket::SOL_SOCKET, or a protocol level. A string or symbol of the name, possibly without prefix, is also accepted. -
optname
is an integer, usually one of the SO_ constants, such as Socket::SO_REUSEADDR. A string or symbol of the name, possibly without prefix, is also accepted. -
optval
is the value of the option, it is passed to the underlying setsockopt() as a pointer to a certain number of bytes. How this is done depends on the type:-
Integer: value is assigned to an int, and a pointer to the int is passed, with length of sizeof(int).
-
true or false: 1 or 0 (respectively) is assigned to an int, and the int is passed as for an Integer. Note that
false
must be passed, notnil
. -
String: the string's data and length is passed to the socket.
-
-
socketoption
is an instance of Socket::Option
Examples¶ ↑
Some socket options are integers with boolean values, in this case setsockopt could be called like this:
sock.setsockopt(:SOCKET, :REUSEADDR, true) sock.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true) sock.setsockopt(Socket::Option.bool(:INET, :SOCKET, :REUSEADDR, true))
Some socket options are integers with numeric values, in this case setsockopt could be called like this:
sock.setsockopt(:IP, :TTL, 255) sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_TTL, 255) sock.setsockopt(Socket::Option.int(:INET, :IP, :TTL, 255))
Option values may be structs. Passing them can be complex as it involves
examining your system headers to determine the correct definition. An
example is an ip_mreq
, which may be defined in your system
headers as:
struct ip_mreq { struct in_addr imr_multiaddr; struct in_addr imr_interface; };
In this case setsockopt could be called like this:
optval = IPAddr.new("<IP_ADDRESS>").hton + IPAddr.new(Socket::INADDR_ANY, Socket::AF_INET).hton sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, optval)
static VALUE bsock_setsockopt(int argc, VALUE *argv, VALUE sock) { VALUE lev, optname, val; int family, level, option; rb_io_t *fptr; int i; char *v; int vlen; if (argc == 1) { lev = rb_funcall(argv[0], rb_intern("level"), 0); optname = rb_funcall(argv[0], rb_intern("optname"), 0); val = rb_funcall(argv[0], rb_intern("data"), 0); } else { rb_scan_args(argc, argv, "30", &lev, &optname, &val); } GetOpenFile(sock, fptr); family = rsock_getfamily(fptr); level = rsock_level_arg(family, lev); option = rsock_optname_arg(family, level, optname); switch (TYPE(val)) { case T_FIXNUM: i = FIX2INT(val); goto numval; case T_FALSE: i = 0; goto numval; case T_TRUE: i = 1; numval: v = (char*)&i; vlen = (int)sizeof(i); break; default: StringValue(val); v = RSTRING_PTR(val); vlen = RSTRING_SOCKLEN(val); break; } rb_io_check_closed(fptr); if (setsockopt(fptr->fd, level, option, v, vlen) < 0) rsock_sys_fail_path("setsockopt(2)", fptr->pathv); return INT2FIX(0); }
Calls shutdown(2) system call.
s.shutdown(Socket::SHUT_RD) disallows further read.
s.shutdown(Socket::SHUT_WR) disallows further write.
s.shutdown(Socket::SHUT_RDWR) disallows further read and write.
how can be symbol or string:
-
:RD, :SHUT_RD, “RD” and “SHUT_RD” are accepted as Socket::SHUT_RD.
-
:WR, :SHUT_WR, “WR” and “SHUT_WR” are accepted as Socket::SHUT_WR.
-
:RDWR, :SHUT_RDWR, “RDWR” and “SHUT_RDWR” are accepted as Socket::SHUT_RDWR.
UNIXSocket.pair {|s1, s2|
s1.puts "ping" s1.shutdown(:WR) p s2.read #=> "ping\n" s2.puts "pong" s2.close p s1.read #=> "pong\n"
}
static VALUE bsock_shutdown(int argc, VALUE *argv, VALUE sock) { VALUE howto; int how; rb_io_t *fptr; rb_scan_args(argc, argv, "01", &howto); if (howto == Qnil) how = SHUT_RDWR; else { how = rsock_shutdown_how_arg(howto); if (how != SHUT_WR && how != SHUT_RD && how != SHUT_RDWR) { rb_raise(rb_eArgError, "`how' should be either :SHUT_RD, :SHUT_WR, :SHUT_RDWR"); } } GetOpenFile(sock, fptr); if (shutdown(fptr->fd, how) == -1) rb_sys_fail("shutdown(2)"); return INT2FIX(0); }


Uncle Tom's Cabin (Told to the Children)
by Harriet Beecher Stowe
Chapter 17: Eva's Last Good-Bye
Additional Information
- Year Published: 1852
- Language: English
- Country of Origin: United States of America
- Source: Stowe, H. B. (1852). Uncle Tom's Cabin (Told to the Children). H. E. Marshall, (Ed.).
-
Readability:
- Flesch–Kincaid Level: 3.7
- Word Count: 1,134
- Genre: Historical Fiction
- Keywords: 19th century literature, american literature
- ✎ Cite This
Downloads
It soon became quite plain to everybody that Eva was very ill indeed. She never ran about and played now, but spent most of the day lying on the sofa in her own pretty room.
Every one loved her, and tried to do things for her. Even naughty little Topsy used to bring her flowers, and try to be good for her sake.
Uncle Tom was a great deal in Eva's room. She used to get very restless, and then she liked to be carried about. He was so big and strong that he could do it very easily. He would walk about with her under the orange–trees in the garden, or sitting down on some of their old seats, would sing their favorite hymns.
He loved to do it, and could not bear to be long away from his little mistress. He gave up sleeping in his bed, and lay all night on the mat outside her door.
One day Eva made her aunt cut off a lot of her beautiful hair. Then she called all the slaves together, said good–bye to them, and gave them each a curl of her hair as a keepsake. They all cried very much and said they would never forget her, and would try to be good for her sake.
A few nights later Miss Ophelia came quickly to Tom, as he lay on the mat outside Eva's door. 'Go, Tom,' she said, 'go as fast as you can for the doctor.'
Tom ran. But in the morning little Eva lay on her bed, cold and white, with closed eyes and folded hands.
She had gone to God.
Mr. St. Clare was very, very unhappy for a long time after Eva died. He had loved her so much, that now his life seemed quite empty without her.
He did not forget his promise to her about Tom. He went to his lawyer, and told him to begin writing out the papers that would make Tom free. It took some time to make a slave free.
'Well, Tom,' said Mr. St. Clare the day after he had spoken to his lawyer, 'I'm going to make a free man of you. So have your trunk packed and get ready to set out for home.'
Joy shone in Uncle Tom's face. 'Bless the Lord,' he said, raising his hands to heaven.
Mr. St. Clare felt rather hurt. He did not like Tom to be so glad to leave him.
'You haven't had such a very bad time here that you need be such rapture, Tom,' he said.
'No, no, mas'r! tan't that. It's bein' a free man! That's what I'm joyin' for.'
'Why, Tom, don't you think that you are really better off as you are?'
'No, indeed, Mas'r St. Clare,' said Tom, very decidedly; 'no, indeed.'
'But, Tom, you couldn't possibly have earned by your work such clothes and such nice, comfortable rooms and good food as I have given you.'
'I knows all that, Mas'r St. Clare. Mas'r has been too good. But, mas'r, I'd rather have poor clothes, poor house, poor everything, and have 'em mine than have the best, and have 'em any man's else. I had so, mas'r. I thinks it's nature, mas'r.'
'I suppose so, Tom. You will be going off and leaving me, in a month or two,' he said, rather discontentedly. 'Though why you shouldn't, I don't know,' he added, in a gayer voice.
'Not while mas'r is in trouble,' said Tom. 'I'll stay with mas'r as long as he wants me—so as I can be of any use.'
'Not while I am in trouble, Tom?' said Mr. St. Clare, looking sadly out of the window. 'And when will my trouble be over?' Then half–smiling he turned from the window, and laid his hand on Tom's shoulder.  'I won't keep you. Go home to your wife and children, and give them all my love.'
'Cousin,' said Miss Ophelia, coming into the room, 'I want to speak to you about Topsy.'
'What has she been doing now?'
'Nothing; she is a much better girl than she used to be. But I want to ask you, whose is she—yours or mine?'
'Why yours, of course; I gave her to you,' said Mr. St. Clare.
'But not by law. There is no use my trying to make this child a Christian, unless I can be quite sure that she will not be sold as a slave again. If you are really willing I should have her, I want you to give me a paper saying she is mine.'
'But you think it is wicked to keep slaves. Now you want to have one of your own. Oh! shocking, cousin,' said Mr. St. Clare, who loved to tease.
'Nonsense! I only want to have her, so that I can set her free.'
'Very well,' said Mr. St. Clare, 'I will write the paper for you.' Then he sat down and began to read.
'But I want it done now,' said Miss Ophelia.
'Why are you in such a hurry?'
'Because now is the only time there ever is to do a thing in,' said Miss Ophelia. 'I want to make sure of it.  Then Topsy would be taken away and sold, in spite of anything I could say.'
Mr. St. Clare hated being made to do things when he didn't want to. However, after teasing his cousin a little more, he wrote out the paper, and Topsy belonged to Miss Ophelia. That evening Mr. St. Clare went out for a walk.
Tom saw him go, and asked if he should come too. 'No, my boy,' said Mr. St. Clare, 'I shall be back in an hour.'
Tom sat down on the verandah to wait till his master came home. While he waited, he fell asleep.
Presently he was awakened by loud knocking, and the sound of voices at the gate.
He ran to open it.
Several men were there carrying a load. It was Mr. St. Clare. He had been hurt in an accident, and was dying.
Very gently they laid him on a sofa. Nothing could be done.


Hi! I am Yu Wu (吴俣). I obtained my B.S. and Ph.D. degree at Beihang University. During my Ph.D. career, I was supervised by Professor Ming Zhou and Zhoujun Li in a joint program of Beihang University and Microsoft Research Asia. From July 2013 to May 2019, I was a full time intern of Microsoft Research Asia. I joined Microsoft Research Asia (MSRA) in June 2019 as an Associate Researcher.
I have adequent experiences in building open domain chatbot. During my five-years internship in MSRA, I developed several key algorithms for Chatbot, some of which are published in top tier conferences and transfer to XiaoIce. You can find more details on my Google Scholar or on my Curriculum vitae. I also enjoy innovation projects, and I participated in the music creation project (incl. lyrics generation, melody composition and background accompanying).
Research interests
I collaborated with Wei Wu, Furu Wei and Shujie Liu on several key products of Micorosoft, such as: XiaoIce, Musely and so on.
I study hard core problems of chatbots and speech language processing, such as multi-turn response generation, dialog model pre-training, end-to-end ASR, and TTS.


Aurobindo Pharma receives 8 US FDA observations for two of its facilities
Observations are related to procedural improvements, not data integrity, says the company
by BS ReporterAurobindo Pharma on Wednesday said the US Food and Drug Administration (US FDA) had issued Form 483 with 4 observations each for two of its manufacturing facilities — Unit 5 API facility at Pashamailaram and Unit 8 API facility at Gaddapotharam in Hyderabad.
The company said the latest inspections by the US drug regulator were conducted from October 21 to 28 at the first facility, and from October 21 to 25 at the second. A similar inspection at Unit 4 formulations facility at Pashamailaram was currently under way, it said.
"We believe that these observations are related to procedural improvements and none of these relates to data integrity. The company will respond to the US FDA within the prescribed timelines," Aurobindo said in a filing.


Every year when I watch the Oscars I'm annoyed…
that films like King Kong, Moulin Rouge and Munich get the statue whilst the real cinematic heroes lose out. Not very Hollywood is it?
We’re here to put things right.
these should have won »that films like King Kong, Moulin Rouge and Munich get the statue whilst the real cinematic heroes lose out. Not very Hollywood is it?
We’re here to put things right.
these should have won »


1 Introduction to Mix
In this guide, we will learn how to build a complete Elixir application, with its own supervision tree, configuration, tests and more.
The application works as a distributed key-value store. We are going to organize key-value pairs into buckets and distribute those buckets across multiple nodes. We will also build a simple client that allows us to connect to any of those nodes and send requests such as:
CREATE shopping
OK
PUT shopping milk 1
OK
PUT shopping eggs 3
OK
GET shopping milk
1
OK
DELETE shopping eggs
OK
In order to build our key-value application, we are going to use three main tools:
OTP is a set of libraries that ships with Erlang. Erlang developers use OTP to build robust, fault-tolerant applications. In this chapter we will explore how many aspects from OTP integrate with Elixir, including supervision trees, event managers and more;
Mix is a build tool that ships with Elixir that provides tasks for creating, compiling, testing your application, managing its dependencies and much more;
ExUnit is a test-unit based framework that ships with Elixir;
In this chapter, we will create our first project using Mix and explore different features in OTP, Mix and ExUnit as we go.
Note: this guide requires Elixir v0.15.0 or later. You can check your Elixir version with
elixir -v
and install a more recent version if required by following the steps described in the first chapter of the Getting Started guide.If you have any questions or improvements to the guide, please let us know in our mailing list or issues tracker respectively. Your input is really important to help us guarantee the guides are accessible and up to date!
1.1 Our first project
When you install Elixir, besides getting the elixir
, elixirc
and iex
executables, you also get an executable Elixir script named mix
.
Let's create our first project by invoking mix new
from the command line. We'll pass the project name as argument (kv
, in this case), and tell mix that our main module should be the all-uppercase KV
, instead of the default, which would have been Kv
:
$ mix new kv --module KV
Mix will create a directory named kv
with a few files in it:
* creating README.md
* creating .gitignore
* creating mix.exs
* creating config
* creating config/config.exs
* creating lib
* creating lib/kv.ex
* creating test
* creating test/test_helper.exs
* creating test/kv_test.exs
Let's take a brief look at those generated files.
Note: Mix is an Elixir executable. This means that in order to run
mix
, you need to have elixir's executable in your PATH. If not, you can run it by passing the script as argument to elixir:$ bin/elixir bin/mix new kv --module KV
Note that you can also execute any script in your PATH from Elixir via the -S option:
$ bin/elixir -S mix new kv --module KV
When using -S, elixir finds the script wherever it is in your PATH and executes it.
1.2 Project compilation
A file named mix.exs
was generated inside our new project and its main responsibility is to configure our project. Let's take a look at it (comments removed):
defmodule KV.Mixfile do
use Mix.Project
def project do
[app: :kv,
version: "0.0.1",
deps: deps]
end
def application do
[applications: [:logger]]
end
defp deps do
[]
end
end
Our mix.exs
defines two public functions: project
, which returns project configuration like the project name and version, and application
, which is used to generate an application file.
There is also a private function named deps
, which is invoked from the project
function, that defines our project dependencies. Defining deps
as a separate function is not required, but it helps keep the project configuration tidy.
Mix also generates a file at lib/kv.ex
with a simple module definition:
defmodule KV do
end
This structure is enough to compile our project:
$ mix compile
Will generate:
Compiled lib/kv.ex
Generated kv.app
Notice the lib/kv.ex
file was compiled and kv.app
file was generated. This .app
file is generated with the information from the application/0
function in the mix.exs
file. We will further explore mix.exs
configuration features in future chapters.
Once the project is compiled, you can start an iex
session inside the project by running:
$ iex -S mix
1.3 Running tests
Mix also generated the appropriate structure for running our project tests. Mix projects usually follow the convention of having a <filename>_test.exs
file in the test
directory for each file in the lib
directory. For this reason, we can already find a test/kv_test.exs
corresponding to our lib/kv.ex
file. It doesn't do much at this point:
defmodule KVTest do
use ExUnit.Case
test "the truth" do
assert 1 + 1 == 2
end
end
It is important to note a couple things:
the test file is an Elixir script file (
.exs
). This is convenient because we don't need to compile test files before running them;we define a test module named
KVTest
, useExUnit.Case
to inject the testing API and define a simple test using thetest/2
macro;
Mix also generated a file named test/test_helper.exs
which is responsible for setting up the test framework:
ExUnit.start
This file will be automatically required by Mix every time before we run our tests. We can run tests with mix test
:
Compiled lib/kv.ex
Generated kv.app
.
Finished in 0.04 seconds (0.04s on load, 0.00s on tests)
1 tests, 0 failures
Randomized with seed 540224
Notice that by running mix test
, Mix has compiled the source files and generated the application file once again. This happens because Mix supports multiple environments, which we will explore in the next section.
Furthermore, you can see that ExUnit prints a dot for each successful test and automatically randomizes tests too. Let's make the test fail on purpose and see what happens.
Change the assertion in test/kv_test.exs
to the following:
assert 1 + 1 == 3
Now run mix test
again (notice this time there was no compilation):
1) test the truth (KVTest)
test/kv_test.exs:4
Assertion with == failed
code: 1 + 1 == 3
lhs: 2
rhs: 3
stacktrace:
test/kv_test.exs:5
Finished in 0.05 seconds (0.05s on load, 0.00s on tests)
1 tests, 1 failures
For each failure, ExUnit prints a detailed report, containing the test name with the test case, the code that failed and the values for the left-hand side (lhs) and right-hand side (rhs) of the ==
operator.
In the second line of the failure, right below the test name, there is the location the test was defined. If you copy the test location in the second line, containing the file and line, and paste it in-front of mix test
, Mix will load and run just that particular test:
$ mix test test/kv_test.exs:4
This shortcut will be extremely useful as we build our project, allowing us to quickly iterate by running just a specific test.
Finally, the stacktrace relates to the failure itself, giving information about the test and often the place the failure was generated from within the source files.
1.4 Environments
Mix supports the concept of "environments". They allow a developer to customize compilation and other options for specific scenarios. By default, Mix understands three environments:
:dev
- the one in which mix tasks (likecompile
) run by default:test
- used bymix test
:prod
- the one you will use to put your project in production
Note: If you add dependencies to your project, they will not inherit your project's environment, but instead run with their
:prod
environment settings!
By default, these environments behave the same and all configuration we have seen so far will affect all three environments. Customization per environment can be done by accessing the Mix.env
function in your mix.exs
file, which returns the current environment as an atom:
def project do
[deps_path: deps_path(Mix.env)]
end
defp deps_path(:prod), do: "prod_deps"
defp deps_path(_), do: "deps"
Mix will default to the :dev
environment, except for the test
task that will default to the :test
environment. The environment can be changed via the MIX_ENV
environment variable:
$ MIX_ENV=prod mix compile
1.5 Exploring
There is much more to Mix, and we will continue to explore it as we build our project. A general overview is available on the Mix documentation.
Keep in mind that you can always invoke the help task to list all available tasks:
$ mix help
You can get further information about a particular task by invoking mix help TASK
.
Let's write some code!


Hello
Welcome to example of app for codecetjs tests with typescript.
Don't use it as an example of web-development.
Some parts of app have duplications, app has terrific design and its elements are terrible like a web 1.0 pages.
Use this app as an E2E test example only.
It's not the only truth. But it has the right to exist.
Look into folders, see how does files are ordered, how typescript config is set, how tests are placed in one git project with app itself.
And make your own solution.
Good luck.
Structure of example app
This app is simple and contains several pages: main page, about page


-
Initial Patient Population =
- AND: FIRST: "Occurrence A of Diagnosis, Active: Alcohol and Drug Dependence" <= 11 month(s) starts after start of "Measurement
Period"
- AND: "Patient Characteristic Birthdate: birth date" >= 13 year(s) starts before start of "Measurement Period"
- AND: "Occurrence A of Diagnosis, Active: Alcohol and Drug Dependence" starts during
- OR: "Occurrence A of Encounter, Performed: Office Visit"
- OR: "Occurrence A of Encounter, Performed: Emergency Department Visit"
- OR: "Occurrence A of Encounter, Performed: Detoxification Visit"
- OR: "Occurrence A of Encounter, Performed: Hospital Observation Care - Initial"
- OR: "Occurrence A of Encounter, Performed: Hospital Inpatient Visit - Initial"
- OR: "Occurrence A of Encounter, Performed: Discharge Services - Hospital Inpatient Same Day Discharge"
- OR: "Occurrence A of Encounter, Performed: Discharge Services - Hospital Inpatient"
- OR: "Occurrence A of Encounter, Performed: Face-to-Face Interaction"
- during "Measurement Period"
-
Denominator =
- AND: "Initial Patient Population"
-
Denominator Exclusions =
- AND: "Occurrence A of Diagnosis, Active: Alcohol and Drug Dependence" <= 60 day(s) starts before start of "Occurrence A of
Diagnosis, Active: Alcohol and Drug Dependence"
-
Numerator 1 =
- AND:
- OR: "Occurrence A of Encounter, Performed: Alcohol and Drug Dependence Treatment"
- OR: "Occurrence A of Encounter, Performed: Psych Visit - Individual Outpatient Interactive Psychotherapy"
- OR: "Occurrence A of Encounter, Performed: Psych Visit - Individual Outpatient Psychotherapy"
- <= 14 day(s) starts after start of "Occurrence A of Diagnosis, Active: Alcohol and Drug Dependence"
-
Numerator 2 =
- AND:
- OR:
- AND: "Occurrence A of Encounter, Performed: Alcohol and Drug Dependence Treatment" <= 14 day(s) starts after start of "Occurrence
A of Diagnosis, Active: Alcohol and Drug Dependence"
- AND: Count >= 2 of:
- OR: "Encounter, Performed: Alcohol and Drug Dependence Treatment"
- OR: "Encounter, Performed: Psych Visit - Individual Outpatient Interactive Psychotherapy"
- OR: "Encounter, Performed: Psych Visit - Individual Outpatient Psychotherapy"
- <= 30 day(s) starts after start of "Occurrence A of Encounter, Performed: Alcohol and Drug Dependence Treatment"
- OR:
- AND: "Occurrence A of Encounter, Performed: Psych Visit - Individual Outpatient Interactive Psychotherapy" <= 14 day(s) starts
after start of "Occurrence A of Diagnosis, Active: Alcohol and Drug Dependence"
- AND: Count >= 2 of:
- OR: "Encounter, Performed: Alcohol and Drug Dependence Treatment"
- OR: "Encounter, Performed: Psych Visit - Individual Outpatient Interactive Psychotherapy"
- OR: "Encounter, Performed: Psych Visit - Individual Outpatient Psychotherapy"
- <= 30 day(s) starts after start of "Occurrence A of Encounter, Performed: Psych Visit - Individual Outpatient Interactive
Psychotherapy"
- OR:
- AND: "Occurrence A of Encounter, Performed: Psych Visit - Individual Outpatient Psychotherapy" <= 14 day(s) starts after
start of "Occurrence A of Diagnosis, Active: Alcohol and Drug Dependence"
- AND: Count >= 2 of:
- OR: "Encounter, Performed: Alcohol and Drug Dependence Treatment"
- OR: "Encounter, Performed: Psych Visit - Individual Outpatient Interactive Psychotherapy"
- OR: "Encounter, Performed: Psych Visit - Individual Outpatient Psychotherapy"
- <= 30 day(s) starts after start of "Occurrence A of Encounter, Performed: Psych Visit - Individual Outpatient Psychotherapy"
-
Denominator Exceptions =
-
"Diagnosis, Active: Alcohol and Drug Dependence" using "Alcohol and Drug Dependence Grouping Value Set (2.16.840.1.113883.3.464.1<IP_ADDRESS>1)"
-
"Encounter, Performed: Alcohol and Drug Dependence Treatment" using "Alcohol and Drug Dependence Treatment Grouping Value Set (2.16.840.1.113883.3.464.1<IP_ADDRESS>5)"
-
"Encounter, Performed: Detoxification Visit" using "Detoxification Visit Grouping Value Set (2.16.840.1.113883.3.464.1<IP_ADDRESS>9)"
-
"Encounter, Performed: Discharge Services - Hospital Inpatient" using "Discharge Services - Hospital Inpatient Grouping Value Set (2.16.840.1.113883.3.464.1<IP_ADDRESS>7)"
-
"Encounter, Performed: Discharge Services - Hospital Inpatient Same Day Discharge" using "Discharge Services - Hospital Inpatient Same Day Discharge Grouping Value Set (2.16.840.1.113883.3.464.1<IP_ADDRESS>6)"
-
"Encounter, Performed: Emergency Department Visit" using "Emergency Department Visit Grouping Value Set (2.16.840.1.113883.3.464.1<IP_ADDRESS>0)"
-
"Encounter, Performed: Face-to-Face Interaction" using "Face-to-Face Interaction Grouping Value Set (2.16.840.1.113883.3.464.1<IP_ADDRESS>8)"
-
"Encounter, Performed: Hospital Inpatient Visit - Initial" using "Hospital Inpatient Visit - Initial Grouping Value Set (2.16.840.1.113883.3.464.1<IP_ADDRESS>4)"
-
"Encounter, Performed: Hospital Observation Care - Initial" using "Hospital Observation Care - Initial Grouping Value Set (2.16.840.1.113883.3.464.1<IP_ADDRESS>2)"
-
"Encounter, Performed: Office Visit" using "Office Visit Grouping Value Set (2.16.840.1.113883.3.464.1<IP_ADDRESS>1)"
-
"Encounter, Performed: Psych Visit - Individual Outpatient Interactive Psychotherapy" using "Psych Visit - Individual Outpatient Interactive Psychotherapy Grouping Value Set (2.16.840.1.113883.3.526.3.1015)"
-
"Encounter, Performed: Psych Visit - Individual Outpatient Psychotherapy" using "Psych Visit - Individual Outpatient Psychotherapy Grouping Value Set (2.16.840.1.113883.3.526.3.1014)"
-
"Patient Characteristic Birthdate: birth date" using "birth date LOINC Value Set (2.16.840.1.113883.3.560.100.4)"
-
Reporting Stratum 1 =
- AND: "Patient Characteristic Birthdate: birth date" >= 13 year(s) starts before start of "Measurement Period"
- AND: "Patient Characteristic Birthdate: birth date" <= 17 year(s) starts before start of "Measurement Period"
-
Reporting Stratum 2 =
- AND: "Patient Characteristic Birthdate: birth date" >= 18 year(s) starts before start of "Measurement Period"
-
"Patient Characteristic Ethnicity: Ethnicity" using "Ethnicity CDC Value Set (2.16.840.1.114<IP_ADDRESS>7)"
-
"Patient Characteristic Payer: Payer" using "Payer Source of Payment Typology Value Set (2.16.840.1.114<IP_ADDRESS>91)"
-
"Patient Characteristic Race: Race" using "Race CDC Value Set (2.16.840.1.114<IP_ADDRESS>6)"
-
"Patient Characteristic Sex: ONC Administrative Sex" using "ONC Administrative Sex Administrative Sex Value Set (2.16.840.1.1137<IP_ADDRESS>)"


--- layout: post date: 2011-05-14 time: "09:00:00" authors: ["Greg Wilson"] title: More Interested in the Asides tags: ["Noticed"] ---
So how did the term go, you ask? Here's what traffic on this site looked like:
The three spikes in March where we had up to ten times our usual 250-a-day visitors were the articles on tuple spaces, literate programming, and graph layout—in other words, the articles that weren't about teaching scientists and engineers basic computational skills. As the man said, "So it goes."


Start Area - only way is right
Path is locked.
Thank you for trying out Explorer!
Key is to the right.
Key found.


The integration service allows to capture money from a PayPal account in a one step process without initiating a separate authorization before.
It will do so by sending an authorization request to the PAYONE platform.
It will store information about such a request as an interface interaction of type
PAYONE_INTERACTION_REQUEST.
Given the following payments for a Paydirekt account that does not support charges for currencies other than EUR:
| Payment Name | Cent Amount | Currency Code | Payment ID (for information only) | Success URL (for information only) | Error URL (for information only) | Cancel URL (for information only) |
|---|---|---|---|---|---|---|
| Payment 1 | 406 | EUR | ||||
| Payment 2 | 91341 | USD | ||||
| Payment 3 | 6113 | EUR | ||||
| Payment 4 | 11283 | EUR |
When I request the integration service to handle them I will get the following results:
| Payment Name | Response Status Code |
total # of authorization requests sent |
Transaction State | Version (for information only) |
|---|---|---|---|---|
| Payment 1 | 200 | 1 | Pending | |
| Payment 2 | 200 | 1 | Failure | |
| Payment 3 | 200 | 1 | Pending | |
| Payment 4 | 200 | 1 | Pending |
The transaction will stay in state Pending as long as we don't follow the received redirect URL and authorize the payment for this account.
| Payment Name | Transaction State | redirect URL contains 'https://sandbox.paydirekt.de/checkout/' | full redirect URL (for information only) | Version (for information only) |
|---|---|---|---|---|
| Payment 1 | Pending | true | ||
| Payment 3 | Pending | true | ||
| Payment 4 | Pending | true |
The service ensures idempotence, hence when I request it to handle the same payments again then I will get the same results as before, especially the total number of requests sent per payment must not change:
| Payment Name | Response Status Code |
total # of authorization requests sent |
Transaction State | Version (for information only) |
|---|---|---|---|---|
| Payment 1 | 200 | 1 | Pending | |
| Payment 2 | 200 | 1 | Failure | |
| Payment 3 | 200 | 1 | Pending | |
| Payment 4 | 200 | 1 | Pending |
The failed payment Payment 2 must have received 0 responses of type PAYONE_INTERACTION_REDIRECT and its custom field redirectUrl must be null.
If I follow the Paydirect process for Payment 1, Payment 3, Payment 4 and verify them successfully by entering my bank account information, I get forwarded to a predefined success url and for each of the payments the following notifications will be received:
| Payment Name | Transaction State | redirect URL contains 'https://sandbox.paydirekt.de/checkout/' | full redirect URL (for information only) | Version (for information only) |
|---|---|---|---|---|
| Payment 1 | Success | true | ||
| Payment 3 | Success | true | ||
| Payment 4 | Success | true |


Abigail Higham
Menu
About Me
Tableau Portfolio
Code Portfolio
Resume
Contact Me
Hello!
Welcome to my online portoflio
Portuguese Writing Example
Fluent in Spanish & Portuguese. Here is an example of my writing
Posted by
Abigail Higham
on August 2, 2018
Water Rights & Disputes
What moral obligations do riparian states have to other states that share the same water source?
Posted by
Abigail Higham
on August 2, 2018
Statistical Analysis
Data analytics and statistical analysis business case
Posted by
Abigail Higham
on August 2, 2018


| I l@ve RuBoard |
16.7 PyForm: A Persistent Object ViewerRather than going into additional database interface details that are freely available at python.org, I'm going to close out this chapter by showing you one way to combine the GUI technology we met earlier in the text with the persistence techniques introduced in this chapter. This section presents PyForm,a Tkinter GUI designed to let you browse and edit tables of records:
Although this example is about GUIs and persistence, it also illustrates Python design techniques. To keep its implementation both simple and type-independent, the PyForm GUI is coded to expect tables to look like dictionaries of dictionaries. To support a variety of table and record types, PyForm relies on separate wrapper classes to translate tables and records to the expected protocol:
The net effect is that PyForm can be used to browse and edit a wide variety of table types, despite its dictionary interface expectations. When PyForm browses shelves and DBM files, table changes made within the GUI are persistent -- they are saved in the underlying files. When used to browse a shelve of class instances, PyForm essentially becomes a GUI frontend to a simple object database, one built using standard Python persistence tools. 16.7.1 Doing It the Hard WayBefore we get to the GUI, though, let's see why you'd want one in the first place. To experiment with shelves in general, I first coded a canned test data file. The script in Example 16-4 hardcodes a dictionary used to populate databases (cast), as well as a class used to populate shelves of class instances (Actor). Example 16-4. PP2E\Dbase\testdata.py# definitions for testing shelves, dbm, and formgui cast = { 'rob': {'name': ('Rob', 'P'), 'job': 'writer', 'spouse': 'Laura'}, 'buddy': {'name': ('Buddy', 'S'), 'job': 'writer', 'spouse': 'Pickles'}, 'sally': {'name': ('Sally', 'R'), 'job': 'writer'}, 'laura': {'name': ('Laura', 'P'), 'spouse': 'Rob', 'kids':1}, 'milly': {'name': ('Milly', '?'), 'spouse': 'Jerry', 'kids':2}, 'mel': {'name': ('Mel', 'C'), 'job': 'producer'}, 'alan': {'name': ('Alan', 'B'), 'job': 'comedian'} } class Actor: # unnested file-level class def __init__(self, name=( ), job=''): # no need for arg defaults, self.name = name # for new pickler or formgui self.job = job def __setattr__(self, attr, value): # on setattr( ): validate if attr == 'kids' and value > 10: # but set it regardless print 'validation error: kids =', value if attr == 'name' and type(value) != type(( )): print 'validation error: name type =', type(value) self.__dict__[attr] = value # don't trigger __setattr__ The cast object here is intended to represent a table of records (it's really a dictionary of dictionaries when written out in Python syntax like this). Now, given this test data, it's easy to populate a shelve with cast dictionaries. Simply open a shelve and copy over cast, key for key, as shown in Example 16-5. Example 16-5. PP2E\Dbase\castinit.pyimport shelve from testdata import cast db = shelve.open('data/castfile') # create a new shelve for key in cast.keys( ): db[key] = cast[key] # store dictionaries in shelve Once you've done that, it's almost as easy to verify your work with a script that prints the contents of the shelve, as shown in Example 16-6. Example 16-6. PP2E\Dbase\castdump.pyimport shelve db = shelve.open('data/castfile') # reopen shelve for key in db.keys( ): # show each key,value print key, db[key] Here are these two scripts in action, populating and displaying a shelve of dictionaries: C:\...\PP2E\Dbase>python castinit.py C:\...\PP2E\Dbase>python castdump.py alan {'job': 'comedian', 'name': ('Alan', 'B')} mel {'job': 'producer', 'name': ('Mel', 'C')} buddy {'spouse': 'Pickles', 'job': 'writer', 'name': ('Buddy', 'S')} sally {'job': 'writer', 'name': ('Sally', 'R')} rob {'spouse': 'Laura', 'job': 'writer', 'name': ('Rob', 'P')} milly {'spouse': 'Jerry', 'name': ('Milly', '?'), 'kids': 2} laura {'spouse': 'Rob', 'name': ('Laura', 'P'), 'kids': 1} So far, so good. But here is where you reach the limitations of manual shelve processing: to modify a shelve, you need much more general tools. You could write little Python scripts that each perform very specific updates. Or you might even get by for awhile typing such update commands by hand in the interactive interpreter: >>> import shelve >>> db = shelve.open('data/castfile') >>> rec = db['rob'] >>> rec['job'] = 'hacker' >>> db['rob'] = rec For all but the most trivial databases, though, this will get tedious in a hurry -- especially for a system's end users. What you'd really like is a GUI that lets you view and edit shelves arbitrarily, and can be started up easily from other programs and scripts, as shown in Example 16-7. Example 16-7. PP2E\Dbase\castview.pyimport shelve from TableBrowser.formgui import FormGui # after initcast db = shelve.open('data/castfile') # reopen shelve file FormGui(db).mainloop( ) # browse existing shelve-of-dicts To make this particular script work, we need to move on to the next section. 16.7.2 Doing It the Graphical WayThe path traced in the last section really is what led me to write PyForm, a GUI tool for editing arbitrary tables of records. When those tables are shelves and DBM files, the data PyForm displays is persistent; it lives beyond the GUI's lifetime. Because of that, PyForm can be seen as a simple database browser. <IP_ADDRESS> PyForm GUI codeWe've already met all the GUI interfaces PyForm uses earlier in this book, so I won't go into all of its implementation details here (see the chapters in Part II, for background details). Before we see the code at all, though, let's see what it does. Figure 16-1 shows PyForm in action on Windows, browsing a shelve of persistent instance objects, created from the testdata module's Actor class. It looks slightly different but works the same on Linux and Macs. Figure 16-1. PyForm displaying a shelf of Actor objectsPyForm uses a three-window interface to the table being browsed; all windows are packed for proper window expansion and clipping, as set by the rules we studied earlier in this book. The window in the upper left of Figure 16-1 is the main window, created when PyForm starts; it has buttons for navigating through a table, finding items by key, and updating, creating, and deleting records (more useful when browsing tables that persist between runs). The table (dictionary) key of the record currently displayed shows up in the input field in the middle of this window. The "index" button pops up the listbox window in the upper right, and selecting a record in either window at the top creates the form window at the bottom. The form window is used both to display a record and to edit it -- if you change field values and press "store," the record is updated. Pressing "new" clears the form for input of new values (fill in the "Key=>" field and press "store" to save the new record). Field values are typed with Python syntax, so strings are quoted (more on this later). When browsing a table with records that contain different sets of field names, PyForm erases and redraws the form window for new field sets as new records are selected; to avoid seeing the window recreated, use the same format for all records within a given table. On to the code. The first thing I did when writing PyForm was to code utility functions to hide some of the details of widget creation. By making a few simplifying assumptions (e.g., packing protocol), the module in Example 16-8 helps keep some GUI coding details out of the rest of the PyForm implementation. Example 16-8. PP2E\Dbase\guitools.py# added extras for entry width, calcgui font/color from Tkinter import * def frame(root, side, **extras): widget = Frame(root) widget.pack(side=side, expand=YES, fill=BOTH) if extras: apply(widget.config, ( ), extras) return widget def label(root, side, text, **extras): widget = Label(root, text=text, relief=RIDGE) widget.pack(side=side, expand=YES, fill=BOTH) if extras: apply(widget.config, ( ), extras) return widget def button(root, side, text, command, **extras): widget = Button(root, text=text, command=command) widget.pack(side=side, expand=YES, fill=BOTH) if extras: apply(widget.config, ( ), extras) return widget def entry(root, side, linkvar, **extras): widget = Entry(root, relief=SUNKEN, textvariable=linkvar) widget.pack(side=side, expand=YES, fill=BOTH) if extras: apply(widget.config, ( ), extras) return widget Armed with this utility module, the file in Example 16-9 implements the rest of the PyForm GUI. It uses the GuiMixin module we wrote in Chapter 9, for simple access to standard popup dialogs. It's also coded as a class that can be specialized in subclasses, or attached to a larger GUI. I run PyForm as a standalone program. Attaching its FormGui class really attaches its main window only, but it can be used to provide a pre-coded table browser widget for other GUIs. This file's FormGui class creates the GUI shown in Figure 16-1, and responds to user interaction in all three of the interface's windows. Because we've already covered all the GUI tools that PyForm uses, you should study this module's source code listing for additional implementation details. Notice, though, that this file knows almost nothing about the table being browsed, other than that it looks and feels like a dictionary of dictionaries. To understand how PyForm supports browsing things like shelves of class instances, you will need to look elsewhere (or at least wait for the next module). Example 16-9. PP2E\Dbase\TableBrowser\formgui.py#!/usr/local/bin/python ############################################################################# # PyForm: a persistent table viewer GUI. Uses guimixin for std dialogs. # Assumes the browsed table has a dictionary-of-dictionary interface, and # relies on table wrapper classes to convert other structures as needed. # Store an initial record with dbinit script to start a dbase from scratch. # Caveat: doesn't do object method calls, shows complex field values poorly. ############################################################################# from Tkinter import * # Tk widgets from guitools import frame, label, button, entry # widget builders from PP2E.Gui.Tools.guimixin import GuiMixin # common methods class FormGui(GuiMixin, Frame): def __init__(self, mapping): # an extended frame Frame.__init__(self) # on default top-level self.pack(expand=YES, fill=BOTH) # all parts expandable self.master.title('PyForm 2.0 - Table browser') self.master.iconname("PyForm") self.makeMainBox( ) self.table = mapping # a dict, dbm, shelve, Table,.. self.index = mapping.keys( ) # list of table keys self.cursor = -1 # current index position self.currslots = [] # current form's (key,text)s self.currform = None # current form window self.listbox = None # index listbox window def makeMainBox(self): frm = frame(self, TOP) frm.config(bd=2) button(frm, LEFT, 'next', self.onNext) # next in list button(frm, LEFT, 'prev', self.onPrev) # backup in list button(frm, LEFT, 'find', self.onFind) # find from key frm = frame(self, TOP) self.keytext = StringVar( ) # current record's key label(frm, LEFT, 'KEY=>') # change before 'find' entry(frm, LEFT, self.keytext) frm = frame(self, TOP) frm.config(bd=2) button(frm, LEFT, 'store', self.onStore) # updated entry data button(frm, LEFT, 'new', self.onNew) # clear fields button(frm, LEFT, 'index', self.onMakeList) # show key list button(frm, LEFT, 'delete', self.onDelete) # show key list button(self, BOTTOM,'quit', self.quit) # from guimixin def onPrev(self): if self.cursor <= 0: self.infobox('Backup', "Front of table") else: self.cursor = self.cursor - 1 self.display( ) def onNext(self): if self.cursor >= len(self.index)-1: self.infobox('Advance', "End of table") else: self.cursor = self.cursor + 1 self.display( ) def sameKeys(self, record): # can we reuse the same form? keys1 = record.keys( ) keys2 = map(lambda x:x[0], self.currslots) keys1.sort(); keys2.sort( ) # keys list order differs return keys1 == keys2 # if insertion-order differs def display(self): key = self.index[self.cursor] # show record at index cursor self.keytext.set(key) # change key in main box record = self.table[key] # in dict, dbm, shelf, class if self.sameKeys(record): self.currform.title('PyForm - Key=' + `key`) for (field, text) in self.currslots: text.set(`record[field]`) # same fields? reuse form else: # expr `x` works like repr(x) if self.currform: self.currform.destroy( ) # different fields? new = Toplevel( ) # replace current box new.title('PyForm - Key=' + `key`) # new resizable window new.iconname("pform") left = frame(new, LEFT) right = frame(new, RIGHT) self.currslots = [] # list of (field, entry) for field in record.keys( ): label(left, TOP, `field`) # key,value to strings text = StringVar( ) # we could sort keys here text.set( `record[field]` ) entry(right, TOP, text, width=40) self.currslots.append((field, text)) self.currform = new new.protocol('WM_DELETE_WINDOW', lambda:0) # ignore destroy's self.selectlist( ) # update listbox def onStore(self): if not self.currform: return key = self.keytext.get( ) if key in self.index: # change existing record record = self.table[key] # not: self.table[key][field]= else: record = {} # create a new record self.index.append(key) # add to index and listbox if self.listbox: self.listbox.insert(END, key) # or at len(self.index)-1 for (field, text) in self.currslots: try: # fill out dictionary rec record[field] = eval(text.get( )) # convert back from string except: self.errorbox('Bad data: "%s" = "%s"' % (field, text.get( ))) record[field] = None self.table[key] = record # add to dict, dbm, shelf,... self.onFind(key) # readback: set cursor,listbox def onNew(self): if not self.currform: return # clear input form and key self.keytext.set('?%d' % len(self.index)) # default key unless typed for (field, text) in self.currslots: # clear key/fields for entry text.set('') self.currform.title('Key: ?') def onFind(self, key=None): target = key or self.keytext.get( ) # passed in, or entered try: self.cursor = self.index.index(target) # find label in keys list self.display( ) except: self.infobox('Not found', "Key doesn't exist", 'info') def onDelete(self): if not self.currform or not self.index: return currkey = self.index[self.cursor] del self.table[currkey] # table, index, listbox del self.index[self.cursor:self.cursor+1] # like "list[i:i+1] = []" if self.listbox: self.listbox.delete(self.cursor) # delete from listbox if self.cursor < len(self.index): self.display( ) # show next record if any elif self.cursor > 0: self.cursor = self.cursor-1 # show prior if delete end self.display( ) else: # leave box if delete last self.onNew( ) def onList(self,evnt): if not self.index: return # on listbox double-click index = self.listbox.curselection( ) # fetch selected key text label = self.listbox.get(index) # or use listbox.get(ACTIVE) self.onFind(label) # and call method here def onMakeList(self): if self.listbox: return # already up? new = Toplevel( ) # new resizable window new.title("PyForm - Key Index") # select keys from a listbox new.iconname("pindex") frm = frame(new, TOP) scroll = Scrollbar(frm) list = Listbox(frm, bg='white') scroll.config(command=list.yview, relief=SUNKEN) list.config(yscrollcommand=scroll.set, relief=SUNKEN) scroll.pack(side=RIGHT, fill=BOTH) list.pack(side=LEFT, expand=YES, fill=BOTH) # pack last, clip first for key in self.index: # add to list-box list.insert(END, key) # or: sort list first list.config(selectmode=SINGLE, setgrid=1) # select,resize modes list.bind('<Double-1>', self.onList) # on double-clicks self.listbox = list if self.index and self.cursor >= 0: # highlight position self.selectlist( ) new.protocol('WM_DELETE_WINDOW', lambda:0) # ignore destroy's def selectlist(self): # listbox tracks cursor if self.listbox: self.listbox.select_clear(0, self.listbox.size( )) self.listbox.select_set(self.cursor) if __name__ == '__main__': from PP2E.Dbase.testdata import cast # self-test code for k in cast.keys( ): print k, cast[k] # view in-memory dict-of-dicts FormGui(cast).mainloop( ) for k in cast.keys( ): print k, cast[k] # show modified table on exit The file's self-test code starts up the PyForm GUI to browse the in-memory dictionary of dictionaries called cast in the testdata module listed earlier. To start PyForm, you simply make and run the FormGui class object this file defines, passing in the table to be browsed. Here are the messages that show up in stdout after running this file and editing a few entries displayed in the GUI; the dictionary is displayed on GUI startup and exit: C:\...\PP2E\Dbase\TableBrowser>python formgui.py alan {'job': 'comedian', 'name': ('Alan', 'B')} sally {'job': 'writer', 'name': ('Sally', 'R')} rob {'spouse': 'Laura', 'job': 'writer', 'name': ('Rob', 'P')} mel {'job': 'producer', 'name': ('Mel', 'C')} milly {'spouse': 'Jerry', 'name': ('Milly', '?'), 'kids': 2} buddy {'spouse': 'Pickles', 'job': 'writer', 'name': ('Buddy', 'S')} laura {'spouse': 'Rob', 'name': ('Laura', 'P'), 'kids': 1} alan {'job': 'comedian', 'name': ('Alan', 'B')} jerry {'spouse': 'Milly', 'name': 'Jerry', 'kids': 0} sally {'job': 'writer', 'name': ('Sally', 'R')} rob {'spouse': 'Laura', 'job': 'writer', 'name': ('Rob', 'P')} mel {'job': 'producer', 'name': ('Mel', 'C')} milly {'spouse': 'Jerry', 'name': ('Milly', '?'), 'kids': 2} buddy {'spouse': 'Pickles', 'job': 'writer', 'name': ('Buddy', 'S')} laura {'name': ('Laura', 'P'), 'kids': 3, 'spouse': 'bob'} The last line (in bold) represents a change made in the GUI. Since this is an in-memory table, changes made in the GUI are not retained (dictionaries are not persistent by themselves). To see how to use the PyForm GUI on persistent stores like DBM files and shelves, we need to move on to the next topic. <IP_ADDRESS> PyForm table wrappersThe following file defines generic classes that "wrap" (interface with) various kinds of tables for use in PyForm. It's what makes PyForm useful for a variety of table types. The prior module was coded to handle GUI chores, and assumes that tables expose a dictionary-of-dictionaries interface. Conversely, this next module knows nothing about the GUI, but provides the translations necessary to browse non-dictionary objects in PyForm. In fact, this module doesn't even import Tkinter at all -- it strictly deals in object protocol conversions and nothing else. Because PyForm's implementation is divided into functionally distinct modules like this, it's easier to focus on each module's task in isolation. Here is the hook between the two modules: for special kinds of tables, PyForm's FormGui is passed an instance of the Table class coded here. The Table class intercepts table index fetch and assignment operations, and uses an embedded record wrapper class to convert records to and from dictionary format as needed. For example, because DBM files can store only strings, Table converts real dictionaries to and from their printable string representation on table stores and fetches. For class instances, Table extracts the object's __dict__ attribute dictionary on fetches, and copies a dictionary's fields to attributes of a newly generated class instance on stores.[3] The end result is that the GUI thinks the table is all dictionaries, even if it is really something very different here.
While you study this module's listing, shown in Example 16-10, notice that there is nothing here about the record formats of any particular database. In fact, there was none in the GUI-related formgui module either. Because neither module cares about the structure of fields used for database records, both can be used to browse arbitrary records. Example 16-10. PP2E\Dbase\formtable.py############################################################################# # PyForm table wrapper classes and tests # Because PyForm assumes a dictionary-of-dictionary interface, this module # converts strings and class instance records to and from dicts. PyForm # contains the table mapping--Table is not a PyForm subclass. Note that # some of the wrapper classes may be useful outside PyForm--DmbOfString can # wrap a dbm containing arbitrary datatypes. Run the dbinit scripts to # start a new database from scratch, and run the dbview script to browse # a database other than the one tested here. No longer requires classes to # have defaults in constructor args, and auto picks up record class from the # first one fetched if not passed in to class-record wrapper. Caveat: still # assumes that all instances in a table are instances of the same class. ############################################################################ ############################################################################# # records within tables ############################################################################# class DictionaryRecord: def todict(self, value): return value # to dictionary: no need to convert def fromdict(self, value): return value # from dictionary: no need to convert class StringRecord: def todict(self, value): return eval(value) # convert string to dictionary (or any) def fromdict(self, value): return str(value) # convert dictionary (or any) to string class InstanceRecord: def __init__(self, Class=None): # need class object to make instances self.Class = Class def todict(self, value): # convert instance to attr dictionary if not self.Class: # get class from obj if not yet known self.Class = value.__class__ return value.__dict__ def fromdict(self, value): # convert attr dictionary to instance try: class Dummy: pass # try what new pickle does instance = Dummy( ) # fails in restricted mode instance.__class__ = self.Class except: # else call class, no args instance = self.Class( ) # init args need defaults for attr in value.keys( ): setattr(instance, attr, value[attr]) # set instance attributes return instance # may run Class.__setattr__ ############################################################################# # table containing records ############################################################################# class Table: def __init__(self, mapping, converter): # table object, record converter self.table = mapping # wrap arbitrary table mapping self.record = converter # wrap arbitrary record types def storeItems(self, items): # initialize from dictionary for key in items.keys( ): # do __setitem__ to xlate, store self[key] = items[key] def printItems(self): # print wrapped mapping for key in self.keys( ): # do self.keys to get table keys print key, self[key] # do __getitem__ to fetch, xlate def __getitem__(self, key): # on tbl[key] index fetch rawval = self.table[key] # fetch from table mapping return self.record.todict(rawval) # translate to dictionary def __setitem__(self, key, value): # on tbl[key]=val index assign rawval = self.record.fromdict(value) # translate from dictionary self.table[key] = rawval # store in table mapping def __delitem__(self, key): # delete from table mapping del self.table[key] def keys(self): # get table mapping keys index return self.table.keys( ) def close(self): if hasattr(self.table, 'close'): # call table close if has one self.table.close( ) # may need for shelves, dbm ############################################################################# # table/record combinations ############################################################################# import shelve, anydbm def ShelveOfInstance(filename, Class=None): return Table(shelve.open(filename), InstanceRecord(Class)) def ShelveOfDictionary(filename): return Table(shelve.open(filename), DictionaryRecord( )) def ShelveOfString(filename): return Table(shelve.open(filename), StringRecord( )) def DbmOfString(filename): return Table(anydbm.open(filename, 'c'), StringRecord( )) def DictOfInstance(dict, Class=None): return Table(dict, InstanceRecord(Class)) def DictOfDictionary(dict): return Table(dict, DictionaryRecord( )) def DictOfString(filename): return Table(dict, StringRecord( )) ObjectOfInstance = DictOfInstance # other mapping objects ObjectOfDictionary = DictOfDictionary # classes that look like dicts ObjectOfString = DictOfString ############################################################################# # test common applications ############################################################################# if __name__ == '__main__': from sys import argv from formgui import FormGui # get dict-based gui from PP2E.Dbase.testdata import Actor, cast # get class, dict-of-dicts TestType = 'shelve' # shelve, dbm, dict TestInit = 0 # init file on startup? TestFile = '../data/shelve1' # external filename if len(argv) > 1: TestType = argv[1] if len(argv) > 2: TestInit = int(argv[2]) if len(argv) > 3: TestFile = argv[3] if TestType == 'shelve': # python formtbl.py shelve? print 'shelve-of-instance test' table = ShelveOfInstance(TestFile, Actor) # wrap shelf in Table object if TestInit: table.storeItems(cast) # python formtbl.py shelve 1 FormGui(table).mainloop( ) table.close( ) ShelveOfInstance(TestFile).printItems( ) # class picked up on fetch elif TestType == 'dbm': # python formtbl.py dbm print 'dbm-of-dictstring test' table = DbmOfString(TestFile) # wrap dbm in Table object if TestInit: table.storeItems(cast) # python formtbl.py dbm 1 FormGui(table).mainloop( ) table.close( ) DbmOfString(TestFile).printItems( ) # dump new table contents Besides the Table and record-wrapper classes, the module defines generator functions (e.g., ShelveOfInstance) that create a Table for all reasonable table and record combinations. Not all combinations are valid; DBM files, for example, can only contain dictionaries coded as strings, because class instances don't easily map to the string value format expected by DBM. However, these classes are flexible enough to allow additional Table configurations to be introduced. The only thing that is GUI-related about this file at all is its self-test code at the end. When run as a script, this module starts a PyForm GUI to browse and edit either a shelve of persistent Actor class instances or a DBM file of dictionaries, by passing in the right kind of Table object. The GUI looks like the one we saw in Figure 16-1 earlier; when run without arguments, the self-test code lets you browse a shelve of class instances: C:\...\PP2E\Dbase\TableBrowser>python formtable.py shelve-of-instance test ...display of contents on exit... Because PyForm displays a shelve this time, any changes you make are retained after the GUI exits. To reinitialize the shelve from the cast dictionary in testdata, pass a second argument of "1" ("0" means don't reinitialize the shelve). To override the script's default shelve filename, pass a different name as a third argument: C:\...\PP2E\Dbase\TableBrowser>python formtable.py shelve 1 C:\...\PP2E\Dbase\TableBrowser>python formtable.py shelve 0 ../data/shelve1 To instead test PyForm on a DBM file of dictionaries mapped to strings, pass a dbm in the first command-line argument; the next two arguments work the same: C:\...\PP2E\Dbase\TableBrowser>python formtable.py dbm 1 ..\data\dbm1 dbm-of-dictstring test ...display of contents on exit... Finally, because these self-tests ultimately process concrete shelve and DBM files, you can manually open and inspect their contents using normal library calls. Here is what they look like when opened in an interactive session: C:\...\PP2E\Dbase\data>ls dbm1 myfile shelve1 C:\...\PP2E\Dbase\data>python >>> import shelve >>> db = shelve.open('shelve1') >>> db.keys( ) ['alan', 'buddy', 'sally', 'rob', 'milly', 'laura', 'mel'] >>> db['laura'] <PP2E.Dbase.testdata.Actor instance at 799850> >>> import anydbm >>> db = anydbm.open('dbm1') >>> db.keys( ) ['alan', 'mel', 'buddy', 'sally', 'rob', 'milly', 'laura'] >>> db['laura'] "{'name': ('Laura', 'P'), 'kids': 2, 'spouse': 'Rob'}" The shelve file contains real Actor class instance objects, and the DBM file holds dictionaries converted to strings. Both formats are retained in these files between GUI runs and are converted back to dictionaries for later redisplay.[4]
<IP_ADDRESS> PyForm creation and view utility scriptsThe formtable module's self-test code proves that it works, but it is limited to canned test case files and classes. What about using PyForm for other kinds of databases that store more useful kinds of data? Luckily, both the formgui and formtable modules are written to be generic -- they are independent of a particular database's record format. Because of that, it's easy to point PyForm to databases of your own; simply import and run the FormGui object with the (possibly wrapped) table you wish to browse. The required startup calls are not too complex, and you could type them at the interactive prompt every time you want to browse a database; but it's usually easier to store them in scripts so they can be reused. The script in Example 16-11, for example, can be run to open PyForm on any shelve containing records stored in class instance or dictionary format. Example 16-11. PP2E\Dbase\dbview.py################################################################## # view any existing shelve directly; this is more general than a # "formtable.py shelve 1 filename" cmdline--only works for Actor; # pass in a filename (and mode) to use this to browse any shelve: # formtable auto picks up class from the first instance fetched; # run dbinit1 to (re)initialize dbase shelve with a template. ################################################################## from sys import argv from formtable import * from formgui import FormGui mode = 'class' file = '../data/mydbase-' + mode if len(argv) > 1: file = argv[1] # dbview.py file? mode?? if len(argv) > 2: mode = argv[2] if mode == 'dict': table = ShelveOfDictionary(file) # view dictionaries else: table = ShelveOfInstance(file) # view class objects FormGui(table).mainloop( ) table.close( ) # close needed for some dbm The only catch here is that PyForm doesn't handle completely empty tables very well; there is no way to add new records within the GUI unless a record is already present. That is, PyForm has no record layout design tool; its "new" button simply clears an existing input form. Because of that, to start a new database from scratch, you need to add an initial record that gives PyForm the field layout. Again, this requires only a few lines of code that could be typed interactively, but why not instead put it in generalized scripts for reuse? The file in Example 16-12, shows one way to go about initializing a PyForm database with a first empty record. Example 16-12. PP2E\Dbase\dbinit1.py###################################################################### # store a first record in a new shelve to give initial fields list; # PyForm GUI requires an existing record before you can more records; # delete the '?' key template record after real records are added; # change mode, file, template to use this for other kinds of data; # if you populate shelves from other data files you don't need this; # see dbinit2 for object-based version, and dbview to browse shelves. ###################################################################### import os from sys import argv mode = 'class' file = '../data/mydbase-' + mode if len(argv) > 1: file = argv[1] # dbinit1.py file? mode?? if len(argv) > 2: mode = argv[2] try: os.remove(file) # delete if present except: pass if mode == 'dict': template = {'name': None, 'age': None, 'job': None} # start dict shelve else: from PP2E.Dbase.person import Person # one arg defaulted template = Person(None, None) # start object shelve import shelve dbase = shelve.open(file) # create it now dbase['?empty?'] = template dbase.close( ) Now, simply change some of this script's settings or pass in command-line arguments to generate a new shelve-based database for use in PyForm. You can substitute any fields list or class name in this script to maintain a simple object database with PyForm that keeps track of real-world information (we'll see two such databases in action in a moment). The empty record shows up with key "?empty?" when you first browse the database with dbview; replace it with a first real record using the PyForm "store" key, and you are in business. As long as you don't change the database's shelve outside of the GUI, all its records will have the same fields format, as defined in the initialization script. But notice that the dbinit1 script goes straight to the shelve file to store the first record; that's fine today, but might break if PyForm is ever changed to do something more custom with its stored data representation. Perhaps a better way to populate tables outside the GUI is to use the Table wrapper classes it employs. The following alternative script, for instance, initializes a PyForm database with generated Table objects, not direct shelve operations (see Example 16-13). Example 16-13. PP2E\Dbase\dbinit2.py################################################################# # this works too--based on Table objects not manual shelve ops; # store a first record in shelve, as required by PyForm GUI. ################################################################# from formtable import * import sys, os mode = 'dict' file = '../data/mydbase-' + mode if len(sys.argv) > 1: file = sys.argv[1] if len(sys.argv) > 2: mode = sys.argv[2] try: os.remove(file) except: pass if mode == 'dict': table = ShelveOfDictionary(file) template = {'name': None, 'shoesize': None, 'language': 'Python'} else: from PP2E.Dbase.person import Person table = ShelveOfInstance(file, Person) template = Person(None, None).__dict__ table.storeItems({'?empty?': template}) table.close( ) Let's put these scripts to work to initialize and edit a couple of custom databases. Figure 16-2 shows one being browsed after initializing the database with a script, and adding a handful of real records within the GUI. Figure 16-2. A shelf of Person objects (dbinit1, dbview)The listbox here shows the record I added to the shelve within the GUI. I ran the following commands to initialize the database with a starter record and open it in PyForm to add records (that is, Person class instances): C:\...\PP2E\Dbase\TableBrowser>python dbinit1.py C:\...\PP2E\Dbase\TableBrowser>python dbview.py You can tweak the class name or fields dictionary in the dbinit scripts to initialize records for any sort of database you care to maintain with PyForm; use dictionaries if you don't want to represent persistent objects with classes (but classes let you add other sorts of behavior as methods not visible under PyForm). Be sure to use a distinct filename for each database; the initial "?empty?" record can be deleted as soon as you add a real entry (later, simply select an entry from the listbox and press "new" to clear the form for input of a new record's values). The data displayed in the GUI represents a true shelve of persistent Person class instance objects -- changes and additions made in the GUI will be retained for the next time you view this shelve with PyForm. If you like to type, though, you can still open the shelve directly to check PyForm's work: C:\...\PP2E\Dbase\data>ls mydbase-class myfile shelve1 C:\...\PP2E\Dbase\data>python >>> import shelve >>> db = shelve.open('mydbase-class') >>> db.keys( ) ['emily', 'jerry', '?empty?', 'bob', 'howard'] >>> db['bob'] <PP2E.Dbase.person.Person instance at 798d70> >>> db['emily'].job 'teacher' >>> db['bob'].tax 30000.0 Notice that "bob" is an instance of the Person class we met earlier in this chapter (see the shelve section). Assuming that the person module is still the version that introduced a __getattr__ method, asking for a shelved object's tax attribute computes a value on the fly, because this really invokes a class method. Also note that this works even though Person was never imported here -- Python loads the class internally when recreating its shelved instances. You can just as easily base a PyForm-compatible database on an internal dictionary structure, instead of classes. Figure 16-3 shows one being browsed, after being initialized with a script and populated with the GUI. Figure 16-3. A shelf of dictionaries (dbinit2, dbview)Besides its different internal format, this database has a different record structure (its record's field names differ from the last example), and it is stored in a shelve file of its own. Here are the commands I used to initialize and edit this database: C:\...\PP2E\Dbase\TableBrowser>python dbinit2.py ../data/mydbase-dict dict C:\...\PP2E\Dbase\TableBrowser>python dbview.py ../data/mydbase-dict dict After adding a few records (that is, dictionaries) to the shelve, you can either view them again in PyForm or open the shelve manually to verify PyForm's work: C:\...\PP2E\Dbase\data>ls mydbase-class mydbase-dict myfile shelve1 C:\...\PP2E\Dbase\data>python >>> db = shelve.open('mydbase-dict') >>> db.keys( ) ['tom', 'guido', '?empty?', 'larry', 'randal', 'mel'] >>> db['guido'] {'shoesize': 42, 'name': 'benevolent dictator', 'language': 'Python'} >>> db['mel']['shoesize'] {'left': 7.5, 'right': 7L} This time, shelve entries are really dictionaries, not instances of a class or converted strings. PyForm doesn't care, though -- because all tables are wrapped to conform to PyForm's interface, both formats look the same when browsed in the GUI. Notice that the "shoe size" and "language" fields in this screen shot really are a dictionary and list. You can type any Python expression syntax into this GUI's form fields to give values (that's why strings are quoted there). PyForm uses the Python backquotes expression to convert value objects for display (`x` is like repr(x), which is like str(x), but quotes are added around strings). To convert from a string back to value objects, PyForm uses the Python eval function to parse and evaluate the code typed in fields. The key entry/display field in the main window does not add or accept quotes around the key string, because keys must still be strings in things like shelves (even though fields can be arbitrary types).
Although PyForm expects to find a dictionary-of-dictionary interface (protocol) in the tables it browses, a surprising number of objects fit this mold because dictionaries are so pervasive in Python object internals. In fact, PyForm can be used to browse things that have nothing to do with the notion of database tables of records at all, as long as they can be made to conform to the protocol. For instance, the Python sys.modules table we met in Chapter 2 is a built-in dictionary of loaded module objects. With an appropriate wrapper class to make modules look like dictionaries, there's no reason we can't browse the in-memory sys.modules with PyForm too, as shown in Example 16-14. Example 16-14. PP2E\Dbase\TableBrowser\viewsysmod.py# view the sys.modules table in FormGui class modrec: def todict(self, value): return value.__dict__ # not dir(value): need dict def fromdict(self, value): assert 0, 'Module updates not supported' import sys from formgui import FormGui from formtable import Table FormGui(Table(sys.modules, modrec())).mainloop( ) This script defines a class to pull out a module's __dict__ attribute dictionary (formtable's InstanceRecord won't do, because it also looks for a __class__ ). The rest of it simply passes sys.modules to PyForm (FormGui) wrapped in a Table object; the result appears in Figure 16-4. Figure 16-4. FormGui browsing sys.modules (viewsysmod)With similar record and table wrappers, all sorts of objects could be viewed in PyForm. As usual in Python, all that matters is that they provide a compatible interface. <IP_ADDRESS> PyForm limitationsAlthough the sys.modules viewer script works, it also highlights a few limitations of PyForm's current design:
In other words, there is room for improvement if you care to experiment. There are other coding styles you might wish to explore, as well. For instance, PyForm current overloads table index fetch and assignment, and the GUI uses dictionaries to represent records internally. It would be almost as easy to overload record field index fetch and assignment instead, and add a Table method for creating a new empty record. In this scheme, records held in PyForm would be whatever object the table stores (not dictionaries), and each field fetch or assignment in PyForm would be routed back to record wrapper classes. The downside of this approach is that PyForm could not browse any object unless it is wrapped in a Table. Raw dictionaries would not work, because they have no method for making new empties. Moreover, DBM files that map whole records to strings might need extra logic to handle field-at-a-time requests. On the other hand, extensions in this domain are somewhat open-ended, so we'll leave them as suggested exercises. PyForm was never meant to be a general Python object viewer. But as a simple GUI interface to tables of persistent objects, it meets its design goals as planned. Python's shelves and classes make such systems both easy to code and powerful to use. Complex data can be stored and fetched in a single step, and augmented with methods that provide dynamic record behavior. As an added bonus, by programming such programs in Python and Tkinter, they are automatically portable among all major GUI platforms. When you mix Python persistence and GUIs, you get a lot of features "for free." |
| I l@ve RuBoard |


| Invoice For | {{ invoice.attendee.first_name }} {{ invoice.attendee.last_name }} |
|---|---|
| Paid For By: | {{ invoice.paid_for_by }} |
| Total Invoice Amount | {{ invoice.total_amount}} |
| Invoice Date | {{ invoice.invoice_date }} |
| Paid? | {{ invoice.paid_for_by|yesno:"yes,no" }} |
| Payment Type | {{ invoice.payment_type }} |
| Items |
{% for item in invoice.items.all %}
{{ item }} {% endfor %} |


#include <TreeBuilder.hpp>
◆ TreeBuilder()
| TreeBuilder::TreeBuilder |
( |
std::string ** |
names, |
|
|
int ** |
distances, |
|
|
int |
namesSize |
|
) |
| |
◆ ~TreeBuilder()
| TreeBuilder::~TreeBuilder |
( |
| ) |
|
◆ finishMerging()
| void TreeBuilder::finishMerging |
( |
| ) |
|
|
protected |
◆ candidateIters
| int TreeBuilder::candidateIters = 50 |
|
static |
◆ clustCnt
| const int TreeBuilder::clustCnt = 30 |
|
static |
◆ distInMem
| bool TreeBuilder::distInMem = false |
|
static |
◆ firstActiveNode
| int TreeBuilder::firstActiveNode |
|
protected |
◆ names
| std::string** TreeBuilder::names |
|
protected |
◆ nextActiveNode
| int* TreeBuilder::nextActiveNode |
|
protected |
◆ nodes
◆ prevActiveNode
| int* TreeBuilder::prevActiveNode |
|
protected |
◆ rebuildStepRatio
| float TreeBuilder::rebuildStepRatio = (float) 0.5 |
|
static |
◆ rebuildSteps
| int TreeBuilder::rebuildSteps = -1 |
|
static |
◆ rebuildStepsConstant
| bool TreeBuilder::rebuildStepsConstant = false |
|
static |
◆ redirect
| int* TreeBuilder::redirect |
|
protected |
◆ verbose
| int TreeBuilder::verbose = 1 |
|
static |
The documentation for this class was generated from the following files:


The clear property cancels the effects of the float property, and can prevent wrapping from taking place.


BU Libraries Search enables you to find books available in the BU Libraries, link to journals online, and discover scholarly articles for your research.
BU Libraries Search also helps you manage your research by formatting citations, or by exporting to citation managers such as Refworks, Zotero, and Mendeley.
Sign In to My Library Account to:
In a Basic Search you'll receive results that contain all of your search terms. These may match keywords in a title, author names, subjects, abstract, or other descriptions.
Use the Advanced Search instead to pre-limit to search only in specific fields, material types, and publication dates.
Use the Filters to limit to items available online or physically available in library. You can also include or exclude particular material types, dates, authors, subjects, or library locations.
The asterisk (*) character can be used as a wildcard in place of one or more characters. [Examples: recycl*, organiz*, hymn*]
Enclosing your search in quotes "" will only return results with an exact match. [Examples: “global warming”, “Affordable Care Act”, “mutual funds”]
Searches can also be nested in (), combined with "" and Boolean operators AND, OR, NOT. [Example: “World War II” AND (sites OR battles) NOT (Normandy OR Pearl Harbor)]
SEE MORE SEARCH STRATEGIESHere you can save results to My Favorites, create alerts for saved searches, and renew items.
GO TO MY LIBRARY ACCOUNTComplete course reading lists are now located in a new course reserves tool (Leganto). See our Course Reserves services page for more details about this.
We're here to help by email or chat in the lower right of screen.
ASK A LIBRARIAN


--- layout: page title: Turn Trump’s useless tweets into something good subtitle: We track and calculate the price per tweet. You turn it into real change. use-site-title: true ---
Trump tweeted a total of {{ site.data.data.tweet_total }} times last week. {{ site.data.data.all_caps }} were in all caps.
Updated every Sunday
Last update: {{ site.data.data.update_time }}
Click to copy


tutorial/workshop proposals | June 1, 2015 |
full paper submissions | June 8, 2015 |
paper acceptance notification | July 15, 2015 |
short paper submissions | August 1, 2015 |
short paper acceptance notification | August 20, 2015 |
camera-ready full papers due | August 24, 2015 |
camera-ready short papers due | August 31, 2015 |
early registration cutoff date | September 18, 2015 |
hotel reservation cutoff date | September 18, 2015 |


vkThread
|
Overview
|
API
|
GitHub
|
Single Thread
Regular Function
Function with Context
Function with Dependencies
Context + Dependencies
Anonymous Function
Lambda Function
Remote Function
AJAX
Multi-Threading
Parallel Computing


Device Configuration
Individual Provisioning
Bulk Provisioning
Select Device Type
*
Select Device Type
{{deviceType.name}}
Device Name
*
No special character are allowed.
Device Serial No
*
Accepted values are a/A to f/F and 0 to 9
Is Buzz
Save
Update
DownloadSampleCSV
Choose a file to upload
{{myFile.name}}
Upload
Update Device Management
×
Are you sure to update this data ?
Device List
Device Name
Device Type
Serial No.
Action
Device List
No records Found!


--- title: Title keywords: fastai sidebar: home_sidebar nb_path: "nbs/10c_experiment.synthetic-task-analysis.ipynb" ---
from fastai.text.all import *
from reformer_fastai.expscript import get_twin_sequence_dataloaders, get_lshlm_model, get_synthetic_learner
from reformer_fastai.data import MaskTargCallback
Settings from experiement. Note: LSH-models run with seed 42. Full attention with 1234 (didn't converge in 42).
bs=64
sl=1024
train_sz=12800
valid_sz=1280
n_epochs=750
seed=42
dls = get_twin_sequence_dataloaders(bs=bs, sl=sl, train_sz=train_sz, valid_sz=valid_sz, seed=seed)
n_hashes=1
bucket_size=64 # suggested in trax
vocab_sz=128 # specific for the synthetic task
d_model=256
n_layers=1 # specified in paper
n_heads=4
d_ff=256
attn_dropout=0
ff_dropout=0
emb_dropout=0
max_seq_len=sl
causal=True
use_lsh=True
def load_learner(n_hashes, use_lsh, fn, d_ff):
model = get_lshlm_model(vocab_sz=vocab_sz, d_model=d_model, n_layers=n_layers, n_heads=n_heads,
max_seq_len=max_seq_len, bucket_size=bucket_size, n_hashes=n_hashes, causal=causal,
use_lsh=use_lsh, seed=seed, attn_dropout=attn_dropout, ff_dropout=ff_dropout, emb_dropout=emb_dropout,
d_ff=d_ff)
learn = get_synthetic_learner(dls, model)
learn = learn.load(fn)
return learn
learn_lsh1 = load_learner(n_hashes=1, use_lsh=True, fn=fn1, d_ff=256)
learn_lsh2 = load_learner(n_hashes=2, use_lsh=True, fn=fn2, d_ff=256)
learn_lsh4 = load_learner(n_hashes=4, use_lsh=True, fn=fn4, d_ff=256)
learn_lsh1.model.n_hashes, learn_lsh2.model.n_hashes, learn_lsh4.model.n_hashes
This model was trained with a different seed, since it did't converge with the one used for the LSH-models. Note that n_hashes
=6 is set in config, but is not used when use_lsh
=False.
seed=1234
dls = get_twin_sequence_dataloaders(bs=bs, sl=sl, train_sz=train_sz, valid_sz=valid_sz, seed=seed)
learn_full = load_learner(n_hashes=6, use_lsh=False, fn=fn_full, d_ff=256)
learn_full.model.use_lsh
Validate lsh-models with n_hashes=1,2,4,8
res = []
for learner in [learn_lsh4, learn_lsh2, learn_lsh1]:
train_hashes = learner.model.n_hashes
for eval_hashes in [8,4,2,1]:
learner.model.n_hashes=eval_hashes
_, m_acc = learner.validate(cbs=MaskTargCallback)
res.append((f'LSH-{train_hashes}', f'LSH-{eval_hashes}', m_acc))
learner.model.n_hashes=train_hashes #reset n_hashes
Evaluate LSH-models with full-attention:
for learner in [learn_lsh4, learn_lsh2, learn_lsh1]:
learner.model.use_lsh=False
_, m_acc = learner.validate(cbs=MaskTargCallback)
res.append((f'LSH-{learner.model.n_hashes}', 'Full Attention', m_acc))
learner.model.use_lsh=True #reset
Validate model trained with full attention with full attention and LSH
_,m_acc = learn_full.validate(cbs=MaskTargCallback)
res.append(('Full Attention','Full Attention', m_acc))
#validate with lsh-1,2,4,8
learn_full.model.use_lsh=True
for n_hashes in [8,4,2,1]:
learn_full.model.n_hashes=n_hashes
_, m_acc = learn_full.validate(cbs=MaskTargCallback)
res.append(('Full Attention', f'LSH-{learn_full.model.n_hashes}', m_acc))
cols = ['Train', 'Eval', 'Masked_Accuracy']
df = pd.DataFrame(res, columns=cols)
df['Masked_Accuracy'] = df['Masked_Accuracy'].round(4)*100
df = df.pivot_table(index=cols[0],
columns=cols[1],
values=cols[2])
df = df.iloc[[0,3,2,1], [0,4,3,2,1]]
df


unsuccessful login attempt
forgot your password?
fill in your email and we'll send you a password reset code
process could not complete
a password reset code has been sent to {{data.reset.username}}
password could not be resetted
your password has been successfuly changed


A virtual battery is a battery that is simulated within a larger battery. This is useful in PHEV applications where the vehicle requires a small battery on the bottom end to operate.


--- layout: home img: /assets/img/members.jpg ---
Zhou Lab at the University of Florida is focused on understanding how the regulatory pathways controlling cellular suicide (apoptosis) are activated in response to cellular stresses and virus infection.