I'm using the NumPy python library to run large-scale edits on a .csv file. I'm using this python code:
import numpy as np
def main():
try:
e,a,ad,c,s,z,ca,fn,ln,p,p2,g,ssn,cn,com,dob,doh,em = np.loadtxt('c:\wamp\www\_quac\carryover_data\SI\Employees.csv',delimiter=',',unpack=True,dtype='str')
x=0
dob = dob.split('/')
for digit in dob:
if len(digit) == 1:
digit = str('0'+digit)
dob = str(dob[2]+'-'+dob[0]+'-'+dob[1])
doh = doh.split('/')
for digit in doh:
if len(digit) == 1:
digit = str('0'+digit)
doh = str(doh[2]+'-'+doh[0]+'-'+doh[1])
for eID in e:
saveLine=eID+','+a[x]+','+ad[x]+','+c[x]+','+s[x]+','+z[x]+','+ca[x]+','+fn[x]+','+ln[x]+','+p[x]+','+p2[x]+','+g[x]+','+ssn[x]+','+cn[x]+','+com[x]+','+dob[x]+','+doh[x]+','+em[x]+'\n'
saveFile = open('fixedEmployees.csv','a')
saveFile.write(saveLine)
saveFile.close()
x+=1
except Exception, e:
print str(e)
main()
dob and doh contain a string, e.g. 4/26/2012 and I'm trying to convert these to mysql friendly DATE forms, e.g. 2012-04-26. The error that is printed when I run this script is
cannot set an array element with a sequence
It does not specify a line and so I don't know what this really means. I'm pretty new to python; I've checked other questions with this same error but I can't make sense of their code. Any help is very appreciated.
Try using zfill to reformat the date string so you can have a '0' before your '4'. (zfill pads a string on the left with zeros to fill the width.)
doh = '4/26/2012'
doh = doh.split('/')
for i, s in enumerate(doh):
doh[i] = s.zfill(2)
doh = doh[2]+'-'+doh[0]+'-'+doh[1]
# result: '2012-04-26'
As for the cannot set an array element with a sequence it would be helpful to know
where that is occurring. I'm guessing there is something wrong with structure of the array.
Ok, to solve it I had to do a couple things. After removing the try-except commands, I found out that the error was on line 5, the line with e,a,ad,c,s etc. I couldn't eliminate the problem until I simply copied the 2 columns I wanted to focus on only and made a new program for dealing with those.
Then I had to create a .txt instead of a .csv because Excel auto-formats the dates and literally changes the values before I can even touch them. There is no way around that, I've learned. You can't turn the date-auto-format off. A serious problem with excel. So here's my solution for this NumPy script (it changes the first column and keeps the second the same):
import numpy as np
def main():
dob,doh=np.loadtxt('temp.csv',
delimiter=',',
unpack=True,
dtype='str')
x=0
for eachDate in dob:
if any(c.isalpha() for c in eachDate):
newDate=eachDate
elif (eachDate == ''):
newDate=''
else:
sp = eachDate.split('/')
y=0
ndArray = ['','','']
for eachDig in sp:
if len(eachDig) == 1:
eachDig = str('0'+eachDig)
if y == 0:
ndArray[0] = eachDig
elif y == 1:
ndArray[1] = eachDig
elif y == 2:
ndArray[2] = eachDig
newDate=str(ndArray[2]+'-'+ndArray[0]+'-'+ndArray[1])
y=0
y+=1
print eachDate+'--->'+newDate
"""creates a .txt file with the edited dates"""
saveLine=str(newDate+','+doh[x]+'\n')
saveFile=open('__newTemp.txt','a')
saveFile.write(saveLine)
saveFile.close()
x+=1
main()
I then used Data->Import from text with "TEXT" format option in Excel to get the column into my .csv. I realize this is probably bulky and noobish but it got the job done :3
Related
Ayo, guys
Im started to learn python 2 days ago and started with simple Translator
My problem is:
I wanted to write "#" to the console, my values change, but I don't know how to achieve that "Toggle" effect, when when writing "#" is chekcing if language number 1 is enabled and I change it to language number 2 and vice versa, if Language number 2 is enabled then switch to Language number 1
I found a solution on the Internet by:
var = itertools.cycle(['1', '2']).__next__
However, I can't get langtoggle to give me values one by one
At the moment, I'm stuck on this moment, which gives me value number 2 and does not want to change it to value 1
Please tell me what am I doing wrong?
Thank you :)
import itertools
langtoggle = itertools.cycle(['eng', 'rus']).__next__
engstroke = 'ENGLISH > RUSSIAN'
russtroke = 'RUSSIAN > ENGLISH'
lstroke = engstroke
while True:
print (lstroke)
word = input('Введите слово: ')
if word == '#':
while True:
langtoggle()
if langtoggle() == 'eng':
lstroke = engstroke
if langtoggle() == 'rus':
lstroke = russtroke
break
to be honest, I need a solution what let me change to 1,2,3 and more values by same action so thats why I dont want to use boolean value for that problem
Also, I notice that "var()" cycling to next value even if im just checking this var in "if var() = 1"
that looks strange, but I dont understand a huge things in coding right now, so..
In your while block you're calling langtoggle() three times. Change this to be called only once.
Something like this:
import itertools
langtoggle = itertools.cycle(['eng', 'rus']).__next__
engstroke = 'ENGLISH > RUSSIAN'
russtroke = 'RUSSIAN > ENGLISH'
lstroke = eng
while True:
print (lstroke)
word = input('Введите слово: ')
if word == '#':
while True:
toggled = langtoggle()
if toggled == 'eng':
lstroke = engstroke
if toggled == 'rus':
lstroke = russtroke
break
This is your code but modified by setting toggled to the result of the first call to langtoggle(). Then the tests are looking at the value of toggled instead of separate calls they were making previously.
All,
I am trying to write a python script that will go through a crime file and separate the file based on the following items: UPDATES, INCIDENTS, and ARRESTS. The reports that I generally receive either show these sections as I have previously listed or by **UPDATES**, **INCIDENTS**, or **ARRESTS**. I have already started to write the following script to separate the files based on the following format with the **. However, I was wondering if there was a better way to check the files for both formats at the same time? Also, sometimes there is not an UPDATES or ARRESTS section which causes my code to break. I was wondering if there is a check I can do for this instance, and if this is the case, how can I still get the INCIDENTS section without the other two?
with open('CrimeReport20150518.txt', 'r') as f:
content = f.read()
print content.index('**UPDATES**')
print content.index('**INCIDENTS**')
print content.index('**ARRESTS**')
updatesLine = content.index('**UPDATES**')
incidentsLine = content.index('**INCIDENTS**')
arrestsLine = content.index('**ARRESTS**')
#print content[updatesLine:incidentsLine]
updates = content[updatesLine:incidentsLine]
#print updates
incidents = content[incidentsLine:arrestsLine]
#print incidents
arrests = content[arrestsLine:]
print arrests
You are currently using .index() to locate the headings in the text. The documentation states:
Like find(), but raise ValueError when the substring is not found.
That means that you need to catch the exception in order to handle it. For example:
try:
updatesLine = content.index('**UPDATES**')
print "Found updates heading at", updatesLine
except ValueError:
print "Note: no updates"
updatesLine = -1
From here you can determine the correct indexes for slicing the string based on which sections are present.
Alternatively, you could use the .find() method referenced in the documentation for .index().
Return -1 if sub is not found.
Using find you can just test the value it returned.
updatesLine = content.find('**UPDATES**')
# the following is straightforward, but unwieldy
if updatesLine != -1:
if incidentsLine != -1:
updates = content[updatesLine:incidentsLine]
elif arrestsLine != -1:
updates = content[updatesLine:arrestsLine]
else:
updates = content[updatesLine:]
Either way, you'll have to deal with all combinations of which sections are and are not present to determine the correct slice boundaries.
I would prefer to approach this using a state machine. Read the file line by line and add the line to the appropriate list. When a header is found then update the state. Here is an untested demonstration of the principle:
data = {
'updates': [],
'incidents': [],
'arrests': [],
}
state = None
with open('CrimeReport20150518.txt', 'r') as f:
for line in f:
if line == '**UPDATES**':
state = 'updates'
elif line == '**INCIDENTS**':
state = 'incidents'
elif line == '**ARRESTS**':
state = 'arrests'
else:
if state is None:
print "Warn: no header seen; skipping line"
else
data[state].append(line)
print data['arrests'].join('')
Try using content.find() instead of content.index(). Instead of breaking when the string isn't there, it returns -1. Then you can do something like this:
updatesLine = content.find('**UPDATES**')
incidentsLine = content.find('**INCIDENTS**')
arrestsLine = content.find('**ARRESTS**')
if incidentsLine != -1 and arrestsLine != -1:
# Do what you normally do
updatesLine = content.index('**UPDATES**')
incidentsLine = content.index('**INCIDENTS**')
arrestsLine = content.index('**ARRESTS**')
updates = content[updatesLine:incidentsLine]
incidents = content[incidentsLine:arrestsLine]
arrests = content[arrestsLine:]
elif incidentsLine != -1:
# Do whatever you need to do to files that don't have an arrests section here
elif arreststsLine != -1:
# Handle files that don't have an incidents section here
else:
# Handle files that are missing both
Probably you'll need to handle all four possible combinations slightly differently.
Your solution generally looks OK to me as long as the sections always come in the same order and the files don't get too big. You can get real feedback at stack exchange's code review https://codereview.stackexchange.com/
So, I'm brand new to programming, and this is frustrating me! What I want to do is be able to import a 4x8 text file, and turn the text into a 2D list so that I can swap two characters. For example, if the imported text file looks like this:
OOOOOOOO
OOOXOOOO
OOOOOOOO
OOOOOOOO
then I would like to be able to change the position of the X (the row/column location) when user input is entered, such that an O will get put in its place to preserve formatting. So, for exapmle, the program will prompt the user for their input and if the user enters "up," then the X will move one space up.
OOOXOOOO
OOOOOOOO
OOOOOOOO
OOOOOOOO
I want it to repeatedly prompt for a new move after each time one is made, and display the new grid each time (so you can see the X in its new position each time you enter a movement).
This is all I have so far. I know I need to first find the X, but I really don't know how to. I'm stuck here. Any help is appreciated.
#Global variables for the movements
UP = 8
DOWN = 2
RIGHT = 6
LEFT = 4
#Dimensions of grid
ROWS = 4
COLUMNS = 8
def start():
filename = input("Enter the name of the Start Positions file: ")
textFile = open(filename)
aMaze = [line.strip() for line in textFile]
for r in range(ROWS):
for c in range(COLUMNS):
print(aMaze[r][c], end="")
print()
def moveType():
while (True):
try:
move = input("ENTER YOUR MOVE: ")
except ValueError:
print("unimportant error message")
continue
if ((int(move)) in (DOWN, LEFT, RIGHT, UP)):
playerMove(move)
continue
else:
print("unimportant error message")
continue
return(move)
def playerMove(move):
move = (int(move))
if (move == DOWN):
#need help here
elif (move == UP):
#and here
elif (move == LEFT):
#don't know what i'm doing
elif (move == RIGHT):
#also here
start()
moveType()
This is a perfect opportunity to learn about abstraction. To solve your problem, think about the sub problems you could solve (with functions) that would make your final problem easier.
In your specific instance, wouldn't it be easier to write a program to find the Cartesian coordinates of where X is? With an (x,y) coordinate, you could then make a function to turn that coordinate (likely stored as a tuple) into a 2d array where that coordinate is an X an everything else is a zero.
Hint 1:
x =0
y =0
for row in numrows:
for col in numcols:
if array[row][col] == X
y = row
x = col
Hint 2:
for row in numrows:
for col in numcols:
if col is x and row is y:
place X
else:
place O
Note: if this were an application where you wanted to eek out every bit of performance, you certainly would not need to iterate through your array every time to find X. You could (and should) opt to store the location of X and then use two accesses into your array to flip X's and O's. But seeing as this is likely one of your first problems you are solving this is of course not a concern.
Hope this helps! Good luck starting to code!
Ok guys, I am using python to try to complete a task. In short, I need to read in a number from a text file that can be thousands of digits long. I'm getting this error as I try to take the digits from the string and cast them to integers so I can do some math with them.
of = open("input.txt","r")
counter = 0
big=0
of.seek(0,0)
while True:
temp = of.read(5)
if temp=="":
break
else:
a=int(temp[0])
b=int(temp[1])
c=int(temp[2])
d=int(temp[3])
e=int(temp[4])
if a*b*c*d*e>big:
big = a*b*c*d*e
counter+=1
of.seek(counter,0)
print big
of.close()
I'm really stuck on this one so any help much appreciated.
Thanks in advance.
EDIT==============================================================
After tinkering around a bit I finally got the code to run correctly. Here's what I ended with:
x = int(open("input.txt","r").read())
y = str(x)
big = 0
for i in range(0,len(y)-5):
a = int(y[i])
b = int(y[i+1])
c = int(y[i+2])
d = int(y[i+3])
e = int(y[i+4])
if a*b*c*d*e>big:
big = a*b*c*d*e
print big
thanks for the help
Python supports long integers so if the file is just one big integer you can read it like this:
bignum=int(open("input.txt","r").read())
Your indentation is wrong; if-else should be nested inside the while loop.
I have written a code for detecting the EOF of an excel file using python:
row_no = 1
while True:
x = xlws.Cells(row_no,1).value
if type(x) is None:
break
else:
print(len(x))
print(x)
row_no = row_no + 1
i expect the while loop will stop then x becomes a "blank cell", which I support to be None, but it doesn't work, and it go to len(x) and prompt me an error of NoneType has no len. Why?
Thanks!
This here is your problem:
if type(x) is None:
If x is None, its type is NoneType. Therefore, this is never true, so you never see the blank cell and you end up trying to get the length of None.
Instead, write:
if x is None:
It looks like you are using pywin32com ... you don't need to loop around finding "EOF" (you mean end of Sheet, not end of File).
If xlws refers to a Worksheet object, you can use this:
used = xlws.UsedRange
nrows = used.Row + used.Rows.Count - 1
to get the effective number of rows in the worksheet. used.Row is the 1-based row number of the first used row, and the meaning of used.Rows.Count should be rather obvious.
Alternative: use xlrd ... [dis]claimer: I'm the author.
As mentioned in other comments you can use 'xlrd' as well to know the limits of the excel file as:
workbook = xlrd.open_workbook (excel_loc)
excel_sheet = workbook.sheet_by_index(0)
print("no of rows: %d" %excel_sheet.nrows)
print("no of cols: %d" %excel_sheet.ncols)