TypeError: 'NoneType' does not support item assignment

**I am trying to create a clock in/out system. I created a row and a function to get the current time. I want to get the new row that I create in - “def clock_in_button_click(self, **event_args)” and update the row “Clock_Out_Lunch” with variable “Out_For_Lunch_LA_time” in function clock_out_button_click(self, **event_args) **

**I read the docs and tried a multitude of variations to get this to work. I know I am making a dumb mistake somewhere, but I just can’t see it.

The error I keep getting is:
TypeError: ‘NoneType’ does not support item assignment at [Main, line 87]
which is
out_for_lunch_table[‘Clock_Out_Lunch’] = Out_For_Lunch_LA_time
**

Code Sample:

  def Start_time(self):
    current_clock_in_time = DT.datetime.now()
    Start_time_UTC_current = DT.datetime.now(anvil.tz.tzutc())
    Start_time_UTC_current = Start_time_UTC_current.strftime("%m-%d-%Y %H:%M")
    Start_time_UTC_current2 = DT.datetime.strptime(Start_time_UTC_current,"%m-%d-%Y %H:%M")
    Current_start_time = Start_time_UTC_current2 - timedelta(hours=7)
    return Current_start_time
  
  def clock_in_button_click(self, **event_args):
    Start_time = self.Start_time()
    Clocked_In = app_tables.clockinoutsystem.add_row(Users=anvil.users.get_user()['email'],Clock_In_Start=Start_time, Clock_Out_Lunch=Start_time, Clock_In=Start_time, Clock_Out_End=Start_time)
    return Start_time
  
  #def Start_time(self):
  #  current_clock_in_time = DT.datetime.now()
  #  Start_time_UTC_current = DT.datetime.now(anvil.tz.tzutc())
  #  Start_time_UTC_current = Start_time_UTC_current.strftime("%m-%d-%Y %H:%M")
  #  Start_time_UTC_current2 = DT.datetime.strptime(Start_time_UTC_current,"%m-%d-%Y %H:%M")
  #  Current_start_time = Start_time_UTC_current2 - timedelta(hours=7)
  #  return Current_start_time
    
  def clock_out_button_click(self, **event_args):
    Out_For_Lunch_UTC_current = DT.datetime.now(anvil.tz.tzutc())
    Out_For_Lunch_UTC_current = Out_For_Lunch_UTC_current.strftime("%m-%d-%Y %H:%M")
    Out_For_Lunch_UTC_current2 = DT.datetime.strptime(Out_For_Lunch_UTC_current,"%m-%d-%Y %H:%M")
    Out_For_Lunch_LA_time = Out_For_Lunch_UTC_current2 - timedelta(hours=7)
    
    #Start_time = self.Start_time()
    self.Start_time()
    Start_time = self.Start_time()
    out_for_lunch_table = app_tables.clockinoutsystem.get(Clock_In_Start=Start_time)
    out_for_lunch_table['Clock_Out_Lunch'] = Out_For_Lunch_LA_time
    pass

Anvil | Login

The results of this is None . Since it was not found in the database.
Since None cannot be assigned to, you got the error:

Another bug here is when you are calling .strftime() you are not passing the timezone back into it making it an unaware datetime object. If you tried to pass this back to the database, the time will be corrected twice. When you pass an unaware timestamp to anvil it gets adjusted to make it aware compared to the clients origin. This will not happen from inside the server which is utc time, it would automatically (correctly) get utc.

Thank you for taking the time this. I am new to python so bear with me on the silly questions haha.

out_for_lunch_table = app_tables.clockinoutsystem.get(Clock_In_Start=Start_time)

Why is the results None? I thought I assigned a value to it here:

def clock_in_button_click(self, **event_args):
    Start_time = self.Start_time()
    Clocked_In = app_tables.clockinoutsystem.add_row(Users=anvil.users.get_user()['email'],**Clock_In_Start=Start_time**, Clock_Out_Lunch=Start_time, Clock_In=Start_time, Clock_Out_End=Start_time)
    return Start_time

Thank you for catching the other bug. How do I fix it?

I got a hint at what is wrong, but I cannot figure out how to fix it.

Between the time I click on Clock in and wait 1 min, the Clock out button does not work. If I click on the clock out button right after I click on the clock in, and then it works.

It seems as if it stops recognizing something after 1 minute, but what is it and how to fix it is the question. Aghh

Because you’re calling Start_time to calculate the starting time. But that just gives you the current time.

You’re using the wrong approach. There’s no way to calculate the starting time when they click the clock out button, you have to remember the starting time in some fashion. e.g. using self.whatever variables, using the User record, etc.

This happens quite often to beginners, you might be confusing yourself with the varable names you are choosing. you call it out_for_lunch_table but you are trying to assign it a row from that table that is the result of a single row search operation (.get()).

̶I̶n̶ ̶t̶h̶e̶ ̶f̶u̶n̶c̶t̶i̶o̶n̶ ̶w̶h̶e̶r̶e̶ ̶y̶o̶u̶ ̶s̶e̶t̶ ̶i̶t̶,̶ ̶y̶o̶u̶ ̶s̶e̶t̶ ̶a̶ ̶u̶n̶i̶q̶u̶e̶ ̶e̶m̶a̶i̶l̶,̶ ̶y̶o̶u̶ ̶p̶r̶o̶b̶a̶b̶l̶y̶ ̶w̶a̶n̶t̶ ̶t̶o̶ ̶̶̶̶.̶g̶e̶t̶(̶)̶̶̶̶ ̶t̶h̶e̶ ̶r̶o̶w̶ ̶b̶y̶ ̶s̶e̶a̶r̶c̶h̶i̶n̶g̶ ̶f̶o̶r̶ ̶t̶h̶a̶t̶ ̶i̶n̶s̶t̶e̶a̶d̶.̶.̶.̶ ̶b̶u̶t̶ ̶I̶ ̶d̶o̶n̶’̶t̶ ̶k̶n̶o̶w̶ ̶i̶f̶ ̶y̶o̶u̶ ̶w̶a̶n̶t̶ ̶o̶n̶l̶y̶ ̶o̶n̶e̶ ̶r̶o̶w̶ ̶p̶e̶r̶ ̶u̶s̶e̶r̶.̶.̶.̶

You should really just look at the docs for .get() , .search() etc. :

And then write your architecture / logic around that, I think in another thread someone mentioned you have to make design decisions about how many users you will have etc.

So I start a new row with def clock_in_button_click(self, **event_args), calculate the start time, and record it to the data table.

How do I reference that start time?
Also, how do I reference it in a new function?

I understand now that it is just getting the current time.

Here is an example of some logic, you don’t have to use it, but its what I came up with because I do stuff like this often.

Create a new column of type bool. This column will be called clocked_in.

Create a single “Clock in and out” button.

Have the logic .get() the row that has both the current users email and clocked_in == True
Store this in a variable called row (for clarity)

Do an equivalency test.

if row is None:
  #write code that clocks --in-- the user with by creating a new row 
  #don't forget to set row['clocked_in'] = True
  #set clocked in time to "now"
  ...
else:
  #write code that clocks --out-- the user with by modifying the existing row 
  #don't forget to set row['clocked_in'] = False
  #set clocked OUT time to "now"
  #you can now modify by calling the keys from the row variable, it is not None.
  ...

If it is None, they are not clocked in, and they need to be clocked in. If instead it retrieved a row, then it found a clocked in user, and it should clock them out, by setting the bool column to False and writing the clocked out timestamp to the correct column.

If you are really interested in learning python (It is easier that you might think) you might start at any of these places:

Python Discord Community
This a global community with dedicated rooms for seeking help.

Python Matrix Community
Chat based global community

The last two are freemium:

2 Likes

The Python Discord community has a curated list of resources:

https://www.pythondiscord.com/resources/

1 Like