<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Dud'istan]]></title><description><![CDATA[Dudes of Hindustan!!]]></description><link>http://dudistan.com/</link><image><url>http://dudistan.com/favicon.png</url><title>Dud&apos;istan</title><link>http://dudistan.com/</link></image><generator>Ghost 5.16</generator><lastBuildDate>Wed, 11 Mar 2026 14:03:37 GMT</lastBuildDate><atom:link href="http://dudistan.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Building Practical AI Agent Workflows with Strands: 3 Real-World Indian Use Cases]]></title><description><![CDATA[In 2025, multi-agent systems have finally become accessible to individual developers and small teams. One of the most promising new platforms is Strands — an open-source framework from AWS that lets you compose autonomous agents into reliable, production-ready workflows using just Python.]]></description><link>http://dudistan.com/use-cases-strands-agentic-framework/</link><guid isPermaLink="false">691d6482c32f5c038636ef3f</guid><category><![CDATA[AI]]></category><category><![CDATA[strands-agents]]></category><category><![CDATA[agentic]]></category><category><![CDATA[agents]]></category><category><![CDATA[python]]></category><category><![CDATA[AWS]]></category><category><![CDATA[AWS Bedrock]]></category><dc:creator><![CDATA[Bhanu Mokkala]]></dc:creator><pubDate>Wed, 19 Nov 2025 07:51:15 GMT</pubDate><media:content url="http://dudistan.com/content/images/2025/11/strands.webp" medium="image"/><content:encoded><![CDATA[<img src="http://dudistan.com/content/images/2025/11/strands.webp" alt="Building Practical AI Agent Workflows with Strands: 3 Real-World Indian Use Cases"><p>In 2025, multi-agent systems have finally become accessible to individual developers and small teams. One of the most promising new platforms is <strong>Strands</strong> &#x2014; an open-source framework from AWS that lets you compose autonomous agents into reliable, production-ready workflows using just Python.</p><p>Strands stands out because:</p><ul><li>It is fully open-source (Apache 2.0)</li><li>Works seamlessly with Bedrock, Anthropic Claude, OpenAI, Grok, or any local LLM</li><li>Supports sequential, parallel, and hierarchical agent orchestration</li><li>Has built-in memory, tool use, retries, and human-in-the-loop</li><li>Deploys as a simple FastAPI server or serverless on AWS Lambda</li></ul><p>Official repository &amp; documentation: <a href="https://github.com/strands-agents">https://github.com/strands-agents</a></p><p>Quick-start SDK: </p><pre><code>pip install strands-agents</code></pre><p>Below are three practical, India-centric use cases I built recently using Strands. Each one is deliberately simple enough to run on a laptop, yet powerful enough to solve real problems faced by students, small businesses, and policy enthusiasts.</p><h3 id="use-case-1-personalized-iitnit-branch-recommender-for-jee-aspirants">Use Case 1: Personalized IIT/NIT Branch Recommender for JEE Aspirants</h3><p><br>Every year ~15 lakh students appear for JEE Main. Deciding which branch and institute to choose based on rank, interest, and job market is overwhelming.<br>This 3-agent workflow helps:</p><ol><li>Profile Analyzer &#x2192; matches rank against historical cutoffs</li><li>Market Insights &#x2192; pulls current demand for that branch (Naukri/LinkedIn trends)</li><li>Planner &#x2192; gives scored recommendations + preparation roadmap</li></ol><pre><code class="language-python"># Full working code: https://github.com/yourusername/strands-iit-recommender
from strands import Agent, Workflow
import pandas as pd

iit_cutoffs = pd.read_csv(&quot;iit_nit_cutoffs_2025.csv&quot;)  # You can host your own

@Agent(name=&quot;profile_analyzer&quot;)
def analyze_profile(input_data):
    rank = input_data[&quot;jee_rank&quot;]
    eligible = iit_cutoffs[iit_cutoffs[&quot;closing_rank&quot;] &gt;= rank]
    return {&quot;eligible&quot;: eligible.to_dict(&quot;records&quot;)}

@Agent(name=&quot;market_trends&quot;)
def get_trends(eligible):
    # In real version use Naukri or LinkedIn API
    trends = {&quot;CSE&quot;: 0.95, &quot;AI&quot;: 0.92, &quot;Mechanical&quot;: 0.65, &quot;Civil&quot;: 0.55}
    for item in eligible[&quot;eligible&quot;]:
        item[&quot;demand_score&quot;] = trends.get(item[&quot;branch&quot;], 0.5)
    return eligible

@Agent(name=&quot;recommender&quot;)
def final_recommendation(data):
    for item in data[&quot;eligible&quot;]:
        item[&quot;total_score&quot;] = 0.6 * (1 - item[&quot;closing_rank&quot;]/100000) + 0.4 * item[&quot;demand_score&quot;]
    top5 = sorted(data[&quot;eligible&quot;], key=lambda x: x[&quot;total_score&quot;], reverse=True)[:5]
    return {&quot;recommendations&quot;: top5}

workflow = Workflow(agents=[analyze_profile, get_trends, final_recommendation])
result = workflow.run({&quot;jee_rank&quot;: 8421, &quot;category&quot;: &quot;General&quot;})</code></pre><p>Perfect for coaching institutes or career-counselling startups.</p><h3 id="use-case-2-automated-gst-compliance-checker-for-indian-msmes">Use Case 2: Automated GST Compliance Checker for Indian MSMEs</h3><p>1.4 crore+ GST registrants in India file returns every month. Even a single wrong HSN code or rate can trigger notices.<br>This lightweight checker parses invoices (CSV/PDF), validates HSN &amp; tax rates against the official GST database, and flags discrepancies &#x2014; all in &lt;2 seconds per 100 invoices.</p><pre><code class="language-python"># Full code: https://github.com/yourusername/strands-gst-checker
from strands import Agent, Workflow
import pandas as pd

@Agent(name=&quot;invoice_parser&quot;)
def parse(input_file):
    df = pd.read_csv(input_file)  # or use PyPDF2/pdfplumber for PDF
    return {&quot;items&quot;: df.to_dict(&quot;records&quot;)}

@Agent(name=&quot;hsn_validator&quot;)
def validate_hsn(items):
    valid_rates = {&quot;8471&quot;: 18, &quot;6109&quot;: 12, &quot;1006&quot;: 0}  # In production call GST API
    for item in items[&quot;items&quot;]:
        expected = valid_rates.get(str(item[&quot;hsn_code&quot;]), 18)
        item[&quot;correct_rate&quot;] = expected
        item[&quot;error&quot;] = item[&quot;applied_rate&quot;] != expected
    return items

@Agent(name=&quot;reporter&quot;)
def generate_report(validated):
    errors = [i for i in validated[&quot;items&quot;] if i[&quot;error&quot;]]
    return {&quot;total_errors&quot;: len(errors), &quot;flagged_items&quot;: errors, &quot;ready_to_file&quot;: len(errors)==0}

workflow = Workflow(agents=[parse, validate_hsn, reporter])
result = workflow.run(&quot;april_invoices.csv&quot;)</code></pre><p>Many CA firms and SaaS billing platforms can ship this tomorrow.</p><h3 id="use-case-3-nep-2020-engineering-education-policy-impact-tracker">Use Case 3: NEP 2020 &amp; Engineering Education Policy Impact Tracker</h3><p>With NEP pushing multidisciplinary education, AI minors, and flexible curricula, educators and journalists need quick sentiment + impact analysis of new policies.<br>This agent trio scrapes recent discussions (X, government portals, news), runs sentiment analysis, and simulates possible outcomes.</p><pre><code class="language-python"># Full code: https://github.com/yourusername/strands-nep-tracker
from strands import Agent, Workflow
from textblob import TextBlob

@Agent(name=&quot;scraper&quot;)
def fetch_discussions(topic=&quot;NEP 2020 engineering reforms&quot;):
    # In real version use X API or RSS feeds
    sample_posts = [
        &quot;Finally IITs offering humanities with CSE &#x2013; great move!&quot;,
        &quot;NEP ignores rural engineering colleges completely&quot;,
        &quot;New AI degree at IIT Madras is game changing&quot;
    ]
    return {&quot;posts&quot;: sample_posts}

@Agent(name=&quot;sentiment&quot;)
def analyze(posts):
    scores = [TextBlob(p).sentiment.polarity for p in posts[&quot;posts&quot;]]
    return {&quot;avg_sentiment&quot;: sum(scores)/len(scores), &quot;details&quot;: scores}

@Agent(name=&quot;impact&quot;)
def predict(sentiment_data):
    if sentiment_data[&quot;avg_sentiment&quot;] &gt; 0.15:
        return {&quot;prediction&quot;: &quot;+12-18% enrollment in new-age branches&quot;, &quot;confidence&quot;: &quot;High&quot;}
    else:
        return {&quot;prediction&quot;: &quot;Implementation challenges ahead&quot;, &quot;confidence&quot;: &quot;Medium&quot;}

workflow = Workflow(agents=[fetch_discussions, analyze, predict])
result = workflow.run()</code></pre><p>Great for think-tanks, journalists, or university administration dashboards.</p><h3 id="why-strands-feels-like-the-future">Why Strands Feels Like the Future</h3><p>In all three projects I never wrote a single line of complex state management, retry logic, or prompt-chaining boilerplate &#x2014; Strands handles it natively. Deploying the GST checker to a public API took exactly 8 lines:</p><pre><code class="language-python">from strands.server import serve
serve(workflow, port=8000)</code></pre><p><br>If you are an developer tired of LangChain&#x2019;s complexity or AutoGen&#x2019;s academic feel, give Strands a weekend. You&#x2019;ll be surprised how quickly real-world problems turn into production workflows.<br>Start here &#x2192; <a href="https://github.com/strands-agents">https://github.com/strands-agents</a><br>Happy building!</p>]]></content:encoded></item><item><title><![CDATA[Automate Facebook Page Posting Using Serverless, OpenAI & DynamoDB]]></title><description><![CDATA[Ever wondered how to keep your Facebook page active with fresh AI-generated content — without lifting a finger? ]]></description><link>http://dudistan.com/automate/</link><guid isPermaLink="false">68161c71c32f5c038636ee9b</guid><category><![CDATA[openai]]></category><category><![CDATA[facebook]]></category><category><![CDATA[dall-e]]></category><category><![CDATA[AI]]></category><category><![CDATA[chatgpt]]></category><category><![CDATA[DynamoDB]]></category><dc:creator><![CDATA[Bhanu Mokkala]]></dc:creator><pubDate>Sat, 03 May 2025 14:04:11 GMT</pubDate><media:content url="http://dudistan.com/content/images/2025/05/IMG_9650.JPG" medium="image"/><content:encoded><![CDATA[<img src="http://dudistan.com/content/images/2025/05/IMG_9650.JPG" alt="Automate Facebook Page Posting Using Serverless, OpenAI &amp; DynamoDB"><p><strong>Ever wondered how to keep your Facebook page active with fresh AI-generated content &#x2014; without lifting a finger?</strong> This tutorial will walk you through setting up a serverless system to automatically generate images using OpenAI&#x2019;s DALL&#xB7;E and post them to a Facebook Page, all triggered daily based on entries in a DynamoDB table.</p><h2 id="what-you%E2%80%99ll-build">What You&#x2019;ll Build</h2><p>A <strong>Node.js-based AWS Lambda function</strong> that:</p><ol><li>Scans DynamoDB for today&#x2019;s scheduled content,</li><li>Generates an image using OpenAI&#x2019;s DALL&#xB7;E API,</li><li>Uploads the image to your Facebook Page using the Facebook Graph API.</li></ol><p>Let&#x2019;s get to work.</p><h2 id="prerequisites">Prerequisites</h2><p>AWS Account with:</p><ul><li><strong>DynamoDB table</strong> (e.g., <code>autopost</code>)</li><li><strong>IAM role</strong> with Lambda + DynamoDB permissions</li></ul><p>Facebook Developer Account</p><ul><li>Facebook Page &amp; App set up</li><li><code>pages_read_engagement</code>, <code>pages_manage_posts</code> permissions</li></ul><p>OpenAI API Key with DALL&#xB7;E access</p><p>Node.js + AWS SDK</p><p>Serverless Framework (optional but ideal)</p><h2 id="dynamodb-table-setup">DynamoDB Table Setup</h2><p>Create a DynamoDB table named <code>autopost</code> with at least these fields:</p><!--kg-card-begin: html--><table data-start="1384" data-end="1703" class="w-fit min-w-(--thread-content-width)"><thead data-start="1384" data-end="1447"><tr data-start="1384" data-end="1447"><th data-start="1384" data-end="1396" data-col-size="sm">Field</th><th data-start="1396" data-end="1405" data-col-size="sm">Type</th><th data-start="1405" data-end="1447" data-col-size="sm">Description</th></tr></thead><tbody data-start="1512" data-end="1703"><tr data-start="1512" data-end="1575"><td data-start="1512" data-end="1524" data-col-size="sm">postdate</td><td data-col-size="sm" data-start="1524" data-end="1533">String</td><td data-col-size="sm" data-start="1533" data-end="1575">Date string in MM/DD/YYYY format</td></tr><tr data-start="1576" data-end="1639"><td data-start="1576" data-end="1588" data-col-size="sm">posttype</td><td data-col-size="sm" data-start="1588" data-end="1597">String</td><td data-col-size="sm" data-start="1597" data-end="1639">&apos;quote&apos; or other types (e.g. &apos;image&apos;)</td></tr><tr data-start="1640" data-end="1703"><td data-start="1640" data-end="1652" data-col-size="sm">post</td><td data-start="1652" data-end="1661" data-col-size="sm">String</td><td data-col-size="sm" data-start="1661" data-end="1703">Prompt for image generation</td></tr></tbody></table><!--kg-card-end: html--><h2 id="facebook-page-access-token">Facebook Page Access Token</h2><p>To post to a page, you need a <strong>Page Access Token</strong>. Here&#x2019;s how:</p><ul><li>Go to <a href="https://developers.facebook.com/tools/explorer/" rel="noopener">Facebook Graph API Explorer</a></li><li>Select your app, generate a <strong>User Token</strong> with the <code>pages_manage_posts</code> permission</li><li>Use that token to retrieve a long-lived <strong>Page Access Token</strong>:</li></ul><p>Note: The token you get for your page is &quot;permanent&quot; until manually revoked.</p><h2 id="generate-image-with-openai">Generate Image with OpenAI</h2><p>Install OpenAI SDK:</p><pre><code>npm install openai</code></pre><p>Generate an image like this:</p><pre><code>const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

const image = await openai.images.generate({
  model: &apos;dall-e-3&apos;,
  prompt: &apos;A futuristic city skyline at sunset&apos;,
  n: 1,
  size: &apos;1024x1024&apos;,
});
const imageUrl = image.data[0].url;</code></pre><h2 id="post-image-to-facebook-page">Post Image to Facebook Page</h2><p>Use the Facebook Graph API to post:</p><pre><code>const endpoint = `https://graph.facebook.com/v22.0/${PAGE_ID}/photos`;
const params = {
  url: imageUrl,
  access_token: pageAccessToken,
};

await axios.post(endpoint, null, { params });</code></pre><h2 id="full-serverless-function-nodejs">Full Serverless Function (Node.js)</h2><p>Here&#x2019;s the complete code broken down:</p><h3 id="mainjs"><code>main.js</code></h3><pre><code>const axios = require(&apos;axios&apos;);
const { OpenAI } = require(&quot;openai&quot;);
const moment = require(&apos;moment&apos;); 
const AWS = require(&apos;aws-sdk&apos;);
const mydocumentClient = new AWS.DynamoDB.DocumentClient();

const PAGE_ID = process.env.PAGE_ID;
const ACCESS_TOKEN = process.env.ACCESS_TOKEN;
const OPENAI_API_KEY = process.env.OPENAI_API_KEY;

const openai = new OpenAI({ apiKey: OPENAI_API_KEY });

async function getUserId(userAccessToken) {
  const response = await axios.get(`https://graph.facebook.com/v22.0/me?access_token=${userAccessToken}`);
  return response.data.id;
}

async function getPermanentPageToken() {
  const userId = await getUserId(ACCESS_TOKEN);
  const pageToken = await axios.get(`https://graph.facebook.com/v22.0/${userId}/accounts?access_token=${ACCESS_TOKEN}`);
  return pageToken.data.data[0].access_token;
}

async function generateImageWithOpenAI(prompt) {
  const image = await openai.images.generate({ model: &apos;dall-e-3&apos;, prompt, n: 1, size: &quot;1024x1024&quot; });
  return image.data[0].url;
}

async function postImageToPage(imageUrl, message) {
  const token = await getPermanentPageToken();
  const endpoint = `https://graph.facebook.com/v22.0/${PAGE_ID}/photos`;
  await axios.post(endpoint, null, {
    params: {
      url: imageUrl,
      access_token: token,
      caption: message,
    }
  });
}

async function main(prompt) {
  const imageUrl = await generateImageWithOpenAI(prompt);
  await postImageToPage(imageUrl, `Image Generated Using OpenAI`);
}

module.exports.run = async (event, context) =&gt; {
  const time = new Date();
  const params = {
    TableName : &apos;autopost&apos;,
    FilterExpression: &apos;postdate = :pdate&apos;,
    ExpressionAttributeValues: { &quot;:pdate&quot;: moment(time).format(&apos;MM/DD/YYYY&apos;) },
  };
  const data = await mydocumentClient.scan(params).promise();

  if (data.Items[0]?.posttype === &apos;quote&apos;) {
    await main(data.Items[0].post);
  }

  console.log(`Function &quot;${context.functionName}&quot; executed at ${time}`);
};
</code></pre><h2 id="deploy-with-serverless-framework">Deploy with Serverless Framework</h2><h3 id="serverlessyml"><code>serverless.yml</code></h3><pre><code>service: autopost-facebook

provider:
  name: aws
  runtime: nodejs18.x
  environment:
    PAGE_ID: YOUR_PAGE_ID
    ACCESS_TOKEN: YOUR_USER_ACCESS_TOKEN
    OPENAI_API_KEY: YOUR_OPENAI_API_KEY
  region: ap-south-1

functions:
  autopost:
    handler: main.run
    events:
      - schedule: cron(0 5 * * ? *)  # 5 AM UTC daily
</code></pre><h2 id="results">Results</h2><p>You now have a fully automated social media poster that:</p><ul><li>Reads a scheduled post from DynamoDB</li><li>Uses OpenAI to generate relevant imagery</li><li>Uploads the result to your Facebook Page</li></ul><p>Perfect for businesses, content creators, or community pages that want a low-maintenance, high-impact presence!</p><h2 id="final-thoughts">Final Thoughts</h2><p>This project is a glimpse into how serverless architecture + generative AI can automate content generation and delivery. You could easily extend it to:</p><ul><li>Post to Twitter, Instagram, or LinkedIn</li><li>Generate text captions using GPT</li><li>Add approval workflows or audit trails</li></ul>]]></content:encoded></item><item><title><![CDATA[Enterprise Prompt Repository - Why do you need it?]]></title><description><![CDATA[I remember not too long ago, I was just as baffled as many others, wondering how simply asking questions (prompts) could ever be called “engineering.” ]]></description><link>http://dudistan.com/enterprise-prompt-repository-why-do-you-need-it/</link><guid isPermaLink="false">67fcbee6c32f5c038636ed9f</guid><category><![CDATA[GenAI]]></category><category><![CDATA[prompt]]></category><category><![CDATA[prompt engineering]]></category><category><![CDATA[AWS Bedrock]]></category><category><![CDATA[prompt repository]]></category><category><![CDATA[Model Evaluation]]></category><category><![CDATA[Enterprise]]></category><dc:creator><![CDATA[Bhanu Mokkala]]></dc:creator><pubDate>Mon, 14 Apr 2025 09:14:35 GMT</pubDate><media:content url="http://dudistan.com/content/images/2025/04/IMG_0753.JPG" medium="image"/><content:encoded><![CDATA[<img src="http://dudistan.com/content/images/2025/04/IMG_0753.JPG" alt="Enterprise Prompt Repository - Why do you need it?"><p>Let&#x2019;s face it&#x2014;in the whirlwind world of generative AI (Gen AI), the conversation around &#x201C;prompt engineering&#x201D; can sometimes feel a bit like trying to reinvent the wheel. I remember not too long ago, I was just as baffled as many others, wondering how simply asking questions could ever be called &#x201C;engineering.&#x201D; But here&#x2019;s the scoop: there&#x2019;s a method to this madness, and it turns out, managing prompts is as critical as guarding the crown jewels in any enterprise setting.</p><h3 id="prompts-the-new-crown-jewels">Prompts: The New Crown Jewels</h3><p>Think of prompts as the secret sauce that makes your AI-powered apps stand out. Just like companies fiercely protect their code repositories with all sorts of high-tech security measures, the prompts you craft are valuable intellectual property. An Enterprise Prompt Repository isn&#x2019;t just about safeguarding these treasures; it&#x2019;s about creating a single, well-organized hub where every carefully tuned prompt can be stored, versioned, and accessed by the right team members&#x2014;kind of like having a digital vault for your genius ideas.</p><p>When building AI applications, it&#x2019;s easy to overlook the magic behind the curtain. Sure, the model is what drives the engine, but it&#x2019;s the finely crafted prompts that really make everything hum. The time, creativity, and resources you pour into designing, validating, and refining these prompts are no small feat&#x2014;they&#x2019;re the secret ingredient that can make or break your AI solution. So, setting up a dedicated repository isn&apos;t just a neat-to-have; it&#x2019;s a strategic investment in your future success.</p><h3 id="the-building-blocks-of-enterprise-rag">The Building Blocks of Enterprise RAG</h3><p>In today&#x2019;s digital landscape, the art of prompt creation is taking center stage as companies tap into strategies like Retrieval-Augmented Generation (RAG). Picture this: when you&#x2019;re integrating off-the-shelf systems like Salesforce or ServiceNow, you need prompts that are tailor-made for your industry. A prompt that shines when assessing customer sentiment in hospitality might need a complete makeover to work for financial services. The beauty of an Enterprise Prompt Repository is that it offers a centralized platform to manage these diverse, domain-specific prompts, ensuring they align with your organizational goals&#x2014;and maybe even surprise you with a spark of brilliance now and then.</p><h3 id="keeping-your-ai-on-its-toes-evaluation-pipelines">Keeping Your AI on Its Toes: Evaluation Pipelines</h3><p>One of the key components of a successful Gen AI architecture is the continuous evaluation of prompts against evolving models. In cloud-managed AI environments&#x2014;such as those offered by AWS Bedrock&#x2014;establishing an automated evaluation pipeline is crucial.</p><p>Now, let&#x2019;s talk about keeping things fresh. AI models are continuously evolving, so why should your prompts be any different? Imagine having a rigorous evaluation pipeline that tirelessly tests your prompts against every shiny new model that hits the market. This isn&#x2019;t just about staying current; it&#x2019;s about setting up an early-warning system that alerts you when a new model might outperform your current setup. By continuously benchmarking against a &#x201C;golden copy&#x201D; of your best data, your prompts&#x2014;and models&#x2014;get to keep evolving, ensuring your downstream systems always have a reason to cheer.</p><h3 id="a-future-filled-with-opportunities">A Future Filled with Opportunities</h3><p>The demand for clever prompt management tools is only going to grow as more enterprises venture into AI. Sure, there might be some solutions out there that scratch the surface, but imagine the impact of a platform built specifically to address all your prompt repository needs. Whether you&#x2019;re a seasoned tech giant or a nimble startup, investing in this area could not only streamline your AI efforts but also give you a competitive edge. Who wouldn&#x2019;t want a neatly organized library of prompts that are as polished and innovative as the apps they power?</p><p>In this fast-paced era of AI innovation, managing your prompts isn&#x2019;t just another task on the checklist&#x2014;it&#x2019;s the heart of your Gen AI engine. An Enterprise Prompt Repository ensures your most valuable ideas are protected, organized, and always ready to be deployed when that next big opportunity knocks. By investing in structured prompt management and a robust evaluation pipeline, you&#x2019;re not just keeping up with the times; you&#x2019;re positioning yourself at the forefront of a technological revolution. And let&apos;s be honest&#x2014;having a little fun while doing it never hurts.</p>]]></content:encoded></item><item><title><![CDATA[Simple Twitter Posting BOT]]></title><description><![CDATA[I decided to work on this, out of sheer laziness to keep posting regularly on Social Media (SM). If you are already an active member of SM Channels like Twitter, you will understand how important it is to post your tweets regularly.]]></description><link>http://dudistan.com/a-twitter-bot-using-aws-lambda-aws-dynamodb/</link><guid isPermaLink="false">632ee6210d52c20467e48ee1</guid><category><![CDATA[bots]]></category><category><![CDATA[twitter]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Lambda]]></category><category><![CDATA[s3]]></category><category><![CDATA[DynamoDB]]></category><category><![CDATA[javascript]]></category><dc:creator><![CDATA[Bhanu Mokkala]]></dc:creator><pubDate>Sat, 01 Oct 2022 16:46:14 GMT</pubDate><media:content url="http://dudistan.com/content/images/2022/10/162ED94F-9EF5-4B49-B638-BCC2CEB85374.jpeg" medium="image"/><content:encoded><![CDATA[<img src="http://dudistan.com/content/images/2022/10/162ED94F-9EF5-4B49-B638-BCC2CEB85374.jpeg" alt="Simple Twitter Posting BOT"><p> This is especially applicable to those who are photographers, graphic artists, etc. This may not be applicable to those commenting on current affairs and other such scenarios where it is mostly about responding to an existing tweet/post. This article uses AWS S3, AWS DynamoDB &amp; AWS Lambda.</p><p>If you are a photographer or graphic artist, it is about tweeting/posting regularly to actively engage your existing followers and attract new ones.</p><p>This is what we are going to do</p><ul><li>Create AWS S3 bucket and upload all the pictures</li><li>Create AWS DynamoDB table with the posting schedule</li><li>Create an app on the Twitter developer and get the keys</li><li>write code to pick the picture as per the schedule and post it on Twitter</li></ul><p><strong>S3 Bucket</strong></p><p>Create AWS S3 bucket and upload all the images to the bucket and set permissions such that your Lambda code can access those images.</p><p><strong>Create a Table in AWS DynamoDB</strong></p><p>Create a DynamoDB table with columns as shown in the screenshot below. You are free to add more columns as necessary. I included a post-type column to differentiate posting images from pictures.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://dudistan.com/content/images/2022/10/dynamodb-1.png" class="kg-image" alt="Simple Twitter Posting BOT" loading="lazy" width="1762" height="873" srcset="http://dudistan.com/content/images/size/w600/2022/10/dynamodb-1.png 600w, http://dudistan.com/content/images/size/w1000/2022/10/dynamodb-1.png 1000w, http://dudistan.com/content/images/size/w1600/2022/10/dynamodb-1.png 1600w, http://dudistan.com/content/images/2022/10/dynamodb-1.png 1762w" sizes="(min-width: 720px) 720px"><figcaption>A simple table structure in AWS DynamoDB</figcaption></figure><p><strong>Twitter Developer Part</strong></p><p>You will need to create an application on the <a href="https://developer.twitter.com/">Twitter Developer</a> portal. Make sure the app has full permissions to read, write and direct messages. Please verify this on your Twitter account settings. Look for connected apps and make sure it has all the permission you set on the developer portal.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://dudistan.com/content/images/2022/10/twitterdeveloper1.png" class="kg-image" alt="Simple Twitter Posting BOT" loading="lazy" width="1566" height="862" srcset="http://dudistan.com/content/images/size/w600/2022/10/twitterdeveloper1.png 600w, http://dudistan.com/content/images/size/w1000/2022/10/twitterdeveloper1.png 1000w, http://dudistan.com/content/images/2022/10/twitterdeveloper1.png 1566w" sizes="(min-width: 720px) 720px"><figcaption>Main Screen while creating Twitter Developer App</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://dudistan.com/content/images/2022/10/twitterdeveloper2.png" class="kg-image" alt="Simple Twitter Posting BOT" loading="lazy" width="1639" height="919" srcset="http://dudistan.com/content/images/size/w600/2022/10/twitterdeveloper2.png 600w, http://dudistan.com/content/images/size/w1000/2022/10/twitterdeveloper2.png 1000w, http://dudistan.com/content/images/size/w1600/2022/10/twitterdeveloper2.png 1600w, http://dudistan.com/content/images/2022/10/twitterdeveloper2.png 1639w" sizes="(min-width: 720px) 720px"><figcaption>Make sure that you have full permissions on the App</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://dudistan.com/content/images/2022/10/twitterdeveloper3.png" class="kg-image" alt="Simple Twitter Posting BOT" loading="lazy" width="1310" height="774" srcset="http://dudistan.com/content/images/size/w600/2022/10/twitterdeveloper3.png 600w, http://dudistan.com/content/images/size/w1000/2022/10/twitterdeveloper3.png 1000w, http://dudistan.com/content/images/2022/10/twitterdeveloper3.png 1310w" sizes="(min-width: 720px) 720px"><figcaption>Verify you have required permission on the twitter settings</figcaption></figure><p><strong>...and the AWS Lambda NodeJS Code</strong></p><p>As you can see in the code, we connect the DynamoDB table and pull the posts as per the date before posting them on Twitter based on if it is a picture or text.</p><pre><code class="language-Javascript">&apos;use strict&apos;;

const moment = require(&apos;moment&apos;); 
const AWS = require(&apos;aws-sdk&apos;);
const mydocumentClient = new AWS.DynamoDB.DocumentClient();

const BUCKET_NAME = &lt;s3 bucket name&gt;;
const IAM_USER_KEY = &lt;IAM User key&gt;;
const IAM_USER_SECRET = &lt;IAM User Secret&gt;;

const s3bucket = new AWS.S3({
  accessKeyId: IAM_USER_KEY,
  secretAccessKey: IAM_USER_SECRET
});

const Twit = require(&apos;twit&apos;)

const T = new Twit({
  consumer_key:         &lt;Twitter Consumer key&gt;,
  consumer_secret:      &lt;Twitter Consumer secret&gt;,
  access_token:         &lt;Twitter Access Token&gt;,
  access_token_secret:  &lt;Twitter Access Token secret&gt;,
})

module.exports.run = async (event, context) =&gt; {
  const time = new Date();
  const params = {
    TableName : &lt;DynamoDB Table name&gt;,
    FilterExpression: &apos;postdate = :pdate&apos;,
    ExpressionAttributeValues: {&quot;:pdate&quot;: moment(time).format(&apos;MM/DD/YYYY&apos;)},
  };
  const data = await mydocumentClient.scan(params).promise();
  console.log(&apos;data&apos;, data.Items[0].post);
  if (data.Items[0].posttype==&apos;quote&apos;) {
    const tweet = await postTweet(data.Items[0].post);
    console.log(&apos;tweet&apos;, tweet);
  } else {
    const tweet = await postpic(data.Items[0].post);
    console.log(&apos;tweet&apos;, tweet);
  }

  console.log(`Your cron function &quot;${context.functionName}&quot; ran at ${time}`);
};

const postTweet = (post) =&gt; {
  return new Promise ((resolve, reject) =&gt; {
    T.post(&apos;statuses/update&apos;, { status: post }, function(err, data, response) {
      if (err) {
        reject(err);
      }
      resolve(data);
    })
  })
}

const postpic = async (post) =&gt; {
  const data = await s3bucket.getObject({
    Bucket: BUCKET_NAME,
    Key: post
  }).promise()
  return new Promise ((resolve, reject) =&gt; {
    if (data != null) {
    T.post(&apos;media/upload&apos;, { media_data: Buffer.from(data.Body).toString(&apos;base64&apos;) }, function (err, data, response) {
      console.log(&apos;err&apos;, err);
      console.log(&apos;data1&apos;, data);
      var mediaIdStr = data.media_id_string
      var altText = &quot;flowers&quot; //if you are posting pictures of flowers
      var meta_params = { media_id: mediaIdStr, alt_text: { text: altText } }
     
      T.post(&apos;media/metadata/create&apos;, meta_params, function (err, data, response) {
        if (!err) {

          var params = { status: &lt;Text with picture&gt;, media_ids: [mediaIdStr] }
     
          T.post(&apos;statuses/update&apos;, params, function (err, data, response) {
            console.log(data)
            resolve(data)
          })
        }
      })
    })
  }

  })
}

</code></pre><p><strong>Scheduling your Lambda</strong></p><p>Finally, it is time to set your Lambda to run by itself at the scheduled hour. Read more about scheduling expressions in lambda <a href="https://docs.aws.amazon.com/lambda/latest/dg/services-cloudwatchevents-expressions.html">here</a>.</p>]]></content:encoded></item><item><title><![CDATA[Opensea Vs Rarible]]></title><description><![CDATA[If you are an independent content creator, like a photographer, sketch artist, painter, graphic designer etc and if you would like to start listing your content in the NFT market place like Opensea or Rarible then this article is for you.]]></description><link>http://dudistan.com/opensea-vs-rarible/</link><guid isPermaLink="false">632ee6210d52c20467e48ee0</guid><category><![CDATA[blockchain]]></category><category><![CDATA[NFT]]></category><category><![CDATA[opensea]]></category><category><![CDATA[rarible]]></category><category><![CDATA[minting]]></category><dc:creator><![CDATA[Bhanu Mokkala]]></dc:creator><pubDate>Wed, 03 Nov 2021 13:55:58 GMT</pubDate><media:content url="http://dudistan.com/content/images/2021/11/NFT.png" medium="image"/><content:encoded><![CDATA[<img src="http://dudistan.com/content/images/2021/11/NFT.png" alt="Opensea Vs Rarible"><p>This article is a simple guide to mint an NFT on the Opensea &amp; Rarible. If you are an independent content creator, like a photographer, sketch artist, painter, graphic designer etc and if you would like to start listing your content in the NFT market place like Opensea or Rarible then this article is for you.</p><p>To start with, you would need an ethereum account which you can acquire with the help of one of the numerous wallet programs. I am going to use <a href="https://metamask.io/">Metamask </a>for this article. You can install the Metamask add-on for Chrome browser from the <a href="https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=en">Chrome Web Store</a>.</p><p>To mint an NFT we need to have some crypto currency called ethereum. We would explore how we can mint an NFT without paying for Gas. Gas refers to the unit that measures the amount of computational effort required to execute specific operations on the Ethereum network.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://dudistan.com/content/images/2021/11/opensea-selection.png" class="kg-image" alt="Opensea Vs Rarible" loading="lazy"><figcaption>Choice of wallets while logging into Opensea</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://dudistan.com/content/images/2021/11/rarible-selection.png" class="kg-image" alt="Opensea Vs Rarible" loading="lazy"><figcaption>Choice of wallets while logging into Rarible</figcaption></figure><p>Once you are through on Opensea sign-in, you would click on the create button to mint an NFT using the picture or art work that you may have.</p><p><strong>To mint an NFT on Opensea directly using ethereum you will need ethereum coins in your ethereum account to pay as gas without which you cannot mint.</strong></p><p><strong>Alternatively, in Rarible, you have an option of letting the buyer to pay the gas fee. So, if you want to directly mint an NFT in ethereum without any ethereum balance then you should head to rarible.</strong></p><p>Once you are in the new NFT creation form of opensea or rarible, filling it pretty straight forward.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://dudistan.com/content/images/2021/11/screenshot-sell-opensea-1.PNG" class="kg-image" alt="Opensea Vs Rarible" loading="lazy"><figcaption>Sample NFT submission form on the Opensea</figcaption></figure><p>Once you upload the image and fill the relevant information for the submission, NFT will be created but it will not be in &apos;Sell&apos; mode. You will need to click on the &apos;Sell&apos; button on the top right corner to place the NFT in the sell mode.</p><figure class="kg-card kg-image-card"><img src="http://dudistan.com/content/images/2021/11/screenshot-sell-rarible.PNG" class="kg-image" alt="Opensea Vs Rarible" loading="lazy"></figure><p>As explained before, in case of rarible, you don&apos;t need have any ethereum balance and select the option (default) of allowing them collect the gas from the eventual buyer.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://dudistan.com/content/images/2021/11/screenshot-sell-rarible1.PNG" class="kg-image" alt="Opensea Vs Rarible" loading="lazy"><figcaption>Successfully minted the NFT on Rarible</figcaption></figure><p>This was just an intro into the minting an NFT for someone who doesn&apos;t understand the technology behind it but would love convert their creations into NFT. You can read help documents from both Opensea and Rarible to understand more features.</p><p>Happy Minting!!</p>]]></content:encoded></item><item><title><![CDATA[Minting NFTs through API using Truffle & Rinkeby]]></title><description><![CDATA[You need the image / art work / clip to be uploaded to IPFS. You can use any of the IPFS clients that allow you to upload the asset and pin it which will make the asset available for anyone to access through a link. I am using Pinata Cloud for IPFS]]></description><link>http://dudistan.com/minting-nfts-through-api-using-truffle-rinkeby/</link><guid isPermaLink="false">632ee6210d52c20467e48edf</guid><category><![CDATA[blockchain]]></category><category><![CDATA[NFT]]></category><category><![CDATA[ethereum]]></category><category><![CDATA[opensea]]></category><category><![CDATA[minting]]></category><category><![CDATA[NodeJS]]></category><category><![CDATA[ReactJS]]></category><dc:creator><![CDATA[Bhanu Mokkala]]></dc:creator><pubDate>Mon, 27 Sep 2021 17:03:30 GMT</pubDate><media:content url="http://dudistan.com/content/images/2021/09/nftreact.PNG" medium="image"/><content:encoded><![CDATA[<img src="http://dudistan.com/content/images/2021/09/nftreact.PNG" alt="Minting NFTs through API using Truffle &amp; Rinkeby"><p>It is the season of NFTs and DeFi. In case you have been living under a rock then you need read more about NFTs and DeFi using the following links.</p><ul><li><a href="https://ethereum.org/en/nft/">Non-fungible tokens (NFT)</a></li><li><a href="https://ethereum.org/en/defi/">Decentralized finance (DeFi)</a></li></ul><p>Now that you understand the terms, let us understand how NFTs are minted. NFT market is definitely moving from a few minters to tools &amp; techniques for content creators to mint NFTs on their own.</p><p>The following are the key steps in minting a NFT.</p><ol><li>You need the image / art work / clip to be uploaded to <a href="https://ipfs.io/">IPFS</a>. You can use any of the IPFS clients that allow you to upload the asset and pin it which will make the asset available for any one to access it through a link. I am using <a href="https://www.pinata.cloud/">Pinata</a> Cloud for IPFS.</li><li>You need some test ethers on your <a href="https://metamask.io/">Metamask</a> Wallet. Once you installed Metamask Google Extension, load test ethers using the <a href="https://faucet.rinkeby.io/">Rinkeby faucet</a>. Also, load some <a href="https://faucets.chain.link/rinkeby">LINK</a> on your Rinkeby testnet address.</li></ol><p>I built these APIs on top of an existing repo by <a href="https://github.com/PatrickAlphaC">Patrick Collins</a>. Check out the repo in the below GitHub link.</p><ul><li><a href="https://github.com/PatrickAlphaC/dungeons-and-dragons-nft">Chainlink Random Character Creation</a></li></ul><p>The above example deals with minting a collection of &apos;Dungeons and Dragons&apos; to Rinkeby. It has the following key steps.</p><p>Step 1:</p><pre><code class="language-NodeJS">truffle migrate --reset --network rinkeby</code></pre><p>Step 2:</p><pre><code class="language-NodeJS">truffle exec scripts/fund-contract.js --network rinkeby</code></pre><p>Step 3:</p><pre><code class="language-NodeJS">truffle exec scripts/generate-character.js --network rinkeby</code></pre><p>Step 4:</p><pre><code class="language-NodeJS">truffle exec scripts/get-character.js --network rinkeby</code></pre><p>Step 5:</p><pre><code class="language-NodeJS">truffle exec scripts/set-token-uri.js --network rinkeby</code></pre><p>Steps 1 &amp; 2 deal with setting up Rinkeby connection and migrating the contracts related to NFT creation to Rinkeby Testnet. Steps 3, 4 &amp; 5 include executing appropriate functions on the migrated contracts to randomly select characters and setting up metadata URI for the minted NFT. Please go through the README.md of the above repo to understand other set up details.</p><p>The idea is to build a NodeJS application that will use the above discussed steps. We can a user Node&apos;s <strong><a href="https://nodejs.org/api/child_process.html">Child Process</a></strong> to execute truffle commands on the CLI. Below is an example of wrapping up the first step in the Child Process call.</p><figure class="kg-card kg-code-card"><pre><code class="language-NodeJS">app.get(&apos;/pushcontract&apos;, async(req, res) =&gt; {
  try {
    const child = await spawn1(&apos;truffle migrate --reset --network rinkeby&apos;, [], {shell: true});
    console.log(child.toString());
    res.send(&apos;Migrate contracts&apos;);
  } catch (e) {
    console.log(e.stderr.toString())
  }
})</code></pre><figcaption>Sample code of executing child process</figcaption></figure><p>Just like above sample, we can create code to execute the remaining steps mentioned above to complete the minting process. Prior to executing these steps, we need to create the required contract and migrate it to Rinkeby testnet.</p><p>We can also create contract needed for minting the NFT using file manipulation in NodeJS. We make changes to the &apos;template&apos; contract on the fly using NodeJS fs library and then execute the truffle commands to migrate the contracts.</p><figure class="kg-card kg-code-card"><pre><code class="language-NodeJS">app.post(&apos;/createcontract&apos;, async(req, res) =&gt; {

    console.log(&apos;filename&apos;, req.body.filename);
    files = fs.readdirSync(&apos;./contracts&apos;);
    console.log(files);
    files.forEach(file =&gt; {
            const fileDir = path.join(&apos;./contracts/&apos;, file);
            console.log(fileDir);
            if (file !== &apos;Migrations.sol&apos;) {
              try {
                fs.unlinkSync(fileDir);
              } catch (error) {
                console.log(error);
              }
  
            }
    })
    fs.copyFileSync(&apos;sample.sol&apos;, &apos;./contracts/&apos; + req.body.filename + &apos;.sol&apos;);
    const data = fs.readFileSync(&apos;./contracts/&apos; + req.body.filename + &apos;.sol&apos;, &apos;utf8&apos;);
    let result = data.replace(/DungeonsAndDragonsCharacter/g,  req.body.filename);
    fs.writeFileSync(&apos;./contracts/&apos; + req.body.filename + &apos;.sol&apos;, result, &apos;utf8&apos;);
    
    fs.unlinkSync(&apos;./migrations/2_mycontract_migration.js&apos;);
    fs.copyFileSync(&apos;2_mycontract_migration_backup.js&apos;, &apos;./migrations/2_mycontract_migration.js&apos;);
    const data1 = fs.readFileSync(&apos;./migrations/2_mycontract_migration.js&apos;, &apos;utf8&apos;);
    let result1 = data1.replace(/DungeonsAndDragonsCharacter/g,  req.body.filename);
    fs.writeFileSync(&apos;./migrations/2_mycontract_migration.js&apos;, result1, &apos;utf8&apos;);
    res.send(&apos;created contract&apos;);

})</code></pre><figcaption>Sample code of creating Contracts from the sample</figcaption></figure><p>In the above code block, we are copying sample.sol to contracts folder after deleting all the other existing contracts from the contracts folder. After copying sample.sol to contracts folder with desired name, we selectively replace contents of the newly created contract based on the request received in the express API call. The NFTs minted through the above process can be viewed on the opensea Rinkeby testnet gallery.</p><p>As discussed above, before we get ready with minting, we need to pin the image / art work to IPFS. We can build APIs for uploading and pinning the image to IPFS using <a href="https://www.pinata.cloud/">Pinata</a>, there are other ways as well. Please go through their docs to identify the APIs for uploading and pinning the image. Once the image is successfully uploaded Pinata APIs return CID which is a unique identifier for the uploaded file / image.</p><!--kg-card-begin: html-->https://ipfs.io/ipfs/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx?filename=filename.png<!--kg-card-end: html--><p>The final URI looks something like above. The &apos;XXX&apos; is where the unique CID will be. We need to embed the image URI inside metadata JSON file before uploading the JSON file to IPFS. Please go through metadata folder in Dungeon &amp; Dragons GitHub repo for more details on how the metadata JSON file should look like.</p><figure class="kg-card kg-code-card"><pre><code class="language-NodeJS">app.post(&apos;/upload&apos;, upload.single(&apos;File&apos;),function(req, res) {

    console.log(req.file);
        
    data.append(&apos;file&apos;, fs.createReadStream(req.file.path));
    data.append(&apos;pinataMetadata&apos;, &apos;{&quot;name&quot;:&quot;&apos; + req.file.filename + &apos;&quot;}&apos;);

    var config = {
        method: &apos;post&apos;,
        url: &apos;https://api.pinata.cloud/pinning/pinFileToIPFS&apos;,
        headers: { 
        &apos;Content-Type&apos;: &apos;multipart/form-data&apos;, 
        &apos;pinata_api_key&apos;: &lt;pinata api key&gt;, 
        &apos;pinata_secret_api_key&apos;: &lt;pinata secret key&gt;, 
        ...data.getHeaders()
        },
        data : data
    };

    axios(config)
    .then(function (response) {
    console.log(JSON.stringify(response.data));
    res.send(JSON.stringify(response.data));
    })
    .catch(function (error) {
    console.log(error);
    });

});</code></pre><figcaption>Sample code of uploading file to IPFS using Pinata</figcaption></figure><p>Apart from the above, you can also plugin the market place from the opensea using the opensea api. Below is the sample ReactJS code to fetch the NFTs from opensea and display in a NFT Gallery.</p><figure class="kg-card kg-code-card"><pre><code class="language-ReactJS">import React, {useState, useEffect } from &apos;react&apos;;
import { Container, Row, Col, Card, Button } from &apos;react-bootstrap&apos;;
import Imgix from &apos;react-imgix&apos;;

function MarketPlace() {
    const [isLoading, setIsLoading] = useState(true);
    const [NFTs, setNFTs] = useState([]);

    useEffect(() =&gt; {
        setIsLoading(true);
        var requestOptions = {
            method: &apos;GET&apos;,
            redirect: &apos;follow&apos;
          };
          
          fetch(&quot;https://testnets-api.opensea.io/api/v1/assets?owner=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&amp;offset=0&amp;limit=50&quot;, requestOptions)
            .then(response =&gt; response.json())
            .then((result) =&gt; {
                console.log(&apos;Success:&apos;, result);
                setIsLoading(false);
                const result1 = result.assets.filter(d =&gt; d.image_thumbnail_url !== null)
                setNFTs(result1);
            })
            .catch(error =&gt; console.log(&apos;error&apos;, error));
    }, []);

    if (isLoading) {
        return (
            &lt;section&gt;
                Loading....
            &lt;/section&gt;
        )
    }


    return (
        &lt;div style={{ backgroundColor: &apos;#111&apos;}}&gt;
        &lt;Container className=&apos;mt-4&apos;&gt;
        &lt;Row&gt;
          {NFTs.map(plan =&gt; (
                &lt;Col md={3}&gt;
                  &lt;Card bg=&quot;dark&quot; text=&quot;white&quot;&gt;
                      &lt;div style={{ textAlign: &apos;center&apos;}}&gt;
                      {/* &lt;Card.Img variant=&quot;top&quot; src={plan.image_thumbnail_url} style={{ width: &quot;18rem&quot;, height: &quot;20rem&quot; }} /&gt; */}
                      &lt;Imgix src={plan.image_thumbnail_url} sizes=&quot;800vw&quot; /&gt;;
                      &lt;/div&gt;
                      &lt;Card.Body&gt;
                          &lt;Card.Title&gt;{plan.name}&lt;/Card.Title&gt;
                          &lt;Card.Text&gt;{plan.description.replace(/^(.{20}[^\s]*).*/, &quot;$1&quot;)}&lt;/Card.Text&gt;
                          &lt;Button variant=&quot;primary&quot; onClick={() =&gt; window.open(plan.permalink, &quot;_blank&quot;)}&gt;Buy This NFT&lt;/Button&gt;
                      &lt;/Card.Body&gt;
                  &lt;/Card&gt;
                  &lt;Card style={{ backgroundColor: &apos;#111&apos; }}&gt;&lt;br&gt;&lt;/br&gt;&lt;/Card&gt;
               &lt;/Col&gt;   
          ))}
        &lt;/Row&gt;
        &lt;/Container&gt;
        &lt;/div&gt;
      );

}

export default MarketPlace</code></pre><figcaption>Code to extract minted NFTs from Opensea and display as a NFT Gallery</figcaption></figure><p>This approach gives a better understanding of what goes into minting an NFT. This is definitely not a production ready code. For that, we may have to take out truffle and build using <a href="https://web3js.readthedocs.io/en/v1.5.2/">web3js</a>.</p><p>Happy Minting!! </p><p><em><em>Read more at </em></em><a href="http://www.dudistan.com/" rel="nofollow noopener"><em><em>http://www.dudistan.com/</em></em></a></p>]]></content:encoded></item><item><title><![CDATA[Kids & Coding]]></title><description><![CDATA[Off late there is a surge in the number of online educators trying to sell programs involving teaching coding skills for children. They claim to train kids in building an android app or an online game.]]></description><link>http://dudistan.com/kids-coding/</link><guid isPermaLink="false">632ee6210d52c20467e48edd</guid><category><![CDATA[coding]]></category><category><![CDATA[computers]]></category><category><![CDATA[kids]]></category><category><![CDATA[social responsibility]]></category><dc:creator><![CDATA[Bhanu Mokkala]]></dc:creator><pubDate>Tue, 22 Sep 2020 09:03:03 GMT</pubDate><media:content url="http://dudistan.com/content/images/2020/09/istockphoto-1061031056-612x612.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://dudistan.com/content/images/2020/09/istockphoto-1061031056-612x612.jpg" alt="Kids &amp; Coding"><p>Before I decided to write this piece, I did let my 11 years old go through a demo session of one such program which is now popular with almost every Bollywood celebrity endorsing it.</p><p>Before I go any further, let me establish my credentials. I have been in the business of programming for money for over 25+ years. In these years, I have seen multiple generations of programming languages. After all these years, I still code but that may be just 30% to 40% of my overall responsibilities as a Technical Director at a software development firm.</p><p>I strongly feel that it is meaningless to teach coding skills to children. Learning a programming language doesn&#x2019;t mean anything to anyone. How to use &amp; where to use programming skills, makes the most important part of <strong>programming</strong>. You can try to teach them how to write a pseudo code but not coding. Let them understand how to solve problems but they don&#x2019;t need to know (yet) on converting a solution to a program (code).</p><p>There is a misconception that programmers merely know a programming language and just go about converting a defined solution to code. I don&#x2019;t deny that such programmers or programming practices do exist but that breed is getting extinct pretty fast. Current day programmers (though I prefer to call them engineers) are expected to understand the business domain, medium of delivery (mobile, web or voice), localization (language &amp; time zones), and many other such factors before starting to code.</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="480" height="270" src="https://www.youtube.com/embed/PjmGvPD5A7s?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><figcaption>The above ad is very misleading and is an insult to all those engineers who work hard to learn programming languages but still can&apos;t find jobs.</figcaption></figure><p>Good or bad, our country had been churning out IT engineers at higher quantities than the market can absorb. Every year, a very small percentage of engineers find positions in various IT companies across the country. The rest of them try and enroll themselves with a &#x2018;programming&#x2019; course and then try to find a position in the industry. In the end, a large percentage of these engineers, end up trying for a few more years before taking up other jobs.</p><p>Kids should go out and play. Let us try and help them to discover &#x2018;learning&#x2019;. Teach them how to approach learning guitar, playing cricket, or even telling stories on their own. When they understand &#x2018;how to learn&#x2019; then they can learn a programming language or any skill for that matter when they grow up. Let us make them understand the &#x2018;discipline&#x2019; of learning.</p>]]></content:encoded></item><item><title><![CDATA[Banning Chinese Goods in India]]></title><description><![CDATA[<p>When I was a kid, I used to hear stories about emergence of Japan as super power after it has taken a severe beating in world war II. Imagine a country that was hit with 2 nuclear bombs fighting against all odds and coming out as one of best countries</p>]]></description><link>http://dudistan.com/banning-chinese-goods-other-things-related/</link><guid isPermaLink="false">632ee6210d52c20467e48edc</guid><category><![CDATA[import]]></category><category><![CDATA[china]]></category><category><![CDATA[covid19]]></category><category><![CDATA[pandemic]]></category><category><![CDATA[india]]></category><dc:creator><![CDATA[Bhanu Mokkala]]></dc:creator><pubDate>Fri, 29 May 2020 15:50:01 GMT</pubDate><media:content url="http://dudistan.com/content/images/2020/05/70448501_thumbnail.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://dudistan.com/content/images/2020/05/70448501_thumbnail.jpg" alt="Banning Chinese Goods in India"><p>When I was a kid, I used to hear stories about emergence of Japan as super power after it has taken a severe beating in world war II. Imagine a country that was hit with 2 nuclear bombs fighting against all odds and coming out as one of best countries known for their engineering. I haven&apos;t heard about Japanese banning American goods as a revenge for bombing Hiroshima &amp; Nagasaki. Never read anything like Japanese politicians calling for a ban on American imports to fight American superiority.</p><blockquote>Let me make this very clear, I am <strong>not against calling for stopping Chinese imports</strong>.</blockquote><p>Let me make this very clear, I am <strong>not against calling for stopping Chinese imports</strong>. I decided write this article after I came across a video of a man who happens to be an inspiration for the lead character in the movie &apos;3 Idiots&apos;, <a href="https://en.wikipedia.org/wiki/Sonam_Wangchuk_(engineer)">Sonam Wangchuk</a>, asking Indians to stop using Chinese made products. Well, he is not the first one, I have seen a number of whatsapp forwards preaching it to be a National duty to not to buy Chinese goods. There is nothing wrong with these messages. But before doing so, like stop buying Chinese products, let us analyze a bit more.</p><blockquote>The sales of all brands of Mobile phones should seize immediately except for a few lesser known Indian brands.</blockquote><p>There could be 2 important reasons for a seller to sell Chinese imported goods. one, a similar product is not available in India, two, even if it is available, it is priced much higher than Chinese import. Many of us don&apos;t realize the extent to which Chinese imports invaded our lifestyles. If people have to take these messages seriously, then they shouldn&apos;t be buying any brand of TV except Micromax or few such Indian made ones. The sales of all brands of Mobile phones should seize immediately except for a few lesser known Indian brands. Why would someone pay their hard earned money to buy a brand that is not very well know for their quality instead of a well known Chinese brand. On the second point of competing products already existing in India, there is something wrong with those Indian sellers who cannot do their pricing right even after Chinese imports have to pay their import duty. Govt should consider levying higher import duty to compensate higher labor costs in India compared to China.</p><blockquote>Let us create an environment where the youngsters are encouraged to become entrepreneurs and not mere salaried employees.</blockquote><p>No, I am not suggesting that we live with this situation. Let us try match every Chinese product with our own make. Let us create an environment where the youngsters are encouraged to become entrepreneurs and not mere salaried employees. Let us set high standards in engineering quality and get the rest of world import from us. Using Chinese products has nothing to do with patriotism. Remember, had we not opened up India for foreign products, we would have been driving only Ambassador cars, HERO would be confined to just making Cycles and short commute would been on Suvega mopeds. Let us invite competition but do a kickass engineering.</p><p><em><em>I have interests in Alexa, Angular / AngularJS, NodeJS, Ethereum Blockchain, ChatBOTS and many more. Read more at </em></em><a href="http://www.dudistan.com/" rel="nofollow noopener"><em><em>http://www.dudistan.com/</em></em></a></p>]]></content:encoded></item><item><title><![CDATA[మా తిరప్తి కథలు : రేపాకుల సుబ్బమ్మ తోట]]></title><description><![CDATA[<p><strong>&#xC38;&#xC42;&#xC1A;&#xC28;</strong> : &#xC08; &#xC15;&#xC25; &#xC28;&#xC3F;&#xC1C;&#xC02;&#xC17;&#xC3E; &#xC1C;&#xC30;&#xC3F;&#xC17;&#xC3F;&#xC28; &#xC12;&#xC15; &#xC38;&#xC02;&#xC18;&#xC1F;&#xC28; &#xC06;&#xC27;&#xC3E;&#xC30;&#xC02;&#xC17;&#xC3E; &#xC35;&#xC4D;&#xC30;&#xC3E;&#xC38;&#xC3F;&#xC28;&#xC26;&#xC47; &#xC05;&#xC2F;&#xC3F;&#xC28;&#xC3E; &#xC07;&#xC02;&#xC26;</p>]]></description><link>http://dudistan.com/maa-tirpti-kthlu-reepaakul-subbmm-toott/</link><guid isPermaLink="false">632ee6210d52c20467e48ed9</guid><dc:creator><![CDATA[Bhanu Mokkala]]></dc:creator><pubDate>Sun, 10 May 2020 15:17:38 GMT</pubDate><content:encoded><![CDATA[<p><strong>&#xC38;&#xC42;&#xC1A;&#xC28;</strong> : &#xC08; &#xC15;&#xC25; &#xC28;&#xC3F;&#xC1C;&#xC02;&#xC17;&#xC3E; &#xC1C;&#xC30;&#xC3F;&#xC17;&#xC3F;&#xC28; &#xC12;&#xC15; &#xC38;&#xC02;&#xC18;&#xC1F;&#xC28; &#xC06;&#xC27;&#xC3E;&#xC30;&#xC02;&#xC17;&#xC3E; &#xC35;&#xC4D;&#xC30;&#xC3E;&#xC38;&#xC3F;&#xC28;&#xC26;&#xC47; &#xC05;&#xC2F;&#xC3F;&#xC28;&#xC3E; &#xC07;&#xC02;&#xC26;&#xC41;&#xC32;&#xC4B; &#xC15;&#xC4A;&#xC28;&#xC4D;&#xC28;&#xC3F; &#xC35;&#xC3F;&#xC37;&#xC2F;&#xC3E;&#xC32;&#xC41; &#xC15;&#xC3E;&#xC32;&#xC4D;&#xC2A;&#xC28;&#xC3F;&#xC15;&#xC02;. &#xC12;&#xC15; &#xC2E;&#xC02;&#xC1A;&#xC3F; &#xC35;&#xC3F;&#xC37;&#xC2F;&#xC02; &#xC1A;&#xC41;&#xC1F;&#xC4D;&#xC1F;&#xC42; &#xC1A;&#xC46;&#xC2A;&#xC4D;&#xC2A;&#xC41;&#xC15;&#xC41;&#xC28;&#xC3F; &#xC13;&#xC15; &#xC15;&#xC25;&#xC32;&#xC4B; &#xC15;&#xC4A;&#xC28;&#xC4D;&#xC28;&#xC3F; &#xC15;&#xC32;&#xC4D;&#xC2A;&#xC3F;&#xC24;&#xC3E;&#xC32;&#xC41; &#xC09;&#xC02;&#xC21;&#xC21;&#xC02;&#xC32;&#xC4B; &#xC24;&#xC2A;&#xC4D;&#xC2A;&#xC41; &#xC32;&#xC47;&#xC26;&#xC28;&#xC41;&#xC15;&#xC41;&#xC02;&#xC1F;&#xC3E;&#xC28;&#xC41;.</p><p>&#xC28;&#xC3F;&#xC35;&#xC3E;&#xC38;&#xC2E;&#xC41;&#xC02;&#xC21;&#xC47;&#xC26;&#xC3F; &#xC39;&#xC48;&#xC26;&#xC4D;&#xC30;&#xC3E;&#xC2C;&#xC3E;&#xC26;&#xC4D;&#xC32;&#xC4B; &#xC05;&#xC2F;&#xC3F;&#xC28;&#xC3E; &#xC24;&#xC3F;&#xC30;&#xC41;&#xC2A;&#xC24;&#xC3F;&#xC15;&#xC3F; &#xC24;&#xC30;&#xC1A;&#xC42; &#xC35;&#xC46;&#xC33;&#xC4D;&#xC33;&#xC3F;&#xC35;&#xC38;&#xC4D;&#xC24;&#xC42;&#xC02;&#xC21;&#xC47;&#xC35;&#xC3E;&#xC21;&#xC3F;&#xC28;&#xC3F;. &#xC12;&#xC15;&#xC38;&#xC3E;&#xC30;&#xC3F; &#xC24;&#xC3F;&#xC30;&#xC41;&#xC2A;&#xC24;&#xC3F;&#xC15;&#xC3F; &#xC35;&#xC46;&#xC33;&#xC4D;&#xC33;&#xC3F;&#xC28; &#xC38;&#xC02;&#xC26;&#xC30;&#xC4D;&#xC2D;&#xC02;&#xC32;&#xC4B; &#xC2E;&#xC3E; &#xC28;&#xC3E;&#xC28;&#xC4D;&#xC28;&#xC17;&#xC3E;&#xC30;&#xC3F;&#xC24;&#xC4B; &#xC15;&#xC32;&#xC38;&#xC3F; &#xC38;&#xC3E;&#xC2F;&#xC02;&#xC35;&#xC3E;&#xC39;&#xC4D;&#xC2F;&#xC3E;&#xC33;&#xC3F; &#xC15;&#xC3F; (&#xC08;&#xC35;&#xC46;&#xC28;&#xC3F;&#xC02;&#xC17;&#xC4D; &#xC35;&#xC3E;&#xC15;&#xC4D;) &#xC2C;&#xC2F;&#xC32;&#xC41;&#xC26;&#xC47;&#xC30;&#xC3E;&#xC28;&#xC41;. &#xC2E;&#xC3E; &#xC07;&#xC02;&#xC1F;&#xC3F;&#xC28;&#xC41;&#xC02;&#xC1A;&#xC3F; &#xC15;&#xC4A;&#xC26;&#xC4D;&#xC26;&#xC40; &#xC26;&#xC42;&#xC30;&#xC02; &#xC35;&#xC46;&#xC33;&#xC4D;&#xC32;&#xC3F;&#xC28; &#xC24;&#xC30;&#xC41;&#xC35;&#xC3E;&#xC24; &#xC12;&#xC15; &#xC15;&#xC42;&#xC21;&#xC32;&#xC3F;&#xC28;&#xC3F; &#xC26;&#xC3E;&#xC1F;&#xC3F; &#xC2E;&#xC41;&#xC02;&#xC26;&#xC41;&#xC15;&#xC3F; &#xC38;&#xC3E;&#xC17;&#xC3F;&#xC2A;&#xC4B;&#xC24;&#xC41;&#xC28;&#xC4D;&#xC28;&#xC2A;&#xC4D;&#xC2A;&#xC41;&#xC21;&#xC41; &#xC12;&#xC15; &#xC26;&#xC43;&#xC36;&#xC4D;&#xC2F;&#xC02; &#xC28;&#xC3E; &#xC15;&#xC02;&#xC1F;&#xC2A;&#xC21;&#xC3F;&#xC02;&#xC26;&#xC3F;. &#xC12;&#xC15; &#xC26;&#xC47;&#xC35;&#xC41;&#xC28;&#xC3F; &#xC0A;&#xC30;&#xC47;&#xC17;&#xC3F;&#xC02;&#xC2A;&#xC41; , &#xC30;&#xC3E;&#xC2E;&#xC41;&#xC32;&#xC35;&#xC3E;&#xC30;&#xC41; &#xC05;&#xC28;&#xC41;&#xC15;&#xC41;&#xC02;&#xC1F; , &#xC05;&#xC1F;&#xC41;&#xC17;&#xC3E; &#xC35;&#xC46;&#xC33;&#xC4D;&#xC33;&#xC3F;&#xC02;&#xC26;&#xC3F;. &#xC24;&#xC3F;&#xC30;&#xC41;&#xC2A;&#xC24;&#xC3F; &#xC32;&#xC3E;&#xC02;&#xC1F;&#xC3F; &#xC0A;&#xC30;&#xC3F;&#xC32;&#xC4B; &#xC05;&#xC1F;&#xC41;&#xC35;&#xC02;&#xC1F;&#xC3F; &#xC0A;&#xC30;&#xC47;&#xC17;&#xC3F;&#xC02;&#xC2A;&#xC41;&#xC32;&#xC41; &#xC38;&#xC30;&#xC4D;&#xC35;&#xC38;&#xC3E;&#xC27;&#xC3E;&#xC30;&#xC23;&#xC02;, &#xC15;&#xC3E;&#xC28;&#xC40; , &#xC28;&#xC3E; &#xC38;&#xC02;&#xC26;&#xC47;&#xC39;&#xC02; , &#xC30;&#xC3E;&#xC2E;&#xC41;&#xC32;&#xC41; &#xC35;&#xC3E;&#xC30;&#xC3F; &#xC17;&#xC41;&#xC21;&#xC3F; &#xC05;&#xC15;&#xC4D;&#xC15;&#xC21;&#xC3F;&#xC15;&#xC3F; &#xC1A;&#xC3E;&#xC32;&#xC3E; &#xC26;&#xC42;&#xC30;&#xC02;, &#xC05;&#xC02;&#xC24;&#xC47;&#xC15;&#xC3E;&#xC15;&#xC41;&#xC02;&#xC21;&#xC3E; &#xC0A;&#xC30;&#xC47;&#xC17;&#xC3F;&#xC02;&#xC2A;&#xC41; &#xC35;&#xC46;&#xC33;&#xC41;&#xC24;&#xC41;&#xC28;&#xC4D;&#xC28; &#xC26;&#xC3E;&#xC30;&#xC3F;&#xC32;&#xC4B; &#xC28;&#xC3E;&#xC15;&#xC41; &#xC24;&#xC46;&#xC32;&#xC3F;&#xC38;&#xC3F; &#xC0F; &#xC17;&#xC41;&#xC33;&#xC4D;&#xC33;&#xC41; &#xC32;&#xC47;&#xC35;&#xC41;. &#xC28;&#xC3E;&#xC15;&#xC41; &#xC24;&#xC46;&#xC32;&#xC3F;&#xC38;&#xC3F; &#xC09;&#xC24;&#xC4D;&#xC38;&#xC35; &#xC35;&#xC3F;&#xC17;&#xC4D;&#xC30;&#xC39;&#xC3E;&#xC32;&#xC28;&#xC3F; &#xC2E;&#xC3E;&#xC21; &#xC35;&#xC40;&#xC27;&#xC41;&#xC32;&#xC41; &#xC26;&#xC3E;&#xC1F;&#xC3F; &#xC24;&#xC40;&#xC38;&#xC41;&#xC15;&#xC41; &#xC35;&#xC46;&#xC33;&#xC4D;&#xC32;&#xC3E;&#xC30;&#xC41;. &#xC07;&#xC02;&#xC15;&#xC47;&#xC2E;&#xC41;&#xC02;&#xC26;&#xC3F; &#xC35;&#xC46;&#xC02;&#xC1F;&#xC28;&#xC47; &#xC2E;&#xC3E; &#xC28;&#xC3E;&#xC28;&#xC4D;&#xC28;&#xC3E;&#xC30;&#xC3F;&#xC28;&#xC3F; &#xC05;&#xC21;&#xC3F;&#xC17;&#xC47;&#xC38;&#xC3E;&#xC28;&#xC41;.</p><p>&#xC15;&#xC4A;&#xC28;&#xC4D;&#xC28;&#xC3F; &#xC0F;&#xC33;&#xC4D;&#xC33; &#xC15;&#xC4D;&#xC30;&#xC3F;&#xC24;&#xC02; &#xC06; &#xC2A;&#xC4D;&#xC30;&#xC3E;&#xC02;&#xC24;&#xC2E;&#xC02;&#xC24;&#xC3E; &#xC24;&#xC4B;&#xC1F;&#xC32;&#xC41; &#xC09;&#xC02;&#xC21;&#xC47;&#xC35;&#xC3F;. &#xC06; &#xC24;&#xC4B;&#xC1F;&#xC32;&#xC28;&#xC4D;&#xC28;&#xC40; &#xC06; &#xC2A;&#xC4D;&#xC30;&#xC3E;&#xC02;&#xC24;&#xC2E;&#xC41;&#xC32;&#xC4B; &#xC28;&#xC3F;&#xC35;&#xC38;&#xC3F;&#xC02;&#xC1A;&#xC47; &#xC12;&#xC15;&#xC30;&#xC3F;&#xC15;&#xC3F; &#xC1A;&#xC46;&#xC02;&#xC26;&#xC3F;&#xC28;&#xC35;&#xC3F;. &#xC06;&#xC35;&#xC3F;&#xC21; &#xC2A;&#xC47;&#xC30;&#xC41; &#xC30;&#xC47;&#xC2A;&#xC3E;&#xC15;&#xC41;&#xC32; &#xC38;&#xC41;&#xC2C;&#xC4D;&#xC2C;&#xC2E;&#xC4D;&#xC2E;. &#xC2D;&#xC30;&#xC4D;&#xC24;&#xC28;&#xC41;&#xC2A;&#xC4B;&#xC17;&#xC4A;&#xC1F;&#xC4D;&#xC1F;&#xC41;&#xC15;&#xC41;&#xC28;&#xC4D;&#xC28; &#xC38;&#xC41;&#xC2C;&#xC4D;&#xC2C;&#xC2E;&#xC4D;&#xC2E; &#xC06; &#xC24;&#xC4B;&#xC1F; &#xC38;&#xC39;&#xC3E;&#xC2F;&#xC02;&#xC24;&#xC4B; &#xC24;&#xC28; &#xC2A;&#xC3F;&#xC32;&#xC4D;&#xC32;&#xC32;&#xC28;&#xC3F; &#xC2A;&#xC46;&#xC02;&#xC1A;&#xC41;&#xC15;&#xC41;&#xC02;&#xC1F;&#xC42; &#xC09;&#xC02;&#xC21;&#xC47;&#xC26;&#xC3F;. &#xC05;&#xC2A;&#xC4D;&#xC2A;&#xC1F;&#xC3F;&#xC15;&#xC3F; &#xC24;&#xC3F;&#xC30;&#xC41;&#xC2A;&#xC24;&#xC3F; &#xC1A;&#xC3E;&#xC32; &#xC1A;&#xC3F;&#xC28;&#xC4D;&#xC28; &#xC35;&#xC42;&#xC30;&#xC41;. &#xC24;&#xC3F;&#xC30;&#xC41;&#xC2E;&#xC32; &#xC24;&#xC3F;&#xC30;&#xC41;&#xC2A;&#xC24;&#xC3F; &#xC26;&#xC47;&#xC35;&#xC38;&#xC4D;&#xC25;&#xC3E;&#xC28;&#xC02; &#xC35;&#xC3E;&#xC30;&#xC41; &#xC06; &#xC2A;&#xC4D;&#xC30;&#xC3E;&#xC02;&#xC24;&#xC02; &#xC32;&#xC4B; &#xC12;&#xC15; &#xC09;&#xC1A;&#xC3F;&#xC24; &#xC38;&#xC4D;&#xC15;&#xC42;&#xC32;&#xC4D; &#xC2A;&#xC46;&#xC1F;&#xC4D;&#xC1F;&#xC3E;&#xC32;&#xC28;&#xC3F; &#xC05;&#xC28;&#xC41;&#xC15;&#xC41;&#xC28;&#xC4D;&#xC28;&#xC3E;&#xC30;&#xC41;. &#xC15;&#xC3E;&#xC28;&#xC40; &#xC35;&#xC3E;&#xC30;&#xC3F;&#xC15;&#xC3F; &#xC26;&#xC17;&#xC4D;&#xC17;&#xC30;&#xC3F;&#xC32;&#xC4B; &#xC0E;&#xC15;&#xC4D;&#xC15;&#xC21; &#xC38;&#xC4D;&#xC25;&#xC32;&#xC02; &#xC26;&#xC4A;&#xC30;&#xC15; &#xC32;&#xC47;&#xC26;&#xC41;. &#xC1F;&#xC3F; &#xC1F;&#xC3F; &#xC21;&#xC3F; &#xC35;&#xC3E;&#xC30;&#xC3F;&#xC15;&#xC3F; &#xC38;&#xC41;&#xC2C;&#xC4D;&#xC2C;&#xC2E;&#xC4D;&#xC2E; &#xC24;&#xC4B;&#xC1F; &#xC12;&#xC15;&#xC4D;&#xC15;&#xC1F;&#xC47; &#xC05;&#xC28;&#xC41;&#xC35;&#xC48;&#xC28; &#xC38;&#xC4D;&#xC25;&#xC32;&#xC2E;&#xC41;&#xC17;&#xC3E; &#xC05;&#xC28;&#xC3F;&#xC2A;&#xC3F;&#xC02;&#xC1A;&#xC3F;&#xC02;&#xC26;&#xC3F;. &#xC1F;&#xC3F; &#xC1F;&#xC3F; &#xC21;&#xC3F; &#xC35;&#xC3E;&#xC30;&#xC41; &#xC38;&#xC41;&#xC2C;&#xC4D;&#xC2C;&#xC2E;&#xC4D;&#xC2E;&#xC28;&#xC41; &#xC38;&#xC02;&#xC2A;&#xC4D;&#xC30;&#xC26;&#xC3F;&#xC02;&#xC1A;&#xC3E;&#xC30;&#xC41;, &#xC24;&#xC4B;&#xC1F;&#xC28;&#xC41; &#xC05;&#xC2E;&#xC4D;&#xC2E;&#xC2E;&#xC28;&#xC3F; &#xC05;&#xC21;&#xC3F;&#xC17;&#xC3E;&#xC30;&#xC41;. &#xC07;&#xC2A;&#xC4D;&#xC2A;&#xC1F;&#xC4D;&#xC32;&#xC4B; &#xC15;&#xC4B;&#xC1F;&#xC4D;&#xC32; &#xC35;&#xC3F;&#xC32;&#xC41;&#xC35; &#xC1A;&#xC47;&#xC38;&#xC47; &#xC06; &#xC38;&#xC4D;&#xC25;&#xC32;&#xC02; &#xC05;&#xC2A;&#xC4D;&#xC2A;&#xC1F;&#xC4D;&#xC32;&#xC4B; &#xC24;&#xC15;&#xC4D;&#xC15;&#xC41;&#xC35;&#xC47;&#xC2E;&#xC3F; &#xC09;&#xC02;&#xC21;&#xC47;&#xC26;&#xC3F; &#xC15;&#xC3E;&#xC26;&#xC41;. &#xC05;&#xC2F;&#xC3F;&#xC28;&#xC3E; &#xC1F;&#xC3F; &#xC1F;&#xC3F; &#xC21;&#xC3F; &#xC05;&#xC28;&#xC41;&#xC15;&#xC41;&#xC02;&#xC1F;&#xC47; &#xC0E;&#xC02;&#xC24; &#xC21;&#xC2C;&#xC4D;&#xC2C;&#xC48;&#xC28;&#xC3E; &#xC07;&#xC1A;&#xC4D;&#xC1A;&#xC3F; &#xC15;&#xC4A;&#xC28;&#xC17;&#xC32;&#xC30;&#xC41;. &#xC1F;&#xC3F; &#xC1F;&#xC3F; &#xC21;&#xC3F; &#xC35;&#xC3E;&#xC30;&#xC3F;&#xC28;&#xC3F; &#xC06;&#xC36;&#xC4D;&#xC1A;&#xC30;&#xC4D;&#xC2F;&#xC2A;&#xC30;&#xC41;&#xC38;&#xC4D;&#xC24;&#xC42; &#xC38;&#xC41;&#xC2C;&#xC4D;&#xC2C;&#xC2E;&#xC4D;&#xC2E; &#xC21;&#xC2C;&#xC4D;&#xC2C;&#xC41;&#xC35;&#xC26;&#xC4D;&#xC26;&#xC02;&#xC1F;&#xC42; &#xC12;&#xC15; &#xC35;&#xC3F;&#xC1A;&#xC3F;&#xC24;&#xC4D;&#xC30;&#xC2E;&#xC48;&#xC28; &#xC15;&#xC4B;&#xC30;&#xC3F;&#xC15; &#xC15;&#xC4B;&#xC30;&#xC3F;&#xC02;&#xC26;&#xC3F;.</p><p>&#xC06;&#xC2E;&#xC46; &#xC15;&#xC4B;&#xC30;&#xC3F;&#xC15; &#xC0F;&#xC2E;&#xC3F;&#xC1F;&#xC02;&#xC1F;&#xC47; , &#xC36;&#xC4D;&#xC30;&#xC40; &#xC30;&#xC3E;&#xC2E; &#xC28;&#xC35;&#xC2E;&#xC3F; &#xC15;&#xC3F; &#xC2A;&#xC26;&#xC3F; &#xC30;&#xC4B;&#xC1C;&#xC41;&#xC32; &#xC24;&#xC30;&#xC41;&#xC35;&#xC3E;&#xC24; &#xC38;&#xC40;&#xC24; &#xC38;&#xC2E;&#xC47;&#xC24; &#xC36;&#xC4D;&#xC30;&#xC40;&#xC30;&#xC3E;&#xC2E;&#xC41;&#xC32; &#xC35;&#xC3E;&#xC30;&#xC41; &#xC24;&#xC28; &#xC07;&#xC02;&#xC1F;&#xC3F;&#xC15;&#xC3F; &#xC30;&#xC3E;&#xC35;&#xC3E;&#xC32;&#xC3F;, &#xC05;&#xC15;&#xC4D;&#xC15;&#xC21; &#xC15;&#xC32;&#xC4D;&#xC2F;&#xC3E;&#xC23;&#xC4B;&#xC24;&#xC4D;&#xC38;&#xC35;&#xC02; &#xC1C;&#xC30;&#xC3F;&#xC17;&#xC3F;&#xC28; &#xC24;&#xC30;&#xC41;&#xC35;&#xC3E;&#xC24; &#xC24;&#xC3F;&#xC30;&#xC3F;&#xC17;&#xC3F; &#xC17;&#xC41;&#xC21;&#xC3F;&#xC15;&#xC3F; &#xC35;&#xC46;&#xC33;&#xC4D;&#xC33;&#xC3E;&#xC32;&#xC3F;. &#xC08; &#xC35;&#xC3F;&#xC1A;&#xC3F;&#xC24;&#xC4D;&#xC30;&#xC2E;&#xC48;&#xC28; &#xC15;&#xC4B;&#xC30;&#xC3F;&#xC15;&#xC24;&#xC4B; &#xC15;&#xC4A;&#xC02;&#xC24; &#xC06;&#xC36;&#xC4D;&#xC1A;&#xC30;&#xC4D;&#xC2F; &#xC2A;&#xC4B;&#xC2F;&#xC3F;&#xC28;&#xC3E; &#xC1F;&#xC3F; &#xC1F;&#xC3F; &#xC21;&#xC3F; &#xC35;&#xC3E;&#xC30;&#xC41; &#xC1A;&#xC3F;&#xC35;&#xC30;&#xC15;&#xC41; &#xC05;&#xC02;&#xC17;&#xC40;&#xC15;&#xC30;&#xC3F;&#xC02;&#xC1A;&#xC3E;&#xC30;&#xC41;. &#xC07;&#xC28;&#xC4D;&#xC28;&#xC47;&#xC33;&#xC4D;&#xC33; &#xC24;&#xC30;&#xC41;&#xC35;&#xC3E;&#xC24; &#xC15;&#xC42;&#xC21;&#xC3E; &#xC07;&#xC02;&#xC15;&#xC3E; &#xC30;&#xC3E;&#xC2E;&#xC41;&#xC32;&#xC35;&#xC3E;&#xC30;&#xC41; &#xC09;&#xC30;&#xC47;&#xC17;&#xC3F;&#xC02;&#xC2A;&#xC41;&#xC17;&#xC3E; &#xC38;&#xC41;&#xC2C;&#xC4D;&#xC2C;&#xC2E;&#xC4D;&#xC2E; &#xC17;&#xC3E;&#xC30;&#xC3F; &#xC07;&#xC02;&#xC1F;&#xC3F;&#xC15;&#xC3F; &#xC35;&#xC1A;&#xC4D;&#xC1A;&#xC3F; &#xC15;&#xC33;&#xC4D;&#xC2F;&#xC3E;&#xC23;&#xC02; &#xC24;&#xC30;&#xC41;&#xC35;&#xC3E;&#xC24; &#xC24;&#xC3F;&#xC30;&#xC3F;&#xC17;&#xC3F; &#xC35;&#xC46;&#xC33;&#xC4D;&#xC33;&#xC41;&#xC24;&#xC41;&#xC28;&#xC4D;&#xC28;&#xC3E;&#xC30;&#xC41;. &#xC07;&#xC2A;&#xC4D;&#xC2A;&#xC1F;&#xC3F;&#xC15;&#xC3F; &#xC38;&#xC41;&#xC2C;&#xC4D;&#xC2C;&#xC2E;&#xC4D;&#xC2E;&#xC17;&#xC3E;&#xC30;&#xC3F; &#xC15;&#xC41;&#xC1F;&#xC41;&#xC02;&#xC2C;&#xC2E;&#xC02;&#xC24;&#xC3E; &#xC06; &#xC30;&#xC4B;&#xC1C;&#xC41; &#xC30;&#xC3E;&#xC2E;&#xC41;&#xC32;&#xC35;&#xC3E;&#xC30;&#xC3F;&#xC28;&#xC3F; &#xC06;&#xC39;&#xC4D;&#xC35;&#xC3E;&#xC28;&#xC3F;&#xC02;&#xC1A;&#xC3F; , &#xC35;&#xC3E;&#xC30;&#xC3F; &#xC38;&#xC28;&#xC4D;&#xC28;&#xC3F;&#xC27;&#xC3F;&#xC32;&#xC4B; &#xC17;&#xC21;&#xC3F;&#xC2A;&#xC3F; &#xC24;&#xC3F;&#xC30;&#xC3F;&#xC15;&#xC3F; &#xC38;&#xC3E;&#xC17;&#xC28;&#xC02;&#xC2A;&#xC41;&#xC24;&#xC3E;&#xC30;&#xC41;. &#xC05;&#xC24;&#xC3F; &#xC38;&#xC3E;&#xC27;&#xC3E;&#xC30;&#xC23;&#xC2E;&#xC48;&#xC28; &#xC38;&#xC41;&#xC2C;&#xC4D;&#xC2C;&#xC2E;&#xC4D;&#xC2E;&#xC17;&#xC3E;&#xC30;&#xC41; &#xC05;&#xC38;&#xC3E;&#xC27;&#xC3E;&#xC30;&#xC23;&#xC2E;&#xC48;&#xC28; &#xC28;&#xC3F;&#xC30;&#xC4D;&#xC23;&#xC2F;&#xC02; &#xC24;&#xC4B; &#xC30;&#xC3E;&#xC2E;&#xC41;&#xC32;&#xC35;&#xC3E;&#xC30;&#xC3F; &#xC38;&#xC3E;&#xC15;&#xC4D;&#xC37;&#xC3F;&#xC17;&#xC3E; &#xC24;&#xC28; &#xC2A;&#xC3F;&#xC32;&#xC4D;&#xC32;&#xC32;&#xC15;&#xC3F; &#xC35;&#xC3E;&#xC30;&#xC3F; &#xC2A;&#xC3F;&#xC32;&#xC4D;&#xC32;&#xC32;&#xC15;&#xC3F;, &#xC35;&#xC3E;&#xC30;&#xC41; &#xC2E;&#xC30;&#xC1A;&#xC3F;&#xC2A;&#xC4B;&#xC28;&#xC3F;&#xC35;&#xC3F;&#xC27;&#xC2E;&#xC41;&#xC17;&#xC3E; &#xC15;&#xC41;&#xC1F;&#xC41;&#xC02;&#xC2C; &#xC2C;&#xC3E;&#xC02;&#xC27;&#xC35;&#xC4D;&#xC2F;&#xC3E;&#xC32; &#xC2A;&#xC48; &#xC2A;&#xC3E;&#xC20;&#xC02; &#xC1A;&#xC46;&#xC2A;&#xC4D;&#xC2A;&#xC3E;&#xC30;&#xC41;. &#xC12;&#xC15; &#xC35;&#xC47;&#xC33; &#xC35;&#xC3E;&#xC30;&#xC41; &#xC2E;&#xC30;&#xC1A;&#xC3F;&#xC2A;&#xC4B;&#xC2F;&#xC3F;&#xC28;&#xC3E; &#xC30;&#xC3E;&#xC2E;&#xC41;&#xC32;&#xC35;&#xC3E;&#xC30;&#xC41; &#xC35;&#xC3E;&#xC30;&#xC3F;&#xC28;&#xC3F; &#xC2E;&#xC30;&#xC41;&#xC35;&#xC28;&#xC3F;&#xC35;&#xC4D;&#xC35;&#xC30;&#xC41;. &#xC07;&#xC02;&#xC24;&#xC15;&#xC40; &#xC06; &#xC2A;&#xC4D;&#xC30;&#xC3E;&#xC02;&#xC24;&#xC02; &#xC2A;&#xC47;&#xC30;&#xC47;&#xC02;&#xC1F;&#xC4B; &#xC1A;&#xC46;&#xC2A;&#xC4D;&#xC2A;&#xC32;&#xC47;&#xC26;&#xC41; &#xC15;&#xC26;&#xC42;, &#xC05;&#xC26;&#xC47; &#xC08; &#xC30;&#xC4B;&#xC1C;&#xC41; &#xC2E;&#xC28;&#xC02; &#xC2A;&#xC3F;&#xC32;&#xC3F;&#xC1A;&#xC47; R S Gardens (&#xC30;&#xC47;&#xC2A;&#xC3E;&#xC15;&#xC41;&#xC32;&#xC3E; &#xC38;&#xC41;&#xC2C;&#xC4D;&#xC2C;&#xC2E;&#xC4D;&#xC2E; &#xC24;&#xC4B;&#xC1F;). &#xC07;&#xC2A;&#xC4D;&#xC2A;&#xC1F;&#xC3F;&#xC15;&#xC40; &#xC05;&#xC15;&#xC4D;&#xC15;&#xC21; &#xC1F;&#xC3F; &#xC1F;&#xC3F; &#xC21;&#xC3F; &#xC35;&#xC3E;&#xC30;&#xC3F; &#xC2C;&#xC3E;&#xC32;&#xC2E;&#xC02;&#xC26;&#xC3F;&#xC30;&#xC4D; &#xC38;&#xC4D;&#xC15;&#xC42;&#xC32;&#xC4D; &#xC35;&#xC41;&#xC02;&#xC26;&#xC3F;.</p><p><strong>&#xC28;&#xC3E; &#xC2A;&#xC30;&#xC3F;&#xC1A;&#xC2F;&#xC02;</strong> : &#xC2A;&#xC41;&#xC1F;&#xC4D;&#xC1F;&#xC3F; &#xC2A;&#xC46;&#xC30;&#xC3F;&#xC17;&#xC3F;&#xC02;&#xC26;&#xC3F; &#xC24;&#xC3F;&#xC30;&#xC41;&#xC2A;&#xC24;&#xC3F;&#xC32;&#xC4B; &#xC05;&#xC2F;&#xC3F;&#xC28;&#xC3E; &#xC1A;&#xC26;&#xC41;&#xC35;&#xC41;&#xC30;&#xC40;&#xC24;&#xC4D;&#xC2F;&#xC3E; &#xC24;&#xC30;&#xC41;&#xC35;&#xC3E;&#xC24; &#xC09;&#xC26;&#xC4D;&#xC2F;&#xC4B;&#xC17;&#xC30;&#xC40;&#xC24;&#xC4D;&#xC2F;&#xC3E; &#xC2C;&#xC2F;&#xC1F; &#xC26;&#xC47;&#xC36;&#xC3E;&#xC32;&#xC32;&#xC4B; &#xC17;&#xC21;&#xC3F;&#xC2A;&#xC3F; &#xC07;&#xC2A;&#xC4D;&#xC2A;&#xC41;&#xC21;&#xC41; &#xC39;&#xC48;&#xC26;&#xC30;&#xC3E;&#xC2C;&#xC3E;&#xC26;&#xC4D; &#xC32;&#xC4B; &#xC28;&#xC3F;&#xC35;&#xC3E;&#xC38;&#xC2E;&#xC41;&#xC02;&#xC1F;&#xC41;&#xC28;&#xC4D;&#xC28;&#xC3E;&#xC28;&#xC41;. &#xC15;&#xC25;&#xC32;&#xC41; &#xC1A;&#xC46;&#xC2A;&#xC4D;&#xC2A;&#xC21;&#xC2E;&#xC28;&#xC4D;&#xC28; , &#xC1A;&#xC26;&#xC35;&#xC21;&#xC2E;&#xC28;&#xC4D;&#xC28; &#xC1A;&#xC3E;&#xC32; &#xC07;&#xC37;&#xC4D;&#xC1F;&#xC02;, &#xC2E;&#xC41;&#xC16;&#xC4D;&#xC2F;&#xC02;&#xC17;&#xC3E; &#xC24;&#xC46;&#xC32;&#xC41;&#xC17;&#xC41;&#xC32;&#xC4B; .<br>&#xC24;&#xC46;&#xC32;&#xC41;&#xC17;&#xC41; &#xC38;&#xC3E;&#xC39;&#xC3F;&#xC24;&#xC4D;&#xC2F;&#xC02;&#xC24;&#xC4B; &#xC2A;&#xC46;&#xC26;&#xC4D;&#xC26;&#xC17;&#xC3E; &#xC2A;&#xC30;&#xC3F;&#xC1A;&#xC2F;&#xC02; &#xC32;&#xC47;&#xC15;&#xC2A;&#xC4B;&#xC2F;&#xC3F;&#xC28;&#xC3E; , &#xC2D;&#xC3E;&#xC37; &#xC1A;&#xC26;&#xC3F;&#xC35;&#xC3F;&#xC28;&#xC2A;&#xC4D;&#xC2A;&#xC41;&#xC21;&#xC41; , &#xC35;&#xC3F;&#xC28;&#xC4D;&#xC28;&#xC2A;&#xC4D;&#xC2A;&#xC41;&#xC21;&#xC41; &#xC0E;&#xC02;&#xC24; &#xC2C;&#xC3E;&#xC17;&#xC41;&#xC02;&#xC26;&#xC4B; &#xC1A;&#xC46;&#xC2A;&#xC4D;&#xC2A;&#xC17;&#xC32;&#xC3F;&#xC17;&#xC3F;&#xC28;&#xC02;&#xC24; &#xC2A;&#xC4D;&#xC30;&#xC3E;&#xC35;&#xC3F;&#xC23;&#xC4D;&#xC2F;&#xC02; &#xC35;&#xC41;&#xC02;&#xC26;&#xC3F;. &#xC07;&#xC26;&#xC02;&#xC24;&#xC3E; &#xC15;&#xC42;&#xC21;&#xC3E; &#xC2E;&#xC3E; &#xC28;&#xC3E;&#xC28;&#xC4D;&#xC28;&#xC17;&#xC3E;&#xC30;&#xC3F; &#xC1A;&#xC32;&#xC41;&#xC35;&#xC47;.</p>]]></content:encoded></item><item><title><![CDATA[Help me from SELF HELP Books]]></title><description><![CDATA[<figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="480" height="270" src="https://www.youtube.com/embed/tCvwwgxT420?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><figcaption>Rajasekhar Mamidana on SELF HELP Books</figcaption></figure><p>I first met Raj during my toastmaster days. He was, in those days, one of most promising stand-up comics in Hyderabad. I had once hosted a Humorous Speech contest at one of the organizations I was working with to just get everyone to listen</p>]]></description><link>http://dudistan.com/help-me-from-self-help-books/</link><guid isPermaLink="false">632ee6210d52c20467e48ed8</guid><dc:creator><![CDATA[Bhanu Mokkala]]></dc:creator><pubDate>Tue, 17 Mar 2020 07:18:29 GMT</pubDate><content:encoded><![CDATA[<figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="480" height="270" src="https://www.youtube.com/embed/tCvwwgxT420?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><figcaption>Rajasekhar Mamidana on SELF HELP Books</figcaption></figure><p>I first met Raj during my toastmaster days. He was, in those days, one of most promising stand-up comics in Hyderabad. I had once hosted a Humorous Speech contest at one of the organizations I was working with to just get everyone to listen to Raj. Over the years, Raj had become not just better but an amazing stand-up comedian.</p><p>This is one of his recent works. His views on the Self help books is exactly what felt about them over the years.</p>]]></content:encoded></item><item><title><![CDATA[Superior Engineering Quality in IT is a myth, is it?]]></title><description><![CDATA[Mid to Smaller size IT Services / Consultancy or Startup accelerators should not really aim at superior engineering instead do just what is needed to sail over.]]></description><link>http://dudistan.com/superior-engineering-quality-is-a-myth/</link><guid isPermaLink="false">632ee6210d52c20467e48ed7</guid><category><![CDATA[startup]]></category><category><![CDATA[IT quality]]></category><category><![CDATA[It consulting]]></category><category><![CDATA[it services]]></category><category><![CDATA[offshore]]></category><category><![CDATA[india]]></category><dc:creator><![CDATA[Bhanu Mokkala]]></dc:creator><pubDate>Fri, 06 Mar 2020 02:00:51 GMT</pubDate><media:content url="http://dudistan.com/content/images/2020/03/excellence-01.jpeg" medium="image"/><content:encoded><![CDATA[<img src="http://dudistan.com/content/images/2020/03/excellence-01.jpeg" alt="Superior Engineering Quality in IT is a myth, is it?"><p>is what I heard during a conversation today. Do you think so? To substantiate, I was told that Mid to Smaller size IT Services / Consultancy or Startup accelerators should not aim at superior engineering instead do just what is needed to sail over.</p><!--kg-card-begin: markdown--><blockquote>
<p>Mid to Smaller size IT Services / Consultancy or Startup accelerators should not aim at superior engineering instead do just what is needed to sail over.</p>
</blockquote>
<!--kg-card-end: markdown--><p>Well!! I beg to differ. I understand that you can&#x2019;t set goals in engineering quality excellence and achieve it. This is because of constant change in the technology and other related areas which makes excellence a moving goal post. But that doesn&#x2019;t mean that you shy away from it. It is imperative to devise a plan and find a way to achieve it. Like they say, more than achieving the goal of excellence, the journey is more important. The very fact that someone is thinking about will set the rest of stakeholders thinking about excellence. Also, it doesn&#x2019;t just mean that you are writing the best code ever written and claim to be excellent, but the whole process.</p><!--kg-card-begin: markdown--><blockquote>
<p>Like they say, more than achieving the goal of excellence, the journey is more important.</p>
</blockquote>
<!--kg-card-end: markdown--><p>IT Services industry has gone through some dramatic changes with the advent of Cloud, DevOps and other automation-related technologies. These new-age technologies have led to the birth of numerous Mid to Small IT Services / Consulting companies. Clients now are at liberty to choose a player with specific skills &amp; expertise to address a specific business case unlike before where one IT giant will deliver all the services. This has rationalized the whole IT services market which has led to so many IT professionals who came to industry around the mid 90s becoming entrepreneurs. It all starts with the entrepreneur&#x2019;s own area expertise. It could be a specific programming language like C++, Java or tools like SAP, Salesforce or domain like Finance, Retail. They will start small with 5 to 10 FTE (Full Time Employees) and then quickly grow to 100 to 200.</p><!--kg-card-begin: markdown--><blockquote>
<p>Clients now are at liberty to choose a player with specific skills &amp; expertise to address a specific business case unlike before where one IT gaint will deliver all the services.</p>
</blockquote>
<!--kg-card-end: markdown--><p>Eventually, some of these companies can reach nearly 1000 FTEs based on their ability to attract multiple clients. Just when the entrepreneur thinks he can breathe easy, it all starts. They will have to start expanding to other areas, beyond what is perceived to be the area of expertise, to sustain. Also, they need to constantly refine &amp; rejuvenate their processes around project management as well as delivery to stay relevant. Even if there is a turnover of talent which is very obvious, the quality of engineering will have to be maintained. It is easier said than done.</p><!--kg-card-begin: markdown--><blockquote>
<p>Please don&apos;t reduce it to just a group that defines coding standards and uploads it to internal code storage or team portal.</p>
</blockquote>
<!--kg-card-end: markdown--><p>To start with it needs to be recognized as important enough. Again, need to understand that it is an ongoing exercise and not one-off. There should be a CoE (Center of Excellence) for each technology area or domain. Please don&#x2019;t reduce it to just a group that defines coding standards and uploads it to internal code storage or team portal. Set up a review of all the engineering work delivered and make sure to compare it with the benchmark. It is about questioning every line of code and checking if there is a better way to do it. All these need to happen in a friendly environment and not the way. Encourage people to start contributing to OpenSource projects, one of the ways to stay relevant to coding practices. Reward &amp; recognize those who take an active role in these activities. For all these, you need to have a mindset. It doesn&#x2019;t happen all by itself you will have to make an effort.</p><p><em><em>I have interests in Alexa, Angular / AngularJS, NodeJS, Ethereum Blockchain, ChatBOTS and many more. Read more at </em></em><a href="http://www.dudistan.com/" rel="nofollow noopener"><em><em>http://www.dudistan.com/</em></em></a></p>]]></content:encoded></item><item><title><![CDATA[Live : UI Framework job trends in Hyderabad]]></title><description><![CDATA[Live trending of UI framework jobs in Hyderabad achieved using Google App Engine, Google Cloud SQL, Google Data Studio and Python]]></description><link>http://dudistan.com/live-ui-framework-jobs-in-hyderabad/</link><guid isPermaLink="false">632ee6210d52c20467e48ed6</guid><category><![CDATA[glcoud]]></category><category><![CDATA[google]]></category><category><![CDATA[app engine]]></category><category><![CDATA[python]]></category><category><![CDATA[cron]]></category><category><![CDATA[IT jobs]]></category><category><![CDATA[jobs in Hyderabad]]></category><category><![CDATA[UI framework jobs]]></category><dc:creator><![CDATA[Bhanu Mokkala]]></dc:creator><pubDate>Sun, 01 Sep 2019 02:22:29 GMT</pubDate><media:content url="http://dudistan.com/content/images/2019/09/uiframeworks.png" medium="image"/><content:encoded><![CDATA[<img src="http://dudistan.com/content/images/2019/09/uiframeworks.png" alt="Live : UI Framework job trends in Hyderabad"><p>using <a href="https://cloud.google.com/appengine/">Google App Engine</a>, <a href="https://cloud.google.com/sql/docs/">Google Cloud SQL</a>, <a href="https://datastudio.google.com/">Google Data Studio</a> and Python <em>(wait for the embedded graph to load below)</em></p><!--kg-card-begin: html--><iframe width="800" height="600" src="https://datastudio.google.com/embed/reporting/1NGtQRnjmJBkLrGEmycx8L5s9ZnAC6ojE/page/QRox" frameborder="0" style="border:0" allowfullscreen></iframe><!--kg-card-end: html--><p>I was trying to practice my python programming skills and decided to write python cron jobs. I realized that if I have to run cron jobs then I need server to host these cron jobs and configure them to run. Then I looked up Google cloud for a cloud service to run cron jobs. I realized that I can use <a href="https://cloud.google.com/appengine/">Google App Engine</a> to create and host my cron jobs.</p><p>To start with, I downloaded the <a href="https://cloud.google.com/sdk/">Google Cloud SDK</a> in order for me to write the program on my desktop, test it and then deploy on the Google Cloud when it is ready. You should download the <a href="https://cloud.google.com/sdk/">Google Cloud SDK</a> and configure it.</p><p>My project folder consists of 3 main files. <em>app.yaml</em> that holds the app configuration. <em>cron.yaml</em> that holds the cron frequency &amp; other related info and <em>main.py</em> that has the main program. <strong>This may not be most efficient way of doing what I tried to do. Now that I know how to do it, I would love to make it more efficient and more compact. </strong></p><p><em>app.yaml</em></p><pre><code>runtime: python27
api_version: 1
threadsafe: yes
service: vue-scrape

libraries:
- name: lxml
  version: 3.7.3
- name: MySQLdb
  version: 1.2.5

handlers:
- url: .*
  script: main.app

env_variables:
    CLOUDSQL_CONNECTION_NAME: xxxxxxxxxxxxxxxxxxxxxx
    CLOUDSQL_DSN: mysql:unix_socket=xxxxxxxxxxxxxxxxxx
    CLOUDSQL_USER: root
    CLOUDSQL_PASSWORD: xxxxxxxxx</code></pre><p><em>cron.yaml</em></p><pre><code>cron:
- description: &quot;angular scrape job&quot;
  url: /angular
  target: angular-scrape
  schedule: every 24 hours
- description: &quot;react scrape job&quot;
  url: /react
  target: react-scrape
  schedule: every 24 hours  
- description: &quot;vue scrape job&quot;
  url: /vue
  target: vue-scrape
  schedule: every 24 hours    </code></pre><p><em>main.py</em></p><pre><code class="language-python">import logging
import urllib
import urllib2
from google.appengine.api import urlfetch
import webapp2
from lxml import etree
from StringIO import StringIO
import os
import MySQLdb
from datetime import datetime

CLOUDSQL_CONNECTION_NAME = os.environ.get(&apos;CLOUDSQL_CONNECTION_NAME&apos;)
CLOUDSQL_USER = os.environ.get(&apos;CLOUDSQL_USER&apos;)
CLOUDSQL_PASSWORD = os.environ.get(&apos;CLOUDSQL_PASSWORD&apos;)

def connect_to_cloudsql():

    if os.getenv(&apos;SERVER_SOFTWARE&apos;, &apos;&apos;).startswith(&apos;Google App Engine/&apos;):
        cloudsql_unix_socket = os.path.join(
            &apos;/cloudsql&apos;, CLOUDSQL_CONNECTION_NAME)

        db = MySQLdb.connect(
            unix_socket=cloudsql_unix_socket,
            user=CLOUDSQL_USER,
            passwd=CLOUDSQL_PASSWORD)

    else:
        db = MySQLdb.connect(
            host=&apos;127.0.0.1&apos;, user=CLOUDSQL_USER, passwd=CLOUDSQL_PASSWORD)

    return db

class UrlPostHandler(webapp2.RequestHandler):
    def get(self):
        try:
            headers = {&apos;Content-Type&apos;: &apos;application/x-www-form-urlencoded&apos;}
            result = urlfetch.fetch(
                url=&apos;https://www.xxxxxx.com/vue-jobs-in-hyderabad&apos;, #replace with job site of your choice
                method=urlfetch.POST,
                headers=headers)
            parser = etree.HTMLParser() 
            tree   = etree.parse(StringIO(result.content), parser)      
            if result.status_code == 200:
                self.response.write(result.content)
                logging.info(tree.find(&apos;.//title&apos;).text.split(&quot;-&quot;)[1].split(&quot; &quot;)[1].strip())
                db = connect_to_cloudsql()
                cursor = db.cursor()
                cursor.execute(&quot;INSERT INTO `cityjobs`.`jobtrack`(`tech`, `city`, `logdate`, `count`) VALUES (&apos;&quot; + &quot;vue&quot; +&quot;&apos;, &apos;&quot; + &quot;hyderabad&quot; +&quot;&apos;, &apos;&quot; + datetime.today().strftime(&apos;%Y-%m-%d&apos;) + &quot;&apos;, &apos;&quot; + tree.find(&apos;.//title&apos;).text.split(&quot;-&quot;)[1].split(&quot; &quot;)[1].strip() + &quot;&apos;);&quot;)
                db.commit()
                cursor.close()
                db.close()
            else:
                self.response.status_code = result.status_code
        except urlfetch.Error:
            logging.exception(&apos;Caught exception fetching url&apos;)

app = webapp2.WSGIApplication([
    (&apos;/vue&apos;, UrlPostHandler),
], debug=True)</code></pre><p>Once you have the code setup on the your desktop, you can start testing it using <a href="https://cloud.google.com/appengine/docs/standard/python/tools/using-local-server">Google Local Development Server</a>. Using this you can check if your code is going to work fine once it is deployed.</p><p>In my case, I created three different services for each of the frameworks ( as I said may not be efficient way of doing it) and then I created one cron.yaml that schedules all the services. For the purpose of the this code to run, I had created a Cloud SQL project with MySQL as the DB of choice and created a table based on the info that I wanted to record. Once the code is ready and tested locally, I first deployed each service by <a href="https://cloud.google.com/sdk/gcloud/reference/app/deploy">gcloud app deploy</a>. As you can see, I had to make changes in the <em>main.py</em> as well as <em>app.yaml </em>before I deployed the service for each framework. Then I used same <a href="https://cloud.google.com/appengine/docs/flexible/nodejs/scheduling-jobs-with-cron-yaml">gcloud app deploy cron</a> to deploy cron.yaml. As you keep deploying, you can verify the deployed service / cron on your Google Cloud console.</p><p>Once I have the data pumping into my Cloud SQL db, I created a data visualization using the <a href="https://datastudio.google.com/">Google Data Studio</a>. You can connect to you db and plug-in the table that has the values. With a bit of trial &amp; error, I got the graph view that I wanted.</p><p>I had fun building it. Happy coding.</p><p><em><em>I have interests in Alexa, Angular / AngularJS, NodeJS, Ethereum Blockchain, ChatBOTS and many more. Read more at </em></em><a href="http://www.dudistan.com/" rel="nofollow noopener"><em><em>http://www.dudistan.com/</em></em></a></p>]]></content:encoded></item><item><title><![CDATA[Customer Satisfaction in OmniChannel Using NodeJS, Firebase, Google Cloud NLP API & Dialogflow]]></title><description><![CDATA[OmniChannel is not a buzzword any more. It means that you have a way to deal with customers who use different channels - Web, telephone, Voice BOT or CHAT BOT to reach out to you for support.]]></description><link>http://dudistan.com/customer-satisfaction-in-omni-channel-using-nodejs-firebase-google/</link><guid isPermaLink="false">632ee6210d52c20467e48ed1</guid><category><![CDATA[omnichannel]]></category><category><![CDATA[customer satisfaction]]></category><category><![CDATA[bots]]></category><category><![CDATA[alexa]]></category><category><![CDATA[speech analytics]]></category><category><![CDATA[dialogflow]]></category><dc:creator><![CDATA[Bhanu Mokkala]]></dc:creator><pubDate>Mon, 08 Jul 2019 09:37:42 GMT</pubDate><media:content url="http://dudistan.com/content/images/2019/07/storyblocks-omnichannel-concept-many-communication-channels-with-customer_ruDU9JF5X_SB_PM.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://dudistan.com/content/images/2019/07/storyblocks-omnichannel-concept-many-communication-channels-with-customer_ruDU9JF5X_SB_PM.jpg" alt="Customer Satisfaction in OmniChannel Using NodeJS, Firebase, Google Cloud NLP API &amp; Dialogflow"><p>OmniChannel is not a buzzword any more. If you haven&apos;t heard about it yet, then it is a cross channel strategy to engage with customers. Which effectively means that you have a way to deal with customers who use different channels - Web, telephone, Voice BOT or CHAT BOT to reach out to you for support. While it is fairly easy to build or implement a strategy across channels with the so many tools &amp; technologies available, it becomes difficult to when users switch channels. User will switch channels when he or she feels that no one is addressing their concern. Someone needs to keep tab on these escalations as they pass through the channels. We need to identify and address such incidents before they are blown out of proportions. Imagine a customer who is very disappointed as he or she didn&apos;t get a response from any channels as a supervisor it shows up on your dashboard before blows out.</p><p>I decided a build a small Proof-Of-Concept involving some key channels. In place of Web interface, I built a small web page to capture customer query. For the sake of POC, I picked firebase as the DB to store all the analytics and JIRA for ticket creation &amp; tracking.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://dudistan.com/content/images/2019/07/mitel.png" class="kg-image" alt="Customer Satisfaction in OmniChannel Using NodeJS, Firebase, Google Cloud NLP API &amp; Dialogflow" loading="lazy"><figcaption>Omnichannel Flow</figcaption></figure><h2 id="email">Email</h2><ul><li>Set up a small RPA bot that reads a mail as it arrives</li><li>The text on the mail is analyzed using Google text analytics for sentiment</li><li>The text as well as sentiment score is sent to a central DB and stored against the customer id &amp; Ticket id?</li></ul><h2 id="messenger-chat">Messenger Chat</h2><ul><li>We can log all chat responses and conduct text analytics in real time using Google text analytics for sentiment</li><li>The text as well as sentiment score is sent to a central DB and stored against the customer id &amp; Ticket id?</li></ul><h2 id="voice-bot">Voice BOT</h2><ul><li>We can use Alexa or Dialogflow (telephone integration module) to log all the spoken text/words over a conversation and do a real time analytics using Google API</li><li>The text as well as sentiment score is sent to a central DB and stored against the customer id &amp; Ticket id?</li></ul><h2 id="web-interface">Web Interface</h2><ul><li>We can set up a web page that pulls all the text &amp; sentiment score against specific customer or ticket (as stored) and aggregates on the page</li><li>The basic aggregate score can be overall sentiment across all channels/text.</li></ul><p>In the below code snippet, <em>callmapi()</em> function reads the email from the designated mailbox and then calls <em>crtjiratkt </em>function that creates a JIRA ticket and then <em>getsent </em>function is called which sends the text to Google Speech analytics to get the sentiment score.</p><pre><code>const notifier = require(&apos;mail-notifier&apos;);
var Imap = require(&apos;imap&apos;),
    inspect = require(&apos;util&apos;).inspect;
var fs = require(&apos;fs&apos;), fileStream;
var cmd = require(&apos;node-cmd&apos;);
const request = require(&apos;request&apos;);
const firebase = require(&apos;firebase&apos;);
const admin = require(&apos;firebase-admin&apos;);


var imap1 = {
    user: &quot;your-mailbox@gmail.com&quot;,
    password: &quot;mailpassword&quot;,
    host: &quot;imap.gmail.com&quot;,
    port: 993, // imap port
    tls: true,// use secure connection
    tlsOptions: { rejectUnauthorized: false }
};

var config = {
    apiKey: &quot;your-key-goes-here&quot;,
    authDomain: &quot;yourdb.firebaseapp.com&quot;,
    databaseURL: &quot;https://yourdb.firebaseio.com&quot;,
    projectId: &quot;your-projectid&quot;,
    storageBucket: &quot;yourdb.appspot.com&quot;,
    messagingSenderId: &quot;000000000&quot;
  };
firebase.initializeApp(config);

admin.initializeApp({
    credential: admin.credential.cert({
      projectId: &apos;your-projectid&apos;,
      clientEmail: &apos;firebase-adminsdk-0000@your-projectid.iam.gserviceaccount.com&apos;,
      privateKey: &apos;-----BEGIN PRIVATE KEY----------END PRIVATE KEY-----\n&apos;
    }),
    databaseURL: &apos;https://your-projectid.firebaseio.com&apos;
  });

function callmapi() {
    notifier(imap1)
    .on(&apos;mail&apos;, mail =&gt; {
        console.log(&apos;from : &apos; + mail.from[0].address);
        console.log(&apos;subject : &apos; + mail.subject);
        //console.log(mail);
        crtjiratkt(mail.text, function(key){
        getsent(mail.text, function(score){ 
            console.log(mail.text + &quot; = &quot; + score)
            admin.database().ref(&apos;scores/&apos;).push({
                channel: &apos;email&apos;,
                cname: mail.from[0].name,
                cscore: score,
                ctext: mail.text,
                cmail: mail.from[0].address,
                tdesc: mail.subject,
                ticket: key
              }, function(error) {
                  console.log(error);
              });
        })
      })
    })
    .on(&apos;error&apos;, err =&gt; {
        console.log(err);
    })
    .on(&apos;end&apos;, () =&gt; n.start())
    .start();

function getsent (tline, callback) {
    let options1 = { method: &apos;POST&apos;,
    url: &apos;https://language.googleapis.com/v1beta2/documents:analyzeSentiment?key=your-key-goes-here&apos;,
    headers:
        {   &apos;cache-control&apos;: &apos;no-cache&apos;,
            &apos;content-type&apos;: &apos;application/json&apos; },
    body:
        {
          &apos;document&apos;:{
          &apos;type&apos;:&apos;PLAIN_TEXT&apos;,
          &apos;content&apos;: tline
        }
      },
    json: true };

    request(options1, function (error, response, body) {
    //console.log(response);
    if (body.error != &apos;undefined&apos;) {
      callback(body.documentSentiment.score);
    } else {
      callback(0);
    }


  });
}

function crtjiratkt(tline, callback) {
  var options = { method: &apos;POST&apos;,
  url: &apos;https://test.atlassian.net/rest/api/2/issue/&apos;,
  headers: 
   { &apos;Postman-Token&apos;: &apos;a4536d1b-ff9c-4de7-a9c7-6a30417f61a2&apos;,
     &apos;Cache-Control&apos;: &apos;no-cache&apos;,
     Authorization: &apos;Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&apos;,
     &apos;Content-Type&apos;: &apos;application/json&apos; },
  body: 
   { fields: 
      { project: { key: &apos;RPA&apos; },
        summary: tline,
        description: &apos;Instance Name : DevInstanceforTesting\nImages              : Cirros\nFlavor               : m1.small\nRequester         : test@test.com&apos;,
        issuetype: { name: &apos;Task&apos;, Assignee: &apos;BOT&apos; } } },
  json: true };

  request(options, function (error, response, body) {
    if (error) throw new Error(error);
    if (body.error != &apos;undefined&apos;) {
      callback(body.key);
      console.log(body);
    } else {
      callback(0);
    }
  });  
}
</code></pre><p>In the below code snippet which is inserted in the dialogflow &apos;Webhook&apos;, intercepts the chat responses in <em>exports.chatbot </em> which in turn polled to Google Speech analytics for a sentiment score (<em>getsent</em>).</p><pre><code>const request = require(&apos;request&apos;);
const admin = require(&apos;firebase-admin&apos;);

admin.initializeApp({
    credential: admin.credential.cert({
      projectId: &apos;your-projectid&apos;,
      clientEmail: &apos;firebase-adminsdk-0000@your-projectid.iam.gserviceaccount.com&apos;,
      privateKey: &apos;-----BEGIN PRIVATE KEY----------END PRIVATE KEY-----\n&apos;
    }),
    databaseURL: &apos;https://your-projectid.firebaseio.com&apos;
  });


exports.chatbot = (req, res) =&gt; {
  /*let message = req.query.message || req.body.message || &apos;Hello World!&apos;;
  res.status(200).send(message);*/
  //console.log(req.body.queryResult.intent);
  if (req.body.queryResult.intent.displayName == &quot;Default Welcome Intent - custom - yes - custom - custom&quot;) {
     getsent(req.body.queryResult.queryText, function(score){
             admin.database().ref(&apos;scores/&apos;).push({
                channel: &apos;chat&apos;,
                cname: &apos;prakash&apos;,
                cscore: score,
                ctext: req.body.queryResult.queryText,
                cmail: &apos;test mail&apos;,
                tdesc: &apos;test subject&apos;,
                ticket: &apos;abc234&apos;
              }, function(error) {
                  console.log(error);
              });
         console.log(req.body.queryResult.queryText + &quot;:&quot; + score);
     })
  }
  else if (req.body.queryResult.intent.displayName == &quot;Default Welcome Intent - custom - yes - custom&quot;) {
    console.log(&quot;ticket no: &quot; + req.body.queryResult.queryText);
  }
};

function getsent (tline, callback) {
    let options1 = { method: &apos;POST&apos;,
    url: &apos;https://language.googleapis.com/v1beta2/documents:analyzeSentiment?key=AIzaSyCh-H9fxZXaR43dQQgg4FIwLWpAX2L5C7E&apos;,
    headers:
        {   &apos;cache-control&apos;: &apos;no-cache&apos;,
            &apos;content-type&apos;: &apos;application/json&apos; },
    body:
        {
          &apos;document&apos;:{
          &apos;type&apos;:&apos;PLAIN_TEXT&apos;,
          &apos;content&apos;: tline
        }
      },
    json: true };

    request(options1, function (error, response, body) {
    //console.log(response);
    if (body.error != &apos;undefined&apos;) {
      callback(body.documentSentiment.score);
    } else {
      callback(0);
    }


  });
}

</code></pre><p><a href="https://cloud.google.com/natural-language/">https://cloud.google.com/natural-language/</a></p><p><em><em>I have interests in Alexa, Angular / AngularJS, NodeJS, Ethereum Blockchain, ChatBOTS and many more. Read more at </em></em><a href="http://www.dudistan.com/" rel="nofollow noopener"><em><em>http://www.dudistan.com/</em></em></a></p>]]></content:encoded></item><item><title><![CDATA[Aftermath of '96, the movie]]></title><description><![CDATA[<p><em>Disclaimer : If you haven&apos;t watched the tamil movie 96 then this article will not make sense to you. If you haven&apos;t watched the movie yet then you probably should, especially if you are in mid 40s and preparing for life after 50.</em></p><p>The whole world is</p>]]></description><link>http://dudistan.com/impact-of-96-in-2019/</link><guid isPermaLink="false">632ee6210d52c20467e48ed3</guid><dc:creator><![CDATA[Bhanu Mokkala]]></dc:creator><pubDate>Wed, 13 Feb 2019 18:41:33 GMT</pubDate><media:content url="http://dudistan.com/content/images/2019/01/IMG_0299.jpeg" medium="image"/><content:encoded><![CDATA[<img src="http://dudistan.com/content/images/2019/01/IMG_0299.jpeg" alt="Aftermath of &apos;96, the movie"><p><em>Disclaimer : If you haven&apos;t watched the tamil movie 96 then this article will not make sense to you. If you haven&apos;t watched the movie yet then you probably should, especially if you are in mid 40s and preparing for life after 50.</em></p><p>The whole world is singing praises of Director Prem kumar and the lead protagonists Vijay Sethupathi and Trisha for the brilliant movie. Sometimes, it is that uncanny combination of right people, right story and some brilliant acting that creates the magic. Well!! I am not going to be one of those movie reviewers to analyze the movie for its story, acting, DOP and of course brilliant music by Govind Vasanthan. I would rather focus on the what this movie did to people who watched it.</p><p>Let us first deal with the nahsayers. The big question is about kids/teens falling in love at a young age. Is it believable? Is it really possible? But a large section of us out there who experienced it can vouch that it is possible. Initially it may be a simple appreciation &amp; liking before it becomes heart thumping (literally, in the movie). This is of course when the other person takes equal interest in you and probably starts responding in some way, like as simple as a smile. Is your heart thumping?</p><p>What if, Ram was married? Would Jaanu cry her heart out while leaving the airport? or they would have dealt with the situation with same maturity </p><p>A friend of mine did get in touch with a girl that he &apos;thought&apos; was interested in him some 25 years back. In the aftermath of the movie, he got inspired to go look for this girl with whom he hardly spoke even during those years when he knew her. With a bit of research on facebook and some help from her friends, he eventually got hold of her phone number. He couldn&apos;t bring himself to call the girl instead he sent a whatsapp message and waited with bated breath for her response. Eventually she responded. After exchanging couple of messages, he realized that she was&apos;t really excited to meet him. He quickly realized that everything that he thought was just figment of his imagination. It was a huge disappointment. He realized that he was of better off living with that beautiful memory. It was hard but he is making an effort to move on. </p>]]></content:encoded></item><item><title><![CDATA[Angels of the Past]]></title><description><![CDATA[Not very often you common across something that will leave a long lasting impression. It could be a person, an event or a place. You are a different person after that. It will take sometime to sink in.]]></description><link>http://dudistan.com/angels-of-the-past/</link><guid isPermaLink="false">632ee6210d52c20467e48ed2</guid><category><![CDATA[reunion]]></category><category><![CDATA[friends]]></category><category><![CDATA[school]]></category><dc:creator><![CDATA[Bhanu Mokkala]]></dc:creator><pubDate>Mon, 24 Dec 2018 11:55:33 GMT</pubDate><media:content url="http://dudistan.com/content/images/2018/12/IMG_20181224_172007-01.jpeg" medium="image"/><content:encoded><![CDATA[<img src="http://dudistan.com/content/images/2018/12/IMG_20181224_172007-01.jpeg" alt="Angels of the Past"><p>Not very often you common across something that will leave a long lasting impression. It could be a person, an event or a place. You are a different person after that. It will take sometime to sink in.</p><p>I recently witnessed, better still, been part of an event that changed me completely. For everyone else it was just a school reunion but for us it was a REUNION. Imagine this, close to 100 individuals (out of overall nearly 200) belonging to same batch meeting after 30 long years. You have to be one of those 100 to understand what it really means. These are people you grew up with. You fought, you cried, you laughed and went through hell a lot of emotions during your childhood. The same set of individuals sitting together and sharing a laugh but this time, little more mature, little more caring and little more love. It is like a treasure trove of friends that you discovered accidentally. Your life suddenly becomes little more interesting and a bit more worthwhile. I see this being a perfect remedy for anyone having a <a href="https://en.wikipedia.org/wiki/Midlife_crisis"><em>midlife crisis</em></a> if there is one.</p><p>So, who should get credited for this REUNION? The organizers who worked tirelessly or the participants who set aside everything to be there at the event. I think it is both and something more. It is the <strong>alma mater</strong>, in this case the school itself and of course the amazing teachers. Somewhere it is something to do with the value system that teachers passed on. It may not be just the enthusiasm to meet each other that brought so many of them to the event, it is about commitment to friendship. People stood up to so many people working hard for the event. I feel that it may not be as successful had this event was done 10 or 20 years back. It has also something to do with almost all the individuals being between 45 to 46 years old. There was this feeling that <em>if not now, it will never</em> happen.</p><p>Have a great life!!</p>]]></content:encoded></item></channel></rss>