python list must have all values comma separated - python

I want to make sure argument passed as list has distinct values and comma separated otherwise throw error for any other delimiter like tab, space , semi colon anything.
Case 1-
input -> ['2015-01-01', '2015-02-01', '2015-02-01','2015-03-01']
output -> ['2015-01-01', '2015-02-01','2015-03-01']
Case 2-
input -> ['2015-01-01';'2015-02-01';'2015-02-01';'2015-03-01']
output -> raise exception - please enter comma separated list.

Since there is little information to go on.
Here is a simple solution to what i think it is you are trying to ask:
l1 = []
while True:
user_ = input("> ")
if user_ == "exit":
break
if user_ in l1:
print("already exists")
if user_ not in l1:
l1.append(user_)
print(l1)
print(l1)
Basically this will prevent the user from inputting the same thing twice.
You do not need to worry about the list being in an incorrect format. Lists in python will always have comma separation when user inputs.
If you would like to make sure the user is inputting string in a specific format IE in date form yyyy/mm/dd. You would just need to add another conditional to check that.
Hope this helps.

I am just assuming the expected outcome and input from the comments and answers posted earlier
import re
string_list = ["['2015-01-01';'2015-02-01';'2015-02-01';'2015-03-01']",
"['2015-01-01';'2015-02-01' '2015-02-01';'2015-03-01']",
"['2015-01-01';'2015-02-01' '2015-02-01';'2015-03-01']",
"['2015-01-01','2015-02-01','2015-02-01','2015-03-01']"
]
for i in string_list:
if re.findall(r"\d{4}-\d{2}-\d{2}'[;*&\t\s]{1,}",i):
print('invalid') # raise excpetion here
else:
print(set(i[1:-1].replace("'",'').split(',')))
Output:
invalid
invalid
invalid
set(['2015-03-01', '2015-01-01', '2015-02-01'])
The valid output would be of type set which can be converted to list if required using list()

Something along these lines could cleanup user input, but it will always have the potential for someone to put something unexpected in.
I would take each value separately and append them to a list, myself.
inList = "['2015-01-01';'2015-02-01';'2015-02-01';'2015-03-01']"
delimiters = [",", ";", "\t", "\n", " "]
rem = ["[", "]", '"', "'", " "]
out = []
for delimiter in delimiters:
if delimiter in inList:
for r in rem:
if delimiter == r :break
inList = inList.replace(r, '')
out = inList.split(delimiter)
break
print(out)

Related

Weird error in loop not understanding why the range is out of index

I was asked to:-
Write a program to input a string and then using a function change(), create a new string
with all the consonants deleted from the string. The function should take in the string as
a parameter and return the converted string.
my code :-
str=input("enter a string: ")
def change(stri):
for i in range(0,len(stri)):
for e in ['a','e','i','o','u','A','E','I','O','U']:
if stri[i]==e:
if i==len(stri)-1:
stri = stri[0:i-1] + "" + stri[i: ]
else:
stri = stri[0:i] + "" + stri[i+1: ]
else:
continue
return stri
str=change(str)
print(str)
output :-
Traceback (most recent call last):
File "main.py", line 13, in <module> str=change(str)
File "main.py", line 5, in change if stri[i]==e:
IndexEnoi: string index out of range
^ for any string
Please someone help me out this is my imp project
As said by Johny Mopp: "Let's say len(stri) == 10. Your for loop then is for i in range(0, 10):. But then in the loop you modify stri so that it's new length is less than 10. You will now get an index out of range error at if stri[i]==e: because i is too large"
Use this instead:
text=input("enter a string: ")
vowels = ['a','e','i','o','u','A','E','I','O','U']
for x in vowels:
text = text.replace(x,"")
print(text)
Generally speaking, don't try to reinvent the wheel. Make use of all functions Python offers you.
The issue you are facing is common when deleting from the same object that you are iterating. Eventually you delete a part of the object that is already queued up as part of a future iteration in the for loop and you get an error.
The best way around this, in your case, is to write your vowel only string out to a new variable keeping your stri variable intact as it was passed into your function.
A quick rewrite of your code with the addition of the new variable to catch your output string would look like:
vowels=['a','e','i','o','u','A','E','I','O','U']
stri='This is a test string'
stro=''
for character in stri:
if character in vowels:
stro=stro+character
print(stro)
I believe the issue you have is that you change the string inside the for loop. You delete letters but still have the same range (len(stri) is not updated while changing the stri). Try with the word without vowels. You will not get any error.
But there is a much simpler way of doing this if I understand your task correctly.
def change2(str):
return ''.join([letter for letter in str if letter not in ['a','e','i','o','u','A','E','I','O','U']])
print(change2(input('enter a string: ')))
The join method creates the new string and returns it. The separator between the list elements is a string that calls join() method. In this example, it is an empty string.
You should use a new string variable for concatenation. You are changing the passed string to the function that's why it gives the error.
str=input("enter a string: ")
def change(stri):
nstr = ''
for i in range(0,len(stri)):
for e in ['a','e','i','o','u','A','E','I','O','U']:
print(stri[i])
if stri[i]==e:
if i==len(stri)-1:
nstr = stri[0:i-1] + "" + stri[i: ]
else:
nstr = stri[0:i] + "" + stri[i+1: ]
else:
continue
return nstr
str=change(str)
print(str)

How do I read a file and convert each line into strings and see if any of the strings are in a user input?

What I am trying to do in my program is to have the program open a file with many different words inside it.
Receive a user input and check if any word inside the file is in user input.
Inside the file redflags.txt:
happy
angry
ball
jump
each word on a different line.
For example if the user input is "Hey I am a ball" then it will print redflag.
If the user input is "Hey this is a sphere" then it will print noflag.
Redflags = open("redflags.txt")
data = Redflags.read()
text_post = raw_input("Enter text you wish to analyse")
words = text_post.split() and text_post.lower()
if data in words:
print("redflag")
else:
print("noflag")
This should do the trick! Sets are generally much faster than lookups for list comparisons. Sets can tell you the intersection in this case (overlapping words), differences, etc. We consume the file that has a list of words, remove newline characters, lowercase, and we have our first list. The second list is created from the user input and split on spacing. Now we can perform our set intersection to see if any common words exist.
# read in the words and create list of words with each word on newline
# replace newline chars and lowercase
words = [word.replace('\n', '').lower() for word in open('filepath_to_word_list.txt', 'r').readlines()]
# collect user input and lowercase and split into list
user_input = raw_input('Please enter your words').lower().split()
# use set intersection to find if common words exist and print redflag
if set(words).intersection(set(user_input)):
print('redflag')
else:
print('noflag')
with open('redflags.txt', 'r') as f:
# See this post: https://stackoverflow.com/a/20756176/1141389
file_words = f.read().splitlines()
# get the user's words, lower case them all, then split
user_words = raw_input('Please enter your words').lower().split()
# use sets to find if any user_words are in file_words
if set(file_words).intersection(set(user_words)):
print('redflag')
else:
print('noredflag')
I would suggest you to use list comprehensions
Take a look at this code which does what you want (I will explain them below):
Redflags = open("redflags.txt")
data = Redflags.readlines()
data = [d.strip() for d in data]
text_post = input("Enter text you wish to analyse:")
text_post = text_post.split()
fin_list = [i for i in data if i in text_post]
if (fin_list):
print("RedFlag")
else:
print("NoFlag")
Output 1:
Enter text you wish to analyse:i am sad
NoFlag
Output 2:
Enter text you wish to analyse:i am angry
RedFlag
So first open the file and read them using readlines() this gives a list of lines from file
>>> data = Redflags.readlines()
['happy\n', 'angry \n', 'ball \n', 'jump\n']
See all those unwanted spaces,newlines (\n) use strip() to remove them! But you can't strip() a list. So take individual items from the list and then apply strip(). This can be done efficiently using list comprehensions.
data = [d.strip() for d in data]
Also why are you using raw_input() In Python3 use input() instead.
After getting and splitting the input text.
fin_list = [i for i in data if i in text_post]
I'm creating a list of items where i (each item) from data list is also in text_pos list. So this way I get common items which are in both lists.
>>> fin_list
['angry'] #if my input is "i am angry"
Note: In python empty lists are considered as false,
>>> bool([])
False
While those with values are considered True,
>>> bool(['some','values'])
True
This way your if only executes if list is non-empty. Meaning 'RedFlag' will be printed only when some common item is found between two lists. You get what you want.

How to extract a group of items from a list using enumerate and split?

f=open('insert.dat','w+')
while True:
name=raw_input("ENter name:")
age=input("Enter age")
gen=raw_input("gender")
f.write(name+','+str(age)+','+gen+'')
ch=raw_input("continue")
if(ch=='n'):
break
f=open('insert.dat','r+')
x=f.readline()
x=x.split(',')
for index,line in enumerate(x):
print line,index
f.seek(0,0)
f.close()
in this program, i want to input:
name:lol
age:3
gender:F
name:koi
age:4
gender:F
so x.split should come as
['lol',3,'F','koi',4,'F']
now i want to get first details as a separate list , like:
['lol',3,'F'].
but when i use the above format, each word is coming as a list when used along with split. how to get like this using enumerate and split only.?? Thankyou!
Using the same logic used by you.
The thing you are doing wrong is adding the next details to the end of the previous data.
You can do the below to avoid it:
f=open('insert.dat','w+')
individual = []
while True:
name=raw_input("ENter name:")
age=input("Enter age")
gen=raw_input("gender")
f.write(','+name+','+str(age)+','+gen+'')
individual.append([name,age,gen])
ch=raw_input("continue")
if(ch=='n'):
break
f=open('insert.dat','r+')
x=f.readline()
x=x.replace(',', '', 1)
x=x.split(',')
for index,line in enumerate(x):
print line,index
f.seek(0,0)
f.close()
for ind in individual:
print ind
I have added comma ',' at the beginning of the input. All you need to do is replace the first comma before splitting the string.

python - matching string and replacing

I have a file i am trying to replace parts of a line with another word.
it looks like bobkeiser:bob123#bobscarshop.com:0.0.0.0.0:23rh32o3hro2rh2:234212
i need to delete everything but bob123#bobscarshop.com, but i need to match 23rh32o3hro2rh2 with 23rh32o3hro2rh2:poniacvibe , from a different text file and place poniacvibe infront of bob123#bobscarshop.com
so it would look like this bob123#bobscarshop.com:poniacvibe
I've had a hard time trying to go about doing this, but i think i would have to split the bobkeiser:bob123#bobscarshop.com:0.0.0.0.0:23rh32o3hro2rh2:234212 with data.split(":") , but some of the lines have a (:) in a spot that i don't want the line to be split at, if that makes any sense...
if anyone could help i would really appreciate it.
ok, it looks to me like you are using a colon : to separate your strings.
in this case you can use .split(":") to break your strings into their component substrings
eg:
firststring = "bobkeiser:bob123#bobscarshop.com:0.0.0.0.0:23rh32o3hro2rh2:234212"
print(firststring.split(":"))
would give:
['bobkeiser', 'bob123#bobscarshop.com', '0.0.0.0.0', '23rh32o3hro2rh2', '234212']
and assuming your substrings will always be in the same order, and the same number of substrings in the main string you could then do:
firststring = "bobkeiser:bob123#bobscarshop.com:0.0.0.0.0:23rh32o3hro2rh2:234212"
firstdata = firststring.split(":")
secondstring = "23rh32o3hro2rh2:poniacvibe"
seconddata = secondstring.split(":")
if firstdata[3] == seconddata[0]:
outputdata = firstdata
outputdata.insert(1,seconddata[1])
outputstring = ""
for item in outputdata:
if outputstring == "":
outputstring = item
else
outputstring = outputstring + ":" + item
what this does is:
extract the bits of the strings into lists
see if the "23rh32o3hro2rh2" string can be found in the second list
find the corresponding part of the second list
create a list to contain the output data and put the first list into it
insert the "poniacvibe" string before "bob123#bobscarshop.com"
stitch the outputdata list back into a string using the colon as the separator
the reason your strings need to be the same length is because the index is being used to find the relevant strings rather than trying to use some form of string type matching (which gets much more complex)
if you can keep your data in this form it gets much simpler.
to protect against malformed data (lists too short) you can explicitly test for them before you start using len(list) to see how many elements are in it.
or you could let it run and catch the exception, however in this case you could end up with unintended results, as it may try to match the wrong elements from the list.
hope this helps
James
EDIT:
ok so if you are trying to match up a long list of strings from files you would probably want something along the lines of:
firstfile = open("firstfile.txt", mode = "r")
secondfile= open("secondfile.txt",mode = "r")
first_raw_data = firstfile.readlines()
firstfile.close()
second_raw_data = secondfile.readlines()
secondfile.close()
first_data = []
for item in first_raw_data:
first_data.append(item.replace("\n","").split(":"))
second_data = []
for item in second_raw_data:
second_data.append(item.replace("\n","").split(":"))
output_strings = []
for item in first_data:
searchstring = item[3]
for entry in second_data:
if searchstring == entry[0]:
output_data = item
output_string = ""
output_data.insert(1,entry[1])
for data in output_data:
if output_string == "":
output_string = data
else:
output_string = output_string + ":" + data
output_strings.append(output_string)
break
for entry in output_strings:
print(entry)
this should achieve what you're after and as prove of concept will print the resulting list of stings for you.
if you have any questions feel free to ask.
James
Second edit:
to make this output the results into a file change the last two lines to:
outputfile = open("outputfile.txt", mode = "w")
for entry in output_strings:
outputfile.write(entry+"\n")
outputfile.close()

Print multiple variables in one line using python

I need some assistance with a python script. I need to search a dhcpd file for host entires, their MAC and IP, and print it in one line. I am able to locate the hostname and IP address but cannot figure out how to get the variables out of the if statement to put in one line. Any suggestions, the code is below:
#!/usr/bin/python
import sys
import re
#check for arguments
if len(sys.argv) > 1:
print "usage: no arguments required"
sys.exit()
else:
dhcp_file = open("/etc/dhcp/dhcpd.conf","r")
for line in dhcp_file:
if re.search(r'\bhost\b',line):
split = re.split(r'\s+', line)
print split[1]
if re.search(r'\bhardware ethernet\b',line):
ip = re.split(r'\s+',line)
print ip[2]
dhcp_file.close()
There are a number of ways that you could go about this. The simplest is probably to initialize an empty string before the if statements. Then, instead of printing split[1] and ip[2], concatenate them to the empty string and print that afterwards. So it would look something like this:
printstr = ""
if re.search...
...
printstr += "Label for first item " + split[1] + ", "
if re.search...
...
printstr += "Label for second item " + ip[2]
print printstr
In the general case, you can give comma-separated values to print() to print them all on one line:
entries = ["192.168.1.1", "supercomputer"]
print "Host:", entries[0], "H/W:", entries[1]
In your particular case, how about adding the relevant entries to a list and then printing that list at the end?
entries = []
...
entries.append(split[1])
...
print entries
At this point you may want to join the 'entries' you've collected into a single string. If so, you can use the join() method (as suggested by abarnert):
print ' '.join(entries)
Or, if you want to get fancier, you could use a dictionary of "string": "list" and append to those lists, depending on they key string (eg. 'host', 'hardware', etc...)
You can also use a flag, curhost, and populate a dictionary:
with open("dhcpd.conf","r") as dhcp_file:
curhost,hosts=None,{}
for line in dhcp_file:
if curhost and '}' in line: curhost=None
if not curhost and re.search(r'^\s*host\b',line):
curhost=re.split(r'\s+', line)[1]
hosts[curhost] = dict()
if curhost and 'hardware ethernet' in line:
hosts[curhost]['ethernet'] = line.split()[-1]
print hosts

Categories

Resources