Home | Diary | Todo | Index | About |
#!/usr/bin/python3
# tuple
keys = ('color', 'fruit', 'pet')
# list
values = ['orang', 'orang', 'dog']
# dict from tuple and list
dictionary = {key: value for key, value in zip(keys, values)}
d_items = dictionary.items()
print(d_items)
# dict_items([('color', 'blue'), ('fruit', 'apple'), ('pet', 'dog')])
# dict comprehension
pets = {key: value for key, value in dictionary.items() if value != 'orang'}
for key, value in pets.items():
print(key, '->', value)
# # *args is a tuple [const list], use like:
# for arg in args:
# print(arg)
# # **kwargs is a dictionary, use like:
# for kitem in kwargs.items():
# print(kitem
# for kval in kwargs.values():
# print(kval)
# # or maybe
# for kwarg in kwargs:
# print(kwarg.value())
## This is a Python port of [Zyre](http://zyre.org) 1.0, implementing the same [ZRE protocol](http://rfc.zeromq.org/spec:36).
# import zmq
# import time
# import struct
# import socket
# import uuid
# import logging
# import sys
# # local modules
# from . import __version_info__
# from . import zbeacon
# from . import zhelper
# from .zactor import ZActor
# from .zsocket import ZSocket
# from .pyre_node import PyreNode
# from .pyre_event import PyreEvent
# logger = logging.getLogger(__name__)
# try:
# raw_input # Python 2
# except NameError:
# raw_input = input # Python 3
# class Pyre(object):
# def __init__(self, name=None, ctx=None, *args, **kwargs):
# """Constructor, creates a new Zyre node. Note that until you start the
# node it is silent and invisible to other nodes on the network.
# The node name is provided to other nodes during discovery. If you
# specify NULL, Zyre generates a randomized node name from the UUID.
# Args:
# name (str): The name of the node
# Kwargs:
# ctx: PyZMQ Context, if not specified a new context will be created
# """
# super(Pyre, self).__init__(*args, **kwargs)
# ctx = kwargs.get('ctx')
# if ctx == None:
# ctx = zmq.Context()
# self._ctx = ctx
# self._uuid = None
# self._name = name
# self.verbose = False
# self.inbox, self._outbox = zhelper.zcreate_pipe(self._ctx)
# # Start node engine and wait for it to be ready
# self.actor = ZActor(self._ctx, PyreNode, self._outbox)
# # Send name, if any, to node backend
# if (self._name):
# self.actor.send_unicode("SET NAME", zmq.SNDMORE)
# self.actor.send_unicode(self._name)
# #def __del__(self):
# # We need to explicitly destroy the actor
# # to make sure our node thread is stopped
# #self.actor.destroy()
# def __bool__(self):
# "Determine whether the object is valid by converting to boolean" # Python 3
# return True #TODO
# def __nonzero__(self):
# "Determine whether the object is valid by converting to boolean" # Python 2
# return True #TODO
# def uuid(self):
# """Return our node UUID string, after successful initialization"""
# if not self._uuid:
# self.actor.send_unicode("UUID")
# self._uuid = uuid.UUID(bytes=self.actor.recv())
# return self._uuid
# # Return our node name, after successful initialization
# def name(self):
# """Return our node name, after successful initialization"""
# if not self._name:
# self.actor.send_unicode("NAME")
# self._name = self.actor.recv().decode('utf-8')
# return self._name
# # Not in Zyre api
# def set_name(self, name):
# logger.warning("DEPRECATED: set name in constructor, this method will be removed!")
# self.actor.send_unicode("SET NAME", zmq.SNDMORE)
# self.actor.send_unicode(name)
# def set_header(self, key, value):
# """Set node header; these are provided to other nodes during discovery
# and come in each ENTER message."""
# self.actor.send_unicode("SET HEADER", flags=zmq.SNDMORE)
# self.actor.send_unicode(key, flags=zmq.SNDMORE)
# self.actor.send_unicode(value)
# def set_verbose(self):
# """Set verbose mode; this tells the node to log all traffic as well as
# all major events."""
# self.actor.send_unicode("SET VERBOSE")
# def set_port(self, port_nbr):
# """Set UDP beacon discovery port; defaults to 5670, this call overrides
# that so you can create independent clusters on the same network, for
# e.g. development vs. production. Has no effect after zyre_start()."""
# self.actor.send_unicode("SET PORT", zmq.SNDMORE)
# self.actor.send(port_nbr)
# def set_interval(self, interval):
# """Set UDP beacon discovery interval, in milliseconds. Default is instant
# beacon exploration followed by pinging every 1,000 msecs."""
# self.actor.send_unicode("SET INTERVAL", zmq.SNDMORE)
# self.actor.send_unicode(interval)
# def set_interface(self, value):
# """Set network interface for UDP beacons. If you do not set this, CZMQ will
# choose an interface for you. On boxes with several interfaces you should
# specify which one you want to use, or strange things can happen."""
# logging.debug("set_interface not implemented") #TODO
# # TODO: check args from zyre
# def set_endpoint(self, format, *args):
# """By default, Zyre binds to an ephemeral TCP port and broadcasts the local
# host name using UDP beaconing. When you call this method, Zyre will use
# gossip discovery instead of UDP beaconing. You MUST set-up the gossip
# service separately using zyre_gossip_bind() and _connect(). Note that the
# endpoint MUST be valid for both bind and connect operations. You can use
# inproc://, ipc://, or tcp:// transports (for tcp://, use an IP address
# that is meaningful to remote as well as local nodes). Returns 0 if
# the bind was successful, else -1."""
# self.actor.send_unicode("SET ENDPOINT", zmq.SNDMORE)
# self.actor.send_unicode(format)
# # TODO: We haven't implemented gossiping yet
# #def gossip_bind(self, format, *args):
# #def gossip_connect(self, format, *args):
# def start(self):
# """Start node, after setting header values. When you start a node it
# begins discovery and connection. Returns 0 if OK, -1 if it wasn't
# possible to start the node."""
# self.actor.send_unicode("START")
# # the backend will signal back
# self.actor.resolve().wait()
# def stop(self):
# """Stop node; this signals to other peers that this node will go away.
# This is polite; however you can also just destroy the node without
# stopping it."""
# self.actor.send_unicode("STOP", flags=zmq.DONTWAIT)
# # the backend will signal back
# self.actor.resolve().wait()
# self.actor.destroy()
# # Receive next message from node
# def recv(self):
# """Receive next message from network; the message may be a control
# message (ENTER, EXIT, JOIN, LEAVE) or data (WHISPER, SHOUT).
# """
# return self.inbox.recv_multipart()
# def join(self, group):
# """Join a named group; after joining a group you can send messages to
# the group and all Zyre nodes in that group will receive them."""
# self.actor.send_unicode("JOIN", flags=zmq.SNDMORE)
# self.actor.send_unicode(group)
# def leave(self, group):
# """Leave a group"""
# self.actor.send_unicode("LEAVE", flags=zmq.SNDMORE)
# self.actor.send_unicode(group)
# # Send message to single peer; peer ID is first frame in message
# def whisper(self, peer, msg_p):
# """Send message to single peer, specified as a UUID string
# Destroys message after sending"""
# self.actor.send_unicode("WHISPER", flags=zmq.SNDMORE)
# self.actor.send(peer.bytes, flags=zmq.SNDMORE)
# if isinstance(msg_p, list):
# self.actor.send_multipart(msg_p)
# else:
# self.actor.send(msg_p)
# def shout(self, group, msg_p):
# """Send message to a named group
# Destroys message after sending"""
# self.actor.send_unicode("SHOUT", flags=zmq.SNDMORE)
# self.actor.send_unicode(group, flags=zmq.SNDMORE)
# if isinstance(msg_p, list):
# self.actor.send_multipart(msg_p)
# else:
# self.actor.send(msg_p)
# # TODO: checks args from zyre
# def whispers(self, peer, format, *args):
# """Send formatted string to a single peer specified as UUID string"""
# self.actor.send_unicode("WHISPER", flags=zmq.SNDMORE)
# self.actor.send(peer.bytes, flags=zmq.SNDMORE)
# self.actor.send_unicode(format)
# def shouts(self, group, format, *args):
# """Send formatted string to a named group"""
# self.actor.send_unicode("SHOUT", flags=zmq.SNDMORE)
# self.actor.send_unicode(group, flags=zmq.SNDMORE)
# self.actor.send_unicode(format)
# def peers(self):
# """Return list of current peer ids."""
# self.actor.send_unicode("PEERS")
# peers = self.actor.recv_pyobj()
# return peers
# def peers_by_group(self, group):
# """Return list of current peer ids."""
# self.actor.send_unicode("PEERS BY GROUP", flags=zmq.SNDMORE)
# self.actor.send_unicode(group)
# peers_by_group = self.actor.recv_pyobj()
# return peers_by_group
# def endpoint(self):
# """Return own endpoint"""
# self.actor.send_unicode("ENDPOINT")
# endpoint = self.actor.recv_unicode()
# return endpoint
# def recent_events(self):
# """Iterator that yields recent `PyreEvent`s"""
# while self.socket().get(zmq.EVENTS) & zmq.POLLIN:
# yield PyreEvent(self)
# def events(self):
# """Iterator that yields `PyreEvent`s indefinitely"""
# while True:
# yield PyreEvent(self)
# # --------------------------------------------------------------------------
# # Return the name of a connected peer. Caller owns the
# # string.
# # DEPRECATED: This is dropped in Zyre api. You receive names through events
# def get_peer_name(self, peer):
# logger.warning("get_peer_name() is deprecated, will be removed")
# self.actor.send_unicode("PEER NAME", zmq.SNDMORE)
# self.actor.send(peer.bytes)
# name = self.actor.recv_unicode()
# return name
# def peer_address(self, peer):
# """Return the endpoint of a connected peer."""
# self.actor.send_unicode("PEER ENDPOINT", zmq.SNDMORE)
# self.actor.send(peer.bytes)
# adr = self.actor.recv_unicode()
# return adr
# def peer_header_value(self, peer, name):
# """Return the value of a header of a conected peer.
# Returns null if peer or key doesn't exist."""
# self.actor.send_unicode("PEER HEADER", zmq.SNDMORE)
# self.actor.send(peer.bytes, zmq.SNDMORE)
# self.actor.send_unicode(name)
# value = self.actor.recv_unicode()
# return value
# def peer_headers(self, peer):
# """Return the value of a header of a conected peer.
# Returns null if peer or key doesn't exist."""
# self.actor.send_unicode("PEER HEADERS", zmq.SNDMORE)
# self.actor.send(peer.bytes)
# headers = self.actor.recv_pyobj()
# return headers
# def own_groups(self):
# """Return list of currently joined groups."""
# self.actor.send_unicode("OWN GROUPS");
# groups = self.actor.recv_pyobj()
# return groups
# def peer_groups(self):
# """Return list of groups known through connected peers."""
# self.actor.send_unicode("PEER GROUPS")
# groups = self.actor.recv_pyobj()
# return groups
# # Return node socket, for direct polling of socket
# def socket(self):
# """Return socket for talking to the Zyre node, for polling"""
# return self.inbox
# @staticmethod
# def version():
# return __version_info__
# def chat_task(ctx, pipe):
# n = Pyre(ctx=ctx)
# n.join("CHAT")
# n.start()
# poller = zmq.Poller()
# poller.register(pipe, zmq.POLLIN)
# poller.register(n.socket(), zmq.POLLIN)
# while(True):
# items = dict(poller.poll())
# if pipe in items:
# message = pipe.recv()
# if message == '$TERM':
# break
# logger.debug("CHAT_TASK: {0}".format(message))
# n.shout("CHAT", message)
# if n.socket() in items:
# event = PyreEvent(n)
# logger.debug("NODE_MSG TYPE: {0}".format(event.type))
# logger.debug("NODE_MSG PEER: {0}".format(event.peer_uuid))
# if event.type == "SHOUT":
# logger.debug("NODE_MSG GROUP: {0}".format(event.group))
# logger.debug("NODE_MSG CONT: {0}".format(event.msg))
# n.stop()
# if __name__ == '__main__':
# logging.basicConfig()
# logging.getLogger('__main__').setLevel(logging.DEBUG)
# ctx = zmq.Context()
# chat_pipe = zhelper.zthread_fork(ctx, chat_task)
# while True:
# try:
# msg = raw_input()
# chat_pipe.send_string(msg)
# except (KeyboardInterrupt, SystemExit):
# chat_pipe.send_string('$TERM')
# break
# logger.debug("Exiting")
# Pyre
# ====
# This is a Python port of [Zyre](http://zyre.org) 1.0, implementing the same [ZRE protocol](http://rfc.zeromq.org/spec:36).
# # Pyre - an open-source framework for proximity-based peer-to-peer applications
# ## Description
# Pyre does local area discovery and clustering. A Pyre node broadcasts
# UDP beacons, and connects to peers that it finds. This class wraps a
# Pyre node with a message-based API.
# All incoming events are messages delivered via the recv call of a Pyre
# instance. The first frame defines the type of the message, and following
# frames provide further values:
# ENTER fromnode headers
# a new peer has entered the network
# EXIT fromnode
# a peer has left the network
# JOIN fromnode groupname
# a peer has joined a specific group
# LEAVE fromnode groupname
# a peer has joined a specific group
# WHISPER fromnode message
# a peer has sent this node a message
# SHOUT fromnode groupname message
# a peer has sent one of our groups a message
# In SHOUT and WHISPER the message is a single frame in this version
# of Pyre. In ENTER, the headers frame contains a packed dictionary,
# that can be unpacked using json.loads(msg) (see chat client).
# To join or leave a group, use the join() and leave() methods.
# To set a header value, use the set_header() method. To send a message
# to a single peer, use whisper(). To send a message to a group, use
# shout().
# ## Installation
# For now use Pip:
# pip install https://github.com/zeromq/pyre/archive/master.zip
# ## API
# import pyre
# # Constructor, creates a new Zyre node. Note that until you start the
# # node it is silent and invisible to other nodes on the network.
# node = pyre.Pyre()
# # Set node header; these are provided to other nodes during discovery
# # and come in each ENTER message.
# node.set_header(name, value)
# # (TODO: Currently a Pyre node starts immediately) Start node, after setting header values. When you start a node it
# # begins discovery and connection.
# node.start()
# # Stop node, this signals to other peers that this node will go away.
# # This is polite; however you can also just destroy the node without
# # stopping it.
# node.stop()
# # Join a named group; after joining a group you can send messages to
# # the group and all Zyre nodes in that group will receive them.
# node.join(group)
# # Leave a group
# node.leave(group)
# # Receive next message from network; the message may be a control
# # message (ENTER, EXIT, JOIN, LEAVE) or data (WHISPER, SHOUT).
# # Returns a list of message frames
# msgs = node.recv();
# # Send message to single peer, specified as a UUID object (import uuid)
# # Destroys message after sending
# node.whisper(peer, msg)
# # Send message to a named group
# # Destroys message after sending
# node.shout(group, msg);
# # Send string to single peer specified as a UUID string.
# # String is formatted using printf specifiers.
# node.whispers(peer, msg_string)
# # Send message to a named group
# # Destroys message after sending
# node.shouts(group, msg_string);
# # Return handle to the Zyre node, for polling
# node.get_socket()
# # use node.get_socket().getsockopt(zmq.FD) to acquire
# # the filedescriptor
# # Don't use this for getting Pyre events you can use the
# # node.inbox to get those events
# ## Example Chat Client
# ```python
# try:
# from zyre_pyzmq import Zyre as Pyre
# except Exception as e:
# print("using Python native module", e)
# from pyre import Pyre
# from pyre import zhelper
# import zmq
# import uuid
# import logging
# import sys
# import json
# def chat_task(ctx, pipe):
# n = Pyre("CHAT")
# n.set_header("CHAT_Header1","example header1")
# n.set_header("CHAT_Header2","example header2")
# n.join("CHAT")
# n.start()
# poller = zmq.Poller()
# poller.register(pipe, zmq.POLLIN)
# print(n.socket())
# poller.register(n.socket(), zmq.POLLIN)
# print(n.socket())
# while(True):
# items = dict(poller.poll())
# print(n.socket(), items)
# if pipe in items and items[pipe] == zmq.POLLIN:
# message = pipe.recv()
# # message to quit
# if message.decode('utf-8') == "$$STOP":
# break
# print("CHAT_TASK: %s" % message)
# n.shouts("CHAT", message.decode('utf-8'))
# else:
# #if n.socket() in items and items[n.socket()] == zmq.POLLIN:
# cmds = n.recv()
# msg_type = cmds.pop(0)
# print("NODE_MSG TYPE: %s" % msg_type)
# print("NODE_MSG PEER: %s" % uuid.UUID(bytes=cmds.pop(0)))
# print("NODE_MSG NAME: %s" % cmds.pop(0))
# if msg_type.decode('utf-8') == "SHOUT":
# print("NODE_MSG GROUP: %s" % cmds.pop(0))
# elif msg_type.decode('utf-8') == "ENTER":
# headers = json.loads(cmds.pop(0).decode('utf-8'))
# print("NODE_MSG HEADERS: %s" % headers)
# for key in headers:
# print("key = {0}, value = {1}".format(key, headers[key]))
# print("NODE_MSG CONT: %s" % cmds)
# n.stop()
# if __name__ == '__main__':
# # Create a StreamHandler for debugging
# logger = logging.getLogger("pyre")
# logger.setLevel(logging.INFO)
# logger.addHandler(logging.StreamHandler())
# logger.propagate = False
# ctx = zmq.Context()
# chat_pipe = zhelper.zthread_fork(ctx, chat_task)
# # input in python 2 is different
# if sys.version_info.major < 3:
# input = raw_input
# while True:
# try:
# msg = input()
# chat_pipe.send(msg.encode('utf_8'))
# except (KeyboardInterrupt, SystemExit):
# break
# chat_pipe.send("$$STOP".encode('utf_8'))
# print("FINISHED")
# ```
# Look at the [ZOCP](https://github.com/z25/pyZOCP) project for examples of how Pyre can be
# integrated into different environments and frameworks, i.e.:
# - [Urwid](https://github.com/z25/pyZOCP/blob/master/examples/urwZOCP.py)
# - [Blender](https://github.com/z25/pyZOCP/blob/master/examples/BpyZOCP.py)
# - [Glib](https://github.com/z25/pyZOCP/blob/master/examples/glib_node.py)
# - [QT](https://github.com/z25/pyZOCP/blob/master/examples/qt_ui_node.py)
# Pyre uses the [Python Logging](https://docs.python.org/3.4/library/logging.html) module.
# To change the debug level:
# ```
# # Create a StreamHandler for debugging
# logger = logging.getLogger("pyre")
# logger.setLevel(logging.INFO)
# # i.e. logging.DEBUG, logging.WARNING
# logger.addHandler(logging.StreamHandler())
# logger.propagate = False
# ```
# ## Requirements
# Python only needs PyZMQ. On some older versions of Python
# it also needs the [ipaddress](https://docs.python.org/3.4/library/ipaddress.html?highlight=ipaddress#module-ipaddress) module.
# The recommended Python version is 3.3+
# ## Project Organization
# Pyre is owned by all its authors and contributors. This is an open source
# project licensed under the LGPLv3. To contribute to Zyre please read the
# [C4.1 process](http://rfc.zeromq.org/spec:22) that we use.
# To report an issue, use the [PYRE issue tracker](https://github.com/zeromq/pyre/issues) at github.com.
# For more information on this project's maintenance, see [`MAINTENANCE.md`](MAINTENANCE.md).