Whats does index_set() different things in a <class 'pyomo.core.base.param.IndexedParam'>? - pyomo

I have a model with this parameters:
#DATA
m.d=Param(m.I, m.T)
m.pc=Param(m.I, m.J)
m.pr=Param(m.I, m.J)
m.oc=Param(m.I)
m.hc=Param(m.I)
m.ca=Param(m.J,m.T)
m.fp=Param()
m.imax=Param()
m.lote=Param(m.I)
In other file I want get indexes of the data elements, when it has only one index like oc I get the index with v.index_set() (in this case return me I) but when it has 2 indexes like d I get ().
I don't undestand what is happening.
Thanks!

I have a solution. Thanks to https://groups.google.com/g/pyomo-forum/c/6dYMZwBP3Wo/m/BPwC9KvcAwAJ.
When we have more than 1 index we have to add .subsets()

Related

I need a code which sums different numbers

I got a very difficult assignment as I am new to python, I hope you will be able to help me.
I wrote this code:
def hours_per_student(student_course,course_hours):
new={}
for key in student_course.keys():
for val in student_course.values():
for m in range(len(val)):
if not new.has_key(key):
new[key]=course_hours[val[m]]
else:
new[key]=new[key]+course_hours[val[m]]
return new
for these dictionaries:
student_course = {'rina' : ['math', 'python'], 'yossi' : ['chemistry', 'biology'], 'riki' : ['python']}
course_hours = {'math' : 4, 'python' : 4, 'chemistry' : 6, 'biology' : 5}
And I need to get this:
hours_per_student(student_course, course_hours)
to return this:
{'rina': 8, 'yossi': 11, 'riki': 4}
But I keep getting identical numbers for each key.
You shouldn't be iterating over .values() if you're already iterating over .keys(), just use the key to get the value. Or where you have for m in len(val), just do for m in val and then reference m instead of val[m](the naming here stinks but I discuss that later). Python is much better at iteration than that. For instance, instead of the line
for val in student_course.values():
you should try something like
for courses in student_course[key]:
for course in courses:
if key not in new:
new[key] = course_hours[course]
else:
new[key] += course_hours[course]
Naming your variables intelligently will make it easier for you to keep track of what's happening. For example, each value in student_course is a list of courses, so you should name it that, not something ambiguous like val. Similarly, each element in courses is the name of a course, so name it as such.
Here you go:
solution = {student: sum([hours.get(course, 0) for course in s_courses]) for student, s_courses in student_course.items()}
Here are the things I found lacking in your code:
When iterating over your students, you could have just created a key for each of them, and then add the hours per course.
Naming variables so you understand what they mean is confused, refrain from using new, key or val.
You don't have to use keys() function, iterating a dictionary using for key in dictionary works the same way.
Here's a fixed code snippet:
def hours_per_student(students, course_hours):
total_hours = {}
for student in students:
courses = students[student]
total_hours[student] = 0
for course in courses:
total_hours[student] += course_hours[course]
return total_hours

Python: referring to each duplicate item in a list by unique index

I am trying to extract particular lines from txt output file. The lines I am interested in are few lines above and few below the key_string that I am using to search through the results. The key string is the same for each results.
fi = open('Inputfile.txt')
fo = open('Outputfile.txt', 'a')
lines = fi.readlines()
filtered_list=[]
for item in lines:
if item.startswith("key string"):
filtered_list.append(lines[lines.index(item)-2])
filtered_list.append(lines[lines.index(item)+6])
filtered_list.append(lines[lines.index(item)+10])
filtered_list.append(lines[lines.index(item)+11])
fo.writelines(filtered_list)
fi.close()
fo.close()
The output file contains the right lines for the first record, but multiplied for every record available. How can I update the indexing so it can read every individual record? I've tried to find the solution but as a novice programmer I was struggling to use enumerate() function or collections package.
First of all, it would probably help if you said what exactly goes wrong with your code (a stack trace, it doesn't work at all, etc). Anyway, here's some thoughts. You can try to divide your problem into subproblems to make it easier to work with. In this case, let's separate finding the relevant lines from collecting them.
First, let's find the indexes of all the relevant lines.
key = "key string"
relevant = []
for i, item in enumerate(lines):
if item.startswith(key):
relevant.append(item)
enumerate is actually quite simple. It takes a list, and returns a sequence of (index, item) pairs. So, enumerate(['a', 'b', 'c']) returns [(0, 'a'), (1, 'b'), (2, 'c')].
What I had written above can be achieved with a list comprehension:
relevant = [i for (i, item) in enumerate(lines) if item.startswith(key)]
So, we have the indexes of the relevant lines. Now, let's collected them. You are interested in the line 2 lines before it and 6 and 10 and 11 lines after it. If your first lines contains the key, then you have a problem – you don't really want lines[-1] – that's the last item! Also, you need to handle the situation in which your offset would take you past the end of the list: otherwise Python will raise an IndexError.
out = []
for r in relevant:
for offset in -2, 6, 10, 11:
index = r + offset
if 0 < index < len(lines):
out.append(lines[index])
You could also catch the IndexError, but that won't save us much typing, as we have to handle negative indexes anyway.
The whole program would look like this:
key = "key string"
with open('Inputfile.txt') as fi:
lines = fi.readlines()
relevant = [i for (i, item) in enumerate(lines) if item.startswith(key)]
out = []
for r in relevant:
for offset in -2, 6, 10, 11:
index = r + offset
if 0 < index < len(lines):
out.append(lines[index])
with open('Outputfile.txt', 'a') as fi:
fi.writelines(out)
To get rid of duplicates you can cast list to set; example:
x=['a','b','a']
y=set(x)
print(y)
will result in:
['a','b']

TypeError: list indices must be integers, not unicode in python code

I used the split() function to convert string to a list time = time.split() and this is how my output looks like :
[u'1472120400.107']
[u'1472120399.999']
[u'1472120399.334']
[u'1472120397.633']
[u'1472120397.261']
[u'1472120394.328']
[u'1472120393.762']
[u'1472120393.737']
Then I tried accessing the contents of the list using print time[1] which gives the index out of range error (cause only a single value is stored in one list). I checked questions posted by other people and used print len(time). This is the output for that:
1
[u'1472120400.107']
1
[u'1472120399.999']
1
[u'1472120399.334']
1
[u'1472120397.633']
1
[u'1472120397.261']
1
[u'1472120394.328']
1
[u'1472120393.762']
1
[u'1472120393.737']
I do this entire thing inside a for loop because I get logs dynamically and have to extract out just the time.
This is part of my code:
line_collect = lines.collect() #spark function
for line in line_collect :
a = re.search(rx1,line)
time = a.group()
time = time.split()
#print time[1] #index out of range error which is why I wrote another for below
for k in time :
time1 = time[k]#trying to put those individual list values into one variable but get type error
print len(time1)
I get the following error :
time1 = time[k]
TypeError: list indices must be integers, not unicode
Can someone tell me how to read each of those single list values into just one list so I can access each of them using a single index[value]. I'm new to python.
My required output:
time =['1472120400.107','1472120399.999','1472120399.334','1472120397.633','1472120397.261','1472120394.328','1472120393.762','1472120393.737']
so that i can use time[1] to give 1472120399.999 as result.
Update: I misunderstood what you wanted. You have the correct output already and it's a string. The reason you have a u before the string is because it's a unicode string that has 16 bits. u is a python flag to distinguish it from a normal string. Printing it to the screen will give you the correct string. Use it normally as you would any other string.
time = [u'1472120400.107'] # One element just to show
for k in time:
print(k)
Looping over a list using a for loop will give you one value at a time, not the index itself. Consider using enumerate:
for k, value in enumerate(time):
time1 = value # Or time1 = time[k]
print(time1)
Or just getting the value itself:
for k in time:
time1 = k
print(time1)
--
Also, Python is zero based language, so to get the first element out of a list you probably want to use time[0].
Thanks for your help. I finally got the code right:
newlst = []
for line in line_collect :
a = re.search(rx1,line)
time = a.group()
newlst.append(float(time))
print newlst
This will put the whole list values into one list.
Output:
[1472120400.107, 1472120399.999, 1472120399.334, 1472120397.633,
1472120397.261, 1472120394.328, 1472120393.762, 1472120393.737]

how to find maximum k-mer in a sequence

Sample Input:
ACGTTGCATGTCGCATGATGCATGAGAGCT # this is the sequence in which we
have to search
4 # this is the k-mer(integer value)
Sample Output:
CATG GCAT
I do not understand how to do this. Please help me. Thanks in advance.
If I understand your question correctly, here is one way to work through the list:
s="ACGTTGCATGTCGCATGATGCATGAGAGCT"
n=4
k=len(s)-2*n
klist = []
for i in range(k):
kmer=s[i:i+n]
if not(kmer in klist) and (kmer in s[i+n:]):
klist.append(kmer)
print klist
It looks like your example had a few more kmers that expected, unless I am misunderstanding:
['TGCA', 'GCAT', 'CATG', 'ATGA']
For n = 5:
['TGCAT', 'GCATG', 'CATGA']
And even for n = 6:
['TGCATG', 'GCATGA']

How to save multiple arguments to a Map?

I am using arguments from command line which is in the form of an Array and I would like to convert that into a Map.
So for example when I run my code with scala abc.scala A 10 B 20 C 30 I want to have a Map(A->10, B->20, C->30). Also I can use only val so I cannot reassign it because it is immutable. I am using the following piece of code unsuccessfully:
val names = args.filter(x => for(i <- 0 to args.length-1) i%2==0)
val numbers = args.partition(args(i) => i%2==1)
names.zip(numbers).toMap
You want grouped:
args.grouped(2).map { case Array(n,v) => (n,v) }.toMap
You're using for in completely the wrong way. That runs a new iteration every element of your args. If you want an index that you can work off of, try args.zipWithIndex (which pairs an index with each element). Alternatively, look at args.grouped(2).