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).