Checking if characters in a file can be integers - python

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")

Related

How can I translate words with a python script?

So we have to translate numbers from English to German. I feel I am doing it all wrong because I get no
output when I test my code.
#!/usr/bin/env python3
import sys
english = sys.stdin.read().split()
num = {}
with open("translation.txt") as f:
data = f.read().split("\n")
i = 0
while len(data[i]) < 0:
n = data[i].split()
n1 = n[0]
n2 = n[1]
if n1 not in num:
num[n1] = n2
i = i + 1
i = 0
while i < len(english):
n = english[i]
if n in num:
print(num[n])
i = i + 1
Please help. Am I even getting the code to open the text file? the text file contains numbers translated from English to German
Example of translation.txt
one: eins
two: zwei
three: drei
four: vier
five: funf
six: sechs
seven: sieben
eight: acht
nine: neun
ten: zehn
Well, your code had some major logical errors. First of all, a comparison was wrong for the loops. You also split the line but you left : in the keys. Also checking if the word already exists is not necessary, but I left it as you wrote. I also added two side translation just in case you will need it.
Here is my implementation of the problem:
#!/usr/bin/env python3
import sys
english = sys.stdin.read().split()
num = {}
with open("translation.txt") as f:
data = f.read().split("\n")
i = 0
while i < len(data):
n = data[i].split()
print(n)
n1 = n[0].replace(':', '')
n2 = n[1]
if n1 not in num and n2 not in num:
num[n1] = n2
num[n2] = n1
i = i + 1
print(num['one'])
print(num['eins'])
You read inputs from standard input via sys.stdin.read(). This requires reading ALL characters until an EOF is met, which would happen only if:
An EOF is entered via the keyboard (Ctrl-D for Unix-based systems and Ctrl-Z for Windows);
The input is redirected from another stream that ends with an EOF, such as a file stream.
If the input is entered line by line via the keyboard, the output won't be seen until an EOF is seen. If it is desired that the output is shown immediately after one line of input, input() should be used instead of sys.stdin.read().
Other issues have been explained in #Raguel's answer.
Here we have a major issue with application logic, as were mentioned in previous answers:
First of all, we need to load dictionary - our resource to operate.
Second, we can start the translation, for example word-by-word from continues user input
The compact solution (require python 3.8):
#!/usr/bin/env python3
with open("translation.txt", "r") as f:
dictionary = { k: v.strip() for k, v in [line.split(":") for line in f.readlines()]}
while word:=input("Word to translate: "):
try:
print(dictionary[word])
except KeyError:
print(f"No translation found for the word: {word}")

lowercasing function doesn't work in a different function

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.

Counting each DIFFERENT character in text file

I'm relatively new to python and coding and I'm trying to write a code that counts the number of times each different character comes out in a text file while disregarding the case of the characters.
What I have so far is
letters = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',
'p','q','r','s','t','u','v','w','x','y','z']
prompt = "Enter filename: "
titles = "char count\n---- -----"
itemfmt = "{0:5s}{1:10d}"
totalfmt = "total{0:10d}"
whiteSpace = {' ':'space', '\t':'tab', '\n':'nline', '\r':'crtn'}
filename = input(prompt)
fname = filename
numberCharacters = 0
fname = open(filename, 'r')
for line in fname:
linecount +=1
word = line.split()
word += words
for word in words:
for char in word:
numberCharacters += 1
return numberCharacters
Somethings seems wrong about this. Is there a more efficient way to do my desired task?
Thanks!
from collections import Counter
frequency_per_character = Counter(open(filename).read().lower())
Then you can display them as you wish.
A better way would be to use the str methods such as isAlpha
chars = {}
for l in open('filename', 'rU'):
for c in l:
if not c.isalpha(): continue
chars[c] = chars.get(c, 0) + 1
And then use the chars dict to write the final histogram.
You over-complicating it, you can just convert your file content to a set in order to eliminate duplicated characters:
number_diff_value = len(set(open("file_path").read()))

Nested loops slowing down program. How can I make it faster?

import re
file=input("What is the name of your file? ")
def words_from_file(filename):
try:
f = open(filename, "r")
words = re.split(r"[,.;:?\s]+", f.read())
f.close()
return [word for word in words if word]
except IOError:
print("Error opening %s for reading. Quitting" % (filename))
exit()
dictionary_file=words_from_file("big_word_list.txt")
newfile=words_from_file(file)
def dictionary_check(scores, dictionary_file, full_text):
count=0
for item in full_text:
if item in dictionary_file:
count+=1
scores.append(count)
def decoder(item,shiftval):
decoded = ""
for c in item:
c=c.upper()
if c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
num = ord(c)
num += shiftval
if num > ord("Z"):
num=num-26
elif num < ord("A"):
num=num+26
decoded+=chr(num)
else:
decoded = decoded + c
return decoded
shiftval=0
scores=[]
while shiftval<=26:
full_text=[]
for item in newfile:
result=decoder(item,shiftval)
full_text.append(result)
shiftval+=1
print(full_text)
dictionary_check(scores, dictionary_file, full_text)
highest_so_far=0
for i in range(len(scores)):
if scores[i]>highest_so_far:
i=highest_so_far
i+=1
else:
i+=1
fully_decoded=""
for item in newfile:
test=decoder(item,highest_so_far)
fully_decoded+=test
print(fully_decoded)
Hey everybody.
I have this assignment where I had to make a program that decodes a shift cipher. Right now it works, but it's incredibly slow. I suspect it's probably because of the nested loops. I'm not really sure where to go from this point.
Some explanation of the code: The program reads in an encrypted file where each letter is shifted by a certain amount (i.e With a shift of 5, every A would now be an F. This would be done for every letter). The program reads in a dictionary file as well. There are only 26 possible shifts so for each shift it will decode the file. The program will take the file for each possible shift and compare it to the dictionary file. The one that has the most in common with the dictionary file will be reprinted as the final decrypted file.
Thank you everybody!
https://drive.google.com/file/d/0B3bXyam-ubR2U2Z6dU1Ed3oxN1k/view?usp=sharing
^ There is a link to the program, dictionary, encrypted and decrypted files.
Just change line 16 :
dictionary_file=set(words_from_file("big_word_list.txt"))
So the if item in dictionary_file: is executed in constant time instead of linear time. The program runs now in 4 seconds, disabling print statements,
and changing i=highest_so_far in highest_so_far=i, and capitalizing dictionary.

Counting prefixes from a csv file using python

Is there a way to make this python system count the prefixes in the array? I keep getting a prefixcount result of 0
Any help would be appreciated :)
The code I have is below
file = input("What is the csv file's name?")+".csv"
openfile = open(file)
text = sorted(openfile)
print("Sorted list")
print(text)
dictfile = open("DICT.txt")
prefix = ['de', 'dys', 'fore', 'wh']
prefixcount = 0
for word in text:
for i in range(0, len(prefix)):
if word>prefix[i]:
break
if word[0:len(prefix[i])] == prefix[i]:
prefixcount+=1
break
print(prefixcount)
Firstly, when you meet a condition where you want to skip an iteration, use continue - break ends the loop entirely.
Secondly, word>prefix[i] does not do what you want; it compares the strings lexicographically (see e.g. the Python docs), and you really want to know len(word) < len(prefix[i]).
I think what you want is:
prefixcount = 0
for word in text:
for pref in prefix:
if word.startswith(pref):
prefixcount += 1

Categories