I am using python and some arcpy modules (that I do not think are important for my question) to run a code containing three iterations (a loop with two smaller loops inside). My code looks like this:
file = r"C:Directory\File"
cursor = arcpy.SearchCursor(file,fields)
A = range(1,270)
os.chdir ('C:\Directory')
book = xlwt.Workbook()
sheet1 = book.add_sheet('Sheet1',cell_overwrite_ok = True)
for a in A:
tot = 0
result = 0
for row in cursor:
if row.getValue('Firstfield') == a:
tot = tot + row.getValue('secondfield')
print (tot)
for row in cursor:
print row.getValue('GTYS_Branc')
if row.getValue('GTYS_Branc') == a:
result= result + row.getValue(Field1) * ((row.getValue(Field2))/tot )
sheet1.write((branch-1),0,finalIIIprob)
sheet1.write((a-1),1,result)
book.save('Excel.xls')
The code works but does not give me the results I want. I noticed that the problem is that it practically ignores the second internal loop and every iteration of the first internal loop after the first one. What could the problem be?
The issue may be that you are iterating over values in an "array", but there is nothing in there but one number which is A, not all the numbers from 0 to A, what you need to do is use range function:
try for i in range(A):
Related
I am switching from Python Console to a Python App/Programm.
I was using for loops with many prints.
I switched to PyQT5 with an Output Text aka. as Label
here is an example of my for loops:
i = 0
for x in data['data']:
rank = data['data'][i]["currenttierpatched"]
rr = data['data'][i]["mmr_change_to_last_game"]
date = data['data'][i]["date"]
print(f"{date}\n{rank} {rr}rr")
i += 1
I only have one Output Text, now how can i like get all the things i get from the for loop with only one command so i have one line of code for the Output Text?
Because i cant get the for loop in one single Text, you know what i mean?
because the Person from a comment doesnt answer this Post.
Im gonna answer it.
I simply made a List with
list = []
and instead of printing in every for loop i used list.append("Text")
at the end i made a new variable called Text and used "".join(list)
then in my Output Lable i simply used:
self.DOutputText.setText(f"{text}")
So it would be:
list = []
if data['status'] == 200:
for x in data['data']:
rank = data['data'][i]["currenttierpatched"]
rr = data['data'][i]["mmr_change_to_last_game"]
date = data['data'][i]["date"]
list.append(f"{date}\n{rank} {rr}rr\n")
i += 1
text = "".join(list)
self.COutputText.setText(f"{text}")
else:
self.COutputText.setText(f"Error | {data['status']}\n{data['message']}")
Thanks for you help!
EDIT
With the comment from wyattg71, i removed the i variable and edited the for loop.
list = []
if data['status'] == 200:
for i, x in data['data']:
rank = data['data'][i]["currenttierpatched"]
rr = data['data'][i]["mmr_change_to_last_game"]
date = data['data'][i]["date"]
list.append(f"{date}\n{rank} {rr}rr\n")
text = "".join(list)
self.COutputText.setText(f"{text}")
else:
self.COutputText.setText(f"Error | {data['status']}\n{data['message']}")
Below is my work. I did the printline function before, and this question required to call the function printline above for printing each line. I try to print 3 lines, each line has 4 symbols, but I only can get 2 lines, each line comes with 12 symbols. Can someone help me correct my code?
def printline(num,sym):
for i in range(num):
a = (num*sym)
return a
a = printline(5,'*')
print(a)
def printrectangle(num,height,sym):
for i in range(height):
a = printline(num,sym)*height
print(a)
return a
c = printrectangle(3,4,'*')
print(c)
A few things here:
Your printline function works, but overcomplicates the problem.
In other programming languages, in order to repeat the same string multiple times it is common to create a loop of the form:
String s = "";
for(int i = 0; i < num; i++)
s += sym;
return s;
Since this is equivalent to just concatenating the same string num times, in python there is a simpler way to do this:
s = sym*num
Your solution works because you are overwriting the value in the variable a for num times before returning it.
You misinterpreted your testcase.
You said printrectangle(3, 4, '*') should print 3 lines with 4 symbols. But as you wrote it, the first variable num=3, and the second variable height=4.
The output here is in fact:
***
***
***
***
Your code does not currently do that, but let's not get ahead of ourselves.
Indentation error
The return statement in the printrectangle function is inside the loop. This means that during the first iteration of the loop, the function will return a value.
Easy fix, just backspace until the indentation of the return lines up with that of the loop.
Actually solving the problem.
From part 1, I introduced here that in python to concatenate the same string multiple times you may simply multiply the string by the number of times you want it to show up.
Here we want the string printline(num, sym) to show up height times with an enter key after each time.
The enter key sends the command of \n. In other words, a string such as 'a\nb' is printed as:
a
b
For our purposes, we can concatenate the string printline(num, sym) with \n first, and then multiply the resulting string by height to get the result of printrectangle(num, height, sym)
def printrectangle(num, height, sym):
a = (printline(num, sym)+'\n')*height
return a
Though this code will give you what you are looking for, I still doubt by mistake you swapped num and height values in the call printrectangle(3,4,'*') itself
def printline(h,sym):
a = h*sym # removed unnessary loop
return a
def printrectangle(num,height,sym):
for i in range(num): # swap height with num in your code
a = printline(height,sym) #swap num with height in your code
yield a
for row in printrectangle(3,4,'*'):
print(row)
I'm new to BioPython and I'm trying to import a fasta/fastq file and iterate through each sequence, while performing some operation on each sequence. I know this seems basic, but my code below for some reason is not printing correctly.
from Bio import SeqIO
newfile = open("new.txt", "w")
records = list(SeqIO.parse("rosalind_gc.txt", "fasta"))
i = 0
dna = records[i]
while i <= len(records):
print (dna.name)
i = i + 1
I'm trying to basically iterate through records and print the name, however my code ends up only printing "records[0]", where I want it to print "records[1-10]". Can someone explain why it ends up only print "records[0]"?
The reason for your problem is here:
i = 0
dna = records[i]
Your object 'dna' is fixed to the index 0 of records, i.e., records[0]. Since you are not calling it again, dna will always be fixed on that declaration. On your print statement within your while loop, use something like this:
while i <= len(records):
print (records[i].name)
i = i + 1
If you would like to have an object dna as a copy of records entries, you would need to reassign dna to every single index, making this within your while loop, like this:
while i <= len(records):
dna = records[i]
print (dna.name)
i = i + 1
However, that's not the most efficient way. Finally, for you to learn, a much nicer way than with your while loop with i = i + 1 is to use a for loop, like this:
for i in range(0,len(records)):
print (records[i].name)
For loops do the iteration automatically, one by one. range() will give a set of integers from 0 to the length of records. There are also other ways, but I'm keeping it simple.
I am tasked with running a for-loop which initially finds the value of funds in a mans investment account from his 41-65th birthday. Here is the code below.
mu = 0.076 ###Mean
sigma = 0.167 ###Standard deviation
np.exp(np.random.normal(mu, sigma,))
u = .076 ###set variables
bi = 50000 ###set variables
empty = [] ###empty list
for i in range(25): ###range for birthdays 40-65
bi = ((bi) * (np.exp(np.random.normal(mu, sigma))))
empty.append(bi)
print(empty)
len(empty) ##making sure my lists match up
roundedempty = [ '%.2f' % elem for elem in empty ]
age = [41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,
60,61,62,63,64,65]
len(age) ##making sure my lists match up
investing = pd.DataFrame({"Balance":roundedempty, "Age":age})
investing.set_index('Age', inplace=True)
investing
When I print this out it give me this:
Age Balance
41 53948.13
.........
65 334294.72
Now I am tasked with simulating this 100,000 times, but I am not sure how to nest another loop within that first set of code.
mu = 0.076 ###Mean
sigma = 0.167 ###Standard deviation
bi = 50000
lognormvals = np.zeros(100000)
for i in range(100000):
lognormvals[i] = ((bi) * (np.exp(np.random.normal(mu, sigma,))))
print(lognormvals)
np.mean(lognormvals)
This is what I want, but it is only doing it for his 41st birthday. I am tasked with trying to find the means of each birthday from his 41-65th. How can I nest this loop within the first loop to solve this?
My Shot at solving:
def InvestmentSim():
mu = 0.076 ###Mean
sigma = 0.167 ###Standard deviation
np.exp(np.random.normal(mu, sigma,))
u = .076 ###set variables
bi = 50000 ###set variables
empty = [] ###empty list
for i in range(25): ###range for birthdays 40-65
bi = ((bi) * (np.exp(np.random.normal(mu, sigma))))
empty.append(bi)
roundedempty = [ '%.2f' % elem for elem in empty ]
age = [41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,
60,61,62,63,64,65]
len(age) ##making sure my lists match up
investing = pd.DataFrame({"Balance":roundedempty, "Age":age})
investing.set_index('Age', inplace=True)
a = investing.iloc[24]['Balance']
return a
def AverageSim(iterations):
results = []
for n in range (0, iterations):
a = InvestmentSim()
results.append(a)
print(results)
return myresult
myresult = AverageSim(1)
myresults = np.array(myresult) # Turn the list of values into an array
mean = np.mean(myresults)
median = np.median(myresults)
print(mean, median)
Instead of doing all the balance for each year instead I just singled out the balance on his 65th birthday and set it equal to (a). Is this how my code should work? Doesn't seem to be running
If you just want to repeat the first snippet n times, then I'd suggest wrappning your code for the simulation, up in a function which you can call repeatedly in a for loop. The function should return your expected values, and the for loop should collect the results. After the loop is finished you can do further calculations with the loop such as mean.
# Your simulation as a callable function
def InvestmentSim():
# your first code
return investing
def AverageSims(iterations):
# Initialise an empty list to collect the results
results = []
for n in range (0, iterations):
investing = InvestmentSim()
results.append(investing)
# Adds investing to the end of the list
# Returns a list of all the dataframes which you can use for future
# calculations.
# Or do the desired calculations here and return only those results.
return results
myresult = AverageSims(100000)
Note that with 100,000 iterations you will get a very long list of fairly bulky dataframes. So instead you may want to do some calculations in place or pull out relevant results from each iteration and discard the rest. For example you could just save the start and end balances from each sim and append those to lists and return those.
I'd give an example but I don't use pandas so I don't want to guess at the syntax. The basic principle is the same though: Initialise some blank lists and append the results in the for loop.
Calculations will probably be simpler to set up if you turn the finished list(s) into numpy arrays using np.array(somelist)
Edit
Your code isn't running because you're calling the AverageSims function inside the AverageSims function, so you never actually get to that call. You need to move that call outside so it's executed when you run your script. The simplest way is to write the call the same way I did above, outside any function and without indentation.
Also, if your AverageSims() function doesn't have the return mysresults line, it will return None instead. That's not a problem unless you want to use results later on.
If you don't want to keep the results and are happy with printing them out as you do now, you can also call the function without equating it to a variable:
def InvestmentSim():
# your first code
return investing
def AverageSims(iterations):
# Repeatedly do the simulation, collect results
# Returning the results, if you don't need them you can omit this:
return myresult
# Now call the AverageSims function, otherwise it will never be executed. Note: No indent.
myresults = AverageSims(100000) # If you're returning the results
# OR:
AverageSims(100000) # If you don't return the results
myresult = np.array(myresult) # Turn the list of values into an array
mean = np.mean(myresult)
median = np.median(myresult)
print(mean, median)
You can just put a loop inside another loop:
for x in range(10):
for y in range(5):
print(x,y)
I your case it would also be advisable to put the inner loop into a function, and run that function in the outer loop. Like this:
def calculate(*args):
# do your calculations here that include a loop
return result
for x in range(100000):
calculate()
I am trying to create a loop involving Pandas/ Python and an Excel file. The column in question is named "ITERATION" and it has numbers ranging from 1 to 6. I'm trying to query the number of hits in the Excel file in the following iteration ranges:
1 to 2
3
4 to 6
I've already made a preset data frame named "df".
iteration_list = ["1,2", "3", "4,5,6"]
i = 1
for k in iteration_list:
table = df.query('STATUS == ["Sold", "Refunded"]')
table["ITERATION"] = table["ITERATION"].apply(str)
table = table.query('ITERATION == ["%s"]' % k)
table = pd.pivot_table(table, columns=["Month"], values=["ID"], aggfunc=len)
table.to_excel(writer, startrow = i)
i = i + 3
The snippet above works only for the number "3". The other 2 scenarios don't seem to work as it literally searches for the string "1,2". I've tried other ways such as:
iteration_list = [1:2, 3, 4:6]
iteration_list = [{1:2}, 3, {4:6}]
to no avail.
Does anyone have any suggestions?
EDIT
After looking over Stidgeon's answer, I seemed to come up with the following alternatives. Stidgeon's answer DOES provide an output but not the one I'm looking for (it gives 6 outputs - from iteration 1 to 6 in each loop).
Above, my list was the following:
iteration_list = ["1,2", "3", "4,5,6"]
If you play around with the quotation marks, you could input exactly what you want. Since your strings is literally going to be inputted into this line where %s is:
table = table.query('ITERATION == ["%s"]' % k)
You can essentially play around with the list to fit your precise needs with quotations. Here is a solution that could work:
list = ['1", "2', 3, '4", "5", "6']
Just focusing on getting the values out of the list of strings, this works for me (though - as always - there may be more Pythonic approaches):
lst = ['1,2','3','4,5,6']
for item in lst:
items = item.split(',')
for _ in items:
print int(_)
Though instead of printing at the end, you can pass the value to your script.
This will work if all your strings are either single numbers or numbers separated by commas. If the data are consistently formatted like that, you may have to tweak this code.