I got this error: Attribute Error: ‘type’ object has no attribute ‘datetime’.
My imports were: import datetime from datetime import datetime, tzinfo
Come to find out, using import datetime just causes problems so I removed that. That left me with ‘from datetime import datetime, tzinfo’.
Now. What the heck is the deal?
This is what. Datetime module has an object named datetime that you can use. Which is very confusing. So FROM DATETIME means that I am in the datetime module, importing datetime object to use, and from there I can just use the attributes. Instead, I was writing ‘datetime.datetime’ meaning I was already in the second level of inception (datetime > datetime) and then trying to access an attribute named ‘datetime’. So datetime.datetime.datetime.
This doesn’t work. 🙂
Just be aware of the level of the module you are in when importing and accessing attributes.
I am working with two FTP servers at work and am writing tests for the application we run on it. The test case I am handling right now involves having no application, no backup, and no valid application on the FTP server that will FTP it to the machine. I get an Updater FTP error. After 1s, 2s, 3s, 1m, 10m, and 1 hour it will reboot the machine and since I only have it in the log files to prove that, I need to have the test know when this reboot happens. So I am pinging the machine once a sec for 4,266 seconds and when it goes offline, it will return false.
I encountered a problem I want to document for the future in case anyone else or myself forgets this will happen.
On any other machine, a ‘Destination Host Unreachable’ error will be False, but if you specify identifying the machine as Windows, it will still return true.
I have been waiting for this course to come out for the past six months and now it is here! I was able to get a 50% off on the course so that was really helpful. So far, the course has been amazing and I have built my first app, a dice roller!
This is what I have learned in my first course. I am posting this as reference to myself later.
Namespaces – tools – define dummy content that is only used when you preview the app in the preview pane
Attr using the namespace tools will be gone when the app compiles
Two namespaces at top: tool and android. Android is part of the core framework.
Gradle determines what devices can run your app, compiles app to executable, handles dependency management, automated testing, and app signing for Google play. Gradle packages your app into an apk with its resources, compiled code, Android manifest, etc and then transfers the apk to your emulator or device.
There are two Gradle files: build.gradle (project) and build.gradle (app). The app gradle file handles your different modules that has different functionalities, libraries, and supporting android wearables. In larger apps, each module will have its own gradle file. Inside the Gradle project file, there are repos that are available to the whole project: google() and jcenter().
Gradle also handles all the dependencies which is external code and libraries a project depends on. These are handled in the dependencies block.
dependencies are managed here
app dependencies do not go here
The app folder gradle file configures how to set up the app module and deals with the plugins to run and build Android and kotlin projects. This also tells the app the compilesdk, targetsdk, and minsdk. These are pretty straighforward. Min is the minimum version it can run on. The target will always match the compilesdk. This also has the appID which is a unique identifier and necessary for Google Play. It is the domain your app is hosted on, reversed, followed by the app name. So if my app was hosted on elyse.com and my app is named diceroller, it would be com.elyse.diceroller. This is set up when the project is started.
The version level you lists matches to an API level, and all api levels are named after tasty treats.
ANDROID JETPACK is the new android support libraries – androidx – and has all the support libraries for new and old apis.
APPCOMPATACTIVITY – The main activity extends from this. It is a compatibility class that makes sure activity includes a menu bar (action bar) that looks the same across OS levels and is a part of androidx. I never knew exactly what this was, so this was helpful.
Adding Vector Drawables: The proper way to use vector drawables and keep compatibility with older versions of android is followed.
In Gradle build.app file – under default config add vectorDrawables.useSupportLibrary = true.
Add app:srcCompat=”@drawable/image_name” in the ImageView tag
Add the namespace to the root of the layout xmlns:app="http://schemas.android.com/apk/res-auto"
This is using the support library to reference the image resource in the layout file and enable the support library for vector drawables in the app level build.gradle
THIS OPTIMIZES APP SIZE ON OLDER PLATFORMS
Open drawable (dice.xml) to see the colors and shapes listed in xml
build.gradle app file will generate png files that are use on those devices that are below minsdk. Png files will make app larger and make it slower. Large apps have high chance of being uninstalled. Androidx compat library supports devices all the way back to api level 7.
Adding app namespace supports either custom code or libraries in your project and not core android libraries.
Dependencies required to build the project or enable additional functionality are defined in the build.gradle.
Basic app structure: Layouts – xml files the define what your app will look like Activites – Kotlin classes where you write the dynamic parts of your app Layouts and activities are connected by the process of layout inflation – and finding view objects by their unique id TextView – displays text to the user ImageView – display images to the user Images are a drawable resource type.
Build gradle project in command line: Change the directory of your project. Type gradle run. You can also include gradle run –warning-mode=all to see specific warnings. Or you can type gradle tasks –info. Shows all tasks and what they are doing.
Explain software testing and two other means of quality assurance and how they are applied.
Using software tests and analyzing code coverage is one software testing technique, but that is not the only way to test the quality of the software. Testing is often thought to be just running unit tests or executing test suites, but the reality is that testing has an entire life cycle of its own, very similar to the Software Development Life Cycle. This life cycle means the entire testing approach is a multi-faceted process and has many techniques. Testing is not only about making tests pass, but provides information about the software in terms of finding defects, isolating failures, preventing future defects, gaining confidence in the quality of the system, and meeting entry and exit criteria specifications according to standards, policies, laws, or requirements. Three techniques I want to explain are Test Plan, Regression Testing, and Exit Criteria.
A Test Plan is very important to a project. This plan is document outlining the scope, approach, resources, and schedule of intended test activities. It also outlines who will be doing the testing, when they will do it and degree of autonomy, test design techniques, and entry and exit criteria (Black, 2012). It outlines the entire process and enables testers to start testing early, which prevents exponential costs by having to fix a problem in production. A plan helps identify any weaknesses in the strategy so the team can plan accordingly.
Regression testing is very simple to explain. Once you have all passing tests and the software has been modified by the team or a feature has been added, those same tests will be ran first to make sure that the new code did not break anything that was previously working. If any defects have been introduced, this will identify them (hopefully).
Lastly, exit criteria is important for testing. This criteria is previously agreed on by the stakeholders and allows a project or task to be complete. This protects the stakeholders by not allowing a task to be completed when there are still parts incomplete and also gives the software developers a set of metrics to gauge the software against to know when to end the task and when to stop testing.
This is three test strategies that are common in testing, but testing will be unique in every situation. For example, software that is used where lives are at risk have a more complete and exhaustive list of testing strategies than a game we play on our phone. Keeping this in mind will help see that testing is a very organic process and can be built to assure the level of quality needed for each project.
Black, R. Foundations of Software Testing ISTQB Certification. [Capella]. Retrieved from https://capella.vitalsource.com/#/books/9781305175594/
Testing can focus on various aspects of a system or software. These aspects can include a focus on functionality, or what the system does, or on non-functionality, how the system does it what it does. It can also include testing on the system’s structure, changes to the system, if changes are successful, and if any unintended side effects happened. These four levels of test types are called functional, non-functional, structural, and change related. In this post, I will examine functional testing and testing pertaining to changes.
Functional testing involves testing the specified behavior or “what it does” and may be performed at all test levels. Specification-based testing is also known as “black-box testing” since it tests without reference to the internal structure of the component or system (Black, 2012). The testing focus for functionality testing is usually suitability, interoperability, security, accuracy, and compliance, according to ISO 9126 standards. There are two main approaches to using this test type: requirements-based or business-process based.
Requirements-based testing can take the requirements from the table of contents of a specification document and use them as a test basis for creating the tests. Business-based requirements are focused more on use cases from business processes. In a payroll system, for example, business processes would include when an employee joins the company or how often employees are paid.
Testing related to changes involves confirmation and regression testing. After a failed test, a defect is found and fixed. Confirmation testing involves re-testing the code in the same way and make sure that the new code did not bring in any unintended side effects and can be used at all test levels. Regression testing is used as a follow up to confirmation testing.
Regression testing involves executing test cases that have already been completed and most likely passed the last time they ran. We must organically grow the regression test suite over time in line with the software just as we do with unit tests. Should one of these tests now fail, we will have found a new defect introduced to the system. Regression testing should be performed at all test levels, specifically when a new version of the software is created, or the software environment changes.
As a programmer, we are going to be naming lots of variables, classes, and methods. According to Uncle Bob in Clean Code, we should name a variable with the same care we do in naming a first-born child. After all, we are going to need to be able to call it, know what it’s for, and not confuse it with any other variables in our classes.
When we name with care, we name with “intention-revealing” names. Naming well saves you more time in the long run, saves everyone more time, and prevents a snowball of bad things happening to your precious code. The names we choose should answer the big questions:
Why does it exist? What does it do? How is it used?
We need to be able to tell what the code is doing. In the example picture, it is very easy to see what the purpose is of the last three names versus the first name. Explicit names help immediately see what is going on in the code. If you MUST use a single letter name, it is best practice to use it as a local variable inside a short method. The length of a name should correspond to the size of its scope.
Using a name like h, we would have to mentally map what this variable is doing, translating it in our brain to what it actually does, using much more memory. Clarity is king. Use your powers for good naming practices to write code that everyone can understand. Pretend like the next person who will read your code is a violent psychopath who knows your address. It’s serious business!
Class and Method Names
This is something that needs to be written on your computer or tattooed on your arm or put anywhere you can see it, like an affirmation you are practicing, only programmer edition.
Class names should have a noun or noun phrase. Class names should not be verbs.
Methods should have verb or verb phrases. Accessors, mutators, and predicates should be named for their value and prefixed with get, set, and is according to the javabean standard. (“Oracle Java Technologies | Oracle,” 2019).
Don’t be cute in naming. Clever names are memorable only to people who share the same humor and some of us are the only ones laughing at our jokes. I know I’m funny, but others may not think so. Clarity is more important than entertainment. Our cleverness only goes so far as our cultural slang. Naming something dirtNap() meaning kill() or wipeout() meaning DeleteItems() is cute, but the latter is understood by all. A consistent lexicon is worth its weight in gold for the programmers who must use your code.
Other Important Naming Concepts
Pick one word for an abstract concept and stick with it. Using fetch, retrieve, and get as similar methods in different classes goes back to using too much mental memory. Ask yourself some questions about what these methods are doing and see if they are all serving the same purpose to choose an appropriate word.
Don’t Pun. Converse to using one word per abstract concept, do not use the same word for two purposes. Doing so would be a pun. Using “one word per concept”, could end up with a lot of classes using an “add” method as described in the book. If we are using the word for consistency rather than intent, it can get very confusing. Ask yourself what the method is actually doing so you know if you need to name it “insert” or “append”.
Use Solution Domain Names. Programmers will be reading your code so go ahead and use terms that other programmers understand like algorithm names, math terms, and pattern names.
Use Problem Domain Names. Problem domains refers to all the information that defines the problem (i.e. the problem you are solving with code). If there are no programming or computer science terms for what the code is doing, use the name from the problem domain. Good programmers and designers have the important task of separating solution and problem domain concepts.
Add Meaningful Context, But Not Gratuitous Context. Most of the time we have successfully added meaningful context by using good naming, separation of concerns, and well-defined classes. As a last resort, you may have to add some prefixing. If you saw firstName, lastName, street, houseNumber, city, state, and zipcode in a method, you would assume it’s an address. If city was used alone in a method, would you assume it’s part of an address? The context can be added by prefixing with addrState, addrCity, etc so it’s explicitly part of an address.
This doesn’t mean to do this always. Adding gratuitous context can be very confusing, like prefixing every method with the acronym of the application. “ABCFirstName, ABCLastName, ABCStreetAddress” are too much. Shorter names are generally better than long ones when they are clear.
Following some of these rules and asking yourself the important questions about your code will help get you thinking about what and why you are naming things and keeping the code understandable for all, saving you many headaches in the future. Happy coding!
I just wanted to share something I find really valuable. When people say “Don’t Put It Off”, but you’re a chronic procrastinator, it’s easy to get stuck into this cycle of guilt and shame for not doing anything, draining yourself with stress, feeling guilty, and then not doing anything about it.
Don’t beat yourself up because you procrastinate. I challenge you to ask yourself, “Why?”. Why are you waiting? You’ll be surprised at the answers that start spilling out of your brain. “I’m afraid they won’t like me”, “I’m afraid I don’t know enough”, “I don’t know how”, “what will others think?”, “I don’t have enough time”. What if you already knew how? Explore those thoughts and think what is really holding you back on whatever is important to you? Would failing be worse than never doing it? I didn’t think so. Most of the time I regret the things I haven’t tried more than I regret the things I have done.
If your fear is of embarassing yourself, think of this. Can you think of a time you embarassed yourself? Totally. I once opened the door of our neighbor’s camper in a sleepy stupor one morning after going to the restroom, and the neighbor was laying there spread eagle in his underwear. Whoops! Now, can you think of many times when someone else embarassed themselves? Bet you cannot. Embarassment is a personal experience and no one is feeling it along with you.
Remember that the next time you choose to do something scary and do it anyway. You will not regret it.
I had an amazing experience this year to be on the We Belong Here Podcast with Lauren Lee Anderson (@lolocoding on Twitter).
I had heard a lot of podcasts about how they career transitioned from one career that was totally different and into tech. I didn’t hear a lot about the dark side of transitions. Transitions that come from dark, personal, life-changing experiences. My past is dark.
I got very vulnerable in this podcast to show others that it is your thoughts that allow you to keep going, a desire that keeps you going, knowing what you don’t want in your life that keeps you going.
Roadblocks happen, I believe they are supposed to. Success isn’t linear and those roadblocks build your resiliency. If you struggle with wondering if you can make it, you can. Have a listen.
I would love to hear your stories of how you overcame your obstacles!
I was asked how to get back into working in technology. While I haven’t had my first official job yet, I have been getting ready to apply for three years while I have been in school. They asked about knowing data structures and algorithms and these are the thoughts I had:
For whiteboarding interviews, they are kind of necessary to know. There are resources on how to prep for technical interviews. I recommend www.pramp.com which gives a free practice technical interview to see where your strengths are and what you could improve on.
In my personal experience so far, I have been networking a lot on Twitter and in my town, going to meetups and talking to people hosting them about jobs at their company. A lot of jobs are not posted on job boards and finding the job you like is usually done by word of mouth and or talking to people. A lot of “who you know” can come really handy in your position. If you started attending meetups regularly and talking to people and asking questions, you will be able to get a feel for what jobs are requiring what.
Fundamentals of Java and basic algorithms like LinkedList, B-tree, Bubble sort, Stack, Queue, Hash Tables, are all really helpful to know. Being able to explain them are very useful.
For practicing coding challenges to level up your skills, codegym.cc, leetcode (good for algorithms), codewars, and hyperskill.org are all really good ones for java.
Having projects that you are proud of on your resume (2 is good for a resume), being able to explain what you did, what your challenges were, how you overcame them, and what you would do differently in future revisions are important. Making a demo of them and putting it on your github in the readme is awesome. Having a good readme is important so they can look and see what your project is about. I put hyperlinks right into my resume so they are able to click them from a pdf. You can find the template for a good readme here: https://gist.github.com/PurpleBooth/109311bb0361f32d87a2.So I know that was a lot of info so I will make it a shorter list:
Network with people online and Twitter and have conversations about their company to find out about jobs and what the requirements are. The more people you can talk to, the better.
Go to meetups and present a talk. There are so many things to talk about. Like a specific Java component and all the different ways to implement it.
CodeWars, LeetCode, Codegym.cc, and HyperSkill.org are good resources for furthering your skills and algorithms.
Showcase your best work by putting the projects on your resume, have a good readme, and a demo of your project along with what you did, why you did it, what your challenges were, and what you would do differently.
Practice technical interviews on www.pramp.com. Even asking on Twitter if someone would be wiling to do a practice tech interview could help get feedback. Pramp does unlimited tech interviews. They do data structures and algorithms, system design, frontend, data science, and product management interviews. So practice practice practice and see where you are in terms of interviewing.
Have a well written resume. There are lots of resources on PowerToFly.com about how to write a good resume.