text:
<repo_name>GuanZihan/Data-Analysis<file_sep>/UCL SS/report.Rmd
---
output:
  html_document:
    df_print: default
    toc: yes
---

<meta name="viewport" content="width=device-width, initial-scale=1">
![avatar](store.png)

 Google Play Store Data Analysis Report

## 0. Introduction
This data set is scraped from Google Play Store. There are 13 features that provide detailed information about App in Google Play Store, including the name, category, Rating, Reviews and so on.

In the report, I'm going to analyze the data in the following 5 aspects:

1. **Import packages**: set up the environment for the whole project

2. **Exploratory Data Analysis**: Analyze and visualize the data

3. **Linear Model Analysis**: use linear model to fit the data

4. **Tree-based Model Analysis**: use tree-based model to fit the data

5. **Summary**: Make a conclusion

In this data set, I want to find how to predict game **reviews**(continuous,linear model) and **Installs**(discrete,tree-based model) using the known information.

## 1. Import Packages
```{r,message=FALSE,warning=FALSE}
# creat a new environment
rm(list=ls())
# import packages
library(MASS)
library(readr)
library(ggplot2)
library(corrplot)
library(Amelia)
library(reshape2)
library(caret)
library(caTools)
library(dplyr)
library(tidyr)
library(plotly)
library(texreg)
library(reshape2)
library(leaps)
library(rpart)
library(rpart.plot)
library(e1071)
google_data <- read_csv('googleplaystore.csv')
head(google_data)
```
## 2. Data Cleaning
- Draw the data missmap
- Change data type
- Get the summary of data
```{r,message=FALSE,warning=FALSE}
# Draw the data missmap
missmap(google_data, legend=FALSE)
```

The main NA data are in the 'Rating' column, so we decided to use drop_na() function to drop the row containing NA data.
```{r}
# drop the null data from the original data set
google_data <- drop_na(google_data)
# see first few lines of data
head(google_data)
# see the data type of the data set
str(google_data)
```
As we directly import the data set from csv. file, the data type of these columns are wrong. We need correct them manually.
```{r}
# change data type of the original data set
google_data$App <- as.character(google_data$App)
google_data$Reviews <- as.numeric(as.character(google_data$Reviews))
google_data$Price <- as.numeric(as.character(google_data$Price))
google_data$Size <- as.numeric(google_data$Size)
google_data$`Current Ver` <- as.character(google_data$`Current Ver`)
google_data$`Android Ver` <- as.character(google_data$`Android Ver`)
google_data$Category <- as.factor(google_data$Category)
google_data$Genres <- as.factor(google_data$Genres)
google_data$`Content Rating` <- as.factor(google_data$`Content Rating`)
google_data$Installs <- as.numeric(google_data$Installs)
google_data <- google_data[-which(names(google_data)=='Type')]
# get a summary information of the data set
summary(google_data)
```

```{r}
#since there are some blanks in the name of features, we decided to rename it
data <-rename(google_data,content_rating=`Content Rating`, Android_ver= `Android Ver`,current_ver = `Current Ver`)
head(data)
```

## 3. Exploraroy Data Analysis
We intend to analyze the data in the following aspects

- The category with highest market share
- The distribution of Apps
- The rating in different categories
- The reviews in different categories

### The category with highest market share in the market
```{r}
attach(google_data)
# Compute Market Share of every Categories
share_count <- c()
index <- 1
# the loop is to calculate the market share of every category
for( i in levels(Category)){
  temp_df <- google_data[which(Category == i),]
  share_count[index] <- dim(temp_df)[1]
  index <- index + 1
}
df <- data.frame(levels(Category),share_count)
df <- df[order(df$share_count,decreasing = TRUE),]
p <- plot_ly(df,labels=~levels.Category.,values=~share_count,type='pie')
p

```
**Finding**

1. nearly half of the market share was dominated by games from
**'Family'(20.9%),'Game'(12.6%),'Tools'(8.16%), 'Medical'( 4.22%),'Lifestyle'(3.63%)** categories.

2. the distribution of market share is uneven. the gap between the best and the worst category is very large

### The distributions of Apps
```{r,message=FALSE,warning=FALSE}
# draw the ggplot image
# image_2 is the distribution of App rating
image_2 <- ggplotly(ggplot(google_data, aes(x=Rating)) + geom_area(stat="bin",fill='#1E90FF') +geom_vline(xintercept = mean(Rating),col='red',lty=3,lwd = 1 )+xlab("Rating Score")+ylab("Number of App") +theme_bw() +theme(plot.title = element_text(hjust = 0.5),axis.text.y = element_text(angle=90,hjust=1)))
# image_3 is the distribution of App reviews
image_3 <- ggplotly(ggplot(google_data, aes(x=Reviews)) + geom_area(stat="bin",fill='#98FB98') +geom_vline(xintercept = mean(Reviews),col='red',lty=3,lwd = 1 )+xlab("Reviews Amount")+ylab("Number of App") + ggtitle("Distribution of Different Features") +theme_bw() +theme(plot.title = element_text(hjust = 0.5),axis.text.y = element_text(angle=90,hjust=1)))
# image_4 is the distribution of App size
image_4 <- ggplotly(ggplot(google_data, aes(x=Size)) + geom_area(stat="bin",fill='#DAA520') +geom_vline(xintercept = mean(Size),col='red',lty=3,lwd = 1 )+xlab("Reviews Amount")+ylab("Number of App") +theme_bw() +theme(plot.title = element_text(hjust = 0.5),axis.text.x = element_text(angle = 90, hjust = 1),axis.text.y = element_text(angle=90,hjust=1)))
# image_5 is the distribution of App installs
image_5 <- ggplotly(ggplot(google_data, aes(x=Installs)) + geom_area(stat="bin",fill='#D2691E') +geom_vline(xintercept = mean(Installs),col='red',lty=3,lwd = 1 )+xlab("Reviews Amount")+ylab("Number of App") +theme_bw() +theme(plot.title = element_text(hjust = 0.5),axis.text.x = element_text(angle = 90, hjust = 1),axis.text.y = element_text(angle=90,hjust=1)))
subplot(image_2,image_3,image_4,image_5,nrows=2, margin = 0.05)
```
**Finding**

1. Most apps do well in the game market and get an average score of **4.17**;the low score area and high score area are both very samll

2. Most apps receive reviews lower in the interval **[7000,300000]**

3. The size of the game is usually smalle than 100M

4. The mean install amount is **8458767**

### The rating in different categories
```{r,warning=FALSE}
attach(google_data)
# compute the average Rating score by group
cat_data <- group_by(google_data,Category)
data <- summarise(cat_data,count = n(),rating_score = mean(Rating))
# sort the data by descending order
data <- data[order(data$rating_score,decreasing = TRUE),]
# iamge_6 is the different rating grouped by 'categories'
image_6 <- ggplot(data = data,aes(x = levels(Category),y = rating_score,fill=levels(Category))) + geom_bar(stat = 'identity', position = 'dodge')+theme(axis.text.x = element_text(angle = 90, hjust = 1))+geom_hline(aes(yintercept=4), colour="white", linetype="dashed")+theme(panel.border = element_blank())+ coord_cartesian(ylim=c(3.5, 4.5)) +xlab("Categories in Google Play Store")+ylab("Rating")+ ggtitle("Rating in Different Categories") +theme(plot.title = element_text(hjust = 0.5))+scale_fill_discrete(name="Category")
ggplotly(image_6)
```
**Finding**

1. There is some differece in 'Rating' among categories, but the difference is way too small

2. 'Art and Design' Category always has the highest Rating score, and 'Auto and Vehicles' Category cathes up

### The reviews in different categories
```{r}
# calculate the reviews grouped by 'categories'
cat_data <- group_by(google_data,Category)
cat_data <- summarise(cat_data,count = n(),reviews = sum(Reviews))
# 'p' respresents 'Reviews' grouped by 'categories'
p <- google_data %>%
  plot_ly(
    x = ~Category,
    y = ~Reviews,
    split = ~Category,
    type = 'violin',
    box = list(
      visible = T
    ),
    meanline = list(
      visible = T
    )
  ) %>%
  layout(
    title = "Reviews in Different Categories",
    xaxis = list(
      title = "Categories in Google Play Store"
    ),
    yaxis = list(
      title = "Reviews",
      zeroline = F
    )
  )
p
```
**Finding**

1. Almost all app categories perform decently. Health and Fitness and Books and Reference produce the highest quality

2. apps with 50% apps having a rating greater than 4.5.

3. On the contrary, 50% of apps in the Dating category have a rating lesser than the average rating.

```{r}
# Fitted line by 'Rating' and 'Reviews'
line_1 <- lm(Rating~Reviews,data = google_data)
new <- data.frame(google_data$Reviews)
y <- predict(line_1,newdata = new)
p <- plot_ly(data = google_data, x = ~google_data$Reviews, y = ~google_data$Rating,type = 'scatter',name='Actual Points') %>%add_trace(y = ~y, name = 'Linear Regression', mode = 'lines')%>%
  layout(
    title = "Rating vs Reviews",
    xaxis = list(
      title = "Reviews"
    ),
    yaxis = list(
      title = "Rating",
      zeroline = F
    )
  )
p
```
**Finding**

1. Rating and Reviews seems not have a very strong relationship

2. The fitted line shows that every increase in Reviews only leads to limited increase in Rating score

```{r}
# change the data type and pick the numeric ones from all the columns
google_data$Category <- as.numeric(google_data$Category)
google_data$Genres <- as.numeric(google_data$Genres)
google_data$`Content Rating` <- as.numeric(google_data$`Content Rating`)
google_num <- select_if(google_data,is.numeric,genres = google_data$Genres,content_rating = google_data$`Content Rating`)
google_num <- mutate(google_num,Category=google_data$Category)

```

### T Test
**Claim:The average value of 'rating' equals to 4**
```{r}
# Test if the average value of 'rating' equals to 4
t.test(Rating,mu = 4,alt = "two.sided", conf=0.95,data=google_data)
```
**Finding**

1. p-value in T-Test is less than 0.05, which means our claim can be accepted in the 95% cofidencee interval

## 4. Linear Model Analysis
- Correlation Map
- Polynomial Model
- polynomial Model with interactions
- T Test
- compare the modles in 2 and 3
- visulaize the performance of the two models

### Correlation Map
```{r}
#draw the correlation map of different features in numeric columns of google_data
cor_google <- cor(google_num)
melted_cor <- melt(cor_google)
cor_image <- ggplot(data = melted_cor, aes(x=Var1, y=Var2, fill=value)) + geom_tile() +xlab("")+ylab("")+ ggtitle("The Correlation of Different Features") +theme(plot.title = element_text(hjust = 0.5))
ggplotly(cor_image)
```
Here I change the data type of some columns again and visulaize the correlation of them using the map above
The brighter the square is, the higher relationship the two features will be.

**Finding**

1. 'Reviews and Installs' / 'Genres and Category' have a significant positive relationship

2. Most of the features are not so tightly correlated

### Polynomial Model
```{r}
#set a seed
set.seed(123)
#Split the data to train set and test set
split = sample.split(google_num,SplitRatio =0.75)
train = subset(google_num,split==TRUE)
test = subset(google_num,split=FALSE)
set.seed(123)
train.control = trainControl(method = "repeatedcv",
                              number = 10, repeats = 3)

regsubsets.out <- regsubsets( Reviews ~ .,
                              data = train,
                              nbest = 1,
                              nvmax = NULL,
                              force.in = NULL, force.out = NULL,
                              method = 'forward')
summary(regsubsets.out)
model_1 <- lm(Reviews ~.-Price,data=train)
# use train_validation method to train linear model
model_1_cv= train(Reviews ~.-Price , data = train, method = "lm",
               trControl = train.control)
model_1_cv
```
Here I splitted the original data set into train set and test set, and use foward mothod to see what the best polynomial model is

**Finding**

1. The image tells us that the best polynomial model should have all the variables except 'Price'

2. The performance of the model is so so, reaching **0.46** in R-squared

### Polynomial model with interactions
```{r}
# since the pure polynomial model can not fit the data very well, we try to add some interactions into the model
# Since there is strong relationship between Reviews and Installs, we try to add this first
model_2 <- lm(Reviews ~ Size*Installs+`Content Rating`+Genres+Category,data=train)
# model_2_cv considerates the interaction between different features
model_2_cv= train(Reviews ~ Size*Installs*Rating, data = google_num, method = "lm",
               trControl = train.control)
model_2_cv
```
**Finding**

1. The performance of the model is far better than the previous one, reaching **0.60** in R-squared

### Compare the two models
```{r}
# In order to know the performance of the two models, we use anova function to get F-Test
anova(model_1,model_2)
```
**Finding**

1. The p-value of the model is very low, which means the added parameter -- interaction is pretty important to imrove the performance of the model

### Visualize the performance of two models
```{r}
# visualize the performance of the model_1_cv
pred_1 <- predict(model_1_cv,test)
google_num <- mutate(google_num, pred_1 = pred_1)
image_3 <- ggplot(data = google_num,aes(x = test$Reviews, y = pred_1)) + geom_point(stat='identity')+ geom_point(stat='identity')+geom_abline(slope= 1,intercept = 0,colour='orange')+xlab("Actual Values")+ylab("Predicted Values")+xlab("Actual Values")+ylab("Predicted Values")+theme_bw()
ggplotly(image_3)
# visualize the performance of the model_2_cv
pred_2 <- predict(model_2_cv,test)
google_num <- mutate(google_num, pred_2 = pred_2)
image_4 <- ggplot(data = google_num,aes(x = test$Reviews, y = pred_2)) + geom_point(stat='identity')+geom_abline(slope= 1,intercept = 0,colour='orange')+xlab("Actual Values")+ylab("Predicted Values")+theme_bw()
ggplotly(image_4)
```
Here the two images show the different performance of Linear Model
Apparently the second(with interactions) is fat better than than the first one

## 4. Tree-based Model Analysis
- Decision Tree
- Confusion Matrix I
- Random Forest
- Confusion Matrix II

### Decision Tree
```{r,fig.width=7, fig.height=8}
#Since 'Installs' is the dicrete data, we want to predict the installs an App will be(eg:500+, 5000+)
train <- mutate(train,Installs= as.factor(Installs))
# set up a tree classification
classifier_tree = train(Installs ~Reviews+Rating+Category+Size+Genres, data = train, method = "rpart",parms = list(split = "information"),trControl=train.control,tuneLength = 10)
# visualize the tree model
plot(classifier_tree$finalModel)
text(classifier_tree$finalModel)
# use prp function to visualize the tree model
prp(classifier_tree$finalModel, box.palette = "Reds", tweak = 1.2)
# print the detailed information about tree model
print(classifier_tree)
```

### Confusion Matrix
```{r}
y_pred = predict(classifier_tree, newdata = test)
df<-data.frame(table(test$Installs, y_pred))
df <- mutate(df,Var1 = as.numeric(Var1),y_pred=as.numeric(y_pred),error=Freq)
# cor_image is to visualze the confusion matrix of decision tree model
cor_image <- ggplot(data = df, aes(x=Var1, y=y_pred, fill=error)) + geom_tile() +xlab("Actual Values")+ylab("Predicted Values")+ ggtitle("Confusion Matrix") +theme(plot.title = element_text(hjust = 0.5))
ggplotly(cor_image)
error <- mean(test$Installs != y_pred) # Misclassification error
paste('Accuracy',round(1-error,4))
```

### Decision Tree(Pruned with Length 5)
```{r}
classifier_tree = train(Installs ~Reviews+Rating+Category+Size+Genres, data = train, method = "rpart",parms = list(split = "information"),trControl=train.control,tuneLength = 5)
# visualize the tree model
plot(classifier_tree$finalModel)
text(classifier_tree$finalModel)
# use prp function to visualize the tree model
prp(classifier_tree$finalModel, box.palette = "Reds", tweak = 1.2)
# print the detailed information about tree model
print(classifier_tree)
```

### Confusion Matrix
```{r}
y_pred = predict(classifier_tree, newdata = test)
df<-data.frame(table(test$Installs, y_pred))
df <- mutate(df,Var1 = as.numeric(Var1),y_pred=as.numeric(y_pred),error=Freq)
# cor_image is to visualze the confusion matrix of decision tree model
cor_image <- ggplot(data = df, aes(x=Var1, y=y_pred, fill=error)) + geom_tile() +xlab("Actual Values")+ylab("Predicted Values")+ ggtitle("Confusion Matrix") +theme(plot.title = element_text(hjust = 0.5))
ggplotly(cor_image)
error <- mean(test$Installs != y_pred) # Misclassification error
paste('Accuracy',round(1-error,4))
```

### Random Forest
```{r,warning=FALSE}
mtry = sqrt(ncol(train))
tunegrid = expand.grid(.mtry=mtry)
metric = "Accuracy"
# set up a random forest model to predict installs
classifier_rf = train(Installs ~Reviews+Rating+Category+Size+Genres, data = train, method = "rf",
                      metric=metric, tuneGrid=tunegrid, trControl=train.control,  tuneLength = 5)
# print detailed information about random forest model
print(classifier_rf)
```

### Confusion Matrix II
```{r warning=FALSE}
y_pred = predict(classifier_rf, newdata = test)
# Checking the prediction accuracy
df<-data.frame(table(test$Installs, y_pred)) # Confusion matrix
df <- mutate(df,Var1 = as.numeric(Var1),y_pred=as.numeric(y_pred),error=Freq)
cor_image <- ggplot(data = df, aes(x=Var1, y=y_pred, fill=error)) + geom_tile() +xlab("Actual Values")+ylab("Predicted Values")+ ggtitle("Confusion Matrix") +theme(plot.title = element_text(hjust = 0.5))
ggplotly(cor_image)
error <- mean(test$Installs != y_pred) # Misclassification error
paste('Accuracy',round(1-error,4))
```

## 5. Summary

From the analysis report above, we have got 4 models already. let's do some comparison between the models

1. Linear Model

- anova test tells us already that polynomial model with interactions is better than polynomial model

- compared to the previous one, the new model has a higher r-square, which means that it can explain more data

2. Tree-based Model

- based on confusion matrix, we could find that Random Forest Model performs better than Decision Tree Modle

- The Missclassfication error of random forest model is far less than the decision tree model

- Thus we could make a conclusion that random forest is a better model

Potential Next Steps:

1. evaluate the tree model using more metrics

2. Analyze the categorical variable and see if there are some correlationship among them. (Maybe NLP if possible)

<file_sep>/Dalian Thermoelctric Projects/demo.py
#encoding=utf-8
import pandas as pd
import matplotlib.pyplot as plt
import re
import requests
from pylab import mpl
from pyecharts import Geo
from pandas import DataFrame,Series

#读取数据
mpl.rcParams['font.sans-serif'] = ['SimHei']
data = pd.read_excel('1.xls',header=0,index_col='location',sheet_name='压力')
data_flow = pd.read_excel('1.xls',header=0,index_col='location',sheet_name='流量')
data_tem = pd.read_excel('1.xls',header=0,index_col='location',sheet_name='温度')
data_sum = pd.read_excel('2.xls',header=0,sheet_name='东网',usecols=[4,5,6])
locations = pd. read_excel('1.xls',header=0,usecols=[0])
data = data.fillna(0)

#全局变量放在这
location=[]
place_pressure=dict()
place_20 = dict()
time_pressure_mean=[]
time_flow_mean=[]
time_tem_mean=[]
ak='<KEY>'
lng_lat={}
#获取百度经纬度
def getCoordinate(place):
    place_dalian = "大连市" + str(place)
    url = 'http://api.map.baidu.com/geocoding/v3/?address=' + place_dalian + '&output=json&ak=' + str(
        ak) + '&callback=showLocation'
    r = requests.get(url).text
    lng = eval(re.findall('lng":(.*?),"', r)[0])
    lat = eval(re.findall('lat":(.*?)},"', r)[0])
    return lng,lat
#取得建筑物名字
def getLocation():
    for index,value in locations.iterrows():
        location.append(value['location'])
    return location
#GIS图
for place in getLocation():
    mean_pressure = data.loc[[place]].T.mean().loc[place]
    place_pressure[place]=mean_pressure
lng, lat =getCoordinate(place)
lng_lat[place] = [lng,lat]
net_map = list(zip(place_v.keys(), place_v.values()))
geo = Geo(u"全国主要城市影院数量分布", "data from dydata", title_color="#fff",
                title_pos="center", width= 1200, height=600, background_color='#404a59')
attr, value = geo.cast(net_map)
geo.add("cinema_distribution", attr, value, type="heatmap", visual_range=[0, int(max(value))+1],
                visual_text_color="#fff", symbol_size=12, is_visualmap=True, geo_city_coords=lng_lat)
geo.render("cinema_distribution.html")

#管网节点-压力图
place_v = sorted(zip(place_pressure.values(),place_pressure.keys()),reverse=True)
for i in place_v[1:21]:
    num = float(str(i).split(', ')[0].replace('(',''))
    place_name = str(i).split(', ')[1].replace("')",'').replace("'",'')
    place_20[place_name] = num
DataFrame([place_20.keys()]).to_excel('3.xls')

DataFrame([place_20.values()]).to_excel('4.xls')

plt.figure()
plt.subplot(212)
plt.plot(place_20.keys(),place_20.values())
plt.xticks(rotation=45)
plt.ylabel('管网日均压力')
#时间-压力图
for i in range(0,24):
    time_pressure_mean.append(data[i].mean())
plt.subplot(231)
plt.plot(time_pressure_mean)
plt.plot(data_sum['pressure'],color='black')
plt.xlabel('时间')
plt.ylabel('管网平均压力')
#DataFrame(time_pressure_mean).to_excel('5.xls',sheet_name="压力")
#时间-流量图
for i in range(0,24):
    time_flow_mean.append(data_flow[i].sum())
plt.subplot(232)
plt.plot(time_flow_mean,color='green')
plt.plot(data_sum['flow'],color='black')
plt.plot(data_sum['flow']-time_flow_mean,color='blue')
#DataFrame(time_flow_mean).to_excel('6.xls',sheet_name="流量")
plt.xlabel('时间')
plt.ylabel('管网平均流量')
#时间-温度图
for i in range(0,24):
    time_tem_mean.append(data_tem[i].mean())
plt.subplot(233)
plt.plot(time_tem_mean,color='red')
plt.plot(data_sum['tem'],color='black')
#DataFrame(time_tem_mean).to_excel('7.xls',sheet_name="温度")
plt.xlabel('时间')
plt.ylabel('管网平均温度')

plt.show()

languages: RMarkdown Python

repo_language: RMarkdown

repo_name: GuanZihan/Data-Analysis


text:
<file_sep>/**
 * For each of the following Array methods,

 * 1. use them in an example
 * 2. use console.log() to make the code run in the console!

 **/

 let letters = ['b', 'c', 'd', 'e']
 let numbers = [2, 3, 4, 5]

 .sort(letters)
 console.log(letters)

 let greet = 'Hello, my darling'
 console.log(greet.concat(' ' + 'Jenell' + '!'))

 console.log(numbers.indexOf(4))

 console.log(greet.split(''))

 letters = letters.join()
 console.log(letters)

 console.log(numbers.pop('a'))

 numbers.push(5)
 console.log(numbers)

 console.log(numbers.slice(1, 2))

 console.log(numbers.splice(1, 2))

 console.log(numbers.shift())

 console.log(numbers.unshift())

 function biggerThan (value) {
   return value >= 28
 }
 let filtered = [82, 35, 12, 29.5, 7, 8].filter(biggerThan)
 console.log(filtered)

 let newNumbers = numbers.map(function (number) {
   return newNumbers * 2
 })

 console.log(newNumbers)
// .map()

branch_name: refs/heads/master

repo_language: JavaScript

repo_name: nellarro/coding-katas


text:
<file_sep>https://lauren-lovato.github.io/advanced_class/Week_3/Assignment3_Week3.html
#5 answer: When you try to set viewingMode = "local" it just shows a map without the 3D buildings.
In ArcGIS online, when adding a local scene layer it says that the buildings cannot be added, because "geographic coordinate systems are not supported for a Scene Layer in local scenes".
#6 challenge attempt - tried it but couldn't get it to work, don't think the feature layer works
<file_sep>## Project 2
### Option 1 - Understand the Fragile States Index
The Fragile States Index is an open source dataset that ranks the fragility of the countries of the world. The FSI data is available as CSV files that ranks the countries in terms of fragility but also provides metrics on other aspects of each country's health, such as the economy, human rights, and political division. For this project, I want you to create a well documented Jupyter Notebook where you:
  * Publish each FSI CSV file as a uniquely named feature service.
  * Create a webmap containing each feature service symbolized so that I can tell which countries are worse and which are better.
  * Describe the process and data along the way.
  * Please be as concise as possible with your code. Use for loops where possible rather than repeating code. If you do all of these things, you will get an A

If you want an A+, please complete one of the following additional tasks. Either:
  * Create a Storymap from your FSI Webmaps where your storymap has a new page for each year (this can be done manually, i.e. without Python).

Web Map: http://slustl.maps.arcgis.com/home/item.html?id=8a850244b78e4d9fa3b9608e9de94dbd
Web Map for Story Map (changed colors): http://slustl.maps.arcgis.com/home/item.html?id=58c812476cb9412f897223cc67fdf324
Story Map: https://slustl.maps.arcgis.com/apps/MapJournal/index.html?appid=1e363e0b5ce541de868938c59c0febad
<file_sep>Interactive WebApp of features on Mars, created using ArcGIS JavaScript API: https://lauren-lovato.github.io/advanced_class/USGIF_test/MarsWebApp_USGIF.html
<file_sep>Assignment 4, Week 4

Q1: https://lauren-lovato.github.io/advanced_class/Week_4/Assignment4_Q1.html
Q2: https://lauren-lovato.github.io/advanced_class/Week_4/Assignment4_Q2.html
Q3: https://lauren-lovato.github.io/advanced_class/Week_4/Assignment4_Q3.html
<file_sep>Project 1
Create 2 WebApps from similar datasets
  * Dataset 1: Points of riding stables and barns in the St. Louis area, taken from Goldenhorseshoe Tack Shop list of Boarding Barns: https://www.goldenhorseshoetack.com/boarding-barns, and own knowledge.
  * Dataset 2: Polygons of St. Louis Metro area counties from U.S. Census Bureau: https://www.census.gov/geo/maps-data/data/cbf/cbf_counties.html

Leaflet WebApp: https://lauren-lovato.github.io/advanced_class/Project1/leaflet_STLStables.html
ArcGIS JavaScript API WebApp: https://lauren-lovato.github.io/advanced_class/Project1/ArcGISJavaScriptAPI_STL_stables.html
<file_sep>Week 2, Assignment 2
Q1 Part 1: https://lauren-lovato.github.io/advanced_class/Week_2/Assignment2_Webmap.html
Q1 Part 2: https://lauren-lovato.github.io/advanced_class/Week_2/Assignment2_layer.html
Q2: https://lauren-lovato.github.io/advanced_class/Week_2/Assignment2_Q2.html
Q3: https://lauren-lovato.github.io/advanced_class/Week_2/Assignment2_Q3.html
Q4: https://lauren-lovato.github.io/advanced_class/Week_2/Assignment2_Q4.html

repo_language: Markdown


text:
<file_sep>/* Compile:
**     + gcc   -o magnet{,.c} -W -Wall -O2 -g -lfcgi -llua -lm -ldl -pedantic -ansi -std=c89 -flto -fstack-protector-all
**     + clang -o magnet{,.c} -W -Wall -O2 -g -lfcgi -llua -lm -ldl -pedantic -ansi -std=c89
**   Notes:
**     + clang does not accept -flto for link-time optimization
**     + Enable the directory listing function with -DDIRLIST
*/

/* {{{1 Header Includes */

/* {{{2 Header conditional for DIRLIST */

#if DIRLIST
#	if _BSD_SOURCE
#	else
#		define _BSD_SOURCE
#	endif
#	include <string.h>  /* strerror() */
#	include <dirent.h>  /* scandir(), alphasort(), ... */
typedef struct dirent dirent_t;
#endif

/* }}} */

/*
#if _BSD_SOURCE
#else
#	define _BSD_SOURCE
#endif
*/

#include <assert.h>      /* assert() -- *duh*                  */
#include <stdio.h>       /* fwrite(), fprintf(), fputs(), ...  */
#include <stdlib.h>      /* EXIT_SUCCESS, EXIT_FAILURE         */
#include <string.h>      /* strdup(), strtok()                 */
#include <sys/stat.h>    /* stat()                             */
#include <fcgi_stdio.h>  /* FCGI_Accept()                      */
#include <errno.h>       /* int errno (used with stat() later) */
#include <lualib.h>      /* LUA'Y STUFF :D -S-<                */
#include <lauxlib.h>

/* }}} */

/* {{{1 Macros */

/* For getting the length of an array (obvious) */
#define LEN(array) (sizeof(array) / sizeof((array)[0]))

/* Literal array write */
#define LA_WRITE(array, fd) \
	fwrite(array, sizeof((array)[0]), LEN(array), fd)

/* LA_FCGIOUT("<NAME>")
** `--> LA_WRITE("<NAME>", FCGI_stdout)
**     `--> fwrite("<NAME>", 1, 11, FCGI_stdout) */
#define LA_FCGIOUT(array) LA_WRITE(array, FCGI_stdout)

/* LA_FCGIERR("<NAME>")
** `--> LA_WRITE("<NAME>", FCGI_stderr)
**     `--> fwrite("<NAME>", 1, 11, FCGI_stderr) */
#define LA_FCGIERR(array) LA_WRITE(array, FCGI_stderr)

/* Write a literal page with the provided mime type,
** status and message (reduces to one fwrite()) */
#define LA_PAGEOUT(type, status, message) \
	LA_FCGIOUT                                          \
	(                                                   \
		"Content-Type: "   type                  "\r\n" \
		"Status: "         status                "\r\n" \
												 "\r\n" \
		message                                         \
	)

/* Some browsers like to use their own error pages,
** this seems to only be if Content-Type == text/plain.
** You can define ERRPAGE_TYPE to whatever mime type you
** want or it will obviously use text/plain */
#if ERRPAGE_TYPE
#else
#	define ERRPAGE_TYPE "text/plain"
#endif

/*
** LA_PAGEERR("404 Not Found")
** `--> LA_PAGEOUT(ERR_TYPE, "404 Not Found", "404 Not Found")
**     `--> Content-Type: text/html\r\n
**          Status: 404 Not Found\r\n
**          Content-Length: 13\r\n
**          \r\n
**          404 Not Found
*/
#define LA_PAGEERR(status) \
	LA_PAGEOUT(ERRPAGE_TYPE, status, status)

/* }}} */

/* {{{1 File-scoped "Globals" */

static int        tostring_ref = LUA_NOREF,
           debug_traceback_ref = LUA_NOREF;

/* }}} */

/* {{{1 Helper C-Side Functions */

/*
** static int ref = LUA_REFNIL;
** if (LUA_REFNIL != reference_in_registry(L, &ref, "string.gmatch"))
**     puts("string.gmatch() is now referenced in the Lua C registry...");
** Later: lua_rawgeti(L, LUA_REGISTRYINDEX, ref); Pushed the referenced item...
*/
static int
reference_in_registry(lua_State * const L, int * const ref, const char * const findme)
{
    int n;
	char *token, *str;
    const char seps[] = ".[]\"\'";

    *ref = LUA_NOREF;

    if (findme == NULL || '\0' == *findme)
        return (*ref);

    str = strdup(findme);

	if (NULL == str)
		return (*ref);

    lua_pushvalue(L, LUA_GLOBALSINDEX);
    n = 1;

    for (token = strtok(str, seps); NULL != token; token = strtok(NULL, seps))
    {
		/* In case the strtok() implementation is non-standard and
		** it returns empty ("") strings between 2 separators. */
		if ('\0' == *token)
			continue;

        if (!lua_istable(L, -1))
            goto exit;

        lua_getfield(L, -1, token);
        n++;
    }

	/* luaL_ref() pops the last-pushed item */
    *ref = luaL_ref(L, LUA_REGISTRYINDEX);
	n--;

exit:

    free(str);
    lua_pop(L, n);
    return (*ref);
}

/* }}} */

/* {{{1 Explosed C functions */

/* {{{2 static int magnet_print(lua_State * const L) */

/* magnet_print() becomes the underlying C function for print(),
** it is equivalent to io.stdout:write(...) except that it
** calls tostring() on each arg, possibly invoking a __tostring metamethod */
static int
magnet_print(register lua_State * const L)
{
	const size_t nargs = lua_gettop(L);

	if (0 != nargs)
	{
		const char *s;
		size_t i, s_sz;

		for (i = 1; i <= nargs; i++)
		{
			lua_rawgeti      (L, LUA_REGISTRYINDEX, tostring_ref); /* Push tostring()                      */
			lua_pushvalue    (L,                 i              ); /* Push argument                        */
			lua_call         (L,                 1,            1); /* tostring(argument), take 1, return 1 */
			s = lua_tolstring(L,                -1,       &s_sz); /* Fetch result.                        */

			if (NULL == s)
				return luaL_error(L, LUA_QL("tostring") " must return a string to " LUA_QL("print"));

			FCGI_fwrite((char *) s, 1, s_sz, FCGI_stdout); /* sizeof(char) is always 1 (standard) */
			lua_pop(L, 1);                                 /* Pop result from tostring(argument)  */
		}
	}

	/* Return nothing on the -Lua- stack. */
	return 0;
}

/* }}} */

/* {{{2 static int magnet_dirlist(lua_State * const L) */

#if DIRLIST

/* Eventually I need to put a stat()-like function in here.... */

/* Example: dirlist('/home') Returns: a table of contents as strings
** I tried to follow the nil, 'error' convention on failure... */
static int
magnet_dirlist(register lua_State * const L)
{
	if (lua_gettop(L) != 1)
	{
		/* return nil, '"dirlist" must receive a string' */
		lua_pushnil(L);
		lua_pushstring(L, LUA_QL("dirlist") " must receive a string");
		return 2;
	}
	else
	{
		const char * const s = luaL_checkstring(L, 1);
		if (s == NULL)
		{
			/* return nil, '"tostring" must return a string to "dirlist"' */
			lua_pushnil(L);
			lua_pushstring(L, LUA_QL("tostring") " must return a string to " LUA_QL("dirlist"));
			return 2;
		}
		else
		{
			dirent_t **namelist;
			int n = scandir(s, &namelist, 0, alphasort);

			if (n < 0)
			{
				lua_pushnil(L);
				lua_pushstring(L, strerror(errno));
				return 2;
			}
			else
			{
				/* Create our result table. */
				lua_newtable(L);

				/* Creating the array backwards but this is okay since ipairs()
				** only uses the numerical key index to iterate forwards and
				** pairs() is order-unspecified */
				for (; n != 0; n--)
				{
					lua_pushnumber(L, ((lua_Number) n) + 1); /* Push key, + 1 because Lua arrays start at 1 */
					lua_pushstring(L,  namelist[n]->d_name); /* Push name of item.                          */
					lua_settable  (L,                   -3); /* t.key = value; pop string and number        */
					free(namelist[n]);                       /* Free as we go.... :o)                       */
				}
				free(namelist);

				/* Table is on top */
				return 1;
			}
		}
	}
}

#endif

/* }}} */

/* }}} */

/* {{{1 static int magnet_cache_script(lua_State * const L, const char * const filepath, const time_t mtime) */

static int
magnet_cache_script(register lua_State * const L, const char * const filepath, const time_t mtime)
{
	/* Return value from luaL_loadfile() */
	const int status = luaL_loadfile(L, filepath);

	/* Compile it as a chunk, push it as a function onto the Lua stack. */
	if (status)
	{
		switch (status)
		{
			/* We assume that the only reason loadfile() could
			** fail with this error is it being unreadable to us.
			** We know it exists from the successful stat() */
			case LUA_ERRFILE: LA_PAGEERR("403 Forbidden"          ); break;
			case LUA_ERRMEM:  LA_PAGEERR("503 Service Unavailable"); break;
			case LUA_ERRSYNTAX:
				fprintf
				(
					FCGI_stdout,
					"Content-Type: text/plain" "\r\n"
					"Status: 200 OK"           "\r\n"
					                           "\r\n"
					"%s"                       "\r\n",
					lua_tostring(L, -1)
				);
				break;
		}
		/* Pop luaL_loadfile()'s error message. */
		lua_pop(L, 1);
		return EXIT_FAILURE;
	}

	/* Make sure loadfile() pushed a function */
	assert(1 == lua_gettop(L));
	assert(lua_isfunction(L, -1));

	lua_getglobal  (L, "magnet"          ); /* Push magnet from _G                           */
	lua_getfield   (L,       -1,  "cache"); /* Push magnet.cache from _G                     */
	lua_newtable   (L                    ); /* Push a new table                              */
	lua_pushvalue  (L,       -4          ); /* Push the loadfile() function (again)          */
	lua_setfield   (L,       -2, "script"); /* <table>.script = <function>, pops <function>  */
	lua_pushinteger(L,    mtime          ); /* Push mtime                                    */
	lua_setfield   (L,       -2,  "mtime"); /* <table>.mtime = <mtime>, pops <mtime>         */
	lua_pushinteger(L,        0          ); /* Push 0 (beginning value for ~script~.hits     */
	lua_setfield   (L,       -2,   "hits"); /* <table>.hits = 0, pops the 0                  */
	lua_setfield   (L,       -2, filepath); /* magnet.cache.~script~ = <table>, pops <table> */
	lua_pop        (L,        2          ); /* Pops magnet and magnet.cache                  */

	/* The result of loadfile() should be
	** the only thing on the stack. */
	assert(1 == lua_gettop(L));
	assert(lua_isfunction(L, 1));

	return EXIT_SUCCESS;
}

/* }}} */

/* {{{1 static int magnet_get_script(lua_State * const L, const char * const filepath) */

static int
magnet_get_script(register lua_State * const L, const char * const filepath)
{
	struct stat script;

	if (filepath == NULL)
	{
		LA_PAGEERR("400 Bad Request");
		return EXIT_FAILURE;
	}

	if (stat(filepath, &script) == -1)
	{
		switch (errno)
		{
			case EACCES: LA_PAGEERR("403 Forbidden"            ); break;
			case ENOENT: LA_PAGEERR("404 Not Found"            ); break;
			default:     LA_PAGEERR("500 Internal Server Error"); break;
		}
		return EXIT_FAILURE;
	}

	/* Not sure why one would SCRIPT_FILENAME='somedirectory/' -- symlink?
	** but let's cover our bases anyway. I believe loadfile()
	** should be possible with anything *but* a directory...? */
	if (S_ISDIR(script.st_mode))
	{
		LA_PAGEOUT(ERRPAGE_TYPE, "200 OK", "`SCRIPT_FILENAME' references a directory");
		return EXIT_FAILURE;
	}

	lua_getglobal     (L, "magnet"          );  /* Push magnet from _G              */
	assert(lua_istable(L,       -1          )); /* assert() magnet is a table       */
	lua_getfield      (L,       -1,  "cache");  /* Push magnet.cache                */
	assert(lua_istable(L,       -1          )); /* assert() magnet.cache is a table */
	lua_getfield      (L,       -1, filepath);  /* Push magnet.cache['<script>']    */

	/* magnet.cache['<script>'] is not a
	** table for some reason, re-cache. */
	if (!lua_istable(L, -1))
	{
		lua_pop(L, 3); /* Pop whatever magnet.cache['<script>'] is, magnet.cache, and magnet */
		if (magnet_cache_script(L, filepath, script.st_mtime))
			return EXIT_FAILURE;
	}
	else
	{
		/* Push magnet.cache['<script>'].mtime */
		lua_getfield(L, -1, "mtime");

		/* Script has not been modified, continue as usual. */
		if (script.st_mtime == lua_tointeger(L, -1))
		{
			lua_pop              (L,  1          );  /* Pop <mtime>                                            */
			lua_getfield         (L, -1, "script");  /* Push magnet.cache['<script>'].script                   */
			assert(lua_isfunction(L, -1          )); /* assert() ^ is a function                               */
			lua_insert           (L, -4          );  /* Insert the function 3 indexes before                   */
			lua_pop              (L,  3          );  /* Pop magnet, magnet.cache, and magnet.cache['<script>'] */
		}
		/* Script has been modified since
		** we last stat()'d it, re-cache */
		else
		{
			/* Pop <mtime>, magnet.cache['<script>'],
			** magnet.cache, and magnet. */
			lua_pop(L, 4);
			if (magnet_cache_script(L, filepath, script.st_mtime))
				return EXIT_FAILURE;
		}
	}
	return EXIT_SUCCESS;
}

/* }}} */

/* {{{1 int main(void) */

int
main(void)
{
	register lua_State * const L = luaL_newstate();

	luaL_openlibs(L);

	/* Set our references for later. */
	reference_in_registry(L, &tostring_ref,        "tostring"       );
	assert(LUA_REFNIL != tostring_ref       );
	reference_in_registry(L, &debug_traceback_ref, "debug.traceback");
	assert(LUA_REFNIL != debug_traceback_ref);

	lua_newtable     (L                                ); /* Push a new table.                           */
	lua_newtable     (L                                ); /* Push a new table.                           */
	lua_setfield     (L,             -2,        "cache"); /* <table#1>.cache = <table#2>, pops <table#2> */
	lua_pushinteger  (L,              0                ); /* Push 0                                      */
	lua_setfield     (L,             -2, "conns_served"); /* <table#1>.conns_served = 0, pops 0          */
#if DIRLIST
	lua_pushcfunction(L, magnet_dirlist                ); /* Push magnet_dirlist()                       */
	lua_setfield     (L,             -2,      "dirlist"); /* magnet.dirlist(), pops cfunction            */
#endif
	lua_setglobal    (L,       "magnet"                ); /* _G.magnet = <table#1>, pops <table#1>       */

	while (FCGI_Accept() >= 0)
	{
		/* For the script's hits counter and the
		** global, requests served counter. */
		lua_Number tmp;
		const char * const script = getenv("SCRIPT_FILENAME");

		/* Should be nothing on the stack. */
		assert(0 == lua_gettop(L));

		/* Couldn't get script-function,
		** response has been sent, skip the rest. */
		if (magnet_get_script(L, script))
			continue;

		lua_newtable     (L                             ); /* Will become the env for our script-function         */
		lua_pushcfunction(L,     magnet_print           ); /* Push static int magnet_print(lua_State * const L)   */
		lua_setfield     (L,               -2,   "print"); /* <table>.print() = magnet_print()                    */
		lua_newtable     (L                             ); /* Push a new table.                                   */
		lua_pushvalue    (L, LUA_GLOBALSINDEX           ); /* Push _G                                             */
		lua_setfield     (L,               -2, "__index"); /* <table#2>.__index = _G                              */
		lua_setmetatable (L,               -2           ); /* setmetatable(<table#1>, <table#2>)                  */
		lua_setfenv      (L,               -2           ); /* setfenv(<script-function>, <table#1>) (modded env)  */

		/* script-function on stack */
		assert(1 == lua_gettop(L));

		/* Push the traceback() reference from the registry */
		lua_rawgeti(L, LUA_REGISTRYINDEX, debug_traceback_ref);
		assert(lua_isfunction(L, -1));

		/* Basically swap the traceback()
		** ref and the script-function */
		lua_insert(L, 1);

		/* Any errors generated by pcall() are printed
		** in-place, don't rely on HTTP headers having been sent. */
		if (lua_pcall(L, 0, 0, 1))
		{
			assert(lua_isstring(L, -1));
			fprintf
			(
				FCGI_stdout,
				"Content-Type: text/plain" "\r\n"
				"Status: 200 OK"           "\r\n"
				                           "\r\n"
				"%s"                       "\r\n",
				lua_tostring(L, -1)
			);
			lua_pop(L, 1);
		}

		/* pcall() pops the script-function
		** this pops the traceback() ref */
		lua_pop(L, 1);

		assert(0 == lua_gettop(L));

		/* First just get the script tables. -.- */
		lua_getglobal      (L, "magnet"         );  /* Push magnet from _G                                  */
		assert(lua_istable (L,       -1         )); /* assert() magnet is a table                           */
		lua_getfield       (L,       -1, "cache");  /* Push magnet.cache                                    */
		assert(lua_istable (L,       -1         )); /* assert() magnet.cache is a table                     */
		lua_getfield       (L,       -1,  script);  /* Push magnet.cache['<script>']                        */
		assert(lua_istable (L,       -1         )); /* assert() magnet.cache['<script>'] is a table         */

/* Gets the field (lua_Number) of the table on the top
** of the lua stack, increments it and re-sets it. */
#define _F_MAIN_INCREMENT_LUA_ACCUMULATOR(lua_state, accumulator, lua_num) \
		do                                                                                \
		{                                                                                \
			lua_getfield          (lua_state,          -1, accumulator); /* Push "accumulator" field from table on top of lua state. */ \
			lua_num = lua_tonumber(lua_state,          -1             ); /* lua_num = tonumber(accumulator)                          */ \
			lua_pop               (lua_state,           1             ); /* Pop numberized accumulator                               */ \
			lua_pushnumber        (lua_state, lua_num + 1             ); /* Push (lua_num + 1)                                       */ \
			lua_setfield          (lua_state,          -2, accumulator); /* -1 (table).accmulator = (hits + 1), pops (hits + 1)      */ \
		} while (0)

		/* Stack: table(magnet), table(magnet.cache), table(<script>) */
		_F_MAIN_INCREMENT_LUA_ACCUMULATOR(L,         "hits", tmp);
		lua_pop(L, 2); /* Pop table(script), table(magnet.cache)      */
		_F_MAIN_INCREMENT_LUA_ACCUMULATOR(L, "conns_served", tmp);
		lua_pop(L, 1); /* Pop table(magnet)                           */
#undef _F_MAIN_INCREMENT_LUA_ACCUMULATOR

/* If you want to be strict about memory;
** hurts web servers with many requests since it's
** a full collection and not a step. */
#if GC_COLLECT_AFTER_CONNECT
		lua_gc(L, LUA_GCCOLLECT, 0);
#endif
	}

	lua_close(L);
	return EXIT_SUCCESS;
}

/* }}} */
<file_sep># THIS == DEAD

I pushed this to Github to preserve it.  This is a FastCGI Lua server ~thing~ I wrote and worked on a long time ago.

I don't work on it anymore.

This was one of the first things that got me into webdev.  From FastCGI I went to SCGI, and then WSGI, and then I started making the application the webserver (nodejs).  This is where I started.

--------------------------------------------------------------------------------------------------

	Compile:

		gcc   -Wall -O2 -g -o magnet magnet.c -lfcgi -llua -lm -ldl -pedantic -ansi -std=c89
		clang -Wall -O2 -g -o magnet magnet.c -lfcgi -llua -lm -ldl -pedantic -ansi -std=c89

			> I find clang to be so much more descriptive for errors and warnings. <3

--------------------------------------------------------------------------------------------------

	Flags to consider for gcc:
		-flto                 - link-time optimization (feed zeh linkerzzzzz)
		-fomit-frame-pointer  - omit frame pointer
		-fstack-protector-all - enable the stack protector (can't hurt?)

--------------------------------------------------------------------------------------------------

	Environmental options:

		-DDIRLIST               - Enable magnet.dirlist(directory)
		-DGC_COLLECT_AFTER_RUN  - Force a gc collection after script exec. (hurts performance)
		-DPLAINTEXT_ERROR_PAGES - text/plain in the Content-Type for errors, text/html by default

--------------------------------------------------------------------------------------------------

Associate the .lua extension with the `magnet` fastcgi launcher in your web server.

On my webserver I use the spawn-fcgi program (originally from lighttpd?) like so:

	/usr/bin/spawn-fcgi -u httpd -g httpd -s /tmp/randomstring-webserver-lua.sock -f /path/to/lua-magnet

I then set a rule for all requests to files with the .lua extension to communicate
with that fastcgi server through the /tmp/randomstring-webserver-lua.sock socket.

Request: /path/to/whatever.lua

if ($REQUEST_URI =~ m{\.lua$})
{
	--> Query FastCGI server with SCRIPT_FILENAME='/path/to/whatever.lua'
	<-- FastCGI Server Response... (magnet response)
}

*Happy User* :D-S-<

At least, that's my understanding of it... I am *STILL LEARNING* about FastCGI
and backend-oriented webdev, but so far my attempts have worked out pretty well...

Features (so far)
-----------------

	- Caches scripts under _G.magnet.cache['<script>']
	- Keeps track of how many hits each script gets (_G.magnet.cache['<script'].hits)
	- Also exports the mtime for each script (which it uses to re-cache automagically if it has been altered)

	^ I take no credit for these. ^

	- print(...) has been redefined

		Arguments are converted to a string (if necessary) with Lua's tostring(), which will invoke a defined __tostring).
		This does not exactly like the regular print(), it doesn't print intermittent tabs with multiple arguments.

		Example usage:

			local header =
			{
				['Content-Type'] = 'text/plain',
				['Status']       = '200 OK',
			}

			buildheader =
				function (header_desc)
					return table.concat(header_desc) .. '\r\n\r\n'
				end

			print(build_header(header) .. 'Hello World!', '\r\n', 'How', 'are', 'you?\r\n')

		Outputs:

			Content-Type: text/plain
			Status: 200 OK

			Hello World!
			How are you?

	- Improved error-handling?
		Sends the ~correct~ response if the script can't be accessed for interpretation (403 Forbidden, 404 Not Found, 503 Service Unavailable).
		Errors generated when interpreting the script into bytecode are reported (200 OK, Content-Type: text/html, error...)
		Errors generated at runtime are reported in-place with a stack trace with the stock debug.traceback()

	- Reports how many connections served through magnet.conns_served
		(conns_served = sum of all scripts' magnet.cache['<script>'].hits)

	- magnet.dirlist(directory) - Enable with -DDIRLIST at compile-time.
		Function for returning the items in a specificed directory, very basic.
		Items are pre-sorted alphabetically. (scandir() + alphasort())

		If `directory' is not a string or is not a directory path
		scandir() fails, return looks like: false, 'error'
		Returns at least:                   { '.', '..' }

		Example return value: { [1] = '.', [2] = '..', [3] = 'a.ext', [4] = 'b.ext', ... }

		Example usage:

			-- Could return nil, error
			local str_fmt = string.format
			local t, e = magnet.dirlist('directory')
			local content = ''

			if not t then
			    content = e
			else
			    for i, filename in ipairs(t) do
			        content = content .. str_fmt("%s\t'%s'\n", tostring(i), filename)
			    end
			end

			print(
			    'Content-Type: text/plain\r\n' ..
			    'Status: 200 OK\r\n' ..
			    '\r\n' ..
			    content
			)

	- -DERRPAGE_TYPE=text/html (use at compile-time)
		Error pages are sent as text/plain by default, browsers often
		use their own error pages if the status is not 200 and the type
		is plaintext... You can text text/html or something else to override
		that behavior.

	- -DGC_COLLECT_AFTER_CONNECT (use at compile-time)
		Forces a garbage collection after each script run (the very last thing done)

		Note: This is probably a bad idea since it isn't a gc step and
		probably hurts performance since Lua manages the gc better anyway.

Tip
---

You can check out the interesting CGI environment variables with
os.getenv('REQUEST_URI') or os.getenv('QUERY_STRING'), etc... it's
just up to you to parse said query string.  I've already done
something in pure Lua which you can view at http://partyvan.us/lua/bleh.lua,
the source is icky and viewable with '&highlight' appended: http://partyvan.us/lua/bleh.lua&highlight

List of CGI Environment Variables
---------------------------------

	- 'AUTH_TYPE'
	- 'CONTENT_LENGTH'
	- 'CONTENT_TYPE'
	- 'DOCUMENT_ROOT'
	- 'GATEWAY_INTERFACE'
	- 'HTTP_ACCEPT'
	- 'HTTP_COOKIE'
	- 'HTTP_HOST'
	- 'HTTP_REFERRER'
	- 'HTTP_USER_AGENT'
	- 'HTTPS'
	- 'PATH'
	- 'PATH_INFO'
	- 'PATH_TRANSLATED'
	- 'QUERY_STRING',
	- 'REMOTE_ADDR'
	- 'REMOTE_HOST'
	- 'REMOTE_IDENT'
	- 'REMOTE_USER'
	- 'REQUEST_METHOD'
	- 'REQUEST_URI'
	- 'SCRIPT_NAME'
	- 'SCRIPT_FILENAME'
	- 'SERVER_ADMIN'
	- 'SERVER_NAME'
	- 'SERVER_PORT'
	- 'SERVER_PROTOCOL',
	- 'SERVER_SIGNATURE'
	- 'SERVER_SOFTWARE'

	- Note: Please let me know if there is some standard for all
	that exist, I have checked the original CGI site, but I keep
	finding more standard-yet-non-standard conventional CGI vars
	exported by my webserver.  Just curious what is common.

Roadmap
-------

	DO WANT:
		- Export all the CGI environment variables under magnet.env
			- Find out the standard for parsing the QUERY_STRING if it is defined. -.-
				- I believe ; or & is the (conventional?) record separator... need more info.

	Low Priority: (luaFilesystem works spendidly for now)
		- Add a function for stat()'ing a file.  Return attributes like ^ ?

License
-------

Let's assume my derived work is under the protection of An Hero.
You may do whatever you want with this code and you may not
hold me responsible for any negative affect it has on you,
your posessions, girlfriend, therapist, ...  I would be
amazed if it caused damage to your computer, and if it does
I'll laugh at you.  You have been warned.

Compliments of the Greater Lulz License version 2

languages: Markdown C

repo_name: blitmap/lua-magnet


text:
<repo_name>rubenbc7/ChamukoChaneke<file_sep>/Assets/Scripts/Changemaybe.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Changemaybe : MonoBehaviour
{

  private SpriteRenderer rend;
  private Sprite Chaneke, Candelabro, Posho, Craneo, Carta, Libro, Libro2, Libro3, Pan, Tarro, Vela;
  public BoxCollider player;

  private void Start(){
      rend = GetComponent<SpriteRenderer>();
      Chaneke = Resources.Load<Sprite>("Chaneke");
      Candelabro = Resources.Load<Sprite>("Candelabro");
      Posho = Resources.Load<Sprite>("Posho");
      Craneo = Resources.Load<Sprite>("Craneo");
        Carta = Resources.Load<Sprite>("Carta");
      Libro = Resources.Load<Sprite>("Libro");
      Libro2 = Resources.Load<Sprite>("Libro2");
      Libro3 = Resources.Load<Sprite>("Libro3");
      Pan = Resources.Load<Sprite>("Pan");
    Tarro = Resources.Load<Sprite>("Tarro");
    Vela = Resources.Load<Sprite>("Vela");
      rend.sprite = Chaneke;

      player = player.GetComponent<BoxCollider>();
  }

  private void Update(){
      if(Input.GetMouseButtonDown(0)){

            rend.sprite = Chaneke;
            player.size = new Vector3(7.52f,11.14f,0.2f);
      }
  }

  void OnCollisionEnter (Collision collisionInfo)
  {
      Debug.Log(collisionInfo.collider.name);

      switch(collisionInfo.collider.name){
           case "Candelabro":
                 rend.sprite = Candelabro;
                 player.size = new Vector3(7.7f,9.11f,0.2f);
                 break;
           case "Posho":
                 rend.sprite = Posho;
                 player.size = new Vector3(5.68f,3.9f,1.2f);
                 break;
            case "Craneo":
                 rend.sprite = Craneo;
                 player.size = new Vector3(5.25f,7.28f,1.2f);
                 break;
             case "Carta":
                 rend.sprite = Carta;
                 player.size = new Vector3(7.15f,4.32f, 1.2f);
                 break;
            case "Libro":
                 rend.sprite = Libro;
                 player.size = new Vector3(6.21f,8.32f, 1.2f);
                 break;
            case "Libro2":
                 rend.sprite = Libro2;
                 player.size = new Vector3(6.21f,8.32f, 1.2f);
                 break;
            case "Libro3":
                 rend.sprite = Libro3;
                 player.size = new Vector3(6.21f,8.32f, 1.2f);
                 break;
            case "Tarro":
                 rend.sprite = Tarro;
                 player.size = new Vector3(4.41f,4.32f, 1.2f);
                 break;
            case "Vela":
                 rend.sprite = Vela;
                 player.size = new Vector3(1.06f,3.24f, 1.2f);
                 break;

      }

     /* if(collisionInfo.collider.name == "Candelabro"){
          rend.sprite = Candelabro;
          player.size = new Vector3(7.7f,9.11f,0.2f);
      }
      if(collisionInfo.collider.name =="Posho"){
          rend.sprite = Posho;
          player.size = new Vector3(5.68f,3.9f,1.2f);
      }
        if(collisionInfo.collider.name =="Craneo"){
          rend.sprite = Craneo;
          player.size = new Vector3(5.26f,7.28f,1.2f);
      }*/
  }

}
<file_sep>/Assets/Scripts/PlayerMovementChamuco.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovementChamuco : MonoBehaviour
{
    public float speed = 10f;

    public Animator anim;
    Rigidbody rb;

    public GameObject objetivo;

    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {

        float xMov = Input.GetAxisRaw("Horizontal") * Time.deltaTime * speed;
        float yMov = Input.GetAxisRaw("Vertical") * Time.deltaTime * speed ;

        anim.SetFloat("vertical", Input.GetAxis("Vertical"));

        //rb.velocity = new Vector3(xMov, 0, yMov) * speed;
        transform.Translate(xMov, -yMov, 0);
        /*if (Input.GetKey("d")){
         rb.velocity = transform.right * 5;
        }

        anim.SetBool("garrotazo", true);
            Destroy(objetivo);

        if (Input.GetKey("a")){
         rb.velocity = -transform.right * 5;
        }*/

    }
    private void OnCollisionEnter(Collision collision){
        if(collision.gameObject.name == "Chaneke")
        {
           Destroy(objetivo);
        }
    }

}<file_sep>/Assets/Scripts/PlayerMovement.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    public float speed = 15f;

    Rigidbody rb;
    public bool cubeGround = true;

    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {

        float xMov = Input.GetAxisRaw("Horizontal") * Time.deltaTime * speed;
        float yMov = Input.GetAxisRaw("Vertical") * Time.deltaTime * speed ;

        //rb.velocity = new Vector3(xMov, 0, yMov) * speed;
        transform.Translate(xMov, 0 ,yMov);

        if(cubeGround == false ){
            rb.AddForce(new Vector3(0,-1f,0), ForceMode.Impulse);
        }

        if(Input.GetButtonDown("Jump") && cubeGround){
             rb.AddForce(new Vector3(0,50f,0), ForceMode.Impulse);
             cubeGround = false;
         }

        /*if (Input.GetKey("d")){
         rb.velocity = transform.right * 5;
        }
        if (Input.GetKey("a")){
         rb.velocity = -transform.right * 5;
        }*/

    }
    private void OnCollisionEnter(Collision collision){
        if(collision.gameObject.name == "Cube"){
            cubeGround = true;
        }
    }

}<file_sep>/Assets/Scripts/Tentaculos.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Tentaculos : MonoBehaviour {

	//PUBLIC
	[Range(-1,1)] public float offsetIndividual;
	[Range(0,1)] public float offsetGeneral;
	public float velocidad;
	public float amplitud;

	//PRIVATE
	Cadena[] cadenas;
	Transform parentTransform;
	Transform[] tempTransform;
	List<Transform> listRoots = new List<Transform> ();

	public struct Cadena
	{
		public Transform rootJoint;
		public Transform[] joints;
		public Vector3[] jointsOriginalRot;

		public void AlimentarJoints()
		{
			joints = rootJoint.gameObject.GetComponentsInChildren<Transform> ();
			jointsOriginalRot = new Vector3[joints.Length];
			for (int i = 0; i < joints.Length; i++)
			{
				jointsOriginalRot [i] = joints [i].localEulerAngles;
			}
		}

	}

	void Awake()
	{
		parentTransform = transform;
		tempTransform = GetComponentsInChildren<Transform> ();
		cadenas = new Cadena[parentTransform.childCount];

		for (int x = 1; x < tempTransform.Length; x++)
		{
			if (tempTransform [x].parent == parentTransform)
				listRoots.Add (tempTransform [x]);
		}

		for (int i = 0; i < cadenas.Length; i++)
		{
			cadenas [i].rootJoint = listRoots [i];
			cadenas [i].AlimentarJoints ();
		}

	}

	void FixedUpdate()
	{
		for (int i = 0; i < cadenas.Length; i++)
		{
			RotarJoint(cadenas[i], Time.time - (i*offsetGeneral));
		}

	}

	// SINEWAVE TENTACLE
	void RotarJoint (Cadena _cadena, float tiempo)
	{
		for (int i = 0; i < _cadena.joints.Length; i++)
		{
			float angulo = Mathf.Sin ((tiempo * velocidad) - i * offsetIndividual) * amplitud ;
			float rotOriginal = _cadena.jointsOriginalRot [i].z;
			_cadena.joints [i].localEulerAngles = new Vector3 (0, 0, rotOriginal + angulo);
		}
	}

}

branch_name: refs/heads/main

repo_language: C#


text:
<repo_name>yangwenbo11/SensorDemo<file_sep>/app/src/main/java/com/example/administrator/sensordemo/MainActivity.java
package com.example.administrator.sensordemo;

import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;

import java.util.List;

public class MainActivity extends AppCompatActivity {
    private TextView sensor_text;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sensor_text = (TextView)findViewById(R.id.sensor_text);

    }

    public void getAllSensor(View v){
        //获取传感器SensorManager对象
        SensorManager sensorManager= (SensorManager) getSystemService(SENSOR_SERVICE);
        //获取手机里的所有传感器种类
        List<Sensor> sensors=sensorManager.getSensorList(Sensor.TYPE_ALL);
        for(Sensor sensor:sensors){
            sensor_text.append(sensor.getName()+"\n");
        }
    }
    //加速度传感器
    public void getAccelerometer(View v){
        Intent intent=new Intent(this,AccelerometerActivity.class);
        startActivity(intent);
    }

    //邻近传感器
    public void getProximity(View v){
        Intent intent=new Intent(this,ProximityActivity.class);
        startActivity(intent);
    }

}

repo_language: Java


text:
<repo_name>JRArrington/TreasureIsland<file_sep>/main.py
print("Welcome to Treasure Island. \nYour mission is to find the treasure")
crossroad = input("You're at a crossroad. Where do you want to go? Type 'left' or 'right' ")
if crossroad.lower() == "right":
    print(f"You chose {crossroad.lower()}. You were attacked by rogue pirates. Game Over.")
elif crossroad.lower() == "left":
    print(f"You chose {crossroad.lower()}. You walk to a small lake.")
    swim_or_wait = input("Do you swim or wait for a boat? Type 'swim' or 'wait' ")
    if swim_or_wait.lower() == "swim":
        print("You chose to swim. You were eaten by hungry crocodiles. Game Over.")
    elif swim_or_wait.lower() == "wait":
        print(
            "You chose to wait. A ferryman came by, to take you to the island.\nNow on the island, you walk into a cave. ")
        door_color = input("The cave has three doors, which one do you choose? Red, yellow, or blue ")
        if door_color.lower() == "red":
            print(
                f"You chose the {door_color} door. When opening the door, an explosion went off, and you died. Game Over.")
        elif door_color.lower() == "yellow":
            print(
                f"You chose the {door_color} door. Upon opening the door, you discover a room filled with treasure. You Win!")
        elif door_color.lower() == "blue":
            print(
                f"You chose the {door_color} door. Opening the door set off a trap, and arrows pierced through you. Game Over.")

repo_language: Python

repo_name: JRArrington/TreasureIsland


text:
<file_sep>

New place

It is recommended that you write your review in a word processor, and then copy and paste to this form. Sometime the server may reject your posting, and we wouldn't want all your hard work to go to waste! :)

<%if current_user.try(:admin?) or current_user.try(:editor?) %>
<%= render 'form' %>
<%else%>

This isn't the page you were looking for...
<%= link_to 'Click Here To Return to Homepage', root_path %>

<%end%>

<file_sep>/*This does not show up on the bottom of the article. You would be looking for _comment.html.erb partical
*/

<%= notice %>

  Place:
  <%= @comment.place_id %>

  Body:
  <%= @comment.body %>

<%if current_user.try(:admin?) %>
	<%= link_to 'Edit', edit_comment_path(@comment) %> |
	<%= link_to 'Back', comments_path %>
<%end%><file_sep>

  <% @places.each do |place| %>

<%= place.title %>

        <%= show_overall_stars place if place.overallstars %>

 <%= place.headline %>

        <%= link_to "Read The Review", place, :class => "btn-sm btn-primary indexbutton"%>

        <%= link_to image_tag(place.image.url(:medium)),place %>
          <%if current_user.try(:admin?)%>

              <%= link_to edit_place_path(place) do %>

                Edit
              <% end %> |
              <%= link_to place, method: :delete, data: { confirm: 'Are you sure?' } do %>

                  Delete
              <% end %>

          <%end%>

  <% end %>

   <%= will_paginate @collection, renderer: BootstrapPagination::Rails %>

<file_sep>
Editing place

<%if current_user.try(:admin?) or current_user.try(:editor?) %>
<%= render 'form' %>

<%= link_to 'Show', @place %> |
<%= link_to 'Back', places_path %>
<%else%>

This isn't the page you were looking for...
<%= link_to 'Click Here To Return to Homepage', root_path %>

<%end%>
<file_sep>class ChangeFieldTypeInColumn < ActiveRecord::Migration
  def change
  	change_table :places do |t|
  		t.change :description, :text
  		t.change :restaurants, :text
  		t.change :attractions, :text
  		t.change :hotel, :text
  		t.change :ladies, :text
  	end
  end
end
<file_sep>

<%if current_user.try(:admin?)%>
<%= render 'pages/backdoorheader' %>

 All Places

		Title
		Editor Name
		Editor Email
		Image
		Headline
		Admin Options

		<% @backdoorplaces = Place.all %>
		<% @backdoorplaces.each do |place| %>

			 <%= place.title %>
			 <%= place.user.name if place.user %>
			 <%= place.user.email if place.user %>
			 <%= link_to image_tag(place.image.url(:thumb)),place %>
			 <%= place.headline %>

     				<%= link_to edit_place_path(place) do %>

              Edit
            <% end %> |
            <%= link_to place, method: :delete, data: { confirm: 'Are you sure?' } do %>

                Delete
            <% end %>

		<% end %>

<%else%>

This isn't the page you were looking for...
<%= link_to 'Click Here To Return to Homepage', root_path %>

<%end%>

<file_sep>class AddHotelToPlaces < ActiveRecord::Migration
  def change
    add_column :places, :hotel, :string
  end
end
<file_sep>
  <%= form_for(@comment) do |f| %>
    <% if @comment.errors.any? %>

 You cannot leave a blank comment

 Please Go Back and Try Again

        <%= link_to 'Go Back', comments_path %>

    <%else%>

        <%= f.label :body %>

        <%= f.text_area :body %>

        <%= f.submit %>

    <% end %>
  <% end %>
<file_sep>
 Welcome to the Backdoor, <%= current_user.name %>!

 All of your actions are being logged, so be very careful, or your privledges may get revoked

<%=User.all.count%> Users | <%=Place.all.count%> Articles | <%=Comment.all.count%> Comments

  <li class="<%= 'active' if current_page?(backdoor_path) %>"><%= link_to "Users", backdoor_path %>

  <li class="<%= 'active' if current_page?(comments_path) %>"><%= link_to "Comments", comments_path %>

  <li class="<%= 'active' if current_page?(backdoorplaces_path) %>"><%= link_to "Articles", backdoorplaces_path %>

<file_sep>

<%if current_user.try(:admin?)%>
<%= render 'pages/backdoorheader' %>

 Admin Users

			Name
			Email
			Login Count

		<% @users = User.all %>
		<% @users.each do |user| %>
		<%if user.admin%>

<%= user.name %>
		  <%= user.email %>
		  <%= user.sign_in_count %>

			<% end %>
			<% end %>

 All Users

			Name
			Email
			Login Count

		<% @users = User.all %>
		<% @users.each do |user| %>
		<%if user.admin%>
		<%else%>

<%= user.name %>
		  <%= user.email %>
		  <%= user.sign_in_count %>

			<% end %>
			<% end %>

<%else%>

This isn't the page you were looking for...
<%= link_to 'Click Here To Return to Homepage', root_path %>

<%end%>

<file_sep>class AddStarsToPlaces < ActiveRecord::Migration
  def change
    add_column :places, :restaurantstars, :integer
    add_column :places, :attractionstars, :integer
    add_column :places, :ladiesstars, :integer
    add_column :places, :hotelstars, :integer
  end
end
<file_sep>class RemoveLimitText < ActiveRecord::Migration
  def change
  	change_table :places do |t|
  		t.change :description, :text, :limit => nil
  		t.change :restaurants, :text, :limit => nil
  		t.change :attractions, :text, :limit => nil
  		t.change :hotel, :text, :limit => nil
  		t.change :ladies, :text, :limit => nil
  	end
  end
end
<file_sep>class AddLadiesToPlaces < ActiveRecord::Migration
  def change
    add_column :places, :ladies, :string
  end
end
<file_sep>
	<%= div_for(comment) do %>

	    	 Posted By <%=comment.user_name%> <%= time_ago_in_words(comment.created_at) %> ago

	    	<%= h(comment.body)%>

		<%if current_user.try(:admin?)%>
		<%= link_to 'Show', comment %>
		<%= link_to 'Edit', edit_comment_path(comment) %>
		<%= link_to 'Destroy', comment, method: :delete, data: { confirm: 'Are you sure?' } %>
		<%end%>

	<%end%>
<file_sep><%= form_for @place, html: { multipart: true } do |f| %>
  <% if @place.errors.any? %>

<%= pluralize(@place.errors.count, "error") %> prohibited this place from being saved:

      <% @place.errors.full_messages.each do |msg| %>

<%= msg %>

      <% end %>

  <% end %>

    <%= f.label :image %>
    <%= f.file_field :image, class: "form-control" %>

    <%= f.label :title %>

    <%= f.text_field :title, class:"form-control", :placeholder =>'City, Country' %>

    <%= f.label :headline %>

    <%= f.text_field :headline, class:"form-control", :placeholder =>'Quick Tagline... Be Creative!'  %>

    <%= f.label "Overall Rating" %>

    <%= f.label :overallstars, "1", :value => 1  %>
    <%= f.radio_button :overallstars, 1, :checked =>true %>
    <%= f.label :overallstars, "2", :value => 2 %>
    <%= f.radio_button :overallstars, 2 %>
    <%= f.label :overallstars, "3", :value => 3 %>
    <%= f.radio_button :overallstars, 3 %>
    <%= f.label :overallstars, "4", :value => 4 %>
    <%= f.radio_button :overallstars, 4 %>
    <%= f.label :overallstars, "5", :value => 5 %>
    <%= f.radio_button :overallstars, 5 %>

    <%= f.label :description %>

    <%= f.text_area :description, class:"form-control", :placeholder =>'Overall imperssion, for those who like to skim', :rows=>'4' %>

    <%= f.label "Attraction Rating" %>

    <%= f.label :attractionstars, "1", :value => 1  %>
    <%= f.radio_button :attractionstars, 1, :checked =>true %>
    <%= f.label :attractionstars, "2", :value => 2 %>
    <%= f.radio_button :attractionstars, 2 %>
    <%= f.label :attractionstars, "3", :value => 3 %>
    <%= f.radio_button :attractionstars, 3 %>
    <%= f.label :attractionstars, "4", :value => 4 %>
    <%= f.radio_button :attractionstars, 4 %>
    <%= f.label :attractionstars, "5", :value => 5 %>
    <%= f.radio_button :attractionstars, 5 %>

    <%= f.label :attractions %>

    <%= f.text_area :attractions, class:"form-control", :placeholder =>'Fun Activities, Sights To See, Things that you must do', :rows=>'10' %>

    <%= f.label "Restaurant Rating" %>

    <%= f.label :restaurantstars, "1", :value => 1  %>
    <%= f.radio_button :restaurantstars, 1, :checked =>true %>
    <%= f.label :restaurantstars, "2", :value => 2 %>
    <%= f.radio_button :restaurantstars, 2 %>
    <%= f.label :restaurantstars, "3", :value => 3 %>
    <%= f.radio_button :restaurantstars, 3 %>
    <%= f.label :restaurantstars, "4", :value => 4 %>
    <%= f.radio_button :restaurantstars, 4 %>
    <%= f.label :restaurantstars, "5", :value => 5 %>
    <%= f.radio_button :restaurantstars, 5 %>

    <%= f.label :restaurants %>

    <%= f.text_area :restaurants, class:"form-control", :placeholder =>'Name some places you like to eat at!', :rows=>'10' %>

    <%= f.label "Ladies Rating" %>

    <%= f.label :ladiesstars, "1", :value => 1  %>
    <%= f.radio_button :ladiesstars, 1, :checked =>true %>
    <%= f.label :ladiesstars, "2", :value => 2 %>
    <%= f.radio_button :ladiesstars, 2 %>
    <%= f.label :ladiesstars, "3", :value => 3 %>
    <%= f.radio_button :ladiesstars, 3 %>
    <%= f.label :ladiesstars, "4", :value => 4 %>
    <%= f.radio_button :ladiesstars, 4 %>
    <%= f.label :ladiesstars, "5", :value => 5 %>
    <%= f.radio_button :ladiesstars, 5 %>

    <%= f.label :ladies %>

    <%= f.text_area :ladies, class:"form-control", :placeholder =>'How was the Local Talent, and How were the pros ;)', :rows=>'10'  %>

    <%= f.label "Hotel Rating" %>

    <%= f.label :hotelstars, "1", :value => 1  %>
    <%= f.radio_button :hotelstars, 1, :checked =>true %>
    <%= f.label :hotelstars, "2", :value => 2 %>
    <%= f.radio_button :hotelstars, 2 %>
    <%= f.label :hotelstars, "3", :value => 3 %>
    <%= f.radio_button :hotelstars, 3 %>
    <%= f.label :hotelstars, "4", :value => 4 %>
    <%= f.radio_button :hotelstars, 4 %>
    <%= f.label :hotelstars, "5", :value => 5 %>
    <%= f.radio_button :hotelstars, 5 %>

    <%= f.label :hotel %>

    <%= f.text_area :hotel, class:"form-control", :placeholder =>'Name some hotels that you recommend', :rows=>'10'  %>

    <%= f.submit class: "btn btn-primary" %>

<% end %>
<file_sep>module ApplicationHelper
	def show_overall_stars(place)
  	image_tag "#{place.overallstars}stars.png"
	end
end
<file_sep>class Comment < ActiveRecord::Base
	belongs_to :place
	belongs_to :user
	validates :body, presence: true
end
<file_sep># Be sure to restart your server when you modify this file.

Stagadvisor::Application.config.session_store :cookie_store, key: '_stagadvisor_session'
<file_sep>

				<%= link_to places_path do %>
					Back
				<%end%>
				<% if current_user.try(:admin?) or  @place.user == current_user %>

		       			<%= link_to edit_place_path(@place) do %>
		         	Edit
		     		<%end%>

				<%end%>

<%= @place.title %>

<%= show_overall_stars @place if @place.overallstars %>

<%= @place.headline %>

<%= image_tag @place.image.url(:medium) %>

<%= @place.description %>

Attractions:  <%= show_attraction_stars @place%>

<%= @place.attractions %>

Restaurants:  <%= show_restaurant_stars @place%>

<%= @place.restaurants %>

Ladies:  <%= show_ladies_stars @place%>

<%= @place.ladies %>

Hotels:  <%= show_hotel_stars @place%>
<%= @place.hotel %>

			<% if user_signed_in? %>
				<%= form_for [@place, Comment.new] do |f| %>

						<%= f.text_field :body, class:"form-control"%>

<%=f.submit "Add Comment", class: "btn btn-primary" %>

				<%end%>
			<%else%>

					<%= link_to "Quick Sign Up to Comment", new_user_registration_path, class: "btn btn-primary"%>
				<%end%>

 Stag Comments

				<%= render :partial => @place.comments %>

<file_sep>class Place < ActiveRecord::Base
	belongs_to :user
	has_attached_file :image, :styles => { :medium => "500x500>", :thumb => "100x100>" }
	has_many :comments, :order => "created_at DESC"

	validates :image, presence: true
	validates :image, format: {with: %r{\.gif|jpg|png|jpeg}i, message: 'must be a url for gif, jpg, jpeg, or png image.'}
  	validates :title, presence: true, uniqueness: true
  	validates :headline, presence: true
  	validates :headline, length: {maximum: 60}
  	validates :description, presence: true
  	validates :attractions, presence: true
  	validates :restaurants, presence: true
  	validates :ladies, presence: true
end
<file_sep>

<%if current_user.try(:admin?)%>
<%= render 'pages/backdoorheader' %>

All comments

    Place Number
    Commentor Name
    Comment Body
    Admin Options

    <% @comments.each do |comment| %>

        <%= comment.place_id %>
        <%= comment.user_name %>

        <%= comment.body %>
        <%= link_to 'Show', comment %>
            <%= link_to 'Edit', edit_comment_path(comment) %>
            <%= link_to 'Destroy', comment, method: :delete, data: { confirm: 'Are you sure?' } %>

    <% end %>

<%else%>

This isn't the page you were looking for...
<%= link_to 'Click Here To Return to Homepage', root_path %>

<%end%>

<file_sep>module PlacesHelper

	def show_overall_stars(place)
  	image_tag "#{place.overallstars}stars.png"
	end

	def show_attraction_stars(place)
  	image_tag "#{place.attractionstars}stars.png"
	end

	def show_restaurant_stars(place)
  	image_tag "#{place.restaurantstars}stars.png"
	end

	def show_hotel_stars(place)
  	image_tag "#{place.hotelstars}stars.png"
	end

	def show_ladies_stars(place)
  	image_tag "#{place.ladiesstars}stars.png"
	end

end

languages: HTML+ERB Ruby

repo_language: HTML+ERB


text:
<file_sep>#![deny(warnings)]
extern crate futures;
extern crate hyper;
extern crate pretty_env_logger;
extern crate serde;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate serde_json;
extern crate url;

use std::collections::HashMap;

use futures::{future, Future, Stream};
use hyper::{Body, Method, Request, Response, Server, StatusCode};
use hyper::service::service_fn;
use serde_json::Value;
use url::form_urlencoded;

static INDEX: &[u8] = br#"

Hello, World!

Usage

GET: /query_as_json

curl 'localhost:1337/query_as_json?a=XYZ&b=123&b=456&c'

POST: /param_as_json

curl -X POST -d 'a=XYZ' -d 'b=123' -d 'b=456' -d 'c' 'localhost:1337/param_as_json'

PUT: /json_as_json

curl -X PUT -d '{ "a": "XYZ", "b": [ 123, 456 ], "c": null }' 'localhost:1337/json_as_json'

"#;

#[derive(Serialize, Deserialize, Debug)]
struct  Point {
    x: i32,
    y: i32,
}

// Using service_fn, we can turn this function into a `Service`.
fn param_example(req: Request) -> Box<Future<Item=Response, Error=hyper::Error> + Send> {
    match (req.method(), req.uri().path()) {
        (&Method::GET, "/") | (&Method::GET, "/hello") => {
            Box::new(future::ok(Response::builder()
                .status(StatusCode::OK)
                .header("X-HELLO", "world")
                .body(Body::from(INDEX))
                .unwrap()))
        },
        (&Method::GET, "/query_as_json") => {
            let query_as_map = match req.uri().query() {
                Some(it) => {
                    form_urlencoded::parse(it.as_ref())
                        .into_owned().into_iter()
                        .fold(
                            HashMap::<String, Vec<_>>::new(),
                            |mut acc: HashMap<String, Vec<_>>, pair: (String, String)| {
                                match acc.get_mut(pair.0.as_str()) {
                                    Some(vec) => {
                                        vec.push(pair.1);
                                    }
                                    None => {
                                        acc.insert(pair.0, vec![pair.1]);
                                    }
                                }
                                acc
                            }
                        )
                }
                None => { HashMap::new() }
            };

            println!("{:?}", query_as_map);

            Box::new(future::ok(Response::builder()
                .status(StatusCode::OK)
                .header("Content-Type", "application/json; charset=utf-8")
                .body(Body::from(json!(query_as_map).to_string()))
                .unwrap()))
        },
        (&Method::POST, "/param_as_json") => {
            Box::new(req.into_body().concat2().map(|b| {
                let params_as_map = form_urlencoded::parse(b.as_ref())
                    .into_owned().into_iter()
                    .fold(
                        HashMap::<String, Vec<_>>::new(),
                        |mut acc: HashMap<String, Vec<_>>, pair: (String, String)| {
                            match acc.get_mut(pair.0.as_str()) {
                                Some(vec) => {
                                    vec.push(pair.1);
                                }
                                None => {
                                    acc.insert(pair.0, vec![pair.1]);
                                }
                            }
                            acc
                        }
                    );

                println!("{:?}", params_as_map);

                Response::builder()
                    .status(StatusCode::OK)
                    .header("Content-Type", "application/json; charset=utf-8")
                    .body(Body::from(json!(params_as_map).to_string()))
                    .unwrap()
            }))
        },
        (&Method::PUT, "/json_as_json") => {
            Box::new(req.into_body().concat2().map(|b| {
                let json_str = String::from_utf8(b.as_ref().to_vec()).unwrap();
                let json_as_value: Value = serde_json::from_str(json_str.as_str()).unwrap();

                println!("{:?}", json_as_value);

                Response::builder()
                    .status(StatusCode::OK)
                    .header("Content-Type", "application/json; charset=utf-8")
                    .body(Body::from(json!(json_as_value).to_string()))
                    .unwrap()
            }))
        },
        (&Method::PUT, "/json_as_point") => {
            Box::new(req.into_body().concat2().map(|b| {
                let json_str = String::from_utf8(b.as_ref().to_vec()).unwrap();
                let json_as_point: Point = serde_json::from_str(json_str.as_str()).unwrap();

                println!("{:?}", json_as_point);

                Response::builder()
                    .status(StatusCode::OK)
                    .header("Content-Type", "application/json; charset=utf-8")
                    .body(Body::from(json!(json_as_point).to_string()))
                    .unwrap()
            }))
        },
        _ => {
            Box::new(future::ok(Response::builder()
                .status(StatusCode::NOT_FOUND)
                .body(Body::empty())
                .unwrap()))
        }
    }
}

fn main() {
    pretty_env_logger::init();

    let addr = ([127, 0, 0, 1], 1337).into();

    let server = Server::bind(&addr)
        .serve(|| service_fn(param_example))
        .map_err(|e| eprintln!("server error: {}", e));

    hyper::rt::run(server);
}
<file_sep>[package]
name = "rust-hyper"
version = "0.1.0"
authors = ["yo1000 <<EMAIL>>"]
edition = "2018"

[dependencies]
hyper = "0.12.20"
futures = "0.1.25"
serde = "1.0.88"
serde_derive = "1.0.88"
serde_json = "1.0.35"
url = "1.7.2"
pretty_env_logger = "0.3.0"
uuid = { version = "0.7", features = ["serde", "v4"] }

languages: Rust TOML

repo_language: Rust


text:
<repo_name>miks1965/tree-sitter-pascalabcnet<file_sep>/README.md
# tree-sitter-pascalabcnet

PascalABC.NET grammar for [tree-sitter](https://github.com/tree-sitter/tree-sitter).

## References:

- [PascalABC.NET grammar](https://github.com/pascalabcnet/pascalabcnet/blob/master/Parsers/PascalABCParserNewSaushkin/ABCPascal.y) - grammar file from the original PascalABC.NET repository.


text:
<file_sep>vis-tracker-api
===============

Simple application to log fish you catch while out fishing.

repo_name: IanMcShane/vis-tracker-api