lowercasing function doesn't work in a different function - python

Please bear with me, I am new to Python.
The first function I wrote was one to lowercase any uppercase characters in a string that passed through it, which works by itself, while ignoring any non-uppercase alphabetical ASCII characters.
However, when I try to use it in my second function, (which SHOULD use the lowercasing function on whatever the user inputs and then sticks it in a file) I'm left with a file that contains the the string that's initially passed through without any of the lowercasing function.
import os.path
from os import path
def lowercaser(text):
text = [ord(c) for c in text]
length = len(text)
i = 0
while length != i:
if 65 <= text[i] <= 90:
text[i] = text[i] + 32
i += 1
text = [chr(c) for c in text]
text = "".join(text)
def does_rfid_list_exist():
if path.exists("rfidList.txt"):
print("File found!")
else:
print("File was not located! Creating new file.\n")
f = open("rfidList.txt", "a+")
user_input = input("Please enter your name!\n")
lowercaser(user_input)
f.write(user_input)
f.close()
does_rfid_list_exist()
I have no idea why they don't work together, and I've broken it down as far as I can. Any ideas?

You seem to be expecting this call:
lowercaser(user_input)
to change the value of user_input. It won't do this. The reason is that string values are immutable, which means that every time you "change" a string, you create a new one. The original string object is not touched. So in this case, the variable user_input is pointing at a particular string when you call lowercaser. Once that function returns, user_input will still be pointing at the same string. Some other string will exist that will be the result of the processing the function did.
The way this usually works is that the lowercaser function will return the new string as the return value of the function, like this:
user_input = lowercaser(user_input)
This way, you are pointing user_input to a new string, the string that lowercaser produced for you. But to get this to work, you have to fix your lowercaser function to return its result. So you also have to add return text as the last line of your lowercaser function.

You need to first learn how to define a function.
You can learn it in w3school or any other source or book.
I am posting the solution here but it won't be productive for you.
Put
return text
in the last line of function. And put
user_input=lowercaser(user_input)
instead of
lowercaser(user_input)

the code looks not out of the ordinary , The only issue that I see is even though you are calling the function you are not updating the user_input
user_input = lowercaser(user_input)
Apart from this , return text from lower case function return text
import os.path
from os import path
def lowercaser(text):
text = [ord(c) for c in text]
length = len(text)
i = 0
while length != i:
if 65 <= text[i] <= 90:
text[i] = text[i] + 32
i += 1
text = [chr(c) for c in text]
text = "".join(text)
return text #### Change - 1
def does_rfid_list_exist():
if path.exists("rfidList.txt"):
print("File found!")
else:
print("File was not located! Creating new file.\n")
f = open("rfidList.txt", "a+")
user_input = input("Please enter your name!\n")
user_input = lowercaser(user_input) #### Change - 2
f.write(user_input)
f.close()
does_rfid_list_exist()
Using lower() on user_input
import os.path
from os import path
def lowercaser(text):
text = [ord(c) for c in text]
length = len(text)
i = 0
while length != i:
if 65 <= text[i] <= 90:
text[i] = text[i] + 32
i += 1
text = [chr(c) for c in text]
text = "".join(text)
return text #### Change - 1
def does_rfid_list_exist():
if path.exists("rfidList.txt"):
print("File found!")
else:
print("File was not located! Creating new file.\n")
f = open("rfidList.txt", "a+")
user_input = input("Please enter your name!\n")
user_input = user_input.lower() ### Change - 2
f.write(user_input)
f.close()
does_rfid_list_exist()

Bruv, there is not return statement, and even if there was the variable isn't stored anywhere. Meaning that text (a local variable that can only be accessed inside the function it originates from), is not accessible, passed on or stored in function does_rfid_list_exist(). Another problem is that user_input, which seems to be the data you are trying to manipulate, does not change after lowercaser() function because nothing is returned and the data isn't stored in anything. What I would do to fix is
To make it so that user_input
return text
after
text = "".join(text)
and replace
lowercaser(user_input)
with
user_input = lowercaser(user_input)
I think you got confused and thought that user_input is a public class of some sort.

Related

Given set of numbers in a string in python

I want to check if a set of numbers is present in a string or not
Here is my code:
def check_no(string):
string = string.lower()
no = set(c)
s = set()
for i in string:
if i in no:
s.add(i)
else:
pass
if len(s) == len(no):
return("Valid")
else:
return("Not Valid")
c = input()
print(check_no(c))
if the given set of numbers is present in the string then it prints Valid and if not present it prints Not valid
the program works fine when the input is given as 123 and the string is like I have 12 car and 3 bikes then the output is valid
but when i give input as 254 and string as i hav25555number the output comes as valid but the actual output should be Not valid as 4 is not present in the string.
Can anyone help how to solve it in the provided code
I you want to check if all characters match then use all.
def check_no(text, check):
valid = all(character in text for character in check)
if valid:
return("Valid")
else:
return("Not Valid")
check = '254'
text = 'i hav25555number'
print(check_no(text, check))
The one-liner version
def check_no(text, check):
return 'Valid' if all(character in text for character in check) else 'Not Valid'
Your function is mostly correct, but probably because of your (terrible) choices of variable names, string and c variables were mixed up in the environment.
The solution is to add the parameters explicitly to the function definition (also avoid names like string or c as these could be pre-defined python keywords):
teststring = "254"
testc = "i hav25555number"
def check_no(mystring, myc):
string = mystring.lower()
no = set(c)
print("string is",string)
s = set()
for i in string:
if str(i) in no:
# print(i, " in ", no)
s.add(i)
else:
pass
# print("s is",s)
# print("no is",no)
if len(s) == len(no):
return("Valid")
else:
return("Not Valid")
print(check_no(teststring,testc))
gives:
print(check_no(teststring,testc))
string is 254
Not Valid
As mentioned before, you can use all to make your code more elegant, although there is nothing wrong with your implementation either.

Accepting an empty value in a function

I need to create function that removes dash/underscore and combine the words. however if i use an empty string i get an error string index out of range
I believe whats causing this error is because of the line below. However this is impt in my code since it gets the first letter of my string.
# first_char = text[0]
import re
import string
def to_camel_case(text):
split_chars = []
ans = ''
small = ''
# store the first letter in variable
first_char = text[0]
# use split to separate the phrase given in text
for x in re.split('[-_]',text):
if text == None:
return
else:
ans += x.title()
# combine the vars
if ans[0] != first_char:
small += ans[0].lower()
return small + ans[1:]
else:
return ans
IndexError Traceback (most recent call last)
<ipython-input-64-f8cbc9c16e79> in <module>
----> 1 to_camel_case('')
<ipython-input-61-2bd3248e632d> in to_camel_case(text)
13
14 ## maintain the very first letter to its original form (lower or uppercase) and store it in a var
---> 15 first_char = text[0]
16
17
IndexError: string index out of range
You are trying to read a null value by text[0] as the string is empty. You can always check the input if it is null or have value. If value exist carry on with the operation otherwise return with a response.
Using text[0] needs that text has at least one character. So you must test if text is not empty before.
so this should work, your spacing wasn't good and as well, I've re-done the spacing and fixed your bug. The error was caused because text doesn't have any value when you want to get the first index. It's better to put as much as you can inside the body of the function.
import re
import string
def to_camel_case(text = 'Test'):
split_chars = []
ans = ''
small = ''
first_char = text[0]
# use split to separate the phrase given in text
for x in re.split('[-_]',text):
if text == None:
return
else:
ans += x.title()
# combine the vars
if ans[0] != first_char:
small += ans[0].lower()
return small + ans[1:]
else:
return ans
to_camel_case('StACKoverFLOW')
OUTPUT
Stackoverflow

Why can't I return the modified str_func function back to the main function?

I have gotten about 80% of this program done but I cannot for the life of me figure out how to replace the vowels with asterisks and print the new string.
Instructions are as follows:
prompt the user to enter his/her first name.
output the number of letters in the name.
print all of the letters in the name separated by a space, all on one line.
print the name in all upper case.
use one slicing to make a new string from the name, but without the first and last letters.
print this new string.
pass the original name to a function named str_func.
inside the str_func function:
replace the vowels in the name with asterisks
return the modified name back to main
back in main, print the string returned by str_func.
My code so far:
def main():
name = input('Enter your first name: ')
print(name)
### print name with spaces in between characters
spaces = ''
for ch in name:
spaces = spaces + ch + ' '
print(spaces[:-1]) # to get rid of space after e
print('name in caps is,',name.upper()) # print name in all caps
print('After chopping the name we get',name[1:4])
print(str_func)
def str_func():
str_func = name.replace('a','*')
return str_func
main()
A friend of mine has helped somewhat stating I have issues with my str_func function:
The function is supposed to take the name as an argument in the main function when you call it.
You don't print it. You call it, something like this:
new_name = str_func(name)
Define str_func() like this. I put in some pseudocode for you.
def str_func(name):
###make a string containing the vowels
###loop through the name
###replace vowel if found with *
### after loop, return the name
Please help!!
This may help you.
import re
def main():
#Using "raw_input" instead of "input"
name = raw_input('Enter your first name: ')
print(name)
### print name with spaces in between characters
spaces = ''
for ch in name:
spaces = spaces + ch + ' '
print(spaces[:-1]) # to get rid of space after e
print('name in caps is,',name.upper()) # print name in all caps
print('After chopping the name we get',name[1:4])
new_name=str_func(name)
print(new_name)
def str_func(value):
#re is regular expression module. It will match string "Guido" and re.IGNORECASE makes it case insensitive.
#When value will Guido, it will be returned as it is.
if re.match(r"Guido",value,re.IGNORECASE):
return value
else:
for x in "aeiou":
value= value.replace(x, '*')
return value
main()
Output
C:\Users\Dinesh Pundkar\Desktop>python a.py
Enter your first name: Guido
Guido
G u i d o
('name in caps is,', 'GUIDO')
('After chopping the name we get', 'uid')
Guido
C:\Users\Dinesh Pundkar\Desktop>python a.py
Enter your first name: Jfalcone
Jfalcone
J f a l c o n e
('name in caps is,', 'JFALCONE')
('After chopping the name we get', 'fal')
Jf*lc*n*
C:\Users\Dinesh Pundkar\Desktop>
Others have provided a solution to your immediate problem but I’ll try to improve the whole code. I don't know what functions you've been introduced to so I might provide both a naive and a pythonic implementation for each steps.
To start with, you did not answered question 2: print the length of the input string. You can either count them manually:
size = 0
for letter in name:
size += 1
print(size)
or use the built-in function len:
size = len(name)
print(size) # or print(len(name)) if you don't need the intermediate variable
You can improve the spacing of your input using the join method of strings:
spaced = ' '.join(name)
print(spaced) # or print(' '.join(name)) if you don't need spaced
You can pass any iterable of strings to join and a string fits.
Your slicing take the second, third and fourth letter of your input. No matter what its length is. You need to either make use of the lenght of the string computed earlier:
sliced = name[1:size-1]
print(sliced)
or use negative numbers in the slice notation to count from the end of the string:
print(name[1:-1])
You're required to write a function and call it to mutate the string. You’ll thus have to call it like:
mutated = str_func(name)
print(mutated)
The function can either iterate over the original string:
def str_func(original):
copy = ''
for letter in original:
if letter in 'auieoy':
copy += '*'
else:
copy += letter
return copy
or use replace:
def str_func(original):
copy = original
for vowel in 'aeuioy':
copy = copy.replace(vowel, '*')
return copy
You can even use translate which can be a better fit in a more general use:
def str_func(original):
from string import maketrans
vowels = 'auieoy'
return original.translate(maketrans(vowels, '*' * len(vowels)))
Assembling all that together:
from string import maketrans
def do_stuff():
name = input('Enter your first name: ')
print('Your input is', name)
print('It\'s length is', len(name))
print('Adding spaces:', ' '.join(name))
print('Capitalizing it:', name.upper())
print('Chopping it:', name[1:-1])
mutated = str_func(name)
print('Removing vowels:', mutated)
def str_func(original):
vowels = 'auieoy'
return original.translate(maketrans(vowels, '*' * len(vowels)))
if __name__ == '__main__':
do_stuff()
test = 'qwertyuiopasdfghjklzxcvbnm'
def changestring(string):
for x in 'aeiou':
string = string.replace(x, '*')
return string
changestring(test)
'qw*rty***p*sdfghjklzxcvbnm'
Is this what you are trying to do?

Checking if characters in a file can be integers

So in a Python assignment I have to write a decoder for an mtf encoded file, which is made up of hex characters and words. In my decoder I'm reading the .mtf file char by char and checking whether or not its a letter or a hex number and I can't seem to make it work. I've erased the majority of my code to start fresh but here's the basic framework:
f = open(str(sys.argv[1]), "r")
new_f = str(sys.argv[1])
new_f = new_f[:len(new_f)-3]+ "txt"
f_two = open(new_f, "w")
myList = []
word = ""
words = []
index = 0
while True:
value = None
c = f.read(1)
if not c:
break
try:
value = int(c)
except ValueError:
word = word + c
I apologize for the horribly written code and any mistakes I may have made while writing this, this is all still relatively new to me.
Thank you!
When you read from a file in Python, you're reading in strings. Strings also have a method called isdigit() which tells you if the one character is a digit or not.
while c:
c = f.read(1)
if c.isdigit():
myList.append(c)
If you're checking for hex characters (0-9, A-F), you would have to build your own checking function. Something like this:
def is_hex(n):
return n.isdigit() or ("A" <= n.upper() <= "F")

How can I group while outputs into a single string?

This is a simple encryption code that I've come up with. It uses a single character key.
ar = input('please input string to be de/encrypted:')
key = input('please input single character key:')
def encrypt1(key,ar):
i = 0
while i < len(ar):
br = chr(ord(ar[i])^ord(key))
i = i+1
print(br)
encrypt1(key,ar)
print('Input string = ' + ar+'\n'+'key = '+key)
If I input "CMPUT" for the string to be encrypted and 'a' as the key I will get this printed output:
"
,
1
4
5
Which is the correct encryption (according to my assignment example). Now I just have to get those outputs into a single string and print them in the shell like such:
>>>decrypted string: ",145
I've looked through google and old questions on this website but I've still come up empty. I would appreciate your help.
Check out this code, I believe this is what you need (I changed print(br) line):
ar = input('please input string to be de/encrypted:')
key = input('please input single character key:')
def encrypt1(key,ar):
i = 0
while i < len(ar):
br = chr(ord(ar[i])^ord(key))
i = i+1
print(br, end='')
encrypt1(key,ar)
print('\nInput string = ' + ar+'\n'+'key = '+key)
Most obvious way for a beginner would be to simply accumulate to a string
def encrypt1(key,ar):
i = 0
result = ""
while i < len(ar):
br = chr(ord(ar[i])^ord(key))
i = i+1
result += br
return result
Usually you would just write it using a generator expression
def encrypt1(key,ar):
return ''.join(chr(ord(i) ^ ord(key)) for i in ar)

Categories