My objective is: I need to ask the user to enter the number of emails and then initiate a for loop to register the input email. Then, the emails will be segregated based on '#professor.com' and '#student.com'. This will be counted as appended in the list. Following is what I have tried
email_count = int(input('how many emails you want'))
student_email_count = 0
professor_email_count = 0
student_email = '#student.com'
professor_email = '#professor.com'
for i in range(email_count):
email_list = str(input('Enter the emails')
if email_list.index(student_email):
student_email_count = student_email_count + 1
elif email_list.index(professor_email):
professor_email_count = professor_email_count + 1
Can someone help to shorten this and write it professional with explanations for further reference? Here, the appending part is missing. Could someone through some light there too ?
Thanks
prof_email_count, student_email_count = 0, 0
for i in range(int(input("Email count # "))):
email = input("Email %s # " % (i+1))
if email.endswith("#student.com"): # str.endswith(s) checks whether `str` ends with s, returns boolean
student_email_count += 1
elif email.endswith("#professor.com"):
prof_email_count += 1
Is what a (somewhat) shortened rendition of your code would look like. Main differences is that I'm using str.endswith(...) over str.index(...), also that I've removed the email_count, student_email and professor_email variables which didn't seem to be used anywhere else in the context.
EDIT:
To answer your comment on scalability, you could implement a system such as this:
domains = {
"student.com": 0,
"professor.com": 0,
"assistant.com": 0
}
for i in range(int(input("Email count # "))):
email = input("Email %s # " % (i+1))
try:
domain = email.split('#')[1]
except IndexError:
print("No/invalid domain passed")
continue
if domain not in domains:
print("Domain: %s, invalid." % domain)
continue
domains[domain] += 1
Which allows for further scalability as you can add more domains to the domains dictionary, and access the count per domains[<domain>]
It seems your iteration accepts one email at a time; and executes email_count times. You can use this simple code to count students and professors:
st = '#student.com'
prof = '#professor.com'
for i in range(email_count):
email = str(input('Enter the email'))
if st in email:
student_email_count += 1
elif prof in email:
professor_email_count += 1
else:
print('invalid email domain')
If you are using Python 2.7, you should change input to raw_input.
Here's a scalable version for your code, using defaultdict to support unlimited domains.
email_count = int(input('how many emails you want'))
student_email_count = 0
professor_email_count = 0
from collections import defaultdict
domains = defaultdict(int)
for i in range(email_count):
email = str(raw_input('Enter the email\n'))
try:
email_part = email.split('#')[1]
except IndexError:
print('invalid email syntax')
else:
domains[email_part] += 1
Related
need to count distinct gmail addresses provided by user as input, here are the conditions:
not case sensitive :
"a#gmail.com" == "A#GmaiL.com"
The ‘.’ character in the string in the local name is ignored :
"aa#gmail.com" == "a.a#gmail.com"
Gmail domain is same as googlemail
"aa#gmail.com" == "aa#googlemail.com"
my issue is with the very last one. How to implement the last condition in my code?
distinct_emails=[]
email = []
count=0
for i in range(int(input())):
item = input().lower().replace(".","")
email.append(item)
for i in email:
if i not in distinct_emails:
count = count + 1
distinct_emails.append(i)
print(count)
You could try something like this, where for gmail and googlemail addresses, you check for the swapped versions before appending it to the distinct_emails list.
distinct_emails=[]
email = []
count=0
for i in range(int(input())):
item = e.lower()
# don't remove `.` after the `#`.
parts = item.split("#")
email.append(parts[0].replace(".", "") + "#" + parts[1])
for i in email:
# consider googlemail and gmail to be equivalent
if not any(e in distinct_emails for e in [i, i.replace('#googlemail.com', '#gmail.com'), i.replace('#gmail.com', '#googlemail.com')]):
count = count + 1
distinct_emails.append(i)
print(count)
I'm trying to write code in Python to help with sending an email that I send about twice a week, with the same format every time and just a few elements that differ between emails, so I wrote the following code to help with this:
def visitor():
visitors = []
number_of = int(input("How many visitors are you signing in? "))
time = input("What time are they coming? ")
comments = """
Please type the name of the first visitor, and their nationality on the next line, the name of the second visitor
and their nationality on the next line, until you wrote down all the names and nationalities.
If you wanna stop the program and execute the code with the names & nationalities, just type quit
"""
print(comments)
name, i = "", 1
while name != "quit":
name = str(input("Ignore: "))
visitors.append(name)
visitors = visitors.pop(-1)
email = f"""
Hello,
I have {number_of} visitors coming today at {time}.
Name: {visitors[i]}
Nationality: {visitors[i + 1]}
"""
for i in range(len(visitors)):
to_add = f"""
Name: {visitors[i]}
Nationality: {visitors[i + 1]}
"""
email += to_add
ending = "Awaiting your approval\nThank you"
email += ending
return email
visitor()
However, upon running this code, I run into a problem in line 25, saying "Index out of range" ( line 25 is Nationality: {visitors[i + 1]} ). This normally shouldn't happen since the list has more than one element. Can someone help with this?
P.S. I have another, way longer code written for this that works, but I wanted to try and improve it by making it less sloppy.
The visitors list is acceeded at offset i+1, and i go up to len(visitors)-1 (upper limit specified for the loop through range()), so there is an access out of range when i = len(visitors) - 1
I have the following statement:
There are two type of commands:
store email_content urgency, where email_content is a String consisting of [a-zA-Z0-9_] and urgency is a positive integer
get_next_email - a request that expects email_content with highest urgency as a response. If there are 1+ emails with same urgency, output the one that was stored first. If there are no outstanding emails print "-1" string on a newline.
Input example:
4
store email1 1
store email2 10
store email3 10
get_next_email
Output:
email2
My code:
emails = {}
urgencies = set()
for _ in range(int(input())):
info = input().strip().split(" ")
if info[0] == "store":
info[2] = int(info[2])
urgencies.add(info[2])
if info[2] in emails:
emails[info[2]].append(info[1])
else:
emails[info[2]] = [info[1]]
elif info[0] == "get_next_email":
if emails:
maxval = max(urgencies)
print(emails[maxval].pop(0))
if emails[maxval] == []:
emails.pop(maxval, None)
urgencies.remove(maxval)
else:
print("-1")
I get a runtime error, which according to what I've read is a consecuence of the compexity being very big, and I don't think my code is that complex. What am I doing wrong? And what can I do to improve this? Thanks!
EDIT: It's a contest, the exact error is: Terminated due to timeout (10s)
I currently have a Python reddit bot written using PRAW that gets all of the comments from a specific subreddit, looks at their author and finds out if that author has at least 3 comments in the subreddit. If they have 3+ comments, then they are added to an approved to post submissions text file.
My code currently "works" but honestly, it's so bad that I'm not even sure how. What is a better way of accomplishing my goal?
What I currently have:
def get_approved_posters(reddit):
subreddit = reddit.subreddit('Enter_Subreddit_Here')
subreddit_comments = subreddit.comments(limit=1000)
dictionary_of_posters = {}
unique_posters = {}
commentCount = 1
duplicate_check = False
unique_authors_file = open("unique_posters.txt", "w")
print("Obtaining comments...")
for comment in subreddit_comments:
dictionary_of_posters[commentCount] = str(comment.author)
for key, value in dictionary_of_posters.items():
if value not in unique_posters.values():
unique_posters[key] = value
for key, value in unique_posters.items():
if key >= 3:
commentCount += 1
if duplicate_check is not True:
commentCount += 1
print("Adding author to dictionary of posters...")
unique_posters[commentCount] = str(comment.author)
print("Author added to dictionary of posters.")
if commentCount >= 3:
duplicate_check = True
for x in unique_posters:
unique_authors_file.write(str(unique_posters[x]) + '\n')
total_comments = open("total_comments.txt", "w")
total_comments.write(str(dictionary_of_posters))
unique_authors_file.close()
total_comments.close()
unique_authors_file = open("unique_posters.txt", "r+")
total_comments = open("total_comments.txt", "r")
data = total_comments.read()
approved_list = unique_authors_file.read().split('\n')
print(approved_list)
approved_posters = open("approved_posters.txt", "w")
for username in approved_list:
count = data.count(username)
if(count >= 3):
approved_posters.write(username + '\n')
print("Count for " + username + " is " + str(count))
approved_posters.close()
unique_authors_file.close()
total_comments.close()
Maybe it's just me being slow this morning, but I'm struggling to follow/understand your use of commentCount and unique_posters. Actually, it probably is me.
I would get all the comments from the subreddit, like you did, and for each comment, do the following:
for comment in subreddit_comments:
try:
dictionary_of_posters[comment.author] += 1
except KeyError:
dictionary_of_posters[comment.author] = 1
for username, comment_count in dictionary_of_posters.items():
if comment_count >= 3:
approved_authors.append(username)
This method takes advantage of the fact that dictionaries cannot have two of the same key value. That way, you don't have to do a duplicate check or anything. If it makes you feel better, you can go list(set(approved_authors)) and that will get rid of any stray duplicates.
Noob
I am trying to write a script that gives a running balance. I am messing up on the elementary declared functions of python.
I need it too:
accept a balance via input
append a list of transactions
take those out one by one in the order they were input
print a running total
use pyhtmltable to make the output in html table ready form for copy and pasting
Code:
# transaction posting on available balance
import PyHtmlTable
import twodarr
import string,re
import copy
import sys
posting_trans = [] #creating a list of posting debits here
avail_bal = int(input('What is the balance available to pay transactions?')) #getting the starting balance
while True: #building up the list of transactions
ans = input('Please enter the debits in order of posting one at a time. If there is no more, please enter 0:')
if int(ans) == 0:
break
if ans > 0: # to get out of loop
posting_trans.append(ans)
num_trans = int(len(posting_trans)) #counting the number of transactions
print "<b> Beginning available balance of",avail_bal," </b> " # start of the html table
tabledict = {'width':'400','border':2,'bgcolor':'white'}
t = PyHtmlTable.PyHtmlTable( 2, 1 , tabledict )
t.setCellcontents(0,0,"Transactions") #header cells
t.setCellcontents(1,0,"Available Balance")
while True: #trying to create the rest of a dynamic table
if countdown == 0:
break
for countdown in range(1,num_trans):
t.add_row(1)
def newer_bal():
newer_bal(avail_bal - posting_trans[countdown])
t.setCellcontents(0, 1, posting_trans[countdown])
t.setCellcontents(1, 1, newer_bal)
t.display()
Something like that?
# transaction posting on available balance
import PyHtmlTable
posting_trans = [] #creating a list of posting debits here
#getting the starting balance
print 'What is the balance available to pay transactions? '
avail_bal = float(raw_input('Value: '))
while True: #building up the list of transactions
print 'Please enter the debits in order of posting one at a time.'
print 'If there is no more, please enter 0:'
ans = float(raw_input('Value: '))
if ans == 0:
break # to get out of loop
posting_trans.append(ans)
# start of the html table
print "<b> Beginning available balance of %.2f</b>" % avail_bal
tabledict = {'width': '400', 'border': 2, 'bgcolor': 'white'}
t = PyHtmlTable.PyHtmlTable(2, 1, tabledict)
t.setCellcontents(0, 0, "Transaction Value") #header cells
t.setCellcontents(0, 1, "Available Balance")
for line, trans in enumerate(posting_trans):
avail_bal -= trans
t.setCellcontents(line + 1, 0, '%.2f' % trans)
t.setCellcontents(line + 1, 1, '%.2f' % avail_bal)
t.display()
Hints:
Don't use input(). Use raw_input() instead. It has been renamed to input() in python 3.0.
You don't need to store the values in the list. You could store them in the table already, that is the point into using PyHtmlTable. I left the list for didactic purposes.
Read a tutorial. Read documentation. Write lots of code.