Skip to main content

Standard sequence helper methods with full typing support

Project description

types-linq

Python pypi pytest codecov

This is an attempt to implement linq methods seen in .NET (link). Currently WIP.

Goal:

  • Incorporates Enumerable method specs as precise as possible
  • Handles infinite streams (generators) smoothly like in SICP
    • Deferred evaluations
  • Detailed typing support
  • Honours collections.abc interfaces

Install

To install this library on your computer, do:

$ git clone https://github.com/cleoold/types-linq && cd types-linq
$ pip install .
# or
$ python setup.py install

Or install from pypi:

$ pip install types-linq -U

Dev

Execute the following commands (or something similar) to run the test cases:

# optionally set up venv
$ python -m venv
$ ./scripts/activate

$ pip install pytest
$ python -m pytest

Examples

The usage is simple if you know about the interfaces in .NET as this library provides almost the exact methods.

Grouping & Transforming lists

from typing import NamedTuple
from types_linq import Enumerable as En


class AnswerSheet(NamedTuple):
    subject: str
    score: int
    name: str

students = ['Jacque', 'Franklin', 'Romeo']
papers = [
    AnswerSheet(subject='Calculus', score=78, name='Jacque'),
    AnswerSheet(subject='Calculus', score=98, name='Romeo'),
    AnswerSheet(subject='Algorithms', score=59, name='Romeo'),
    AnswerSheet(subject='Mechanics', score=93, name='Jacque'),
    AnswerSheet(subject='E & M', score=87, name='Jacque'),
]

query = En(students) \
    .order_by(lambda student: student) \
    .group_join(papers,
        lambda student: student,
        lambda paper: paper.name,
        lambda student, papers: {
            'student': student,
            'papers': papers.order_by(lambda paper: paper.subject) \
                .select(lambda paper: {
                    'subject': paper.subject,
                    'score': paper.score,
                }).to_list(),
            'gpa': papers.average2(lambda paper: paper.score, None),
        }
    )

for obj in query:
    print(obj)

# output:
# {'student': 'Franklin', 'papers': [], 'gpa': None}
# {'student': 'Jacque', 'papers': [{'subject': 'E & M', 'score': 87}, {'subject': 'Mechanics', 'score': 93}, {'subject': 'Calculus', 'score': 78}], 'gpa': 86.0}
# {'student': 'Romeo', 'papers': [{'subject': 'Algorithms', 'score': 59}, {'subject': 'Calculus', 'score': 98}], 'gpa': 78.5}

Working with generators

import random
from types_linq import Enumerable as En

def toss_coins():
    while True:
        yield random.choice(('Head', 'Tail'))

times_head = En(toss_coins()).take(5) \  # [:5] also works
    .count(lambda r: r == 'Head')

print(f'You tossed 5 times with {times_head} HEADs!')

# possible output:
# You tossed 5 times with 2 HEADs!

Also querying stream output

Mixing with builtin iterable type objects.

import sys, subprocess
from types_linq import Enumerable as En

proc = subprocess.Popen('kubectl logs -f my-pod', shell=True, stdout=subprocess.PIPE)
stdout = iter(proc.stdout.readline, b'')

query = En(stdout).where(lambda line: line.startswith(b'CRITICAL: ')) \
    .select(lambda line: line[10:].decode())

for line in query:
    sys.stdout.write(line)
    sys.stdout.flush()

# whatever.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

types-linq-0.1.0.tar.gz (15.0 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page