In the for loop, you're overwriting data at every iteration with data = coords_data. If data is a list, then use data.append(coords_data) instead to add new data to it at each iteration. Note that you'll need to initialize it before the for loop with data = []
Essentially:
data = []
for grp_str in group_strings:
data.append(self.point_dict[grp_str]['Coords'])
Answer from glhr on Stack OverflowIn the for loop, you're overwriting data at every iteration with data = coords_data. If data is a list, then use data.append(coords_data) instead to add new data to it at each iteration. Note that you'll need to initialize it before the for loop with data = []
Essentially:
data = []
for grp_str in group_strings:
data.append(self.point_dict[grp_str]['Coords'])
Your with block is outside the for loop so it's executed after loop finishes and has only access to the last element because that's the state with which the loop terminates.
But if you open a with inside your loop block everytime, you'll again get the same result, so you've to open it with append mode 'a+'
self.group_strings = ['CHIN', 'L_EYE_BROW', 'R_EYE_BROW', 'L_EYE', 'R_EYE', 'T_NOSE', 'B_NOSE', 'O_LIPS', 'I_LIPS']
if reply == QMessageBox.Yes:
for grp_str in self.group_strings:
coords_data = self.point_dict[grp_str]['Coords']
data = coords_data
# with is now inside the for loop
with open("data_file.json", "a+") as write_file:
json.dump(data, write_file)
A even better way would be to run the loop inside the context manager.
self.group_strings = ['CHIN', 'L_EYE_BROW', 'R_EYE_BROW', 'L_EYE', 'R_EYE', 'T_NOSE', 'B_NOSE', 'O_LIPS', 'I_LIPS']
if reply == QMessageBox.Yes:
with open("data_file.json", "w") as write_file:
for grp_str in self.group_strings:
coords_data = self.point_dict[grp_str]['Coords']
data = coords_data
json.dump(data, write_file)
I positioned the return outside of the for loop as well but the same results.
def user(number, email, account_type):
for i in range(number):
f_name = fake.first_name()
l_name = fake.last_name()
email = "testmail.com"
acct_type = account_type
return f_name, l_name, acct_type, emailObligatory warning - new to Python and Pandas.
I'm having some difficulty executing a for loop. It is only returning the last value in the list.
I have a .csv file containing information that I'd like to run through CanvasAPI to post user scores. The .csv layout is:
Name user_id Score 0 Name_0 7454 90.0 1 Name_1 7075 96.0 2 Name_2 7377 76.0 3 Name_3 7259 49.0 4 Name_4 7294 48.0 5 Name_5 7491 76.5
My code for executing the loop is:
canvas = Canvas(API_URL, API_KEY)
#this gives access to a particular course
course = canvas.get_course(9997)
#this gives access to an assignment within the course
assignment = course.get_assignment(78290)
#this identifies users within that course, based on values in the dataframe/csv
userlist = [canvas.get_user(user) for user in df['user_id']]
length1 = len(userlist)
#looping attempt2
for i in range(length1):
(userlist[i])
scorelist = df['Score']
length2 = len(scorelist)
#looping attempt2
for x in range(length2):
(scorelist[x])
#this object selects specific submissions by users
submission = assignment.get_submission(userlist[i])
#this command posts grades
submission.edit(submission={'posted_grade': scorelist[x]})The loops successfully runs, but only the final row of the .csv is actually scored (for Name_5). What am I missing? Any help greatly appreciated.
-
I think something got messed up when you copy pasted. Your code appears like it isn't properly indented, please check this first (You're referring to your iterators outside of the loop or this intentional?)
-
You're a bit vague about what you're actually trying to accomplish. What is the output data you want to get? What needs to be passed to the api?
-
When you post code it's best to put comments above logical blocks explaining what you're trying to accomplish with the code below (not what you're doing, eg. looping though list xy, but why you're doing what you're doing.) Nobody here has a clue about your project, so to save everybody time, explain what you're trying to do so we don't have to guess.
-
Looping through dataframes is almost always a bad idea, but we can get to that after my first three points are addressed.
When posting code, please post code such that reddit will format it as a code block.
Either of these work:
-
a) indent every line by 4 extra spaces
-
b) use the code block button. https://i.imgur.com/J2t9krT.png
Do not:
-
use ``` as that only works for the new cropped UI, and not on the old widescreen interface.
-
post links to images of code, as they can't be cut/paste from.
Please see the r/learnpython/w/FAQ for more information.
Your code and data blocks should look like this.
Just add 4 spaces at the start of each line.
And a blank line before the section starts.
Thanks!
Because you're overwriting word in the loop, not really a good idea. You can try something like:
wordlist = ""
for word in wordStr:
wordlist = "%s %s"%(wordlist,word.strip())
print wordlist[1:]
This is fairly primitive Python and I'm sure there's a more Pythonic way to do it with list comprehensions and all that new-fangled stuff :-) but I usually prefer readability where possible.
What this does is to maintain a list of the words in a separate string and then add each stripped word to the end of that list. The [1:] at the end is simply to get rid of the initial space that was added when the first word was tacked on to the end of the empty word list.
It will suffer eventually as the word count becomes substantial since tacking things on to the end of a string is less optimal than other data structures. However, even up to 10,000 words (with the print removed), it's still well under a second of execution time.
At 50,000 words it becomes noticeable, taking 3 seconds on my box. If you're going to be processing that sort of quantity, you would probably opt for a real list-based solution like (equivalent to above but with a different underlying data structure):
wordlist = []
for word in wordStr:
wordlist.append (word.strip())
print wordlist
That takes about 0.22 seconds (without the print) to do my entire dictionary file, some 110,000 words.
To print all the words in wordStr (assuming that wordStr is some kind of iterable that returning strings), you can simply write
for word in wordStr:
word = word.strip()
print word # Notice that the only difference is the indentation on this line
Python cares about indentation, so in your code the print statement is outside the loop and is only executed once. In the modified version, the print statement is inside the loop and is executed once per word.
You don't need range(len(list_)) for iterating over indeces only.
Usual for will do. You can also unpack list with *:
fields = [['a','b','c'],['x','y','z']]
len_ = len(fields)
for i in range(len_):
driver.find_element_by_xpath("element").send_keys(*fields[i])
You could also iterate trhrough the values of the fields itself:
fields = [['a','b','c'],['x','y','z']]
for field in fields:
driver.find_element_by_xpath("element").send_keys(*field)
Firstly there is a bug in your program as you have written it:
fields = [['a','b','c'],['x','y','z']]
for i, v in enumerate(fields):
driver.find_element_by_xpath("element").send_keys(fields[i][0],fields[i[1],fields[i][2])
^ # No closing ]
Secondly there is a term that Python developers like to throw around: Pythonic Code.
We like to write short concise code that favors readability over squeezing every last inch of performance.
Referring to this you should change your code as it is unnecessarily cluttered and you are not even utilizing the value element of enumerate. I would recommend the following:
fields = [['a','b','c'],['x','y','z']]
for field in fields:
name, age, height = field # Replace this line with whatever the fields represent
driver.find_element_by_xpath("element").send_keys(name, age, height)
This code is short, concise, and above all extremely readable to someone else.
Note: Replace the name, age, height with whatever they represent in your program.
If in fact this didn't solve your problem, your problem may not be with python but with selenium itself and that is out of the scope of this question. You can test this with simply printing the values before feeding it to the selenium function like this:
fields = [['a','b','c'],['x','y','z']]
for field in fields:
name, age, height = field # Replace this line with whatever the fields represent
print(name, age, height)
driver.find_element_by_xpath("element").send_keys(name, age, height)
Hope this helps.
As RedzMakersError said, you only check if the word is #, and only #.
You should try something like:
if word.startswith('#'):
hashtag_list.append(word)
As the name of the function says, it returns True if the string starts with #, False otherwise.
Official documentation: https://docs.python.org/3/library/stdtypes.html#str.startswith
I think your problem is that with this line:
if word == '#':
you check if the word is only a "#"
You probaly just want to check if the word starts with a hashtag character (as hashtags do). You can do that with the startswith() function wich checks if a string starts with the given character and returns true if it does.
So in youre case your code should probably look like this:
if word.startswith("#"):
hashtag_list.append(word)
Here you can read a bit more about startswith():
https://www.w3schools.com/python/ref_string_startswith.asp
hope this helps :)
So, what's happening here is that the dictionary you are trying to update is a runtime variable at this point, and every time it gets updated in the for loop, it is also updating the value of the item present in it so that the final output is the same where ever this variable is present. Considering values in both list and dict are not hardcoded values but dynamic in nature.
It can simply be fixed by creating an empty dict at every iteration. So it does not overwrite the same location in memory, and unique values are captured.
instances = []
for i in range(4):
inst = {}
print i
inst['count'] = i
instances.append(inst)
print instances
Place the definition of the inst variable inside the loop.
instances = []
for i in range(4):
inst = {}
inst['count'] = i
instances.append(inst)
print(instances)
Yes it's an indentation issue: the print statement needs to be "inside" the for loop. As you have it, the print statement is executed just once, after the for, using the values of the variables name, hours, pay computed in the last pass through the loop.
Edit: Even more precisely, the print statement should be inside the if statement within the for loop. You don't want to print anything if a line was just blank, and certainly you don't want to print the previously line again (which you would, using values from the previous iteration).
Your print() is not indented correctly. It should be:
for line in open(file_name):
line = line.strip()
if line != '':
(name, wage, hours) = line.split()
wage = float(wage)
hours = float(hours)
pay = wage * hours
print('%-15s%-10d%-10.2f' %(name,hours,pay))
The way it was before the for loop would take the wage, hours, name and pay for the employee in the current line in the file, then do the loop again replacing the old values. When the loop finished it would then print your variables which would contain the name, wage and hours of the last employee.
Edit: Btw, your print function should be inside the if because if it's only inside the for and you read an empty line it will print again the name, hours and pay of the last processed employee.