How to change an input() to lower case? - python-3.x

I'm new to python and trying my best to learn. At this moment I'm following to program along with YouTube. But I got stuck with this piece of code where I'm trying to change user input to lowercase and comparing it to a list to see if item is available or not. And ever time I ran code I get Not available. Here is the code:
stock = ['Keyboard', 'Mouse', 'Headphones', 'Monitor']
productName = input('Which product would you like to look up:').lower()
if productName in stock
print('Available')
else:
print('Not Available')
- List item

Change your stock array to be all lowercase, like so:
stock = ['keyboard', 'mouse', 'headphones', 'monitor']
Because you modify the user input to be lowercase, no matter what, and the stock items in the array are capitalized, no matter what, they will never match in your if statement. String comparison in Python is case sensitive (as it is in nearly every programming language).

Related

Is there a way to only list a certain format of text from a list?

I am quite new to python.
And i want to only get a certain format from a bigger list, example:
Whats in the list:
/ABC/EF213
/ABC/EF
/ABC/12AC4
/ABC/212
However the only on i want listed are the ones with this format /###/##### while the rest gets discarded
You could use a generator expression or a for loop to check each element of the list to see if it matches a pattern. One way of doing this would be to check if the item matches a regex pattern.
As an example:
import re
original_list = ["Item I don't want", "/ABC/EF213", "/ABC/EF", "/ABC/12AC4", "/ABC/212", "123/456", "another useless item", "/ABC/EF"]
filtered_list = [item for item in original_list if re.fullmatch("\/\w+\/\w+", item) is not None]
print(filtered_list)
outputs
['/ABC/EF213', '/ABC/EF', '/ABC/12AC4', '/ABC/212', '/ABC/EF']
If you need help making regex patterns, there are many great websites such as regexr which can help you
Every String can be used as a list without any conversion. If the only format you want to check is /###/##### then you can simply make if commands like these:
for text in your_list:
if len(text) == 10 and text[0] == "/" and text[4] == "/" (and so on):
print(text)
Of course this would require a lot of if statements and would take a pretty long time. So I would recomend doing a faster and simpler scan. We could perform this one by, for example, splitting the texts, which would look something like this:
for text in your_list:
checkstring = text.split("/")
Now you have your text Split in parts, and you can simply check what lengths these new parts have with the len() command.

Entering a word and then searching through and array of words to find the word

I am trying to create a program which checks to see if words entered (when run) are in an array. I would like to use a loop for this.
I have created a list of words and tried a for loop however the code is proving to be erroneous.
def Mylist():
Mylist= [Toyota,BMW,Pontiac,Cadillac,Ford,Opel]
Search=input("Enter a word")
Mylist[1]="Toyota"
for loop in range (1,6):
if Mylist[loop]==Search:
print("found")
break
I have repeated line 4 for the other car manufacturers.
TypeError: 'function' object does not support item assignment
First, here some recommendations to start:
Indentation in Python is IMPORTANT, be careful to have the right indentation. You must take special care when posting code here in SO so your code does not look like complete gibberish.
You should read Naming conventions. TL;DR we use snake_case for naming functions and variables.
If you are not using an IDE (such as PyCharm) to program, or something intelligent that shows the information on functions, you should always check out the documentation (it is beautiful).
Check out the difference between "Toyota" and Toyota. The first one has quotes, it is a string (i.e. chain of characters), it is a primitive type such as integer and boolean; the second is a token that is to be evaluated, it has to be defined before, such as variables, functions and classes.
Search in the docs if there is an in-built function that already does the job you want.
Check out return values in functions. Functions evaluate to None when you do not explicit a return value.
Now to your question. As some people pointed out, there is the in keyword that does exactly what you want.
CAR_BRANDS= ["Toyota", "BMW", "Pontiac", "Cadillac", "Ford","Opel"]
def check_car():
word = input("Enter a word: ")
if word in CAR_BRANDS:
print("found")
return True
print("not found")
return False
If you don't care about the print you can just do return word in CAR_BRANDS
If you actually want to challenge yourself to write the logic, you were right in choosing a for-loop to iterate over the list.
Index in Python starts from 0, and that range does not give you all the indexes to iterate over your list, you are missing the 0 index. Also, we don't like magic numbers, instead of hard-coding the length of your list of car brands, better compute the length!
for i in range(len(CAR_BRANDS)):
if CAR_BRANDS[i] == word:
print("found")
But even better you can directly iterate over the items in your list, no need to do the range, which will give you something like:
CAR_BRANDS= ["Toyota", "BMW", "Pontiac", "Cadillac", "Ford","Opel"]
def check_car():
word = input("Enter a word: ")
for brand in CAR_BRANDS:
if brand == word:
print("found")
return True
print("not found")
return False
If you have any more questions, do not hesitate! Happy coding.

Finding Close String Matches - valuing sub string word matches higher

I'm trying to find close string matches (context - searching for a discord user from user input).
Atm, I'm trying out the difflib. It works ok, but seems to return some funny results sometimes. Eg. if someone's name contains a word, searching that word may result in something that seems far off instead of that name.
I think that's just because of how get_close_matches works. Could I be suggested some other libraries to try out? (Not sure how to quantify what I'm after, but maybe I want a searcher that gives a higher score to names containing a similar word to the search term)
user_names = []
for member in server.members:
if member.name is not None: user_names.append(member.name)
if member.nick is not None: user_names.append(member.nick)
user_name = difflib.get_close_matches(user_msg, user_names, n = 1, cutoff = 0.2)
I've used https://github.com/seatgeek/fuzzywuzzy for this in the past which provides a few options out of the box from single words to tokenizing and sorting larger strings.

Create a list (length and int values defined by user input) and then find lowest value in list and exclude from proceeding calculation

I am having trouble with making a simple calculator work. There are some requirements I need to meet with it:
Need to be able to calculate the average of however many grades the user wants
Be able to calculate within the same program separate grade averages
for multiple 'users'
Give the option to exclude the lowest value entered for each person
from their individual average calculation.
I have some code, it is pretty much a mess:
def main():
Numberofstudents=eval(input("How many students will enter grades today? "))
Name=input("What is your frist and last name? ")
numberofgrades=eval(input("How many grades do you want to enter? "))
gradecount=0
studentcount=1
lowestgradelisty=[]
while studentcount<=Numberofstudents:
gradetotal=0
while gradecount<numberofgrades:
gradeforlisty=eval(input("Enter grade please: "))
gradetotal=gradetotal+gradeforlisty
gradecount=gradecount+1
Numberofstudents=Numberofstudents-1
studentcount=studentcount+1
lowestgradelisty.extend(gradeforlisty)
min(lowestgradelisty.extend(gradeforlisty))
Drop=(min(lowestgradelisty.extend(gradeforlisty))), "is your lowest grade. do you want to drop it? Enter as yes or no: "
if (Drop=="yes"):
print(Name, "The new total of your grades is", gradetotal-min(lowestgradelisty.append(gradeforlisty)/gradecount))
elif (Drop=="no"):
print("the averages of the grades enetered is", gradetotal/gradecount)
gradecount=0
studentcount=1
main()
Here's a function that does what it sounds like you wanted to ask about. It removes the smallest grade and returns the new average.
def avgExceptLowest(listofgrades):
# find minimum value
mingrade = min(listofgrades)
# remove first value matching the minimum
newgradelist = listofgrades.remove(mingrade)
# return the average of of the new list
return sum(newgradelist) / len(newgradelist)
A number of notes on your code:
The indentation of the code in your question is wrong. Fixing it may solve some of your problems if that's how it appears in your python file.
In Python the convention is to never capitalize a variable, and that's making your highlighting come out wrong.
If you code this correctly, you won't need any tracking variables like studentcount or gradecount. Check out Python's list of built-in functions and use things like len(lowestgradelisty) and loops like for i in range(0, numberofstudents): instead to keep your place as you execute.

Creating a function that creates two lists in Python 3

I am trying to create a function, getStocks, that gets from the user two lists, one containing the list of stock names and the second containing the list of stock prices. This should be done in a loop such that it keeps on getting a stock name and price until the user enters the string 'done' as a stock name. The function should return both lists. My main issues are figuring out what my parameters are, how to continuously take in the name and price, and what type of loop I should be using. I am very new to programming so any help would be appreciated. I believe I'm close but I am unsure where my errors are.
def getStocks(name,price):
stockNames = []
stockPrices = []
i = 0
name = str(input("What is the name of the stock?"))
price = int(input("what is the price of that stock?"))
while i < len(stockNames):
stockNames.append(name)
stockPrices.append(price)
i += 1
else:
if name = done
return stockNames
return stockPrices
Your question is a bit unclear but some things off the bat, you cant have two return lines, once you hit the first, it leaves the function. Instead you'do write something like
return (stockNames, stockPrices)
Secondly while loops dont have an else, so you'd actually set up your while loop, then setup an if statement at the beginning to check if the string is 'done', then act accordingly. Break will get you out of your last while loop, even though it looks like it's associated with the if. So something like this:
while i < len(stockNames):
if name.upper() == 'DONE':
break
else:
stockNames.append(name)
stockPrices.append(price)
i += 1
Also you have to use == (comparison) instead of = (assignment) when you check your name = done. And dont forget done is a string, so it needs to be in quotations, and I used .upper() to make the input all caps to cover if its lower case or uppercase.
If you can clear up your question a little bit, I can update this answer to include everything put together. I'm not quite understanding why you want to input a list and then also take user input, unless you're appending to that list, at which point you'd want to put the whole thing in a while loop maybe.
Update:
Based on your comment, you could do something like this and enclose the whole thing in a while loop. This takes the incoming two lists (assuming you made a master list somewhere) and sends them both into the getStocks function, where someone can keep appending to the pre-existing list, and then when they type done or DONE or DoNe (doesn't matter since you use .upper() to make the input capitalized) you break out of your while loop and return the updated lists:
def getStocks(name, price):
stockNames = name
stockPrices = price
while 1:
inputName = str(input("What is the name of the stock?"))
inputPrice = int(input("what is the price of that stock?"))
if name.upper() != 'DONE':
stockNames.append(inputName)
stockPrices.append(inputPrice)
else:
break
return (stockNames, stockPrices)
But really, depending on the rest of the structure, you might want to make a dictionary instead of having 2 separate lists, that way everything stays in key:value pairs, so instead of having to check index 0 on both and hoping they didn't get shifted by some rogue function, you'd have the key:value pair of "stock_x":48 always together.

Resources