Can't get the next line using next() in a loop (python) - python

I'm trying to write a code that iterates through a txt file and only gets the lines I want to print them out.
the text file should look like so:
mimi
passwordmimi
mimi johnson
somejob
joji
passwordjoji
jojo
somejob
john
passwordjohn
jonathan
somejob
....
and so on. this text file contains basically a user information (for a log in). I need to make everyone's username print out and their real name (ex: mimi and mimi johnson.) and only those. I don't want the current user's info to print out (in this ex: joji)
here is my code:
username="joji"
file=open("username.txt","r")
x=file.readlines()
x=[item.rstrip('\n') for item in x]
x=iter(x)
for line in x:
if line==username:
next(x,None)
next(x,None)
next(x,None)
else:
print line + " username" ****username should print out. ex:mimi or john
next(x,None)
print line +" real name ****real name should print out. ex: mimi johnson or jonathan
for whatever reason when I run this program and i print out the second **** i put, it prints out the username's twice. (so ex:
mimi username
mimi real name
mimi johnson username
mimi johnson real name
john username
john real name
jonathan username
jonathan real name
....
why is that? it should print out
mimi username
mimi johnson real name
john username
jonathan realname
...
if someone could help me out i'd be really grateful i dont get python.
Im also open to any other suggestions to do this.
EDIT::: i tried making a change with a suggestion this is the outcome:
new block of code:
else:
print line + "username"
line =next(x,None)
print line
this is the new outcome:
mimi username
passmimi real name
mimi johnson username
somejob real name
john username
passjohn real name
jonathan username
somejob real name(***im assuming this one is from john's job)
:/ its not doing what its supposed to

I would recommend using regex to parse this file:
import re
# regex expression to parse the file as you provided it
# you could access the parseddata as a dict using the
# keys "username", "password", "real_name" and "job"
ex = "\n*(?P<username>.+)\n(?P<password>.+)\n(?P<real_name>.+)\n(?P<job>.+)[\n\$]"
with open("usernames.txt", 'r') as users:
matches = re.finditer(ex, users.read())
for match in matches:
user = match.groupdict() # user is a dict
# print username and real name
print(user['username'], "username", user['real_name'], "real name")
Edit: I figured that regex was not really needed here as the format of this file is quite simple. So here is the same thing without using regex.
def parse(usersfile):
# strip line break characters
lines = (line.rstrip('\n') for line in usersfile)
# keys to be used in the dictionnary
keys = ('username', 'password', 'real_name', 'job')
while True:
# build the user dictionnary with the keys above
user = {key: line for key, line in zip(keys, lines)}
# yield user if all the keys are in the dict
if len(user) == len(keys):
yield user
else: # stop the loop
break
with open("usernames.txt", 'r') as usersfile:
for user in parse(usersfile):
# print username and real name
print(user['username'], "username", user['real_name'], "real name")

Related

Extract data from text file using Python (or any language)

I have a text file that looks like:
First Name Bob
Last name Smith
Phone 555-555-5555
Email bob#bob.com
Date of Birth 11/02/1986
Preferred Method of Contact Text Message
Desired Appointment Date 04/29
Desired Appointment Time 10am
City Pittsburgh
Location State
IP Address x.x.x.x
User-Agent (Browser/OS) Apple Safari 14.0.3 / OS X
Referrer http://www.example.com
First Name john
Last name Smith
Phone 555-555-4444
Email john#gmail.com
Date of Birth 03/02/1955
Preferred Method of Contact Text Message
Desired Appointment Date 05/22
Desired Appointment Time 9am
City Pittsburgh
Location State
IP Address x.x.x.x
User-Agent (Browser/OS) Apple Safari 14.0.3 / OS X
Referrer http://www.example.com
.... and so on
I need to extract each entry to a csv file, so the data should look like: first name, last name, phone, email, etc. I don't even know where to start on something like this.
first of all you'll need to open the text file in read mode.
I'd suggest using a context manager like so:
with open('path/to/your/file.txt', 'r') as file:
for line in file.readlines():
# do something with the line (it is a string)
as for managing the info you could build some intermediate structure, for example a dictionary or a list of dictionaries, and then translate that into a CSV file with the csv module.
you could for example split the file whenever there is a blank line, maybe like this:
with open('Downloads/test.txt', 'r') as f:
my_list = list() # this will be the final list
entry = dict() # this contains each user info as a dict
for line in f.readlines():
if line.strip() == "": # if line is empty start a new dict
my_list.append(entry) # and append the old one to the list
entry = dict()
else: # otherwise split the line and create new dict
line_items = line.split(r' ')
print(line_items)
entry[line_items[0]] = line_items[1]
print(my_list)
this code won't work because your text is not formatted in a consistent way: you need to find a way to make the split between "title" and "content" (like "first name" and "bob") in a consistent way. I suggest maybe looking at regex and fixing the txt file by making spacing more consistent.
assuming the data resides in a:
a="""
First Name Bob
Last name Smith
Phone 555-555-5555
Email bob#bob.com
Date of Birth 11/02/1986
Preferred Method of Contact Text Message
Desired Appointment Date 04/29
Desired Appointment Time 10am
City Pittsburgh
Location State
IP Address x.x.x.x
User-Agent (Browser/OS) Apple Safari 14.0.3 / OS X
Referrer http://www.example.com
First Name john
Last name Smith
Phone 555-555-4444
Email john#gmail.com
Date of Birth 03/02/1955
Preferred Method of Contact Text Message
Desired Appointment Date 05/22
Desired Appointment Time 9am
City Pittsburgh
Location State
IP Address x.x.x.x
User-Agent (Browser/OS) Apple Safari 14.0.3 / OS X
Referrer http://www.example.com
"""
line_sep = "\n" # CHANGE ME ACCORDING TO DATA
fields = ["First Name", "Last name", "Phone",
"Email", "Date of Birth", "Preferred Method of Contact",
"Desired Appointment Date", "Desired Appointment Time",
"City", "Location", "IP Address", "User-Agent","Referrer"]
records = a.split(line_sep * 2)
all_records = []
for record in records:
splitted_record = record.split(line_sep)
one_record = {}
csv_record = []
for f in fields:
found = False
for one_field in splitted_record:
if one_field.startswith(f):
data = one_field[len(f):].strip()
one_record[f] = data
csv_record.append(data)
found = True
if not found:
csv_record.append("")
all_records.append(";".join(csv_record))
one_record will have the record as dictionary and csv_record will have it as a list of fields (ordered as fields variable)
Edited to add: ignore this answer, the code from Koko Jumbo looks infinitely more sensible and actually gives you a CVS file at the end of it! It was a fun exercise though :)
Just to expand on fcagnola's code a bit.
If it's a quick and dirty one-off, and you know that the data will be consistently presented, the following should work to create a list of dictionaries with the correct key/value pairing. Each line is processed by splitting the line and comparing the line number (reset to 0 with each new dict) against an array of values that represent where the boundary between key and value falls.
For example, "First Name Bob" becomes ["First","Name","Bob"]. The function has been told that linenumber= 0 so it checks entries[linenumber] to get the value "2", which it uses to join the key name (items 0 & 1) and then join the data (items 2 onwards). The end result is ["First Name", "Bob"] which is then added to the dictionary.
class Extract:
def extractEntry(self,linedata,lineindex):
# Hardcoded list! The quick and dirty part.
# This is specific to the example data provided. The entries
# represent the index to be used when splitting the string
# between the key and the data
entries = (2,2,1,1,3,4,3,3,1,1,2,2,1)
return self.createNewEntry(linedata,entries[lineindex])
def createNewEntry(self,linedata,dataindex):
list_data = linedata.split()
key = " ".join(list_data[:dataindex])
data = " ".join(list_data[dataindex:])
return [key,data]
with open('test.txt', 'r') as f:
my_list = list() # this will be the final list
entry = dict() # this contains each user info as a dict
extr = Extract() # class for splitting the entries into key/value
x = 0
for line in f.readlines():
if line.strip() == "": # if line is empty start a new dict
my_list.append(entry) # and append the old one to the list
entry = dict()
x = 0
else: # otherwise split the line and create new dict
extracted_data = extr.extractEntry(line,x)
entry[extracted_data[0]] = extracted_data[1]
x += 1
my_list.append(entry)
print(my_list)

How to pull specific parts of a list on each line?

I have a list that spits out information like this: ['username', 'password'], ['username', 'password'], ['username', 'password'], and so on..
I would like to be able to pull a specific username and password later on.
For example:
['abc', '9876'], ['xyz', '1234']
pull abc and tell them the password is 9876.
Then pull xyz and tell them the password is 1234
I tried messing around with the list and I am just drawing a blank on how to do this.
lines = []
with open("output.txt", "r") as f:
for line in f.readlines():
if 'Success' in line:
#get rid of everything after word success so only username and password is printed out
lines.append(line[:line.find("Success")-1])
for element in lines:
#split username and password up at : so they are separate entities
#original output was username:password, want it to be username, password
parts = element.strip().split(":")
print(parts)
I want to pull each username and then pull their password as described above
Current output after running through this is ['username', 'password']. The original output file had extra information that I got rid of which is what the code involving 'Success' took care of
I would like to do this without hardcoding a username in to it. I am trying to automate this process so that it runs through every username and formats it to say, "hi [username}, your password is [123]", for all of the usernames
I then later would like to be able to only tell the specific user their password. For example, i want to send an email to user abc. that email should only contain the username and password of user abc
Instead of printing parts, append them to a list.
data = []
for element in lines:
parts = element.strip().split(":")
data.append(parts)
Then you could convert these into a dictionary for lookup
username_passwords = dict(data)
print(username_passwords['abc'])
If I am understanding this correctly parts is the list that contains [Username:Password]. If that is the case we can assign each value of parts which should only have 2 elements in it to a dictionary as a dictionary pair and then call the username later on.
lines = []
User_Pass = {}
with open("output.txt", "r") as f:
for line in f.readlines():
if 'Success' in line:
#get rid of everything after word success so only username and password is printed out
lines.append(line[:line.find("Success")-1])
for element in lines:
#split username and password up at : so they are separate entities
parts = element.strip().split(":")
User_Pass.update({parts[0] : parts[1]})
Then you can call the password from the username as follows if you know the username:
x = User_Pass["foo"]
Or as you stated in the comments:
for key, value in User_Pass.items():
print('Username ' + key + ' Has a Password of ' + value)
it looks like after you do this
lines.append(line[:line.find("Success")-1])
lines = ['username:password', 'username:password'...]
so I would do this
new_list_of_lists = [element.strip().split(":") for element in lines]
new_list_of_lists should now look like [[username, password], [username, password]]
then just do this:
dict_of_usernames_and_passwords = dict(new_list_of_lists)
with a dict you can have now retrieve passwords using usernames. like:
dict_of_usernames_and_passwords['abc']
you can save the dict, using json module, to a file, for easy retrieval.

How to alter user input?

So atm I'm making a table in python, and for it, I need the user to supply a name of a person for the table (e.g. David Beckham). However when the user has entered this and the table appears, the name needs to look like this: Beckham, David. How would I go about doing this?
With Python 3.6+ you can use formatted string literals (PEP 498). You can use str.rsplit with maxsplit=1 to account for middle names:
x = 'David Robert Bekham'
first_names, last_name = x.rsplit(maxsplit=1)
res = f'{last_name}, {first_names}'
# 'Bekham, David Robert'
Just store the input in a variable:
name = input()
first_name, last_name = name.split(" ")
table_value = last_name + ", " + first_name

Converting a text file into csv file using python

I have a requirement where in I need to convert my text files into csv and am using python for doing it. My text file looks like this ,
Employee Name : XXXXX
Employee Number : 12345
Age : 45
Hobbies: Tennis
Employee Name: xxx
Employee Number :123456
Hobbies : Football
I want my CSV file to have the column names as Employee Name, Employee Number , Age and Hobbies and when a particular value is not present it should have a value of NA in that particular place. Any simple solutions to do this? Thanks in advance
You can do something like this:
records = """Employee Name : XXXXX
Employee Number : 12345
Age : 45
Hobbies: Tennis
Employee Name: xxx
Employee Number :123456
Hobbies : Football"""
for record in records.split('Employee Name'):
fields = record.split('\n')
name = 'NA'
number = 'NA'
age = 'NA'
hobbies = 'NA'
for field in fields:
field_name, field_value = field.split(':')
if field_name == "": # This is employee name, since we split on it
name = field_value
if field_name == "Employee Number":
number = field_value
if field_name == "Age":
age = field_value
if field_name == "Hobbies":
hobbies = field_value
Of course, this method assumes that there is (at least) Employee Name field in every record.
Maybe this helps you get started? It's just the static output of the first employee data. You would now need to wrap this into some sort of iteration over the file. There is very very likely a more elegant solution, but this is how you would do it without a single import statement ;)
with open('test.txt', 'r') as f:
content = f.readlines()
output_line = "".join([line.split(':')[1].replace('\n',';').strip() for line in content[0:4]])
print(output_line)
I followed very simple steps for this and may not be optimal but solves the problem. Important case here I can see is there can be multiple keys ("Employee Name" etc) in single file.
Steps
Read txt file to list of lines.
convert list to dict(logic can be more improved or complex lambdas can be added here)
Simply use pandas to convert dict to csv
Below is the code,
import pandas
etxt_file = r"test.txt"
txt = open(txt_file, "r")
txt_string = txt.read()
txt_lines = txt_string.split("\n")
txt_dict = {}
for txt_line in txt_lines:
k,v = txt_line.split(":")
k = k.strip()
v = v.strip()
if txt_dict.has_key(k):
list = txt_dict.get(k)
else:
list = []
list.append(v)
txt_dict[k]=list
print pandas.DataFrame.from_dict(txt_dict, orient="index")
Output:
0 1
Employee Number 12345 123456
Age 45 None
Employee Name XXXXX xxx
Hobbies Tennis Football
I hope this helps.

Generating unique usernames from an email list for creating new users in django application

I am importing contacts from gmail. c_lst is the list that has the names and email address in a dictionary as follows - [{'name': u'fn1 ln1', 'emails': [u'email1#gmail.com']}, {'name': u'fn2 ln2', 'emails': [u'email2#gmail.com']},.
There are two problems with importing contacts:
Some of the contacts that I might be importing, might already be present in the database, in that case, I do not want to add another contact.
Unique usernames. There is a possibility of two emails being same, except the domain names. eg. email#gmail.com and then email#outlook.com in that case, I need to have distinct usernames so the first username would be like email, and the second one would be email1.
I have implemented both of them, and commented for making things clear.
Can there be more pythonic way of doing it?
for contact in c_lst:
email = contact.get('emails')[0]
name = contact.get('name').split(' ')
first_name, last_name = name[0], name[-1]
try:
# check if there is already a user, with that email address
# if yes then ignore.
u = Users.objects.get(email = email)
print "user exists"
except:
while True:
username = email.split('#')[0]
name, idx = username, 1
try:
# user with current username exists, so add numeral
Users.objects.get(username = username)
name = username + str(idx)
except User.DoesNotExist:
username = name
u = User.objects.create(username = username, email = email, first_name = first_name, last_name = last_name)
u.save()
break
Please let me know, of any other/better flow/approach.
For generating usernames, one might advice generating random numbers, but its okay for me
to go sequentially, as it is only one time activity.
The one thing I would like to change is to handle the first except explicitly. Since you are using:
u = Users.objects.get(email=email) # don't add space before and after "=" in argument
It could raise a MultipleObjectsReturned exception then create an infinite loop in the current except block.
So you should at least change your code to:
# ... your code ...
first_name, last_name = name[0], name[-1]
try:
u = Users.objects.get(email=email)
except User.DoesNotExist:
# ... your code ....
except User.MultipleObjectsReturned:
# handle this case differently ?
Well your might want to handle the second try except block similarly but that's your choice.
Hope this helps.

Categories

Resources