Skip to content

Commit b5af566

Browse files
author
Michael Phelps
committed
Add support for some set methods
1 parent 7e1ec38 commit b5af566

File tree

8 files changed

+281
-1
lines changed

8 files changed

+281
-1
lines changed

README.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,111 @@ func main() {
549549
fmt.Println(l2)
550550
}
551551
```
552+
### set_methods
553+
#### Python
554+
```python
555+
def main():
556+
a = {1, 2, 3, 4}
557+
b = {4, 5, 6}
558+
b.add(7)
559+
print(a.union(b))
560+
print(a.intersection(b))
561+
print(a.difference(b))
562+
print(a.symmetric_difference(b))
563+
564+
print(a.issubset(b))
565+
print(a.issuperset(b))
566+
567+
568+
if __name__ == '__main__':
569+
main()
570+
```
571+
#### Go
572+
```go
573+
package main
574+
import "fmt"
575+
func main() {
576+
a := map[interface{}]struct{}{1: {}, 2: {}, 3: {}, 4: {}}
577+
b := map[interface{}]struct{}{4: {}, 5: {}, 6: {}}
578+
b[7] = struct{}{}
579+
fmt.Println(func(s1 map[interface{}]struct{}, s2 map[interface{}]struct{}) map[interface{}]struct{} {
580+
union := map[interface{}]struct{}{}
581+
for elt := range s1 {
582+
union[elt] = struct{}{}
583+
}
584+
for elt := range s2 {
585+
union[elt] = struct{}{}
586+
}
587+
return union
588+
}(a, b))
589+
fmt.Println(func(s1 map[interface{}]struct{}, s2 map[interface{}]struct{}) map[interface{}]struct{} {
590+
intersection := map[interface{}]struct{}{}
591+
for elt := range s1 {
592+
if func() bool {
593+
_, ok := s2[elt]
594+
return ok
595+
}() {
596+
intersection[elt] = struct{}{}
597+
}
598+
}
599+
return intersection
600+
}(a, b))
601+
fmt.Println(func(s1 map[interface{}]struct{}, s2 map[interface{}]struct{}) map[interface{}]struct{} {
602+
difference := map[interface{}]struct{}{}
603+
for elt := range s1 {
604+
if !func() bool {
605+
_, ok := s2[elt]
606+
return ok
607+
}() {
608+
difference[elt] = struct{}{}
609+
}
610+
}
611+
return difference
612+
}(a, b))
613+
fmt.Println(func(s1 map[interface{}]struct{}, s2 map[interface{}]struct{}) map[interface{}]struct{} {
614+
symmetric_intersection := map[interface{}]struct{}{}
615+
for elt := range s1 {
616+
if !func() bool {
617+
_, ok := s2[elt]
618+
return ok
619+
}() {
620+
symmetric_intersection[elt] = struct{}{}
621+
}
622+
}
623+
for elt := range s2 {
624+
if !func() bool {
625+
_, ok := s1[elt]
626+
return ok
627+
}() {
628+
symmetric_intersection[elt] = struct{}{}
629+
}
630+
}
631+
return symmetric_intersection
632+
}(a, b))
633+
fmt.Println(func(s1 map[interface{}]struct{}, s2 map[interface{}]struct{}) bool {
634+
for elt := range s1 {
635+
if !func() bool {
636+
_, ok := s2[elt]
637+
return ok
638+
}() {
639+
return false
640+
}
641+
}
642+
return true
643+
}(a, b))
644+
fmt.Println(func(s1 map[interface{}]struct{}, s2 map[interface{}]struct{}) bool {
645+
for elt := range s2 {
646+
if !func() bool {
647+
_, ok := s1[elt]
648+
return ok
649+
}() {
650+
return false
651+
}
652+
}
653+
return true
654+
}(a, b))
655+
}
656+
```
552657
### boolnumcompare
553658
#### Python
554659
```python

examples/set_methods.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package main
2+
3+
import "fmt"
4+
5+
func main() {
6+
a := map[interface{}]struct{}{1: {}, 2: {}, 3: {}, 4: {}}
7+
b := map[interface{}]struct{}{4: {}, 5: {}, 6: {}}
8+
b[7] = struct{}{}
9+
fmt.Println(func(s1 map[interface{}]struct{}, s2 map[interface{}]struct{}) map[interface{}]struct{} {
10+
union := map[interface{}]struct{}{}
11+
for elt := range s1 {
12+
union[elt] = struct{}{}
13+
}
14+
for elt := range s2 {
15+
union[elt] = struct{}{}
16+
}
17+
return union
18+
}(a, b))
19+
fmt.Println(func(s1 map[interface{}]struct{}, s2 map[interface{}]struct{}) map[interface{}]struct{} {
20+
intersection := map[interface{}]struct{}{}
21+
for elt := range s1 {
22+
if func() bool {
23+
_, ok := s2[elt]
24+
return ok
25+
}() {
26+
intersection[elt] = struct{}{}
27+
}
28+
}
29+
return intersection
30+
}(a, b))
31+
fmt.Println(func(s1 map[interface{}]struct{}, s2 map[interface{}]struct{}) map[interface{}]struct{} {
32+
difference := map[interface{}]struct{}{}
33+
for elt := range s1 {
34+
if !func() bool {
35+
_, ok := s2[elt]
36+
return ok
37+
}() {
38+
difference[elt] = struct{}{}
39+
}
40+
}
41+
return difference
42+
}(a, b))
43+
fmt.Println(func(s1 map[interface{}]struct{}, s2 map[interface{}]struct{}) map[interface{}]struct{} {
44+
symmetric_intersection := map[interface{}]struct{}{}
45+
for elt := range s1 {
46+
if !func() bool {
47+
_, ok := s2[elt]
48+
return ok
49+
}() {
50+
symmetric_intersection[elt] = struct{}{}
51+
}
52+
}
53+
for elt := range s2 {
54+
if !func() bool {
55+
_, ok := s1[elt]
56+
return ok
57+
}() {
58+
symmetric_intersection[elt] = struct{}{}
59+
}
60+
}
61+
return symmetric_intersection
62+
}(a, b))
63+
fmt.Println(func(s1 map[interface{}]struct{}, s2 map[interface{}]struct{}) bool {
64+
for elt := range s1 {
65+
if !func() bool {
66+
_, ok := s2[elt]
67+
return ok
68+
}() {
69+
return false
70+
}
71+
}
72+
return true
73+
}(a, b))
74+
fmt.Println(func(s1 map[interface{}]struct{}, s2 map[interface{}]struct{}) bool {
75+
for elt := range s2 {
76+
if !func() bool {
77+
_, ok := s1[elt]
78+
return ok
79+
}() {
80+
return false
81+
}
82+
}
83+
return true
84+
}(a, b))
85+
}

examples/set_methods.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
def main():
2+
a = {1, 2, 3, 4}
3+
b = {4, 5, 6}
4+
b.add(7)
5+
print(a.union(b))
6+
print(a.intersection(b))
7+
print(a.difference(b))
8+
print(a.symmetric_difference(b))
9+
10+
print(a.issubset(b))
11+
print(a.issuperset(b))
12+
13+
14+
if __name__ == '__main__':
15+
main()

pytago/go_ast/core.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,6 +1198,9 @@ def from_Constant(cls, node: ast.Constant, **kwargs):
11981198

11991199
@classmethod
12001200
def from_Name(cls, name: ast.Name, **kwargs):
1201+
match name.id:
1202+
case 'PY_EMPTY_STRUCT':
1203+
return CompositeLit(Type=StructType(), **kwargs)
12011204
return cls.from_str(name.id, **kwargs)
12021205

12031206
@classmethod

pytago/go_ast/py_snippets.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ def __getitem__(self, item):
1919
PyInterfaceType = InfinitelySubscriptable()
2020
PyStarExpr = InfinitelySubscriptable()
2121

22+
# Special identifiers can go here
23+
PY_EMPTY_STRUCT = None
24+
2225

2326
class BindType(Enum):
2427
PARAMLESS_FUNC_LIT = 0
@@ -288,6 +291,63 @@ def go_copy(s) -> PyInterfaceType[tmp]:
288291
tmp = append(tmp, *('*'@s))
289292
return
290293

294+
# Set methods
295+
@Bindable.add(r"(.*)\.add", bind_type=BindType.STMT)
296+
def go_add(s, elt):
297+
s[elt] = PY_EMPTY_STRUCT
298+
299+
s1 = TypeVar("s1")
300+
@Bindable.add(r"(.*)\.union", bind_type=BindType.FUNC_LIT)
301+
def go_union(s1: set, s2: set) -> PyInterfaceType[s1]:
302+
union = set()
303+
for elt in s1:
304+
union.add(elt)
305+
for elt in s2:
306+
union.add(elt)
307+
return union
308+
309+
@Bindable.add(r"(.*)\.intersection", bind_type=BindType.FUNC_LIT)
310+
def go_intersection(s1: set, s2: set) -> PyInterfaceType[s1]:
311+
intersection = set()
312+
for elt in s1:
313+
if elt in s2:
314+
intersection.add(elt)
315+
return intersection
316+
317+
@Bindable.add(r"(.*)\.difference", bind_type=BindType.FUNC_LIT)
318+
def go_difference(s1: set, s2: set) -> PyInterfaceType[s1]:
319+
difference = set()
320+
for elt in s1:
321+
if elt not in s2:
322+
difference.add(elt)
323+
return difference
324+
325+
@Bindable.add(r"(.*)\.symmetric_difference", bind_type=BindType.FUNC_LIT)
326+
def go_symmetric_intersection(s1: set, s2: set) -> PyInterfaceType[s1]:
327+
symmetric_intersection = set()
328+
for elt in s1:
329+
if elt not in s2:
330+
symmetric_intersection.add(elt)
331+
for elt in s2:
332+
if elt not in s1:
333+
symmetric_intersection.add(elt)
334+
return symmetric_intersection
335+
336+
@Bindable.add(r"(.*)\.issubset", bind_type=BindType.FUNC_LIT)
337+
def go_issubset(s1: set, s2: set) -> bool:
338+
for elt in s1:
339+
if elt not in s2:
340+
return False
341+
return True
342+
343+
@Bindable.add(r"(.*)\.issuperset", bind_type=BindType.FUNC_LIT)
344+
def go_is_subset(s1: set, s2: set) -> bool:
345+
for elt in s2:
346+
if elt not in s1:
347+
return False
348+
return True
349+
350+
291351
# Dict methods
292352

293353
@Bindable.add(r"(.*)\.keys", bind_type=BindType.EXPR)

pytago/go_ast/transformers.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,6 +1522,14 @@ def exit_callback(*args, **kwargs):
15221522
def generic_missing_type_callback(self, node: Expr, val: Expr, type_: Expr):
15231523
return
15241524

1525+
class LoopThroughSetValuesNotKeys(NodeTransformerWithScope):
1526+
def visit_RangeStmt(self, node: RangeStmt):
1527+
self.generic_visit(node)
1528+
match self.scope._get_type(node.X):
1529+
case MapType(Value=StructType(Fields=FieldList(List=[]))):
1530+
if node.Key == Ident("_"):
1531+
node.Key, node.Value = node.Value, node.Key
1532+
return node
15251533

15261534
ALL_TRANSFORMS = [
15271535
UseConstructorIfAvailable,
@@ -1540,6 +1548,7 @@ def generic_missing_type_callback(self, node: Expr, val: Expr, type_: Expr):
15401548
YieldRangeTransformer,
15411549
ReplacePowWithMathPow,
15421550
NodeTransformerWithScope,
1551+
LoopThroughSetValuesNotKeys,
15431552
# AddMissingFunctionTypes,
15441553
IterFuncs,
15451554
IterMethods,

pytago/tests/test_core.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ def test_string_methods(self):
2828
def test_list_methods(self):
2929
self.assert_examples_match("list_methods")
3030

31+
def test_set_methods(self):
32+
self.assert_examples_match("set_methods")
33+
3134
def test_boolnumcompare(self):
3235
self.assert_examples_match("boolnumcompare")
3336

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setup(
77
name='pytago',
8-
version='0.0.4',
8+
version='0.0.5',
99
packages=['pytago'],
1010
url='https://github.com/nottheswimmer/pytago',
1111
license='',

0 commit comments

Comments
 (0)