[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lojban] Alec's lujvo creator written in python



Hey everyone,

I'm relatively new to the lojban scene, but I decided to write a lujvo creator in python to make adding lujvo easier. I tried my best to understand and codify all of the rules for creating lujvo (although I might have had some trouble understanding the tosmabru test). If people can stress test my script to make sure it is working correctly, I would be very thankful. I have attached the lujvo.py file. You also need to download http://www.lojban.org/files/history/bothraf.txt into the same directory as lujvo.py . Then just run lujvo.py and enter in lujvo components to get a list of (hopefully) correct lujvo with their scores.

Here is a sample run:

Include a list of members of the lujvo separated by spaces. Example:
bangu smuni
bangu smuni
5847    bausmu
5878    bansmu
7917    bansmuni
8008    bangysmu
8986    baursmuni
10047   bangysmuni

If you find any bugs, please post the lujvo components that gave you the error, and why the returned lujvo are wrong, and I'll get right on it, uploading a new version asap.

Thanks everyone!

-Alec

--
You received this message because you are subscribed to the Google Groups "lojban" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lojban+unsubscribe@googlegroups.com.
To post to this group, send email to lojban@googlegroups.com.
Visit this group at http://groups.google.com/group/lojban.
For more options, visit https://groups.google.com/groups/opt_out.
 
 
#This program takes rafsi and turns them into the best lujvo
#Run it with a list as an argument which contains lists of rafsi
#Like this: lujvo([["ger", "ge'u", "gerk", "gerku"],["zda", "zdan", "zdani"]])

#Write it so that you enter a string, which is separated by spaces and commas
#The commas separate different gismu

import itertools
import math

vowels = ['a','e','i','o','u']
initCon = ['bl', 'br', 'cf', 'ck', 'cl', 'cm', 'cn', 'cp', 'cr', 'ct', 'dj', 'dr', 'dz', 'fl', 'fr', 'gl', 'gr', 'jb', 'jd', 'jg', 'jm' ,'jv' ,'kl', 'kr', 'ml', 'mr', 'pl', 'pr' ,'sf' ,'sk', 'sl', 'sm', 'sn', 'sp', 'sr', 'st', 'tc', 'tr', 'ts', 'vl', 'vr', 'xl', 'xr', 'zb', 'zd', 'zg', 'zm', 'zv']

def conBad(x):
    #This uses http://www.lojban.org/publications/reference_grammar/chapter3.html
    #to see if a string of two consonants (a) is not allowed within a lujvo. Return True if not allowed.
    unvoiced = ['p','t','k','f','c','s','x']
    voiced = ['b','d','g','v','j','z']
    forb = ['c','j','s','z']
    forc = ['cx','kx','xc','xk','mz']
    lia = []
    lib = []
    put = False
    if x[0] == x[1]:
        put = True
    if (x[0] in unvoiced and x[1] in voiced) or (x[0] in voiced and x[1] in unvoiced):
        put = True
    if x[0] in forb and x[1] in forb:
        put = True
    if x in forc:
        put = True
    return put

def rafsi():
    #Download http://www.lojban.org/files/history/bothraf.txt
    #and put it in the same folder as lujvo.py
    f = open('bothraf.txt','r+')
    end = {}
    f.readline()
    f.readline()
    f.readline()
    f.readline()
    f.readline()
    f.readline()
    for line in f:
        h = line.split()[0]
        ga = line[29:]
        gb = ga.split()
        gb.append(h)
        end[h] = gb
    return end
    f.close()

def form(a):
    st = ""
    for x in a:
        if x in vowels:
            st += 'V'
        elif x != '\'':
            st += 'C'
    return st

def ln(a):
    g = 0
    for x in a:
        if x != '\'':
            g += 1
    return g

def score(a):
    end = []
    for b in a:
        T = 0
        L = 0
        A = 0
        H = 0
        R = 0
        V = 0
        for c in b:
            L += len(c)
            A += c.count('\'')
            if c == 'y' or c == 'r' or c == 'n':
                H += 1
            if form(c) == 'CVCCV':
                R += 1
            elif form(c) == 'CVCC':
                R += 2
            elif form(c) == 'CCVCV':
                R += 3
            elif form(c) == 'CCVC':
                R += 4
            elif form(c) == 'CVC':
                R += 5
            elif form(c) == 'CVV' and c.count('\'') == 1:
                R += 6
            elif form(c) == 'CCV':
                R += 7
            elif form(c) == 'CVV' and c.count('\'') == 0:
                R += 8
            V += form(c).count('V')
        smu = ""
        for c in b:
            smu += c
        T = (1000 * L) - (500 * A) + (100 * H) - (10 * R) - V
        end.append((T,smu))
    end = sorted(end)
    return end

def lujvo(lia=None):
    if lia == None:
        print "Include a list of members of the lujvo separated by spaces. Example:"
        print "bangu smuni"
        lia = raw_input().lower()
    lib = lia.split()
    li = []
    e = rafsi()
    for x in lib:
        li.append(e[x])
    #li is in format [['asf','asdf'],['asdf,'asdf']]
    #print 'li'
    #print li
    num = len(li)
    new = []
    for x in range(num):
        if x < (num-1):
            g = []
            #print 'lix'
            #print li[x]
            for y in li[x]:
                if ln(y) == 3 or ln(y) == 4:
                    g.append(y)
            new.append(g)
            #print 'g'
            #print g
        else:
            g = []
            for y in li[x]:
                if ln(y) == 5:
                    g.append(y)
                elif ln(y) == 3:
                    if form(y) == 'CVV' or form(y) == 'CCV':
                        g.append(y)
            new.append(g)
    #print "new list"
    #print new
    premade = list(itertools.product(*new))
    parts = []
    for pre in premade:
        p = []
        p.append(pre[0])
        siz = len(pre)
        if siz == 2:
            if form(pre[0]) == "CVV" and form(pre[1]) != "CCV":
                if pre[1][0] == 'r':
                    p.append('n')
                else:
                    p.append('r')
            bef = ln(pre[0])
            imp = pre[0][len(pre[0])-1] + pre[1][0]
            if bef == 4:
                p.append('y')
            elif form(imp) == "CC" and conBad(imp):
                p.append('y')
            p.append(pre[1])
        else:
            n = 0
            if form(pre[0]) == "CVV":
                n += 1
                if pre[1][0] == 'r':
                    p.append('n')
                else:
                    p.append('r')
            while n < len(pre)-1:
                #this goes up until the next to last index, starting at 0
                bef = ln(pre[n])
                imp = pre[n][len(pre[n])-1] + pre[n+1][0]
                if bef == 4:
                    p.append('y')
                elif pre[n][len(pre[n])-1] == pre[n+1][0]:
                    p.append('y')
                elif form(imp) == "CC" and conBad(imp):
                    p.append('y')
                p.append(pre[n+1])
                n += 1
        #tosmabru test on p NOT FINISHED YET!!!!
        if (form(p[len(p)-1]) == "CVCCV" or (p[len(p)-2] == "y" and form(p[len(p)-3]) == "CVC")) and form(p[0]) == "CVC" and form(p[len(p)-2]) == "CVC":
            #print 'true1'
            n = 0
            t = True
            while n < len(p)-1:
                #print '1'
                #This goes from 0 to the next to last index
                if form(p[n]) == "CVC" and form(p[n+1]) == 'CVC':
                    imp = p[n][len(p[n])-1] + p[n+1][0]
                    if imp not in initCon:
                        t = False
                        #print 'false1'
                n += 1
            n = 0
            if t:
                #print'true2'
                d = p
                p = []
                p.append(d[n])
                while n < len(d)-1:
                    #print '2'
                    #This goes from 0 to the next to last index
                    if form(d[n]) == "CVC" and (form(d[n+1]) == 'CVC' or form(d[n+1]) == 'CVCCV'):
                        imp = d[n][len(d[n])-1] + d[n+1][0]
                        #print imp
                        if imp in initCon:
                            #print 'true3'
                            p.append('y')
                    p.append(d[n+1])
                    n += 1
        parts.append(p)
    #print parts
    end = []
    end = score(parts)
    #print 'end'
    for a in end:
        spaces = ""
        for x in range(int(8-math.log((a[0]+1),10))):
            spaces += " "
        print str(a[0]) + spaces + a[1]

lujvo()

#test cases     
'''
lujvo("ger ge'u gerk gerku , zda zdan zdani")
lujvo("lot blo lo\'i , kle lei")
lujvo('loj logj , ban bau bang , gri girzu gir girz')
lujvo('fal fa\'u farl,plin plini')
lujvo("tos,   tos, mabru")
'''