Indexing in Python - python

So, I have this bit of code here that I'm working on for a school
def sem1Sort(semester1, selectionSEM1):
for semester1["1"] in semester1:
if semester1["1"] in selectionSEM1:
print semester1["1"]
def main():
selectionSEM1 = ["a", "t", "b", "f", "d", "e"]
semester1 = {"1": ['a', 'e', 't', 'x', 'l', 'y'], "2": ['b', 'f', 'h', 'm', 'r', 'd'] ,
"3": ['a', 'b', 'j', 'k', 'o', 'q', 'u'], "4": ['c', 'l', 't', 'z', 'd', 'f'],
"5": [], "6": [], "7": [], "8": []}
main()
So in the sem1Sort(): method, it should grab the semester1 list, as well as the artificial selectionSEM1 list. After that for each different index in the list of semester["1"], if it is in selectionSEM1, it should print it, correct?

I think your question is "How do I get the classes that are found in both the student's selections and the classes available for a semester?". Without changing the way your data is formatted try this filtering method.
def sem1Sort(semester1, selectionSEM1):
for period in semester1:
if period == '1':
for cls in semester1[period]:
if cls in selectionSEM1:
print cls
alternately since you were only checking for the first period
def sem1Sort(semester1, selectionSEM1):
print '\n'.join([cls for cls in semester1['1'] if cls in selectionSEM1])

Related

list out of range. Loop list in python

Can you please help me with my problem ? in line 28 says list index out of range.
I tried change for i in list to for i in range(len(message)) but it didn't help.
Thanks for help
letter = [
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
'i', 'j', 'k', 'l','m', 'n', 'o', 'p', 'q',
'r', 's', 't','u', 'v', 'w', 'x','y', 'z',
]
falseletters = [
'r', 's', 't','u', 'v', 'w', 'x','y', 'z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
'i', 'j', 'k', 'l','m', 'n', 'o', 'p', 'q',
]
message = [
]
def writing():
print("start writing")
print("write ,,end'' to end")
x = True
while x:
b = input(">>")
if b == 'end':
x = False
nour = 0
for i in range(len(message)):
nour = nour + 1
check = message[nour]
if check in [falseletters]:
print(falseletters[nour])
if check not in [falseletters]:
print(check)
if b != 'end':
message.append(b)
print("added", b)
writing()
There's several errors in your code: however, the core of your problem I believe lies in the fact that you're not iterating over each letter over each word in the message list, rather you're checking if any of the words is in falseletters. Here's a working example of what I believe you're trying to accomplish:
letters = "abcdefghijklmnopqrstuvwxyz"
falseletters = "rstuvwxyzabcdefghijklmnopq"
def mapper(letter: str) -> str:
return falseletters[letters.index(letter)]
message = []
def writing():
print("start writing")
print("write ,,end'' to end")
x = True
while x:
b = input(">>")
if b == "end":
x = False
for check in message:
print("".join(map(mapper, check)))
else:
message.append(b)
print("added", b)
writing()
It takes each word in message, and maps each letter of the word to the false letter. Then, each mapped character is printed as a string.

Getting a name of a key from a dictionary

I'm currently learning python and I'm struggling in a problem which I need to get a name as input from a user and get the first letter of the name and depending on the letter, tell him what day of the week he needs to go (context doesn't matter), so:
Monday: A - C; Tuesday: D - G; Wednesday: H - L; Thursday: M; Friday: N - Q; Saturday: R - S; Sunday: T - Z.
tuple_letter = (['a', 'b', 'c'], ['d', 'e', 'f', 'g'], ['h', 'i', 'j', 'k', 'l'], ['m'], ['n', 'o', 'p', 'q'], ['r', 's', 't'], ['u', 'v', 'w', 'x', 'y', 'z'])
tuple_week = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
name = input("Name: \n")
for letters in tuple_letter:
if letters.count(name[0]) >= 1:
print(name + ", you should go to the hospital on " + tuple_week[letters])
I thought that just like in c# for example, "letters" inside the for, it'd actually act like the i++, that it counts as a number but in fact, python itself knows that when we say "for letters in tuple_letter" I'm actually refering to the lists inside the list "tuple_letter", so it does not work since I was basing my logic on the fact that I'd use it to refer to the element of each list, because i put each element of each list in the same order (Monday and 'a','b','c' == 1, ....)
To conclude and connect with the title, I had an idea where I'd create a dictionary where each key would be the respective day of the week for a list of letters, just like I tried.
So, how can I do this? Is it possible? Better ways?
You can, it might make a bit more logical sense. Working with dictionaries can be easy in Python since they follow the standards of JSON. Obligatory reading here: https://www.w3schools.com/python/python_dictionaries.asp
Your example would involve a dictionary like this:
example_dict = {
"Monday": ['a', 'b', 'c'],
"Tuesday": ['d', 'e', 'f', 'g'],
"Wednesday": ['h', 'i', 'j', 'k', 'l'],
"Thursday": ['m'],
"Friday": ['n', 'o', 'p', 'q'],
"Saturday": ['r', 's', 't'],
"Sunday": ['u', 'v', 'w', 'x', 'y', 'z']
}
From there you can iterate using a for loop and follow the index lookup with something like example_dict[x]. Here's the second part of your code refactored to show this:
name = input("Name: \n")
if len(name) > 0:
for i in example_dict:
# Lower case the letter for comparison
if name[0].lower() in example_dict[i]:
print(name + ", you should go to the hospital on " + i)
You can store lists in dictionaries! So once you've iterated the values it's just a matter of checking what day contains the letter of the name you're analyzing.
I hope this helps you get started.
Dictionaries work by having keys corresponding to values, so if you do dict[key] or dict.get(key), you get the value.
The issue is that, with your scenario, it gets a little repetitive coding it.
letter_to_day = {
'a':"Monday",
'b':"Monday",
'c':"Monday",
'd':"Tuesday",
... # fair amount of typing
'z':"Sunday"
}
name = input("Name: \n")
print(name + ", you should go to the hospital on " + letter_to_day[name[0].lower()])
#raises an error if it isn't a letter
print(name + ", you should go to the hospital on " + letter_to_day.get(name[0].lower(), "not a letter"))
#this one will return "not a letter" if it isn't found
You can do some workarounds, like doing
letter_to_day = {}
for day in tuple_week:
for letters in tuple_letter:
for letter in letters:
letter_to_day[letter] = day
instead of typing it all out, or even doing print(letter_to_day) and copy-and-pasting the result.
But it turns out that there is another way - you can use inequalities with strings(and also lists, but that's not important).
Strings later alphabetically are greater, while strings earlier are lesser. "a" < "b" is True.
So that means you can do something like
def letter_to_day(letter):
if "a" <= letter <= "c":
return "Monday"
elif "d" <= letter <= "g":
return "Tuesday"
elif "h" <= letter <= "l":
return "Wednesday"
elif letter == "m":
return "Thursday"
elif "n" <= letter <= "q":
return "Friday"
elif "r" <= letter <= "s":
return "Saturday"
elif "t" <= letter <= "z":
return "Sunday"
else:
return "not a letter"
name = input("Name: \n")
print(name + ", you should go to the hospital on " + letter_to_day(name[0].lower()))
The answer on this post by iamwbj answers your question about having a dictionary that has days as its keys and lists of letters as its values. I think mine is faster, although it doesn't go in the direction you were expecting.
P.S. I wasn't sure if you actually meant Saturday R-S; Sunday: T-Z - your example code and question conflicted.
tuple_letter = (['a', 'b', 'c'], ['d', 'e', 'f', 'g'], ['h', 'i', 'j', 'k', 'l'], ['m'], ['n', 'o', 'p', 'q'], ['r', 's', 't'], ['u', 'v', 'w', 'x', 'y', 'z'])
tuple_week = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
dictionary = dict(zip(tuple_week, tuple_letter))
print(dictionary)
name = input("Name: \n")
for key, value in dictionary.items():
if name.lower()[0] in value:
print(name.capitalize() , ", you should go to the hospital on " , key)
Make Dict using inbuilt function and also more attention towards key and value pair
You can input either in Upper case or lower case because during comparison it makes lower case then compare
There two points you are missing:
the list index must be an integer
add the initial parameter like i to represent the index
use break to exit the for loop while check over
the name should be changed to lower case
add lower() to convert name[0]
tuple_letter = (['a', 'b', 'c'], ['d', 'e', 'f', 'g'], ['h', 'i', 'j', 'k', 'l'], ['m'], ['n', 'o', 'p', 'q'], ['r', 's', 't'], ['u', 'v', 'w', 'x', 'y', 'z'])
tuple_week = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
name = input("Name: \n")
i = 0
for letters in tuple_letter:
if letters.count(name[0].lower()) >= 1:
print(name + ", you should go to the hospital on " + tuple_week[i])
break
i += 1

using python array in recursive function cause the reference loss

I tried to solve the question in a recursive way which is known as letter combinations of a telephone number.
In this question, telephone numbers are mapped to letters and for a given digits, the combinations of letters corresponding to the given digits are asked.
dic = {
'2': ['a', 'b', 'c'],
'3': ['d', 'e', 'f'],
'4': ['g', 'h', 'i'],
'5': ['j', 'k', 'l'],
'6': ['m', 'n', 'o'],
'7': ['p', 'q', 'r', 's'],
'8': ['t', 'u', 'v'],
'9': ['w', 'x', 'y', 'z']
}
Input: "23"
Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
I tried to solve it with recursion function but I got the unexpected output [""].
def telephoneHelper(digits, index, ans):
if(index==len(digits)):
return ans
else:
tmp=[]
for letter in dic[digits[index]]:
for an in ans:
tmp.append(an+letter)
ans=tmp
telephoneHelper(digits, index+1, ans)
def telephoneNumberRec(digits):
ans=[""]
if(len(digits)!=0):
telephoneHelper(digits, 0, ans)
return ans
ans=telephoneNumberRec("23")
print(ans)
I know there are many answers related to this topic but I am trying to understand the problem in this code.
You need to add two return statements (one in the telephoneNumberRec and one in the telephoneHelper function) so that the recursion actually works. The working code would look like this:
dic = {
'2': ['a', 'b', 'c'],
'3': ['d', 'e', 'f'],
'4': ['g', 'h', 'i'],
'5': ['j', 'k', 'l'],
'6': ['m', 'n', 'o'],
'7': ['p', 'q', 'r', 's'],
'8': ['t', 'u', 'v'],
'9': ['w', 'x', 'y', 'z']
}
def telephoneHelper(digits, index, ans):
if(index==len(digits)):
return ans
else:
tmp=[]
for letter in dic[digits[index]]:
for an in ans:
tmp.append(an+letter)
ans=tmp
return telephoneHelper(digits, index+1, ans)
def telephoneNumberRec(digits):
ans=[""]
if(len(digits)!=0):
return telephoneHelper(digits, 0, ans)
return ans
ans=telephoneNumberRec("23")
print(ans)
combinations = []
def telephoneHelper(digits,index, ans):
n = len(digits[0])
for i in range(n):
item = ans + digits[0][i]
if (index==len(digits)):
combinations.append(item)
else:
telephoneHelper(digits[1:],index+1, item)
return(combinations)
def telephoneNumberRec(input_):
a = []
for letter in input_:
a.append(dic[letter])
return (telephoneHelper(a, 0, '')) # a = [['a', 'b', 'c'], ['d', 'e', 'f']]
print (telephoneNumberRec('23'))
output:
['ad', 'ae', 'af', 'bd', 'be', 'bf', 'cd', 'ce', 'cf']

Python divide each string by the total lenght of string

Thank you for your help and patience.
I am new to python and am attempting to calculate the number of times a particular atomic symbol appears divided by the total number of atoms. So that the function accepts a list of strings as argument and returns a list containing the fraction of 'C', 'H', 'O' and 'N'. But I keep on getting one result instead of getting all for each of my atoms. My attempt is below:
Atoms = ['N', 'C', 'C', 'O', 'H', 'H', 'C', 'H', 'H', 'H', 'H', 'O', 'H']
def count_atoms (atoms):
for a in atoms:
total = atoms.count(a)/len(atoms)
return total
Then
faa = count_atoms(atoms)
print(faa)
However I only get one result which is 0.07692307692307693. I was supposed to get a list starting with [0.23076923076923078,..etc], but I don't know how to. I was supposed to calculate the fraction of 'C', 'H', 'O' and 'N' atomic symbols in the molecule using a for loop and a return statement. :( Please help, it will be appreciated.
#ganderson comment explains the problem. as to alternative implementation here is one using collections.Counter
from collections import Counter
atoms = ['N', 'C', 'C', 'O', 'H', 'H', 'C', 'H', 'H', 'H', 'H', 'O', 'H']
def count_atoms(atoms):
num = len(atoms)
return {atom:count/num for atom, count in Counter(atoms).items()}
print(count_atoms(atoms))
Well you return the variable total at your first loop. Why don't you use a list to store your values? Like this:
atoms = ['N', 'C', 'C', 'O', 'H', 'H', 'C', 'H', 'H', 'H', 'H', 'O', 'H'] #python is case sensitive!
def count_atoms (atoms):
return_list = [] #empty list
for a in atoms:
total = atoms.count(a)/len(atoms)
return_list.append(total) #we add a new item
return return_list #we return everything and leave the function
It would be better to return a dictionary so you know which element the fraction corresponds to:
>>> fractions = {element: Atoms.count(element)/len(Atoms) for element in Atoms}
>>> fractions
{'N': 0.07692307692307693, 'C': 0.23076923076923078, 'O': 0.15384615384615385, 'H': 0.5384615384615384}
You can, then, even lookup the fraction for a particular element like:
>>> fractions['N']
0.07692307692307693
However, if you must use a for loop and a return statement, then answer from #not_a_bot_no_really_82353 would be the right one.
A simple one liner should do
[atoms.count(a)/float(len(atoms)) for a in set(atoms)]
Or better create a dictionary using comprehension
{a:atoms.count(a)/float(len(atoms)) for a in set(atoms)}
Output
{'C': 0.23076923076923078,
'H': 0.5384615384615384,
'N': 0.07692307692307693,
'O': 0.15384615384615385}
If you still want to use the for loop. I would suggest to go for map which would be a lot cleaner
atoms = ['N', 'C', 'C', 'O', 'H', 'H', 'C', 'H', 'H', 'H', 'H', 'O', 'H']
def count_atoms (a):
total = atoms.count(a)/float(len(atoms))
return total
map(count_atoms,atoms)

How do I converted the string of a nested list back to a nested list?

Sorry if this is breaking any rules, it's my first time posting here. The project that we're working on is to create Connect 4 in Python. We're currently struggling on how to get the game to save and load.
What we're doing so far is saving our 2D list in a .txt file and trying to load the game by reading it. The problem that we've encountered is when you're trying to read the file, it reads as a string instead of a list. For example:
[['R', 'R', 'Y', 'R', 'Y', 'Y', 'Y'], ['Y', 'Y', 'R', 'R', 'R', 'Y', 'Y'], ['R', 'R', 'E', 'E', 'E', 'E', 'E'], ['E', 'E', 'E', 'E', 'E', 'E', 'E'], ['E', 'E', 'E', 'E', 'E', 'E', 'E'], ['E', 'E', 'E', 'E', 'E', 'E', 'E']]
That gets saved as a string and we'd like to convert it back to be used to place saved dots back where they belong.
def save():
global GAME_LIST
save_file = open("savedGame.txt","w")
print('Game', GAME_LIST)
save_file.write(str(GAME_LIST))
#Will basically be the new def main() once you load a file.
def load():
global PIECES
savedFile = open("savedGame.txt","r")
loadedState = savedFile.readline()
print(loadedState)
grid()
PIECES = {'1': 0, '2': 0, '3': 0, '4': 0, '5': 0, '6': 0, '7': 0}
def newRed(column):
coordinates = {'1': -210, '2': -140, '3': -70, '4': 0, '5': 70, '6': 140, '7': 210}
red = turtle.Turtle()
red.hideturtle()
red.up()
#Pieces * Cell length for Y value
red.goto(coordinates[column], -160 + (PIECES[column] * 70))
PIECES[column] += 1
red.dot(60, 'red')
def newYellow(column):
coordinates = {'1': -210, '2': -140, '3': -70, '4': 0, '5': 70, '6': 140, '7': 210}
#Computer turtle
yellow = turtle.Turtle()
yellow.hideturtle()
yellow.up()
yellow.goto(coordinates[column], -160 + (PIECES[column] * 70))
PIECES[column] += 1
yellow.dot(60, 'yellow')
def toList(stringState):
sublist = []
for characters in stringState:
sublist.append(characters)
print(sublist)
return sublist
def reDot(loadedState):
global ROW
global COLUMN
for sortList in range(ROW):
newList = loadedState[sortList]
for sortSubList in range(COLUMN):
sortSubList = int(sortSubList)
if newList[sortSubList] == "R":
newRed(sortSubList + 1)
elif newList[sortSubList] == "Y":
newYellow(sortSubList + 1)
newList = toList(loadedState)
reDot(newList)
This is a snippet of our code for reference. reDot() is supposed to take the location of 'R'/'Y' and place a dot there.
If you want to save data into files and read them back, I think JSON library will be helpful to you, very easy to use, this way:
data = [['R', 'R', 'Y', 'R', 'Y', 'Y', 'Y'], ['Y', 'Y', 'R', 'R', 'R', 'Y', 'Y'], ['R', 'R', 'E', 'E', 'E', 'E', 'E'], ['E', 'E', 'E', 'E', 'E', 'E', 'E'], ['E', 'E', 'E', 'E', 'E', 'E', 'E'], ['E', 'E', 'E', 'E', 'E', 'E', 'E']]
with open('game_data.json', 'w') as fp:
json.dump(data, fp)
And then when you want to read it back:
with open('game_data.json', 'r') as fp:
data = fp.read()
You may also want to wrap the above code with a try-except block in case the file was not found or any other exception.

Categories

Resources