outlook = Dispatch("Outlook.Application")
mapi = outlook.GetNamespace("MAPI")
your_folder = mapi.Folders['email#outlook.com'].Folders['Blah']
blah_inbox = your_folder.Items
f = open("email_txt.csv", "w")
for message in blah_inbox:
if message.Class == 43:
if message.SenderEmailType == 'EX':
print(message.Sender.GetExchangeUser().PrimarySmtpAddress)
f.write(message.Sender.GetExchangeUser().PrimarySmtpAddress)
else:
print(message.SenderEmailAddress)
I opened a new fie and wrote it to a csv, but I get the following result.
user1#outlook.comuser2#outlook.comuser3#outook.com.....
However, I need the result to be like the below
user1#outlook.com
user2#outlook.com
user3#outlook.com
The Simple solution is the following
f = open("email_txt.csv", "w")
for message in blah_inbox:
if message.Class == 43:
if message.SenderEmailType == 'EX':
print(message.Sender.GetExchangeUser().PrimarySmtpAddress)
f.write(message.Sender.GetExchangeUser().PrimarySmtpAddress + '\n')
else:
print(message.SenderEmailAddress)
I added a "\n" to the end of the write command
Alternatively, since my whole intention was to save in a CSV with some sort of headers. Below is what worked for me. This is the entire code.
Todays_Mail = dt.datetime.now() - dt.timedelta(hours=24)
Todays_Mail = Todays_Mail.strftime('%m/%d/%Y %H:%M %p')
# Connect to Outlook inbox
outlook = Dispatch("Outlook.Application")
mapi = outlook.GetNamespace("MAPI")
your_folder = mapi.Folders['email'].Folders['Blah']
blah_inbox = your_folder.Items
blah_inbox = blah_inbox.Restrict("[ReceivedTime] >= '" + Todays_Mail + "'")
f = open("email.csv", "w")
f.write('Emails,Index\n')
index = 0
for message in blah_inbox:
if message.Class == 43:
if message.SenderEmailType == 'EX':
print(message.Sender.GetExchangeUser().PrimarySmtpAddress)
f.write(message.Sender.GetExchangeUser().PrimarySmtpAddress + ',' + str(index) + '\n')
index = index + 1
else:
print(message.SenderEmailAddress)
f.close()
The above will give you two columns, one with the header Email, and the second would be a column with the header Index.
i want save all numbers at subject in next row but only save 1 row only. the "number" still showing when print them but excel file (1.xlsx) only save only first number at A1
def read_email_from_gmail():
workbook = xlsxwriter.Workbook('1.xlsx')
worksheet = workbook.add_worksheet()
column = 0
row = 0
mail = imaplib.IMAP4_SSL('imap.yandex.com')
mail.login('myemail','password')
mail.select('inbox')
result, data = mail.search(None, 'SUBJECT "New"')
mail_ids = data[0]
id_list = mail_ids.split()
first_email_id = int(id_list[0])
latest_email_id = int(id_list[-1])
for i in range(latest_email_id,first_email_id, -1):
# need str(i)
result, data = mail.fetch(str(i), '(RFC822)' )
for response_part in data:
if isinstance(response_part, tuple):
# from_bytes, not from_string
msg = email.message_from_bytes(response_part[1])
email_subject = msg['subject']
if (email_subject.find('#') != -1):
number = email_subject.split("#")[1]
worksheet.write(row, column, number)
row += 1
workbook.close()
else:
print ("no have Number")
email_from = msg['from']
print ('From : ' + email_from + '\n')
print ('Subject : ' + email_subject + '\n')
print ('Number : ' + number + '\n')
# nothing to print here
read_email_from_gmail()
The program is closing the xlsx file directly after it writes to it:
if (email_subject.find('#') != -1):
number = email_subject.split("#")[1]
worksheet.write(row, column, number)
row += 1
workbook.close()
You should move the close() out of the loops to the same level that you created the file with xlsxwriter.Workbook().
from geopy.geocoders import Nominatim
import openpyxl
wb = openpyxl.load_workbook('#######.xlsx')
ws = wb.active
geolocator = Nominatim(timeout=60)
for i in range(2,1810):
count1 = 0
count2 = 1
address = str(ws['B'+str(i)].value)
city = str(ws['C'+str(i)].value)
state = str(ws['D'+str(i)].value)
zipc = str(ws['F'+str(i)].value)
result = None
iden1 = address + ' ' + city + ' ' + state
iden2 = city + ' ' + zipc + ' ' + state
iden3 = city + ' ' + state
print(iden1, iden2, iden3)
print(geolocator.geocode(iden2).address)
try:
location1 = geolocator.geocode(iden1)
except:
pass
try:
location2 = geolocator.geocode(iden2)
except:
pass
try:
location3 = geolocator.geocode(iden3)
except:
pass
count = None
try:
county1 = str(location1.address)
county1_list = county1.split(", ")
#print(county1_list)
for q in county1_list:
if 'county' in q.lower():
if count == None:
count = q
except:
pass
try:
county2 = str(location2.address)
county2_list = county2.split(", ")
#print(county2_list)
for z in county2_list:
if 'county' in z.lower():
if count == None:
count = z
except:
pass
try:
county3 = str(location3.address)
county3_list = county3.split(", ")
#print(county3_list)
for j in county3_list:
if 'county' in j.lower():
if count == None:
count = j
except:
pass
print(i, count)
#ws['E'+str(i)] = count
if count == 50:
#wb.save("#####" +str(count2) +".xlsx")
count2 += 1
count1 = 0
Hello all, this code is pretty simple and uses geopy to extract county names using 3 different methods names iden1, iden2, and iden3 which are a combination of address, city, state, and zipcode. This ran fine for about 300 lines but began to repeat the same county, and after restarting the script, just spat out Nones. I put in the line print (geolocator.geocode(iden2).address) to find the error and got this error message.
Traceback (most recent call last):
File "C:/Users/#####/Downloads/Web content/#####/####_county.py",
line 19, in
print(geolocator.geocode(iden2).address) File "C:\Users#####\AppData\Local\Programs\Python\Python36-32\lib\site-packages\geopy\geocoders\osm.py",
line 193, in geocode
self._call_geocoder(url, timeout=timeout), exactly_one File "C:\Users#####\AppData\Local\Programs\Python\Python36-32\lib\site-packages\geopy\geocoders\base.py",
line 171, in _call_geocoder
raise GeocoderServiceError(message) geopy.exc.GeocoderServiceError: [WinError 10061] No connection could
be made because the target machine actively refused it
This script was working before but now does not. Is my IP being blocked from using goepy's database or something? Thanks for your help!
It looks like you're hitting their ratelimiting. It seems that they ask that you limit your API requests to 1/second. You can take a look here for their usage policy where they list alternatives to using their API as well as contraints.
So the code below:
Takes a given square, and if it is an X does nothing. If the square has an O in it, it changes the O to an X and autofills the square above, below, to the left, and to the right.
#openFile(filename): This function opens and prints the users txt file for paint
#input: none
#output: The file that needs to be painted
def openFile(filename):
file = open(filename, 'r')
for line in file:
print(line)
file.close()
#convertFile(filename): This function is used to convert the .txt file into a 2D arrary
#input: none
#output: none
def convertFile(filename):
empty = []
filename = open(filename, 'r')
for line in filename:
line = line.rstrip("\n")
empty.append(list(line))
return empty
#getCoordinates(x,y): This function is used to get the coordinates the user wants to pain from
#input: user coordinates.
#output: none
def getCoordinates(x, y):
coordinates = []
userInt = 0
user = []
try:
user = input("Please enter a square to fill , or q to exit: ")
user.split()
coordinates.append(int(user[0]))
coordinates.append(int(user[2]))
except ValueError:
print("Enter a valid input!")
user = input("Please enter a square to fill, or q to exit: ")
user.split()
coordinates.append(int(user[0]))
coordinates.append(int(user[2]))
return coordinates
def printGrid(grid):
for innerList in grid:
for item in innerList:
print(item, end = "")
print()
#autoFill(board, row, col): This is the heart of the program and the recursive program
# use to fill the board with x's
#input: none
#output: none
def autoFill(grid, rows, cols):
if grid[cols][rows] == "X":
return 0
else:
grid[cols][rows] = "X"
if rows > 0:
autoFill(grid, rows - 1, cols)
if rows < len(grid[cols]) - 1:
autoFill(grid, rows + 1, cols)
if cols > 0:
autoFill(grid, rows, cols - 1)
if cols < len(grid) - 1:
autoFill(grid, rows, cols + 1)
def main():
coordinates = []
empty = []
while True:
filename = input("Please enter a filename: ")
openFile(filename)
empty = convertFile(filename)
coordinates = getCoordinates(len(empty), len(empty[0]))
empty = autoFill(empty(coordinates[0], coordinates[1]))
for item in empty:
s = ""
s.join(item)
for x in item:
s += str(x)
print(s)
if user == "q":
return 0
main()
output should look like:
Please enter a filename: input.txt
OOOOOOXOOOO
OOOOOXOOOOO
OOOOXOOOOOO
XXOOXOOOOOO
XXXXOOOOOOO
OOOOOOOOOOO
Please enter a square to fill, or q to exit: 1, 1
XXXXXXXOOOO
XXXXXXOOOOO
XXXXXOOOOOO
XXXXXOOOOOO
XXXXOOOOOOO
OOOOOOOOOOO
But when i type in the coordinate points i get:
empty = autoFill(empty(coordinates[0], coordinates[1]))
TypeError: 'list' object is not callable
Any guidance in fixing this issue will be much appreciated
The particular error you're asking about is happening because you're trying to call empty (which is a list, as returned by convertFile) as if it were a function.
I have some code that I need to evaluate in python 3.4.1
def foo(bar):
somecode
def myFunction(codeInString):
eval("foo(" + codeInString + ")")
But every time I try to evaluate it, I get an error that says
NameError: name 'foo' is not
When I use 'q Patrick m 1880 1885 2' as input, it should give me back a list of three tuples. Instead I get
File "C:\...\Project 1\names.py", line XXX, in BBNInput
return(eval("getBirthsByName(" + query + ")"))
File "<string>", line 1, in <module>
NameError: name 'getBirthsByName' is not defined
I defined tiny_names.csv below the code block
import matplotlib.pyplot as plt
import string
def names( infile = 'tiny_names.csv'):
#This takes in the name of the file containing the clean name data and returns a list in the format [year, name, sex, quantity]
def readNames(infile = 'tiny_names.csv'):
#Counts the number of name-year combinations
counter = 0
#Opens the file
file = open(infile, 'r')
#Reads each line into an item on the list
names = [i for i in file]
#Formatting
for i in names:
#increments the counter
counter = counter + 1
index = names.index(i)
#Removes the newline char
names[index] = i.strip('\n')
#splits by the comma
names[index] = names[index].split(',')
#reformats the numbers into ints, makes names all lowercase to make searching easier
names[index] = [ int(names[index][0]), names[index][1].lower(), names[index][2], int(names[index][3])]
#closes the file
file.close()
#returns the names
return(names)
#Takes names as an argument and returns a dictionary with keys of names and values of lists of tuples (year, male births, female births)
def nameIndex(names):
#Initialize the empty dictionary
result = {}
for i in names:
name = i[1]
if name not in result.keys():
#if it's a male, add in the male format
if i[2] == 'M':
result[name] = [(i[0], i[3], 0)]
#otherwise, add in the female format
else:
result[name] = [(i[0], 0, i[3])]
#Checking if there is already a datapoint for that year
elif True in [( i[0] == a[0]) for a in result[name]]:
xx = [( i[0] == a[0]) for a in result[name]]
index = xx.index(True)
#If there is a datum in the male slot, add the new datum to the female slot
if result[name][index][1] == 0:
result[name][index] = (result[name][index][0], i[3], result[name][index][2])
#Otherwise, vice versa
else:
result[name][index][2] == (result[name][index][0], result[name][index][1], i[3])
#if the name exists but the year is unique
else:
#if it is a male, add it in the male format
if i[2] == 'M':
result[name].append((i[0], i[3], 0))
#otherwise add it in the female format
else:
result[name].append((i[0], 0, i[3]))
#Return the results
return(result)
def getBirthsByName (name , gender=None, start=None, end=None, interval=None):
#initialize the return variable
thing = []
#Make the name variable auto match the format of the names
name = name.lower()
#if the name doesn't exist, say so
if name not in nameIndex:
return("Name not in index")
#if there are no time constraints
if not start and not end and not interval:
#cycle through the name Data Points (dp) and addup the numbers for
for dp in nameIndex[name]:
year = dp[0]
#Gender neutral
if not gender:
thing.append((year, dp[1] +dp[2]))
#Males
elif gender.upper() == "M":
thing.append((year, dp[1]))
#Females
elif gender.upper() == "F":
thing.append((year, dp[2]))
#Data validation, gender != m or f
else:
return("You have entered and invalid gender, because we are insensitive people")
else:
#Data Validation, see return comments
if interval and (not start or not end):
return("You must have a start and an end to have an interval")
if not end:
end = 2013 #initializes end if blank
if start:
return("You must have a start to have an end")
if not start:
start = 1880 #initializes start if blank
if not interval:
interval = 1 #initializes interval if blank
#If the input passes all the validation tests, return data
for year in range (start, end, interval):
if year not in yearIndex.keys():
continue
if name not in yearIndex.get(year).keys():
continue
#Assign the tuple to dp
dp = yearIndex.get(year).get(name)
#Gender neutral
if not gender:
thing.append((year, dp[0] +dp[1]))
#Males
elif gender.upper() == "M":
thing.append((year, dp[0]))
#Females
elif gender.upper() == "F":
thing.append((year, dp[1]))
return(thing)
def BBNInput(inp):
split = inp[2:].split()
query = '"' + split[0] + '"'
if (split[1] != None):
query = query + ',"' + split[1] + '"'
if (split[2] != None):
query = query + "," + split[2]
if (split[3] != None):
query = query + "," + split[3]
if (split[4] != None):
query = query + "," + split[4]
return(eval("getBirthsByName(" + query + ")"))
#read the names
print("read the names")
nameList = readNames()
#store the name index
print("make the name index")
nameIndex = nameIndex(nameList)
#initialize the exit bool
exit = False
#Functional loop
while not exit:
queue = []
inp = input('names> ')
if inp == 'x':
exit = True
continue
elif inp[0] == 'c':
data = BBNInput(inp)
total = 0
for dp in data:
total = total + dp[1]
print(total)
elif inp[0] == 'q':
print(BBNInput(inp))
elif inp[0] == 'p':
split = inp[2:].split()
query = '"' + split[0] + '"'
if (split[1] != None):
query = query + ',"' + split[1] + '"'
if (split[2] != None):
query = query + "," + split[2]
if (split[3] != None):
query = query + "," + split[3]
if (split[4] != None):
query = query + "," + split[4]
exec("print(getBirthsByName(" +query + "))")
names()
tiny_names.csv =
1890,Patrick,M,227
1890,Mary,F,12078
1890,Charles,M,4061
1890,Alice,F,2271
1889,Patrick,M,236
1889,Mary,F,11648
1889,Charles,M,4199
1889,Alice,F,2145
1888,Patrick,M,245
1888,Mary,F,11754
1888,Charles,M,4591
1888,Alice,F,2202
1887,Patrick,M,218
1887,Mary,F,9888
1887,Charles,M,4031
1887,Alice,F,1819
1886,Patrick,M,249
1886,Mary,F,9890
1886,Charles,M,4533
1886,Alice,F,1811
1885,Patrick,M,217
1885,Mary,F,9128
1885,Charles,M,4599
1885,Alice,F,1681
1884,Patrick,M,222
1884,Mary,F,9217
1884,Charles,M,4802
1884,Alice,F,1732
1883,Patrick,M,213
1883,Mary,F,8012
1883,Charles,M,4826
1883,Alice,F,1488
1882,Patrick,M,249
1882,Mary,F,8148
1882,Charles,M,5092
1882,Alice,F,1542
1881,Patrick,M,188
1881,Mary,F,6919
1881,Charles,M,4636
1881,Alice,F,1308
1880,Patrick,M,248
1880,Mary,F,7065
1880,Charles,M,5348
1880,Alice,F,1414
Well, now I think there is too much code to obviously see what the problem is. However, you probably don't need to even use eval() at all. The following will likely do what you want:
def BBNInput(inp):
split = inp[2:].split()
return getBirthsByName(*split)
See What does ** (double star) and * (star) do for Python parameters? for further information on what this means.
I fixed it by changing my BBNInput function to a query building function and evaluated (using eval()) on the same level as the def for getBirthsByName. But I think that #GregHewgill has the right of it, makes way more sense. Thanks for your help everyone!