Feats from http://www.aclweb.org/anthology/P10-1040
322582
public List<String> extractFeatSingle(int i, final String[] tokens, final String[] pos) {
        List<String> currentFeats = new ArrayList<>();

        for (int index = Math.max(0, i - 2); index < Math.min(i + 3, tokens.length); index++) { // [-2,2]
            IFeatureExtractor.addFeat(currentFeats, "w" + (index - i), tokens[index]);
            IFeatureExtractor.addFeat(currentFeats, "pos" + (index - i), pos[index]);

            if (index == i - 1) {
                IFeatureExtractor.addFeat(currentFeats, "w-10", tokens[i - 1], tokens[i]);
                IFeatureExtractor.addFeat(currentFeats, "pos-10", pos[i - 1], pos[i]);
            } else if (index == i + 1) {
                IFeatureExtractor.addFeat(currentFeats, "w0+1", tokens[i], tokens[i + 1]);
                IFeatureExtractor.addFeat(currentFeats, "pos0+1", pos[i], pos[i + 1]);
            } else if (index == i - 2) {
                IFeatureExtractor.addFeat(currentFeats, "pos-2-1", pos[i - 2], pos[i - 1]);
                IFeatureExtractor.addFeat(currentFeats, "pos-2-10", pos[i - 2], pos[i - 1], pos[i]);
            } else if (index == i + 2) {
                IFeatureExtractor.addFeat(currentFeats, "pos+1+2", pos[i + 1], pos[i + 2]);
            }

            if (index == i - 1 && i < tokens.length - 1) {
                IFeatureExtractor.addFeat(currentFeats, "pos-10+1", pos[i - 1], pos[i], pos[i + 1]);
            }

            if (index == i + 2) {
                IFeatureExtractor.addFeat(currentFeats, "pos0+1+2", pos[i], pos[i + 1], pos[i + 2]);
            }
        }

        currentFeats.addAll(BrownFeatExtractor.extractBrownFeat(i, -2, 2, tokens));
        return currentFeats;
    }
16875
def _elements(self, IDs, func, aspList):
        
        res = []
        for asp in aspList:
            if (asp in [0, 180]):
                # Generate func for conjunctions and oppositions
                if func == self.N:
                    res.extend([func(ID, asp) for ID in IDs])
                else:
                    res.extend([func(ID) for ID in IDs])
            else:
                # Generate Dexter and Sinister for others
                res.extend([self.D(ID, asp) for ID in IDs])
                res.extend([self.S(ID, asp) for ID in IDs])
        return res
818042
def from_dir(dirpath: Path, feat_type: str) -> None:
    

    logger.info("Extracting features from directory {}".format(dirpath))

    dirname = str(dirpath)

    def all_wavs_processed() -> bool:
        """
        True if all wavs in the directory have corresponding numpy feature
        file; False otherwise.
        """

        for fn in os.listdir(dirname):
            prefix, ext = os.path.splitext(fn)
            if ext == ".wav":
                if not os.path.exists(
                        os.path.join(dirname, "%s.%s.npy" % (prefix, feat_type))):
                    return False
        return True

    if all_wavs_processed():
        # Then nothing needs to be done here
        logger.info("All WAV files already preprocessed")
        return
    # Otherwise, go on and process everything...

    # If pitch features are needed as part of this, extract them
    if feat_type == "pitch" or feat_type == "fbank_and_pitch":
        kaldi_pitch(dirname, dirname)

    # Then apply file-wise feature extraction
    for filename in os.listdir(dirname):
        logger.info("Preparing %s features for %s", feat_type, filename)
        path = os.path.join(dirname, filename)
        if path.endswith(".wav"):
            if empty_wav(path):
                raise PersephoneException("Can't extract features for {} since it is an empty WAV file. Remove it from the corpus.".format(path))
            if feat_type == "fbank":
                fbank(path)
            elif feat_type == "fbank_and_pitch":
                fbank(path)
                prefix = os.path.splitext(filename)[0]
                combine_fbank_and_pitch(dirname, prefix)
            elif feat_type == "pitch":
                # Already extracted pitch at the start of this function.
                pass
            elif feat_type == "mfcc13_d":
                mfcc(path)
            else:
                logger.warning("Feature type not found: %s", feat_type)
                raise PersephoneException("Feature type not found: %s" % feat_type)
1289392
def assemble_phi5_works_filepaths():
    """"""
    plaintext_dir_rel = '~/cltk_data/latin/text/phi5/individual_works/'
    plaintext_dir = os.path.expanduser(plaintext_dir_rel)
    all_filepaths = []
    for author_code in PHI5_WORKS_INDEX:
        author_data = PHI5_WORKS_INDEX[author_code]
        works = author_data['works']
        for work in works:
            f = os.path.join(plaintext_dir, author_code + '.TXT' + '-' + work + '.txt')
            all_filepaths.append(f)
    return all_filepaths
1174715
def knearest(self, f_or_start, end=None, chrom=None, k=1):
        


        if end is not None:
            f = Feature(f_or_start, end, chrom=chrom)
        else:
            f = f_or_start

        DIST = 2000
        feats = filter_feats(self.find(f.start - DIST, f.end + DIST, chrom=f.chrom), f, k)
        if len(feats) >= k:
            return feats

        nfeats = k - len(feats)
        fleft = Feature(f.start - DIST, f.start, chrom=f.chrom)
        feats.extend(self.left(fleft, n=nfeats))

        fright = Feature(f.end, f.end + DIST, chrom=f.chrom)
        feats.extend(self.right(fright, n=nfeats))
        return filter_feats(feats, f, k)
1108881
def complete_set_acls(self, cmd_param_text, full_cmd, *rest):
        
        possible_acl = [
            "digest:",
            "username_password:",
            "world:anyone:c",
            "world:anyone:cd",
            "world:anyone:cdr",
            "world:anyone:cdrw",
            "world:anyone:cdrwa",
        ]
        complete_acl = partial(complete_values, possible_acl)
        completers = [self._complete_path, complete_acl, complete_labeled_boolean("recursive")]
        return complete(completers, cmd_param_text, full_cmd, *rest)
428958
def convert_examples_to_features(examples, tokenizer, max_seq_length,
                                 doc_stride, max_query_length, is_training):
    """"""

    unique_id = 1000000000

    features = []
    for (example_index, example) in enumerate(examples):
        query_tokens = tokenizer.tokenize(example.question_text)

        if len(query_tokens) > max_query_length:
            query_tokens = query_tokens[0:max_query_length]

        tok_to_orig_index = []
        orig_to_tok_index = []
        all_doc_tokens = []
        for (i, token) in enumerate(example.doc_tokens):
            orig_to_tok_index.append(len(all_doc_tokens))
            sub_tokens = tokenizer.tokenize(token)
            for sub_token in sub_tokens:
                tok_to_orig_index.append(i)
                all_doc_tokens.append(sub_token)

        tok_start_position = None
        tok_end_position = None
        if is_training and example.is_impossible:
            tok_start_position = -1
            tok_end_position = -1
        if is_training and not example.is_impossible:
            tok_start_position = orig_to_tok_index[example.start_position]
            if example.end_position < len(example.doc_tokens) - 1:
                tok_end_position = orig_to_tok_index[example.end_position + 1] - 1
            else:
                tok_end_position = len(all_doc_tokens) - 1
            (tok_start_position, tok_end_position) = _improve_answer_span(
                all_doc_tokens, tok_start_position, tok_end_position, tokenizer,
                example.orig_answer_text)

        # The -3 accounts for [CLS], [SEP] and [SEP]
        max_tokens_for_doc = max_seq_length - len(query_tokens) - 3

        # We can have documents that are longer than the maximum sequence length.
        # To deal with this we do a sliding window approach, where we take chunks
        # of the up to our max length with a stride of `doc_stride`.
        _DocSpan = collections.namedtuple(  # pylint: disable=invalid-name
            "DocSpan", ["start", "length"])
        doc_spans = []
        start_offset = 0
        while start_offset < len(all_doc_tokens):
            length = len(all_doc_tokens) - start_offset
            if length > max_tokens_for_doc:
                length = max_tokens_for_doc
            doc_spans.append(_DocSpan(start=start_offset, length=length))
            if start_offset + length == len(all_doc_tokens):
                break
            start_offset += min(length, doc_stride)

        for (doc_span_index, doc_span) in enumerate(doc_spans):
            tokens = []
            token_to_orig_map = {}
            token_is_max_context = {}
            segment_ids = []
            tokens.append("[CLS]")
            segment_ids.append(0)
            for token in query_tokens:
                tokens.append(token)
                segment_ids.append(0)
            tokens.append("[SEP]")
            segment_ids.append(0)

            for i in range(doc_span.length):
                split_token_index = doc_span.start + i
                token_to_orig_map[len(tokens)] = tok_to_orig_index[split_token_index]

                is_max_context = _check_is_max_context(doc_spans, doc_span_index,
                                                       split_token_index)
                token_is_max_context[len(tokens)] = is_max_context
                tokens.append(all_doc_tokens[split_token_index])
                segment_ids.append(1)
            tokens.append("[SEP]")
            segment_ids.append(1)

            input_ids = tokenizer.convert_tokens_to_ids(tokens)

            # The mask has 1 for real tokens and 0 for padding tokens. Only real
            # tokens are attended to.
            input_mask = [1] * len(input_ids)

            # Zero-pad up to the sequence length.
            while len(input_ids) < max_seq_length:
                input_ids.append(0)
                input_mask.append(0)
                segment_ids.append(0)

            assert len(input_ids) == max_seq_length
            assert len(input_mask) == max_seq_length
            assert len(segment_ids) == max_seq_length

            start_position = None
            end_position = None
            if is_training and not example.is_impossible:
                # For training, if our document chunk does not contain an annotation
                # we throw it out, since there is nothing to predict.
                doc_start = doc_span.start
                doc_end = doc_span.start + doc_span.length - 1
                out_of_span = False
                if not (tok_start_position >= doc_start and
                        tok_end_position <= doc_end):
                    out_of_span = True
                if out_of_span:
                    start_position = 0
                    end_position = 0
                else:
                    doc_offset = len(query_tokens) + 2
                    start_position = tok_start_position - doc_start + doc_offset
                    end_position = tok_end_position - doc_start + doc_offset
            if is_training and example.is_impossible:
                start_position = 0
                end_position = 0
            if example_index < 20:
                logger.info("*** Example ***")
                logger.info("unique_id: %s" % (unique_id))
                logger.info("example_index: %s" % (example_index))
                logger.info("doc_span_index: %s" % (doc_span_index))
                logger.info("tokens: %s" % " ".join(tokens))
                logger.info("token_to_orig_map: %s" % " ".join([
                    "%d:%d" % (x, y) for (x, y) in token_to_orig_map.items()]))
                logger.info("token_is_max_context: %s" % " ".join([
                    "%d:%s" % (x, y) for (x, y) in token_is_max_context.items()
                ]))
                logger.info("input_ids: %s" % " ".join([str(x) for x in input_ids]))
                logger.info(
                    "input_mask: %s" % " ".join([str(x) for x in input_mask]))
                logger.info(
                    "segment_ids: %s" % " ".join([str(x) for x in segment_ids]))
                if is_training and example.is_impossible:
                    logger.info("impossible example")
                if is_training and not example.is_impossible:
                    answer_text = " ".join(tokens[start_position:(end_position + 1)])
                    logger.info("start_position: %d" % (start_position))
                    logger.info("end_position: %d" % (end_position))
                    logger.info(
                        "answer: %s" % (answer_text))

            features.append(
                InputFeatures(
                    unique_id=unique_id,
                    example_index=example_index,
                    doc_span_index=doc_span_index,
                    tokens=tokens,
                    token_to_orig_map=token_to_orig_map,
                    token_is_max_context=token_is_max_context,
                    input_ids=input_ids,
                    input_mask=input_mask,
                    segment_ids=segment_ids,
                    start_position=start_position,
                    end_position=end_position,
                    is_impossible=example.is_impossible))
            unique_id += 1

    return features
532593
private static IAccessRule[] getAccessRules(IPath[] accessibleFiles, IPath[] nonAccessibleFiles) {
        final int accessibleFilesLength = accessibleFiles == null ? 0 : accessibleFiles.length;
        final int nonAccessibleFilesLength = nonAccessibleFiles == null ? 0 : nonAccessibleFiles.length;
        final int length = accessibleFilesLength + nonAccessibleFilesLength;
        if (length == 0) {
            return null;
        }
        final IAccessRule[] accessRules = new IAccessRule[length];
        if (accessibleFiles != null) {
	        for (int i = 0; i < accessibleFilesLength; i++) {
	            accessRules[i] = JavaCore.newAccessRule(accessibleFiles[i], IAccessRule.K_ACCESSIBLE);
	        }
        }
        if (nonAccessibleFiles != null) {
	        for (int i = 0; i < nonAccessibleFilesLength; i++) {
	            accessRules[accessibleFilesLength + i] = JavaCore.newAccessRule(nonAccessibleFiles[i], IAccessRule.K_NON_ACCESSIBLE);
	        }
        }
        return accessRules;
    }
1111925
public static void reduceDimension(final List<Tuple> trainingData) {
        // FeatName - <feat possible vals, count of instances that has this val>
        // Do NOT store index for featname, index might not be same among tuples for the same featname.
        Map<String, Map<Double, Integer>> featNameValues = new HashMap<>();
        for (Tuple t : trainingData) {
            double[] featValues = t.vector.getVector();
            String[] name;
            if (t.vector instanceof FeatNamedVector) {
                name = ((FeatNamedVector) t.vector).featsName;
            } else {
                name = IntStream.range(0, t.vector.getVector().length).mapToObj(String::valueOf).toArray(String[]::new);
            }

            for (int i = 0; i < featValues.length; i++) {
                if (!featNameValues.containsKey(name[i])) {
                    featNameValues.put(name[i], new HashMap<>());
                }

                Map<Double, Integer> valMap = featNameValues.get(name[i]);
                int newCount = 0;
                if (valMap.containsKey(featValues[i])) {
                    newCount = valMap.get(featValues[i]);
                }

                newCount++;
                valMap.put(featValues[i], newCount);
            }
        }

        Set<String> singleValFeats = getSingleValFeat(featNameValues, trainingData.size());
        LOG.debug("Single value feats: ");
        LOG.debug(singleValFeats.toString().replaceAll(", ", System.lineSeparator()));

        for (Tuple t : trainingData) {
            List<Double> featVal = new ArrayList<>();
            double[] originalVectorVal = t.vector.getVector();

            Set<Integer> indicesToBeRemoved;
            if (t.vector instanceof FeatNamedVector) {
                indicesToBeRemoved = new HashSet<>();
                String[] featName = ((FeatNamedVector) t.vector).featsName;

                for (int i = 0; i < featName.length; i++) {
                    if (singleValFeats.contains(featName[i])) {
                        indicesToBeRemoved.add(i);
                    }
                }
            } else {
                indicesToBeRemoved = singleValFeats.stream().map(Integer::parseInt).collect(Collectors.toSet());
            }


            for (int i = 0; i < originalVectorVal.length; i++) {
                if (!indicesToBeRemoved.contains(i)) {
                    featVal.add(originalVectorVal[i]);
                }
            }

            t.vector.setVector(featVal.stream().mapToDouble(x -> x).toArray());

            // Set feat name if needed
            if (t.vector instanceof FeatNamedVector) {
                List<String> featName = new ArrayList<>();
                String[] originalFeatName = ((FeatNamedVector) t.vector).featsName;

                for (int i = 0; i < originalVectorVal.length; i++) {
                    if (!indicesToBeRemoved.contains(i)) {
                        featName.add(originalFeatName[i]);
                    }
                }

                ((FeatNamedVector) t.vector).featsName = featName.stream().toArray(String[]::new);
            }


        }

    }
283233
@Override
    public Fighter parseDocument(Document doc) throws IOException {
        Fighter fighter = new Fighter();
        fighter.setSherdogUrl(ParserUtils.getSherdogPageUrl(doc));

        logger.info("Refreshing fighter {}", fighter.getSherdogUrl());


        try {
            Elements name = doc.select(".bio_fighter h1 span.fn");
            fighter.setName(name.get(0).html());
        } catch (Exception e) {
            // no info, skipping
        }

        // Getting nick name
        try {
            Elements nickname = doc.select(".bio_fighter span.nickname em");
            fighter.setNickname(nickname.get(0).html());
        } catch (Exception e) {
            // no info, skipping
        }

        // Birthday
        try {
            Elements birthday = doc.select("span[itemprop=\"birthDate\"]");
            fighter.setBirthday(df.parse(birthday.get(0).html()));
        } catch (Exception e) {
            // no info, skipping
        }
        // height
        try {
            Elements height = doc.select(".size_info .height strong");
            fighter.setHeight(height.get(0).html());
        } catch (Exception e) {
            // no info, skipping
        }
        // weight
        try {
            Elements weight = doc.select(".size_info .weight strong");
            fighter.setWeight(weight.get(0).html());
        } catch (Exception e) {
            // no info, skipping
        }
        // wins
        try {
            Elements wins = doc.select(".bio_graph .counter");
            fighter.setWins(Integer.parseInt(wins.get(0).html()));
        } catch (Exception e) {
            // no info, skipping
        }
        Elements winsMethods = doc.select(".bio_graph:first-of-type .graph_tag");
        try {
            fighter.setWinsKo(Integer.parseInt(winsMethods.get(METHOD_KO).html().split(" ")[0]));
        } catch (Exception e) {
            // no info, skipping
        }

        try {
            fighter.setWinsSub(Integer.parseInt(winsMethods.get(METHOD_SUBMISSION).html().split(" ")[0]));
        } catch (Exception e) {
            // no info, skipping
        }

        try {
            fighter.setWinsDec(Integer.parseInt(winsMethods.get(METHOD_DECISION).html().split(" ")[0]));
        } catch (Exception e) {
            // no info, skipping
        }


        try {
            fighter.setWinsOther(Integer.parseInt(winsMethods.get(METHOD_OTHERS).html().split(" ")[0]));
        } catch (Exception e) {
            // no info, skipping
        }
        // loses
        try {
            Elements losses = doc.select(".bio_graph.loser .counter");
            fighter.setLosses(Integer.parseInt(losses.get(0).html()));
        } catch (Exception e) {
            // no info, skipping
        }

        Elements lossesMethods = doc.select(".bio_graph.loser .graph_tag");


        try {

            fighter.setLossesKo((Integer.parseInt(lossesMethods.get(METHOD_KO).html().split(" ")[0])));
        } catch (Exception e) {
            // no info, skipping
        }

        try {
            fighter.setLossesSub(Integer.parseInt(lossesMethods.get(METHOD_SUBMISSION).html().split(" ")[0]));
        } catch (Exception e) {
            // no info, skipping
        }

        try {
            fighter.setLossesDec(Integer.parseInt(lossesMethods.get(METHOD_DECISION).html().split(" ")[0]));
        } catch (Exception e) {
            // no info, skipping
        }

        try {
            fighter.setLossesOther(Integer.parseInt(lossesMethods.get(METHOD_OTHERS).html().split(" ")[0]));
        } catch (Exception e) {
            // no info, skipping
        }
        // draws and NC
        Elements drawsNc = doc.select(".right_side .bio_graph .card");
        for (Element element : drawsNc) {

            switch (element.select("span.result").html()) {
                case "Draws":
                    fighter.setDraws(Integer.parseInt(element.select("span.counter").html()));
                    break;

                case "N/C":
                    fighter.setNc(Integer.parseInt(element.select("span.counter").html()));
                    break;
            }

        }

        Elements picture = doc.select(".bio_fighter .content img[itemprop=\"image\"]");
        String pictureUrl = "https://www.sherdog.com" + picture.attr("src").trim();


        Elements fightTables = doc.select(".fight_history");
        logger.info("Found {} fight history tables", fightTables.size());


        fightTables.stream()
                //excluding upcoming fights
                .filter(div -> !div.select(".module_header h2").html().trim().contains("Upcoming"))
                .collect(Collectors.groupingBy(div -> {
                    String categoryName = div.select(".module_header h2").html().trim().replaceAll("(?i)FIGHT HISTORY - ", "").trim();

                    return FightType.fromString(categoryName);
                }))
                .forEach((key, div) -> div.stream()
                        .map(d -> d.select(".table table tr"))
                        .filter(tdList -> tdList.size() > 0)
                        .findFirst()
                        .ifPresent(tdList -> {
                                    List<Fight> f = getFights(tdList, fighter);

                                    f.forEach(fight -> fight.setType(key));

                                    fighter.getFights().addAll(f);
                                }
                        ));

        List<Fight> sorted = fighter.getFights()
                .stream()
                .sorted(Comparator.comparing(Fight::getDate, Comparator.nullsFirst(Comparator.naturalOrder())))
                .collect(Collectors.toList());

        fighter.setFights(sorted);


        logger.info("Found {} fights for {}", fighter.getFights().size(), fighter.getName());

        //setting the picture last to make sure the fighter variable has all the data
        if (pictureUrl.length() > 0) {
            fighter.setPicture(PROCESSOR.process(pictureUrl, fighter));
        }

        return fighter;
    }
284421
def get_ddlib_feats(span, context, idxs):
    

    if span.stable_id not in unary_ddlib_feats:
        unary_ddlib_feats[span.stable_id] = set()

        for seq_feat in _get_seq_features(context, idxs):
            unary_ddlib_feats[span.stable_id].add(seq_feat)

        for window_feat in _get_window_features(context, idxs):
            unary_ddlib_feats[span.stable_id].add(window_feat)

    for f in unary_ddlib_feats[span.stable_id]:
        yield f
1057472
function get_tops($limit = 10, $xattr = '') {
        $ret = array();
        if (!$this->_txt) return false;
        $xmode = false;
        $attrs = array();
        if ($xattr != '') {
            if (substr($xattr, 0, 1) == '~') {
                $xattr = substr($xattr, 1);
                $xmode = true;
            }
            foreach (explode(',', $xattr) as $tmp) {
                $tmp = strtolower(trim($tmp));
                if (!empty($tmp)) $attrs[$tmp] = true;
            }
        }

        // save the old offset
        $off = $this->_off;
        $this->_off = $cnt = 0;
        $list = array();
        while ($tmpa = $this->get_result()) {
            foreach ($tmpa as $tmp) {
                $tmp['attr'] = trim($tmp['attr']);
                if ($tmp['idf'] < 0.2 || substr($tmp['attr'], 0, 1) == '#') continue;
                // check attr filter
                if (count($attrs) > 0) {
                    if ($xmode == true && isset($attrs[$tmp['attr']])) continue;
                    if ($xmode == false && !isset($attrs[$tmp['attr']])) continue;
                }
                // check stopwords
                $word = strtolower($tmp['word']);
                if ($this->_rule_checkbit($word, PSCWS4_RULE_NOSTATS)) continue;
                // put to list
                if (isset($list[$word])) {
                    $list[$word]['weight'] += $tmp['idf'];
                    $list[$word]['times']++;
                } else {
                    $list[$word] = array('word' => $tmp['word'], 'times' => 1, 'weight' => $tmp['idf'], 'attr' => $tmp['attr']);
                }
            }
        }
        // restore the offset
        $this->_off = $off;
        // sort it & return
        if ( (float)substr(PHP_VERSION, 0, 3) >= 5.3 ) {
            $cmp_func = function($a, $b) {return ($b['weight'] > $a['weight'] ? 1 : -1);};
        } else {
            $cmp_func = create_function('$a,$b', 'return ($b[\'weight\'] > $a[\'weight\'] ? 1 : -1);');
        }

        usort($list, $cmp_func);
        if (count($list) > $limit) $list = array_slice($list, 0, $limit);
        return $list;
    }
962483
function () {
			var aOutput = [];

			_aRuns.forEach(function (oRun) {
				var oTmp = _generateRootLevelKeys(oRun);

				for (var sLibraryName in oRun.rules) {
					_generateLibraryStructure(oTmp, sLibraryName, oRun);

					for (var sRuleName in oRun.rules[sLibraryName]) {
						_generateRuleStructure(oTmp, sLibraryName, sRuleName, oRun);
					}
				}

				aOutput.push(oTmp);
			});

			return aOutput;
		}
906202
def _parse_acl_config(self, acl_config):
        
        parsed_acls = dict()
        for acl in acl_config['aclList']:
            parsed_acls[acl['name']] = set()
            for rule in acl['sequence']:
                parsed_acls[acl['name']].add(rule['text'])
        return parsed_acls
982222
def get_feats(self, doc):
		'''
		
		'''
		ngram_counter = Counter()
		for sent in doc.sents:
			ngrams = self.phrases[str(sent)]
			for subphrases in self.phrases[1:]:
				ngrams = subphrases[str(sent)]
			for ngram in ngrams:
				ngram_counter[ngram] += 1
		return ngram_counter
1005789
def as_conll(self):
        """"""
        def get(field):
            value = getattr(self, field)
            if value is None:
                value = '_'
            elif field == 'feats':
                value = '|'.join(value)
            return str(value)
        return '\t'.join([get(field) for field in FIELD_NAMES])
1102406
def local_constraints(self):
        
        cs = []
        for feat, val in self._avm.items():
            try:
                if val.supertypes and not val._avm:
                    cs.append((feat, val))
                else:
                    for subfeat, subval in val.features():
                        cs.append(('{}.{}'.format(feat, subfeat), subval))
            except AttributeError:
                cs.append((feat, val))
        return cs