Python loop list in function call - python-3.x

This is my first question on StackOverflow. I have always found what I was looking for just googling, but this time I'm stuck and can't figure it out.
I'm a beginner programmer with python and still learning a lot.
I want to change a dateEdit box in a Userinterface with a small code to set det current date time.
the code looks like this.
self.dateEdit_2.setDateTime(QtCore.QDateTime.currentDateTime())
Now i want to change every dateEdit box the same, starting from 2 and going to 29, without typing every single line out.
i have tried to make a for loop with a filled list.
and i get it to print out what i want, but how does i get "set_date_numb" to be a attribute that does what i want.
hope you understand, Thanks.
dateTimeList = ['2','3','4','5','6','7','8','9',
'10','11','12','13','14','15','16','17','18','19','20',
'21','22','23','24','25','26','27','28','29']
indexval = 0
for i in range(len(dateTimeList)):
date_numb = (dateTimeList[indexval])
set_date_numb ='self.dateEdit_{}.setDateTime(QtCore.QDateTime.currentDateTime())'.format(date_numb)
print(set_date_numb)
indexval += 1

You could use getattr(), see the documentation here. Since the functions you are after are members of your instance you can grab them with their names as strings (which I think is the main problem you are facing):
dateTimeList = [str(x) for x in range(2,30)]
for dt in dateTimeList:
name = "dateEdit_{}".format(dt)
currentDateEdit = getattr(self, name)
currentDateEdit.setDateTime(QtCore.QDateTime.currentDateTime())

Related

connecting a variable output to send Keys string

I am trying to generate a random number that is six digits and then submit that 6 digit out put to a website.
here is my code:
send_code = self.chrome_browser.find_element_by_xpath("/html/body/div[1]/section/div/div/div[3]/form/span/button").click()
random_num = random.randrange(000000, 999999)
(f'{random_num:06}')
send_random_num = self.chrome_browser.find_elements_by_xpath('/html/body/div[1]/section/div/div/div[2]/form/div/input')
random_num.send_keys(Keys.random_num, Keys.ENTER)
the generating the random number is working but for some reason my send_random_num variable is not executing the right commands. I feel like I am formatting this wrong. Keys.(var) just isn't close to right so any suggestions? thanks (using selenium)
To me, it looks like you are using selenium. Maybe next time try adding that as a tag or clearly stating what module you are using. I believe this will work, and I took the liberty clarifying some of your variable names:
button = self.chrome_browser.find_element_by_xpath("/html/body/div[1]/section/div/div/div[3]/form/span/button")
button.click()
random_num = random.randrange(000000, 999999)
random_code = (f'{random_num:06}')
input = self.chrome_browser.find_elements_by_xpath('/html/body/div[1]/section/div/div/div[2]/form/div/input')
input.send_keys(random_code)

loop to read multiple files

I am using Obspy _read_segy function to read a segy file using following line of code:
line_1=_read_segy('st1.segy')
However I have a large number of files in a folder as follow:
st1.segy
st2.segy
st3.segy
.
.
st700.segy
I want to use a for loop to read the data but I am new so can any one help me in this regard.
Currently i am using repeated lines to read data as follow:
line_2=_read_segy('st1.segy')
line_2=_read_segy('st2.segy')
The next step is to display the segy data using matplotlib and again i am using following line of code on individual lines which makes it way to much repeated work. Can someone help me with creating a loop to display the data and save the figures .
data=np.stack(t.data for t in line_1.traces)
vm=np.percentile(data,99)
plt.figure(figsize=(60,30))
plt.imshow(data.T, cmap='seismic',vmin=-vm, vmax=vm, aspect='auto')
plt.title('Line_1')
plt.savefig('Line_1.png')
plt.show()
Your kind suggestions will help me a lot as I am a beginner in python programming.
Thank you
If you want to reduce code duplication, you use something called functions. And If you want to repeatedly do something, you can use loops. So you can call a function in a loop, if you want to do this for all files.
Now, for reading the files in folder, you can use glob package of python. Something like below:
import glob, os
def save_fig(in_file_name, out_file_name):
line_1 = _read_segy(in_file_name)
data = np.stack(t.data for t in line_1.traces)
vm = np.percentile(data, 99)
plt.figure(figsize=(60, 30))
plt.imshow(data.T, cmap='seismic', vmin=-vm, vmax=vm, aspect='auto')
plt.title(out_file_name)
plt.savefig(out_file_name)
segy_files = list(glob.glob(segy_files_path+"/*.segy"))
for index, file in enumerate(segy_files):
save_fig(file, "Line_{}.png".format(index + 1))
I have not added other imports here, which you know to add!. segy_files_path is the folder where your files reside.
You just need to dynamically open the files in a loop. Fortunately they all follow the same naming pattern.
N = 700
for n in range(N):
line_n =_read_segy(f"st{n}.segy") # Dynamic name.
data = np.stack(t.data for t in line_n.traces)
vm = np.percentile(data, 99)
plt.figure(figsize=(60, 30))
plt.imshow(data.T, cmap="seismic", vmin=-vm, vmax=vm, aspect="auto")
plt.title(f"Line_{n}")
plt.show()
plt.savefig(f"Line_{n}.png")
plt.close() # Needed if you don't want to keep 700 figures open.
I'll focus on addressing the file looping, as you said you're new and I'm assuming simple loops are something you'd like to learn about (the first example is sufficient for this).
If you'd like an answer to your second question, it might be worth providing some example data, the output result (graph) of your current attempt, and a description of your desired output. If you provide that reproducible example and clear description of the problem you're having it'd be easier to answer.
Create a list (or other iterable) to hold the file names to read, and another container (maybe a dict) to hold the result of your read_segy.
files = ['st1.segy', 'st2.segy']
lines = {} # creates an empty dictionary; dictionaries consist of key: value pairs
for f in files: # f will first be 'st1.segy', then 'st2.segy'
lines[f] = read_segy(f)
As stated in the comment by #Guimoute, if you want to dynamically generate the file names, you can create the files list by pasting integers to the base file name.
lines = {} # creates an empty dictionary; dictionaries have key: value pairs
missing_files = []
for i in range(1, 701):
f = f"st{str(i)}.segy" # would give "st1.segy" for i = 1
try: # in case one of the files is missing or can’t be read
lines[f] = read_segy(f)
except:
missing_files.append(f) # store names of missing or unreadable files

Selecting an element of a list inside a list (python)

Im attempting to write a turn based, pokemon-esque, game to test my python skills & learn new things.
I'm having trouble selecting an element from a list inside of another list.
Punch = ["Punch!", 20]
Kick = ["Kick!", 40]
Moves = [Punch, Kick]
Player = ["Jamie", 100, Moves]
print ("Do you want to punch, or kick?")
attack = input(" ")
if attack == "punch":
atk = 0
if attack == "kick":
atk = 1
damage = Player[2[atk[1]]]
print (Player[0]," uses ", Player[2[atk[0]]])
but this results in error:
TypeError: 'int' object is not subscriptable
I understand why this error happens. But I'm wondering is there is another way to call up an element of a list inside of a list.
Thanks
What you want is probably something like this :
damage = Player[2][atk][1]
But beware because you only define atk in if statements so atk could potentially not be defined after those ifs.
Moreover you place either 1 or 2 in atk but you only have two moves which makes me think you want to put either 0 or 1 in it.
Note: You should not capitalise the name of your variables as it would imply they are classes instead of variables
from the way i understand
damage=Player[2][atk][1]
As has already been mentioned . The thing to understand is what is happening when you do this.
player[2] refers to Moves and when you further subscript it, it subscripts to the Moves, so player[2][atk] simply becomes Moves[atk].
A thing to keep in mind is that it is truly just a reference, if you were to change the list Moves, the value in player[2] will also change.
For example:
code:
Moves[1][2]=1000
print(player[2][1][2])
Will give output
1000

Python3 - Advice on a while loop with range?

Good afternoon! I am relatively new to Python - and am working on an assignment for a class.
The goal of this code is to download a file, add a line of data to the file, then create a while loop that iterates through each line of data, and prints out the city name and the highest average temp from the data for that city.
My code is below - I have the output working, no problem. The only issue I am running into is an IndexError: list index out of range - at the end.
I have searched on StackOverflow - as well as digging into the range() function documentation online with Python. I think I just need to figure to the range() properly, and I'd be done with it.
If I take out the range, I get the same error - so I tried to change the for/in to - for city in mean_temps:
The result of that was that the output only showed 4 of the 7 cities - skipping every other city.
Any advice would be greatly appreciated!
here is my code - the screenshot link below shows output and the error as well:
!curl https://raw.githubusercontent.com/MicrosoftLearning/intropython/master/world_temp_mean.csv -o mean_temp.txt
mean_temps = open('mean_temp.txt', 'a+')
mean_temps.write("Rio de Janeiro,Brazil,30.0,18.0")
mean_temps.seek(0)
headings = mean_temps.readline().split(',')
print(headings)
while mean_temps:
range(len(city_temp))
for city in mean_temps:
city_temp = mean_temps.readline().split(',')
print(headings[0].capitalize(),"of", city_temp[0],headings[2], "is", city_temp[2], "Celsius")
mean_temps.close()
You have used a while loop, when you actually want to use a for loop. You have no condition on your while loop, therefore, it will evaluate to True, and run forever. You should use a for loop in the pattern
for x in x:
do stuff
In your case, you will want to use
for x in range(len(city_temp)):
for city in means_temp:
EDIT:
If you have to use a while loop, you could have variable, x, that is incremented by the while loop. The while loop could run while x is less than range(len(city_temp)).
A basic example is
text = "hi"
counter = 0
while counter < 10:
print(text)
counter += 1
EDIT 2:
You also said that they expected you to get out of a while loop. If you want a while loop to run forever unless a condition is met later, you can use the break command to stop a while or for loop.
I've been stuck with this as well with the index error. My original code was:
city_temp = mean_temp.readline().strip(" \n").split(",")
while city_temp:
print("City of",city_temp[0],headings[2],city_temp[2],"Celcius")
city_temp = mean_temp.readline().split(",")
So I read the line then, in the loop, print the line, create the list from reading the line and if the list is empty, or false, break. Problem is I was getting the same error as yourself and this is because city_temp is still true after reading the last line. If you add..
print(city_temp)
to your code you will see that city_temp returns as "" and even though it's an empty string the list has content so will return true. My best guess (and it is a guess) it looks for the split condition and returns back nothing which then populates the list as an empty string.
The solution I found was to readline into a string first (or at the end of the whole loop) before creating the list:
city_temp = mean_temp.readline()
while city_temp:
city_temp = city_temp.split(',')
print(headings[0].capitalize(),"of",city_temp[0],headings[2],"is",city_temp[2],"Celcius")
city_temp = mean_temp.readline()
This time city_temp is checked by the while loop as a string and now returns false. Hope this helps from someone else who struggled with this

Python3 access previously created object

Im new to programming in general and I need some help for accessing a previously created instance of Class. I did some search on SO but I could not find anything... Maybe it's just because I should not try to do that.
for s in servers:
c = rconprotocol.Rcon(s[0], s[2],s[1])
t = threading.Thread(target=c.connect)
t.start()
c.messengers(allmessages, 10)
Now, what can I do if I want to call a function on "c" ?
Thanks, Hugo
You're creating several different objects that you briefly name c as you go through the loop. If you want to be able to access more than the last of them, you'll need to save them somewhere that won't be overwritten. Probably the best approach is to use a list to hold the successive values, but depending on your specific needs another data structure might make sense too (for instance, using a dictionary you could look up each value by a specific key).
Here's a trivial adjustment to your current code that will save the c values in a list:
c_list = []
for s in servers:
c = rconprotocol.Rcon(s[0], s[2],s[1])
t = threading.Thread(target=c.connect)
t.start()
c.messengers(allmessages, 10)
c_list.append(c)
Later you can access any of the c values with c_list[index], or by iterating with for c in c_list.
A slightly more Pythonic version might use a list comprehension rather than append to create the list (this also shows what a loop over c_list later one might look like):
c_list = [rconprotocol.Rcon(s[0], s[2],s[1]) for s in servers]
for c in c_list:
t = threading.Thread(target=c.connect)
t.start()
c.messengers(allmessages, 10)

Resources