Searching for an equal string? - python

I am not sure how to word the question title.
a = "Alpha";
b = "Bravo";
c = "Charlie";
fn = input("What is your first name: ")
for fletter in fn.split():
fl = fletter[0]
The code above gets the first letter entered. The goal is to then get the first letter to possible check in a while loop to see if the value of fl = one of the starting strings. Is that possible to do? Tips on where to begin?

Solution 1 [Using a dictionary]
Also makes things much simpler.
In this case, instead of defining separate variables for each string, you store them in a dictionary. So for example, instead of this:
a = "Alpha"
b = "Bravo"
c = "Charlie"
You would have this:
letterwords = {"a":"Alpha", "b":"Bravo", "c":"Charlie"}
This works very similarly to a list, however instead of indexing the dictionary you would reference to separate objects inside a dictionary according to its key. So if the dictionary letterwords is defined as above, you would reference to the string Alpha by calling letterwords["a"]. Therefore, in this case, the code would look something like this:
letterwords = {"a":"Alpha", "b":"Bravo", "c":"Charlie"}
fn = input("Please enter your first name: ")
try:
letterwords[fn[0]]
except KeyError:
print("There is no matching variable with that letter in the database.")
Solution 2 [Using the eval() function]
Not recommended.
This is perfectly possible, with the eval function. However, you should be aware that this is a quite dangerous function to run, as malicious users can use this to control the console. (Especially if you imported os.) However, it should get you over the hump for now. Here's the code:
a = "Alpha"
b = "Bravo"
c = "Charlie"
fl = input("Please enter your first name: ")
try:
compared = eval(fl[0])
except NameError:
print("Your first name's first letter does not match any strings in the database.")
More information on the eval() function here: https://docs.python.org/3/library/functions.html#eval
Hope this helped!

Related

Append number to list if string matches list name

I am trying to write a Python program as following:
list_a = []
list_b = []
list_c = []
listName = str(input('insert list name: '))
listValue = int(input('insert value: '))
listName.append(listValue)
But unfortunately "listName.append()" won't work.
Using only IF functions as in:
if listName == 'list_a':
list_a.append(listValue)
is impractical because I am actually working with 600+ lists...
Is there any other way I could do to make something like this work properly??
Help is much appreciated!
Thank you very much in advance!!
When you're tempted to use variable names to hold data — like the names of stocks — you should almost certainly be using a dictionary with the data as keys. You can still pre-populate the dictionary if you want to (although you don't have to).
You can change your existing to code to something like:
# all the valid names
names = ['list_a', 'list_b', 'list_c']
# pre-populate a dictionary with them
names = {name:[] for name in names}
# later you can add data to the arrays:
listName = str(input('insert list name: '))
listValue = int(input('insert value: '))
# append value
names[listName].append(listValue)
With this, all your data is in one structure. It will be easy to loop through it, make summary statistics like sums/averages act. Having a dictionary with 600 keys is no big deal, but having 600 individual variables is a recipe for a mess.
This will raise a key error if you try to add a name that doesn't exists, which you can catch in a try block if that's a possibility.
Keep your lists in a dict. You could initialize your dict from a file, db, etc.
lists = {"GOOG": []}
listName = str(input('insert list name: '))
listValue = int(input('insert value: '))
lists.setdefault(listName,[]).append(listValue)
# Just a little output to see what you've got in there...
for list_name, list_value in lists.items():
print(list_name, list_value)
So, following Mark Meyer's and MSlimmer's suggestions above, I am using a dictionary of lists to simplify data input, which has made this section of my program work flawlessly (thanks again, guys!).
However, I am experiencing problems with the next section of my code (which was working before when I had it all as lists haha). I have a dictionary as below:
names = {'list_a':[5, 7, -3], 'list_b':[10, 12, -10, -10]}
Now, I have to add up all positives and all negatives to each list. I want it to have the following result:
names_positives = {'list_a': 12, 'list_b': 22}
names_negatives = {'list_a': -3, 'list_b': -20}
I have tried three different ways, but none of them worked:
## first try:
names_positives = sum(a for a in names.values() if a > 0)
## second try:
names_positives = []
names_positives.append(a for a in names.values() if compras > 0)
## third try:
names_positives = dict(zip(names.keys(), [[sum(a)] for a in names.values() if compra > 0]))
To be honest, I have no idea how to proceed -- I am getting errors due to mixing strings and integers in those lines, and I am not being able to work some way around this problem... Any help is much appreciated. It could result in a dictionary, in a list or even in only the total sum (as in the first try, under no better circumstances).
Cheers!
You can try this one:
I just added one line for your code to work.
list_a = ['a']
list_b = []
list_c = []
listName = str(input('insert list name: '))
listValue = int(input('insert value: '))
eval(listName).append(listValue)
the eval function evaluates the string into an actual python expression. It should be noted however that there are security issues regarding the use of eval. But for the exact question that you were trying to answer, this would be the easiest way that wouldn't require much refactoring of the existing code.

Displaying the first name alphabetically and last name alphabetically after being given a list of names from the user in python

Design a program that asks the user for a series of names (in no particular order). After the final person's name has been entered, the program should display the name that is first alphabetically and the name that is last alphabetically. For example, if the user enters the names Kristin, Joel, Adam, Beth, Zeb, and Chris, the program would display Adam and Zeb.
Note: A condition-controlled loop must be used. The user will enter a sentinel value of DONE to indicate that there are no more names to be input.
We really haven't gone over this in class and I've tried looking it up online to see if I can understand anything but most of the people are asking about it in java or C++.
My Code:
# Prompt user to enter names
names = input("Enter the names: ")
# breakdown the names into a list
words = names.split()
# sort the names
words.sort()
# display the sorted names
print("The sorted names are:")
for word in words:
print(word)
Best way to learn is to try it yourself. Most import things is (imho) to read the assignment carefully and then break it down in smaller, but easier to solve problems:
# init names list
names = []
# get input
while True:
name = input("Enter a name:")
# end while loop, when name = 'DONE'
if name == "DONE":
break;
else:
# else add it to 'names' list
names.append(name)
# Do some sorting of the list
names.sort()
# Print the first item of a list
print(names[0])
# Print the last item of a list
print(names[-1])
Here is a code that will solve your problem:
print("Keep entering names by typing space bar after every name. Once done, press Enter")
final_list = list(map(str, input().rstrip().split()))
final_list.sort()
print("The first name is {}. The last name is {}".format(final_list[0],final_list[-1]))

Sorting on list values read into a list from a file

I am trying to write a routine to read values from a text file, (names and scores) and then be able to sort the values az by name, highest to lowest etc. I am able to sort the data but only by the position in the string, which is no good where names are different lengths. This is the code I have written so far:
ClassChoice = input("Please choose a class to analyse Class 1 = 1, Class 2 = 2")
if ClassChoice == "1":
Classfile = open("Class1.txt",'r')
else:
Classfile = open("Class2.txt",'r')
ClassList = [line.strip() for line in Classfile]
ClassList.sort(key=lambda s: s[x])
print(ClassList)
This is an example of one of the data files (Each piece of data is on a separate line):
Bob,8,7,5
Fred,10,9,9
Jane,7,8,9
Anne,6,4,8
Maddy,8,5,5
Jim, 4,6,5
Mike,3,6,5
Jess,8,8,6
Dave,4,3,8
Ed,3,3,4
I can sort on the name, but not on score 1, 2 or 3. Something obvious probably but I have not been able to find an example that works in the same way.
Thanks
How about something like this?
indexToSortOn = 0 # will sort on the first integer value of each line
classChoice = ""
while not classChoice.isdigit():
classChoice = raw_input("Please choose a class to analyse (Class 1 = 1, Class 2 = 2) ")
classFile = "Class%s.txt" % classChoice
with open(classFile, 'r') as fileObj:
classList = [line.strip() for line in fileObj]
classList.sort(key=lambda s: int(s.split(",")[indexToSortOn+1]))
print(classList)
The key is to specify in the key function that you pass in what part of each string (the line) you want to be sorting on:
classList.sort(key=lambda s: int(s.split(",")[indexToSortOn+1]))
The cast to an integer is important as it ensures the sort is numeric instead of alphanumeric (e.g. 100 > 2, but "100" < "2")
I think I understand what you are asking. I am not a sort expert, but here goes:
Assuming you would like the ability to sort the lines by either the name, the first int, second int or third int, you have to realize that when you are creating the list, you aren't creating a two dimensional list, but a list of strings. Due to this, you may wish to consider changing your lambda to something more like this:
ClassList.sort(key=lambda s: str(s).split(',')[x])
This assumes that the x is defined as one of the fields in the line with possible values 0-3.
The one issue I see with this is that list.sort() may sort Fred's score of 10 as being less than 2 but greater than 0 (I seem to remember this being how sort worked on ints, but I might be mistaken).

Python skipping some lines in for loop

I've got a script I'm writing, and have a function that should search a dictionary with this layout:
{
1 : ['name1','name2','name3','name4','name5'],
2 : ['name1','name2','name3','name4','name5']
}
for a word. Here's the function:
def find_student(list_curr):
''' (str, dict) -> list
Input is the student's name and the dictionary of lists that they should exist in; output is a list in the format:
[group,index]
'''
while True:
try:
stu_name = input("\nPlease enter the first or last name of the student, or press enter to exit:\n> ")
if not stu_name:
return False
else:
break
except ValueError:
print("Please enter a valid name")
for g,s in list_curr.items():
print("G",g)
print("S",s)
if any(stu_name in n for n in s):
# name was in group
print("\nFound a possible match: {} (group {}):".format(s[s.index(stu_name)],g))
pp.pprint(s)
if input("\nIs this the student you're looking for?\n> ") in "yesYES":
# found the correct student
print("Saving {} for group and {} for index.".format(g,s.index(stu_name)))
stu_info = [g,s.index(stu_name)]
return stu_info
# nothing was found
print("\n{} was not found in the list.".format(stu_name))
return False
When I run it, though, it breaks as soon as it finds a match. Everything below the if any(): part is not run, and it just returns without even printing the Found a possible match... line. I've tried using the debugger in IDLE but it continually crashes whenever I open it. I've seen other posts really similar to this, but don't understand where I'm going wrong. Any ideas?
Edit: sorry, had for any(), should be if any().
You may be getting a ValueError on
if any(stu_name in n for n in s):
# name was in group
print("\nFound a possible match: {} (group {}):".format(s[s.index(stu_name)],g))
any(stu_name in n for n in s) checks if stu_name occurs as a substring of a string in list s.
The s.index(stu_name) however tries to find the index of an exact match between stu_name and the elements within s.
Try substituting example values to see what's going on:
s = ['James Joyce', 'Tom Stoppard', 'William Shakespeare']
stu_name = 'William'
print(any(stu_name in name for name in s))
print(s.index(stu_name))
Not sure why you're not seeing an Exception, perhaps there's a naked Except clause somewhere else in your code?
If the above issue is your problem, maybe write an inline function like this within find_student:
def get_index(stu_name, names):
for index, name in enumerate(names):
if stu_name in name:
return index
and call get_index(stu_name, s) instead of s.index(stu_names).
Alternatively, maybe you just want to edit your code so that you only accept exact matches.
In which case,
if any(stu_name in name for name in s):
becomes
if stu_name in s:
And the user needs to enter "William Shakespeare" instead of just "William".
P.S. This isn't what was asked for in the op, but...
What happens if there are multiple people with the inputted first/last name in the same group? As I see it, it looks like the script will only give the user the option to choose the index of the first match, and if the user says this isn't the student in question, the script starts looking at the next group, rather than returning the next index within the same group.

Python- Use value of pop as object name

I am taking in user input and creating objects with it. So I have a list of acceptable object names (A-E). What I figured I could do was pop(0) and use the return value as the name of the object. This way there is never a duplicate object name upon entry. Here is what I have so far I just cannot figure out how to assign the popped value to the name of the object properly.(Net is a defined class at the start of the program)
userIP = None
name_list = ['A', 'B', 'C', 'D', 'E']
while True:
if userIP == 'end':
break
userIP = input("Enter IP (type 'end' to exit): ")
userMask = input("Enter Mask: ")
name_list.pop(0) = Net(userIP, userMask)
print("The object just created would print here")
Put the results in a dictionary. Don't try to create variables with specified names. That way lies madness.
net_dict = {}
# ...
name = name_list.pop(0)
net_dict[name] = Net(userIP, userMask)
print(net_dict[name])
If you have them in a container, you may find you don't actually need the names. What are the names for, in other words? If the answer is just "to keep them in some order," use a list:
net_list = []
# ...
net_list.append(Net(userIP, userMask))
print(net_list[-1])
I just cannot figure out how to assign the popped value to the name of the object properly
It's not easy to do that, because it's not very useful to do that. What if you do get it to work, and you want to use the thing later on?
name_list.pop(0) = Net(userIP, userMask)
print ?.userMask
What do you put for the ? when you have no idea which variable name was used?
The right approach to this is #kindall's answer, or similar. But it is possible ( How can you dynamically create variables via a while loop? ) but not recommended.

Categories

Resources