Friday, April 9, 2021

Azure Health Bot

Bots have been available to developers and consumers alike for many years.  They have been used in many facets of everyday life that many times we don’t even realize.  The intelligence behind these has continued to become more sophisticated and specialized for specific business sectors.  In addition, Microsoft has made the bot development experience very easy and straightforward for developers. 

 

Continuing in the path of specialization and ease of creation, Microsoft has a developed a Health Bot, with strict focus on health care.  It’s backed by a pre-trained Machine Learning model with focus on the healthcare terminology.  This empowers developers to quickly build and deploy AI-powered conversational bots.  In addition, the bot service follows industry compliance requirements and HIPAA standards.  These bots can be used in any healthcare related environment to assess a potential sickness of a patient, inquire about certain medications/supplements for a specific scenario, etc.  The bot can also be combined with the Text to Speech service to provide a more human-like interaction with users.

To get started, follow the Step by step guide to creating your first health bot.

For more information, please visit the following links:

 

Thursday, April 1, 2021

Global AI Night 2021

The Global AI Night is a an online community event organized across the world by local communities that are passionate about artificial intelligence on Microsoft Azure.  For one night, you will get to join various speakers as they share their experience with AI features in Azure.  The event is free of charge, virtual, and open to all. The event is scheduled for Tuesday, April 20th 4PM-9 PM EST and it will be virtual.

 

To learn more about this event, please visit https://globalai.community/global-ai-night-april-2021/usa-cleveland

 

If you’re interested in sharing your AI story, feel free to submit your presentation at https://sessionize.com/global-ai-night-2021-cleveland/

 

Join us for a night of AI and expand your skill set.

 

Thursday, March 25, 2021

Apr/May '21 Tech Events

Virtual User Group Meetings

 

Virtual Conferences

 

Monday, March 15, 2021

Free Microsoft Certification Courses!

 

 

 

SkillMeUp.com is hosting four free events in March and April! Each Saturday will prepare you to pass a new Microsoft fundamentals certification exam!

 

Free Live Courses

 

Microsoft Azure

March 20th │ $250 Free

 

Power Platform

April 3rd │ $250 Free

 

 

Security Compliance & Identity

April 10th │ $250 Free

 

Microsoft 365

April 17th │ $250 Free

 

 

Meet the Instructors

 

 

 

Dwayne Natwick

Cloud Training Architect Lead

Dwayne Natwick is a lifelong learner and teacher. Dwayne delivers live training, creates curriculum, writes blogs and more! He is an expert in Azure and cloud computing.

Dwayne has over 30 years of experience in the IT industry, holding multiple positions and certifications.

 

 

Brian Nielson

Senior Cloud Training Architect

Brian has 26 years of professional IT experience. He has exceptional knowledge of Microsoft Azure, Microsoft 365, and Open Source software. As a consultant he is used to solving highly visible and complex problems.

Brian is well-versed in current technological trends and familiar with a variety of business concepts. He can meet ever-changing technology needs with innovative and up-to-date solutions.

 

 

 

 

 

 

 

 

Sunday, March 7, 2021

Podcast: SQL Server For Developers

I recently had the pleasure of being featured on Azure DevOps Podcast.  The host, Jeffery Palermo, interviewed me about a topic I’m passionate about “SQL Server For Developers”.  These are features available within SQL Server that make some specific development tasks easy to implement.  Some of these features include:

File Streams: “Pointers” that allow you to store a BLOB within the SQL Server File Groups and maintain security over it, not storing it in a DB and bloating the table size.

Temporal Tables: Tables that automatically maintain historical changes to every record with a time span of those changes.

FileTables: Tables that duplicate a structure of a specific folder, giving developers the ability to quickly query the files one they’re dropped in the folder.

 

I discuss these topics and more on the podcast.  For the full podcast, please visit http://azuredevopspodcast.clear-measure.com/sam-nasr-on-sql-server-for-developers-episode-122#

Thursday, February 25, 2021

Thursday, December 17, 2020

Global AI Bootcamp 2021

The Global AI Bootcamp is a free one-day event organized across the world by local communities that are passionate about artificial intelligence on Microsoft Azure. It takes place on January 15-16th, 2021 with venues on every continent. The event is a perfect balance of quality content, awesome talks, and hands-on learning with like-minded peers in your community.  Currently, there are 4 events happening in the US in different time zones. 

 

Las Vegas, NV: https://globalai.community/global-ai-bootcamp-2020/united-states-las-vegas

Plano, TX: https://globalai.community/global-ai-bootcamp-2020/usa-plano-tx-1

Des Moines, IA: https://globalai.community/global-ai-bootcamp-2020/usa-des-moines

Raleigh, NC: https://globalai.community/global-ai-bootcamp-2020/united-states-raleigh

 

Find the one that best suits you or choose another event elsewhere in the world.  To see a full list of all events, please visit https://globalai.community/global-ai-bootcamp-2020/

For more info on the bootcamp, please visit https://globalai.community/about.

 

Monday, December 14, 2020

Wednesday, October 28, 2020

Separating Combo Boxes with Similar Data

A situation came up where a Windows Forms application required 2 combo boxes filled with customer IDs.  A caption of that form is shown below, where a user must select “From Customer ID” and “To Customer ID”.  Since both combo boxes were populated from the same data column, the natural thing to do was to use the same code for filling both with the same data.  However, this caused an undesirable effect.  When the user selected the “From Customer ID”, the “To Customer ID” was automatically populated with the same value. 

 

To resolve this problem, 2 separate DataTable objects must be used, dtFrom and dtTo.  Although both objects are populated using the same method (dm.GetCustomerIDNames()), keeping the objects separate will prevent one control selection from effecting the other control.  See sample code shown below.

 

 

 

        private void FillCustomerIDs()

        {

            Cursor.Current = Cursors.WaitCursor;  //Produces a "wait cursor" while data is loading

 

            //Must have 2 separate instances for the data method. 

            //DataTables must also be kept separate to prevent issues with binding

            //Data must NOT be cached, must be retrieved directly from the DB for each call. 

            //Otherwise all comboboxes will bind to the same datasource and to each other.

 

            DataTable dtFrom = dm.GetCustomerIDNames();

            FillFromCustomer(dtFrom);

 

            DataTable dtTo = dm.GetCustomerIDNames();

            FillToCustomer(dtTo);

        }

 

 

        private void FillFromCustomer(DataTable dtFrom)

        {

            AutoCompleteStringCollection acsFrom = new AutoCompleteStringCollection();

 

            foreach (var rec in dtFrom.AsEnumerable())

                acsFrom.Add(rec.ItemArray[0].ToString());

 

            cbFromCustomerID.AutoCompleteCustomSource = acsFrom;

            cbFromCustomerID.AutoCompleteMode = AutoCompleteMode.SuggestAppend;

            cbFromCustomerID.AutoCompleteSource = AutoCompleteSource.CustomSource;

 

            cbFromCustomerID.DataSource = dtFrom;

            cbFromCustomerID.DisplayMember = "ID";

            cbFromCustomerID.ValueMember = "Name";

            cbFromCustomerID.SelectedIndex = -1;    //Forces a blank item in the comboBox

        }

 

 

        private void FillToCustomer(DataTable dtTo)

        {

            AutoCompleteStringCollection acsTo = new AutoCompleteStringCollection();

 

            foreach (var rec in dtTo.AsEnumerable())

                acsTo.Add(rec.ItemArray[0].ToString());

 

            cbToCustomerID.AutoCompleteCustomSource = acsTo;

            cbToCustomerID.AutoCompleteMode = AutoCompleteMode.SuggestAppend;

            cbToCustomerID.AutoCompleteSource = AutoCompleteSource.CustomSource;

 

            cbToCustomerID.DataSource = dtTo;

            cbToCustomerID.DisplayMember = "ID";

            cbToCustomerID.ValueMember = "Name";

            cbToCustomerID.SelectedIndex = -1;

        }

 

 

Thursday, September 24, 2020

Sep/Oct'20 Events

Virtual User Group Meetings

Sep 29: .Net Virtual User Group - “VS/Code Hidden Gems”

https://www.meetup.com/dotnet-virtual-user-group/events/

Oct 15: Akron AITP User Group – “Enterprise Architecture in the Cloud”

https://www.meetup.com/AkronAITP/events/

Oct 21: Hudson Software Craftsmanship - “Crafting Better Software”

https://www.meetup.com/Hudson-Software-Craftsmanship-Meetup/

Oct 22: Cleveland C#/VB.Net User Group - “Multi-Model Databases in Azure SQL”

https://www.meetup.com/Cleveland-C-VB-Net-User-Group/

 

Virtual Conferences

Sep 26: Northern Virginia Code Camp

https://novacodecamp.org/index.html

Oct 3: SQL Saturday-Memphis

https://www.sqlsaturday.com/1003/

Oct 24: SQL Saturday-Oregon

https://www.sqlsaturday.com/1000/

 

Sorting and Filtering ADO Objects

Listed below is an example of using Sorting and Filtering on ADO objects.  This examples utilizes an Oracle DB, but ADO objects can be used with various databases.  In this situation, the entire data table is retrieved in memory.  When needed, that data table can be sorted using a specific column or filtered using the SELECT method with the specified predicate.

 

        public void ProcesssData()

        {

//Retrieve entire data table into memory

gPOLines = RGNdm.GetLineNumsByPO(PO);


 //Create a VIEW from the in-memory data table

var newView = gPOLines.DefaultView.ToTable(false, "PART_ID", "PO_NUMBER", "CREATE_DATE", "VENDOR_NAME", "INITIATED_BY");


//SORT by desired field

gPOLines.DefaultView.Sort = " PART_ID ASC ";

 

//SELECT (filter) for specific criteria

                DataRow[] filteredRows = gPOLines.Select($" PART_ID = '{cbPartID1.Text}' ");

 

                if (filteredRows.Count() >= 1)

                {

                    decimal userOrderQty = (decimal)filteredRows[0].Field<double>("USER_ORDER_QTY");

                }

        }

 

        public DataTable GetLineNumsByPO(string PO)

        {

            string sql = $" SELECT LINE_NO, PART_ID, USER_ORDER_QTY FROM PO_TABLE ";

            OracleDataAdapter da = new OracleDataAdapter(sql, User.connString);

            DataTable tbl = new DataTable();

            da.Fill(tbl);

            return tbl;

        }

 

Wednesday, September 23, 2020

Capturing the file name and line number of an Exception

Handling exceptions is a critical task in any application.  When an exception is logged, it needs to have sufficient detail so it can be researched at a later time.  In addition, as a developer, you want to extract and log as much detail about it as possible.  Some of those details include the file name and line number where the exception occurred.  Listed below is a method that handles exceptions, extracts the message, file name, and line number for logging.

 

 

        private void ProcessEx(Exception ex, string details = "")

        {

            int lineNumber = 0;

            const string lineNumberMarker = ":line ";

            string traceText = ex.StackTrace + "";  //Adding empty space will ensure final value is never null

 

            int lineIndex = traceText.LastIndexOf(lineNumberMarker);

            if (lineIndex >= 0)

            {

                string lineNumberText = traceText.Substring(lineIndex + lineNumberMarker.Length);

                int.TryParse(lineNumberText, out lineNumber);

            }

 

            string fileName = string.Empty;

            const string fileNameMarker = " in ";

            int fileNameIndex = traceText.LastIndexOf(fileNameMarker);

            if (fileNameIndex >= 0)

            {

                int fileNameStart = fileNameIndex + fileNameMarker.Length;

                int fileNameLength = lineIndex - fileNameIndex - fileNameMarker.Length;

                fileName = traceText.Substring(fileNameStart, fileNameLength);

            }

 

            //Log error message + file/line info

            string msg = $"Error: {ex.Message}. \r\n{details}";

            string fileInfo = $"\r\nFile {fileName}, Line {lineNumber} ";

            Logging lg = new Logging();

            lg.WriteLog(msg + fileInfo);           

        }