This for loop should iterate over even 'lines' in my input, as it holds the users name which I would like to place in a dictionary as a key, with a dictionary inside that key. My output does include the information I needed, but also odd lines which I do not want.
I'm new to python so I'm still trying to understand syntax.
Here's my code:
def get_name(string_input):
split_fullstop = string_input.split('.')
list = [] #creates a list
for line in split_fullstop:
count = 0
if count % 2 == 0: #if count is even
list.append(line.split('is connected to')) #add info to 'list'
count += 1 #increase count
names = {name[0]:{} for name in list}
return names
And here's the output after printing the function:
{'': {}, 'Levi ': {}, 'Bryant ': {}, 'Jennie likes to play Super Mushroom Man, Dinosaur Diner, Call of Arms': {}, 'Olive likes to play The Legend of Corgi, Starfleet Commander': {}, 'Debra likes to play Seven Schemers, Pirates in Java Island, Dwarves and Swords': {}, 'Levi likes to play The Legend of Corgi, Seven Schemers, City Comptroller: The Fiscal Dilemma': {}, 'Walter ': {}, 'Robin ': {}, 'John ': {}, 'Walter likes to play Seahorse Adventures, Ninja Hamsters, Super Mushroom Man': {}, 'Debra ': {}, 'Freda likes to play Starfleet Commander, Ninja Hamsters, Seahorse Adventures': {}, 'Mercedes likes to play The Legend of Corgi, Pirates in Java Island, Seahorse Adventures': {}, 'Ollie ': {}, 'Robin likes to play Call of Arms, Dwarves and Swords': {}, 'Bryant likes to play City Comptroller: The Fiscal Dilemma, Super Mushroom Man': {}, 'Freda ': {}, 'Olive ': {}, 'Mercedes ': {}, 'John likes to play The Movie: The Game, The Legend of Corgi, Dinosaur Diner': {}, 'Jennie ': {}, 'Ollie likes to play Call of Arms, Dwarves and Swords, The Movie: The Game': {}}
Remember that all code at the same indentation level below the for-loop will be run EACH iteration. Therefore you are redefining the variables count and names at each item the for-loop goes through. As mentioned in one of the comments, names should be at the same indentation level as the return statement.
Redefining count at each iteration means you will always find 0 % 2 == 0. It should be defined BEFORE the for-loop. Also, you only increment count when you run the #if count is even portion. So, assuming count is defined before the loop, you will see 0 as even, increment count and be left with an odd value of 1 forever.
Look at looping though indices and values simultaneously using enumerate. That way you need only check the even/odd value of the index.
maybe your count is a error indentation, count is design to filter even line.
for line in split_fullstop:
count = 0
if count % 2 == 0: #if count is even
list.append(line.split('is connected to')) #add info to 'list'
count += 1 #increase count
So you have used a "for each loop", which loops over every element in the iterable and built in functionality to only evaluate the even indexes. Instead of this, I think it is more clear and clean to use the function range.
range(0, len(split_fullstop), 2)
Evaluating only the even
I'll just focus on your count variable, because that's the first thing that tells me there's an error:
for line in split_fullstop:
count = 0
if count % 2 == 0: #if count is even
# some code
count += 1 #increase count
#some code
return names
First of all, you're resetting the count variable on each loop with that count = 0 inside the loop, so on EVERY loop count%2 will be equal to 0. This line should be OUTSIDE (before) the loop.
Second, you're increasing the variable inside that if condition count%2 == 0, if in one iteration, count == 0, then it will enter the if-part, and will increase the value to count == 1.
In the next (and all other) iteration, since count == 1, the inside of the if-part won't be executed and thus the count variable won't change.
So, it should be like:
count = 0
for line in split_fullstop:
if count % 2 == 0: #if count is even
#some code
count += 1 #increase count
return names
Note: Don't use built'in variables such as list because you'll overwrite them and it could lead to the unexpected behaviour in future. Use l for example for that.
Your line with names = {name[0]:{} for name in list} will be executed every step because it placed not in the same position as if statement. For steps where count % 2 == 1 you'll add to your dict empty lists. But in your solution you redefine count in each step so you'll never get that as #Isaac Drachman mentioned. So just delete some spaces or tab and define count before for loop:
def get_name(string_input):
split_fullstop = string_input.split('.')
l = [] #creates a list
count = 0
for line in split_fullstop:
if count % 2 == 0: #if count is even
l.append(line.split('is connected to')) #add info to 'list'
count += 1 #increase count
names = {name[0]:{} for name in l}
return names
Or you could rewrite it with list comprehension and enumerate:
def get_name(string_input):
l = [line.split('is connected to') for i, line in enumerate(string_input.split('.')) if i % 2 == 0]
names = {name[0]:{} for name in l}
return names
Related
I'm nearly done building a dictionary that counts the number of each element entered...Although for example if I input coffee water and then enter, prints 1 coffee water in the same line... I want it to print:
1 coffee
1 water
in separate lines
What am I doing wrong?
dictionary = {}
while True:
user_input = input("Input: ")
dictionary[user_input] = dictionary.get(user_input, 0) + 1
for key, value in sorted(dictionary.items()):
print(value, key.upper())
print("\n")
Okay, here's the thing.
input() ends when Enter is hit.
i.e. - if you type "coffee water" and then press enter, it's gonna think that's the name of the item you're entering. ("coffee water")
Basically, enter one item at a time.
Or, if you want, split by whitespace and support the addition of multiple items at the same time. something like:
dictionary = {}
value = input("Enter item: ")
while value !="":
value = value.split(" ") # split by space.
# if there's no space (i.e. only one item is entered this time, this gives a list with a single item in it. (the word entered)
for item in value:
if item in dictionary.keys(): # if the item exists, add 1 to its counter
dictionary[item] +=1
else: # if the item doesn't exist, set its counter to 1
dictionary[item] = 1
value = input("Enter item: ")
for key, value in sorted(dictionary.items()):
print(value, key.upper())
Entering:
coffee
water
water coffee
gives:
2 COFFEE
2 WATER
Note: this breaks if you have items with spaces in their name. like "water bottle"
also read about the defaultdict module
To solve the problem you mention in your last comment and to provide an escape from the while loop, I would revise your code as follows. This changes lines 2, 5, 6, 8 and 9. I had trouble getting my code in here. Let me know if you have any problems.
dictionary = {}
i = 1
while True:
user_input = input("Input: ")
if user_input == "":
break #provides escape
dictionary[user_input] = dictionary.get(user_input, i)
i = i + 1 #solves numbering problem
for key, value in (dictionary.items()):
print(f"{value} {key.upper()}", end=" ")
print("\n")
I don’t have my PC in front of me so this is kind of pseudo code.
Try something like:
input_list = user_input.split()
for i in input_list:
dictionary[i] = dictionary.get(i, 0) + 1
print(i)
By default the input will be as one string, so you cannot do your operations on it directly, you need to split it.
Edit: check out Yarin_007’s answer, however you can use the default .split() instead so that it gets split on any white space.
New to coding, sorry if the question is too simple.
I am trying to keep a tally of how many times a character in a certain string range appears. I want to use that tally, count, later and add it to different values, and other tallies. If I return it I can't seem to be able to reuse it. How would I be able to reuse the tally, but outside of the loop?
def function(word):
letters = 'abcdefgh'
while count < len(word):
for i in word:
if i in letters:
count += 1
return count
a = count + 5
print(a)
print(function('AaB5a'))
count should be 2, but how do I take it, and add it to other values, like a = count + 5? print(a) does not print 7, or anything.
Like most of the comments already covered, you should remove the return to the end, and also the while loop doesn't seem to be required (and in fact, appears to provide a wrong result).
Please let me know if this is not what you wanted, and I will correct it based on your input, but it does output 2 and prints 7 as you requested in OP
def function(word):
count = 0
letters = 'abcdefgh'
for i in word:
if i in letters:
count += 1
a = count + 5
print(a)
return count
First, you should probably not use the word function to name your function. I changed your sample to check_letters
You also want to create the variable count outside of the while loop so you can save the incremented count. At the end, return the count.
def check_letters(word):
letters = 'abcdefgh'
count = 0
while count < len(word):
for i in word:
if i in letters:
count += 1
return count
Once that is done, you can call the function and pass in your paramenter, it will return an int which in this case, you want to add 5. We're then saving the results to the variable
a = check_letters('AaB5a') + 5
print (a)
11
if you print the check letters, you'll get the return count to the output.
print (check_letters('AaB5a'))
6
I set the count variable to zero because it throws UnboundLocalError: local variable 'count' referenced before assignment. The function will return the count of the string passed in. The count is now returned by the function. You can then assign it to a variable and then add, subtract, etc., to that variable.
def function(word):
letters = 'abcdefgh'
count=0
while count < len(word):
for i in word:
if i in letters:
count += 1
return count
c=function('AaB5a')
a=c + 5
print(a)
Im and MSc student who has been lumped with doing python code this year but have no prior experience. I was wondering if someone could help me with this question, i have some parts done.
Q6)
Assignment 6
Grades are classified according to % (ranging from 0 to 100 inclusive), if greater than or equal to the following:-
70 First ; 60 Second Upper ; 50 Second Lower ; 45 Third ; 40 Pass; 0 Fail.
Create a dictionary from the data above, and use it as part of a program to grade marks, from 2 sources:-
1. during development, grade marks in sequence from a hardcoded list of marks = [-1,0,1,49,60,71,100,101],
2. after development, include code to repeatedly request marks for testing, until terminated by entering q or Q.
Marks will be awarded for concise coding, which should run efficiently with minimal use of comparisons tests.
Retain features to take input from both sources above in the final code, i.e. don't delete item '1' after development.
My solution so far looks something like this :
hardcoded_lst = [-1,0,1,49,60,71,100,101]
grade_input=int(input('What grade?')
input_lst= []
while grade_input !=
input_lst.append(grade_input)
grade_input=int(input('What grade?')
print(input_lst)
i need to create a dictionary for the values but currently that isnt working either.
Id appreciate any help, in basic code as i am not very advanced.
Thanks
creating dictionary isn't that tough, its as simple as creating list, which you have already done
For list
mylist = []
#for dictionary
mydictionary = {}
Adding item into dictionary
mylist.append(value)
mydictionary["fail"] = 50
Iterating the list
for item in mylist:
print item
Iterating in dictionary
for key,value in mydictionary.iteritem():
print key,value
I hope this helps you, there might be mistake in iteritem spelling etc you could google it but thats how its done normally
here is updated thing
mydictionary = {}
marks = 0
mydictionary[(0,45)] = "Fail"
mydictionary[(46,59)] = "Lower"
mydictionary[(60,69)] = "Second Lower"
mydictionary[(70,100)] = "First"
marks = 63
for key,value in mydictionary.iteritems():
if marks >= key[0] and marks <= key[1]:
print value
The given code works you could also do it in this way though
The following program should do as you asked. There are several lines that are commented out with the # character. You may uncomment those lines if you wish to see the value of the variable referenced in the call to the debug function. Please take time to study the code so that you understand how and why it works.
import pprint
import sys
RANGE = range(0, 101)
GRADE = {70: 'First', 60: 'Second Upper',
50: 'Second Lower', 45: 'Third',
40: 'Pass', 0: 'Fail'}
MARKS = -1, 0, 1, 49, 60, 71, 100, 101
def main():
"""Grade hardcoded marks and grade marks entered by the user."""
# debug('MARKS')
grade_all(MARKS)
grade_all(get_marks())
print('Goodbye!')
def grade_all(marks):
"""Take an iterable of marks and grade each one individually."""
for mark in marks:
# debug('mark')
if mark in RANGE:
print(mark, 'gets a grade of', grade_one(mark))
else:
print(mark, 'is not a valid mark')
def grade_one(mark):
"""Find the correct grade for a mark while checking for errors."""
# debug('RANGE')
if mark in RANGE:
for score, grade in sorted(GRADE.items(), reverse=True):
if mark >= score:
return grade
raise ValueError(mark)
def get_marks():
"""Create a generator yielding marks until the user is finished."""
while True:
try:
text = input('Mark: ')
except EOFError:
sys.exit()
else:
# debug('text')
if text.upper() == 'Q':
break
try:
mark = round(float(text))
except ValueError:
print('Please enter a mark')
else:
# debug('mark')
if mark in RANGE:
yield mark
else:
print('Marks must be in', RANGE)
def debug(name):
"""Take the name of a variable and report its current status."""
frame, (head, *tail) = sys._getframe(1), name.split('.')
for scope, space in ('local', frame.f_locals), ('global', frame.f_globals):
if head in space:
value = space[head]
break
else:
raise NameError('name {!r} is not defined'.format(head))
for attr in tail:
value = getattr(value, attr)
print('{} {} {} = {}'.format(
scope, type(value).__name__, name, pprint.pformat(value)), flush=True)
if __name__ == '__main__':
main()
You need to create a dictionary using the grade values as keys, and depending on the input populate the key with the input, or reject it as invalid. Maybe something like this:
if input>=70:
grade[first]=input
elif input>=60 and input<70:
grade[secondupper]=input
elif input<0 or input>100:
print 'invalid grade!'
If you have more than one value for each grade then consider using a list to read the values into, and then setting the corresonding dictionarty value to the list as you fill it.
places=["Jack", "John", "Sochi"]
place = places[0]
while places != "Sochi" and count < len(places):
if ' ' in place:
multi_word += 1
count += 1
place = places[count]
I basically want the program to check how many cities till Sochi, by adding one for each element of the list. Then when it reaches Sochi it stops adding 1 to the list then it do nothing when it reaches Sochi. The program adds one for every element of the list. Then it checks if their is a space in any of the elements of the list and if so adds one but only if that element of the list comes from Sochi. What is wrong with this program?
Also what does this line do..{count < len(places)}
The main error I see is that you need to check if place != "Sochi", instead of using places. Assuming you initialize count=0, this will give you the output you desire:
places = ["Jack", "John", "Sochi"]
place = places[count]
while place != "Sochi" and count < len(places):
if ' ' in place:
multi_word += 1
count += 1
place = places[count]
print 'Number of cities before Sochi:', count
The clause count < len(places) makes sure that you don't try access indices in places beyond the length of the list, which would return an IndexError.
places = ["Jack", "John", "Sochi"]
count=0
multi_word=0
place = places[count]
while place != "Sochi" and count < len(places):
if ' ' in place:
multi_word += 1
count += 1
place = places[count]
print ('Number of cities before Sochi:', count)
Here is the fixed code
I'm using Python (3.x) to create a simple program for an assignment. It takes a multiline input, and if there is more than one consecutive whitespace it strips them out and replaces it with one whitespace. [That's the easy part.] It must also print the value of the most consecutive whitespaces in the entire input.
Example:
input = ("This is the input.")
Should print:
This is the input.
3
My code is below:
def blanks():
#this function works wonderfully!
all_line_max= []
while True:
try:
strline= input()
if len(strline)>0:
z= (maxspaces(strline))
all_line_max.append(z)
y= ' '.join(strline.split())
print(y)
print(z)
if strline =='END':
break
except:
break
print(all_line_max)
def maxspaces(x):
y= list(x)
count = 0
#this is the number of consecutive spaces we've found so far
counts=[]
for character in y:
count_max= 0
if character == ' ':
count= count + 1
if count > count_max:
count_max = count
counts.append(count_max)
else:
count = 0
return(max(counts))
blanks()
I understand that this is probably horribly inefficient, but it seems to almost work. My issue is this: I would like to, once the loop is finished appending to all_lines_max, print the largest value of that list. However, there doesn't seem to be a way to print the max of that list without doing it on every line, if that makes sense. Any ideas on my convoluted code?
Just print the max of all_line_max, right where you currently print the whole list:
print(max(all_line_max))
but leave it at the top level (so dedent once):
def blanks():
all_line_max = []
while True:
try:
strline = input()
if strline:
z = maxspaces(strline)
all_line_max.append(z)
y = ' '.join(strline.split())
print(y)
if strline == 'END':
break
except Exception:
break
print(max(all_line_max))
and remove the print(z) call, which prints the maximum whitespace count per line.
Your maxspaces() function adds count_max to your counts list each time a space is found; not the most efficient method. You don't even need to keep a list there; count_max needs to be moved out of the loop and will then correctly reflect the maximum space count. You also don't have to turn the sentence into a list, you can directly loop over a string:
def maxspaces(x):
max_count = count = 0
for character in x:
if character == ' ':
count += 1
if count > max_count:
max_count = count
else:
count = 0
return max_count