quadrismegistus / prosodic

Prosodic: a metrical-phonological parser, written in Python. For English and Finnish, with flexible language support.
http://quadrismegistus.github.io/prosodic/
GNU General Public License v3.0
277 stars 43 forks source link

isIambic is incorrect #39

Closed zouharvi closed 4 months ago

zouharvi commented 2 years ago

The isIambic function is just looking at the first two stresses which may not be consistent across the whole line. Furthermore, it seems inconsistent to have the iambic meter but not trochaic, anapaestic and dactylic. I could rewrite them in a more general way because I'll have some wrapper for it in my application anyway. However, I am not sure if these kinds of PR are welcomed in this repo and whether someone has time to merge them.

def isIambic(self):
    if len(self.positions) < 2:
        return None
    else:
        return self.positions[0].meterVal == 'w' and self.positions[1].meterVal == 's'
quadrismegistus commented 4 months ago

Hello, thanks for your comment. Have you worked on this issue? I welcome PRs, and/or I can try to patch the issue.

The latest prosodic has this logic for determining iambicity:

@property
def is_rising(self):
    if not self.positions:
        return
    try:
        if self.nary_feet == 3:
            if self.slots[3].is_prom:
                return False  # swws
            else:
                return True  # wssw
        elif self.nary_feet == 2:
            if self.slots[3].is_prom:
                return True  # wsws
            else:
                return False  # swsw
    except (IndexError, AttributeError):
        pass
    return not self.positions[0].is_prom

@property
def nary_feet(self):
    return int(np.median(self.foot_sizes))

@property
def feet(self):
    if self.num_positions == 1:
        feet = [self.positions[0].meter_str]
    else:
        feet = []
        for i in range(1, self.num_positions, 2):
            pos1, pos2 = self.positions[i - 1], self.positions[i]
            feet.append(pos1.meter_str + pos2.meter_str)
    return feet

@property
def foot_sizes(self):
    return [len(ft) for ft in self.feet]

@property
def foot_type(self):
    if self.nary_feet == 2:
        return "iambic" if self.is_rising else "trochaic"
    elif self.nary_feet == 3:
        return "anapestic" if self.is_rising else "dactylic"
    logger.error("foot type?")
    return ""

@property
def is_iambic(self):
    return self.foot_type == "iambic"

This is on the Parse object.

In other words it's currently looking at the 4th syllable, not the 1st and 2nd, -- because you're absolutely right, especially given trochaic inversions, the first 2 syllables are less reliable an indicator.

I'm going to close this for now but please feel free to comment or re-open!