Python List object attribute 'append' is read-only - python

as the title says, in python, I'm trying to make it so when someone types in a choice (in this case Choice13) then it deletes the old password from the list passwords and adds the new one instead.
passwords = ['mrjoebblock' , 'mrjoefblock' , 'mrjoegblock', 'mrmjoeadmin' ]
if choice == '3':
password = raw_input('Welcome admin! I\'m going to need your password ')
if password == 'mrjoeadmin':
print('Welcome Mr. Joe!')
Choice11 = raw_input('What would you like to do? Press 1 for changing your admin password, 2 for viewing a class\'s comments, or 3 for changing a class\'s password')
if Choice11 == '1':
print('You have chosen to change your password! ')
Choice12 = raw_input('You will need to put in your current password to access this feature ')
if Choice12 == 'mrmajoeadmin':
Choice13 = raw_input('What would you like to change your password to? ')
passwords.remove('mrjoeadmin')
passwords.append = Choice13

To append something to a list, you need to call the append method:
passwords.append(Choice13)
As you've seen, assigning to the append method results in an exception as you shouldn't be replacing methods on builtin objects -- (If you want to modify a builtin type, the supported way to do that is via subclassing).

or you could modify the same list slot by doing:
passwords[passwords.index('mrjoeadmin')] = Choice13

Related

How can I create an input that will loop and create a new list each time?

in case it isn't already obvious im new to python so if the answers could explain like im 5 years old that would be hugely appreirecated.
I'm basically trying to prove to myself that I can apply some of the basic that I have learnt into making a mini-contact book app. I don't want the data to save after the application has closed or anything like that. Just input your name, phone number and the city you live in. Once multiple names are inputted you can input a specific name to have their information printed back to you.
This is what I have so far:
Name = input("enter name here: ")
Number = input("enter phone number here: ")
City = input("enter city here: ")
User = list((Name, Number, City))
This, worked fine for the job of giving python the data. I made another input that made python print the information back to me just to make sure python was doing what I wanted it to:
print("Thank you! \nWould you like me to read your details back to you?")
bck = input("Y / N")
if bck == "Y":
print(User)
print("Thank you! Goodbye")
else:
print("Goodbye!")
The output of this, is the list that the user creates through the three inputs. Which is great! I'm happy that I have managed to make it function so far;
But I want the 'Name' input to be what names the 'User' list. This way, if I ask the user to input a name, that name will be used to find the list and print it.
How do I assign the input from Name to ALSO be what the currently named "User" list
You will need to create a variable which can store multiple contacts inside of it. Each contact will be a list (or a tuple. Here I have used a tuple, but it doesn't matter much either way).
For this you could use a list of lists, but a dictionary will be more suitable in this case.
What is a dictionary?
A dictionary is just like a list, except that you can give each of the elements a name. This name is called a "key", and it will most commonly be a string. This is perfect for this use case, as we want to be able to store the name of each contact.
Each value within the dictionary can be whatever you want - in this case, it will be storing a list/tuple containing information about a user.
To create a dictionary, you use curly brackets:
empty_dictionary = {}
dictionary_with_stuff_in_it = {
"key1": "value1",
"key2": "value2"
}
To get an item from a dictionary, you index it with square brackets, putting a key inside the square brackets:
print(dictionary_with_stuff_in_it["key1"]) # Prints "value1"
You can also set an item / add a new item to a dictionary like so:
empty_dictionary["a"] = 1
print(empty_dictionary["a"]) # Prints 1
How to use a dictionary here
At the start of the code, you should create an empty dictionary, then as input is received, you should add to the dictionary.
Here is the code I made, in which I have used a while loop to continue receiving input until the user wants to exit:
contacts = {}
msg = "Would you like to: \n - n: Enter a new contact \n - g: Get details for an existing contact \n - e: Exit \nPlease type n, g, or e: \n"
action = input(msg)
while action != "e":
if action == "n": # Enter a new contact
name = input("Enter name here: ")
number = input("Enter phone number here: ")
city = input("Enter city here: ")
contacts[name] = (number, city)
print("Contact saved! \n")
action = input(msg)
elif action == "g": # Get details for an existing contact
name = input("Enter name here: ")
try:
number, city = contacts[name] # Get that contact's information from the dictionary, and store it into the number and city variables
print("Number:", number)
print("City:", city)
print()
except KeyError: # If the contact does not exist, a KeyError will be raised
print("Could not find a contact with that name. \n")
action = input(msg)
else:
action = input("Oops, you did not enter a valid action. Please type n, g, or e: ")
#can be easier to use with a dictionary
#but its just basic
#main list storing all the contacts
Contact=[]
#takes length of contact list,'int' just change input from string to integer
contact_lenght=int(input('enter lenght for contact'))
print("enter contacts:-")
#using for loop to add contacts
for i in range(0,len(contact_lenght)):
#contact no.
print("contact",i+1)
Name=input('enter name:')
Number=input('enter number:')
City=input("enter city:")
#adding contact to contact list using .append(obj)
Contact.append((Name,Number,City))
#we can directly take input from user using input()
bck=input("Thank you! \nWould you like me to read your details back to you?[y/n]:")
#checking if user wants to read back
if bck=='y':
u=input("enter your name:")
#using for loop to read contacts
for i in range(0,len(Contact)):
#if user name is same as contact name then print contact details
if u==Contact[i][0]:
print("your number is",Contact[i][1])
print("your city is",Contact[i][2])
else:
#if user doesnt want to read back then print thank you
print("Good bye")
For this purpose you should use a dictionary.
The key of every entry should be the string 'User[0]' that corresponds to the person's name.
The contents of every entry should be the list with the information of that user.
I'll give you an example:
# first we need to create an empty dictionary
data = {}
# in your code when you want to store information into
# the dictionary you should do like this
user_name = User[0] # this is a string
data[user_name] = User # the list with the information
If you want to access the information of one person you should do like this:
# user_you_want string with user name you want the information
data[user_you_want]
Also you can remove information with this command:
del data[user_you_want_to_delete]
You can get more information on dictionaries here: https://docs.python.org/3/tutorial/datastructures.html#dictionaries
You should start by defining a class to support name, phone and city. Once you've done that, everything else is easy.
class Data:
def __init__(self, name, city, phone):
self.name = name
self.city = city
self.phone = phone
def __eq__(self, other):
if isinstance(other, str):
return self.name == other
if isinstance(name, type(self)):
return self.name == other.name and self.city == other.city and self.phone == other.phone
return False
def __str__(self):
return f'Name={self.name}, City={self.city}, Phone={self.phone}'
DataList = []
while (name := input('Name (return to finish): ')):
city = input('City: ')
phone = input('Phone: ')
DataList.append(Data(name, city, phone))
while (name := input('Enter name to search (return to finish): ')):
try:
print(DataList[DataList.index(name)])
except ValueError:
print('Not found')

Why IF statement become false , If I write a name present in the nested list

When I input "Ali" it jumps to new user statement. Anyone please explain me why?
Data_base = [["Ali","1234","5000"],["Sara","1234","2000"]]
User_name = input("Enter your name")
if User_name in Data_base:
print("User persent")
elif User_name not in Data_base:
print("New User")
New_User_name = input("Your name: ")
Data_base.append(New_User_name)
print(Data_base)
The problem is that your list is made up of two separate lists.
Data_base = [["Ali","1234","5000"],["Sara","1234","2000"]]
So when you check if the input is in the list, Python checks if any of the internal values are equal to the input. i.e.:
input = ["Ali","1234","5000"] or input = ["Sara","1234","2000"]
By grouping it into a list I assume the second and third values belong to the first value. Instead of the list I would suggest using a dictionary:
Data_base = {"Ali" : ["1234","5000"], "Sara" : ["1234","2000"]}
And then, for checking:
if User_name in Data_base:
print("User persent")
else:
# Do whatever

What kind of unittests make sense for a chatbot in python?

I am creating a simple chatbot at the moment and now I would like to test it using the unittests package. I am new to programming and I have only recently heard about the existence of unit tests. I am thinking that for a chatbot to be tested, it would make sense to see if it gives the right output to the right user input. So if the user writes "Hi", for example, it should output "Hey what's up?" as specified in the library (I have written a bunch of libraries for it; it is not a deep-learning-kinda-bot).
This is the code of my chatbot:
# importing regular expression operations, which we need later to access the libraries
import re
import random # later we want to pick a chatbot answer to a statement by random
from Jordan_Library import dict_smalltalk, dict_caring, dict_cursing, dict_meditating, dict_corona # import libraries
# and here we imported all the topic libraries
class JordanBot:
"""
A class that represents the abilities of Jordan the chatbot.
...
Attributes
----------
name : str
user can insert name, which will later be shown in the chat.
Methods
----------
name : str
user can insert name, which will later be shown in the chat.
"""
def __init__(self, name): # this function is always called when a new object of the class is called
"""
Constructing topics for Jordan. Takes the user's name as an argument.
"""
self.name = name
def chat(self):
"""
A function that enables chatting with Jordan after picking a topic.
Take no arguments.
"""
topics = [dict_smalltalk, dict_caring, dict_cursing, dict_meditating, dict_corona]
while True:
print("Welcome. My name is Jordan. You can now choose a topic that we can talk about.")
print("Press '0' to have some good old-fashioned smalltalk.")
print("Press '1' to tell me about your deepest sorrows and your destroyed soul.")
print("Press '2' to curse with me.")
print("Press '3' to meditate with me.")
print("Press '4' to talk about Corona.")
# execute this welcome text and tell user what to press in order to pick a topic.
choice = input(">>> ")
# initialize input
if choice == '0': # determine which key to press to initiate the specific topic
print("Alrighty, let's do some chitchatting.")# initiate welcome text for specific topic
print("Don't forget that I am sensitive to punctuation.")
elif choice == '1':
print("Please tell me about your deepest sorrows and your destroyed soul.")
print("Don't forget that I am sensitive to punctuation.")
elif choice == '2':
print("Make yourself ready. let's insult each other!")
print("Don't forget that I am sensitive to punctuation.")
elif choice == '3':
print("Ok then, let's meditate.")
print("Don't forget that I am sensitive to punctuation..")
elif choice == '4':
print("Let's talk about Corona.")
print("Don't forget that I am sensitive to punctuation..")
elif choice == 'q': # if user wants to quit
break
else: # if user pressed the wrong key.
print("Try again.")
edition = topics[int(choice)]
statement = list(map(lambda x:re.compile(x[0], re.IGNORECASE), edition))
# list(map()) applies a function to all elements of a specified object, in this case the cursing library
# lambda makes sure that re.compile is applied in a certain way to all elements of the library without being case-sensitive
# re.compile makes sure that the elemets are turned into objects that can be matched later to another item in the library
answer = list(map(lambda x:x[1], edition))
# same here, but here we pick the second argument in the list x[1], which entails Jordan's answers
while True:
userInput = input(' ' + self.name + ' >>> ') # this allows for the user to type in keys
resp = "I did not understand what you said. Also, I am sensitive to punctuation." # initalize response variable
counter = 0 # initalize counter
while resp == "I did not understand what you said. Also, I am sensitive to punctuation." and counter < len(statement): # determine when to start my loop
for i in range(0, len(statement)): # loop through the indexed library
match = statement[i].match(userInput) # look if input of the user matches with one of the words in the library
if match:
word = statement[i].split(userInput)[1] # We have to take the first element of this list
resp = random.choice(answer[i]) # if there is a match, pick a random answer from x[1]
counter += 1 # make sure that the counter is now + 1 so it does not write the initialized response from the beginning but continues with the loop
# if there is no match though, then it will write the initialized answer
if userInput == 'q':
print(random.choice(answer[i]))
print("---------------------------------")
print("Do you want to choose another topic? Pick below or press 'q' to quit for realsies.")
print("---------------------------------")
break
resp = resp.format(word)
print('____________')
print(' ')
print('Jordan >>> ' + resp) # print Jordan's answer
The unittests I am trying to create are something like:
import unittest
from Jordan_Library import dict_smalltalk, dict_caring, dict_cursing, dict_meditating, dict_corona # import dictionairies
from Jordan_Class import JordanBot
class testJordan(unittest.TestCase):
"""
A class to test several units of Jordan to make sure everything is working correctly.
"""
def test_match(self):
j = JordanBot('StringName')
j.chat()
user_input = "What are you?"
bot_output = list(map(lambda x:x[1], dict_smalltalk)) # this is how I access the right response in the right library
matched = bot_output.match(user_input)
self.assertIn("I am a chatbot, dude. What do you think?", matched)
def test_regex(self):
j = JordanBot('StringName')
j.chat()
text = 'something'
regex = {}
self.assertRegexpMatches(text, regex)
if __name__ == '__main__':
unittest.main()
The main problem is that these lines only run my code, but not really any unit tests. Advice is much appreciated!

Can python interpret lists in text files?

I am trying to make a password keeper and I have the usernames and passwords of the user accounts in a text file. However, since the script wants to know if the user input for loginUser and loginPass are in the file, that creates the opportunity for the user to log in with mismatched usernames and passwords. Can I create a list (or at least a pair of strings) and check if the input for the login variables are in a specific list?
Here's my code If you want to test it yourself:
def title():
# This is the title screen
print('____This is a password keeper____')
main()
def main():
abc = open("userpassfile.txt", "r+")
userpassfile = abc.read().strip().split()
actCheck = input('Do you already have an account?')
if(actCheck == 'Yes' or actCheck == 'yes'):
loginUser = input('What is your username?')
loginPass = input('What is yout password?')
if(loginUser and loginPass in userpassfile):
dirCheck = input('Account Settings? [y/n]')
if(dirCheck == 'y' or dirCheck == 'Y'):
print('This function is not working yet!')
else:
print('hihi')
else:
print('Incorrect password or username!')
else:
createAct = input('would you like to create one?')
if (createAct == 'Yes' or createAct == 'yes'):
createUser = input('What would you like your username to be?:')
createPass = input('What would you like your password to be?:')
abc.write(createUser + '\n')
abc.write(createPass + '\n')
open(createUser + '.txt', "w")
title()
If you have any questions about my code, please ask! Thanks!
To me, it would make more sense to store the user / pass pairs in a single line. Something like
user:pass
Or
user|pass
The problem with this approach is that you eliminate a character, the one used as the delimiter, from being used in your username or password. To get around that limitation, you can do something similar to how strings protocol works and prepend the line with a number representing the length of the username.
004userpass
014longerusernamepassword
You read the first 3 characters as an integer, and know how many more to read for the user and how many for the password.
Of course you could also store it in several other formats like json, yaml, or csv,
Given that you are storing them in pairs of lines, you should be able to break them up into their groups with code similar to this:
f = """username1
password1
username2
password2""".splitlines()
pairs = [tuple(f[i*2:i*2+2]) for i in range(len(f)/2)]
print(pairs)
This would output:
[('username1', 'password1'), ('username2', 'password2')]
Then you would simply check
if (loginUser, loginPass) in pairs:
...
You could use a more generic approach for breaking your list of usernames / passwords into pairs as well with this function
def groups(inval, size):
for i in range(0, len(inval), size):
yield inval[i:i+size]
And you could then do
pairs = tuple(groups(f, 2))

Python optimization of simple login system

i don't have a problem with my code but i am very new to python and programming in general so i would like some inputs as to what i could do better.
I decided to do a very simple login / register system and i am hoping you have some input so i can improve myself. I don't post here so often and don't know if this is the sort of question usually asked, but i hope you will help me. Thanks in advance.
Here is the code:
username = ['mel1', 'mel2', 'mel3']
password = ['tyr1', 'tyr2', 'tyr3']
def log_sys():
logged_in = False
log_user = raw_input('Please type in your username: ')
log_pass = raw_input('Please type in your password: ')
if log_user in username:
index = username.index(log_user)
if log_pass == password[index]:
logged_in = True
if logged_in:
print 'You are logged in'
else:
print 'Wrong username or password'
log_sys()
def reg_sys(user):
regpass1 = raw_input('Please choose a password: ')
regpass2 = raw_input('Please retype password: ')
if regpass1 == regpass2:
username.append(user)
password.append(regpass1)
log_sys()
else:
print 'Passwords did not match'
reg_sys(user)
def reglog_system():
reglog = raw_input('Do you want to register or login?: ')
if reglog == 'register':
regname = raw_input('Please choose a username: ')
reg_sys(regname)
elif reglog == 'login':
log_sys()
else:
reglog_system()
reglog_system()
This is not a complete answer; I'm not a python expert.
I would strongly suggest using an associative array or dictionary / hash instead of a list / array for storing usernames and passwords. At a minimum, the performance for large lists of users will be better.
I would move the prompt for username when the user is registering into the function for that process; It seems odd that you pass the username into reg_sys() but prompt in log_sys().
Your test for password seems flawed; You only check to see if the first matches the second, without checking to see if either or both is None, an empty list, the empty string, or some other special value.
I hope that helps.
Got some criticism after all!
1) To make clear what your main function is, you should change:
reglog_system()
to
main()
2) Call your script with:
if __name__ == "main":
main()
Makes it more portable. You can then call it directly or import it as a module
3) Use some return functions:
return raw_input("foo")
And handle the return within main(). It makes your code easier on the eyes and may help deciding when/where to deal with the result of a function.
Performance wise, I can't really criticise anything else, at least nothing springs to mind. For future planning, maybe implement hashing? SHA256 seems pretty robust these days.
i found out that if you use example = input() you can use example directly
Example:
name = input("Username: ")
if name == 'Username':
passwd = input("Password: ")
if passwd == 'Password':
print("Login Sucsessful!")
else:
print("Incorrect Username or password.")

Categories