need explanation for max and min building function - python

I don't understand the built-in functions max and min in python 2.7
max("sehir")
min("sehir")
max gives the letter "s" and min gives the letter "e"

max and min take as parameter (given you only give it one unnamed parameter) an iterable, and returns the maximum / minimum item.
A string is an iterable: if you iterate over a string, you obtain the 1-char strings that are the characters of the string.
Then max and min iterate over that iterable and returns the maximum or minimum item. For a string the lexicographical order is defined. So 'a' < 'b', and 'ab' > 'aa'. So it is compared lexicographically, and the individual characters are compared by ASCII code (Unicode code in python-3.x). Since all characters have are one-caracter strings. We only have to take the ASCII code into account here. You can inspect the ASCII table here [wiki].
So max("sehir") will return 's', since max(['s', 'e', 'h', 'i', 'r']) == 's': the maximum character in the iterable. For min('sehir') == 'e', since min(['s', 'e', 'h', 'i', 'r']) == 'e' because it is the "smallest" character in the string.

Related

Recreating the strip() method using list comprehensions but output returns unexpected result

I am trying to 'recreate' the str.split() method in python for fun.
def ourveryownstrip(string, character):
newString = [n for n in string if n != character]
return newString
print("The string is", ourveryownstrip(input("Enter a string.`n"), input("enter character to remove`n")))
The way it works is that I create a function that passes in two arguments: 1) the first one is a string supplied, 2) the second is a a string or char that the person wants to remote/whitespace to be moved from the string. Then I use a list comprehension to store the 'modified' string as a new list by using a conditional statement. Then it returns the modified string as a list.
The output however, returns the entire thing as an array with every character in the string separated by a comma.
Expected output:
Boeing 747 Boeing 787
enter character to removeBoeing
The string is ['B', 'o', 'e', 'i', 'n', 'g', ' ', '7', '4', '7', ' ', 'B', 'o', 'e', 'i', 'n', 'g', ' ', '7', '8', '7']
How can I fix this?
What you have set up is checking each individual character in a list and seeing if it matches 'Boeing' which will never be true so it will always return the whole input. It is returning it as a list because using list comprehension makes a list. Like #BrutusForcus said this can be solved using string slicing and the string.index() function like this:
def ourveryownstrip(string,character):
while character in string:
string = string[:string.index(character)] + string[string.index(character)+len(character):]
return string
This will first check if the value you want removed is in your string. If it is then string[:string.index(character)] will get all of the string before the first occurrence of the character variable value and string[string.index(character)+len(character):] will get everything in the string after the first occurrence of the variable value. That will keep happening until the variable value doesn't occur in the string anymore.

How do i do the checksum for Singapore Car License Plate Recognition with Python

I am able to do recognition of car license plate and extract the plate values. Sometimes, the results are inaccurate as i am using OCR to do the recognition. I uses a checksum to ensure only the correct results are being printed and viewed. After the calculation for the checksum, I need to use another formula to get the last letter of the plate. match with these 19 letter, A=0, Z=1, Y=2, X=3, U=4, T=5, S=6, R=7, P=8, M=9, L=10, K=11, J=12, H=13, G=14, E=15, D=16, C=17, B=18. Is there any way i can use a loop to like declare the values of this letters instead of doing it one by one manually? Please help out. Thank you.
You can use a list and perform the lookups according to your needs.
The list looks like this:
plate_letter_list = ['A', 'Z', 'Y', 'X', 'U', 'T', 'S', 'R', 'P', 'M', 'L', 'K', 'J', 'H', 'G', 'E', 'D', 'C', 'B']
Case 1: Lookup value from letter
If you need to find the numeric value associated with a letter, use the index method:
letter = 'T'
print(plate_letter_list.index(letter))
>> 5
Case 2: Lookup letter from value
If you need to find the letter associated with a numeric value, use it as index:
value = 13
print(plate_letter_list[value])
>> H
There are two ways to search for these values. One of it is to use the List datatype like #sal provided. The other way is to use Dictionary datatype
**
Solution using List Datatype
**
pl_vals_list = ['A', 'Z', 'Y', 'X', 'U', 'T', 'S', 'R', 'P', 'M', 'L', 'K', 'J', 'H', 'G', 'E', 'D', 'C', 'B']
You can then do a lookup either by position or by value
To search by position, will provide you the value you assigned to the alphabet.
print(pl_vals_list[0]). This will result in A.
Alternatively, you can search by the alphabet itself. In this case, you have to use the index() function.
print(pl_vals_list.index('A')). This will result in the assigned number you gave to the alphabet. The result will be 0
This provides you a means to look-up based on alphabet or value.
You can also check if the alphabet is inside the list using:
if 'A' in pl_vals_list:
#then do something for value A
elif 'B' in pl_vals_list:
#then do something for value B
else:
#then do something
You can also iterate through the list using a for loop and enumerate. However, I don't know if that will be of value to you.
for i, v in enumerate(pl_vals_list):
#do something with each value in the list
#here i will store the index, and v will have the value - A, B, C, etc
You can get the value of each of these and determine what you want to do.
**
Solution using Dictionary Datatype
**
Similarly, you can do the same using a dictionary.
pl_vals_dict = {'A':0, 'Z':1, 'Y':2, 'X':3, 'U':4, 'T':5, 'S':6, 'R':7, 'P':8, 'M':9, 'L':10, 'K':11, 'J':12, 'H':13, 'G':14, 'E':15, 'D':16, 'C':17, 'B':18}
To look for alphabets within a dictionary, you can use
if 'A' in pl_vals_dict.keys():
#then do something for value A
elif 'A' in pl_vals_dict.keys():
#then do something for value B
else:
#do something else
An alternate way to check for something would be:
x = True if 'F' in pl_vals_dict.keys() else False
In this case x will have a value of False
You can also use the get() function to get the value.
x = pl_vals_dict.get('A') # OR
print (pl_vals_dict.get('A')
The simplest way to look up a dictionary value is:
print (pl_vals_dict['A'])
which will result in 0
However, you have to be careful if you try to print value of 'F', it will throw an error as 'F' is not part of the key value pair within the dictionary.
print (pl_vals_dict['F'])
this will give you the following error:
Traceback (most recent call last):
File "<pyshell#48>", line 1, in <module>
pl_vals_dict['F']
KeyError: 'F'
Similar to list, you can also iterate through the dictionary for keys and values. Not sure if you will need to use this but here's an example for you.
for k, v in pl_vals_dict.items():
#do something with each pair of key and value
#here k will have the keys A Z Y X ....
#and v will have the values 1, 2, 3, 4, ....

Recursion, out of memory?

I wrote a function with two parameters. One is an empty string and the other is a string word. My assignment is to use to recursion to reverse the word and place it in the empty string. Just as I think ive got it, i received an "out of memory error". I wrote the code so that so it take the word, turn it into a list, flips it backwards, then places the first letter in the empty string, then deletes the letter out of the list so recursion can happen to each letter. Then it compares the length of the the original word to the length of the empty string (i made a list so they can be compared) so that when their equivalent the recursion will end, but idk
def reverseString(prefix, aStr):
num = 1
if num > 0:
#prefix = ""
aStrlist = list(aStr)
revaStrlist = list(reversed(aStrlist))
revaStrlist2 = list(reversed(aStrlist))
prefixlist = list(prefix)
prefixlist.append(revaStrlist[0])
del revaStrlist[0]
if len(revaStrlist2)!= len(prefixlist):
aStr = str(revaStrlist)
return reverseString(prefix,aStr)
When writing something recursive I try and think about 2 things
The condition to stop the recursion
What I want one iteration to do and how I can pass that progress to the next iteration.
Also I'd recommend getting the one iteration working then worry about calling itself again. Otherwise it can be harder to debug
Anyway so applying this to your logic
When the length of the output string matches the length of the input string
add one letter to the new list in reverse. to maintain progress pass list accumulated so far to itself
I wanted to just modify your code slightly as I thought that would help you learn the most...but was having a hard time with that so I tried to write what i would do with your logic.
Hopefully you can still learn something from this example.
def reverse_string(input_string, output_list=[]):
# condition to keep going, lengths don't match we still have work to do otherwise output result
if len(output_list) < len(list(input_string)):
# lets see how much we have done so far.
# use the length of current new list as a way to get current character we are on
# as we are reversing it we need to take the length of the string minus the current character we are on
# because lists are zero indexed and strings aren't we need to minus 1 from the string length
character_index = len(input_string)-1 - len(output_list)
# then add it to our output list
output_list.append(input_string[character_index])
# output_list is our progress so far pass it to the next iteration
return reverse_string(input_string, output_list)
else:
# combine the output list back into string when we are all done
return ''.join(output_list)
if __name__ == '__main__':
print(reverse_string('hello'))
This is what the recursion will look like for this code
1.
character_index = 5-1 - 0
character_index is set to 4
output_list so far = ['o']
reverse_string('hello', ['o'])
2.
character_index = 5-1 - 1
character_index is set to 3
output_list so far = ['o', 'l']
reverse_string('hello', ['o', 'l'])
3.
character_index = 5-1 - 2
character_index is set to 2
output_list so far = ['o', 'l', 'l']
reverse_string('hello', ['o', 'l', 'l'])
4.
character_index = 5-1 - 3
character_index is set to 1
output_list so far = ['o', 'l', 'l', 'e']
reverse_string('hello', ['o', 'l', 'l', 'e'])
5.
character_index = 5-1 - 4
character_index is set to 0
output_list so far = ['o', 'l', 'l', 'e', 'h']
reverse_string('hello', ['o', 'l', 'l', 'e', 'h'])
6. lengths match just print what we have!
olleh

How to sort one item to match another but applying the sort elsewhere?

For example say I have the word and arbitrary string
LEAST HDKEN
Now say I rearrange LEAST to STEAL. I want to apply that same "transformation" to the second word.
STEAL ENDKH
So since the L (first character) in LEAST went to the end (of STEAL), the first character of the string (H) therefore goes to the end position as well. Similar goes for the rest.
Zip the two strings together so that you sort pairs of letters. Then sort, and unzip.
>>> zip(*sorted(zip('LEAST', 'HDKEN'), key=lambda s:'STEAL'.index(s[0])))
[('S', 'T', 'E', 'A', 'L'), ('E', 'N', 'D', 'K', 'H')]
or, a bit longer:
# Make pairs of letters
pairs = zip('LEAST', 'HDKEN')
# Sort pairs, using the index into STEAL as the sort key
sortedpairs = sorted(pairs, key=lambda s:'STEAL'.index(s[0]))
# Unzip the pairs back into words
result = zip(*sortedpairs)
# Print the words
print ''.join(result[0]), ''.join(result[1])
(prints STEAL ENDKH as desired)

Convert string / character to integer in python

I want to convert a single character of a string into an integer, add 2 to it, and then convert it back to a string. Hence, A becomes C, K becomes M, etc.
This is done through the chr and ord functions. Eg; chr(ord(ch)+2) does what you want. These are fully described here.
This sounds a lot like homework, so I'll give you a couple of pieces and let you fill in the rest.
To access a single character of string s, its s[x] where x is an integer index. Indices start at 0.
To get the integer value of a character it is ord(c) where c is the character. To cast an integer back to a character it is chr(x). Be careful of letters close to the end of the alphabet!
Edit: if you have trouble coming up with what to do for Y and Z, leave a comment and I'll give a hint.
Normally, Just ord and add 2 and chr back, (Y, Z will give you unexpected result ("[","\")
>>> chr(ord("A")+2)
'C'
If you want to change Y, Z to A, B, you could do like this.
>>> chr((ord("A")-0x41+2)%26+0x41)
'C'
>>> chr((ord("Y")-0x41+2)%26+0x41)
'A'
>>> chr((ord("Z")-0x41+2)%26+0x41)
'B'
Here is A to Z
>>> [chr((i-0x41+2)%26+0x41) for i in range(0x41,0x41+26)]
['C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B']
http://docs.python.org/library/functions.html
ord(c)
Given a string of length one, return an integer representing the Unicode code point of the character when the argument is a unicode object, or the value of the byte when the argument is an 8-bit string. For example, ord('a') returns the integer 97, ord(u'\u2020') returns 8224. This is the inverse of chr() for 8-bit strings and of unichr() for unicode objects. If a unicode argument is given and Python was built with UCS2 Unicode, then the character’s code point must be in the range [0..65535] inclusive; otherwise the string length is two, and a TypeError will be raised.
"ord" is only part of the solution. The puzzle you mentioned there rotates, so that "X"+3 rotates to "A". The most famous of these is rot-13, which rotates 13 characters. Applying rot-13 twice (rotating 26 characters) brings the text back to itself.
The easiest way to handle this is with a translation table.
import string
def rotate(letters, n):
return letters[n:] + letters[:n]
from_letters = string.ascii_lowercase + string.ascii_uppercase
to_letters = rotate(string.ascii_lowercase, 2) + rotate(string.ascii_uppercase, 2)
translation_table = string.maketrans(from_letters, to_letters)
message = "g fmnc wms bgblr"
print message.translate(translation_table)
Not a single ord() or chr() in here. That's because I'm answering a different question than what was asked. ;)
Try ord(), should do the trick :)
For a whole string this would be:
>>> s = "Anne"
>>> ''.join([chr(ord(i)+2) for i in s])
'Cppg'
It's diffucult for 'Y', 'Z' ...
>>> s = "Zappa"
>>> ''.join([chr(ord(i)+2) for i in s])
'\\crrc'
Functions: chr, ord
For those who need to perform the operation on each character of the string, another way of handling this is by converting the str object to/from a bytes object which will take advantage of the fact that a bytes object is just a sequence of integers.
import numpy
old_text_str = "abcde" # Original text
old_num_list = list(old_text_str.encode()) # Integer values of the original text
new_num_list = numpy.add(old_num_list, 2).tolist() # Add +2 to the integer values
new_text_str = bytes(new_num_list).decode() # Updated text
print(f"{old_text_str=}")
print(f"{old_num_list=}")
print(f"{new_num_list=}")
print(f"{new_text_str=}")
Output:
old_text_str='abcde'
old_num_list=[97, 98, 99, 100, 101]
new_num_list=[99, 100, 101, 102, 103]
new_text_str='cdefg'
Related topics:
How do I convert a list of ascii values to a string in python?
How can I convert a character to a integer in Python, and viceversa?
How to add an integer to each element in a list?

Categories