# Why does this code have trubles with a specific input?

I wrote this code and I found out it gives problem with specific inputs

   def counter(w):                       #turns a list of classes into a list of cardinality of the classes
n=len(w)
s=[]
for i in range(n):
a=len(w[i])
s.append(a)
return s

str=[1,3,1,2,1,2,1,3,1]
def stringer(s,j):                     #computes mu(i)
n=len(s)
m=0
d=0
m=m+(s[j])
d=d+s[j]^2
for i in range(j+1):
for k in range(j,n):
if i!=k:
ss=0
for q in range(i,k+1):
ss=ss+s[q]
m=m+2*s[i]*s[k]/ss
d=d+2*s[i]*s[k]
w=m/d
return w

def mumaker(s):                            #makes the mu line
n=len(s)
m=[]
m = numpy.empty(n, dtype=object)
for j in range(n):
m[j]=stringer(s,j)
return(m)

def fuser(s,w,m):                 #aggregates elements with the same mu in s,w and m
g=[]
h=[]
n=len(m)
for j in range(n):
l=s[j]
r=w[j]
for i in range(j+1,n):
if m[i]==m[j]:
l=l+s[i]
r=r+w[i]
s[i]=0
m[i]=2
w[i]=0
g.append(l)
h.append(r)
return(g,h,m)

def orderer(s,w,m):             #orderes the strings based on the mu
k=0
q=0
t=0
r=len(s)
n=[]
for j in range(r):
n=[]
for i in range(j,r):
n.append(m[i])
t=min(n)
for i in range(j,r):
if m[i]==t:
k=s[j]
q=w[j]
s[j]=s[i]
w[j]=w[i]
s[i]=k
w[i]=q
k=m[j]
m[j]=m[i]
m[i]=k
return(s,w)

def reducer(v):                 #removes the 0
w=[]
n=len(v)
for i in range(n):
if v[i]!=0:
w.append(v[i])
v=w
return(v)

def final(w):
str=counter(w)
n=mumaker(str)
[g,h,m]=fuser(str,w,n)
[p,q]=orderer(g,h,m)
k=reducer(p)
u=reducer(q)
return(k,u)

def cycler(w):
for i in range(10):
i=i+1
u=w
[k,w]=final(u)
print('New mu line cardinalities=',k, 'New mu line=', u)
if u==final(u)[1]:
break

cycler(v)


This works fine with almost every input, for example v=[[0],[1],[2],[3],[4,5]]. However if I try inputs like v=[[0],[1],[2],[3],[4],[5]] or v=[[0,1],[2,3],[4,5]] (i.e. inputs in which every element has the same lenght) the following error comes up:

TypeError                                 Traceback (most recent call last)
Input In [1], in <cell line: 134>()
131             break
--> 134 cycler(v)

Input In [1], in cycler(w)
125 i=i+Integer(1)
126 u=w
--> 127 [k,w]=final(u)
128 print('New mu line cardinalities=',k, 'New mu line=', u)
129 if u==final(u)[Integer(1)]:

Input In [1], in final(w)
112 def final(w):
--> 113     str=counter(w)
114     n=mumaker(str)
115     [g,h,m]=fuser(str,w,n)

Input In [1], in counter(w)
7 s=[]
8 for i in range(n):
----> 9     a=len(w[i])
10     s.append(a)
11 return s

TypeError: object of type 'sage.rings.integer.Integer' has no len()


How can I solve this?

edit retag close merge delete

Sort by ยป oldest newest most voted

Your function fuser changes values of its arguments, and in inconsistent manner - eg., second argument w comes as a list of lists but after modifications done by fuser some elements of w may change type from list to integer.

The argument change is further propagated to function final(w) which also changes the value of w and in inconsistent manner. I do not know if the argument change is intended, but if so it's done wrong. If it's not intended, then a quick fix one would changing the call final(u) into final(u.copy()) to protect the value of u from modification which then results in the eror.

On general scale it's better to change the design of functions so that modifications of arguments are either avoided (via use of new variables), or done in consistent manner.

more