Pop from Empty list error - python

I am trying to push elements from a list to a stack. Here is the code:
#!/usr/bin/python
class Stack :
def __init__(self) :
self.items = []
def push(self, item) :
self.items.append(item)
def pop(self) :
return self.items.pop()
def isEmpty(self) :
if self.items == []:
return true
def InsertIntostacks(lst1):
X = Stack() #for each expression a stack is defined
Y = Stack()
for words in lst1:
if (ord(words) >= 48 and ord(words) <= 57) or (ord(words) >=65 and ord(words) <= 90):
X.push(words)
else:
Y.push(words)
print X.pop()
if __name__ == '__main__':
a = open("testinput1.txt","r+")
wordList = [line.strip() for line in a];
#print wordList[1]
lst=list()
for words in wordList:
if words == '#':
print "End of file"
else:
lst = list(words)
lst1 = list()
print lst
for x1 in lst:
if x1 != ' ':
lst1.append(x1)
InsertIntostacks(lst1)
So X is getting populated and I need Y to contain the operators, but apparently none of the elements are getting in Y ( input like A=B=C, so Y should contain = = ).
If i remove the constraints and just push all the elements in one stack the operators are there.
What am I doing wrong here?

I suspect maybe your indentation is wrong for InsertIntostacks(lst1), and that's the problem.
Try ensuring that InsertIntostacks(lst1) is properly aligned with the for loop, meaning it executes after the loop, not within it. Right now it's executing during every iteration of the loop, including the first one, where lst is indeed empty.

Related

finding the longest common prefix of elements inside a list

I have a sequence print(lcp(["flower","flow","flight", "dog"])) which should return fl. Currently I can get it to return flowfl.
I can locate the instances where o or w should be removed, and tried different approaches to remove them. However they seem to hit syntax issue, which I cannot seem to resolve by myself.
I would very much appreciate a little guidance to either have the tools to remedy this issue my self, or learn from a working proposed solution.
def lcp(strs):
if not isinstance(strs, list) or len(strs) == 0:
return ""
if len(strs) == 1:
return strs[0]
original = strs[0]
original_max = len(original)
result = ""
for _, word in enumerate(strs[1:],1):
current_max = len(word)
i = 0
while i < current_max and i < original_max:
copy = "".join(result)
if len(copy) and copy[i-1] not in word:
# result = result.replace(copy[i-1], "")
# result = copy[:i-1]
print(copy[i-1], copy, result.index(copy[i-1]), i, word)
if word[i] == original[i]:
result += word[i]
i += 1
return result
print(lcp(["flower","flow","flight", "dog"])) # returns flowfl should be fl
print(lcp(["dog","car"])) # works
print(lcp(["dog","racecar","car"])) # works
print(lcp([])) # works
print(lcp(["one"])) # works
I worked on an alternative which does not be solve removing inside the same loop, adding a counter at the end. However my instincts suggest it can be solved within the for and while loops without increasing code bloat.
if len(result) > 1:
counter = {char: result.count(char) for char in result}
print(counter)
I have solved this using the below approach.
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
N = len(strs)
if N == 1:
return strs[0]
len_of_small_str, small_str = self.get_min_str(strs)
ans = ""
for i in range(len_of_small_str):
ch = small_str[i]
is_qualified = True
for j in range(N):
if strs[j][i] != ch:
is_qualified = False
break
if is_qualified:
ans += ch
else:
break
return ans
def get_min_str(self, A):
min_len = len(A[0])
s = A[0]
for i in range(1, len(A)):
if len(A[i]) < min_len:
min_len = len(A[i])
s = A[i]
return min_len, s
Returns the longest prefix that the set of words have in common.
def lcp(strs):
if len(strs) == 0:
return ""
result = strs[0]
for word in strs[1:]:
for i, (l1, l2) in enumerate(zip(result, word)):
if l1 != l2:
result = result[:i]
break
else:
result = result[:i+1]
return result
Results:
>>> print(lcp(["flower","flow","flight"]))
fl
>>> print(lcp(["flower","flow","flight", "dog"]))
>>> print(lcp(["dog","car"]))
>>> print(lcp(["dog","racecar","car"]))
>>> print(lcp([]))
>>> print(lcp(["one"]))
one
>>> print(lcp(["one", "one"]))
one
You might need to rephrase your goal.
By your description you don't want the longest common prefix, but the prefix that the most words have in common with the first one.
One of your issues is that your tests only test one real case and four edgecases. Make some more real examples.
Here's my proposition: I mostly added the elif to check if we already have a difference on the first letter to then discard the entry.
It also overwrites the original to rebuild the string based on the common prefix with the next word (if there are any)
def lcp(strs):
if not isinstance(strs, list) or len(strs) == 0:
return ""
if len(strs) == 1:
return strs[0]
original = strs[0]
result = ""
for word in strs[1:]:
i = 0
while i < len(word) and i < len(original) :
if word[i] == original[i]:
result += word[i]
elif i == 0:
result = original
break
i += 1
original = result
result = ""
return original
print(lcp(["flower","flow","flight", "dog"])) # fl
print(lcp(["shift", "shill", "hunter", "shame"])) # sh
print(lcp(["dog","car"])) # dog
print(lcp(["dog","racecar","car"])) # dog
print(lcp(["dog","racecar","dodge"])) # do
print(lcp([])) # [nothing]
print(lcp(["one"])) # one

list.remove(x) x seems to be in list but not being found

So in VSCode, I'm receiving this error...
Given the input
2
21 22
We have variables saying
best_choice = '22'
a: ['21', '22']
However, a.remove(best_choice) returns an error.
I am completely confounded... please help.
I checked for this problem on stacks and found that remove() doesn't work when iterating through a list, so I changed my loop to while(True). However, I'm still receiving the same error.
Here is the code:
import sys
def best_option(a):
iterator = 0
while(len(a)>1):
previous_best_digit = 0
current_best_digit = 0
best_short_option = []
return_list = []
for item in a:
if len(item)-1 < iterator:
char_previous = item[iterator-1:iterator]
dig_previous = ord(char_previous)
previous_best_digit = dig_previous
best_short_option = item
continue
char = item[iterator:iterator+1]
dig = ord(char)
if dig > current_best_digit:
current_best_digit = dig
return_list.clear()
return_list.append(item)
elif dig == current_best_digit:
return_list.append(item)
if (current_best_digit < previous_best_digit):
return_list.clear()
return_list.append(best_short_option)
a = return_list
iterator+=1
return a
def largest_number(a):
#write your code here
res = ""
while (True):
best_choice = best_option(a)
print(best_choice)
a.remove(best_choice)
res += best_choice
if (len(a)==1):
break
res.append(a)
print(res)
return res
if __name__ == '__main__':
input = sys.stdin.read()
data = input.split()
a = data[1:]
print(largest_number(a))
It's purpose create a string with the greatest possible value from a list of strings.
your best_choice is ['22'], not '22'

Python: Failing to break out of while loop with "SyntaxError: 'break' outside loop"

I am developing a breadth-first-search algorithm for a factorization problem and am running into an interesting/confusing bug when attempting to break out of a while loop. If you run the code below, it will fail inside the "construct_path" method, stating :
File "main.py", line 96
break
SyntaxError: 'break' outside loop
but I am inside of a while loop! If anyone could give me some advice on this issue, I would really appreciate it. Thanks in advance.
from numpy import random
import itertools
import Queue
#Finding multiples, BFS problem
#Given input of list with unique integers 0 - 9 and n = range(0,1000000), calculate smallest multiple of n and unique combination of values in the list
#Example : Input : list = {0,1,2} , n = 3,
# output = 12
# Input : list = {0,1,2} , n = 50
# Output = 200
class Problem:
def __init__(self):
self.n = random.randint(0,10000000)
listSize = random.randint(1,9)
mainSet = set()
self.mainList = []
while True:
toAdd = random.randint(0,9)
if(toAdd not in self.mainList):
self.mainList.append(toAdd)
if(len(self.mainList) == listSize):
break
def get_start_state(self):
s = ''.join(map(str, self.mainList))
return int(s)
def is_goal(self, state):
return True
def get_sucessors(self):
print "Getting successors"
def breadth_first_search(problem):
# a FIFO open_set
open_set = Queue.Queue()
# an empty set to maintain visited nodes
closed_set = set()
# a dictionary to maintain meta information (used for path formation)
meta = dict() # key -> (parent state, action to reach child)
# initialize
start = problem.get_start_state()
meta[start] = (None, None)
open_set.put(start)
while not open_set.empty():
parent_state = open_set.get()
print "{} {}".format("parent_state is ", parent_state)
if problem.is_goal(parent_state):
return construct_path(parent_state, meta)
for (child_state, action) in problem.get_successors(parent_state):
if child_state in closed_set:
continue
if child_state not in open_set:
meta[child_state] = (parent_state, action)
open_set.put(child_state)
closed_set.add(parent_state)
#collect path to desired answer
def construct_path(state, meta):
action_list = list()
while True:
row = meta[state]
if (len(row) == 2):
state = row[0]
action = row[1]
action_list.append(action)
else:
break
return action_list.reverse()
x = Problem()
breadth_first_search(x)
Could be that you have a mix of tabs and spaces so that the break in line 96 looks like it is indented to be below action_list.append(action) but effectively it is below the while. That would explain the error at least.
It is just a guess. But it could be like this, using a visible tabwidth of 4 in the editor:
→ while True:
→ → row = meta[state]
if (len(row) == 2):
state = row[0]
action = row[1]
action_list.append(action)
else:
break
To the Python interpreter this looks like this (because it assumes a tabwidth of 8):
→ while True:
→ → row = meta[state]
if (len(row) == 2):
state = row[0]
action = row[1]
action_list.append(action)
else:
break
This is still valid but obviously means a different thing and would put your break outside of the while loop.

Python character math using stack

I received an interesting challenge in an algorithm Meetup. Given an input string, return a string in which all substrings within brackets have been replicated n times, where n is the integer outside the brackets. Characters outside brackets should simply be concatenated to the substring inside. For example:
2[ab] should return abab
a[3[bc]] should return abcbcbc
2[ab[cd]] should return abcdabcd
I've started implementing the solution using a stack, but I've got the feeling that my approach of checking each de-stacked character for a bracket is off, anyone have any suggestions? Code is below
class Stack:
def __init__(self):
self.items = []
def push(self, item):
self.items.append(item)
def pop(self):
return self.items.pop()
def length(self):
return len(self.items)
def is_number(s):
try:
int(s)
return True
except ValueError:
return False
def character_math(charstr):
final_output = ""
substring = ""
for i in charstr:
myStack.push(i)
for m in range(myStack.length() - 2):
destacked = myStack.pop()
# We want to go to the inner-most right bracket
if destacked != "]":
substring += destacked
if destacked == "[":
possible_multiplier = myStack.pop()
if is_number(possible_multiplier):
final_output += int(possible_multiplier) * substring
else:
final_output += possible_multiplier[::-1]
break
final_output += substring[::-1]
return "Final output is ", final_output
myStack = Stack()
# 3[ab[cd]] should return 'abcdabcd'
sample_str = '2[ab[cd]]'
print(character_math(sample_str))
The best way to do that is to use a recursive algorithm. The idea is to repeat a function until a condition is match. Here is the code I used, it works on your examples, and I don't think I forgot one of the possibilities.
# -*-coding:Utf-8 -*
Input = "2[ab[cd]]"
def Treatment(STR):
# Exit the treatment. That's the end condition.
if "[" not in STR:
return STR
# Find the inner [], in this case, the "cd" part
Bound1_ID = len(STR) - STR[::-1].index("[") - 1
Bound2_ID = STR.index("]")
# Separate STR into : First_part + middle between [] + Last_part
Last_part = STR[Bound2_ID + 1:]
# First_part depends if there is a number or not
try:
Multiplier = int(STR[Bound1_ID - 1])
First_part = STR[:Bound1_ID - 1]
except:
Multiplier = 1
First_part = STR[:Bound1_ID]
Middle_part = STR[Bound1_ID + 1: Bound2_ID] * Multiplier
# Assemble the new STR :
New_STR = First_part + Middle_part + Last_part
# Recursive command, repeat the function on the new STR
return Treatment(New_STR)
print (Treatment(Input))
EDIT : That's what it does :
First iteration : "2[ab[cd]]"
Second iteration : "2[abcd]"
Third iteration : abcdabcd => No more "[" so stop here.

python: taking the return of a function and using it in another function

Hi guys i got my code to work by putting everything in one function which is this
spam = ''
def enterList (names):
newList = []
while True:
names = raw_input('list a series of items and press blank when finished: ')
if names == '':
break
newList = newList + [names]
a = ''
finalText = ''
listOfStuff = []
item = 0
for i in newList:
if item < len(newList)-2:
a = (i + ', ')
listOfStuff.append(a)
item +=1
elif item == len(newList)-2:
a = (i + ' and ')
listOfStuff.append(a)
item +=1
else:
a = i
listOfStuff.append(a)
break
finalText = finalText.join(listOfStuff)
return finalText
print enterList(spam)
So the above code works as i want it to. However i was trying to do the same thing by having two separate functions, the issue that i was having was that i couldn't take the return value of one function and use it in the next function.
This is the old code
spam = ''
def enterList (names):
newList = []
while True:
names = raw_input('list a series of items and press blank when finished: ')
if names == '':
break
newList = newList + [names]
return newList
print enterList(spam)
def newFunc(Addand):
a = ''
finalText = ''
listOfStuff = []
item = 0
for i in spam:
if item < len(spam)-2:
a = (i + ', ')
listOfStuff.append(a)
item +=1
elif item == len(spam)-2:
a = (i + ' and ')
listOfStuff.append(a)
item +=1
else:
a = i
listOfStuff.append(a)
break
finalText = finalText.join(listOfStuff)
return finalText
newFunc(spam)
print newFunc (spam)
I'm not sure what I was doing wrong doing it this way.
Thanks for any help to get my head around the error with this approach.
In your first function make the return statement
return newFunc(newlist)
It's not working because the second function is never actually called.

Categories

Resources