XNetwork 1.7.5; VERSION ${PROJECT_VERSION}
Loading...
Searching...
No Matches
reportviews.hpp
Go to the documentation of this file.
1
11#pragma once
12
97// from collections import Mapping, Set, Iterable
98// #include <initializer_list>
99#include <iterator>
100
101namespace xnetwork {
102
103 // static const auto __all__ = {"NodeView",
104 // "NodeDataView",
105 // "EdgeView",
106 // "OutEdgeView",
107 // "InEdgeView",
108 // "EdgeDataView",
109 // "OutEdgeDataView",
110 // "InEdgeDataView",
111 // "MultiEdgeView",
112 // "OutMultiEdgeView",
113 // "InMultiEdgeView",
114 // "MultiEdgeDataView",
115 // "OutMultiEdgeDataView",
116 // "InMultiEdgeDataView",
117 // "DegreeView",
118 // "DiDegreeView",
119 // "InDegreeView",
120 // "OutDegreeView",
121 // "MultiDegreeView",
122 // "DiMultiDegreeView",
123 // "InMultiDegreeView",
124 // "OutMultiDegreeView"};
125
130 template <typename nodeview_t> class NodeView {
131 private:
133 using Node = typename nodeview_t::value_type;
134
135 nodeview_t& _nodes;
136
137 // auto __getstate__( ) {
138 // return {"_nodes": this->_nodes};
139 // }
140
141 // auto __setstate__( state) {
142 // this->_nodes = state["_nodes"];
143 // }
144 public:
149 explicit NodeView(nodeview_t& nodes) : _nodes{nodes} {}
150
151 // Mapping methods
156 auto size() const { return this->_nodes.size(); }
157
162 auto begin() const { return std::begin(this->_nodes); }
163
168 auto end() const { return std::end(this->_nodes); }
169
175 auto operator[](const Node& node) const -> const auto& { return this->_nodes[node]; }
176
182 auto operator[](const Node& node) -> auto& { return this->_nodes[node]; }
183
184 // Set methods
190 auto contains(const Node& node) const -> bool { return this->_nodes.contains(node); }
191
192 // /// @classmethod
193 // auto _from_iterable(cls, it) {
194 // return set(it);
195 // }
196
197 // // DataView method
198 // auto __call__( data=false, default=None) {
199 // if (data == false) {
200 // return (*this);
201 // }
202 // return NodeDataView(this->_nodes, data, default);
203 // }
204
205 // auto data( data=true, default=None) {
206 // if (data == false) {
207 // return (*this);
208 // }
209 // return NodeDataView(this->_nodes, data, default);
210 // }
211
212 // auto __str__( ) {
213 // return str(list( ));
214 // }
215
216 // auto __repr__( ) {
217 // return "%s(%r)" % (this->__class__.__name__, tuple( ));
218 // }
219 };
220
221 // class NodeDataView: public Set {
222 // /** A DataView class for nodes of a XNetwork Graph
223
224 // The main use for this class is to iterate through node-data pairs.
225 // The data can be the entire data-dictionary for each node, or it
226 // can be a specific attribute (with default) for each node.
227 // Set operations are enabled with NodeDataView, but don't work in
228 // cases where the data is not hashable. Use with caution.
229 // Typically, set operations on nodes use NodeView, not NodeDataView.
230 // That is, they use `gra.nodes` instead of `gra.nodes(data="foo")`.
231
232 // Parameters
233 // ==========
234 // graph : XNetwork graph-like class
235 // data : bool or string (default=false);
236 // default : object (default=None);
237 // */
238 // using _Self = NodeDataView;
239
240 // static const auto __slots__ = ("_nodes", "_data", "_default");
241
242 // // auto __getstate__( ) {
243 // // return {"_nodes": this->_nodes,
244 // // "_data": this->_data,
245 // // "_default": this->_default};
246 // // }
247
248 // // auto __setstate__( state) {
249 // // this->_nodes = state["_nodes"];
250 // // this->_data = state["_data"];
251 // // this->_default = state["_default"];
252 // // }
253
254 // explicit _Self( nodedict, data=false, default=None) {
255 // this->_nodes = nodedict;
256 // this->_data = data;
257 // this->_default = default;
258 // }
259
260 // /// @classmethod
261 // auto _from_iterable(cls, it) {
262 // try {
263 // return set(it);
264 // } catch (TypeError as err) {
265 // if ("unhashable" : str(err) {
266 // const auto msg = " : Could be b/c data=true or your values
267 // are unhashable"; throw TypeError(str(err) + msg);
268 // }
269 // throw;
270 // }
271 // }
272
273 // auto __len__( ) {
274 // return len(this->_nodes);
275 // }
276
277 // auto __iter__( ) {
278 // data = this->_data;
279 // if (data == false) {
280 // return iter(this->_nodes);
281 // }
282 // if (data == true) {
283 // return iter(this->_nodes.items());
284 // }
285 // return ((n, dd[data] if (data : dd else this->_default)
286 // for (auto n, dd : this->_nodes.items());
287 // }
288
289 // bool contains( n) {
290 // try {
291 // node_in = n : this->_nodes;
292 // } catch (TypeError) {
293 // n, d = n;
294 // return n : this->_nodes and self[n] == d;
295 // }
296 // if (node_in == true) {
297 // return node_in;
298 // }
299 // try {
300 // n, d = n;
301 // } catch ((TypeError, ValueError) {
302 // return false;
303 // }
304 // return n : this->_nodes and self[n] == d;
305 // }
306
307 // auto operator[]( n) {
308 // ddict = this->_nodes[n];
309 // data = this->_data;
310 // if (data == false or data == true) {
311 // return ddict;
312 // }
313 // return ddict[data] if (data : ddict else this->_default;
314 // }
315
316 // auto __str__( ) {
317 // return str(list( ));
318 // }
319
320 // // auto __repr__( ) {
321 // // if (this->_data == false) {
322 // // return "%s(%r)" % (this->__class__.__name__, tuple( ));
323 // // }
324 // // if (this->_data == true) {
325 // // return "%s(%r)" % (this->__class__.__name__, dict( ));
326 // // }
327 // // return "%s(%r, data=%r)" %
328 // // this->__class__.__name__, dict( ), this->_data);
329 // // }
330 // };
331
332 // // DegreeViews
333 // /** A View class for degree of nodes : a XNetwork Graph
334
335 // The functionality is like dict.items() with (node, degree) pairs.
336 // Additional functionality includes read-only lookup of node degree,
337 // and calling with optional features nbunch (for only a subset of nodes);
338 // and weight (use edge weights to compute degree).
339
340 // Parameters
341 // ==========
342 // graph : XNetwork graph-like class
343 // nbunch : node, container of nodes, or None meaning all nodes
344 // (default=None); weight : bool or string (default=None);
345
346 // Notes
347 // -----
348 // DegreeView can still lookup any node even if (nbunch is specified.
349
350 // Examples
351 // --------
352 // > gra = xnetwork::path_graph(3);
353 // > DV = gra.degree();
354 // > assert(DV[2] == 1);
355 // > assert(sum(deg for n, deg : DV) == 4);
356
357 // > DVweight = gra.degree(weight="span");
358 // > gra.add_edge(1, 2, span=34);
359 // > DVweight[2];
360 // 34
361 // > DVweight[0]; // default edge weight is 1
362 // 1
363 // > sum(span for n, span : DVweight); // sum weighted degrees
364 // 70
365
366 // > DVnbunch = gra.degree(nbunch=(1, 2));
367 // > assert(len(list(DVnbunch)) == 2); // iteration over nbunch only
368 // */
369 // class DiDegreeView: public object {
370 // using _Self = DiDegreeView;
371
372 // explicit _Self( gra, nbunch=None, weight=None) {
373 // this->_graph = gra;
374 // this->_succ = gra._adj;
375 // this->_pred = gra._adj;
376 // this->_nodes = this->_succ if (nbunch.empty()
377 // else list(gra.nbunch_iter(nbunch));
378 // this->_weight = weight;
379 // }
380
381 // auto __call__( nbunch=None, weight=None) {
382 // if (nbunch.empty()) {
383 // if (weight == this->_weight) {
384 // return (*this);
385 // }
386 // return this->__class__(this->_graph, None, weight);
387 // }
388 // try {
389 // if (nbunch : this->_nodes) {
390 // if (weight == this->_weight) {
391 // return (*this)[nbunch];
392 // }
393 // return this->__class__(this->_graph, None, weight)[nbunch];
394 // }
395 // } catch (TypeError) {
396 // // pass;
397 // }
398 // return this->__class__(this->_graph, nbunch, weight);
399 // }
400
401 // auto operator[]( n) {
402 // weight = this->_weight;
403 // succs = this->_succ[n];
404 // preds = this->_pred[n];
405 // if (weight.empty()) {
406 // return len(succs) + len(preds);
407 // }
408 // return sum(dd.get(weight, 1) for dd : succs.values()) +
409 // sum(dd.get(weight, 1) for dd : preds.values());
410 // }
411
412 // auto __iter__( ) {
413 // weight = this->_weight;
414 // if (weight.empty()) {
415 // for (auto n : this->_nodes) {
416 // succs = this->_succ[n];
417 // preds = this->_pred[n];
418 // yield (n, len(succs) + len(preds));
419 // }
420 // } else {
421 // for (auto n : this->_nodes) {
422 // succs = this->_succ[n];
423 // preds = this->_pred[n];
424 // deg = sum(dd.get(weight, 1) for dd : succs.values())
425 // + sum(dd.get(weight, 1) for dd : preds.values());
426 // yield (n, deg);
427 // }
428 // }
429 // }
430
431 // auto __len__( ) {
432 // return len(this->_nodes);
433 // }
434
435 // auto __str__( ) {
436 // return str(list( ));
437 // }
438
439 // // auto __repr__( ) {
440 // // return "%s(%r)" % (this->__class__.__name__, dict( ));
441 // // }
442 // };
443
444 // class DegreeView: public DiDegreeView {
445 // /** A DegreeView class to act as gra.degree for a XNetwork Graph
446
447 // Typical usage focuses on iteration over `(node, degree)` pairs.
448 // The degree is by default the number of edges incident to the node.
449 // Optional argument `weight` enables weighted degree using the edge
450 // attribute named : the `weight` argument. Reporting and iteration
451 // can also be restricted to a subset of nodes using `nbunch`.
452
453 // Additional functionality include node lookup so that `gra.degree[n]`
454 // reported the (possibly weighted) degree of node `n`. Calling the
455 // view creates a view with different arguments `nbunch` or `weight`.
456
457 // Parameters
458 // ==========
459 // graph : XNetwork graph-like class
460 // nbunch : node, container of nodes, or None meaning all nodes
461 // (default=None); weight : string or None (default=None);
462
463 // Notes
464 // -----
465 // DegreeView can still lookup any node even if (nbunch is specified.
466
467 // Examples
468 // --------
469 // > gra = xnetwork::path_graph(3);
470 // > DV = gra.degree();
471 // > assert(DV[2] == 1);
472 // > assert(gra.degree[2] == 1);
473 // > assert(sum(deg for n, deg : DV) == 4);
474
475 // > DVweight = gra.degree(weight="span");
476 // > gra.add_edge(1, 2, span=34);
477 // > DVweight[2];
478 // 34
479 // > DVweight[0]; // default edge weight is 1
480 // 1
481 // > sum(span for n, span : DVweight); // sum weighted degrees
482 // 70
483
484 // > DVnbunch = gra.degree(nbunch=(1, 2));
485 // > assert(len(list(DVnbunch)) == 2); // iteration over nbunch only
486 // */
487
488 // auto operator[]( n) {
489 // weight = this->_weight;
490 // nbrs = this->_succ[n];
491 // if (weight.empty()) {
492 // return len(nbrs) + (n : nbrs);
493 // }
494 // return sum(dd.get(weight, 1) for dd : nbrs.values()) +
495 // (n : nbrs and nbrs[n].get(weight, 1));
496 // }
497
498 // auto __iter__( ) {
499 // weight = this->_weight;
500 // if (weight.empty()) {
501 // for (auto n : this->_nodes) {
502 // nbrs = this->_succ[n];
503 // yield (n, len(nbrs) + (n : nbrs));
504 // }
505 // } else {
506 // for (auto n : this->_nodes) {
507 // nbrs = this->_succ[n];
508 // deg = sum(dd.get(weight, 1) for dd : nbrs.values()) +
509 // (n : nbrs and nbrs[n].get(weight, 1));
510 // yield (n, deg);
511 // }
512 // }
513 // }
514 // };
515
516 // class OutDegreeView: public DiDegreeView {
517 // /** A DegreeView class to report out_degree for a DiGraph; See DegreeView
518 // */
519
520 // auto operator[]( n) {
521 // weight = this->_weight;
522 // nbrs = this->_succ[n];
523 // if (this->_weight.empty()) {
524 // return len(nbrs);
525 // }
526 // return sum(dd.get(this->_weight, 1) for dd : nbrs.values());
527 // }
528
529 // auto __iter__( ) {
530 // weight = this->_weight;
531 // if (weight.empty()) {
532 // for (auto n : this->_nodes) {
533 // succs = this->_succ[n];
534 // yield (n, len(succs));
535 // }
536 // } else {
537 // for (auto n : this->_nodes) {
538 // succs = this->_succ[n];
539 // deg = sum(dd.get(weight, 1) for dd : succs.values());
540 // yield (n, deg);
541 // }
542 // }
543 // }
544 // };
545
546 // class InDegreeView: public DiDegreeView {
547 // /** A DegreeView class to report in_degree for a DiGraph; See DegreeView
548 // */
549
550 // auto operator[]( n) {
551 // weight = this->_weight;
552 // nbrs = this->_pred[n];
553 // if (weight.empty()) {
554 // return len(nbrs);
555 // }
556 // return sum(dd.get(weight, 1) for dd : nbrs.values());
557 // }
558
559 // auto __iter__( ) {
560 // weight = this->_weight;
561 // if (weight.empty()) {
562 // for (auto n : this->_nodes) {
563 // preds = this->_pred[n];
564 // yield (n, len(preds));
565 // }
566 // } else {
567 // for (auto n : this->_nodes) {
568 // preds = this->_pred[n];
569 // deg = sum(dd.get(weight, 1) for dd : preds.values());
570 // yield (n, deg);
571 // }
572 // }
573 // }
574 // };
575
576 // class MultiDegreeView: public DiDegreeView {
577 // /** A DegreeView class for undirected multigraphs; See DegreeView */
578
579 // auto operator[]( n) {
580 // weight = this->_weight;
581 // nbrs = this->_succ[n];
582 // if (weight.empty()) {
583 // return sum(len(keys) for keys : nbrs.values()) +
584 // (n : nbrs and len(nbrs[n]));
585 // }
586 // // edge weighted graph - degree is sum of nbr edge weights
587 // deg = sum(d.get(weight, 1) for key_dict : nbrs.values();
588 // for (auto d : key_dict.values());
589 // if (n : nbrs) {
590 // deg += sum(d.get(weight, 1) for d : nbrs[n].values());
591 // }
592 // return deg;
593 // }
594
595 // auto __iter__( ) {
596 // weight = this->_weight;
597 // if (weight.empty()) {
598 // for (auto n : this->_nodes) {
599 // nbrs = this->_succ[n];
600 // deg = sum(len(keys) for keys : nbrs.values()) +
601 // (n : nbrs and len(nbrs[n]));
602 // yield (n, deg);
603 // }
604 // } else {
605 // for (auto n : this->_nodes) {
606 // nbrs = this->_succ[n];
607 // deg = sum(d.get(weight, 1) for key_dict : nbrs.values();
608 // for (auto d : key_dict.values());
609 // if (n : nbrs) {
610 // deg += sum(d.get(weight, 1) for d : nbrs[n].values());
611 // }
612 // yield (n, deg);
613 // }
614 // }
615 // }
616 // };
617
618 // class DiMultiDegreeView: public DiDegreeView {
619 // /** A DegreeView class for MultiDiGraph; See DegreeView */
620
621 // auto operator[]( n) {
622 // weight = this->_weight;
623 // succs = this->_succ[n];
624 // preds = this->_pred[n];
625 // if (weight.empty()) {
626 // return sum(len(keys) for keys : succs.values()) +
627 // sum(len(keys) for keys : preds.values());
628 // }
629 // // edge weighted graph - degree is sum of nbr edge weights
630 // deg = sum(d.get(weight, 1) for key_dict : succs.values();
631 // for (auto d : key_dict.values()) +
632 // sum(d.get(weight, 1) for key_dict : preds.values();
633 // for (auto d : key_dict.values());
634 // return deg;
635 // }
636
637 // auto __iter__( ) {
638 // weight = this->_weight;
639 // if (weight.empty()) {
640 // for (auto n : this->_nodes) {
641 // succs = this->_succ[n];
642 // preds = this->_pred[n];
643 // deg = sum(len(keys) for keys : succs.values()) +
644 // sum(len(keys) for keys : preds.values());
645 // yield (n, deg);
646 // }
647 // } else {
648 // for (auto n : this->_nodes) {
649 // succs = this->_succ[n];
650 // preds = this->_pred[n];
651 // deg = sum(d.get(weight, 1) for key_dict : succs.values();
652 // for (auto d : key_dict.values()) +
653 // sum(d.get(weight, 1) for key_dict : preds.values();
654 // for (auto d : key_dict.values());
655 // yield (n, deg);
656 // }
657 // }
658 // }
659 // };
660
661 // class InMultiDegreeView: public DiDegreeView {
662 // /** A DegreeView class for inward degree of MultiDiGraph; See DegreeView
663 // */
664
665 // auto operator[]( n) {
666 // weight = this->_weight;
667 // nbrs = this->_pred[n];
668 // if (weight.empty()) {
669 // return sum(len(data) for data : nbrs.values());
670 // }
671 // // edge weighted graph - degree is sum of nbr edge weights
672 // return sum(d.get(weight, 1) for key_dict : nbrs.values();
673 // for (auto d : key_dict.values());
674 // }
675
676 // auto __iter__( ) {
677 // weight = this->_weight;
678 // if (weight.empty()) {
679 // for (auto n : this->_nodes) {
680 // nbrs = this->_pred[n];
681 // deg = sum(len(data) for data : nbrs.values());
682 // yield (n, deg);
683 // }
684 // } else {
685 // for (auto n : this->_nodes) {
686 // nbrs = this->_pred[n];
687 // deg = sum(d.get(weight, 1) for key_dict : nbrs.values();
688 // for (auto d : key_dict.values());
689 // yield (n, deg);
690 // }
691 // }
692 // }
693 // };
694
695 // class OutMultiDegreeView: public DiDegreeView {
696 // /** A DegreeView class for outward degree of MultiDiGraph; See DegreeView
697 // */
698
699 // auto operator[]( n) {
700 // weight = this->_weight;
701 // nbrs = this->_succ[n];
702 // if (weight.empty()) {
703 // return sum(len(data) for data : nbrs.values());
704 // }
705 // // edge weighted graph - degree is sum of nbr edge weights
706 // return sum(d.get(weight, 1) for key_dict : nbrs.values();
707 // for (auto d : key_dict.values());
708 // }
709
710 // auto __iter__( ) {
711 // weight = this->_weight;
712 // if (weight.empty()) {
713 // for (auto n : this->_nodes) {
714 // nbrs = this->_succ[n];
715 // deg = sum(len(data) for data : nbrs.values());
716 // yield (n, deg);
717 // }
718 // } else {
719 // for (auto n : this->_nodes) {
720 // nbrs = this->_succ[n];
721 // deg = sum(d.get(weight, 1) for key_dict : nbrs.values();
722 // for (auto d : key_dict.values());
723 // yield (n, deg);
724 // }
725 // }
726 // }
727 // };
728
729 // // EdgeDataViews
730 // class OutEdgeDataView: public object {
731 // /** EdgeDataView for outward edges of DiGraph; See EdgeDataView */
732 // static const auto __slots__ = ("_viewer", "_nbunch", "_data", "_default",
733 // "_adjdict", "_nodes_nbrs", "_report");
734
735 // auto __getstate__( ) {
736 // return {"viewer": this->_viewer,
737 // "nbunch": this->_nbunch,
738 // "data": this->_data,;
739 // "default": this->_default};
740 // }
741
742 // auto __setstate__( state) {
743 // this->__init__(**state);
744 // }
745
746 // explicit _Self( viewer, nbunch=None, data=false, default=None) {
747 // this->_viewer = viewer;
748 // this->_adjdict = viewer._adjdict;
749 // if (nbunch.empty()) {
750 // this->_nodes_nbrs = this->_adjdict.items;
751 // } else {
752 // nbunch = list(viewer._graph.nbunch_iter(nbunch));
753 // this->_nodes_nbrs = lambda: [(n, this->_adjdict[n]) for n :
754 // nbunch];
755 // }
756 // this->_nbunch = nbunch;
757 // this->_data = data;
758 // this->_default = default;
759 // // Set _report based on data and default
760 // if (data == true) {
761 // this->_report = lambda n, nbr, dd: (n, nbr, dd);
762 // } else if (data == false) {
763 // this->_report = lambda n, nbr, dd: (n, nbr);
764 // } else { //data is attribute name
765 // this->_report = lambda n, nbr, dd:
766 // (n, nbr, dd[data]) if (data : dd else (n, nbr, default);
767 // }
768 // }
769
770 // auto __len__( ) {
771 // return sum(len(nbrs) for n, nbrs : this->_nodes_nbrs());
772 // }
773
774 // auto __iter__( ) {
775 // return (this->_report(n, nbr, dd) for n, nbrs : this->_nodes_nbrs();
776 // for (auto nbr, dd : nbrs.items());
777 // }
778
779 // bool contains( e) {
780 // try {
781 // auto [u, v] = e[:2];
782 // ddict = this->_adjdict[u][v];
783 // } catch (KeyError) {
784 // return false;
785 // }
786 // return e == this->_report(u, v, ddict);
787 // }
788
789 // auto __str__( ) {
790 // return str(list( ));
791 // }
792
793 // // auto __repr__( ) {
794 // // return "%s(%r)" % (this->__class__.__name__, list( ));
795 // // }
796 // };
797
798 // class EdgeDataView(OutEdgeDataView) {
799 // /** A EdgeDataView class for edges of Graph
800
801 // This view is primarily used to iterate over the edges reporting
802 // edges as node-tuples with edge data optionally reported. The
803 // argument `nbunch` allows restriction to edges incident to nodes
804 // : that container/singleton. The default (nbunch=None);
805 // reports all edges. The arguments `data` and `default` control
806 // what edge data is reported. The default `data == false` reports
807 // only node-tuples for each edge. If `data is true` the entire edge
808 // data dict is returned. Otherwise `data` is assumed to hold the name
809 // of the edge attribute to report with default `default` if ( that
810 // edge attribute is not present.
811
812 // Parameters
813 // ----------
814 // nbunch : container of nodes, node or None (default None);
815 // data : false, true or string (default false);
816 // default : default value (default None);
817
818 // Examples
819 // --------
820 // > gra = xnetwork::path_graph(3);
821 // > gra.add_edge(1, 2, foo="bar");
822 // > list(gra.edges(data="foo", default="biz"));
823 // [(0, 1, "biz"), (1, 2, "bar")];
824 // > assert((0, 1, "biz"] : gra.edges(data="foo", default="biz"));
825 // */
826 // static const auto __slots__ = ();
827
828 // auto __len__( ) {
829 // return sum(1 for e : *this);
830 // }
831
832 // auto __iter__( ) {
833 // seen = {};
834 // for (auto n, nbrs : this->_nodes_nbrs() {
835 // for (auto nbr, dd : nbrs.items() {
836 // if (nbr not : seen) {
837 // yield this->_report(n, nbr, dd);
838 // }
839 // }
840 // seen[n] = 1;
841 // }
842 // del seen;
843 // }
844
845 // bool contains( e) {
846 // try {
847 // auto [u, v] = e[:2];
848 // ddict = this->_adjdict[u][v];
849 // } catch (KeyError) {
850 // try {
851 // ddict = this->_adjdict[v][u];
852 // } catch (KeyError) {
853 // return false;
854 // }
855 // }
856 // return e == this->_report(u, v, ddict);
857 // }
858 // };
859
860 // class InEdgeDataView(OutEdgeDataView) {
861 // /** An EdgeDataView class for outward edges of DiGraph; See EdgeDataView
862 // */ static const auto __slots__ = ();
863
864 // auto __iter__( ) {
865 // return (this->_report(nbr, n, dd) for n, nbrs : this->_nodes_nbrs();
866 // for (auto nbr, dd : nbrs.items());
867 // }
868
869 // bool contains( e) {
870 // try {
871 // auto [u, v] = e[:2];
872 // ddict = this->_adjdict[v][u];
873 // } catch (KeyError) {
874 // return false;
875 // }
876 // return e == this->_report(u, v, ddict);
877 // }
878 // };
879
880 // class OutMultiEdgeDataView(OutEdgeDataView) {
881 // /** An EdgeDataView for outward edges of MultiDiGraph; See EdgeDataView
882 // */ static const auto __slots__ = ("keys",);
883
884 // auto __getstate__( ) {
885 // return {"viewer": this->_viewer,
886 // "nbunch": this->_nbunch,
887 // "keys": this->keys,
888 // "data": this->_data,
889 // "default": this->_default};
890 // }
891
892 // auto __setstate__( state) {
893 // this->__init__(**state);
894 // }
895
896 // explicit _Self( viewer, nbunch=None,
897 // data=false, keys=false, default=None) {
898 // this->_viewer = viewer;
899 // this->_adjdict = viewer._adjdict;
900 // this->keys = keys;
901 // if (nbunch.empty()) {
902 // this->_nodes_nbrs = this->_adjdict.items;
903 // } else {
904 // nbunch = list(viewer._graph.nbunch_iter(nbunch));
905 // this->_nodes_nbrs = lambda: [(n, this->_adjdict[n]) for n :
906 // nbunch];
907 // }
908 // this->_nbunch = nbunch;
909 // this->_data = data;
910 // this->_default = default;
911 // // Set _report based on data and default
912 // if (data == true) {
913 // if (keys == true) {
914 // this->_report = lambda n, nbr, k, dd: (n, nbr, k, dd);
915 // } else {
916 // this->_report = lambda n, nbr, k, dd: (n, nbr, dd);
917 // }
918 // } else if (data == false) {
919 // if (keys == true) {
920 // this->_report = lambda n, nbr, k, dd: (n, nbr, k);
921 // } else {
922 // this->_report = lambda n, nbr, k, dd: (n, nbr);
923 // }
924 // } else { //data is attribute name
925 // if (keys == true) {
926 // this->_report = lambda n, nbr, k, dd: (n, nbr, k, dd[data])
927 // if (data : dd else (n, nbr, k, default);
928 // } else {
929 // this->_report = lambda n, nbr, k, dd: (n, nbr, dd[data])
930 // if (data : dd else (n, nbr, default);
931 // }
932 // }
933 // }
934
935 // auto __len__( ) {
936 // return sum(1 for e : *this);
937 // }
938
939 // auto __iter__( ) {
940 // return (this->_report(n, nbr, k, dd) for n, nbrs :
941 // this->_nodes_nbrs();
942 // for (auto nbr, kd : nbrs.items() for k, dd : kd.items());
943 // }
944
945 // bool contains( e) {
946 // auto [u, v] = e[:2];
947 // try {
948 // kdict = this->_adjdict[u][v];
949 // } catch (KeyError) {
950 // return false;
951 // }
952 // if (this->keys == true) {
953 // k = e[2];
954 // try {
955 // dd = kdict[k];
956 // } catch (KeyError) {
957 // return false;
958 // }
959 // return e == this->_report(u, v, k, dd);
960 // }
961 // for (auto k, dd : kdict.items() {
962 // if (e == this->_report(u, v, k, dd) {
963 // return true;
964 // }
965 // }
966 // return false;
967 // }
968 // };
969
970 // class MultiEdgeDataView(OutMultiEdgeDataView) {
971 // /** An EdgeDataView class for edges of MultiGraph; See EdgeDataView */
972 // static const auto __slots__ = ();
973
974 // auto __iter__( ) {
975 // seen = {};
976 // for (auto n, nbrs : this->_nodes_nbrs() {
977 // for (auto nbr, kd : nbrs.items() {
978 // if (nbr not : seen) {
979 // for (auto k, dd : kd.items() {
980 // yield this->_report(n, nbr, k, dd);
981 // }
982 // }
983 // }
984 // seen[n] = 1;
985 // }
986 // del seen;
987 // }
988
989 // bool contains( e) {
990 // auto [u, v] = e[:2];
991 // try {
992 // kdict = this->_adjdict[u][v];
993 // } catch (KeyError) {
994 // try {
995 // kdict = this->_adjdict[v][u];
996 // } catch (KeyError) {
997 // return false;
998 // }
999 // }
1000 // if (this->keys == true) {
1001 // k = e[2];
1002 // try {
1003 // dd = kdict[k];
1004 // } catch (KeyError) {
1005 // return false;
1006 // }
1007 // return e == this->_report(u, v, k, dd);
1008 // }
1009 // for (auto k, dd : kdict.items() {
1010 // if (e == this->_report(u, v, k, dd) {
1011 // return true;
1012 // }
1013 // }
1014 // return false;
1015 // }
1016 // };
1017
1018 // class InMultiEdgeDataView(OutMultiEdgeDataView) {
1019 // /** An EdgeDataView for inward edges of MultiDiGraph; See EdgeDataView */
1020 // static const auto __slots__ = ();
1021
1022 // auto __iter__( ) {
1023 // return (this->_report(nbr, n, k, dd) for n, nbrs :
1024 // this->_nodes_nbrs();
1025 // for (auto nbr, kd : nbrs.items() for k, dd : kd.items());
1026 // }
1027
1028 // bool contains( e) {
1029 // auto [u, v] = e[:2];
1030 // try {
1031 // kdict = this->_adjdict[v][u];
1032 // } catch (KeyError) {
1033 // return false;
1034 // }
1035 // if (this->keys == true) {
1036 // k = e[2];
1037 // dd = kdict[k];
1038 // return e == this->_report(u, v, k, dd);
1039 // }
1040 // for (auto k, dd : kdict.items() {
1041 // if (e == this->_report(u, v, k, dd) {
1042 // return true;
1043 // }
1044 // }
1045 // return false;
1046 // }
1047 // };
1048
1049 // EdgeViews have set operations and no data reported
1050 // Interface: Set, Mapping
1052 // template <typename graph_t>
1053 // class OutEdgeView {
1054 // // static const auto __slots__ = ("_adjdict", "_graph", "_nodes_nbrs");
1055
1056 // // auto __getstate__( ) {
1057 // // return {"_graph": this->_graph};
1058 // // }
1059
1060 // // auto __setstate__( state) {
1061 // // this->_graph = gra = state["_graph"];
1062 // // this->_adjdict = gra._succ if (hasattr(gra, "succ") else gra._adj;
1063 // // this->_nodes_nbrs = this->_adjdict.items;
1064 // // }
1065
1066 // /// @classmethod
1067 // // auto _from_iterable(cls, it) {
1068 // // return set(it);
1069 // // }
1070
1071 // // using dataview = OutEdgeDataView;
1072 // using Self = OutEdgeView<graph_t>;
1073
1074 // using node_t = typename graph_t::Node;
1075 // using edge_t = std::pair<node_t, node_t>;
1076 // using adjdict_t = typename graph_t::adjlist_outer_dict_factory;
1077
1078 // graph_t& _graph;
1079 // adjdict_t& _adjdict;
1080 // // T _nodes_nbrs;
1081
1082 // // using adjiterator = decltype(_graph.adj().begin());
1083 // // adjiterator curitem; /* ??? */
1084
1085 // explicit OutEdgeView(graph_t& gra) :
1086 // _graph{gra},
1087 // // _adjdict = gra._succ if (hasattr(gra, "succ") else gra._adj;
1088 // // _nodes_nbrs{this->_adjdict.items()},
1089 // _adjdict{gra._adj}
1090 // {}
1091
1092 // // Set methods
1093 // // auto __len__( ) {
1094 // // return sum(len(nbrs) for n, nbrs : this->_nodes_nbrs());
1095 // // }
1096
1097 // // auto __iter__( ) {
1098 // // for (auto [n, nbrs] : this->_nodes_nbrs()) {
1099 // // for (auto nbr : nbrs) {
1100 // // yield (n, nbr);
1101 // // }
1102 // // }
1103 // // }
1104
1105 // bool contains(const edge_t& e) {
1106 // auto [u, v] = e;
1107 // return this->_adjdict[u].contains(v);
1108 // }
1109
1110 // // Mapping Methods
1111 // auto operator[](const edge_t& e) {
1112 // auto [u, v] = e;
1113 // return this->_adjdict[u][v];
1114 // }
1115
1116 // // // EdgeDataView methods
1117 // // auto __call__( nbunch=None, data=false, default=None) {
1118 // // if (nbunch.empty() and data == false) {
1119 // // return (*this);
1120 // // }
1121 // // return this->dataview( nbunch, data, default);
1122 // // }
1123
1124 // // auto data( data=true, default=None, nbunch=None) {
1125 // // if (nbunch.empty() and data == false) {
1126 // // return (*this);
1127 // // }
1128 // // return this->dataview( nbunch, data, default);
1129 // // }
1130
1131 // // // String Methods
1132 // // auto __str__( ) {
1133 // // return str(list( ));
1134 // // }
1135
1136 // // auto __repr__( ) {
1137 // // return "{0.__class__.__name__}({1!r})".format( list( ));
1138 // // }
1139 // };
1140
1141 // class EdgeView(OutEdgeView) {
1142 // /** A EdgeView class for edges of a Graph
1143
1144 // This densely packed View allows iteration over edges, data lookup
1145 // like a dict and set operations on edges represented by node-tuples.
1146 // In addition, edge data can be controlled by calling this object
1147 // possibly creating an EdgeDataView. Typically edges are iterated over
1148 // and reported as `(u, v)` node tuples or `(u, v, key)` node/key tuples
1149 // for (auto multigraphs. Those edge representations can also be using to
1150 // lookup the data dict for any edge. Set operations also are available
1151 // where those tuples are the elements of the set.
1152 // Calling this object with optional arguments `data`, `default` and `keys`
1153 // controls the form of the tuple (see EdgeDataView). Optional argument
1154 // `nbunch` allows restriction to edges only involving certain nodes.
1155
1156 // If `data == false` (the default) then iterate over 2-tuples `(u, v)`.
1157 // If `data is true` iterate over 3-tuples `(u, v, datadict)`.
1158 // Otherwise iterate over `(u, v, datadict.get(data, default))`.
1159 // For Multigraphs, if (`keys is true`, replace `u, v` with `u, v, key`
1160 // above.
1161
1162 // Parameters
1163 // ==========
1164 // graph : XNetwork graph-like class
1165 // nbunch : (default= all nodes : graph) only report edges with these nodes
1166 // keys : (only for MultiGraph. default=false) report edge key : tuple
1167 // data : bool or string (default=false) see above
1168 // default : object (default=None);
1169
1170 // Examples
1171 // ========
1172 // > gra = xnetwork::path_graph(4);
1173 // > EV = gra.edges();
1174 // > (2, 3] : EV
1175 // true
1176 // > for u, v : EV: print((u, v));
1177 // (0, 1);
1178 // (1, 2);
1179 // (2, 3);
1180 // > assert(EV & {(1, 2), (3, 4)} == {(1, 2)});
1181
1182 // > EVdata = gra.edges(data="color", default="aqua");
1183 // > gra.add_edge(2, 3, color="blue");
1184 // > assert((2, 3, "blue"] : EVdata);
1185 // > for u, v, c : EVdata: print("({}, {}) has color: {}".format(u, v,
1186 // c)); (0, 1) has color: aqua (1, 2) has color: aqua (2, 3) has color: blue
1187
1188 // > EVnbunch = gra.edges(nbunch=2);
1189 // > assert((2, 3] : EVnbunch);
1190 // > assert((0, 1] : EVnbunch) // nbunch is ignored : __contains__
1191 // > for u, v : EVnbunch: assert(u == 2 or v == 2);
1192
1193 // > MG = xnetwork::path_graph(4, create_using=xnetwork::MultiGraph());
1194 // > EVmulti = MG.edges(keys=true);
1195 // > (2, 3, 0] : EVmulti
1196 // true
1197 // > (2, 3] : EVmulti // 2-tuples work even when keys is true
1198 // true
1199 // > key = MG.add_edge(2, 3);
1200 // > for u, v, k : EVmulti: print((u, v, k));
1201 // (0, 1, 0);
1202 // (1, 2, 0);
1203 // (2, 3, 0);
1204 // (2, 3, 1);
1205 // */
1206 // static const auto __slots__ = ();
1207
1208 // dataview = EdgeDataView;
1209
1210 // auto __len__( ) {
1211 // return sum(len(nbrs) + (n : nbrs) for n, nbrs : this->_nodes_nbrs())
1212 // / 2;
1213 // }
1214
1215 // auto __iter__( ) {
1216 // seen = {};
1217 // for (auto n, nbrs : this->_nodes_nbrs() {
1218 // for (auto nbr : nbrs) {
1219 // if (nbr not : seen) {
1220 // yield (n, nbr);
1221 // }
1222 // }
1223 // seen[n] = 1;
1224 // }
1225 // del seen;
1226 // }
1227
1228 // bool contains( e) {
1229 // try {
1230 // auto [u, v] = e[:2];
1231 // return v : this->_adjdict[u] or u : this->_adjdict[v];
1232 // } catch ((KeyError, ValueError) {
1233 // return false;
1234 // }
1235 // }
1236 // };
1237
1238 // class InEdgeView(OutEdgeView) {
1239 // /** A EdgeView class for inward edges of a DiGraph */
1240 // static const auto __slots__ = ();
1241
1242 // auto __setstate__( state) {
1243 // this->_graph = gra = state["_graph"];
1244 // this->_adjdict = gra._pred if (hasattr(gra, "pred") else gra._adj;
1245 // this->_nodes_nbrs = this->_adjdict.items;
1246 // }
1247
1248 // dataview = InEdgeDataView;
1249
1250 // explicit _Self( gra) {
1251 // this->_graph = gra;
1252 // this->_adjdict = gra._pred if (hasattr(gra, "pred") else gra._adj;
1253 // this->_nodes_nbrs = this->_adjdict.items;
1254 // }
1255
1256 // auto __iter__( ) {
1257 // for (auto n, nbrs : this->_nodes_nbrs() {
1258 // for (auto nbr : nbrs) {
1259 // yield (nbr, n);
1260 // }
1261 // }
1262 // }
1263
1264 // bool contains( e) {
1265 // try {
1266 // auto [u, v] = e;
1267 // return u : this->_adjdict[v];
1268 // } catch (KeyError) {
1269 // return false;
1270 // }
1271 // }
1272
1273 // auto operator[]( e) {
1274 // auto [u, v] = e;
1275 // return this->_adjdict[v][u];
1276 // }
1277 // };
1278
1279 // class OutMultiEdgeView(OutEdgeView) {
1280 // /** A EdgeView class for outward edges of a MultiDiGraph */
1281 // static const auto __slots__ = ();
1282
1283 // dataview = OutMultiEdgeDataView;
1284
1285 // auto __len__( ) {
1286 // return sum(len(kdict) for n, nbrs : this->_nodes_nbrs();
1287 // for (auto nbr, kdict : nbrs.items());
1288 // }
1289
1290 // auto __iter__( ) {
1291 // for (auto n, nbrs : this->_nodes_nbrs() {
1292 // for (auto nbr, kdict : nbrs.items() {
1293 // for (auto key : kdict) {
1294 // yield (n, nbr, key);
1295 // }
1296 // }
1297 // }
1298 // }
1299
1300 // bool contains( e) {
1301 // N = len(e);
1302 // if (N == 3) {
1303 // u, v, k = e;
1304 // } else if (N == 2) {
1305 // auto [u, v] = e;
1306 // k = 0.;
1307 // } else {
1308 // throw ValueError("MultiEdge must have length 2 or 3");
1309 // }
1310 // try {
1311 // return k : this->_adjdict[u][v];
1312 // } catch (KeyError) {
1313 // return false;
1314 // }
1315 // }
1316
1317 // auto operator[]( e) {
1318 // u, v, k = e;
1319 // return this->_adjdict[u][v][k];
1320 // }
1321
1322 // auto __call__( nbunch=None, data=false, keys=false, default=None) {
1323 // if (nbunch.empty() and data == false and keys == true) {
1324 // return (*this);
1325 // }
1326 // return this->dataview( nbunch, data, keys, default);
1327 // }
1328
1329 // auto data( data=true, keys=false, default=None, nbunch=None) {
1330 // if (nbunch.empty() and data == false and keys == true) {
1331 // return (*this);
1332 // }
1333 // return this->dataview( nbunch, data, keys, default);
1334 // }
1335 // };
1336
1337 // class MultiEdgeView(OutMultiEdgeView) {
1338 // /** A EdgeView class for edges of a MultiGraph */
1339 // static const auto __slots__ = ();
1340
1341 // dataview = MultiEdgeDataView;
1342
1343 // auto __len__( ) {
1344 // return sum(1 for e : *this);
1345 // }
1346
1347 // auto __iter__( ) {
1348 // seen = {};
1349 // for (auto n, nbrs : this->_nodes_nbrs() {
1350 // for (auto nbr, kd : nbrs.items() {
1351 // if (nbr not : seen) {
1352 // for (auto k, dd : kd.items() {
1353 // yield (n, nbr, k);
1354 // }
1355 // }
1356 // }
1357 // seen[n] = 1;
1358 // }
1359 // del seen;
1360 // }
1361 // };
1362
1363 // class InMultiEdgeView(OutMultiEdgeView) {
1364 // /** A EdgeView class for inward edges of a MultiDiGraph */
1365 // static const auto __slots__ = ();
1366
1367 // auto __setstate__( state) {
1368 // this->_graph = gra = state["_graph"];
1369 // this->_adjdict = gra._pred if (hasattr(gra, "pred") else gra._adj;
1370 // this->_nodes_nbrs = this->_adjdict.items;
1371 // }
1372
1373 // dataview = InMultiEdgeDataView;
1374
1375 // explicit _Self( gra) {
1376 // this->_graph = gra;
1377 // this->_adjdict = gra._pred if (hasattr(gra, "pred") else gra._adj;
1378 // this->_nodes_nbrs = this->_adjdict.items;
1379 // }
1380
1381 // auto __iter__( ) {
1382 // for (auto n, nbrs : this->_nodes_nbrs() {
1383 // for (auto nbr, kdict : nbrs.items() {
1384 // for (auto key : kdict) {
1385 // yield (nbr, n, key);
1386 // }
1387 // }
1388 // }
1389 // }
1390
1391 // bool contains( e) {
1392 // N = len(e);
1393 // if (N == 3) {
1394 // u, v, k = e;
1395 // } else if (N == 2) {
1396 // auto [u, v] = e;
1397 // k = 0.;
1398 // } else {
1399 // throw ValueError("MultiEdge must have length 2 or 3");
1400 // }
1401 // try {
1402 // return k : this->_adjdict[v][u];
1403 // } catch (KeyError) {
1404 // return false;
1405 // }
1406 // }
1407
1408 // auto operator[]( e) {
1409 // u, v, k = e;
1410 // return this->_adjdict[v][u][k];
1411 // }
1412 // };
1413
1414} // namespace xnetwork
Read-only map of maps of maps (view into a dict-of-dict-of-dict structure)
Definition coreviews.hpp:109
auto size() const -> size_t
Get the number of elements in the view.
Definition coreviews.hpp:49
NodeView class - acts as gra.nodes() for an XNetwork Graph.
Definition reportviews.hpp:130
auto end() const
Get iterator to the end of the view.
Definition reportviews.hpp:168
auto contains(const Node &node) const -> bool
Check if a node exists in the view.
Definition reportviews.hpp:190
auto begin() const
Get iterator to the beginning of the view.
Definition reportviews.hpp:162
auto size() const
Get the number of nodes in the view.
Definition reportviews.hpp:156
auto operator[](const Node &node) const -> const auto &
Access node data at specified node (const version)
Definition reportviews.hpp:175
auto operator[](const Node &node) -> auto &
Access node data at specified node (non-const version)
Definition reportviews.hpp:182
NodeView(nodeview_t &nodes)
Construct a NodeView from a node container.
Definition reportviews.hpp:149
Definition digraphs.hpp:24