How do you slice part of an input statement in Python 3? - python

I have a question which asks me to get a user's email address and then return the URL it is associated with. So, for example: 'abc123#address.com' --> 'http:://www.address.com'
I did get this:
def main():
email_address = input('Enter your email address (eg. abc123#address.com): ').strip()
strip_username = email_address.split('#', 1)[-1]
the_url(strip_username)
def the_url(url_ending):
print('Your associated URL is: http://www.' + str(url_ending))
main()
which does what I want, but this code: split('#'...) is something I haven't learned yet. I just found it online. I need to use indexing and splicing for this program, but how can I use splicing if I don't know the length of the user's email? I need to get rid of everything before and including the '#' symbol so that it can leave me with just 'address.com' but I don't know what address it will be. It could be hotmail, gmail, etc. Thanks, and I'm really new to Python so I'm trying to only use what I've learned in class so far.

The split method just splits up the string based on the character to you give it, so:
"Hello#cat".split("#")
Will give you
["Hello", "cat"]
Then you can just take the 1st index of that array to give you whatever's after the first # symbol.

If you don't want to use str.split then by indexing and slicing,
you can do something like this.
>>> str = 'abc123#address.com'
>>> 'http://www.' + str[str.index('#')+1:]
'http://www.address.com'

Related

How to ping members from a string discord.py

I'm getting strings of game-chat from a server and I need to check if a user is mentioned in that string and if he is, I need to find him on the server and mention him because I can't just send the string as it is as it's not mentioning him.
Here's a simple example:
socket_str = "Hey this is a ping test for #TheBeast"
I need to check for tags on that string (#) , then get the name separated so TheBeast , then I need to go over the members in the servers and find a member object with that name and build a final fstring that contains the string before the mention, and with the mention.
so it will look the same but the bot will actually mention this user.
This was the simplest example, but there are so many edge cases that I can't deal with, for example, what if the the person has spaces in his name, how do you know when the name ends? Here's is the most complicated example I could make:
socket_str = "Hey I'm looking for #The New Beast is he online?, or #Newly Born Beast or #someone that doesnt exists is on?"
I'm looking for a different approach for this, I could share what I wrote so far which is a lot but honestly it's so complex code even I don't understand from it much anymore
This is actually very non-trivial. You've already said it yourself
"if the the person has spaces in his name, how do you know when the name ends?"
The only option I can think of to reliably check if a username (containing spaces) exists is to iteratively check each combination of spaced words as long as a certain semantic criteria is met.
In Discord, the only restrictions usernames have is that it can be at max 32 characters long. AFAIK you can have every symbol, emoji whatsoever in your name...
To illustrate, the statements would look something like this
string = "Hello #This is a username! Whats up?"
# is "This" a username?
# yes -> great! | no -> is "This is" a username?
# yes -> great! | no -> is "This is a" a username?
# yes -> great! | no -> is "This is a username!" a username?
# ...
However, this is also another edge case. This is a username is a valid user, but by spliting with spaces the program would look for This is a username!, which isn't valid. So as far as I can tell, the best option to say for sure, if a username is valid is to actually check for each character until the max length of Discord usernames.
This could be implemented like so
string = "Hello #This is a username! Whats up?"
potentialUsernames = string.split("#") # Split string into potential usernames
del potentialUsernames [0] # Delete first element, as it is definitely not a username
for potentialUsername in potentialUsernames: # for every potential username, do
for run, letter in enumerate(potentialUsername): # for every letter in every potential username, do
checkUsername = potentialUsername[:(run+1)]
if run > 32:
break # break out of this loop as there cant be a username here anymore
potentialMember = guild.get_member_named(checkUsername) # check if potential username exists
if potentialMember != None: # BOOM, we found a member!
string = string.replace("#" + checkUsername, potentialMember.mention) # replace the username with real mention in string
break # break because the user was already found
The output of print(string) would be
"Hello <#!1234567891011121314>! Whats up?"
yes.. this is how mentions would look in text-form, if you didn't know. The long number would be the user-id, however Member.mention already constructs this for you!
In this code, guild will have to be the guild object, of which you want to get the members from.
Now, what this code does is checking every potential username split by #, and check for every possible length until the next #, or Discords restriction of 32 characters.
I.e.
# is "T" a username?
# yes -> great | no -> is "Th" a username?
# yes -> great | no -> is "Thi" a username?
# ...
As a side note, this method should work with any amount of mentions!

how to convert string contains list to regular list in python?

I have an the following function in Apache Airflow:
from airflow.utils.email import send_email
send_email(to=['a#mail.com','b#mail.com'],
subject=....)
This works great.
Now I don't want to hard code the email list so I save it as a configurable field that the user can change from his UI.
So I change my code to:
NOTIFY_LIST = Variable.get("a_emails")
send_email([NOTIFY_LIST],
subject=....)
But this doesn't work.
When I do:
logging.info(NOTIFY_LIST)
logging.info([NOTIFY_LIST])
logging.info(NOTIFY_LIST.split(','))
I see:
'a#mail.com', 'b#mail.com'
[u"'a#mail.com', 'b#mail.com'"]
[u"'a#mail.com'", u" 'b#mail.com'"]
So my problem is that:
['a#mail.com','b#mail.com']
and
[NOTIFY_LIST]
isn't the same.
How can I fix this? I tried any conversion I could think of.
A suggestion to try the following;
logging.info(NOTIFY_LIST.replace("'", "").split(','))
The problem here is that the elements in the list contain quote marks.
The other answer will fail if there's an ' in the midle of the strings, to fix that I'll use str.strip:
logging.info([s.strip("' ") for s in NOTIFY_LIST.split(',')])

Python - Searching a dictionary for strings

Basically, I have a troubleshooting program, which, I want the user to enter their input. Then, I take this input and split the words into separate strings. After that, I want to create a dictionary from the contents of a .CSV file, with the key as recognisable keywords and the second column as solutions. Finally, I want to check if any of the strings from the split users input are in the dictionary key, print the solution.
However, the problem I am facing is that I can do what I have stated above, however, it loops through and if my input was 'My phone is wet', and 'wet' was a recognisable keyword, it would go through and say 'Not recognised', 'Not recognised', 'Not recognised', then finally it would print the solution. It says not recognised so many times because the strings 'My', 'phone' and 'is' are not recognised.
So how do I test if a users split input is in my dictionary without it outputting 'Not recognised' etc..
Sorry if this was unclear, I'm quite confused by the whole matter.
Code:
import csv, easygui as eg
KeywordsCSV = dict(csv.reader(open('Keywords and Solutions.csv')))
Problem = eg.enterbox('Please enter your problem: ', 'Troubleshooting').lower().split()
for Problems, Solutions in (KeywordsCSV.items()):
pass
Note, I have the pass there, because this is the part I need help on.
My CSV file consists of:
problemKeyword | solution
For example;
wet Put the phone in a bowl of rice.
Your code reads like some ugly code golf. Let's clean it up before we look at how to solve the problem
import easygui as eg
import csv
# # KeywordsCSV = dict(csv.reader(open('Keywords and Solutions.csv')))
# why are you nesting THREE function calls? That's awful. Don't do that.
# KeywordsCSV should be named something different, too. `problems` is probably fine.
with open("Keywords and Solutions.csv") as f:
reader = csv.reader(f)
problems = dict(reader)
problem = eg.enterbox('Please enter your problem: ', 'Troubleshooting').lower().split()
# this one's not bad, but I lowercased your `Problem` because capital-case
# words are idiomatically class names. Chaining this many functions together isn't
# ideal, but for this one-shot case it's not awful.
Let's break a second here and notice that I changed something on literally every line of your code. Take time to familiarize yourself with PEP8 when you can! It will drastically improve any code you write in Python.
Anyway, once you've got a problems dict, and a problem that should be a KEY in that dict, you can do:
if problem in problems:
solution = problems[problem]
or even using the default return of dict.get:
solution = problems.get(problem)
# if KeyError: solution is None
If you wanted to loop this, you could do something like:
while True:
problem = eg.enterbox(...) # as above
solution = problems.get(problem)
if solution is None:
# invalid problem, warn the user
else:
# display the solution? Do whatever it is you're doing with it and...
break
Just have a boolean and an if after the loop that only runs if none of the words in the sentence were recognized.
I think you might be able to use something like:
for word in Problem:
if KeywordsCSV.has_key(word):
KeywordsCSV.get(word)
or the list comprehension:
[KeywordsCSV.get(word) for word in Problem if KeywordsCSV.has_key(word)]

Python splitting values from urllib in string

I'm trying to get IP location and other stuff from ipinfodb.com, but I'm stuck.
I want to split all of the values into new strings that I can format how I want later. What I wrote so far is:
resp = urllib2.urlopen('http://api.ipinfodb.com/v3/ip-city/?key=mykey&ip=someip').read()
out = resp.replace(";", " ")
print out
Before I replaced the string into new one the output was:
OK;;someip;somecountry;somecountrycode;somecity;somecity;-;42.1975;23.3342;+05:00
So I made it show only
OK someip somecountry somecountrycode somecity somecity - 42.1975;23.3342 +05:00
But the problem is that this is pretty stupid, because I want to use them not in one string, but in more, because what I do now is print out and it outputs this, I want to change it like print country, print city and it outputs the country,city etc. I tried checking in their site, there's some class for that but it's for different api version so I can't use it (v2, mine is v3). Does anyone have an idea how to do that?
PS. Sorry if the answer is obvious or I'm mistaken, I'm new with Python :s
You need to split the resp text by ;:
out = resp.split(';')
Now out is a list of values instead, use indexes to access various items:
print 'Country: {}'.format(out[3])
Alternatively, add format=json to your query string and receive a JSON response from that API:
import json
resp = urllib2.urlopen('http://api.ipinfodb.com/v3/ip-city/?format=json&key=mykey&ip=someip')
data = json.load(resp)
print data['countryName']

"ValueError: list.index(x): x not in list" in Python, but it exists

I want to use Python to pull the username from an email address. The solution I thought of was to append the email address into a list, find the index of the # symbol, and then slice the list until I found the index.
My code is:
#!/usr/bin/env python<br/>
email = raw_input("Please enter your e-mail address: ")
email_list = []
email_list.append(email)
at_symbol_index = email_list.index("#")
email_username = email_list[0:at_symbol_index]
print email_username
But, everytime I run the script, it returns the error:
ValueError: list.index(x): x not in list
What's wrong with my code?
The reason for this is that you are making a list containing the string, so unless the string entered is "#", then it is not in the list.
To fix, simply don't add the email address to a list. You can perform these operations on a string directly.
As a note, you might want to check out str.split() instead, or str.partition:
email_username, _, email_host = email.partition("#")
You add the entire e-mail address to a list. Did you perhaps mean
email_list = list(email)
which adds the characters of email (as opposed to the whole string at once). But even this is unnecessary, as strings can be sliced / indexed much like lists (so you don't need a list at all in this case).
An easier way to determine the username of an e-mail address would probably be
email.split("#")[0]

Categories