Replacing each letter with its number self - python

I want to take each letter of a word (a is 1, b is 2, etc.), then add them all together to find the sum of all the numbers. For example, “apple” would be 50. I have this code:
conversions = {
'a': 1,
'b': 2,
'c': 3,
'd': 4,
'e': 5,
'f': 6,
'g': 7,
'h': 8,
'i': 9,
'j': 10,
'k': 11,
'l': 12,
'm': 13,
'n': 14,
'o': 15,
'p': 16,
'q': 17,
'r': 18,
's': 19,
't': 20,
'u': 21,
'v': 22,
'w': 23,
'x': 24,
'y': 25,
'z': 26
}
def conversion(word):
for letter in word:
word.replace(letter, str(conversions[letter]))
word = list(word)
for number in word:
number = int(number)
return sum(word)
However, this returns the following error:
invalid literal for int() with base 10
I’ve probably done some dumb mistake, but I can’t seem to figure out what the problem is. Any help would be much appreciated.

Strings are immutable. word.replace() returns the modifies string, it doesn't update word. And you can't change a string into a list of numbers anyway.
You don't need to use replace at all, just add up the conversions.
def conversion(word):
return sum(conversions[letter] for letter in word)

You are definitely making things unnecessarily complicated. All lowercase alphabetic characters are sequentially coded. Get their codes and add them up:
def conversion(word):
return sum(ord(x) - ord('a') + 1 for x in word)
conversion('apple')
#50
Beware that this code will not handle upper-case letters or punctuation correctly.

Try this (this will handle upper and lowercase):
def conversion(word):
return sum([ord(x.lower()) - 96 for x in word])
>>> conversion("AppLe")
50

Related

Don't undestand cause of this 'dict' object is not callable" error

I am trying to write a program that asks the user to enter a sentence, then it counts and displays the occurrence of each letter.
I have to write a program using loops and collections/containers, which counts all the letters in a sentence input and displays how many times each was used. 'A' and 'a' count as the same letter.
This is my code so far:
def split(sentence):
return [char for char in sentence]
def get_key(val):
for key, value in letters.items():
if val == value:
return key
letters = {'a': ['a','A'], 'b': ['b','B'], 'c': ['c','C'], 'd': ['d','D'], 'e': ['e','E'], 'f': ['f','F'], 'g': ['g','G'],
'h': ['h','H'], 'i': ['i','I'],'j': ['j','J'], 'k': ['k','K'], 'l': ['l','L'], 'm': ['m','M'], 'n': ['n','N'], 'o': ['o','O'],
'p': ['p','P'], 'q': ['q','Q'], 'r': ['r','R'], 's': ['s','S'], 't': ['t','T'], 'u': ['u','U'], 'v': ['v','V'], 'w': ['w','W'],
'x': ['x','X'], 'y': ['y','Y'], 'z': ['z','Z']}
sentence = str(input("Enter a sentence: "))
sentence_letters = split(sentence)
i = 0
while i in range(len(sentence_letters)):
actual_letter = sentence_letters[i]
for key,value in letters():
if value == actual_letter:
print(actual_letter + ':' + str(sentence_letters.count(actual_letter)) + 'times')
sentence_letters.remove(actual_letter)
i += 1
else:
i += 1
This is the most recent message I get when I run the code:
Traceback (most recent call last):
File "main.py", line 21, in <module>
for key,value in letters():
TypeError: 'dict' object is not callable
I do not know what I am doing wrong, I am not even sure if this is the right way to solve this.
Note that there are other ideas that would be helpful here, just focusing on your error:
Looking at letters() - following an identifier by parentheses like this attempts to call it as you would a function. Because letters is not a function (or anything else that can be called) it can't be called. This is what the error is telling you.

Remove multiple keys from dictionary from txt file using python

So I have a txt file with this reddit comments:
There's a lot of information on each line of the dict, and I only want 2 elements from there, which is author and body. I'm trying to iterate over each line of the file, to remove the unnecessary information and keep only those two. I searched a lot and I didn't found any thing that help me.
The output should be a new filename.txt with only author and body in the dict for each line.
I just realize that it is in json format. So I tried this:
The problem is, now when I remove the unnecessary elements, it also removes it's value.
listcomments = []
for line in open ('RC_2009-01.json', 'r'):
listcomments.append(json.loads(line))
#res = dict([(key, val) for key, val in comments.items() if key not in rem_list])
#print(res)
for line in listcomments:
rem_list = ['subreddit_id', 'name', 'author_flair_text', 'link_id', 'score_hidden', 'retrieved_on', 'controversiality',
'parent_id', 'subreddit', 'author_flair_css_class', 'created_utc', 'gilded', 'archived', 'distinguished',
'id', 'edited', 'score', 'downs', 'ups']
list1 = [ele for ele in line if ele not in rem_list]
out_file = open("teste2.json", "w")
json.dump(list1, out_file, indent = 4)
Example in the image file is in json format. You have to parse json and get needed tags from the parser.
forward the following link :
https://www.w3schools.com/python/python_json.asp
You do this.
Say you have a dictionary like this below.
a={chr(i):j for i,j in zip(range(65,91),range(1,27))}
'''a={'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 'F': 6, 'G': 7, 'H': 8, 'I': 9,
'J': 10, 'K': 11, 'L': 12, 'M': 13, 'N': 14, 'O': 15, 'P': 16, 'Q': 17, 'R': 18,
'S': 19, 'T': 20, 'U': 21, 'V': 22, 'W': 23, 'X': 24, 'Y': 25, 'Z': 26}'''
And you want to extract only 'A' and 'C'.
wanted_key=['A','C']
res={key:a.get(key) for key in wanted_key}
print(res)
output
{'A': 1, 'C': 3}

Letter Count with Frequency, using Dictionaries

I was wondering if anyone could help me out.
How do I get this code to record ONLY the frequency of letters in a text file into a dictionary (does NOT count spaces, line, numbers, etc)?
Additionally how do I divide each letter by the total letters to report the percent frequency of each letter in the file?
This is what I have currently:
def linguisticCalc():
"""
Asks user to input a VALID filename. File must be a text file. IF valid, returns the frequency of ONLY letters in file.
"""
filename = input("Please type your VALID filename")
if os.path.exists(filename) == True:
with open(filename, 'r') as f:
f_content = f.read()
freq = {}
for i in f_content:
if i in freq:
freq[i] += 1
else:
freq[i] = 1
print(str(freq))
else:
print("This filename is NOT valid. Use the getValidFilename function to test inputs.")
Something that might help you determine whether the character in question is a letter, is this:
import string
# code here
if character in string.ascii_letters:
# code here
Check out collections.Counter()
You can use it to Count every letter in a string:
Counter('Articles containing potentially dated statements from 2011')
It gives this output, which is useful for counting characters in a string:
Counter({'A': 1,
'r': 2,
't': 8,
'i': 4,
'c': 2,
'l': 3,
'e': 5,
's': 3,
' ': 6,
'o': 3,
'n': 5,
'a': 4,
'g': 1,
'p': 1,
'y': 1,
'd': 2,
'm': 2,
'f': 1,
'2': 1,
'0': 1,
'1': 2})

count characters of a string using function

Write a function named count_letters that takes as a parameter a string and returns a dictionary that tabulates how many of each letter is in that string. The string can contain characters other than letters, but only the letters should be counted. The string could even be the empty string. Lower-case and upper-case versions of a letter should be part of the same count. The keys of the dictionary should be the upper-case letters. If a letter does not appear in the string, then it would not get added to the dictionary. For example, if the string is
"AaBb"
then the dictionary that is returned should contain these key-value pairs:
{'A': 2, 'B': 2}
def count_letters(string):
"""counts all the letters in a given string"""
your_dict = dict()
for x in string:
x = x.upper() # makes lowercase upper
if x not in your_dict:
your_dict[x]= 1
else:
your_dict[x] += 1
return your_dict
I am getting the following error when I go to upload:
Test Failed: {'Q': 1, 'U': 3, 'I': 3, 'S': 6, ' ': 3, 'C[48 chars]': 1} != {'S': 6, 'U': 3, 'I': 3, 'T': 3, 'O': 3, 'C[32 chars]': 1}
+ {'C': 2, 'D': 2, 'E': 2, 'I': 3, 'O': 3, 'P': 1, 'Q': 1, 'S': 6, 'T': 3, 'U': 3}
- {' ': 3,
- '?': 1,
- 'C': 2,
- 'D': 2,
- 'E': 2,
- 'I': 3,
- 'O': 3,
- 'P': 1,
- 'Q': 1,
- 'S': 6,
- 'T': 3,
- 'U': 3}
Try something like this. Feel free to adjust it to your requirements:
import collections
def count_letters(string):
return collections.Counter(string.upper())
print(count_letters('Google'))
Output: Counter({'G': 2, 'O': 2, 'L': 1, 'E': 1})
For documentation of the Counter dict subclass in collections module, check this.
Update without using collections module:
def count_letters(string):
your_dict={}
for i in string.upper():
if i in your_dict:
your_dict[i] += 1
else:
your_dict[i] = 1
return your_dict
Output: {'G': 2, 'O': 2, 'L': 1, 'E': 1}
This solution does use collections, but unlike with Counter we aren’t getting the entire solution from a single library function. I hope it’s permitted, and if it isn’t, that it will at least be informative in some way.
import collections as colls
def count_letters(str_in):
str_folded = str_in.casefold()
counts = colls.defaultdict(int)
for curr_char in str_folded:
counts[curr_char] += 1
return counts
defaultdict is extremely practical. As the name indicates, when we try to index a dictionary with a key that doesn’t exist, it creates a default value for that key and carries out our original operation. In this case, since we declare that our defaultdict will use integers for its keys, the default value is 0.
str.casefold() is a method designed specifically for the complex problem that is case-insensitive comparison. While it is unlikely to make a difference here, it’s a good function to know.
Let me know if you have any questions :)
Without using collections, here is a solution:
def count_letters(string):
string = string.upper()
counts = {}
for a in set(string):
counts[a] = string.count(a)
return counts
This function iterates over set(string), which is equal to all the letters used in your word, without duplicates, and in uppercase. Then it counts how many times each letter appears in your string, and adds it to your counts dictionary.
I hope this answers your question. :)

Creating instance names from a list (Python)

I've got a function that builds a random number of object instances. For the sake of demonstrating the general idea, we're going to pretend that this is an algorithm to build a series of nethack-like rooms.
The requirements are such that I won't know how many instances there will be in advance; these are generated randomly and on-the-fly.
As a brief note: I am fully aware that the following code is nonfunctional, but it should (hopefully!) demonstrate my aims.
import random
class Levelbuild(object):
def __init__(self):
self.l1 = dict({0:'a',1:'b',2:'c',3:'d',4:'e',5:'f',6:'g',7:'h',8:'i'})
# Pick a random number between 4 and 9.
for i in range(random.randint(4,9)):
self.l1[i] = Roombuilder()
If we assume that the chosen random integer is 5, the ideal result would be 5 Roombuilder() instances; labeled a, b, c, d, and e, respectively.
Is there a simple way of doing this? Is there a way to do this period?
--Edit--
A giant "thank you" to Nick ODell for his answer. This isn't a complete copy/paste-- but it's a variation that works for what I need;
import random
class Room(object):
def __init__(self):
self.size = (5,5)
class Level(object):
def __init__(self):
roomnames = ['a','b','c','d','e','f','g','h','i']
self.rooms = {}
for i in range(random.randint(4, 9)):
self.rooms[roomnames[i]] = Room()
Rather than build each "room" by hand, I can now...
test = Level()
print test.rooms['a'].size
>>> (5,5)
import string
import random
class Levelbuild(object):
def __init__(self,min_room_count,max_room_count):
rooms_temp = [new RoomBuilder() for i in range(random.randint(min_room_count,max_room_count))]
self.l1 = dict(zip(string.ascii_lowercase, rooms_temp))
Note: This will fail silently if given more than 26 rooms.
You're pretty close, actually. You don't need a dict; just use a list. (And, by the way, {...} is already a dict, so wrapping it in dict() doesn't do anything.)
roomnames = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
self.rooms = []
for i in range(random.randint(4, 9)):
self.rooms.append(Roombuilder(roomnames[i]))
For what it's worth, putting builder in the name of a class is kind of funky. The objects are rooms, right? So the type should just be Room.
As another answer for a more general solution (mainly as a companion to Nick ODell's answer, if you want to handle any number of names, it's a pretty simply solution with an infinite generator:
import string
import itertools
def generate_names(characters):
for i in itertools.count(1):
for name in itertools.product(characters, repeat=i):
yield "".join(name)
You can then use it as you would any other generator:
>>>print(dict(zip(generate_names(string.ascii_lowercase), range(30))))
{'aa': 26, 'ac': 28, 'ab': 27, 'ad': 29, 'a': 0, 'c': 2, 'b': 1, 'e': 4, 'd': 3, 'g': 6, 'f': 5, 'i': 8, 'h': 7, 'k': 10, 'j': 9, 'm': 12, 'l': 11, 'o': 14, 'n': 13, 'q': 16, 'p': 15, 's': 18, 'r': 17, 'u': 20, 't': 19, 'w': 22, 'v': 21, 'y': 24, 'x': 23, 'z': 25}
If you need to generate actual names, then you have a few choices. If you need a real word, pick from a dictionary file (most Linux users have one in /usr/share/dict). If you need word-like things, then I have actually written a Python script to generate such 'words' using Markov Chains, which is available under the GPL. Naturally, you'd have to check these for uniqueness.

Categories