Using Linked lists and patterns in python - python

Trying to write a function that will iterate over the linked list, sum up all of the odd numbers and then display the sum. Here is what I have so far:
from List import *
def main():
array = eval(input("Give me an array of numbers: "))
ArrayToList(array)
print(array[0])
print(array[1])
print(array[2])
print(array[3])
print(sumOdds(array))
def isOdd(x):
return x % 2 != 0
def sumOdds(array):
if (array == None):
return 0
elif (isOdd(head(array))):
return head(array) + sumOdds(tail(array))
else:
return sumOdds(tail(array))
main()
I can't get it to actually print the sum though. Can anybody help me out with that?
Here is the output of the program when I run it:
$ python3 1.py
Give me an array of numbers: [11, 5, 3, 51]
Traceback (most recent call last):
File "1.py", line 22, in <module>
main()
File "1.py", line 10, in main
print(sumOdds(array))
File "1.py", line 19, in sumOdds
return head(array) + sumOdds(tail(array))
File "1.py", line 18, in sumOdds
elif (isOdd(head(array))):
File "/Users/~/cs150/practice3/friday/List.py", line 34, in head
return NodeValue(items)
File "/Users/~/cs150/practice3/friday/List.py", line 12, in NodeValue
def NodeValue(n): return n[0]
TypeError: 'int' object is not subscriptable

In Python you iterate through a list like this:
list_of_numbers = [1,4,3,7,5,8,3,7,24,23,76]
sum_of_odds = 0
for number in list_of_numbers:
# now you check for odds
if isOdd(number):
sum_of_odds = sum_of_odds + number
print(sum_of_odds)
List is also a module only on your computer. I do not know what is inside. Therefore, I can not help you after ArrayToList(array).

Related

How to call python function call subsequently

I have a python function which is working as expected when called first time.
as soon as i add another call it is errors out "IndexError: list index out of range"
import os
import re
import glob
LDIR="/data/reports/get-snapshots/labs"
PDIR="/data/reports/get-snapsnots/prod"
def get_latest_snap_files(path, *paths):
snap_path=os.path.join(path, *paths)
snap_file=sorted(glob.iglob(snap_path), key=os.path.getctime, reverse=True)
return snap_file[0]
def main():
l=get_latest_snap_files(LDIR, '*')
print(l)
p=get_latest_snap_files(PDIR, '*')
print(p)
main()
$python h.py
/data/reports/get-snapshots/labs/labs.snapshot.2019-05-25_184501-out.sorted.log
Traceback (most recent call last):
File "h.py", line 24, in <module>
main()
File "h.py", line 22, in main
p=get_latest_snap_files(PDIR, '*')
File "h.py", line 16, in get_latest_snap_files
print(snap_file[0])
IndexError: list index out of range
As per the #Chris_Rands's comment on your answer, snap_file is probably empty sometimes.
You should check that and return None when that happens.
import os
import re
import glob
LDIR="/data/reports/get-snapshots/labs"
PDIR="/data/reports/get-snapsnots/prod"
def get_latest_snap_files(path, *paths):
snap_path=os.path.join(path, *paths)
snap_file=sorted(glob.iglob(snap_path), key=os.path.getctime, reverse=True)
return None if len(snap_file) == 0 else snap_file[0]
def main():
l=get_latest_snap_files(LDIR, '*')
print(l)
p=get_latest_snap_files(PDIR, '*')
print(p)
main()

AttributeError: 'numpy.ndarray' object has no attribute 'convert' and error of IndexError: list index out of range

Attribute errors may have posted earlier however in my situation when I found a solution, I got another error stating that my list index was out of range. I am beginner in Python working on breaking an image captcha. I have used the code provided from here - How to remove line from captcha completely
Based on that I added few lines to run it
lineRemoval.py
from PIL import Image,ImageFilter
from scipy.misc import toimage
from operator import itemgetter
from skimage import measure
import numpy as np
import copy
import heapq
import cv2
import matplotlib.pyplot as plt
from scipy.ndimage.filters import median_filter
#----------------------------------------------------------------
class preprocessing:
def pre_proc_image(self,img):
#img_removed_noise=self.apply_median_filter(img)
img_removed_noise=self.remove_noise(img)
p1,p2,LL=self.get_line_position(img_removed_noise)
img=self.remove_line(p1,p2,LL,img_removed_noise)
img=median_filter(np.asarray(img),1)
return img
def remove_noise(self,img):
img_gray=img.convert('L')
w,h=img_gray.size
max_color=np.asarray(img_gray).max()
pix_access_img=img_gray.load()
row_img=list(map(lambda x:255 if x in range(max_color-15,max_color+1) else 0,np.asarray(img_gray.getdata())))
img=np.reshape(row_img,[h,w])
return img
def apply_median_filter(self,img):
img_gray=img.convert('L')
img_gray=cv2.medianBlur(np.asarray(img_gray),3)
img_bw=(img_gray>np.mean(img_gray))*255
return img_bw
def eliminate_zeros(self,vector):
return [(dex,v) for (dex,v) in enumerate(vector) if v!=0 ]
def get_line_position(self,img):
sumx=img.sum(axis=0)
list_without_zeros=self.eliminate_zeros(sumx)
min1,min2=heapq.nsmallest(2,list_without_zeros,key=itemgetter(1))
l=[dex for [dex,val] in enumerate(sumx) if val==min1[1] or val==min2[1]]
mindex=[l[0],l[len(l)-1]]
cols=img[:,mindex[:]]
col1=cols[:,0]
col2=cols[:,1]
col1_without_0=self.eliminate_zeros(col1)
col2_without_0=self.eliminate_zeros(col2)
line_length=len(col1_without_0)
dex1=col1_without_0[round(len(col1_without_0)/2)][0]
dex2=col2_without_0[round(len(col2_without_0)/2)][0]
p1=[dex1,mindex[0]]
p2=[dex2,mindex[1]]
return p1,p2,line_length
def remove_line(self,p1,p2,LL,img):
m=(p2[0]-p1[0])/(p2[1]-p1[1]) if p2[1]!=p1[1] else np.inf
w,h=len(img),len(img[0])
x=list(range(h))
y=list(map(lambda z : int(np.round(p1[0]+m*(z-p1[1]))),x))
img_removed_line=list(img)
for dex in range(h):
i,j=y[dex],x[dex]
i=int(i)
j=int(j)
rlist=[]
while i>=0:
f1=i
if img_removed_line[i][j]==0 and img_removed_line[i-1][j]==0:
break
rlist.append(i)
i=i-1
i,j=y[dex],x[dex]
i=int(i)
j=int(j)
while True:
f2=i
if img_removed_line[i][j]==0 and img_removed_line[i+1][j]==0:
break
rlist.append(i)
i=i+1
if np.abs(f2-f1) in [LL+1,LL,LL-1]:
rlist=list(set(rlist))
for k in rlist:
img_removed_line[k][j]=0
return img_removed_line
if __name__ == '__main__':
img = cv2.imread("captcha.png")
p = preprocessing()
imgNew = p.pre_proc_image(img)
cv2.imshow("Image", imgNew)
cv2.waitKey(0)
Initially when trying with the above code I was getting the error
Traceback (most recent call last):
File "lineRemoval.py", line 98, in <module>
imgNew = p.pre_proc_image(img)
File "lineRemoval.py", line 18, in pre_proc_image
img_removed_noise=self.remove_noise(img)
File "lineRemoval.py", line 25, in remove_noise
img_gray=img.convert('L')
AttributeError: 'numpy.ndarray' object has no attribute 'convert'
I searched and found the solution by changing my main function to this
if __name__ == '__main__':
image = cv2.imread("captcha.png")
img = Image.fromarray(image)
p = preprocessing()
imgNew = p.pre_proc_image(img)
cv2.imshow("Image", imgNew)
cv2.waitKey(0)
However after that my array is out of index
Traceback (most recent call last):
File "lineRemoval.py", line 98, in <module>
imgNew = p.pre_proc_image(img)
File "lineRemoval.py", line 20, in pre_proc_image
img=self.remove_line(p1,p2,LL,img_removed_noise)
File "lineRemoval.py", line 83, in remove_line
if img_removed_line[i][j]==0 and img_removed_line[i+1][j]==0:
IndexError: list index out of range
Cannot identify where the error lies, does the while condition need to be changed or was the previous change causing it or is it something else.
Update
I have changed the condition for the while loop however similar comes for the initial while loop condition of i>=0
lineRemoval.py
while i>=0:
f1=i
if img_removed_line[i][j]==0 and img_removed_line[i-1][j]==0:
break
rlist.append(i)
i=i-1
i,j=y[dex],x[dex]
i=int(i)
j=int(j)
while i<len(img_removed_line)-1:
f2=i
if img_removed_line[i][j]==0 and img_removed_line[i+1][j]==0:
break
rlist.append(i)
i=i+1
Error that is shown
Traceback (most recent call last):
File "lineRemoval.py", line 98, in <module>
imgNew = p.pre_proc_image(img)
File "lineRemoval.py", line 20, in pre_proc_image
img=self.remove_line(p1,p2,LL,img_removed_noise)
File "lineRemoval.py", line 73, in remove_line
if img_removed_line[i][j]==0 and img_removed_line[i-1][j]==0:
IndexError: list index out of range
Replace your second while loop in the function removed line with this code:
while i<len(img_remmoved_line)-1:
f2=i
if img_removed_line[i][j]==0 and img_removed_line[i+1][j]==0:
break
rlist.append(i)
i=i+1
You are increasing i at each iteration which after sometime breaks the index limit of the list. This condition protects the iteration of the loop if the value of i is bigger then index limit of that list.

Code runs in Python 3, not in Python 2

I am pretty new to Python and I am just doing a bunch of exercises.
This is one of them, a simple DiceRoller.
It works perfectly fine in ATOM, the issue arises when I try to run it in IDLE. I am unable to figure out why the issue happen. Pretty sure this is a noob question.
The code:
import random
dices=[2, 3, 4, 6, 8, 10, 12, 20, 100]
Y= ['yes', 'y']
N= ['no', 'n']
def DiceRoller():
dice_selection=input('Please, choose the dice(d2, d3, etc. - only the number): ')
try:
dice = int(dice_selection)
except ValueError:
print('You have to select a number, try again')
DiceRoller()
if dice not in dices:
print('You have to select a 2, 3, 4, 6, 8, 10, 12, 20, 100 faces dice, try again')
DiceRoller()
number=input('How many dice(s) do you want to roll? ')
try:
numint = int(number)
except ValueError:
print('You have to select a number, try again')
DiceRoller()
ripet=0
while ripet < numint:
ripet += 1
if dice in dices:
result=random.randint(1,dice)
print(result)
else:
Continue()
def Continue():
risposta=input('Do you want to roll again? (Y/N) ')
rispostal= risposta.lower()
if rispostal in Y:
DiceRoller()
elif rispostal in N:
return 'Goodbye'
quit()
else:
print('Please, answer Yes or No')
Continue()
DiceRoller()
Errors whit IDLE after the program ask me if I want to roll again (input y or n):
Traceback (most recent call last):
File "E:\Corso Python\DiceRoller.py", line 44, in <module>
DiceRoller()
File "E:\Corso Python\DiceRoller.py", line 30, in DiceRoller
Continue()
File "E:\Corso Python\DiceRoller.py", line 33, in Continue
risposta=input('Do you want to roll again? (Y/N) ')
File "<string>", line 1, in <module>
NameError: name 'y' is not defined
Errors whit IDLE after the program ask me if I want to roll again (input Y or N):
Traceback (most recent call last):
File "E:\Corso Python\DiceRoller.py", line 44, in <module>
DiceRoller()
File "E:\Corso Python\DiceRoller.py", line 30, in DiceRoller
Continue()
File "E:\Corso Python\DiceRoller.py", line 34, in Continue
rispostal= risposta.lower()
AttributeError: 'list' object has no attribute 'lower'
Thank you for your patience!
That's because in the atom editor, you use python3 and your IDLE uses python2. In Python 2, the function for reading user's input was called raw_input(); it was renamed to input() in Python 3 (section starting with PEP 3111: raw_input() was renamed to input()).
You can either ensure you are using python3 by default or make the code python2-compatible: add a code block
import sys
compatible_input = raw_input if sys.version_info < (3, 0) else input
and replace all usages of ... = input(...) in your code with ... = compatible_input(...).

Python: Unable to add a new key:value to a dictionary

I am making a dictionary for storing tests and their grades for different students.
def tests():
test1 = {'craig':88, 'jeanie':100}
test2 = {'craig':85, 'jeanie':95}
test3 = {'craig':80, 'jeanie':98}
return test1,test2,test3
def actions(test1,test2,test3):
test1.update({'john':95})
test1.update({'chris':92})
test1.update({'charles',100})
test2.update({'john':100})
test2.update({'chris':96})
test2.update({'charles',98})
test3.update({'john':97})
test3.update({'chris':100})
test3.update({'charles',94})
return test1,test2,test3
def main():
one,two,three = tests()
one,two,three = actions(one,two,three)
print (test1,test2,test3)
main()
However, when I try to append a new key:value to my dicts two errors come up:
First:
Traceback (most recent call last):
File "C:\file.py", line 26, in <module>
main()
File "C:\file.py", line 24, in main
one,two,three = actions(one,two,three)
File "C:\file.py", line 14, in actions
test1.update({'charles',100})
TypeError: cannot convert dictionary update sequence element #0 to a sequence
Second:
Traceback (most recent call last):
File "C:\file.py", line 26, in <module>
main()
File "C:\file.py", line 24, in main
one,two,three = actions(one,two,three)
File "C:\file.py", line 14, in actions
test1.update({'charles',100})
ValueError: dictionary update sequence element #0 has length 7; 2 is required
If I run it over and over again, sometimes the first error comes up, sometimes the other.
I do not want any imports such as collections.
test1.update({'charles',100})
is updating the dict with a set not a dict, which it clearly cannot use to update ... instead of sets pass it dicts
test1.update({'charles':100})
just to demonstrate
{1,2,3,4,4,5,6} # a set that will contain 1,2,3,4,5,6
{1:2,3:4,4:5} # a dict with 3 elements dict(1=2,3=4,4=5)
If I understand your need you need add new values not update and for that operation you need change update for setdefault method. I have tested on Aptana Studio that code:
def tests():
test1 = {'craig':88, 'jeanie':100}
test2 = {'craig':85, 'jeanie':95}
test3 = {'craig':80, 'jeanie':98}
return test1,test2,test3
def actions(test1,test2,test3):
test1.setdefault('john',95)
test1.setdefault('chris',92)
test1.setdefault('charles',100)
test2.setdefault('john',100)
test2.setdefault('chris',96)
test2.setdefault('charles',98)
test3.setdefault('john',97)
test3.setdefault('chris',100)
test3.setdefault('charles',94)
return test1,test2,test3
def main():
one,two,three = tests()
one,two,three = actions(one,two,three)
print(one,two,three)
main()
and get response:
one - {'john': 95, 'charles': 100, 'jeanie': 100, 'chris': 92, 'craig': 88}
two - {'john': 100, 'charles': 98, 'jeanie': 95, 'chris': 96, 'craig': 85}
three - {'john': 97, 'charles': 94, 'jeanie': 98, 'chris': 100, 'craig': 80}
Your problem is that update search one dictionary with key for update your value and not insert but setdefault insert new pair key:value with that syntax case not exists and return the value for one key case her exists.
Good work for you,
See answer here:
Add new keys to a dictionary?
To update:
#### Inserting/Updating value ####
data['a']=1 # updates if 'a' exists, else adds 'a'
# OR #
data.update({'a':1})
# OR #
data.update(dict(a=1))
# OR #
data.update(a=1)
# OR #
data.update([(a,1)])
Instead of this:
test3.update({'charles',94})

Learning Python, scripts for other project

Question: I am having some issues with my old scripts that do not work on Python 3.x
Offtopic; how flexible is Python when trying to access binary and text files for mass renaming, renumbering? within Collision and IMG archives?
I do not have the best understanding of this anymore as I have gone the direction of Level design using 3dsmax.
Anyway..
Error:
Traceback (most recent call last):
File "C:\SOL_REM.py", line 26, in <module>
process_ide(sys.argv[1], int(sys.argv[2]),
File "C:\SOL_REM.py", line 18, in process_ide
ide_line = reduce(lambda x,y: str(x)+","+st
NameError: global name 'reduce' is not defined
Code:
import sys
if len(sys.argv) < 4:
sys.exit('Usage: Source ide | ID number | Dest ide filename.' sys.argv[0])
def process_ide(ide_source, num, ide_destination):
src = open(ide_source,'r')
dst = open(ide_destination,'w')
for line in src:
ide_line = line
if not (line == "" or line[0]=="#" or len(line.split(",")) < 2):
ide_line = line.split(",")
ide_line[-1] = ide_line[-1][:-2]
ide_line[0] = num
num+=1
ide_line = reduce(lambda x,y: str(x)+","+str(y), ide_line)+"\n"
dst.write(ide_line)
src.close()
dst.close()
process_ide(sys.argv[1], int(sys.argv[2]), sys.argv[3])
Starting out simple:
What I am trying to do is parse an ide text file by changing numbers in enumerate order.
Syntax would be SOL_rem.py game.ide 1845 game2.ide
Example file:
ID Modelname TexName Rendering flags.
objs
1700, ap_booth2_03, ap_airstuff1, 1, 190, 0
1701, ap_seaplaland1, ap_seasplane, 1, 299, 0
1702, ap_seaplanehanger1, ap_seasplane, 1, 299, 0
1703, ap_termwindows1, ap_termwindows, 1, 299, 4
1704, ap_blastdef_01, ap_newprops1opac, 1, 299, 4
1705, ap_blastdef_03, ap_newprops1opac, 1, 299, 4
1706, air_brway_030, airgrndb, 1, 299, 0
end
The IDs would be re-adjusted from 1845 in ascending order.
reduce is no longer in the builtin namespace in Python 3.
Instead of using reduce, why not just use a join?
ide_line = ','.join(ide_line) + '\n'
In Python3, you can do
from functools import reduce
And even in Python2.6+ the above should be okay, but is not required.
Yes. Python is totally flexible for whatever you want to do. Like overriding builtins too.

Categories

Resources