Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Q on classes
#1
Hi,

I appreciate some help on this micropython code as I'm learning classes.

When I execute it, I get the error:
Error:
Error in sysc: function takes 4 positional arguments but 3 were given
from line 78.

I don't understand why it's saying 4 when the function only requires 3.

TIA

import umachine
import ntptime
import utime

rtc = umachine.RTC()

class Clock:
    def __init__(self):
        self.hours = 0
        self.minutes = 0
        self.seconds = 0
                  
    
    def set_time(self, hours, minutes, seconds):
        self.hours = hours
        self.minutes = minutes
        self.seconds = seconds
        
    
    def get_time(self):
        return '{:02d}:{:02d}:{:02d}'.format(self.hours, self.minutes, self.seconds)
    
        
# sync time
class Sync:
    year = 2000
    month = 1
    day = 1
    weekday = 1
    hours = 12
    minutes = 12
    seconds = 30
    milliseconds = 0
    
    def __init__(self):
        pass
#         self.year
#         self.month 
#         self.day
#         self.weekday
#         self.hours
#         self.minutes
#         self.seconds
#         self.milliseconds

    @staticmethod
    def sync_time():
        try:
            ntptime.settime()
            
            (year, month, day, weekday, hours, minutes, seconds, milliseconds) = rtc.datetime()
            print (f"UTC (before synchronization):",(year, month, day, hours, minutes, seconds))
                        
            # adjust for local timezone
            HHMarch   = utime.mktime((year,3 ,(31-(int(5*year/4+4))%7),1,0,0,0,0,0)) #Time of March change to CEST
            HHOctober = utime.mktime((year,10,(31-(int(5*year/4+1))%7),1,0,0,0,0,0)) #Time of October change to CET
            now=utime.time()
                        
            if now < HHMarch :                # we are before last sunday of march
                cet=utime.localtime(now+3600) # CET:  UTC+1H
            elif now < HHOctober :            # we are before last sunday of october
                cet=utime.localtime(now+7200) # CEST: UTC+2H
            else:                             # we are after last sunday of october
                cet=utime.localtime(now+3600) # CET:  UTC+1H
                             
            print(f"Local time after synchronization:{cet}")
                        
            year = cet[0]
            month = cet[1]
            day = cet[2]
            hours = cet[3]
            minutes = cet[4]
            seconds = cet[5]
            weekday = cet[6]

            print(f'Updating RTC...')
            rtc.datetime((year, month, day, weekday, hours, minutes, seconds, milliseconds))
            Clock.set_time(hours, minutes, seconds)
        except Exception as err:
            # catch any other exceptions
            print(f'Error in sysc: {err}')
Reply
#2
It is saying 4 because it requires 4. Clock.set_time() is an instance method. The first argument must be an instance of Clock. You are treating it like a static method.

I would rename this method __str__:
    def get_time(self):
        return '{:02d}:{:02d}:{:02d}'.format(self.hours, self.minutes, self.seconds)
I would also use f'string formatting because format() is old and not great, and also because you use f'string formatting everywhere else in your program.
    def __str__(self):
        return f'{self.hours:02d}:{self.minutes:02d}:{self.seconds:02d}'
But I would not use f'string formatting here.
print(f'Updating RTC...')
And I would use unpacking here:
            year = cet[0]
            month = cet[1]
            day = cet[2]
            hours = cet[3]
            minutes = cet[4]
            seconds = cet[5]
            weekday = cet[6]
year, month, day, hours, minutes, seconds, weekday, *_ = cet
Reply
#3
(Mar-06-2023, 03:20 PM)deanhystad Wrote: Clock.set_time() is an instance method. You need to call it using an instance of Clock.

Thanks for the quick response but then how do I recall a function within a different class?
Reply
#4
(Mar-06-2023, 03:21 PM)deanhystad Wrote: Clock.set_time() is an instance method. You need to call it using an instance of Clock.

I would rename this method __str__:
    def get_time(self):
        return '{:02d}:{:02d}:{:02d}'.format(self.hours, self.minutes, self.seconds)

Actually, I'm trying to execute set_time() from line 14.
Reply
#5
Sync needs to make an instance of Clock, probably in the __init__ (self.clock = Clock()) or as a class variable (clock = Clock(). Then it calls self.clock.set_time(hours, minutes, seconds).
ebolisa likes this post
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Using classes? Can I just use classes to structure code? muteboy 5 5,117 Nov-01-2017, 04:20 PM
Last Post: metulburr

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020