Python code not appending 'Free Period' when I want it to - python

list1 = []
elective = []
prereq = []
someNumber = 1
dict2 = {
1: SEM2period1, 2: SEM2period2,
2: SEM2period3, 4: SEM2period4,
5: SEM2period5, 6: SEM2period6,
7: SEM2period7, 8: SEM2period8
}
for key, dlist in dict2.items():
if not dlist:
list1.append("Free Period")
someNumber += 1
continue
for item in dlist:
if item in list1:
continue
elif item in elective:
elecStorage.append(item)
elif item in prereq:
list1.append(item)
someNumber += 1
break
if someNumber > len(list1):
for index in elecStorage:
if index in list1:
break
else:
list1.append(index)
someNumber += 1
elecStorage[:] = []
break
Notes: Electives and Prereq both contain strings like "Calculus 1" (for prereq), or "Astronomy" (for elective.) The variables in dict2 are lists that contain class (as in classroom) names that were called earlier by the function.
What the snippet that starts out with "for key, dlist in dict2.items()" should do is search through the the elements of the first list, checking first if there is a list, if there isn't then append "Free Period" into the list. Then it should check if any of the elements of the list exist in prereq, and finally if there isn't, append something from electives into it. (Because if it gets past the first condition, it's safe to assume there is at least an elective.) and then loop back around and perform the same operation to the next list of elements.
Issue is, unless all of the lists contain nothing, it won't append 'Free Period' and I can't figure out why.
Ideas?

Something in your SEM*period* is likely returning an empty list, and not None. The correct checks for empty list '[]', is 'if list1 == []' or 'if len(list1) == 0'.
None is placeholder meaning a non-existing object. [] is a valid list object, it just has no entries in the list. 'if not foo' is simply checking for None, not an empty list.

You should verify the contents of your SEM2period variables, this is hard to diagnose without them. I didn't follow the rest of your logic, but it's really just the first block in the loop that you are interested in, yes? You may have a list containing an empty list, perhaps? That would mess up your logic:
d2 = {1:['elec'], 2:[]}
for key, dlist in d2.items():
if not dlist:
print 'empty!'
else:
print dlist
gives you
['elec']
empty!
but
d2 = {1:['elec'], 2:[[]]}
for key, dlist in d2.items():
if not dlist:
print 'empty!'
else:
print dlist
gives you
['elec']
[[]]

Related

list of list comparing

I want to compare the amount of values in a list of a list.
If there would be an empty list in the one of the "sub" lists, it should print "too short".
If the list is long enough, meaning that it has more or 1 value in it, it should print "good". how can I do this?
No library imports please.
You can iterate through the sub-lists and check for len, or just for falsey for empty lists as Python evaluates [] as False.
lists = [[1,2],[],[3,4,5]]
for l in lists:
if len(l) < 1: #or just `if not l:`
print('too short')
else:
print('good')
You need to iterate each element in the list and compare the length using the len function.
Please see sample code below:
#list with one element sublist and 3 element sublist
a = [[1],[3,4,5]]
for index_length in a:
if len(index_length) > 1:
print("Good")
else:
print("too short")
Output:
Reference:
https://www.geeksforgeeks.org/how-to-get-the-number-of-elements-in-a-python-list/#:~:text=Using%20Len()%20function%20to,elements%20present%20in%20the%20list.

How to do something else at the end of an iteration

I have a list that contains some strings , I want to add some predefined values before every string in a list but the value at the end of the iteration should be different
Here is the list
lst = ['USER_INVITE','USER_LEAVE','GIVEAWAY_START','GIVEAWAY_EDIT','USER_INVITE','USER_LEAVE']
the expected output is
<:878677713269968896:909470525108154399> USER_INVITE
<:878677713269968896:909470525108154399> USER_LEAVE
<:878677713269968896:909470525108154399> GIVEAWAY_START
<:878677713269968896:909470525108154399> GIVEAWAY_EDIT
<:878677713269968896:909470525108154399> USER_INVITE
<:878677686350934027:910454682219085834> USER_LEAVE
here you can see the value before USER_LEAVE is different than others
I can simply do something like this to put these values before strings without a loop
logs = '<:878677713269968896:909470525108154399>\n'.join(map(str,keys[I]))
maybe iteration will help in this case by doing something else at the end of the loop
Using iteration, and some control flow logic around identifying the last item in the list, this can be done as follows:
output_str = ""
for i, item in enumerate(lst):
if i == len(lst) - 1: # Logic for identifying the last element
prefix = '<:878677686350934027:910454682219085834>'
else: # If not the last element in the list, do this:
prefix = '<:878677713269968896:909470525108154399>'
output_str += f'{prefix} {item}\n'
output_str = ""
for item in lst[:-1]:
output_str += f'<:878677686350934027:910454682219085834> {item}\n'
output_str += f'<:878677713269968896:909470525108154399> {lst[-1]}'
You can just work on every key but the last and then combine the output at the end.
a = "\n".join('<:878677713269968896:909470525108154399>' + key for key in lst[:-1])
b = '<:878677686350934027:910454682219085834>' + lst[-1]
a + b
'<:878677713269968896:909470525108154399>USER_INVITE\n<:878677713269968896:909470525108154399>USER_LEAVE\n<:878677713269968896:909470525108154399>GIVEAWAY_START\n<:878677713269968896:909470525108154399>GIVEAWAY_EDIT\n<:878677713269968896:909470525108154399>USER_INVITE<:878677686350934027:910454682219085834>USER_LEAVE'

check several lists with several for loops

keylist = ['A/P', 'A/Q', 'B/P', 'B/Q', 'C/P', 'C/Q']
List = ['A','B','C']
I want to make an Operation for every element in List and for every element in keylist :
for n in List:
for key in keylist:
if key.split('/')[0] == List[n] and key.split('/')[-1] == 'P':
try:
print(n) #placeholder
except:
pass
Basically, I want to check if the first split element of keylist is an element of List but the Output is an error:
TypeError: list indices must be integers or slices, not str
Because n you are using in List[n] is not an index to element in List.
for n in List: # here n is not the index to element in list but element itself.
for key in keylist: # so you can't use List[n] below e.g. n is 'A' in first iteration
if key.split('/')[0] == List[n] and key.split('/')[-1] == 'P':
try:
print(n) #placeholder
except:
pass
If you need index of element in the list, use code as below.
for idx, ele in enumerate(List):
for key in keylist:
if key.split('/')[0] == List[idx] and key.split('/')[-1] == 'P':
try:
print(List[idx]) # or print(ele)
except:
pass
Here, ele == List[idx]
keylist = ['A/P', 'A/Q', 'B/P', 'B/Q', 'C/P', 'C/Q']
List = ['A','B','C']
for n in List:
for key in keylist:
if ((key.split('/')[0] in List) and (key.split('/')[1] == 'P')):
try:
print(n) #placeholder
except:
pass
Keeping with the Zen of Python.
Flat is better than nested
for key in keylist:
s = key.split('/')
if s[0] in List and s[-1] == 'P':
try:
print(s[0]) #placeholder
except:
pass
This will work as long as the elements in List are unique. Your algorithm will duplicate outputs for duplicates in List. This algorithm will not.

Basic Python looping and appending

Write a program that takes a list and prints a message for each element in the list, based on that element's data type.
Your program input will always be a list. For each item in the list, test its data type. If the item is a string, concatenate it onto a new string. If it is a number, add it to a running sum. At the end of your program print the string, the number and an analysis of what the array contains. If it contains only one type, print that type, otherwise, print 'mixed'.
So the above is what I am trying to accomplish. And I am extremely new to all this so sorry if I don't make sense at times. Right now I am just trying to set up running through my list and appending any str to string list, and any int to my num list. Ive tried tons of ways and read documentation, and tried to search for help but I am either misreading stuff or just searching the wrong stuff. any help would be greatly appreciated.
stuff = ['magical unicorns',19,'hello',98.98,'world']
string = []
num = []
for i in range(len(stuff)):
if isinstance(i,str):
string.append(value,i)
if isinstance(i,int):
num.append(i)
print (string)
print (num)
You can use list comprehension for a quick, concise solution:
stuff = ['magical unicorns',19,'hello',98.98,'world']
s = ''.join(i for i in stuff if isinstance(i, str))
a = sum(i for i in stuff if isinstance(i, int) or isinstance(i, float))
print(s)
print(a)
if len(s) > 0 and a > 0:
print("mixed")
elif len(s) > 0 and a == 0:
print("string")
elif len(s) == 0 and a > 0:
print("integer")
Output:
magical unicornshelloworld
19
mixed
for i in range(len(stuff))
This will iterate over the indexes of your lists. So, you will only append this indexes to your list num.
Do the same loop but replace for i in range(len(stuff)) by for i in stuff. With this, you will iterate over your list elements.
stuff = ['magical unicorns',19,'hello',98.98,'world']
string = []
num = []
for i in stuff:
if isinstance(i,str):
string.append(i)
if isinstance(i,int):
num.append(i)
print (string)
print (num)
Think about python for loops as foreach loops in other languages. So we want to iterate over each item in the stuff list.
We then want to make running totals of the strings and numbers.
Here is a simple loop which accomplishes this :)
from numbers import Number
stuff = ['magical unicorns',19,'hello',98.98,'world']
running_string = ''
running_total = 0
for item in stuff:
if isinstance(item, basestring):
running_string += item
if isinstance(item, Number):
running_total += item
print running_total
print running_string
if running_string and running_total:
print 'mixed'
elif running_string:
print 'string'
elif running_total:
print 'int'
else:
print 'empty'
This should do the trick.
stuff = ['magical unicorns',19,'hello',98.98,'world']
s = ""
num = 0
hasnum = False
hasstr = False
for i in stuff:
if isinstance(i, str):
s += i
hasstr = True
if isinstance(i, int):
num += i
hasnum = True
print (string)
print (num)
if hasnum and not hasstr:
print "Only ints"
elif hasstr:
print "Only strs"
else:
print "Mixed"

Reference next item in list: python

I'm making a variation of Codecademy's pyglatin.py to make a translator that accepts and translates multiple words. However, I'm having trouble translating more than one word. I've been able to transfer the raw input into a list and translate the first, but I do not know how to reference the next item in the list. Any help would be greatly appreciated.
def piglatin1():
pig = 'ay'
original = raw_input('Enter a phrase:').split(' ')
L = list(original)
print L
i = iter(L)
item = i.next()
for item in L:
if len(item) > 0 and item.isalpha():
word = item.lower()
first = word
if first == "a" or first == "e" or first == "i" or first == "o" or first =="u":
new_word = word + pig
print new_word
else:
new_word = word[1:] + word[0:1] + pig
# first word translated
L = []
M = L[:]
L.append(new_word)
print L # secondary list created.
again = raw_input('Translate again? Y/N')
print again
if len(again) > 0 and again.isalpha():
second_word = again.lower()
if second_word == "y":
return piglatin()
else:
print "Okay Dokey!"
else:
print 'Letters only please!'
return piglatin1()
I was working on this problem recently as well and came up with the following solution (rather than use range, use enumerate to get the index).
for index, item in enumerate(L):
next = index + 1
if next < len(L):
print index, item, next
This example shows how to access the current index, the current item, and then the next item in the list (if it exists in the bounds of the list).
Here are a few things to note that might help.
The lines i = iter(L) and item = i.next() are unnecessary. They have no effect in this method because you are redefining item immediately afterwards in the line for item in L. Go ahead and comment out those two lines to see if it makes any changes in your output.
The looping construct for item in L will go once over every item in the list. Whatever code you write within this loop will be executed once for each item in the list. The variable item is your handle to the list element of an iteration.
If, during any iteration, you really do want to access the "next" element in the list as well, then consider using a looping construct such as for i in range(0,len(L)). Then L[i] will be the current item and L[i+1] will you give the subsequent item.
There are some slight issues with the code but I think there is one main reason why it will not repeat.
In order to process the entire string the
again = raw_input('Translate again? Y/N')
and it's succeeding lines should be brought outside the for statement.
Also you appear to be setting L to an empty string inside the loop:
L = []
The following is a modified version of your code which will loop through the entire sentence and then ask for another one.
def piglatin():
pig = 'ay'
while True:
L = raw_input('Enter a phrase:').split(' ')
M = []
for item in L:
if len(item) > 0 and item.isalpha():
word = item.lower()
first = word
if first == "a" or first == "e" or first == "i" or first == "o" or first =="u":
new_word = word + pig
print new_word
else:
new_word = word[1:] + word[0:1] + pig
M.append(new_word)
else:
print 'Letters only please!'
print M # secondary list created.
again = raw_input('Translate again? Y/N')
print again
if len(again) > 0 and again.isalpha():
second_word = again.lower()
if second_word == "n":
print "Okay Dokey!"
break
Changes made:
You don't need to cast the return of the split to a list. The split
return type is a list.
It isn't necessary to make an iterator, the for loop will do this for you.
I removed the function as the return type. I'm assuming you were attempting some form of recursion but it isn't strictly necessary.
Hope this helps.
Step by step:
If you set variable original in this way:
original = raw_input('Enter a phrase:').split()
it will be already a list, so need to additional assignment.
What is the purpose of these lines?
i = iter(L)
item = i.next()
In a loop, you assign variable to the word, when it is actually only the first letter of the word, so it’ll be better like this: first = word[0]
Then if you want to check if first is a vowel, you can just do:
if first in 'aeuoiy'
Answer to your actual question: do not assign L to an empty list!
If you want to repeat the action of a function, you can just call it again, no need to rewrite the code.

Categories

Resources