human
Give me a the Python program you requested given the following:
I am working on the file "10-notebook-solution.ipynb".
The first task is:
Sie modelliert sehr einfache Sätze der Form SBJ saw OBJ mit optionaler Präpositionalphrase am Ende. Diese Präpositionalphrase kann entweder der näheren Bestimmung des Objekts oder der näheren Bestimmung der in der Verbalphrase ausgedrückten Handlung dienen.
Im folgenden sollen aus der Penn Treebank Wahrscheinlichkeiten für die einzelnen Regeln extrahiert werden, um dieser Ambiguität Herr zu werden.
(a) Relevante Konstruktionen erkennen
Nutzen das im NLTK enthaltene Sample der Penn Treebank (nach Installation unter nltk.corpus.treebank zu finden) zunächst zur Identifikation der für eine Disambiguierung nützlichen (Teil-)bäume der Penn Treebank.
Gegebenfalls müssen Sie die obige Grammatik den Strukturen, die Sie finden, anpassen.
Hinweis: Sie können sich bei der Analyse auf die jeweils 30 häufigsten Konstruktionen der Baumbank beschränken.
Can you write Python program for it?
assistant
#Here is the Python program you requested.

from collections import defaultdict
from nltk.corpus import treebank

def find_relevant_constructions(lhs, only_with=None):
    lhs_nt = nltk.grammar.Nonterminal(lhs)
    should_filter = only_with is not None
    if should_filter:
        filter_by = list(map(nltk.grammar.Nonterminal, only_with))
        def passes_filter(tup):
            for f in filter_by:
                if f not in tup:
                    return False
            return True

    # iterate over all trees and all their productions
    # and count those which pass the filter
    counter = defaultdict(int)
    for tree in treebank.parsed_sents():
        for prod in tree.productions():
            if prod.lhs() == lhs_nt:
                # either we do not have to filter or the rhs has to pass the filter
                if not should_filter or passes_filter(prod.rhs()):
                    counter[prod.rhs()] += 1

    # sort right sides of productions according to frequency
    return [ (k, counter[k]) for k in sorted(counter.keys(), key=counter.__getitem__) ]

constructions = find_relevant_constructions('VP', only_with=["NP"])
constructions[-30:]