Skip to content

Commit c32c686

Browse files
committed
Added linq-partitions
1 parent 4e7189f commit c32c686

File tree

4 files changed

+154
-67
lines changed

4 files changed

+154
-67
lines changed

README.md

Lines changed: 58 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11

2-
101 LINQ Samples in Dart
2+
101 LINQ Samples in Python
33
========================
44

5-
Port of the [C# 101 LINQ Samples](http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b) rewritten into idiomatic Dart and utilizing its functional collection mixins.
5+
Port of the [C# 101 LINQ Samples](http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b) rewritten into idiomatic Python and utilizing its functional methods where possible.
6+
7+
Python doesn't really lend itself well to functional programming because is functional methods are really procedural. There is support for lambda expressions, but you can't chain or compose your your functional operations very well as you will see compare to C# equivalent below.
68

79
### Why the fork?
810

@@ -47,10 +49,10 @@ The samples below mirrors the C# LINQ samples layout with the names of the top-l
4749
|---------|--|----|-------|
4850
|**Restriction**|`Where`|`filter`||
4951
|**Projection**|`Select`|`map`||
50-
||`SelectMany`|`expand`||
51-
|**Partitioning**|`Take`|`take`||
52+
||`SelectMany`||Customer select_many utility added|
53+
|**Partitioning**|`IEnumerable.Take(n)`|`array[:n]`||
5254
||`TakeWhile`|`takeWhile`||
53-
||`Skip`|`skip`||
55+
||`IEnumerable.Skip(n)`|`array[n:]`||
5456
||`SkipWhile`|`skipWhile`||
5557
|**Ordering**|`OrderBy`||Custom [order](#dart-utils-added) utility added|
5658
||`OrderByDescending`||Custom [order](#dart-utils-added) utility added, followed by `reversed`|
@@ -96,10 +98,10 @@ The samples below mirrors the C# LINQ samples layout with the names of the top-l
9698
- [Phython](src/python/linq-restrictions.py)
9799
- [C#](src/csharp/linq-restrictions/Program.cs)
98100
- [Projection Operators](#linq---projection-operators)
99-
- [Dart](bin/linq-projections.dart)
101+
- [Phython](src/python/linq-projections.py)
100102
- [C#](src/csharp/linq-projections/Program.cs)
101103
- [Partitioning Operators](#linq---partitioning-operators)
102-
- [Dart](bin/linq-partitioning.dart)
104+
- [Phython]src/python/linq-partitions.py)
103105
- [C#](src/csharp/linq-partitioning/Program.cs)
104106
- [Ordering Operators](#linq---ordering-operators)
105107
- [Dart](bin/linq-ordering.dart)
@@ -338,6 +340,19 @@ def linq5():
338340
LINQ - Projection Operators
339341
---------------------------
340342

343+
### Python utils added
344+
345+
```python
346+
def select_many(outer_list, inner_list):
347+
def select(item, the_list):
348+
return map(lambda b: SimpleNamespace(a=item, b=b), the_list)
349+
350+
result = []
351+
for outer_list in outer_list:
352+
result.extend(select(outer_list, inner_list))
353+
return result
354+
```
355+
341356
### linq6: Select - Simple 1
342357
```csharp
343358
//c#
@@ -638,21 +653,18 @@ public void Linq14()
638653
pairs.ForEach(pair => Console.WriteLine("{0} is less than {1}", pair.a, pair.b));
639654
}
640655
```
641-
```dart
642-
//dart
643-
linq14(){
644-
var numbersA = [ 0, 2, 4, 5, 6, 8, 9 ];
645-
var numbersB = [ 1, 3, 5, 7, 8 ];
646-
647-
var pairs = numbersA
648-
.expand((a) => numbersB
649-
.where((b) => a < b)
650-
.map((b) => { 'a':a, 'b':b }));
651-
652-
print("Pairs where a < b:");
653-
pairs.forEach((pair) =>
654-
print("${pair['a']} is less than ${pair['b']}"));
655-
}
656+
```python
657+
#python
658+
def linq_14():
659+
numbers_a = [0, 2, 4, 5, 6, 8, 9]
660+
numbers_b = [1, 3, 5, 7, 8]
661+
662+
pairs = filter(lambda pair: pair.a < pair.b, select_many(numbers_a, numbers_b))
663+
664+
print("Pairs where a < b:")
665+
for p in pairs:
666+
print("%d is less than %d}" % (p.a, p.b))
667+
656668
```
657669
#### Output
658670

@@ -689,18 +701,16 @@ public void Linq15()
689701
ObjectDumper.Write(orders);
690702
}
691703
```
692-
```dart
693-
//dart
694-
linq15(){
695-
var customers = customersList();
696-
697-
var orders = customers
698-
.expand((c) => c.orders
699-
.where((o) => o.total < 500)
700-
.map((o) => { 'CustomerId': c.customerId, 'OrderId':o.orderId, 'Total':o.total }));
701-
702-
orders.forEach(print);
703-
}
704+
```python
705+
#python
706+
def linq15():
707+
customers = shared.getCustomerList()
708+
709+
orders = map(lambda x: SimpleNamespace(customer_id=x.item_a.CustomerID, order_id=x.item_b.OrderID, total=x.item_b.Total),
710+
filter(lambda x: x.item_b.Total < 500.00,
711+
select_many(customers, "Orders")))
712+
713+
shared.print_namespace(orders)
704714
```
705715
#### Output
706716

@@ -725,8 +735,8 @@ public void Linq16()
725735
ObjectDumper.Write(orders);
726736
}
727737
```
728-
```dart
729-
//dart
738+
```python
739+
#python
730740
linq16(){
731741
var customers = customersList();
732742

@@ -899,15 +909,15 @@ public void Linq20()
899909
first3Numbers.ForEach(Console.WriteLine);
900910
}
901911
```
902-
```dart
903-
//dart
904-
linq20(){
905-
var numbers = [ 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 ];
906-
907-
var first3Numbers = numbers.take(3);
912+
```python
913+
#python
914+
def linq20():
915+
numbers = [5, 4, 1, 3, 9, 8, 6, 7, 2, 0]
916+
917+
first3_numbers = numbers[:3]
908918

909-
print("First 3 numbers:");
910-
first3Numbers.forEach(print);
919+
print("First 3 numbers:")
920+
shared.printN(first3_numbers)
911921
}
912922
```
913923
#### Output
@@ -934,8 +944,8 @@ public void Linq21()
934944
first3WAOrders.ForEach(ObjectDumper.Write);
935945
}
936946
```
937-
```dart
938-
//dart
947+
```python
948+
#python
939949
linq21(){
940950
var customers = customersList();
941951

@@ -1190,9 +1200,9 @@ LINQ - Ordering Operators
11901200
StringComparer.CurrentCultureIgnoreCase
11911201
```
11921202

1193-
### Dart utils added
1203+
### Python utils added
11941204

1195-
```dart
1205+
```python
11961206
wrap(value, fn(x)) => fn(value);
11971207

11981208
order(List seq, {Comparator by, List<Comparator> byAll, on(x), List<Function> onAll}) =>

src/python/linq-partitions.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import shared
2+
3+
def linq20():
4+
numbers = [5, 4, 1, 3, 9, 8, 6, 7, 2, 0]
5+
6+
first3_numbers = numbers[:3]
7+
8+
print("First 3 numbers:")
9+
shared.printN(first3_numbers)
10+
11+
12+
def linq22():
13+
numbers = [5, 4, 1, 3, 9, 8, 6, 7, 2, 0];
14+
all_but_first4_numbers = numbers[4:]
15+
16+
print("All but first 4 numbers:");
17+
shared.printN(all_but_first4_numbers)
18+
19+
20+
21+
linq20()
22+
linq22()

src/python/linq-projections.py

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,77 +2,96 @@
22
from types import SimpleNamespace
33

44

5+
def select(item, the_list):
6+
return map(lambda b: SimpleNamespace(item_a=item, item_b=b), the_list)
7+
8+
9+
def left_outer_join(outer_list, inner_list):
10+
11+
result = []
12+
for outer_item in outer_list:
13+
result.extend(select(outer_item, inner_list))
14+
return result
15+
16+
17+
def select_many(outer_list, inner_item_list_key):
18+
result = []
19+
for outer_item in outer_list:
20+
result.extend(select(outer_item, getattr(outer_item, inner_item_list_key)))
21+
return result
22+
23+
524
def linq6():
625
numbers = [5, 4, 1, 3, 9, 8, 6, 7, 2, 0]
7-
numsPlusOne = map(lambda n: n + 1, numbers)
26+
nums_plus_one = map(lambda n: n + 1, numbers)
827

928
print("Numbers + 1:")
10-
print(list(numsPlusOne))
29+
print(list(nums_plus_one))
1130

1231

1332
def linq7():
1433
products = shared.getProductList()
1534

16-
productNames = map(lambda p: p.ProductName, products)
35+
product_names = map(lambda p: p.ProductName, products)
1736

1837
print("Product Names:")
19-
shared.printS(productNames)
38+
shared.printS(product_names)
2039

2140

2241
def linq8():
2342
numbers = [5, 4, 1, 3, 9, 8, 6, 7, 2, 0]
2443
strings = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
2544

26-
textNums = map(lambda n: strings[n], numbers)
45+
text_nums = map(lambda n: strings[n], numbers)
2746

2847
print("Number strings:")
29-
shared.printS(textNums)
48+
shared.printS(text_nums)
3049

3150

3251
def linq9():
3352
words = ["aPPLE", "BlUeBeRrY", "cHeRry"]
3453

35-
upperLowerWords = map(lambda w: SimpleNamespace(Upper=w.upper(), Lower=w.lower()), words)
36-
for word in upperLowerWords:
54+
upper_lower_words = map(lambda w: SimpleNamespace(Upper=w.upper(), Lower=w.lower()), words)
55+
for word in upper_lower_words:
3756
print("Uppercase: %s, Lowercase: %s" % (word.Upper, word.Lower))
3857

3958

4059
def linq10():
4160
numbers = [5, 4, 1, 3, 9, 8, 6, 7, 2, 0];
4261
strings = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
4362

44-
digitOddEvens = map(lambda n: SimpleNamespace(Digit=strings[n], Even=(n % 2 == 0)), numbers)
63+
digit_odd_evens = map(lambda n: SimpleNamespace(Digit=strings[n], Even=(n % 2 == 0)), numbers)
4564

46-
for d in digitOddEvens:
65+
for d in digit_odd_evens:
4766
print("The digit %s is %s" % (d.Digit, 'even' if d.Even else 'odd'))
4867

4968

5069
def linq11():
5170
products = shared.getProductList()
5271

53-
productInfos = map(lambda p: SimpleNamespace(ProductName=p.ProductName, Category=p.Category, Price=p.UnitPrice),
72+
product_info = map(lambda p: SimpleNamespace(ProductName=p.ProductName, Category=p.Category, Price=p.UnitPrice),
5473
products)
5574

5675
print("Product Info:")
57-
for p in productInfos:
58-
print("%s is in the category %s and costs %.2f per unit." % (p.ProductName, p.Category, p.Price))
76+
for product in product_info:
77+
print("%s is in the category %s and costs %.2f per unit." % (product.ProductName, product.Category, product.Price))
5978

6079

6180
def linq12():
6281
numbers = [5, 4, 1, 3, 9, 8, 6, 7, 2, 0]
6382

6483
index = 0
6584

66-
def CheckInPlace(digit):
85+
def digit_equals_index(digit):
6786
nonlocal index
6887
result = digit == index
6988
index += 1
7089
return result
7190

72-
numsInPlace = map(lambda num: SimpleNamespace(Num=num, InPlace=CheckInPlace(num)), numbers)
91+
nums_in_place = map(lambda num: SimpleNamespace(Num=num, InPlace=digit_equals_index(num)), numbers)
7392

7493
print("Number: In-place?");
75-
for n in numsInPlace:
94+
for n in nums_in_place:
7695
print("%d: %s" % (n.Num, n.InPlace))
7796

7897

@@ -86,11 +105,34 @@ def linq13():
86105
shared.printS(result)
87106

88107

108+
def linq14():
109+
numbers_a = [0, 2, 4, 5, 6, 8, 9]
110+
numbers_b = [1, 3, 5, 7, 8]
111+
112+
pairs = filter(lambda pair: pair.item_a < pair.item_b, left_outer_join(numbers_a, numbers_b))
113+
114+
print("Pairs where a < b:")
115+
for p in pairs:
116+
print("%d is less than %d}" % (p.item_a, p.item_b))
117+
118+
119+
def linq15():
120+
customers = shared.getCustomerList()
121+
122+
orders = map(lambda x: SimpleNamespace(customer_id=x.item_a.CustomerID, order_id=x.item_b.OrderID, total=x.item_b.Total),
123+
filter(lambda x: x.item_b.Total < 500.00,
124+
select_many(customers, "Orders")))
125+
126+
shared.print_namespace(orders)
127+
128+
89129
# linq6()
90130
# linq7()
91131
# linq8()
92132
# linq9()
93133
# linq10()
94134
# linq11()
95135
# linq12()
96-
linq13()
136+
# linq13()
137+
#linq14()
138+
# linq15()

src/python/shared.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
1+
import datetime
12
import json
23

34
def printS(sequence):
45
print ("\n".join(list(sequence)))
56

7+
def printN(sequence):
8+
for item in sequence:
9+
s = repr(item)
10+
print(s)
11+
12+
def print_namespace(sequence):
13+
for item in sequence:
14+
s = repr(item)
15+
print(s.lstrip("namespace"))
16+
617
class Product(object):
718
def __init__(self, ProductID=None, ProductName=None, Category=None, UnitPrice=None, UnitsInStock=None):
819
self.ProductID = ProductID
@@ -12,7 +23,7 @@ def __init__(self, ProductID=None, ProductName=None, Category=None, UnitPrice=No
1223
self.UnitsInStock = UnitsInStock
1324

1425
class Order(object):
15-
def __init__(self, OrderId=None, OrderDate=None, Total=None):
26+
def __init__(self, OrderId=None, OrderDate=datetime.datetime(1970, 1, 1), Total=0):
1627
self.OrderID = OrderId
1728
self.OrderDate = OrderDate
1829
self.Total = Total
@@ -130,7 +141,9 @@ def getCustomerList():
130141

131142
if "orders" in customer:
132143
for order in customer["orders"]["order"]:
133-
ord = Order(order["id"], order["orderdate"], order["total"])
144+
ord = Order(int(order["id"]))
145+
ord.OrderDate = datetime.datetime.strptime( order["orderdate"], "%Y-%m-%dT%H:%M:%S" )
146+
ord.Total = float(order["total"])
134147
cust.Orders.append(ord)
135148
result.append(cust)
136149
return result

0 commit comments

Comments
 (0)