How to find the number of rows in a namedtuple collection? - python-3.x

I have the following code:
Action = namedtuple('Action', 'name index delta_i delta_j')
up = Action('up', 0, -1, 0)
down = Action('down', 1, 1, 0)
left = Action('left', 2, 0, -1)
right = Action('right', 3, 0, 1)
I know there are 4 actions in the collection Action.
But what if I don't know? What Python code do I use to find out?
UPDATE
I have found out from the answers that there is no answer to this question.
Action is a class rather than a collection. I am tempted to delete this question, although it may help someone like me who is new to Python.

It depends on which object you wish to extract the length from.
From one of the instances:
size = len(up)
From the generated class itself, you can do e.g.
size = len(Action._fields) # try print(Action._fields)
From the string used to create the class:
fields = 'name index delta_i delta_j'
size = len(fields.split()) # again, try print(fields.split())

Related

Why do I get IndexError: string index out of range in this code?

message_text = ["text1\n", variable1, "\ntext2", variable2, "\ntext3", variable3]
u = MIMEText(message_text[0][1][2][3][4][5])
u['Subject'] = 'title of email'
s.sendmail("test1#test.com", "example1#example.com", u.as_string())
I got the error on this line:
u = MIMEText(message_text[0][1][2][3][4][5])
The error:
IndexError: string index out of range
What should I do?
When creating u, I loaded the indices 0, 1, 2, 3, 4, 5 from message_text, but that created the error.
Example Error Screen
It looks like you are using a multi-dimensional array.
Here's what python sees.
Take message_text[0] which is "text1\n"
Now take message_text[0][1] which is "e"
Now with message_text[0][1][2] we try to find what is the third element in "e"
This doesn't make sense, because the string "e" only has one element: the character 'e'.
If you want to add them all together, you'll need to convert your variables into text, and string them together.
u = MIMEText(message_text[0] + str(message_text[1]), message_text[2], str(message_text[3]), message_text[4], str(message_text[5]))
Converts all your variables into one long string before passing it the MIMEText command.
Not entirely sure how the MIMEText function works, but I think it takes in a text string instead of a list of strings. You can try writing something like this instead and see if it works:
message_text = f"text1\n{variable1}\ntext2{variable2}\ntext3{variable3}"
u = MIMEText(message_text)

Django automatically changes camel case

I am using models.IntegerChoices as Enum in Django, but it is saved in DB in a changed way.
class FruitsEnum(models.IntegerChoices):
Apple = 1
RedApple = 2
GreenApple = 3
LongBanana = 4
DragonFruit = 5
But it is saved in database like this : [('0','Apple'),('1','Redapple'),('2','Greenapple')...]
As you see the word 'apple' is not uppercase in two-word combinations. How Can I achive this :
[('0','Apple'),('1','RedApple'),('2','GreenApple')...]
Instead of passing integers, just pass a tuple consisting of the integer and the related name. Something like:
class FruitsEnum(models.IntegerChoices):
Apple = 1, 'Apple'
RedApple = 2, 'RedApple'
GreenApple = 3, 'GreenApple'
LongBanana = 4, 'LongBanana'
DragonFruit = 5, 'DragonFruit'
Alternatively, within your model, in the IntegerField where you're using this, you can replace FruitsEnum.choices with a tuple like:
[(1,'Apple'),(2,'RedApple'),(3,'GreenApple'),(4,'LongBanana'),(5,'DragonFruit')]
Note: Any differences you observe here are purely cosmetic and does not exist outside django (i.e within the database). You can open the database directly and see that only the integers are stored in the table.

How do I store the value of an indexed list in a global variable and call at it through a formatted function?

How do I store the value of an index and then use that value in a formatted exec function to print me the second results of each list under class Animal(): Dog list, which is what I expect to print. A simplified version of the essence of my problem along with further clarification below:
class Global():
str_list = []
current_word = ""
adj_word = 'poofy'
adj_int = 0
size = 0
pounds = 0
dog_years = 0
class Animal():
##### Formatted like so:[[visual size],[pounds],[age in dog years],[almost dead]] #####
dog = [['small', 'poofy'],[7, 45],[18, 101],[0, 1]]
input = 'dog'
def done():
print(Global.adj_int)
print(str(Global.size), str(Global.pounds), str(Global.dog_years))
def split_str():
Global.str_list = input.split()
split_str()
def analyze():
Global.current_word = Global.str_list.pop(0)
exec(f"""if Global.adj_word in Animal.{Global.current_word}[0]:
Global.adj_int = Animal.{Global.current_word}[0].index('{Global.adj_word}')
Global.size = Animal.{Global.current_word}[1][{Global.adj_int}]
Global.pounds = Animal.{Global.current_word}[2][{Global.adj_int}]
Global.dog_years = Animal.{Global.current_word}[3][{Global.adj_int}]""")
if len(Global.str_list) == 0:
done()
analyze()
it returns:
1
7 18 0
When I expect it to return "45 101 1" for size, pounds, dog_years because I am storing the .index value of 'poofy' for Animal.dog list in Global.adj_int. which in this case is '1'. Then I try to format the code so it uses that value to print the second values of each list but for some reason it will not print the expected results(under def analyze():... exec(f""".... Does anyone have an answer to this question?? This is a much more simple version of what I originally have but produces the exact same result. when I try to use the formatted code it acts as if adj_int = 0 when really it's adj_int = 1 (and I know it is stored as 1 like it should be because I print adj_int at the end to check) or I am not able to format the code in this way? But I need a work around regardless.
The problem is that the string argument to exec is being evaluated before it is executed. So, when you are calling exec this is what is called:
exec(f"""if Global.adj_word in Animal.dog[0]:
Global.adj_int = Animal.{dog}[0].index('poofy')
Global.size = Animal.dog[1][0]
Global.pounds = Animal.dog[2][0]
Global.dog_years = Animal.dog[3][0]""")
And after this, Global.adj_int becomes 1. The control flow and the structure of your code is incredibly complex comparing to its simplicity so I would carefully rethink its design, but for a quick fix, you probably want to first execute the part that sets the adj_int and then the rest, like this:
exec(f"""if Global.adj_word in Animal.{Global.current_word}[0]:
Global.adj_int = Animal.{Global.current_word}[0].index('{Global.adj_word}'"""))
exec(f"""if Global.adj_word in Animal.{Global.current_word}[0]:
Global.size = Animal.{Global.current_word}[1][{Global.adj_int}]
Global.pounds = Animal.{Global.current_word}[2][{Global.adj_int}]
Global.dog_years = Animal.{Global.current_word}[3][{Global.adj_int}]""")
Even after stating that your program is unnecessarily complex, let me additionally point out that using a global, mutable state is a really really bad practice, which makes your programs hard to follow, maintain & debug. The same concern relates to using exec.

How to implement a custom sorting algorithm to accept any type in python?

If I have to implement the sort, how can I make it accept any type of data (a list, string, set, dictionary or my own class type) and sort it? (I have done it for list, though). I'm new to OOPS and I couldn't understand much of source code of sorted(), which is written in 'C'.
EDITS
Here is the code:
class InsertionSort:
def insertion_sort(it):
for i in range(len(it)):
j = i
while j > 0 and it[j] < it[j - 1]:
it[j], it[j-1] = it[j-1], it[j]
j -= 1
return it
it_ints = [9, 8, 7, 6, 5, 4, 3, 2, 1]
sorted_ints = InsertionSort.insertion_sort(it_ints)
Now, what if I wanna pass other data structures? I could convert them to list as one of the answers say, but, how to sort dictionary or other types of data
I'm looking for something like Comparable of Java
in Python to implement
PS: I'm actually doing Algorithms course on Coursera which is in JAVA. I'm trying to analyze the lectures there and re-write programs in python, particularly with class implementation.
Need help
Now that you've mentioned that you already have a function to sort list than why not try this?
def yourSortingFunction(items):
#now that you're expecting them to be list:
items = list(items)
//your sorting code
P.S: even sorted() function in python 3.x returns a list of sorted elements when you pass(list, set, string) and since you asked about these 3 in your question I'm suggesting this solution.
Comments and edits are most welcome. I'm new to StackOverflow (and coding).

Increment string in Matlab

i am using a video with a simple background and prompting an alert text whenever someone passes by.
clear all
myVideoObj = VideoReader('video.avi');
nFrames = myVideoObj.NumberOfFrames;
sound = wavread('somethingwrong.wav');
flag = 1;
% Read one frame at a time.
for i = 2 : nFrames-1
frame1 = read(myVideoObj, i-1); frame2 = read(myVideoObj, i);
diff = abs(rgb2gray(frame1) - rgb2gray(frame2));
if sum(sum(diff)) < 46000
imshow(frame2, [])
drawnow
else
imshow(frame2, [])
text(100, 100, 'Intruder!!!' , 'FontSize',24)
drawnow
end
end
The drawon works. But now im trying to figure out how to do an increment of strings for each person that passes by. How do i start? Thanks in advance
Are you trying to make it so the text increments a counter each time it detects an intruder (so this is included in the "Intruder!!!" message)? If so, you should be able to accomplish this as follows:
You can make a string variable and a counter:
message_string = 'Intruder #';
count = 1;
and then each time you find a new person, you would set a new message string:
total_message = strcat(message_string, num2str(count));
which would be sent to the text function:
text(100, 100, total_message, 'FontSize', 24)
then increment the count.
If this is not an answer to your question, please clarify what you mean by doing an increment of strings for each person that passes by.

Resources