Creating a map/contents of any object - python

In Python 3.6. What I'm trying to do is create a function that can accept any object and then generate a tree like contents.
Similar to a book:
1. Object
1.1 member: integer
1.2 member: list
2.1 list: element 1
2.2 list: element 2
1.3 member: string
My purpose is to use the numbers as a key for a technical readout, the number could also stand in for a more understandable ID number than id() generates. Because the objects I want to deal with are all types, I'd like the function to be recursive. Here is what I have so far:
def contents(a, n = 0, lim = 5, prefix=""):
index = 1
text = ""
j = None
if n < lim:
try:
for i in a.__dict__:
text = text + "\n" + ("\t" *(n)) + prefix + str(index) + ", " + str(i) + ": " + contents(a.__dict__[i], n = n + 1, prefix=str(n)+".") + ""
index += 1
except:
try:
for i, j in a.items():
text = text + "\n" + ("\t"*(n)) + prefix + str(index) + ", " + str(i) + ": " + contents(i, n = n + 1, prefix=str(n)+".") + ""
index += 1
except:
if isinstance(a, str):
text = text + "\n" + ("\t"*(n)) + prefix + str(index) + ", " + str(a) + " "
else:
try:
for i in a:
text = text + "\n" + ("\t"*(n)) + prefix + str(index) + ", " + str(i) + contents(i, n = n + 1, prefix=str(n)+".") + " "
index += 1
except:
text = text + "\n" + ("\t"*(n)) + prefix + str(index) + ", " + str(a) + " "
else:
text = text + "limit. \n"
return text
a is the object, n is the current number of recursion, lim is the recursion limit, prefix has to do with the object ID displayed.
Here's the testing object
class Aclass:
def __init__(self):
self.a = [12, 24]
self.b = 5
a = [Aclass(), 1, "2", 3, 4, Aclass(), {"c":"d","e":"f"}]
The problem I'm running into has to do with strange revursive behavior with lists, I already made an exception for strings, because the string would register as an iterable made up of iterables, which would recurse indefinitely if I hadn't put in a limit. Now simple lists of numbers like [1, 2, 3, 4] will often list the number twice as if it breaks down into a one item list [1] and then reports on the number inside: 1.

You should have a look at the pprint module, which is part of the standard distribution. It solves this problem already, and so might serve as a basis for your code. (I can easily see, for instance, adding numbers by subclassing the PrettyPrinter class.)
This code:
class Aclass:
def __init__(self):
self.a = [12, 24]
self.b = 5
a = [Aclass(), 1, "2", 3, 4, Aclass(), {"c":"d","e":"f"}]
import pprint
s = pprint.pformat(a, indent=4)
print(s)
Produces this output:
[ <__main__.Aclass object at 0x1060fb160>,
1,
'2',
3,
4,
<__main__.Aclass object at 0x1060fb198>,
{'c': 'd', 'e': 'f'}]

Related

How to randomly choose something from a list then remove it while in a function

from random import choice
from random import choices
from random import shuffle
wkd = ["Razvan", "Vali", "Stefan", "Dontu","Abel", "David P.", "Beni N."]
cls = ["Angelo", "Dragos", "Beni D.", "Andy", "Vlad T.", "Dani", "Ruben", "George", "Sebi Br."]
restul = ["Claudiu", "Cipri", "David", "Rares N.", "Vlad P.", "Marian", "Seba", "Emi", "Darius", "Stefano", "Iosif", "Radu", "Rares", "Robert", "Alberto B.", "David B.", "Robert T."," James", ]
Duminica = "Duminica"
Luni = "Luni"
Marti = "Marti"
Miercuri = "Miercuri"
Joi = "Joi"
Vineri = "Vineri"
def choice_restul():
global restul
restul1 = choice(restul)
restul.remove(restul1)
return restul1
def choice_restul_wkd():
global wkd
global restul
restul_wkd = str(choice(restul + wkd))
nr = 1
try:
restul.remove(restul_wkd)
wkd.remove(restul_wkd)
except ValueError:
nr += 1
return restul_wkd
def choice_toti():
global restul
global wkd
global cls
choice_toti = str(choice(restul + wkd + cls))
nr = 1
try:
restul.remove(choice_toti)
wkd.remove(choice_toti)
cls.remove(choice_toti)
except ValueError:
nr += 1
class servicii:
def cantina():
nr_sapt = 1
while nr_sapt < 5:
with open(f'cantina{nr_sapt}.txt', 'w') as f:
f.write("Cantina")
f.write("\n")
f.write(Duminica + "" + "-" + choice_restul())
f.write("\n")
f.write(Luni + "" + "-" + choice_restul_wkd())
f.write("\n")
f.write(Marti + "" + "-" + choice_restul_wkd())
f.write("\n")
f.write(Miercuri + "" + "-" + choice_restul_wkd())
f.write("\n")
f.write(Joi + "" + "-" + choice_restul_wkd())
f.write("\n")
f.write(Vineri + "" + "-" + choice_restul())
f.write("\n")
nr_sapt += 1
return "Cantina"
def palier():
with open('rezultat.txt', 'w') as f:
f.write("\n")
f.write("Palier")
f.write("\n")
f.write(Duminica + "" + "-" + choice_restul())
f.write("\n")
f.write(Luni + "" + "-" + choice_restul_wkd())
f.write("\n")
f.write(Marti + "" + "-" + choice_restul_wkd())
f.write("\n")
f.write(Miercuri + "" + "-" + choice_restul_wkd())
f.write("\n")
f.write(Joi + "" + "-" + choice_restul_wkd())
f.write("\n")
f.write(Vineri + "" + "-" + choice_restul())
f.write("\n")
return "Palier"
def curte():
curte = "curte"
return curte
def poarta():
poarta = "poarta"
return poarta
print(servicii.cantina())
This is my code. It's in another language but basically what I want to do is randomly choose someone from a list to do certain tasks but I don't want someone to be picked again. I did something to remove from the list once picked but it isn't working. The same person is picked again. Can somebody help?
I tried everything (I think) I want to remove someone from the list once picked, but the remove is only local but I want it to be globally.
When you do your random choice, you pick from the sum of lists (which is ok). When you come to remove the chosen item, you catch errors, which then may mask the actual removal. You probably need a function which tried each container in turn:
def remove_element(containers, element):
for c in containers:
try:
c.remove(element)
return
except ValueError:
pass
def choice_restul_wkd():
global wkd
global restul
restul_wkd = choice(restul + wkd)
remove_element([restul, wkd], restul_wkd)
return restul_wkd

Implementing a match counter into a lotto number guesser

im rather new to python and found someones lottery simulation in github. After playing around with it for a while i wanted to add a counter, that counts the number of matches of your Number out of the total draws.
I don't know if it is because i did not write the code myself, but i can't seem to make it happen. I've tried some of pythons counter modules bu that did'nt seem to be the right thing.
Heres my code:
import random
import time
### TODO - Refactor GetDrawNumbers (add timers)
### TODO - Refactor CheckNumbers
def GetDrawNumbers():
drawNumbers = []
for i in range(6):
x = None
while (x == None or x in drawNumbers):
x = random.randint(1, 49)
drawNumbers.append(x)
return drawNumbers
def CheckNumbers(myTicket, actualNumbers):
numbersMatched = 0
for number in myTicket:
if number in actualNumbers:
numbersMatched += 1
return numbersMatched
### Script starts here
startTime = time.perf_counter()
myNumbers = [4, 8, 15, 16, 23, 42]
for draw in range(2000):
drawNumber = draw + 1
thisWeeksDraw = GetDrawNumbers()
numbersMatched = CheckNumbers(myNumbers, thisWeeksDraw)
##print("Week " + str(drawNumber) + " numbers : " + str(thisWeeksDraw) + " (" + str(numbersMatched) + " matched)")
if numbersMatched == 4:
print("Week " + str(drawNumber) + " numbers : " + str(thisWeeksDraw) + " (" + str(numbersMatched) + " matched)")
count = numbersMatched
print("Total matches: " + str(count))
endTime = time.perf_counter()
elapsedTime = endTime - startTime
print("Completed in " + str(elapsedTime) + " seconds!")
If anyone knows a way to implement a counter, that counts the number of times this the program gets 3,4,5 or 6 correct matches i would be super relieved! It's not that this project would be super important but solving the problem would be a milestone for me and my learning process!
Thanks in advance and best wishes!
How about this where I have added a check of the numbersMatched value and increment a counter whenever it is 3 or more
import random
import time
### TODO - Refactor GetDrawNumbers (add timers)
### TODO - Refactor CheckNumbers
def GetDrawNumbers():
drawNumbers = []
for i in range(6):
x = None
while (x == None or x in drawNumbers):
x = random.randint(1, 49)
drawNumbers.append(x)
return drawNumbers
def CheckNumbers(myTicket, actualNumbers):
numbersMatched = 0
for number in myTicket:
if number in actualNumbers:
numbersMatched += 1
return numbersMatched
### Script starts here
startTime = time.perf_counter()
myNumbers = [4, 8, 15, 16, 23, 42]
countOfThreeOrMoreMatched = 0
for draw in range(2000):
drawNumber = draw + 1
thisWeeksDraw = GetDrawNumbers()
numbersMatched = CheckNumbers(myNumbers, thisWeeksDraw)
##print("Week " + str(drawNumber) + " numbers : " + str(thisWeeksDraw) + " (" + str(numbersMatched) + " matched)")
if numbersMatched >= 3:
countOfThreeOrMoreMatched += 1
if numbersMatched == 4:
print("Week " + str(drawNumber) + " numbers : " + str(thisWeeksDraw) + " (" + str(numbersMatched) + " matched)")
print(f"Count with 3 or more matches {countOfThreeOrMoreMatched}")
count = numbersMatched
print("Total matches: " + str(count))
endTime = time.perf_counter()
elapsedTime = endTime - startTime
print("Completed in " + str(elapsedTime) + " seconds!")

Rosalind Consensus and Profile Problem code doesn't work

This is the problem: http://rosalind.info/problems/cons/
def file_read(fname):
with open(fname, "r") as myfile:
global data
data = myfile.readlines()
print(data)
i = 0
while i < len(data):
data[i] = data[i].replace("\n", "")
if ">" in data[i]:
data.remove(data[i])
else:
i += 1
file_read('rosalind_cons.txt')
res = ["".join(el) for el in zip(*data)]
print(res)
a_str = ""
c_str = ""
g_str = ""
t_str = ""
for x in range(0, len(res)):
a_str += (str(res[x].count("A"))) + " "
for x in range(0, len(res)):
c_str += (str(res[x].count("C"))) + " "
for x in range(0, len(res)):
g_str += (str(res[x].count("G"))) + " "
for x in range(0, len(res)):
t_str += (str(res[x].count("T"))) + " "
a_str_nospace = a_str.replace(" ", "")
c_str_nospace = c_str.replace(" ", "")
g_str_nospace = g_str.replace(" ", "")
t_str_nospace = t_str.replace(" ", "")
consensus_string = ""
for x in range(0, len(a_str_nospace)):
if max(a_str_nospace[x], c_str_nospace[x], g_str_nospace[x], t_str_nospace[x]) in a_str_nospace[x]:
consensus_string += "A"
elif max(a_str_nospace[x], c_str_nospace[x], g_str_nospace[x], t_str_nospace[x]) in c_str_nospace[x]:
consensus_string += "C"
elif max(a_str_nospace[x], c_str_nospace[x], g_str_nospace[x], t_str_nospace[x]) in g_str_nospace[x]:
consensus_string += "G"
elif max(a_str_nospace[x], c_str_nospace[x], g_str_nospace[x], t_str_nospace[x]) in t_str_nospace[x]:
consensus_string += "T"
print(consensus_string)
print("A: " + a_str)
print("C: " + c_str)
print("G: " + g_str)
print("T: " + t_str)
What's wrong with my code?
For the sample output it works but for the larger datasets it doesn't.
I don't know what is wrong, I think it's the file reading part that's not correct (maybe?)
EDIT: There are some print functions in there but I don't copy them in the answer box so they don't matter in the result
nice to see a fellow Rosalind user. I discovered that page when I studied Bioinformatics and just stumbled upon it again last month.
To answer your question:
You're creating a string of numbers, so that works fine if the numbers are all below 10.
Try building a list of integers first and only convert them to a string in the final step.

How do I make random.randint refresh while program is running?

I'm making a small program that shoots out math problems and requires an answer to pass. It works fine, but all the randint values I generate stay static for as long as the progran is running. I figured if I change:
Tehtävä = random.choice(Laskut)
Into a function it should refresh with the loop. Problem is I can't for the life of me figure out how to do that. Would it even work for what I'm trying? The randint values are determined in a seperate list. Heres the rest of the code:
Peli = 1
while Peli != 2:
pulma = 1
refresh = 1
Tehtävä = random.choice(Laskut)
while pulma == 1:
ratkaisu = float(input(Tehtävä.problem + "\n:"))
if ratkaisu == Tehtävä.answer:
pulma += 1
refresh += 1
print("oikein")
elif ratkaisu == "loppu":
pulma += 1
refresh += 1
Peli += 1
else:
print("väärin")
Here are the values I used:
import random
class Algebra:
def __init__(self, problem, answer):
self.problem = problem
self.answer = answer
#Muuttujat
#erotus ja summa
a = random.randint(1,99)
b = random.randint(1,99)
c = random.randint(1,99)
d = random.randint(1,99)
#jako ja kerto
e = random.randint(1,10)
f = e*random.randint(1,10)
g = random.randint(1,10)
#Kysymykset
Kysymys_M = [str(a) + "+" + str(b) + "-x=" + str(c),
str(a) + "-" + str(b) + "-x=" + str(a),
str(a) + "-" + str(b) + "-" + str(c) + "-x=" + str(d),
str(e) + "*x=" + str(f),
str(f) + ":x=" + str(e),
"x:" + str(e) + "=" + str(g)]
#Vastaukset
Vastaus_M = [a+b-c,
-b,
a-b-c-d,
f/e,
f/e,
e*g]
Laskut = [
Algebra(Kysymys_M[0], Vastaus_M[0]),
Algebra(Kysymys_M[1], Vastaus_M[1]),
Algebra(Kysymys_M[2], Vastaus_M[2]),
Algebra(Kysymys_M[3], Vastaus_M[3]),
Algebra(Kysymys_M[4], Vastaus_M[4]),
Algebra(Kysymys_M[5], Vastaus_M[5]),]
(If I have packed too much information please let me know.)

Python formatting print

I'm having some formatting issues with my call to print function. For lack of knowledge of better ways to format, i've ended up with an issue. here is what it should look like
However the actual result of my print returns this.
def tupleMaker(inputString):
s1 = inputString.split()
# Adding the surname at the end of the string
s2 = [s1[len(s1) - 1]]
# Number of other names(no surname)
global noOfNames
noOfNames = len(s1) - 4
# Adding all the other names
for i in range(noOfNames):
s2.append((s1[i + 3]))
# Adding the Reg number
s2.append(s1[0])
# Adding the Degree scheme
s2.append(s1[2])
# Adding the year
s2.append("Year " + s1[1])
# Making it a tuple
t = ()
for i in range(len(s2)):
t = t + (s2[i],)
return t
def formatting(t):
s1 = ""
for i in range(len(t)):
s1 += t[i]
if (i == 0):
s1 += ", "
elif (i == len(t) - 4):
s1 += " "
else:
s1 += " "
#print(t[0] + ", ", end="")
#for i in range(noOfNames):
#print (t[i+1], end= " ")
#print(format(t[1+noOfNames], "<32s"))
#print(format(thenames, "<32d") + format(regNo, "<7d") + format(degScheme, ">6s") + format(year, ">1s")
print("")
print(s1)
I would recommend looking at using pythons built in string.format() function a small tutorial is located here: https://pyformat.info/

Categories