"""Explicit word/code-point n-grams, no library tokenizer or normalization."""
import json
def grams(units,n):
    if type(n) is not int or n<1:raise ValueError('positive integer n')
    return [tuple(units[i:i+n]) for i in range(max(0,len(units)-n+1))]
if __name__=='__main__':
    text='این کتاب خوب است';word2=grams(text.split(),2);char2=grams(list('این کتاب'),2)
    assert word2==[('این','کتاب'),('کتاب','خوب'),('خوب','است')]
    assert len(char2)==7 and ('ن',' ') in char2 and (' ','ک') in char2
    assert grams(['الف'],2)==[] and grams([],1)==[]
    a=grams('کتاب خوب نیست'.split(),2);b=grams('کتاب خوب است'.split(),2)
    assert ('خوب','نیست') in a and ('خوب','است') in b
    assert len(list('می‌کنم'))==6 and '\u200c' in 'می‌کنم'
    for n in [0,-1,True,1.5]:
        try:grams(['الف'],n)
        except ValueError:continue
        raise AssertionError('invalid n accepted')
    print(json.dumps({'word_bigrams':word2,'character_bigrams_including_spaces':char2,'negative_word_bigrams':a,'positive_word_bigrams':b,'unit':'Unicode code point for character mode, whitespace-split item for word mode'},ensure_ascii=False,indent=2))
