How do i fix the answer it always wrong if it is in other number?

.model small
.stack 100h
.data

Spc     db 0dh,0ah, " $"                                                ;New Line
;Bases Calculation in Calculator
BsA31   db 0dh,0ah, "   Base 03 Addition "                          ;Addition Base 03
        db 0dh,0ah, " "
        db 0dh,0ah, "Addend[00-22]:  $"
BsA32   db 0dh,0ah, "Augend[00-22]:  $"

SumA    db 0dh,0ah, "   Sum is    : $"                             ;Sum

;Calculation Logic
Dg11    db 0
Dg12    db 0
NoAd1   db 0
NoAd2   db 0
SumAd   db 0

.code
main proc

mov ax,@data                    ;initialize ds
mov ds,ax

AdBs3:
    mov ah,09h
    lea dx, Spc
    int 21h

    lea dx, BsA31               ;Addend
    int 21h
    mov ah,01h
    int 21h                     ;1st Digit

    sub al,30h
    mov ch,al


    mov ah,01h
    int 21h                     ;2nd Digit

    sub al,30h
    mov cl,al
    jmp AdBs32

AdBs32:

    mov ah,09h
    lea dx, BsA32               ;Augend
    int 21h
    mov ah,01h
    int 21h                     ;1st Digit

    sub al,30h
    add al,ch                   ;4
    mov ch,al

    mov ah,01h
    int 21h                     ;2nd Digit

    sub al,30h
    add al,cl
    mov cl,al

    ;Addition
    mov ah,09h
    lea dx, SumA
    int 21h

    mov ah,0000h
    mov bl,03h
    mov al,ch
    div bl                      ;1 r1
    mov ch,ah                   ;0102
    mov bh,al                   ;0103

    mov ah,0000h
    mov al,cl                   ;4
    add al,bh                   ;4 + 1 = 5
    div bl                      ;1 r2
    mov bx,ax                   ;0201 > r = 02 q = 01

    mov ah,02h
    add bx,3030h
    mov dl,bl
    int 21h
    mov dl,bh
    int 21h

    add ch,30h
    cmp ch,30h
    jz  AdBs3

    mov dl,ch
    int 21h

    mov ah,4Ch                      ;end here
    int 21h
AdDg3:
    sub bh,30h
    mov al,bh
    mov cl,10h
    mul cl
    mov cx,ax
    add cx,3030h
    mov ch,10h
    cmp cl,ch
    je AdDg3

    mov ah,4Ch                      ;end here
    int 21h

AdDg32:
    mov ah,02h

    mov dl,cl
    int 21h

    mov ah,4Ch                      ;end here
    int 21h

main endp
end main

Output Error:

21213.png

12 + 12 is the correct but other is not like 21 + 12 / 12 + 12...

Introduction to Serverless With AWS Lambda and Bitrise API: Part 1

In the early days of software development, anyone seeking to develop a web, mobile, or backend application had to own the hardware required to run a server, which is an expensive process.

Then, when cloud computing came, it became possible to lease server space or a number of servers remotely. The developers and companies who rent these fixed units of server space generally overbuy to ensure that a spike in traffic or activity won't exceed their monthly limits and break their applications. Because of this, a lot of the server space that gets paid for can be wasted.

Reference: Non-Printable Characters List

Non-printable characters on Linux, macOS, or Windows are characters that do not represent a symbol, character, or number that is part of the document's text, but rather are used for things like character encoding. A full list of all non-printable characters along with their decimal and hexidecimal codes are shown below.

How to Find Non-Printable Characters in a File

If you need to see all nonprintable characters in a document, you can use cat -v filename.txt in terminal to find them, where filename.txt is the file you want to show. The contents of the file, along with the non-printable characters in caret notation will be shown in your terminal window.

Require pattern or password when user attempts to shutdown device from lock

Hey guys is there a way to intercept shut down to make the user enter password if the state is in the locked state? Its just that I am engineering an anti-theft app and would to disable shut down from lock screen while the device is in the locked state. Is there a way of achieving this with Android Java. I tried listening on the shut down intent but the device does not even give the code in the OnRecieve to execute

How do i convert the Base needed to a base needed of Assembly Language

.model small
.stack 100h
.data

Spc     db 0dh,0ah, " $"                                                ;New Line

;Bases Conversion
ConT    db 0dh,0ah, "   Conversion  $"                                  ;Conversion Title
ConBs3  db 0dh,0ah, "Base 3  to Base 5  "                           
        db 0dh,0ah,0dh,0ah, "Base 3 [00 to 22] : $"                     ;Enter Base 03 Number
EqBs3       db 0dh,0ah, "Base 5 Equivalent : $"                         ;Equivalent Base 05

ConBs4  db 0dh,0ah, "Base 4  to Base 5  "                           
        db 0dh,0ah,0dh,0ah, "Base 4 [00 to 33] : $"                     ;Enter Base 04 Number
EqBs4       db 0dh,0ah, "Base 5 Equivalent : $"                         ;Equivalent Base 05

ConBs5  db 0dh,0ah, "Base 5  to Base 4  "                           
        db 0dh,0ah,0dh,0ah, "Base 5 [00 to 44] : $"                     ;Enter Base 05 Number
EqBs5       db 0dh,0ah, "Base 4 Equivalent : $"                         ;Equivalent Base 04

.code
main proc

mov ax,@data                    ;initialize ds
mov ds,ax

mov ah,09h
lea dx, Spc                 ;new line
int 21h

mov ah,4Ch                      ;end here
int 21h

main endp
end main

Android Native – How to launch Activity from an exact alarm

Introduction ##

Starting from Android 10 (API 29), Android places many restrictions on how apps can launch activities from the background.

There are a couple of exemptions, which can be found on this list. At the end of the list is the usage of the dangerous permission SYSTEM_ALERT_WINDOW. I have seen this permission recommended elsewhere, but usage of this permission is unnecessary to show an Activity for an alarm application and violates best practices for Android permission. Even the stock Clock app does not require this permission, the only install-time permission that it needs is SCHEDULE_EXACT_ALARM.

The correct way to show an Activity with an alarm is by using a notification with a full-screen Intent.

Goals

At the end of the tutorial, you would have learned:

  1. How to schedule an exact alarm.
  2. How to show an Activity on the lock screen even if the screen is off and the Activity destroyed.
Tools Required
  1. Android Studio. The version used in this tutorial is Android Studio Chipmunk 2021.2.1.
Prerequisite Knowledge
  1. Intermediate Android.
  2. Notification.
  3. BroadcastReceiver.
Project Setup

To follow along with the tutorial, perform the steps below:

  1. Create a new Android project with the default Empty Activity.

  2. Add the <string> resource below into strings.xml.

     <string name="schedule_alarm">Schedule Alarm</string>
  3. Replace the code in activity_main.xml with the code below. This replaces the default TextView with a Button.

     <?xml version="1.0" encoding="utf-8"?>
     <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <Button
            android:id="@+id/button_scheduleAlarm"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/schedule_alarm"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
     </androidx.constraintlayout.widget.ConstraintLayout>
AlarmManager Overview

Although there are many types of alarms that you can set on Android, for this tutorial, knowing that we are only working with exact alarms is enough. Android allows other types of inexact alarms, which are not relevant for this tutorial. To set an exact alarm, you can use the method setAlarmClock() from the AlarmManager class.

You can retrieve an instance of AlarmManager inside your Activity by calling getSystemService().

Project Plan

To be able to set an exact alarm and show the Activity on the lock screen when the device is sleeping, there are quite a few steps involved. The list below provides a quick summary.

  1. The application must be ready to show a notification on high priority, so we must create a NotificationChannel with IMPORTANTCE_HIGH.
  2. The AlarmManager cannot show the Activity directly, so it must go through a BroadcastReceiver, which will then displays a Notification that can show an Activity.
    AlarmManager.jpg
  3. Install-time permissions and proper attributes for the Activity must be set in the manifest.

Now that we have a rough idea of what to do next, it is time to write some code.

Create the NotificationChannel
  1. Add the constants above on top of MainActivity.kt. These are just convenient constants for the NotificationManager.

     private const val NOTIFICATION_CHANNEL_NAME = "0"
     const val NOTIFICATION_CHANNEL_ID = "1"
  2. Add the function to create the NotificationChannel to MainActivity.

     private fun createNotificationChannel(){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                NOTIFICATION_CHANNEL_ID,
                NOTIFICATION_CHANNEL_NAME,
                NotificationManager.IMPORTANCE_HIGH
            )
    
            with(getSystemService(NOTIFICATION_SERVICE) as NotificationManager){
                createNotificationChannel(channel)
            }
        }
     }
  3. Finally, call it in onCreate().

     createNotificationChannel()
Schedule an exact alarm

Next, we will have to bind the Button to schedule an exact alarm.

  1. Append the code below to onCreate() to find the Button and binds its onClickListener.

     findViewById<Button>(R.id.button_scheduleAlarm).setOnClickListener {
     }
  2. We will have to add FLAG_IMMUTABLE to all PendingIntent created in this tutorial, so add the constant below above MainActivity.kt

     val compatFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        FLAG_IMMUTABLE
     } else {
        0
     }
  3. Add the code below inside the setOnClickListener() callback. This code creates the explicit Intent as well as wrapping it in a PendingIntent, which is required later by AlarmClockInfo. Ignores the compile error because of the missing AlarmReceiver for now.

     val sendBroadcastIntent = Intent(this, AlarmReceiver::class.java)
     val pendingIntent = PendingIntent.getBroadcast(
        this,
        0,
        sendBroadcastIntent,
        compatFlags
     )
  4. Finally, retrieve the AlarmManager, and use setAlarmClock().

     with(getSystemService(Context.ALARM_SERVICE) as AlarmManager){
        //Alarm will trigger in 10 seconds
        //You should set the alarm by clicking the Button, and then clears the Activity
        // from the backstack by swiping up on the Recents screen.
        val triggerTime = Calendar.getInstance().apply {
            add(SECOND, 10)
        }
    
        val alarmInfo = AlarmManager.AlarmClockInfo(
            triggerTime.timeInMillis,
            pendingIntent //The alarm will fire this PendingIntent
        )
    
        setAlarmClock(
            alarmInfo,
            pendingIntent
        )
     }
Create the BroadcastReceiver

We will now create a BroadcastReceiver called AlarmReceiver.

Copy and paste the entire code below into your project. Here, we created and show a Notification with a full-screen Intent.

import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat

class AlarmReceiver : BroadcastReceiver() {
   override fun onReceive(context: Context?, intent: Intent?) {
       if (context != null){
           val fullScreenPendingIntent = PendingIntent.getActivity(
               context,
               0,
               Intent(context, MainActivity::class.java),
               compatFlags
           )

           val notificationBuilder = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
               .setSmallIcon(R.drawable.ic_launcher_foreground)
               .setPriority(NotificationCompat.PRIORITY_HIGH)
               .setFullScreenIntent(fullScreenPendingIntent, true)

           with(NotificationManagerCompat.from(context)) {
               //This notification only works once until the end user dismiss the previous notification.
               //Can also make the notification auto-dismiss if desired.
               notify(1, notificationBuilder.build())
           }
       }
   }
}
Tasks in the Manifest
  1. For the app to work, we will need to declare two install-time permissions, so add to the the manifest.

     <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
     <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT"/>
  2. For MainActivity, we will need to add the showWhenLocked and turnScreenOn attributes.

     android:showWhenLocked="true"
     android:turnScreenOn="true"
  3. Finally, declare the BroadcastReceiver AlarmReceiver.

     <receiver
        android:name=".AlarmReceiver"
        android:exported="false"/>
Run the App

If you ran the app previously on your device, completely uninstall it and install it again.

To test if the app is working correctly, follow the steps below:

  1. Starts the app.
  2. Press the Button to schedule an alarm.
  3. Immediately kills the app from the Recents screen.
  4. Put the device into sleep.
  5. Wait a couple of seconds. Remember that you only have ten seconds to perform steps 2-4.
  6. Wait for the app to show on the home screen. Home screen is still locked for obvious security reasons.

You can use the animation below as reference.

Alarm.gif

Solution Code

MainActivity.kt

private const val NOTIFICATION_CHANNEL_NAME = "0"
const val NOTIFICATION_CHANNEL_ID = "1"

val compatFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
   FLAG_IMMUTABLE
} else {
   0
}

class MainActivity : AppCompatActivity() {
   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)

       createNotificationChannel()

       findViewById<Button>(R.id.button_scheduleAlarm).setOnClickListener {
           val sendBroadcastIntent = Intent(this, AlarmReceiver::class.java)
           val pendingIntent = PendingIntent.getBroadcast(
               this,
               0,
               sendBroadcastIntent,
               compatFlags
           )

           with(getSystemService(Context.ALARM_SERVICE) as AlarmManager){
               //Alarm will trigger in 10 seconds
               //You should set the alarm by clicking the Button, and then clears the Activity
               // from the backstack by swiping up on the Recents screen.
               val triggerTime = Calendar.getInstance().apply {
                   add(SECOND, 10)
               }

               val alarmInfo = AlarmManager.AlarmClockInfo(
                   triggerTime.timeInMillis,
                   pendingIntent //The alarm will fire this PendingIntent
               )

               setAlarmClock(
                   alarmInfo,
                   pendingIntent
               )
           }
       }
   }

   private fun createNotificationChannel(){
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
           val channel = NotificationChannel(
               NOTIFICATION_CHANNEL_ID,
               NOTIFICATION_CHANNEL_NAME,
               NotificationManager.IMPORTANCE_HIGH
           )

           with(getSystemService(NOTIFICATION_SERVICE) as NotificationManager){
               createNotificationChannel(channel)
           }
       }
   }
}

AlarmReceiver.kt

class AlarmReceiver : BroadcastReceiver() {
   override fun onReceive(context: Context?, intent: Intent?) {
       if (context != null){
           val fullScreenPendingIntent = PendingIntent.getActivity(
               context,
               0,
               Intent(context, MainActivity::class.java),
               compatFlags
           )

           val notificationBuilder = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
               .setSmallIcon(R.drawable.ic_launcher_foreground)
               .setPriority(NotificationCompat.PRIORITY_HIGH)
               .setFullScreenIntent(fullScreenPendingIntent, true)

           with(NotificationManagerCompat.from(context)) {
               //This notification only works once until the end user dismiss the previous notification.
               //Can also make the notification auto-dismiss if desired.
               notify(1, notificationBuilder.build())
           }
       }
   }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity">

   <Button
       android:id="@+id/button_scheduleAlarm"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/schedule_alarm"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

strings.xml

<resources>
   <string name="app_name">Daniweb Android Native AlarmManager</string>
   <string name="schedule_alarm">Schedule Alarm</string>
</resources>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   package="com.example.daniwebandroidnativealarmmanager">

   <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
   <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT"/>

   <application
       android:allowBackup="true"
       android:dataExtractionRules="@xml/data_extraction_rules"
       android:fullBackupContent="@xml/backup_rules"
       android:icon="@mipmap/ic_launcher"
       android:label="@string/app_name"
       android:roundIcon="@mipmap/ic_launcher_round"
       android:supportsRtl="true"
       android:theme="@style/Theme.DaniwebAndroidNativeAlarmManager"
       tools:targetApi="31">
       <activity
           android:name=".MainActivity"
           android:showWhenLocked="true"
           android:turnScreenOn="true"
           android:exported="true">
           <intent-filter>
               <action android:name="android.intent.action.MAIN" />

               <category android:name="android.intent.category.LAUNCHER" />
           </intent-filter>
       </activity>
       <receiver
           android:name=".AlarmReceiver"
           android:exported="false"/>
   </application>

</manifest>
Summary

We have learned how to launch an Activity from an exact alarm in this tutorial. Please keep in mind that this tutorial was only tested on Android API 32. The full project code can be found at https://github.com/dmitrilc/DaniwebAndroidNativeAlarmManager.

WordPress Turns 19

Today marks 19 years since 19-year old Matt Mullenweg partnered with Mike Little to release the first version of WordPress based on the b2/cafelog software. The blog where he shared his thoughts on life and tech was starting to get more traffic and he wanted to ensure its future after the b2/cafelog’s main developer disappeared.

Mullenweg had the vision for what WordPress should be, even before it had a name. It centered on extensibility, a hallmark feature that has made the platform as popular as it is today:

What should it do? Well, it would be nice to have the flexibility of MovableType, the parsing of TextPattern, the hackability of b2, and the ease of setup of Blogger.

Matt Mullenweg – The Blogging Software Dilemma, January 24, 2003

Although Textpattern, the interesting new publishing tool at the time, had everything Mullenweg might want in a blogging tool, he wasn’t sure about its licensing at the time. He decided to fork b2/cafelog, which lives on today in a different form as WordPress, thanks to its GPL licensing. Mike Little joined the effort and the rest is history.

The highlight of this year’s anniversary celebrations is the wp19.day website created by David Bisset and his daughter Olivia Bisset, who also managed the project. WordPress users and contributors from all over the world left their heartfelt greetings to celebrate the occasion. Reading through, it’s easy to get a sense of the tremendous good WordPress has done for the world, giving so many a voice, a livelihood, and a chance to live their dreams.

The wp19.day website also featured video submissions from WordPress enthusiasts. Although many first came for the software, the common thread among those who have stayed is the value of the community that has grown up around the project and the leadership it has cultivated. WordCamp and meetup organizer Joe Simpson said WordPress empowered him to take a leadership role in his local community.

“Our community here is nurturing – it’s a family,” Simpson said. “I’m excited to see where we go from here. Happy birthday, WordPress.”

Matt Mullenweg also joined in the fun of celebrating the milestone by contributing his own greeting to the wp19.day project. In his video submission, he said it’s very rare for a 19-year-old software project and its community to not just still be surviving but actually thriving and “doing better than ever.” He thanked contributors of all kinds who have helped people find their way with WordPress.

Matt Mullenweg on WordPress’ 19th Birthday – video source: wp19.day

“That is a testament to every single person who has ever told a friend about WordPress, participated on the forums, had a translation, contributed code,” Mullenweg said. “Anything that’s been part of the WordPress ecosystem is part of why WordPress is transforming the web and making it into a place that is more open, more inclusive, more democratic, and a place that we want our future generations to grow up in.”

The 3 Conversations That Improve Developers’ Lives w/ Reprise’s Jennie MacDougall

We want to make the Dev Interrupted podcast a vital, enjoyable part of your week. Please take 2 minutes and answer our new Listener Survey. It lets us know a bit about you, what you want from Dev Interrupted and what you want from podcasts in general! 

If you’re doing your job right, most of your time and your team’s time should be spent actually building things. That means conversations should be reserved to the very important ones.

5 Tips if You’re the First SRE Hire, by Instacart’s First SRE

Site Reliability Engineers (SREs) have a considerable set of tasks to juggle no matter where they work or how long their company has had an SRE practice. But if you’re the very first SRE to join an organization – as many SREs are these days, given that the SRE trend is trickling down into smaller and smaller companies – you face a special group of challenges.

You may find it difficult to get buy-in for SRE from other technical teams. You may struggle to know how to convince your boss that the company’s decision to hire an SRE is paying off. You probably worry that you’ll end up being over-extended because you are on the only SRE at the place, and so on.

Chopping the Monolith: The Demo

In my previous blog post entitled "Chopping the Monolith," I explained my stance on microservices and why they shouldn't be your golden standard. However, I admitted that some parts of the codebase were less stable than others and had to change more frequently. I proposed "chopping" these few parts to cope with this requirement while keeping the monolith intact. As Linus Torvalds once wrote:

"Talk is cheap, show me the code!"

Gutenberg 13.3 Introduces Experimental Table of Contents Block

Gutenberg 13.3 was released this week with support for an experimental new Table of Contents block. It is perfect for longform content that is organized by multiple headings within the document. The block automatically detects Heading blocks within the content and will display them with anchor links that jump to each section.

Table of Contents block – video credit: Gutenberg 13.3 release post

Users may select the block without knowing how it works with headings. If the post or page doesn’t contain any headings, the block inserts a message prompting users to start adding Heading blocks in order to display a Table of Contents.

For sites that have registered custom taxonomies, Gutenberg’s Post Terms Block now automatically generates a block variation for each term. That means users can select a block to display all the terms associated with that custom taxonomy.

Other notable additions in 13.3 include the following:

  • Query block now supports a “parent” filter that will display content of children from the defined parent
  • Heading block now supports Font Family controls
  • Save Block List default view preference – allowes users to set a preference for having the Blost Lick view open or closed by default
  • New transforms between the Cover and Media & Text blocks

The latest release also brings dozens of enhancements and bug fixes to preferences, border controls, error messages, tooling, accessiblity, and performance. Check out the release post for the full list of changes.

Xmake and C/C++ Package Management

Xmake is a lightweight cross-platform build tool based on Lua. A previous article provides a detailed introduction to Xmake and the build system.

If you already have a general understanding of Xmake, you will know that it is not only a build tool, but also has built-in support for C/C++ package management. We can also understand Xmake as:

Oculus Highlights Improvements to Its Hand Tracking API

Oculus has announced what the company is describing as “major improvements” to the Hand Tracking API and is encouraging developers to take the enhanced implementation for a spin. Hand tracking in virtual reality has been a priority for Oculus since the introduction of this API in 2019. 

Just How Long Should Alt Text Be?

I teach a class over at the local college here in Long Beach and a majority of the content is hosted on the Canvas LMS so students can access it online. And, naturally, I want the content to be as accessible as possible, so thank goodness Canvas has a11y tooling built right into it.

But it ain’t all that rosy. It makes assumptions like all other a11y tooling and adheres to guidelines that were programmed into it. It’s not like the WCAG is baked right in and updated when it updates.

The reason this is even on my mind is that Jeremy yesterday described his love for writing image descriptions:

I enjoy writing alt text. I recently described how I updated my posting interface here on my own site to put a textarea for alt text front and centre for my notes with photos. Since then I’ve been enjoying the creative challenge of writing useful—but also evocative—alt text.

I buy into that! Writing alt text is a challenge that requires a delicate dance between the technical and the creative. It’s both an opportunity to make content more accessible and enhance the user experience.

One of those programmed guidelines in the Canvas tool is a cap of 120 characters on alt text. Why 120? I dunno, I couldn’t find any supporting guideline or rule for that exact number. One answer is that screen readers stop announcing text after 125 characters, but that’s apparently untrue, at least today. The general advice for how long alt text should be comes in varying degrees:

  • Jake Archibald talks of length in terms of emotion. Detail is great, but too much detail might distort the focal point, which makes total sense.
  • Dave sees them as short, succinct paragraphs.
  • Carrie Fisher suggests a 150-character limit not because screen readers will truncate them but more as a mental note that maybe things are getting too descriptive.
  • Daniel Göransson says in this 2017 guide that it comes down to context and knowing when certain details of an image are worth additional explanation. But he generally errs on the side of conciseness.

So, how long should alt text be? The general consensus here is that there is no hard limit, but more of a contextual awareness of what purpose the image serves and adapting to it accordingly.

Which gets me back to Jeremy’s article. He was writing alt text for a group of speaker headshots and realized the text was all starting to sound the same. He paused, thought about the experience, compared it to the experience of a sighted user, and created parity between them:

The more speakers were added to the line-up, the more I felt like I was repeating myself with the alt text. […] The experience of a sighted person looking at a page full of speakers is that after a while the images kind of blend together. So if the alt text also starts to sound a bit repetitive after a while, maybe that’s not such a bad thing. A screen reader user would be getting an equivalent experience.

I dig that. So if you’re looking for a hard and fast rule on character counts, sorry to disappoint. Like so many other things, context is king and that’s the sort of thing that can’t be codified, or even automated for that matter.

And while we’re on the topic, just noticed that Twitter has UI to display alt text:

Now if only there was more contrast between that text and the background… a11y is hard.

Just How Long Should Alt Text Be? originally published on CSS-Tricks. You should get the newsletter.

What Is Smoke Testing? – A Brief Guide

Smoke testing is a method of determining whether a newly released build is stable. It assists a QA or testing team in determining whether they may proceed with further testing. It also ensures that the builds received from development are functional.

What Is Smoke Testing?

Smoke Testing is a type of software testing typically performed on early software builds to guarantee that the program's critical capabilities are fully functional.